Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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"],
},
Expand Down
24 changes: 24 additions & 0 deletions vllm/utils/flashinfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)

Expand All @@ -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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not >=?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree >= would work

except (ImportError, AttributeError):
return False
Comment on lines +56 to +57

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The try...except block does not handle a potential ValueError (or packaging.version.InvalidVersion) that can be raised by packaging.version.parse() if flashinfer.__version__ is not a valid PEP 440 version string. An unhandled exception here would crash the application during initialization. It's safer to catch this exception to prevent such crashes.

Suggested change
except (ImportError, AttributeError):
return False
except (ImportError, AttributeError, ValueError):
return False



def _missing(*_: Any, **__: Any) -> NoReturn:
"""Placeholder for unavailable FlashInfer backend."""
raise RuntimeError(
Expand All @@ -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

Expand Down Expand Up @@ -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",
Expand Down
7 changes: 7 additions & 0 deletions vllm/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Loading