[MyPy] Fix mypy errors in `vllm/model_executor/models/[kK]*` (#59402)

Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

Harry Mellor committed Oct 1, 2026 at 20:32 UTC 7b44aad5db820f8914810ae9f238ffb871e86d44
10 files changed +106 -100
tools/pre_commit/mypy.py
-8
@@ -109,10 +109,6 @@ SEPARATE_GROUPS = [
109 "tests/v1/worker",
110 ]
111
112 -EXCLUDE = [
113 - r"vllm/model_executor/models/[kK]",
114 -]
115 -
112
113 def group_files(changed_files: list[str]) -> dict[str, list[str]]:
114 """Group changed files into different mypy calls.
@@ -124,16 +120,12 @@ def group_files(changed_files: list[str]) -> dict[str, list[str]]:
120 A dictionary mapping file group names to lists of changed files.
121
122 """
127 - exclude_pattern = re.compile(f"^{'|'.join(EXCLUDE)}.*")
123 silent_pattern = re.compile(f"^({'|'.join(SILENT_GROUPS)}).*")
124 file_groups: dict[str, list[str]] = {"": []}
125 file_groups.update({k: [] for k in SEPARATE_GROUPS})
126 # Longest path first so a sub-directory is not shadowed by its parent
127 separate_groups = sorted(SEPARATE_GROUPS, key=len, reverse=True)
128 for changed_file in changed_files:
134 - # Skip files which should be ignored completely
135 - if exclude_pattern.match(changed_file):
136 - continue
129 # Already-fixed paths go in the default group, which runs at the
130 # stricter follow_imports setting from pyproject.toml
131 if silent_pattern.match(changed_file):
vllm/model_executor/models/k2_horizon.py
+28 -17
@@ -502,6 +502,7 @@ class K2HorizonSparseMoeBlock(nn.Module):
502 self.gate.bias = nn.Parameter(self.gate.bias.float(), requires_grad=False)
503
504 self.num_shared_experts = config.num_shared_experts
505 + self.shared_experts: K2HorizonMLP | None
506 if config.num_shared_experts > 0:
507 self.shared_experts = K2HorizonMLP(
508 hidden_size=config.hidden_size,
@@ -644,6 +645,14 @@ class K2HorizonAttention(nn.Module):
645 rope_parameters=rope_parameters,
646 dual_chunk_attention_config=dual_chunk_attention_config,
647 )
648 + attn_kwargs: dict[str, Any] = (
649 + {
650 + "layer_idx": extract_layer_index(prefix),
651 + "dual_chunk_attention_config": dual_chunk_attention_config,
652 + }
653 + if dual_chunk_attention_config
654 + else {}
655 + )
656 self.attn = Attention(
657 self.num_heads,
658 self.head_dim,
@@ -652,12 +661,7 @@ class K2HorizonAttention(nn.Module):
661 cache_config=cache_config,
662 quant_config=quant_config,
663 prefix=f"{prefix}.attn",
655 - **{
656 - "layer_idx": extract_layer_index(prefix),
657 - "dual_chunk_attention_config": dual_chunk_attention_config,
658 - }
659 - if dual_chunk_attention_config
660 - else {},
664 + **attn_kwargs,
665 )
666
667 self.query_key_norm = query_key_norm
@@ -842,6 +846,14 @@ class K2HorizonMoVAAttention(nn.Module):
846 rope_parameters=rope_parameters,
847 dual_chunk_attention_config=dual_chunk_attention_config,
848 )
849 + attn_kwargs: dict[str, Any] = (
850 + {
851 + "layer_idx": extract_layer_index(prefix),
852 + "dual_chunk_attention_config": dual_chunk_attention_config,
853 + }
854 + if dual_chunk_attention_config
855 + else {}
856 + )
857 self.attn = Attention(
858 self.num_heads,
859 self.head_dim,
@@ -850,12 +862,7 @@ class K2HorizonMoVAAttention(nn.Module):
862 cache_config=cache_config,
863 quant_config=quant_config,
864 prefix=f"{prefix}.attn",
853 - **{
854 - "layer_idx": extract_layer_index(prefix),
855 - "dual_chunk_attention_config": dual_chunk_attention_config,
856 - }
857 - if dual_chunk_attention_config
858 - else {},
865 + **attn_kwargs,
866 )
867
868 self.query_key_norm = query_key_norm
@@ -1228,9 +1235,10 @@ class K2HorizonModel(nn.Module, EagleModelMixin):
1235 expert_params_mapping = self.get_expert_mapping()
1236 for name, loaded_weight in weights:
1237 if "scale" in name or "zero_point" in name:
1231 - name = maybe_remap_kv_scale_name(name, params_dict)
1232 - if name is None:
1238 + remapped_name = maybe_remap_kv_scale_name(name, params_dict)
1239 + if remapped_name is None:
1240 continue
1241 + name = remapped_name
1242
1243 # QK norm weights
1244 if name.endswith(".self_attn.q_norm.weight") or name.endswith(
@@ -1267,7 +1275,9 @@ class K2HorizonModel(nn.Module, EagleModelMixin):
1275 kv_rank
1276 ]
1277
1270 - weight_loader = getattr(param, "weight_loader", default_weight_loader)
1278 + weight_loader: Callable[..., Any] = getattr(
1279 + param, "weight_loader", default_weight_loader
1280 + )
1281 weight_loader(param, loaded_weight)
1282 loaded_params.add(name)
1283 continue
@@ -1380,9 +1390,10 @@ class K2HorizonModel(nn.Module, EagleModelMixin):
1390 continue
1391 if name.endswith("scale"):
1392 # Remapping the name of FP8 kv-scale.
1383 - name = maybe_remap_kv_scale_name(name, params_dict)
1384 - if name is None:
1393 + remapped_name = maybe_remap_kv_scale_name(name, params_dict)
1394 + if remapped_name is None:
1395 continue
1396 + name = remapped_name
1397 if name not in params_dict:
1398 continue
1399
vllm/model_executor/models/kanana_v.py
+16 -15
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable, Mapping, Sequence
4 from functools import partial
5 -from typing import Annotated, Literal, TypeAlias
5 +from typing import Annotated, Any, Literal, TypeAlias, cast
6
7 import numpy as np
8 import regex as re
@@ -288,7 +288,7 @@ class CustomQwen2VLVE(Qwen2VisionTransformer):
288 """Drop-in replacement for the HF `_from_config` constructor."""
289 return cls(config)
290
291 - def forward(
291 + def forward( # type: ignore[override]
292 self,
293 pixel_values: torch.Tensor,
294 grid_thw: torch.Tensor,
@@ -331,12 +331,12 @@ class CustomQwen2VLVE(Qwen2VisionTransformer):
331 # Pre-compute seqlens for attention backend.
332 max_seqlen = self.compute_attn_mask_seqlen(cu_seqlens)
333
334 - encoder_states = () if output_hidden_states else None
334 + encoder_states: tuple[torch.Tensor, ...] = ()
335
336 for blk in self.blocks:
337 if output_hidden_states:
338 # Store patch-level states (S, D).
339 - encoder_states = encoder_states + (x.squeeze(1),)
339 + encoder_states += (x.squeeze(1),)
340
341 x = blk(
342 x,
@@ -348,14 +348,15 @@ class CustomQwen2VLVE(Qwen2VisionTransformer):
348
349 # Final hidden state at patch level (S, D).
350 hidden_states = x.squeeze(1)
351 + all_hidden_states = None
352 if output_hidden_states:
352 - encoder_states = encoder_states + (hidden_states,)
353 + all_hidden_states = encoder_states + (hidden_states,)
354
355 if not return_dict:
355 - return tuple(v for v in [hidden_states, encoder_states] if v is not None)
356 + return tuple(v for v in [hidden_states, all_hidden_states] if v is not None)
357 return BaseModelOutput(
358 last_hidden_state=hidden_states,
358 - hidden_states=encoder_states,
359 + hidden_states=all_hidden_states,
360 )
361
362 def get_num_tokens(self) -> int:
@@ -479,7 +480,7 @@ class KananaVMultiModalProcessor(BaseMultiModalProcessor[KananaVProcessingInfo])
480 assert isinstance(prompt_text, str)
481
482 # Images
482 - image_inputs = hf_data.get("images", [])
483 + image_inputs = cast(list[Any], hf_data.get("images", []))
484 pixel_sizes = []
485 if not isinstance(image_inputs[0], Image.Image):
486 image_inputs = [Image.fromarray(image) for image in image_inputs]
@@ -487,9 +488,9 @@ class KananaVMultiModalProcessor(BaseMultiModalProcessor[KananaVProcessingInfo])
488 image_processor = self.info.get_hf_processor().image_processor
489 processor_output = [image_processor(image) for image in image_inputs]
490 pixel_values = [o["pixel_values"] for o in processor_output]
490 - image_meta = [o["image_meta"] for o in processor_output]
491 + image_meta_list = [o["image_meta"] for o in processor_output]
492 # list of dict -> dict of list
492 - image_meta = {k: [d[k] for d in image_meta] for k in image_meta[0]}
493 + image_meta = {k: [d[k] for d in image_meta_list] for k in image_meta_list[0]}
494
495 for pixel_value in pixel_values:
496 pixel_sizes.append(pixel_value.shape[0])
@@ -545,7 +546,7 @@ class KananaVMultiModalProcessor(BaseMultiModalProcessor[KananaVProcessingInfo])
546 ) -> Sequence[PromptUpdate]:
547 tokenizer = self.info.get_tokenizer()
548
548 - def get_replacement(idx: int) -> Sequence[int]:
549 + def get_replacement(idx: int) -> list[int]:
550 out_item = out_mm_kwargs["image"][idx]
551 image_token_thw = out_item["image_token_thw"].data
552 assert isinstance(image_token_thw, torch.Tensor)
@@ -683,7 +684,7 @@ class KananaVForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
684 def _get_visual_feature_at(
685 self,
686 v_output: Sequence[torch.Tensor],
686 - layer_index: int | Sequence[int],
687 + layer_index: int | list[int] | tuple[int, ...],
688 ) -> torch.Tensor:
689 if isinstance(layer_index, (list, tuple)):
690 visual_features = torch.stack(v_output, dim=1)[
@@ -696,7 +697,7 @@ class KananaVForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
697 def forward_vision(
698 self,
699 pixel_values: torch.Tensor,
699 - image_metas: dict | None = None,
700 + image_metas: dict,
701 ) -> torch.Tensor:
702 vision_model_args = {
703 "pixel_values": pixel_values,
@@ -714,7 +715,7 @@ class KananaVForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
715 def forward_projector(
716 self,
717 visual_features: torch.Tensor,
717 - image_metas: dict | None = None,
718 + image_metas: dict,
719 ) -> torch.Tensor:
720 visual_embeds = self.abstractor(
721 visual_features,
@@ -725,7 +726,7 @@ class KananaVForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
726 def forward_and_project_vision(
727 self,
728 pixel_values: torch.Tensor,
728 - image_metas: dict | None = None,
729 + image_metas: dict,
730 ) -> torch.Tensor:
731 assert pixel_values is not None
732 visual_features = self.forward_vision(pixel_values, image_metas=image_metas)
vllm/model_executor/models/keye.py
+29 -34
@@ -208,8 +208,8 @@ class KeyeVisionEmbeddings(nn.Module):
208
209 self.num_patches = (self.image_size // self.patch_size) ** 2
210 self.num_positions = self.num_patches
211 - self.cache_position_embedding = dict()
212 - self.cache_position_count = dict()
211 + self.cache_position_embedding: dict[tuple[int, int], torch.Tensor] = {}
212 + self.cache_position_count: dict[tuple[int, int], int] = {}
213 self.position_embedding = nn.Embedding(self.num_positions, self.embed_dim)
214 self.packing_position_embedding = nn.Embedding(32768, self.embed_dim)
215
@@ -264,7 +264,7 @@ class KeyeVisionEmbeddings(nn.Module):
264 if len(self.cache_position_embedding) >= max_cache:
265 min_hit_grid = min(
266 self.cache_position_count,
267 - key=self.cache_position_count.get,
267 + key=self.cache_position_count.__getitem__,
268 )
269 self.cache_position_count.pop(min_hit_grid)
270 self.cache_position_embedding.pop(min_hit_grid)
@@ -278,8 +278,7 @@ class KeyeVisionEmbeddings(nn.Module):
278 self,
279 pixel_values: torch.FloatTensor,
280 position_ids: torch.Tensor | None = None,
281 - image_grid_thw: list[tuple[int, int, int] | list[tuple[int, int, int]]]
282 - | None = None,
281 + image_grid_thw: list[tuple[int, int, int]] | None = None,
282 interpolate_pos_encoding=False,
283 ) -> torch.Tensor:
284 if pixel_values.dim() == 4:
@@ -408,7 +407,7 @@ class KeyeSiglipAttention(nn.Module):
407 hidden_states: torch.Tensor,
408 attention_mask: torch.Tensor | None = None,
409 output_attentions: bool | None = False,
411 - cu_seqlens: list[torch.Tensor] | None = None,
410 + cu_seqlens: torch.Tensor | None = None,
411 rope_emb: tuple[torch.Tensor, torch.Tensor] | None = None,
412 ) -> torch.Tensor:
413 qkv, _ = self.qkv_proj(hidden_states)
@@ -417,6 +416,8 @@ class KeyeSiglipAttention(nn.Module):
416 dim=-1,
417 )
418
419 + if cu_seqlens is None:
420 + raise ValueError("cu_seqlens cannot be None.")
421 max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max()
422
423 if rope_emb is None:
@@ -432,8 +433,6 @@ class KeyeSiglipAttention(nn.Module):
433 self.head_dim,
434 )
435 else:
435 - if cu_seqlens is None:
436 - raise ValueError("cu_seqlens cannot be None when rope_emb is not None.")
436 cos, sin = rope_emb
437 q = q.view(*q.shape[:-1], self.num_heads, self.head_dim)
438 k = k.view(
@@ -511,7 +510,7 @@ class KeyeSiglipEncoderLayer(nn.Module):
510 hidden_states: torch.Tensor,
511 attention_mask: torch.Tensor,
512 output_attentions: bool | None = False,
514 - cu_seqlens: list[torch.Tensor] | None = None,
513 + cu_seqlens: torch.Tensor | None = None,
514 rope_emb: tuple[torch.Tensor, torch.Tensor] | None = None,
515 ) -> tuple[torch.FloatTensor]:
516 residual = hidden_states
@@ -576,13 +575,12 @@ class KeyeSiglipEncoder(nn.Module):
575 attention_mask: torch.Tensor | None = None,
576 output_attentions: bool | None = None,
577 output_hidden_states: bool | None = None,
579 - cu_seqlens: list[torch.Tensor] | None = None,
580 - image_grid_thw: list[tuple[int, int, int] | list[tuple[int, int, int]]]
581 - | None = None,
578 + cu_seqlens: torch.Tensor | None = None,
579 + image_grid_thw: list[tuple[int, int, int]] | None = None,
580 height_position_ids: torch.Tensor | None = None,
581 width_position_ids: torch.Tensor | None = None,
582 use_rope: bool | None = False,
585 - window_size: bool | None = -1,
583 + window_size: int = -1,
584 vision_or_text: str = "vision",
585 ) -> BaseModelOutput:
586 device = inputs_embeds.device
@@ -662,14 +660,13 @@ class KeyeSiglipVisionTransformer(nn.Module):
660 position_ids: torch.Tensor | None = None,
661 height_position_ids: torch.Tensor | None = None,
662 width_position_ids: torch.Tensor | None = None,
665 - cu_seqlens: list[torch.Tensor] | None = None,
663 + cu_seqlens: torch.Tensor | None = None,
664 padding_mask: torch.Tensor | None = None,
665 vision_return_embed_list: bool | None = False,
668 - image_grid_thw: list[tuple[int, int, int] | list[tuple[int, int, int]]]
669 - | None = None,
666 + image_grid_thw: list[tuple[int, int, int]] | None = None,
667 return_pooler_output: bool | None = True,
668 use_rope: bool | None = False,
672 - window_size: bool | None = -1,
669 + window_size: int = -1,
670 ) -> BaseModelOutputWithPooling:
671 hidden_states = self.embeddings(
672 pixel_values,
@@ -757,12 +754,11 @@ class KeyeSiglipVisionModel(nn.Module):
754 interpolate_pos_encoding: bool = False,
755 position_ids: torch.Tensor | None = None,
756 vision_return_embed_list: bool | None = False,
760 - image_grid_thw: list[tuple[int, int, int] | list[tuple[int, int, int]]]
761 - | None = None,
762 - cu_seqlens: list[torch.Tensor] | None = None,
757 + image_grid_thw: list[tuple[int, int, int]] | None = None,
758 + cu_seqlens: torch.Tensor | None = None,
759 return_pooler_output: bool | None = True,
760 use_rope: bool | None = False,
765 - window_size: bool | None = -1,
761 + window_size: int = -1,
762 ) -> BaseModelOutputWithPooling:
763 return self.vision_model(
764 pixel_values=pixel_values,
@@ -1337,7 +1333,7 @@ class BaseKeyeModule(nn.Module, SupportsMultiModal):
1333 def _process_video_embeds(
1334 self,
1335 video_type: Literal["video_embeds", "pixel_values_videos"],
1340 - video_grid_thw: list[torch.Tensor],
1336 + video_grid_thw: torch.Tensor,
1337 pixel_values_videos: torch.Tensor | None = None,
1338 ) -> torch.Tensor | list[torch.Tensor]:
1339 siglip_position_ids = list()
@@ -1361,6 +1357,7 @@ class BaseKeyeModule(nn.Module, SupportsMultiModal):
1357 "Video embeddings are not supported for this processing path."
1358 )
1359 else:
1360 + assert pixel_values_videos is not None
1361 pixel_values_videos = pixel_values_videos.type(self.visual.dtype)
1362 # These are host-built; concat straight into pinned buffers so
1363 # the H2D copies stay non-blocking.
@@ -1535,12 +1532,11 @@ class KeyeForConditionalGeneration(
1532 image_grid_thw=image_grid_thw,
1533 )
1534
1538 - if image_embeds is not None:
1539 - return KeyeImageEmbeddingInputs(
1540 - type="image_embeds",
1541 - image_embeds=image_embeds,
1542 - image_grid_thw=image_grid_thw,
1543 - )
1535 + return KeyeImageEmbeddingInputs(
1536 + type="image_embeds",
1537 + image_embeds=image_embeds,
1538 + image_grid_thw=image_grid_thw,
1539 + )
1540
1541 def _parse_and_validate_video_input(
1542 self, **kwargs: object
@@ -1559,12 +1555,11 @@ class KeyeForConditionalGeneration(
1555 video_grid_thw=video_grid_thw,
1556 )
1557
1562 - if video_embeds is not None:
1563 - return KeyeVideoEmbeddingInputs(
1564 - type="video_embeds",
1565 - video_embeds=video_embeds,
1566 - video_grid_thw=video_grid_thw,
1567 - )
1558 + return KeyeVideoEmbeddingInputs(
1559 + type="video_embeds",
1560 + video_embeds=video_embeds,
1561 + video_grid_thw=video_grid_thw,
1562 + )
1563
1564 def _process_video_input(
1565 self, video_input: KeyeVideoInputs
vllm/model_executor/models/keye_vl1_5.py
+13 -15
@@ -75,7 +75,7 @@ def split_thw(grid_thw: torch.Tensor) -> torch.Tensor:
75
76 def get_num_patches(
77 grid_thw: torch.Tensor, num_frames: list[int] | torch.Tensor
78 -) -> list[int]:
78 +) -> torch.Tensor:
79 """Return num_patches per video.
80
81 Args:
@@ -84,7 +84,7 @@ def get_num_patches(
84 num_frames: List or tensor indicating the number of frames per video
85
86 Returns:
87 - List of ints representing the number of patches for each video
87 + Tensor of the number of patches for each video
88
89 Examples:
90 >>> # Suppose there are 2 videos with a total of 3 grids
@@ -538,12 +538,11 @@ class KeyeVL1_5ForConditionalGeneration(
538 image_grid_thw=image_grid_thw,
539 )
540
541 - if image_embeds is not None:
542 - return KeyeVL1_5ImageEmbeddingInputs(
543 - type="image_embeds",
544 - image_embeds=image_embeds,
545 - image_grid_thw=image_grid_thw,
546 - )
541 + return KeyeVL1_5ImageEmbeddingInputs(
542 + type="image_embeds",
543 + image_embeds=image_embeds,
544 + image_grid_thw=image_grid_thw,
545 + )
546
547 def _parse_and_validate_video_input(
548 self, **kwargs: object
@@ -564,13 +563,12 @@ class KeyeVL1_5ForConditionalGeneration(
563 num_frames=num_frames,
564 )
565
567 - if video_embeds is not None:
568 - return KeyeVL1_5VideoEmbeddingInputs(
569 - type="video_embeds",
570 - video_embeds=video_embeds,
571 - video_grid_thw=video_grid_thw,
572 - num_frames=num_frames,
573 - )
566 + return KeyeVL1_5VideoEmbeddingInputs(
567 + type="video_embeds",
568 + video_embeds=video_embeds,
569 + video_grid_thw=video_grid_thw,
570 + num_frames=num_frames,
571 + )
572
573 def _process_video_input(
574 self, video_input: KeyeVL1_5VideoInputs
vllm/model_executor/models/kimi_audio.py
+3 -1
@@ -18,6 +18,7 @@ from vllm.config.speech_to_text import SpeechToTextParams
18 from vllm.inputs import PromptType, TokensPrompt
19 from vllm.model_executor.model_loader import DefaultModelLoader
20 from vllm.model_executor.models.interfaces import (
21 + MultiModalEmbeddings,
22 SupportsMultiModal,
23 SupportsPP,
24 SupportsTranscription,
@@ -240,6 +241,7 @@ class KimiAudioMultiModalProcessor(BaseMultiModalProcessor[KimiAudioProcessingIn
241 # KimiAudioProcessor expects raw numpy arrays
242 mm_data = hf_inputs.hf_data
243 if audios := mm_data.pop("audio", []):
244 + assert isinstance(audios, Sequence)
245 audio_arrays = []
246 for aud in audios:
247 if isinstance(aud, (tuple, list)) and len(aud) == 2:
@@ -485,7 +487,7 @@ class KimiAudioForConditionalGeneration(
487 def embed_input_ids(
488 self,
489 input_ids: torch.Tensor,
488 - multimodal_embeddings: tuple[torch.Tensor, ...] | None = None,
490 + multimodal_embeddings: MultiModalEmbeddings | None = None,
491 *,
492 is_multimodal: torch.Tensor | None = None,
493 ) -> torch.Tensor:
vllm/model_executor/models/kimi_k25.py
+12 -6
@@ -136,9 +136,9 @@ class KimiK25ProcessingInfo(BaseProcessingInfo):
136 # may remap token IDs vs config.json.
137 config_token_id = hf_config.media_placeholder_token_id
138 resolved_token_id = tokenizer.convert_tokens_to_ids("<|media_pad|>")
139 + unk_token_id = getattr(tokenizer, "unk_token_id", None)
140 is_valid_resolved = isinstance(resolved_token_id, int) and (
140 - tokenizer.unk_token_id is None
141 - or resolved_token_id != tokenizer.unk_token_id
141 + unk_token_id is None or resolved_token_id != unk_token_id
142 )
143 if is_valid_resolved and resolved_token_id != config_token_id:
144 logger.warning_once(
@@ -165,7 +165,7 @@ class KimiK25ProcessingInfo(BaseProcessingInfo):
165 )
166 self.media_tokens_calculator = image_processor.media_tokens_calculator
167
168 - def get_hf_processor(self):
168 + def get_hf_processor(self, **kwargs: object):
169 return self.hf_processor
170
171 def get_hf_config(self):
@@ -191,7 +191,11 @@ class KimiK25DummyInputsBuilder(BaseDummyInputsBuilder[KimiK25ProcessingInfo]):
191 )
192
193 video_chunk_dummy_item = VisionChunkVideo(
194 - type="video_chunk", video_chunk=dummy_videos
194 + type="video_chunk",
195 + video_chunk=dummy_videos,
196 + uuid=None,
197 + prompt="",
198 + video_idx=0,
199 )
200 video_chunk_num_tokens = self.info.media_tokens_calculator(
201 video_chunk_dummy_item
@@ -204,6 +208,7 @@ class KimiK25DummyInputsBuilder(BaseDummyInputsBuilder[KimiK25ProcessingInfo]):
208 width=MaxImageTokenMeta.width,
209 num_images=1,
210 )[0],
211 + uuid=None,
212 )
213 image_num_tokens = self.info.media_tokens_calculator(image_dummy_item)
214 # return the larger one
@@ -377,7 +382,7 @@ class KimiK25ForConditionalGeneration(
382 )
383 self.media_placeholder: int = self.config.media_placeholder_token_id
384
380 - def _maybe_ignore_quant_config(self, quant_config: QuantizationConfig):
385 + def _maybe_ignore_quant_config(self, quant_config: QuantizationConfig | None):
386 if isinstance(quant_config, compressed_tensors.CompressedTensorsConfig):
387 return None
388 return quant_config
@@ -392,6 +397,7 @@ class KimiK25ForConditionalGeneration(
397
398 if isinstance(pixel_values, list):
399 pixel_values = torch.cat(pixel_values, dim=0)
400 + assert isinstance(pixel_values, torch.Tensor)
401
402 if len(pixel_values.shape) == 5 or len(pixel_values.shape) == 3:
403 pixel_values = pixel_values.reshape(
@@ -612,7 +618,7 @@ class KimiK25ForConditionalGeneration(
618
619 grid_thw_list = [[1, ho * kh, wo * kw] for _ in range(max_batch_size)]
620
615 - ps = self.vision_tower.patch_size
621 + ps: int | tuple[int, int] = self.vision_tower.patch_size
622 if isinstance(ps, int):
623 ps = (ps, ps)
624 total_patches = max_batch_size * ho * kh * wo * kw
vllm/model_executor/models/kimi_k25_vit.py
+1 -1
@@ -804,7 +804,7 @@ class MoonViT3dPretrainedModel(nn.Module):
804 self,
805 grid_thw_list: list[list[int]],
806 *,
807 - max_batch_size: int,
807 + max_batch_size: int | None,
808 max_seqlen_override: int | None = None,
809 device: torch.device,
810 ) -> dict[str, torch.Tensor | None]:
vllm/model_executor/models/kimi_vl.py
+3 -2
@@ -268,6 +268,7 @@ class KimiVLMultiModalProcessor(BaseMultiModalProcessor[KimiVLProcessingInfo]):
268 if isinstance(images, ImageEmbeddingItems):
269 num_image_tokens = images.get_feature_size(item_idx)
270 else:
271 + assert isinstance(images, ImageProcessorItems)
272 image_size = images.get_image_size(item_idx)
273 num_image_tokens = self.info.get_num_image_tokens(
274 image_width=image_size.width,
@@ -317,7 +318,7 @@ class KimiVLForConditionalGeneration(
318
319 assert isinstance(config.vision_config, MoonViTConfig)
320 self.use_data_parallel = (
320 - model_config.multimodal_config.mm_encoder_tp_mode == "data"
321 + model_config.get_multimodal_config().mm_encoder_tp_mode == "data"
322 )
323 self.hidden_size = config.text_config.hidden_size
324
@@ -469,7 +470,7 @@ class KimiVLForConditionalGeneration(
470 )
471 grid_hws_list = [(ho * kh, wo * kw) for _ in range(max_batch_size)]
472
472 - patch_size = self.config.vision_config.patch_size
473 + patch_size: int | tuple[int, int] = self.config.vision_config.patch_size
474 if isinstance(patch_size, int):
475 patch_size = (patch_size, patch_size)
476
vllm/transformers_utils/configs/kimi_vl.py
+1 -1
@@ -30,7 +30,7 @@ class KimiVLConfig(PreTrainedConfig):
30 text_config = DeepseekV2Config()
31 elif isinstance(text_config, dict):
32 text_config = DeepseekV2Config(**text_config)
33 - self.text_config = text_config
33 + self.text_config: DeepseekV2Config = text_config
34
35 self.ignore_index = ignore_index
36 self.media_placeholder_token_id = media_placeholder_token_id