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 6, 23:00 UTC
[CI] Bump `mypy` version to 1.19.1 (#36104)
Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>
Harry Mellor committed
Mar 10, 2026 at 16:18 UTC
f83b933b84b85ee54121575fc347881b35090616
14 files changed
+77
-36
.pre-commit-config.yaml
+1
-1
@@ -55,7 +55,7 @@ repos:
55
language: python
56
types_or: [python, pyi]
57
require_serial: true
58
- additional_dependencies: ["mypy[faster-cache]==1.15.0", regex, types-cachetools, types-setuptools, types-PyYAML, types-requests, types-torch, pydantic]
58
+ additional_dependencies: ["mypy[faster-cache]==1.19.1", regex, types-cachetools, types-setuptools, types-PyYAML, types-requests, types-torch, pydantic]
59
- id: mypy-3.10 # TODO: Use https://github.com/pre-commit/mirrors-mypy when mypy setup is less awkward
60
name: Run mypy for Python 3.10
61
entry: python tools/pre_commit/mypy.py 1 "3.10"
tests/quantization/test_mixed_precision.py
+1
@@ -8,6 +8,7 @@ Run `pytest tests/quantization/test_mixed_precision.py`.
8
9
import importlib
10
import importlib.metadata
11
+import importlib.util
12
from dataclasses import dataclass
13
14
import lm_eval
vllm/distributed/device_communicators/shm_broadcast.py
+3
@@ -274,6 +274,7 @@ class ShmRingBuffer:
274
self.shared_memory = shared_memory.SharedMemory(
275
create=True, size=self.total_bytes_of_buffer
276
)
277
+ assert self.shared_memory.buf is not None, "Buffer was not created"
278
# initialize the metadata section to 0
279
with self.shared_memory.buf[self.metadata_offset :] as metadata_buffer:
280
torch.frombuffer(metadata_buffer, dtype=torch.uint8).fill_(0)
@@ -325,6 +326,7 @@ class ShmRingBuffer:
326
def get_data(self, current_idx: int):
327
start = self.data_offset + current_idx * self.max_chunk_bytes
328
end = start + self.max_chunk_bytes
329
+ assert self.shared_memory.buf is not None, "Buffer has been closed"
330
with self.shared_memory.buf[start:end] as buf:
331
yield buf
332
@@ -332,6 +334,7 @@ class ShmRingBuffer:
334
def get_metadata(self, current_idx: int):
335
start = self.metadata_offset + current_idx * self.metadata_size
336
end = start + self.metadata_size
337
+ assert self.shared_memory.buf is not None, "Buffer has been closed"
338
with self.shared_memory.buf[start:end] as buf:
339
yield buf
340
vllm/distributed/device_communicators/shm_object_storage.py
+2
@@ -197,6 +197,7 @@ class SingleWriterShmRingBuffer:
197
"""
198
assert self.is_writer, "Only the writer can allocate buffers."
199
assert size > 0, "Size must be greater than 0"
200
+ assert self.shared_memory.buf is not None, "Buffer has been closed"
201
size += self.MD_SIZE # add metadata size to the buffer size
202
# reset to beginning if the buffer does have enough contiguous space
203
buffer_end_reset = self.data_buffer_end % self.data_buffer_size
@@ -239,6 +240,7 @@ class SingleWriterShmRingBuffer:
240
241
@contextmanager
242
def access_buf(self, address: int):
243
+ assert self.shared_memory.buf is not None, "Buffer has been closed"
244
buf_idx = address % self.data_buffer_size
245
246
# read metadata
vllm/distributed/kv_transfer/kv_connector/utils.py
+1
@@ -351,6 +351,7 @@ class TpKVTopology:
351
include_num_layers_dimension=self._cross_layers_blocks
352
)
353
except (AttributeError, NotImplementedError):
354
+ assert self.tensor_shape is not None
355
kv_cache_stride_order = tuple(range(len(self.tensor_shape)))
356
357
# In case of cross layers permute kv_cache_shape according to
vllm/distributed/parallel_state.py
+2
@@ -1964,6 +1964,7 @@ def in_the_same_node_as(
1964
if rank == source_rank:
1965
# create a shared memory segment
1966
shm = shared_memory.SharedMemory(create=True, size=128)
1967
+ assert shm.buf is not None, "Buffer was not created"
1968
shm.buf[: len(magic_message)] = magic_message
1969
if isinstance(pg, ProcessGroup):
1970
torch.distributed.broadcast_object_list(
@@ -1990,6 +1991,7 @@ def in_the_same_node_as(
1991
lambda *args, **kwargs: None,
1992
):
1993
shm = shared_memory.SharedMemory(name=name)
1994
+ assert shm.buf is not None, "Buffer was not opened"
1995
if shm.buf[: len(magic_message)] == magic_message:
1996
is_in_the_same_node[rank] = 1
1997
except Exception as e:
vllm/lora/layers/base.py
+13
-1
@@ -1,7 +1,7 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-from typing import TYPE_CHECKING
4
+from typing import TYPE_CHECKING, overload
5
6
import torch
7
import torch.nn as nn
@@ -14,12 +14,24 @@ if TYPE_CHECKING:
14
15
16
class BaseLayerWithLoRA(nn.Module):
17
+ @overload
18
+ def slice_lora_a(
19
+ self, lora_a: list[torch.Tensor | None]
20
+ ) -> list[torch.Tensor | None]: ...
21
+ @overload
22
+ def slice_lora_a(self, lora_a: torch.Tensor) -> torch.Tensor: ...
23
def slice_lora_a(
24
self, lora_a: torch.Tensor | list[torch.Tensor | None]
25
) -> torch.Tensor | list[torch.Tensor | None]:
26
"""Slice lora a if splitting for tensor parallelism."""
27
...
28
29
+ @overload
30
+ def slice_lora_b(
31
+ self, lora_b: list[torch.Tensor | None]
32
+ ) -> list[torch.Tensor | None]: ...
33
+ @overload
34
+ def slice_lora_b(self, lora_b: torch.Tensor) -> torch.Tensor: ...
35
def slice_lora_b(
36
self, lora_b: torch.Tensor | list[torch.Tensor | None]
37
) -> torch.Tensor | list[torch.Tensor | None]:
vllm/renderers/hf.py
+23
-1
@@ -5,7 +5,7 @@ import itertools
5
from collections import defaultdict, deque
6
from collections.abc import Set
7
from functools import lru_cache
8
-from typing import TYPE_CHECKING, Any, cast
8
+from typing import TYPE_CHECKING, Any, Literal, cast, overload
9
10
import jinja2
11
import jinja2.ext
@@ -439,6 +439,28 @@ def resolve_chat_template_kwargs(
439
return {k: v for k, v in chat_template_kwargs.items() if k in accept_vars}
440
441
442
+@overload
443
+def safe_apply_chat_template(
444
+ model_config: "ModelConfig",
445
+ tokenizer: HfTokenizer,
446
+ conversation: list[ConversationMessage],
447
+ *,
448
+ tools: list[dict[str, Any]] | None = ...,
449
+ chat_template: str | None = ...,
450
+ tokenize: Literal[True] = ...,
451
+ **kwargs,
452
+) -> list[int]: ...
453
+@overload
454
+def safe_apply_chat_template(
455
+ model_config: "ModelConfig",
456
+ tokenizer: HfTokenizer,
457
+ conversation: list[ConversationMessage],
458
+ *,
459
+ tools: list[dict[str, Any]] | None = ...,
460
+ chat_template: str | None = ...,
461
+ tokenize: Literal[False] = ...,
462
+ **kwargs,
463
+) -> str: ...
464
def safe_apply_chat_template(
465
model_config: "ModelConfig",
466
tokenizer: HfTokenizer,
vllm/sampling_params.py
+1
@@ -533,6 +533,7 @@ class SamplingParams(
533
if eos_ids:
534
self._all_stop_token_ids.update(eos_ids)
535
if not self.ignore_eos:
536
+ assert self.stop_token_ids is not None
537
eos_ids.update(self.stop_token_ids)
538
self.stop_token_ids = list(eos_ids)
539
vllm/transformers_utils/configs/funaudiochat.py
+16
-20
@@ -3,7 +3,7 @@
3
4
from __future__ import annotations
5
6
-from transformers import PretrainedConfig
6
+from transformers import CONFIG_MAPPING, PretrainedConfig
7
8
# NOTE: Temporary shim for FunAudioChat checkpoints.
9
# These checkpoints use `model_type="funaudiochat"`, which is not currently
@@ -92,28 +92,24 @@ class FunAudioChatConfig(PretrainedConfig):
92
self.audio_token_index = audio_token_index
93
self.ignore_index = ignore_index
94
95
- if isinstance(audio_config, dict):
96
- audio_config.setdefault(
97
- "model_type", FunAudioChatAudioEncoderConfig.model_type
98
- )
99
- audio_config = FunAudioChatAudioEncoderConfig(**audio_config)
100
- elif audio_config is None:
101
- audio_config = FunAudioChatAudioEncoderConfig()
102
- self.audio_config = audio_config
103
-
104
- if isinstance(text_config, dict):
95
+ if audio_config is None:
96
+ self.audio_config = FunAudioChatAudioEncoderConfig()
97
+ elif isinstance(audio_config, dict):
98
+ default_model_type = FunAudioChatAudioEncoderConfig.model_type
99
+ audio_config.setdefault("model_type", default_model_type)
100
+ self.audio_config = FunAudioChatAudioEncoderConfig(**audio_config)
101
+ else:
102
+ self.audio_config = audio_config
103
+
104
+ if text_config is None:
105
+ self.text_config = CONFIG_MAPPING["qwen2"]()
106
+ elif isinstance(text_config, dict):
107
# Default to qwen2 for backwards compatibility; FunAudioChat uses
108
# qwen3 in practice for recent checkpoints.
109
text_config.setdefault("model_type", "qwen2")
108
- import transformers
109
-
110
- text_cls = transformers.CONFIG_MAPPING[text_config["model_type"]]
111
- text_config = text_cls(**text_config)
112
- elif text_config is None:
113
- import transformers
114
-
115
- text_config = transformers.CONFIG_MAPPING["qwen2"]()
116
- self.text_config = text_config
110
+ self.text_config = CONFIG_MAPPING[text_config["model_type"]](**text_config)
111
+ else:
112
+ self.text_config = text_config
113
114
self.hidden_size = (
115
int(self.text_config.hidden_size)
vllm/transformers_utils/configs/kimi_k25.py
+8
-6
@@ -90,17 +90,19 @@ class KimiK25Config(PretrainedConfig):
90
):
91
# Vision config
92
if vision_config is None:
93
- vision_config = KimiK25VisionConfig()
93
+ self.vision_config = KimiK25VisionConfig()
94
elif isinstance(vision_config, dict):
95
- vision_config = KimiK25VisionConfig(**vision_config)
96
- self.vision_config: KimiK25VisionConfig = vision_config
95
+ self.vision_config = KimiK25VisionConfig(**vision_config)
96
+ else:
97
+ self.vision_config = vision_config
98
99
# Text config
100
if text_config is None:
100
- text_config = DeepseekV3Config()
101
+ self.text_config = DeepseekV3Config()
102
elif isinstance(text_config, dict):
102
- text_config = DeepseekV3Config(**text_config)
103
- self.text_config: DeepseekV3Config = text_config
103
+ self.text_config = DeepseekV3Config(**text_config)
104
+ else:
105
+ self.text_config = text_config
106
107
# Set mm_hidden_size to text hidden size if not explicitly set
108
if self.vision_config.mm_hidden_size == self.vision_config.hidden_size:
vllm/transformers_utils/processors/ovis2_5.py
+1
@@ -412,6 +412,7 @@ class Ovis2_5Processor(ProcessorMixin):
412
images = video
413
else:
414
raise ValueError("Either images or video should be provided.")
415
+ assert images is not None
416
min_pixels = min(
417
max_pixels if max_pixels is not None else MAX_PIXELS,
418
min_pixels if min_pixels is not None else MIN_PIXELS,
vllm/v1/engine/detokenizer.py
+3
-5
@@ -72,14 +72,12 @@ class BaseIncrementalDetokenizer(IncrementalDetokenizer, ABC):
72
# Stop strings
73
params = request.sampling_params
74
assert params is not None
75
- stop_list: list[str]
75
if params.stop is None:
77
- stop_list = []
76
+ self.stop = []
77
elif isinstance(params.stop, str):
79
- stop_list = [params.stop]
78
+ self.stop = [params.stop]
79
else:
81
- stop_list = params.stop
82
- self.stop = stop_list
80
+ self.stop = params.stop
81
self.min_tokens = params.min_tokens
82
self.include_stop_str_in_output = params.include_stop_str_in_output
83
vllm/v1/executor/ray_executor.py
+2
-2
@@ -282,8 +282,8 @@ class RayDistributedExecutor(Executor):
282
# driver_dummy_worker can be None when using ray spmd worker.
283
continue
284
worker_node_and_gpu_ids.append(
285
- ray.get(worker.get_node_and_gpu_ids.remote())
286
- ) # type: ignore[attr-defined]
285
+ ray.get(worker.get_node_and_gpu_ids.remote()) # type: ignore[attr-defined]
286
+ )
287
288
node_workers = defaultdict(list) # node id -> list of worker ranks
289
node_gpus = defaultdict(list) # node id -> list of gpu ids