diff --git a/docker/Dockerfile.rock_base b/docker/Dockerfile.rock_base index 3ee203a347..40100a1bbf 100644 --- a/docker/Dockerfile.rock_base +++ b/docker/Dockerfile.rock_base @@ -8,7 +8,7 @@ ARG TRITON_VERSION=3.8.0+git669b31ac ARG TRITON_REPO="https://github.com/ROCm/triton.git" ARG FA_BRANCH="0e60e394" ARG FA_REPO="https://github.com/Dao-AILab/flash-attention.git" -ARG AITER_BRANCH="v0.1.23" +ARG AITER_BRANCH="v0.1.24.post1" ARG AITER_REPO="https://github.com/ROCm/aiter.git" ARG MORI_BRANCH="v1.2.3.post1" ARG MORI_REPO="https://github.com/ROCm/mori.git" diff --git a/docker/Dockerfile.rocm_base b/docker/Dockerfile.rocm_base index 15e3e2468e..bd8099dd15 100644 --- a/docker/Dockerfile.rocm_base +++ b/docker/Dockerfile.rocm_base @@ -9,7 +9,7 @@ ARG PYTORCH_AUDIO_BRANCH="v2.11.0" ARG PYTORCH_AUDIO_REPO="https://github.com/pytorch/audio.git" ARG FA_BRANCH="0e60e394" ARG FA_REPO="https://github.com/Dao-AILab/flash-attention.git" -ARG AITER_BRANCH="v0.1.23" +ARG AITER_BRANCH="v0.1.24.post1" ARG AITER_REPO="https://github.com/ROCm/aiter.git" ARG MORI_BRANCH="v1.2.3.post1" ARG MORI_REPO="https://github.com/ROCm/mori.git" diff --git a/docs/models/supported_models.md b/docs/models/supported_models.md index e461379bcb..a55559b0d6 100644 --- a/docs/models/supported_models.md +++ b/docs/models/supported_models.md @@ -19,12 +19,10 @@ vLLM also supports model implementations that are available in Transformers. We Currently, the Transformers modeling backend works for the following: -- Modalities: embedding models, language models, vision-language models* and audio-language models +- Modalities: embedding models, language models, vision-language models and audio-language models - Architectures: encoder-only, decoder-only, mixture-of-experts - Attention types: full attention and/or sliding attention -_*Vision-language models currently accept only image inputs. Support for video inputs will be added in a future release._ - If the Transformers model implementation follows all the steps in [writing a custom model](#writing-custom-models) then, when used with the Transformers modeling backend, it will be compatible with the following features of vLLM: - All the features listed in the [compatibility matrix](../features/README.md#feature-x-feature) diff --git a/tests/kernels/attention/test_attention_selector.py b/tests/kernels/attention/test_attention_selector.py index 24f02836e9..c6f4094eb6 100644 --- a/tests/kernels/attention/test_attention_selector.py +++ b/tests/kernels/attention/test_attention_selector.py @@ -455,6 +455,31 @@ def test_per_head_quant_scales_backend_selection( assert backend_name in str(exc_info.value) +@pytest.mark.skipif( + CudaPlatform is None, reason="CUDA platform is required for this test" +) +@pytest.mark.parametrize("head_size", [64, 80, 96, 128, 192, 256]) +def test_int4_per_token_head_head_size_selection(head_size: int): + """INT4 per-token-head KV cache is selectable at any even head size. + + The Hadamard rotation the INT4 write path applies is now defined for + non-power-of-two rows as well (it runs block-diagonally, see + ``fast_hadamard_transform``), so a model such as Phi-3 (head_size=96) must + keep selecting TRITON_ATTN instead of being rejected. + """ + vllm_config = VllmConfig(cache_config=CacheConfig(block_size=64)) + with ( + set_current_vllm_config(vllm_config), + patch("vllm.platforms.current_platform", CudaPlatform()), + ): + backend = get_attn_backend( + head_size=head_size, + dtype=torch.float16, + kv_cache_dtype="int4_per_token_head", + ) + assert backend.get_name() == "TRITON_ATTN" + + @pytest.mark.parametrize( "backend_name,use_non_causal,should_succeed", [ diff --git a/tests/kernels/test_bf16_skinny_gemm.py b/tests/kernels/test_bf16_skinny_gemm.py index 7cdaf2b495..7ca207c8e4 100644 --- a/tests/kernels/test_bf16_skinny_gemm.py +++ b/tests/kernels/test_bf16_skinny_gemm.py @@ -713,8 +713,8 @@ def test_low_latency_table_capability_routing( def test_qwen4_exp_hopper_plans_are_valid() -> None: plans = qwen4_exp_gemm.QWEN4_EXP_SM90_GEMM_PLANS - assert len(plans) == 9 - assert sum(map(len, plans.values())) == 31 + assert len(plans) == 7 + assert sum(map(len, plans.values())) == 24 assert (320, 10240) in plans assert (10240, 320) not in plans for (n, k), shape_plans in plans.items(): @@ -728,10 +728,11 @@ def test_qwen4_exp_hopper_plans_are_valid() -> None: @pytest.mark.parametrize( "capability,expected_plans", [ - ((10, 3), qwen4_exp_gemm.QWEN4_EXP_GEMM_PLANS), + ((10, 3), qwen4_exp_gemm.QWEN4_EXP_SM103_GEMM_PLANS), ((10, 0), qwen4_exp_gemm.QWEN4_EXP_SM100_GEMM_PLANS), ((9, 0), qwen4_exp_gemm.QWEN4_EXP_SM90_GEMM_PLANS), ((12, 1), qwen4_exp_gemm.QWEN4_EXP_SM121_GEMM_PLANS), + ((12, 0), {}), ((8, 0), {}), ], ) @@ -742,11 +743,16 @@ def test_qwen4_exp_gemm_capability_routing( ) -> None: monkeypatch.setattr( qwen4_exp_gemm.current_platform, - "is_device_capability", - lambda target: capability == target, + "get_device_capability", + lambda: capability, ) - assert qwen4_exp_gemm._gemm_plans() == expected_plans + assert ( + qwen4_exp_gemm.QWEN4_EXP_GEMM_PLANS_BY_CAPABILITY.get( + qwen4_exp_gemm.current_platform.get_device_capability(), {} + ) + == expected_plans + ) def test_installation_is_shape_specific_and_unquantized( diff --git a/tests/models/multimodal/generation/test_transformers_audio.py b/tests/models/multimodal/generation/test_transformers_audio.py index 9195579877..230cbc910c 100644 --- a/tests/models/multimodal/generation/test_transformers_audio.py +++ b/tests/models/multimodal/generation/test_transformers_audio.py @@ -69,13 +69,8 @@ AUDIO_MODEL_SETTINGS: dict[str, dict[str, Any]] = { } -@pytest.mark.parametrize("model_id", list(AUDIO_MODEL_SETTINGS)) -def test_transformers_audio_generation( - hf_runner: type[HfRunner], - vllm_runner: type[VllmRunner], - monkeypatch, - model_id: str, -): +@pytest.fixture(autouse=True) +def use_spawn_for_audio_models(monkeypatch): """Single-process workaround for V1 fork safety deadlock issue (vllm-project/vllm/issues/17676). Running multiple audio models together under pytest can cause (possibly flaky) hangs, so they are grouped under @@ -87,6 +82,13 @@ def test_transformers_audio_generation( disable_envs_cache() monkeypatch.setenv("VLLM_WORKER_MULTIPROC_METHOD", "spawn") + +@pytest.mark.parametrize("model_id", list(AUDIO_MODEL_SETTINGS)) +def test_transformers_audio_generation( + hf_runner: type[HfRunner], + vllm_runner: type[VllmRunner], + model_id: str, +): settings = AUDIO_MODEL_SETTINGS[model_id] audio_lora_path = settings.get("audio_lora_path") diff --git a/tests/models/multimodal/generation/test_transformers_video.py b/tests/models/multimodal/generation/test_transformers_video.py new file mode 100644 index 0000000000..bbb31b7be8 --- /dev/null +++ b/tests/models/multimodal/generation/test_transformers_video.py @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project + +from typing import Any + +import pytest +from transformers import AutoModelForImageTextToText + +from vllm.assets.video import VideoAsset +from vllm.envs import disable_envs_cache + +from ....conftest import HfRunner, VllmRunner +from ...utils import check_logprobs_close +from .vlm_utils import model_utils + +VIDEO_ASSET = VideoAsset("baby_reading", num_frames=8) + +VIDEO_MODEL_SETTINGS: dict[str, dict[str, Any]] = { + "Qwen/Qwen3-VL-2B-Instruct": { + "prompt": ( + "<|im_start|>user\n" + "<|vision_start|><|video_pad|><|vision_end|>" + "Describe this video.<|im_end|>\n" + "<|im_start|>assistant\n" + ), + }, + "llava-hf/llava-onevision-qwen2-0.5b-ov-hf": { + "prompt": ( + "<|im_start|>user