@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 01cae37713
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 15, 02:15 UTC

[CI/Build] Ensure compatability with Transformers v4.53 (#20541)

Signed-off-by: Isotr0py <2037008807@qq.com> Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>

Isotr0py committed Jul 12, 2025 at 11:53 UTC 01cae3771384599e887dceea38b078165f23a44e
13 files changed +74 -38
requirements/test.in
+1 -1
@@ -34,7 +34,7 @@ opencv-python-headless >= 4.11.0 # required for video test
34 datamodel_code_generator # required for minicpm3 test
35 lm-eval[api]==0.4.8 # required for model evaluation test
36 mteb[bm25s]>=1.38.11, <2 # required for mteb test
37 -transformers==4.52.4
37 +transformers==4.53.2
38 tokenizers==0.21.1
39 huggingface-hub[hf_xet]>=0.33.0 # Required for Xet downloads.
40 schemathesis>=3.39.15 # Required for openai schema test.
requirements/test.txt
+1 -1
@@ -800,7 +800,7 @@ tqdm==4.66.6
800 # transformers
801 tqdm-multiprocess==0.0.11
802 # via lm-eval
803 -transformers==4.52.4
803 +transformers==4.53.2
804 # via
805 # -r requirements/test.in
806 # genai-perf
tests/models/multimodal/generation/test_common.py
+2 -2
@@ -318,6 +318,7 @@ VLM_TEST_SETTINGS = {
318 num_logprobs=10,
319 image_size_factors=[(), (0.25,), (0.25, 0.25, 0.25), (0.25, 0.2, 0.15)],
320 auto_cls=AutoModelForImageTextToText,
321 + marks=[large_gpu_mark(min_gb=32)],
322 ),
323 "glm4_1v-video": VLMTestInfo(
324 models=["THUDM/GLM-4.1V-9B-Thinking"],
@@ -331,8 +332,7 @@ VLM_TEST_SETTINGS = {
332 inputs=custom_inputs.video_with_metadata_glm4_1v(),
333 limit_mm_per_prompt={"video": 1},
334 )],
334 - # This is needed to run on machine with 24GB VRAM
335 - vllm_runner_kwargs={"gpu_memory_utilization": 0.95},
335 + marks=[large_gpu_mark(min_gb=32)],
336 ),
337 "h2ovl": VLMTestInfo(
338 models = [
tests/models/multimodal/processing/test_common.py
+1
@@ -159,6 +159,7 @@ def _test_processing_correctness(
159 _ADD_SPECIAL_TOKENS_OVERRIDES = {
160 "mllama": False,
161 "ovis": False,
162 + "paligemma": False,
163 "ultravox": False,
164 "whisper": False,
165 }
tests/models/test_initialization.py
+10 -2
@@ -31,7 +31,8 @@ def test_can_initialize(model_arch: str, monkeypatch: pytest.MonkeyPatch):
31 model_info.check_transformers_version(on_fail="skip")
32
33 # FIXME: Possible memory leak in the previous tests?
34 - if model_arch in ("GraniteSpeechForConditionalGeneration",
34 + if model_arch in ("Glm4vForConditionalGeneration",
35 + "GraniteSpeechForConditionalGeneration",
36 "KimiVLForConditionalGeneration"):
37 pytest.skip("Avoid OOM")
38
@@ -46,9 +47,14 @@ def test_can_initialize(model_arch: str, monkeypatch: pytest.MonkeyPatch):
47 n_group = getattr(text_config, 'n_group', None)
48 num_experts = n_group * 2 if n_group is not None else 2
49
50 + # we use three layers for Gemma-3n to check
51 + # both normal layer and kv_shared_layer
52 + num_hidden_layers = (3 if model_arch
53 + == "Gemma3nForConditionalGeneration" else 1)
54 +
55 text_config.update({
56 "num_layers": 1,
51 - "num_hidden_layers": 1,
57 + "num_hidden_layers": num_hidden_layers,
58 "num_experts": num_experts,
59 "num_experts_per_tok": 2,
60 "num_local_experts": num_experts,
@@ -56,6 +62,8 @@ def test_can_initialize(model_arch: str, monkeypatch: pytest.MonkeyPatch):
62 "first_k_dense_replace": 0,
63 # To avoid OOM on DeepSeek-V3
64 "n_routed_experts": num_experts,
65 + # For Gemma-3n
66 + "num_kv_shared_layers": 1,
67 })
68
69 if hasattr(hf_config, "vision_config"):
vllm/inputs/registry.py
+1 -7
@@ -5,9 +5,7 @@ from dataclasses import dataclass
5 from typing import TYPE_CHECKING, Any, NamedTuple, Optional, Union
6
7 import torch
8 -from packaging.version import Version
8 from transformers import BatchFeature, PretrainedConfig, ProcessorMixin
10 -from transformers import __version__ as TRANSFORMERS_VERSION
9 from typing_extensions import TypeVar
10
11 from vllm.jsontree import JSONTree, json_map_leaves
@@ -137,13 +135,9 @@ class InputProcessingContext(InputContext):
135 /,
136 **kwargs: object,
137 ) -> _P:
140 - # Transformers 4.53.0 has issue with passing tokenizer to
141 - # initialize processor. We disable it for this version.
142 - # See: https://github.com/vllm-project/vllm/issues/20224
143 - if Version(TRANSFORMERS_VERSION) != Version("4.53.0"):
144 - kwargs["tokenizer"] = self.tokenizer
138 return super().get_hf_processor(
139 typ,
140 + tokenizer=self.tokenizer,
141 **kwargs,
142 )
143
vllm/model_executor/models/commandr.py
+5 -2
@@ -189,10 +189,13 @@ class CohereAttention(nn.Module):
189
190 layer_idx = extract_layer_index(prefix)
191 layer_has_sliding_window = (
192 - getattr(config, "sliding_window_pattern", False)
193 - and (layer_idx + 1) % self.config.sliding_window_pattern != 0)
192 + getattr(config, "sliding_window_pattern", False) and
193 + (layer_idx + 1) % self.config.sliding_window_pattern
194 + != 0) or (getattr(config, "layer_types", False)
195 + and config.layer_types[layer_idx] == "sliding_attention")
196
197 self.sliding_window = (interleaved_sliding_window
198 + or config.sliding_window
199 if layer_has_sliding_window else None)
200
201 self.attn = Attention(self.num_heads,
vllm/model_executor/models/fuyu.py
+18 -7
@@ -175,12 +175,21 @@ class FuyuMultiModalProcessor(BaseMultiModalProcessor[FuyuProcessingInfo]):
175
176 # Original output: (1, num_images, Pn, Px * Py * C)
177 # New output: (num_images, Pn, Px * Py * C)
178 - assert (isinstance(image_patches, list)
179 - and len(image_patches) == 1)
180 - assert (isinstance(image_patches[0], torch.Tensor)
181 - and len(image_patches[0]) == len(images))
182 -
183 - processed_outputs["image_patches"] = image_patches[0]
178 + # image_patches is a list with shape:
179 + # (1, num_images, Pn, Px * Py * C)
180 + # before Transformers 4.53
181 + if isinstance(image_patches, list):
182 + assert len(image_patches) == 1
183 + assert (isinstance(image_patches[0], torch.Tensor)
184 + and len(image_patches[0]) == len(images))
185 + processed_outputs["image_patches"] = image_patches[0]
186 + # image_patches is a tensor with shape:
187 + # (num_images, Pn, Px * Py * C)
188 + # after Transformers 4.53
189 + elif isinstance(image_patches, torch.Tensor):
190 + assert len(image_patches) == len(images)
191 + else:
192 + raise AssertionError("This line should be unreachable.")
193
194 return processed_outputs
195
@@ -193,8 +202,10 @@ class FuyuMultiModalProcessor(BaseMultiModalProcessor[FuyuProcessingInfo]):
202 vocab = tokenizer.get_vocab()
203
204 boa_token_id = vocab["<0x04>"]
205 + if prompt_tokens[-1] != boa_token_id:
206 + prompt_tokens.append(boa_token_id)
207
197 - return prompt_tokens + [boa_token_id]
208 + return prompt_tokens
209
210 def _get_mm_fields_config(
211 self,
vllm/model_executor/models/gemma3.py
+6 -3
@@ -149,14 +149,17 @@ class Gemma3Attention(nn.Module):
149 # TODO(woosuk): Add reference to the original HF implementation.
150 layer_idx = extract_layer_index(prefix)
151 self.is_sliding = (getattr(
152 - config, "interleaved_sliding_window", None) is not None and bool(
153 - (layer_idx + 1) % config.sliding_window_pattern))
152 + config, "interleaved_sliding_window", None) is not None and (bool(
153 + (layer_idx + 1) % config.sliding_window_pattern))) or (
154 + getattr(config, "layer_types", None) is not None
155 + and config.layer_types[layer_idx] == "sliding_attention")
156 # Initialize the rotary embedding.
157 if self.is_sliding:
158 # Local attention. Override the values in config.json.
159 self.rope_theta = config.rope_local_base_freq
160 self.rope_scaling = {"rope_type": "default"}
159 - self.sliding_window = config.interleaved_sliding_window
161 + self.sliding_window = (config.interleaved_sliding_window
162 + or config.sliding_window)
163 else:
164 # Global attention. Use the values in config.json.
165 self.rope_theta = config.rope_theta
vllm/model_executor/models/minicpmo.py
+11 -10
@@ -30,8 +30,10 @@ import torch
30 from torch import nn
31 from transformers import BatchFeature, PretrainedConfig
32 from transformers.modeling_outputs import BaseModelOutputWithPast
33 -from transformers.models.whisper.modeling_whisper import (
34 - ACT2FN, WHISPER_ATTENTION_CLASSES, WhisperConfig, WhisperEncoder)
33 +from transformers.models.whisper.modeling_whisper import (ACT2FN,
34 + WhisperAttention,
35 + WhisperConfig,
36 + WhisperEncoder)
37
38 from vllm.config import VllmConfig
39 from vllm.model_executor.layers.quantization import QuantizationConfig
@@ -378,14 +380,13 @@ class MiniCPMWhisperEncoderLayer(nn.Module):
380 def __init__(self, config: WhisperConfig, layer_idx: int):
381 super().__init__()
382 self.embed_dim = config.d_model
381 - self.self_attn = WHISPER_ATTENTION_CLASSES[
382 - config._attn_implementation](
383 - embed_dim=self.embed_dim,
384 - num_heads=config.encoder_attention_heads,
385 - dropout=config.attention_dropout,
386 - config=config,
387 - layer_idx=layer_idx,
388 - )
383 + self.self_attn = WhisperAttention(
384 + embed_dim=self.embed_dim,
385 + num_heads=config.encoder_attention_heads,
386 + dropout=config.attention_dropout,
387 + config=config,
388 + layer_idx=layer_idx,
389 + )
390 self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim)
391 self.dropout = config.dropout
392 self.activation_fn = ACT2FN[config.activation_function]
vllm/model_executor/models/paligemma.py
+1 -1
@@ -125,7 +125,7 @@ class PaliGemmaMultiModalProcessor(
125 ) -> BatchFeature:
126 tokenizer = self.info.get_tokenizer()
127 if not mm_data:
128 - prompt_ids = tokenizer.encode(prompt)
128 + prompt_ids = tokenizer.encode(prompt, add_special_tokens=False)
129 return BatchFeature(dict(input_ids=[prompt_ids]), tensor_type="pt")
130
131 return super()._call_hf_processor(
vllm/model_executor/models/qwen2_5_omni_thinker.py
+9 -1
@@ -144,8 +144,16 @@ class Qwen2_5OmniThinkerProcessingInfo(Qwen2AudioProcessingInfo,
144 ) -> Qwen2_5OmniProcessor:
145 if fps is not None:
146 kwargs["fps"] = fps
147 +
148 + # Monkey patch for Transformers v4.53
149 + processor_class = Qwen2_5OmniProcessor
150 + if processor_class.image_processor_class != "AutoImageProcessor":
151 + processor_class.image_processor_class = "AutoImageProcessor"
152 + if processor_class.video_processor_class != "AutoVideoProcessor":
153 + processor_class.video_processor_class = "AutoVideoProcessor"
154 +
155 processor = self.ctx.get_hf_processor(
148 - Qwen2_5OmniProcessor,
156 + processor_class,
157 image_processor=self.get_image_processor(min_pixels=min_pixels,
158 max_pixels=max_pixels,
159 size=size,
vllm/model_executor/models/whisper.py
+8 -1
@@ -634,7 +634,14 @@ class WhisperProcessingInfo(BaseProcessingInfo):
634 def get_hf_processor(self,
635 sampling_rate: Optional[int] = None
636 ) -> WhisperProcessor:
637 - return self.ctx.get_hf_processor(WhisperProcessor)
637 + # HACK: Transformers 4.53.0 has issue with whisper tokenizer to
638 + # initialize processor. We use a monkeypatch to fix it here.
639 + # See: https://github.com/vllm-project/vllm/issues/20224
640 + processor_class = WhisperProcessor
641 + tokenizer_class = ("WhisperTokenizer", "WhisperTokenizerFast")
642 + if processor_class.tokenizer_class != tokenizer_class:
643 + processor_class.tokenizer_class = tokenizer_class
644 + return self.ctx.get_hf_processor(processor_class)
645
646 def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
647 return {"audio": 1}