diff --git a/setup.py b/setup.py index eb313b7d219c..73c94f1a5b86 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,8 @@ def load_module_from_path(module_name, path): # cannot import envs directly because it depends on vllm, # which is not installed yet envs = load_module_from_path('envs', os.path.join(ROOT_DIR, 'vllm', 'envs.py')) +version = load_module_from_path('version', + os.path.join(ROOT_DIR, 'vllm', 'version.py')) VLLM_TARGET_DEVICE = envs.VLLM_TARGET_DEVICE @@ -664,7 +666,7 @@ def _read_requirements(filename: str) -> list[str]: "mistral_common[audio]"], # Required for audio processing "video": [], # Kept for backwards compatibility # FlashInfer should be updated together with the Dockerfile - "flashinfer": ["flashinfer-python==0.3.0"], + "flashinfer": [f"flashinfer-python=={version.FLASHINFER_VERSION}"], # Optional deps for AMD FP4 quantization support "petit-kernel": ["petit-kernel"], }, diff --git a/vllm/utils/flashinfer.py b/vllm/utils/flashinfer.py index fab134733d4f..6ae0481b1d68 100644 --- a/vllm/utils/flashinfer.py +++ b/vllm/utils/flashinfer.py @@ -15,10 +15,12 @@ import requests import torch +from packaging.version import parse import vllm.envs as envs from vllm.logger import init_logger from vllm.platforms import current_platform +from vllm.version import FLASHINFER_VERSION logger = init_logger(__name__) @@ -39,6 +41,22 @@ def has_flashinfer() -> bool: return importlib.util.find_spec("flashinfer") is not None +def valid_flashinfer_version() -> bool: + """Check the installed FlashInfer version matches the expected.""" + if not has_flashinfer(): + return False + + try: + import flashinfer + + # Parse both versions to handle version comparison properly + expected = parse(FLASHINFER_VERSION) + actual = parse(flashinfer.__version__) + return actual == expected + except (ImportError, AttributeError): + return False + + def _missing(*_: Any, **__: Any) -> NoReturn: """Placeholder for unavailable FlashInfer backend.""" raise RuntimeError( @@ -65,6 +83,11 @@ def _lazy_import_wrapper(module_name: str, def _get_impl(): if not has_flashinfer(): return None + if not valid_flashinfer_version(): + raise RuntimeError( + "Installed FlashInfer version is not supported. " + f"Please install flashinfer-python=={FLASHINFER_VERSION} " + "or use the vLLM extra: pip install 'vllm[flashinfer]'") mod = _get_submodule(module_name) return getattr(mod, attr_name, None) if mod else None @@ -355,6 +378,7 @@ def flashinfer_scaled_fp8_mm( __all__ = [ "has_flashinfer", + "valid_flashinfer_version", "flashinfer_trtllm_fp8_block_scale_moe", "flashinfer_cutlass_fused_moe", "fp4_quantize", diff --git a/vllm/version.py b/vllm/version.py index 6c88b1b5a3bf..9aa4868f28d7 100644 --- a/vllm/version.py +++ b/vllm/version.py @@ -39,3 +39,10 @@ def _prev_minor_version(): # In dev tree, this will return "0.-1", but that will work fine" assert isinstance(__version_tuple__[1], int) return f"{__version_tuple__[0]}.{__version_tuple__[1] - 1}" + + +# Optional dependency versions +# This should be kept in sync with: +# - setup.py extras_require +# - docker/Dockerfile version specifications +FLASHINFER_VERSION = "0.3.0"