[build-system] requires = [ "setuptools>=77.0.3,<81.0.0", "wheel", "setuptools-scm>=8.0", ] build-backend = "setuptools.build_meta" [project] name = "vllm-omni" dynamic = ["version", "dependencies"] description = "A framework for efficient model inference with omni-modality models" readme = "README.md" requires-python = ">=3.10,<3.14" license = "Apache-2.0" authors = [ {name = "vLLM-Omni Team"} ] keywords = ["vllm", "multimodal", "diffusion", "transformer", "inference", "serving"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development :: Libraries :: Python Modules", ] # Dependencies are now managed dynamically via setup.py based on detected hardware platform. # This allows automatic installation of the correct platform-specific dependencies (CUDA/ROCm/CPU/XPU/NPU) # without requiring extras like [cuda]. See requirements/ directory for platform-specific dependencies. [project.optional-dependencies] dev = [ "pytest>=7.0.0", "pytest-asyncio>=0.21.0", "pytest-cov>=4.0.0", "pytest-mock>=3.10.0", "websockets>=15.0.1", "pytest-subtests>=0.11.0", "datasets>=2.14.0", "mypy==1.11.1", "pre-commit==4.0.1", "openai-whisper>=20250625", "psutil>=7.2.0", "soundfile>=0.13.1", "imageio[ffmpeg]>=0.6.0", "opencv-python>=4.12.0.88", "mooncake-transfer-engine-cuda13>=0.3.9", "av", # for ComfyUI tests "openpyxl>=3.0.0", # for nightly CI "pyttsx3>=2.99", "opencc>=1.2.0", "mistune>=3.2.0", # for example tests "torchmetrics>=1.4.0", # for accuracy similarity metrics "ray[default]", # for RL test "jiwer>=3.0.0", "zhon>=2.0.0", "zhconv>=1.4.2", "scipy>=1.10.0", "funasr>=1.0.0", "lpips>=0.1.4", # for quantization fp8 "orjson>=3.11.7", # to make v1/embeddings API fast "voxcpm>=2.0.2", # for VoxCPM2 path-locating in tests "torchdiffeq>=0.2.5", # for covo_audio Test "FlagEmbedding", # for hunyuan_image3 tests "kernels<0.15.0", # for accuracy tests comparison with diffusers output (0.15.0 incompatible with diffusers 0.38.0) "s3tokenizer>=0.3.0", # for tts test "step-audio2>=1.0.0", # Step-Audio2 Token2Wav (flashcosyvoice / hyperpyyaml) ] demo = [ "opencv-python>=4.12.0.88", # cli/stream_client frame reading "requests>=2.28.0", # cli/stream_client HTTP "cn2an>=0.5.22", # Chinese number normalization for TTS (e.g. "1次" -> "一次") ] forced-aligner = [ "qwen-asr>=0.0.6", # faithful Japanese/Korean word segmentation for the TTS forced aligner ] # Local-test-only extras local = [ "FlagEmbedding", ] # Optional runtime dependencies for the MiniCPM-o 4.5 talker pipeline. # The talker loads MiniCPMTTS via `trust_remote_code` from the model repo, # and that module performs `from stepaudio2 import Token2wav` against the # MiniCPM-o-flavored Token2wav vocoder (PyPI: `stepaudio2-minicpmo`, NOT # upstream `stepfun-ai/Step-Audio2` — the upstream signature rejects # `n_timesteps` and crashes at construction). A clean `vllm-omni` install # does not pull this in by default to avoid forcing the dep onto users # who only need other models; opt in with `pip install vllm-omni[minicpmo]`. minicpmo = [ "stepaudio2-minicpmo", ] # Optional Blackwell-only fused-bias FP8 GEMM; package is `quack-kernels` (imported # as `quack`), not the unrelated `quack`. See docs/user_guide/quantization/fp8.md. quack = [ "quack-kernels>=0.3.11", ] docs = [ "mkdocs>=1.5.0", "mkdocs-api-autonav", "mkdocs-material", "mkdocstrings-python", "mkdocs-gen-files", "mkdocs-awesome-nav", "mkdocs-glightbox", "mkdocs-git-revision-date-localized-plugin", "mkdocs-minify-plugin", "regex", "ruff", "pydantic", ] soulx-svs = [ "funasr>=1.0.0", "g2pM>=0.1.2.5", "g2p-en>=2.1.0", "ToJyutping>=3.2.0", ] [project.urls] Homepage = "https://github.com/vllm-project/vllm-omni" Repository = "https://github.com/vllm-project/vllm-omni" Documentation = "https://vllm-omni.readthedocs.io" "Bug Tracker" = "https://github.com/vllm-project/vllm-omni/issues" [project.scripts] vllm-omni = "vllm_omni.entrypoints.cli.main:main" # Register vllm-omni's model registrations on every vllm subprocess. vllm # auto-loads anything advertised under `vllm.general_plugins` in its own # `load_general_plugins()`, so worker subprocesses spawned by vllm (which # only import vllm, not vllm_omni) will still pick up the omni archs. [project.entry-points."vllm.general_plugins"] vllm_omni_register_models = "vllm_omni.engine.arg_utils:register_omni_models_to_vllm" [tool.setuptools.packages.find] where = ["."] include = ["vllm_omni*"] [tool.setuptools.package-data] "vllm_omni" = ["_version.py", "py.typed"] "vllm_omni.model_executor.stage_configs" = ["*.yaml"] [tool.setuptools_scm] # no extra settings needed, presence enables setuptools-scm [tool.ruff] line-length = 120 exclude = [ ".eggs", ".git", ".hg", ".mypy_cache", ".tox", ".venv", "build", "dist", "vllm_omni.egg-info", ] [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort (handled separately, but included for compatibility) "N", # pep8-naming "UP", # pyupgrade "TID251", # flake8-tidy-imports.banned-api ] ignore = [ "E203", # whitespace before ':' (conflicts with black) # W503 is not needed in ruff as it's compatible with black by default "N801", # class names should use CapWords convention "N802", # function name should follow snake_case "N806", # variable in function should follow snake_case "N812", # lowercase imported as non-lowercase: functional as F ] [tool.ruff.lint.per-file-ignores] "examples/**" = ["E501"] # Allow long lines in examples "tests/**" = ["E501"] # Allow long lines in tests # MiniCPM-o reference modeling code vendored from upstream HF/transformers/MiniCPM-o. # These files keep upstream conventions (star imports, long lines, math-symbol # argument names) so they stay easy to diff against upstream releases. "vllm_omni/model_executor/models/minicpmo_4_5/minicpmo_4_5_omni_llm.py" = ["E402", "E501", "F403", "F405", "N803"] "vllm_omni/experimental/fullduplex/joyvl/decision/prompts.py" = ["E501"] # System/summarizer prompts are long prose lines [tool.ruff.lint.flake8-tidy-imports.banned-api] "librosa".msg = "The librosa module is banned, use vllm.multimodal helpers instead" "torch.cuda.max_memory_allocated".msg = "Use torch.accelerator.max_memory_allocated" "torch.cuda.reset_peak_memory_stats".msg = "Use torch.accelerator.reset_peak_memory_stats" "torch.cuda.device_count".msg = "Use torch.accelerator.device_count" "torch.cuda.current_device".msg = "Use torch.accelerator.current_device_index" "torch.cuda.empty_cache".msg = "Use torch.accelerator.empty_cache" "torch.cuda.synchronize".msg = "Use torch.accelerator.synchronize" [tool.mypy] python_version = "3.12, 3.13" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true disallow_incomplete_defs = true check_untyped_defs = true disallow_untyped_decorators = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_no_return = true warn_unreachable = true strict_equality = true [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] python_files = ["test_*.py", "*_test.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "--strict-markers", "--strict-config" ] markers = [ # ci/cd required "core_model: L1&L2 tests (run in each PR)", "advanced_model: L3 level tests (run on each merge)", "full_model: L4 level tests (run nightly)", "local_model: tests (run locally)", # function module markers "diffusion: Diffusion model tests", "omni: Omni model tests", "tts: TTS model tests", "cache: Cache backend tests", "parallel: Parallelism/distributed tests", "sp: Sequence parallelism tests", "example: Doc example code tests", # platform markers "cpu: Tests that run on CPU", "gpu: Tests that run on GPU (auto-added)", "cuda: Tests that run on CUDA (auto-added)", "rocm: Tests that run on AMD/ROCm (auto-added)", "xpu: Tests that run on XPU (auto-added)", "npu: Tests that run on NPU/Ascend (auto-added)", "musa: Tests that run on MUSA/Moore Threads (auto-added)", # specified computation resources marks (auto-added) "H100: Tests that require H100 GPU", "L4: Tests that require L4 GPU", "MI325: Tests that require MI325 GPU (AMD/ROCm)", "B60: Tests that require Intel Arc Pro B60 XPU", "S5000: Tests that require S5000 GPU (Moore Threads/MUSA)", "A2: Tests that require A2 NPU", "A3: Tests that require A3 NPU", "distributed_cuda: Tests that require multi cards on CUDA platform", "distributed_rocm: Tests that require multi cards on ROCm platform", "distributed_xpu: Tests that require multi cards on XPU platform", "distributed_npu: Tests that require multi cards on NPU platform", "distributed_musa: Tests that require multi cards on MUSA platform", "skipif_cuda: Skip if the num of CUDA cards is less than the required", "skipif_rocm: Skip if the num of ROCm cards is less than the required", "skipif_xpu: Skip if the num of XPU cards is less than the required", "skipif_npu: Skip if the num of NPU cards is less than the required", "skipif_musa: Skip if the num of MUSA cards is less than the required", # more detailed markers "sp: Sequence parallelism tests (multi-GPU)", "slow: Slow tests (may skip in quick CI)", "benchmark: Benchmark tests", ] filterwarnings = [ "ignore:.*does not have '__test__' attribute.*:UserWarning", "ignore:.*does not have '__bases__' attribute.*:UserWarning", ] [tool.typos.default] extend-ignore-identifiers-re = [ ".*_thw", ".*thw", "ein", ".*arange", ".*MoBA", ".*temperal_downsample", ".*_nd", ".*nd$", ".*EmbedND$", ".*nothink.*", ".*NOTHINK.*", ".*nin.*", ".*[Oo]no_[Aa]nna.*", ".*cann.*", ".*[Nn][Dd]3.*", ".*updator.*", "byt5.*", ] extend-ignore-re = [ "\\.\\.\\.n,d->\\.\\.\\.nd", ] [tool.typos.default.extend-words] ue = "ue" semantics = "semantics" fullset = "fullset" Vai = "Vai" tockens = "tockens" CANN = "CANN" # Step-Audio reasoning parser streams `` tokens split across chunks # (e.g. ""). The fragment "thi" appears literally in its # parser logic and tests and is not a typo of "the"/"this". thi = "thi" ND = "ND" byt5 = "byt5" # "seeked" is the standard HTML media element DOM event name (fires when a # seek completes), used by the word-timestamps Gradio demo. Not a typo. seeked = "seeked"