@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 56669c1f29
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 12, 19:45 UTC

[CI] Fix mypy for `vllm/v1/worker` (#29037)

Signed-off-by: yewentao256 <zhyanwentao@126.com>

Wentao Ye committed Nov 20, 2025 at 22:36 UTC 56669c1f293d5c53b6a19ddf2f78802fa9fff2c2
13 files changed +180 -104
tools/pre_commit/mypy.py
+1 -1
@@ -38,6 +38,7 @@ FILES = [
38 "vllm/usage",
39 "vllm/v1/core",
40 "vllm/v1/engine",
41 + "vllm/v1/worker",
42 ]
43
44 # After fixing errors resulting from changing follow_imports
@@ -62,7 +63,6 @@ SEPARATE_GROUPS = [
63 "vllm/v1/sample",
64 "vllm/v1/spec_decode",
65 "vllm/v1/structured_output",
65 - "vllm/v1/worker",
66 ]
67
68 # TODO(woosuk): Include the code from Megatron and HuggingFace.
vllm/model_executor/utils.py
+1 -1
@@ -10,7 +10,7 @@ import torch
10 from vllm.utils.torch_utils import is_torch_equal_or_newer
11
12
13 -def set_random_seed(seed: int) -> None:
13 +def set_random_seed(seed: int | None) -> None:
14 from vllm.platforms import current_platform
15
16 current_platform.seed_everything(seed)
vllm/multimodal/utils.py
+2 -2
@@ -3,7 +3,7 @@
3
4 import asyncio
5 import atexit
6 -from collections.abc import Iterable, Set
6 +from collections.abc import Generator, Set
7 from concurrent.futures import ThreadPoolExecutor
8 from itertools import groupby
9 from pathlib import Path
@@ -403,7 +403,7 @@ def group_mm_kwargs_by_modality(
403 pin_memory: bool = False,
404 merge_by_field_config: bool | None = None,
405 multimodal_cpu_fields: Set[str] = frozenset(),
406 -) -> Iterable[tuple[str, int, BatchedTensorInputs]]:
406 +) -> Generator[tuple[str, int, BatchedTensorInputs], None, None]:
407 """Group consecutive `MultiModalKwargsItem`s from `mm_kwargs` with the same
408 modality together into the same `MultiModalKwargs` instance.
409
vllm/v1/worker/cpu_worker.py
+8 -4
@@ -3,6 +3,7 @@
3 import os
4 import platform
5 from collections.abc import Callable
6 +from typing import Any
7
8 import torch
9
@@ -37,6 +38,9 @@ class CPUWorker(Worker):
38
39 self.parallel_config.disable_custom_all_reduce = True
40
41 + # Torch profiler. Enabled and configured through env vars:
42 + # VLLM_TORCH_PROFILER_DIR=/path/to/save/trace
43 + self.profiler: Any | None = None
44 if envs.VLLM_TORCH_PROFILER_DIR:
45 torch_profiler_trace_dir = envs.VLLM_TORCH_PROFILER_DIR
46 worker_name = f"{vllm_config.instance_id}-rank-{self.rank}"
@@ -80,13 +84,13 @@ class CPUWorker(Worker):
84 self.local_omp_cpuid = "nobind"
85 else:
86 local_dp_rank = self.parallel_config.data_parallel_rank_local
83 - omp_cpuids = omp_cpuids.split("|")
87 + omp_cpuids_list = omp_cpuids.split("|")
88 if local_dp_rank is not None:
89 world_size = self.parallel_config.world_size
86 - omp_cpuids = omp_cpuids[
90 + omp_cpuids_list = omp_cpuids_list[
91 local_dp_rank * world_size : (local_dp_rank + 1) * world_size
92 ]
89 - self.local_omp_cpuid = omp_cpuids[self.rank]
93 + self.local_omp_cpuid = omp_cpuids_list[self.rank]
94
95 if self.local_omp_cpuid != "nobind":
96 ret = torch.ops._C_utils.init_cpu_threads_env(self.local_omp_cpuid)
@@ -120,7 +124,7 @@ class CPUWorker(Worker):
124 pass
125
126 def determine_available_memory(self) -> int:
123 - return self.cache_config.cpu_kvcache_space_bytes # type: ignore
127 + return self.cache_config.cpu_kvcache_space_bytes or 0
128
129 def compile_or_warm_up_model(self) -> None:
130 # Reset the seed to ensure that the random state is not affected by
vllm/v1/worker/gpu_model_runner.py
+82 -46
@@ -5,7 +5,7 @@ import gc
5 import itertools
6 import time
7 from collections import defaultdict
8 -from collections.abc import Iterator
8 +from collections.abc import Iterator, Sequence
9 from contextlib import contextmanager
10 from copy import copy, deepcopy
11 from functools import reduce
@@ -53,6 +53,7 @@ from vllm.model_executor.layers.attention_layer_base import AttentionLayerBase
53 from vllm.model_executor.layers.rotary_embedding import MRotaryEmbedding
54 from vllm.model_executor.model_loader import TensorizerLoader, get_model_loader
55 from vllm.model_executor.models.interfaces import (
56 + SupportsMRoPE,
57 SupportsMultiModal,
58 is_mixture_of_experts,
59 supports_eagle3,
@@ -126,6 +127,7 @@ from vllm.v1.outputs import (
127 )
128 from vllm.v1.pool.metadata import PoolingMetadata
129 from vllm.v1.sample.logits_processor import LogitsProcessors, build_logitsprocs
130 +from vllm.v1.sample.logits_processor.interface import LogitsProcessor
131 from vllm.v1.sample.metadata import SamplingMetadata
132 from vllm.v1.sample.rejection_sampler import RejectionSampler
133 from vllm.v1.sample.sampler import Sampler
@@ -404,7 +406,10 @@ class GPUModelRunner(
406 # solution, we initialize the input batch here, and re-initialize it
407 # in `initialize_kv_cache` if the block_sizes here is different from
408 # the block_sizes in the kv cache config.
407 - custom_logitsprocs = model_config.logits_processors
409 + logits_processors = model_config.logits_processors
410 + custom_logitsprocs: Sequence[str | type[LogitsProcessor]] = (
411 + tuple(logits_processors) if logits_processors is not None else ()
412 + )
413 self.input_batch = InputBatch(
414 max_num_reqs=self.max_num_reqs,
415 # We need to use the encoder length for encoder-decoer
@@ -959,9 +964,13 @@ class GPUModelRunner(
964 def _init_mrope_positions(self, req_state: CachedRequestState):
965 model = self.get_model()
966 assert supports_mrope(model), "M-RoPE support is not implemented."
967 + assert req_state.prompt_token_ids is not None, (
968 + "M-RoPE requires prompt_token_ids to be available."
969 + )
970 + mrope_model = cast(SupportsMRoPE, model)
971
972 req_state.mrope_positions, req_state.mrope_position_delta = (
964 - model.get_mrope_input_positions(
973 + mrope_model.get_mrope_input_positions(
974 req_state.prompt_token_ids,
975 req_state.mm_features,
976 )
@@ -1762,6 +1771,7 @@ class GPUModelRunner(
1771 dst_start = mrope_pos_ptr
1772 dst_end = mrope_pos_ptr + completion_part_len
1773
1774 + assert req.mrope_position_delta is not None
1775 MRotaryEmbedding.get_next_input_positions_tensor(
1776 out=self.mrope_positions.np,
1777 out_offset=dst_start,
@@ -1907,6 +1917,8 @@ class GPUModelRunner(
1917
1918 for mm_input_id in encoder_input_ids:
1919 mm_feature = req_state.mm_features[mm_input_id]
1920 + if mm_feature.data is None:
1921 + continue
1922 mm_hash = mm_feature.identifier
1923 mm_kwargs.append(mm_feature.data)
1924 mm_hashes_pos.append((mm_hash, mm_feature.mm_position))
@@ -1930,7 +1942,7 @@ class GPUModelRunner(
1942 # multimodal inputs. The proper solution should be reordering the
1943 # encoder outputs.
1944 model = cast(SupportsMultiModal, self.model)
1933 - encoder_outputs = []
1945 + encoder_outputs: list[torch.Tensor] = []
1946 for modality, num_items, mm_kwargs_group in group_mm_kwargs_by_modality(
1947 mm_kwargs,
1948 device=self.device,
@@ -1938,7 +1950,7 @@ class GPUModelRunner(
1950 merge_by_field_config=model.merge_by_field_config,
1951 multimodal_cpu_fields=model.multimodal_cpu_fields,
1952 ):
1941 - curr_group_outputs = []
1953 + curr_group_outputs: list[torch.Tensor] = []
1954
1955 # EVS-related change.
1956 # (ekhvedchenia): Temporary hack to limit peak memory usage when
@@ -1980,7 +1992,7 @@ class GPUModelRunner(
1992 # 2. A list or tuple (length: num_items) of tensors,
1993 # each of shape (feature_size, hidden_size) in case the feature
1994 # size is dynamic depending on the input multimodal items.
1983 - curr_group_outputs = model.embed_multimodal(**mm_kwargs_group)
1995 + curr_group_outputs = model.embed_multimodal(**mm_kwargs_group) # type: ignore[assignment]
1996
1997 sanity_check_mm_encoder_outputs(
1998 curr_group_outputs,
@@ -2180,7 +2192,7 @@ class GPUModelRunner(
2192 def sync_and_slice_intermediate_tensors(
2193 self,
2194 num_tokens: int,
2183 - intermediate_tensors: IntermediateTensors,
2195 + intermediate_tensors: IntermediateTensors | None,
2196 sync_self: bool,
2197 ) -> IntermediateTensors:
2198 assert self.intermediate_tensors is not None
@@ -2397,6 +2409,7 @@ class GPUModelRunner(
2409 if is_first_rank:
2410 intermediate_tensors = None
2411 else:
2412 + assert intermediate_tensors is not None
2413 intermediate_tensors = self.sync_and_slice_intermediate_tensors(
2414 num_input_tokens, intermediate_tensors, True
2415 )
@@ -2765,14 +2778,14 @@ class GPUModelRunner(
2778 uniform_decode = (
2779 max_num_scheduled_tokens == self.uniform_decode_query_len
2780 ) and (num_scheduled_tokens == num_reqs * max_num_scheduled_tokens)
2768 - batch_descriptor = BatchDescriptor(
2781 + batch_desc = BatchDescriptor(
2782 num_tokens=num_input_tokens,
2783 uniform_decode=uniform_decode,
2784 has_lora=len(self.input_batch.lora_id_to_lora_request) > 0,
2785 )
2786 cudagraph_runtime_mode, batch_descriptor = (
2787 self.cudagraph_dispatcher.dispatch(
2775 - batch_descriptor,
2788 + batch_desc,
2789 use_cascade_attn=cascade_attn_prefix_lens is not None,
2790 )
2791 )
@@ -2856,15 +2869,15 @@ class GPUModelRunner(
2869 else:
2870 logits = self.model.compute_logits(sample_hidden_states)
2871
2859 - model_output_broadcast_data = {}
2872 + model_output_broadcast_data: dict[str, Any] = {}
2873 if logits is not None:
2874 model_output_broadcast_data["logits"] = logits.contiguous()
2875
2863 - model_output_broadcast_data = get_pp_group().broadcast_tensor_dict(
2876 + broadcasted = get_pp_group().broadcast_tensor_dict(
2877 model_output_broadcast_data, src=len(get_pp_group().ranks) - 1
2878 )
2866 - assert model_output_broadcast_data is not None
2867 - logits = model_output_broadcast_data["logits"]
2879 + assert broadcasted is not None
2880 + logits = broadcasted["logits"]
2881
2882 self.execute_model_state = ExecuteModelState(
2883 scheduler_output,
@@ -2889,7 +2902,7 @@ class GPUModelRunner(
2902 if self.execute_model_state is None:
2903 # Nothing to do (PP non-final rank case), output isn't used.
2904 if not kv_connector_output:
2892 - return None # noqa
2905 + return None # type: ignore[return-value]
2906
2907 # In case of PP with kv transfer, we need to pass through the
2908 # kv_connector_output
@@ -2941,33 +2954,37 @@ class GPUModelRunner(
2954 spec_decode_common_attn_metadata,
2955 )
2956
2957 + spec_config = self.speculative_config
2958 use_padded_batch_for_eagle = (
2945 - self.speculative_config
2946 - and self.speculative_config.use_eagle()
2947 - and not self.speculative_config.disable_padded_drafter_batch
2959 + spec_config is not None
2960 + and spec_config.use_eagle()
2961 + and not spec_config.disable_padded_drafter_batch
2962 )
2963 effective_drafter_max_model_len = self.max_model_len
2964 if effective_drafter_max_model_len is None:
2965 effective_drafter_max_model_len = self.model_config.max_model_len
2966 if (
2953 - self.speculative_config
2954 - and self.speculative_config.draft_model_config is not None
2955 - and self.speculative_config.draft_model_config.max_model_len is not None
2967 + spec_config is not None
2968 + and spec_config.draft_model_config is not None
2969 + and spec_config.draft_model_config.max_model_len is not None
2970 ):
2971 effective_drafter_max_model_len = (
2958 - self.speculative_config.draft_model_config.max_model_len
2972 + spec_config.draft_model_config.max_model_len
2973 )
2974 input_fits_in_drafter = spec_decode_common_attn_metadata and (
2975 spec_decode_common_attn_metadata.max_seq_len + self.num_spec_tokens
2976 <= effective_drafter_max_model_len
2977 )
2978 if use_padded_batch_for_eagle:
2979 + assert self.speculative_config is not None
2980 + assert isinstance(self.drafter, EagleProposer)
2981 sampled_token_ids = sampler_output.sampled_token_ids
2982 if input_fits_in_drafter:
2983 # EAGLE speculative decoding can use the GPU sampled tokens
2984 # as inputs, and does not need to wait for bookkeeping to finish.
2985 propose_draft_token_ids(sampled_token_ids)
2986 elif self.valid_sampled_token_count_event is not None:
2987 + assert spec_decode_common_attn_metadata is not None
2988 next_token_ids, valid_sampled_tokens_count = (
2989 self.drafter.prepare_next_token_ids_padded(
2990 spec_decode_common_attn_metadata,
@@ -3105,7 +3122,9 @@ class GPUModelRunner(
3122 common_attn_metadata: CommonAttentionMetadata,
3123 ) -> torch.Tensor | list[list[int]]:
3124 num_scheduled_tokens = scheduler_output.total_num_scheduled_tokens
3108 - if self.speculative_config.method == "ngram":
3125 + spec_config = self.speculative_config
3126 + assert spec_config is not None
3127 + if spec_config.method == "ngram":
3128 assert isinstance(sampled_token_ids, list)
3129 assert isinstance(self.drafter, NgramProposer)
3130 draft_token_ids = self.drafter.propose(
@@ -3115,11 +3134,11 @@ class GPUModelRunner(
3134 self.input_batch.token_ids_cpu,
3135 self.input_batch.spec_decode_unsupported_reqs,
3136 )
3118 - elif self.speculative_config.method == "suffix":
3137 + elif spec_config.method == "suffix":
3138 assert isinstance(sampled_token_ids, list)
3139 assert isinstance(self.drafter, SuffixDecodingProposer)
3140 draft_token_ids = self.drafter.propose(self.input_batch, sampled_token_ids)
3122 - elif self.speculative_config.method == "medusa":
3141 + elif spec_config.method == "medusa":
3142 assert isinstance(sampled_token_ids, list)
3143 assert isinstance(self.drafter, MedusaProposer)
3144
@@ -3144,10 +3163,10 @@ class GPUModelRunner(
3163 target_hidden_states=hidden_states,
3164 sampling_metadata=sampling_metadata,
3165 )
3147 - elif self.speculative_config.use_eagle():
3166 + elif spec_config.use_eagle():
3167 assert isinstance(self.drafter, EagleProposer)
3168
3150 - if self.speculative_config.disable_padded_drafter_batch:
3169 + if spec_config.disable_padded_drafter_batch:
3170 # When padded-batch is disabled, the sampled_token_ids should be
3171 # the cpu-side list[list[int]] of valid sampled tokens for each
3172 # request, with invalid requests having empty lists.
@@ -3197,7 +3216,7 @@ class GPUModelRunner(
3216 else:
3217 target_hidden_states = hidden_states[:num_scheduled_tokens]
3218 else:
3200 - if self.speculative_config.disable_padded_drafter_batch:
3219 + if spec_config.disable_padded_drafter_batch:
3220 token_indices_to_sample = None
3221 common_attn_metadata, token_indices = self.drafter.prepare_inputs(
3222 common_attn_metadata,
@@ -3292,9 +3311,12 @@ class GPUModelRunner(
3311 and is_mixture_of_experts(self.drafter.model)
3312 and self.parallel_config.enable_eplb
3313 ):
3314 + spec_config = self.vllm_config.speculative_config
3315 + assert spec_config is not None
3316 + assert spec_config.draft_model_config is not None
3317 logger.info_once(
3318 "EPLB is enabled for drafter model %s.",
3297 - self.vllm_config.speculative_config.draft_model_config.model,
3319 + spec_config.draft_model_config.model,
3320 )
3321
3322 global_expert_load = (
@@ -3311,7 +3333,7 @@ class GPUModelRunner(
3333 self.eplb_state = EplbState(self.parallel_config, self.device)
3334 self.eplb_state.add_model(
3335 self.drafter.model,
3314 - self.vllm_config.speculative_config.draft_model_config,
3336 + spec_config.draft_model_config,
3337 global_expert_load,
3338 old_global_expert_indices,
3339 rank_mapping,
@@ -3346,9 +3368,11 @@ class GPUModelRunner(
3368 scope="local",
3369 )
3370 prepare_communication_buffer_for_model(self.model)
3371 + mm_config = self.model_config.multimodal_config
3372 self.is_multimodal_pruning_enabled = (
3373 supports_multimodal_pruning(self.get_model())
3351 - and self.model_config.multimodal_config.is_multimodal_pruning_enabled()
3374 + and mm_config is not None
3375 + and mm_config.is_multimodal_pruning_enabled()
3376 )
3377
3378 if is_mixture_of_experts(self.model) and self.parallel_config.enable_eplb:
@@ -3383,15 +3407,14 @@ class GPUModelRunner(
3407 # CudagraphWraper and CudagraphDispatcher of vllm.
3408
3409 # wrap the model with full cudagraph wrapper if needed.
3386 - if (
3387 - self.compilation_config.cudagraph_mode.has_full_cudagraphs()
3388 - and not self.parallel_config.enable_dbo
3389 - ):
3410 + cudagraph_mode = self.compilation_config.cudagraph_mode
3411 + assert cudagraph_mode is not None
3412 + if cudagraph_mode.has_full_cudagraphs() and not self.parallel_config.enable_dbo:
3413 self.model = CUDAGraphWrapper(
3414 self.model, self.vllm_config, runtime_mode=CUDAGraphMode.FULL
3415 )
3416 elif self.parallel_config.enable_dbo:
3394 - if self.compilation_config.cudagraph_mode.has_full_cudagraphs():
3417 + if cudagraph_mode.has_full_cudagraphs():
3418 self.model = UBatchWrapper(
3419 self.model, self.vllm_config, CUDAGraphMode.FULL, self.device
3420 )
@@ -4071,7 +4094,8 @@ class GPUModelRunner(
4094 def profile_run(self) -> None:
4095 # Profile with multimodal encoder & encoder cache.
4096 if self.supports_mm_inputs:
4074 - if self.model_config.multimodal_config.skip_mm_profiling:
4097 + mm_config = self.model_config.multimodal_config
4098 + if mm_config is not None and mm_config.skip_mm_profiling:
4099 logger.info(
4100 "Skipping memory profiling for multimodal encoder and "
4101 "encoder cache."
@@ -4333,8 +4357,9 @@ class GPUModelRunner(
4357 def get_attn_backends_for_group(
4358 kv_cache_group_spec: KVCacheGroupSpec,
4359 ) -> tuple[dict[AttentionGroupKey, list[str]], set[type[AttentionBackend]]]:
4360 + layer_type = cast(type[Any], AttentionLayerBase)
4361 layers = get_layers_from_vllm_config(
4337 - self.vllm_config, AttentionLayerBase, kv_cache_group_spec.layer_names
4362 + self.vllm_config, layer_type, kv_cache_group_spec.layer_names
4363 )
4364 attn_backends = {}
4365 attn_backend_layers = defaultdict(list)
@@ -4349,7 +4374,7 @@ class GPUModelRunner(
4374 if layer_name in self.kv_sharing_fast_prefill_eligible_layers:
4375 attn_backend = create_fast_prefill_custom_backend(
4376 "FastPrefill",
4352 - attn_backend,
4377 + attn_backend, # type: ignore[arg-type]
4378 )
4379
4380 full_cls_name = attn_backend.full_cls_name()
@@ -4448,6 +4473,7 @@ class GPUModelRunner(
4473 min_cg_backend_name = attn_backend.__name__
4474 # Flexible resolve the cudagraph mode
4475 cudagraph_mode = self.compilation_config.cudagraph_mode
4476 + assert cudagraph_mode is not None
4477 # check cudagraph for mixed batch is supported
4478 if (
4479 cudagraph_mode.mixed_mode() == CUDAGraphMode.FULL
@@ -4562,12 +4588,17 @@ class GPUModelRunner(
4588 self.compilation_config.adjust_cudagraph_sizes_for_spec_decode(
4589 self.uniform_decode_query_len, self.parallel_config.tensor_parallel_size
4590 )
4565 - self.cudagraph_batch_sizes = self.compilation_config.cudagraph_capture_sizes
4591 + capture_sizes = self.compilation_config.cudagraph_capture_sizes
4592 + self.cudagraph_batch_sizes = (
4593 + capture_sizes if capture_sizes is not None else []
4594 + )
4595
4596 # Trigger cudagraph dispatching keys initialization after
4597 # resolved cudagraph mode.
4598 + cudagraph_mode = self.compilation_config.cudagraph_mode
4599 + assert cudagraph_mode is not None
4600 self.cudagraph_dispatcher.initialize_cudagraph_keys(
4570 - self.compilation_config.cudagraph_mode, self.uniform_decode_query_len
4601 + cudagraph_mode, self.uniform_decode_query_len
4602 )
4603
4604 def calculate_reorder_batch_threshold(self) -> None:
@@ -4579,7 +4610,7 @@ class GPUModelRunner(
4610 """
4611 min_none_high = lambda a, b: a if b is None else b if a is None else min(a, b)
4612
4582 - reorder_batch_thresholds = [
4613 + reorder_batch_thresholds: list[int | None] = [
4614 group.get_metadata_builder().reorder_batch_threshold
4615 for group in self._attn_group_iterator()
4616 ]
@@ -4588,7 +4619,7 @@ class GPUModelRunner(
4619 if len(reorder_batch_thresholds) == 0:
4620 self.reorder_batch_threshold = None
4621 return
4591 - self.reorder_batch_threshold = reduce(min_none_high, reorder_batch_thresholds)
4622 + self.reorder_batch_threshold = reduce(min_none_high, reorder_batch_thresholds) # type: ignore[assignment]
4623
4624 @staticmethod
4625 def select_common_block_size(
@@ -5048,12 +5079,16 @@ class GPUModelRunner(
5079 kv_transfer_group.set_host_xfer_buffer_ops(copy_kv_blocks)
5080
5081 if self.dcp_world_size > 1:
5051 - layers = get_layers_from_vllm_config(self.vllm_config, AttentionLayerBase)
5082 + layer_type = cast(type[Any], AttentionLayerBase)
5083 + layers = get_layers_from_vllm_config(self.vllm_config, layer_type)
5084 for layer in layers.values():
5053 - assert layer.impl.need_to_return_lse_for_decode, (
5085 + layer_impl = getattr(layer, "impl", None)
5086 + if layer_impl is None:
5087 + continue
5088 + assert layer_impl.need_to_return_lse_for_decode, (
5089 "DCP requires attention impls to return"
5090 " the softmax lse for decode, but the impl "
5056 - f"{layer.impl.__class__.__name__} "
5091 + f"{layer_impl.__class__.__name__} "
5092 "does not return the softmax lse for decode."
5093 )
5094
@@ -5094,7 +5129,8 @@ class GPUModelRunner(
5129 if has_ec_transfer() and get_ec_transfer().is_producer:
5130 return {}
5131 kv_cache_spec: dict[str, KVCacheSpec] = {}
5097 - attn_layers = get_layers_from_vllm_config(self.vllm_config, AttentionLayerBase)
5132 + layer_type = cast(type[Any], AttentionLayerBase)
5133 + attn_layers = get_layers_from_vllm_config(self.vllm_config, layer_type)
5134 for layer_name, attn_module in attn_layers.items():
5135 if isinstance(attn_module, Attention) and (
5136 kv_tgt_layer := attn_module.kv_sharing_target_layer_name
vllm/v1/worker/gpu_ubatch_wrapper.py
+13 -7
@@ -121,18 +121,24 @@ class UBatchWrapper:
121
122 @staticmethod
123 def _create_sm_control_context(vllm_config: VllmConfig):
124 - comm_sms = envs.VLLM_DBO_COMM_SMS
124 + comm_sms: int = envs.VLLM_DBO_COMM_SMS
125
126 set_comm_sms = lambda sms: None
127 if vllm_config.parallel_config.enable_expert_parallel:
128 # Currently only DeepEP highthroughput supports SM control so this
129 # only affects that case.
130 - all2all_manager = get_ep_group().device_communicator.all2all_manager
131 -
132 - if all2all_manager.max_sms_used() is not None:
133 - comm_sms = min(comm_sms, all2all_manager.max_sms_used())
134 -
135 - if comm_sms > 0:
130 + ep_group = get_ep_group()
131 + device_communicator = ep_group.device_communicator
132 + all2all_manager = None
133 + if device_communicator is not None:
134 + all2all_manager = device_communicator.all2all_manager
135 +
136 + if all2all_manager is not None:
137 + max_sms_used = all2all_manager.max_sms_used()
138 + if max_sms_used is not None:
139 + comm_sms = min(comm_sms, max_sms_used)
140 +
141 + if comm_sms > 0 and all2all_manager is not None:
142 set_comm_sms = lambda sms: all2all_manager.set_num_sms(sms)
143
144 # TODO(lucas): support other kernels besides DeepGEMM
vllm/v1/worker/gpu_worker.py
+33 -29
@@ -6,7 +6,7 @@ import gc
6 import os
7 from contextlib import AbstractContextManager, nullcontext
8 from types import NoneType
9 -from typing import TYPE_CHECKING, Any
9 +from typing import TYPE_CHECKING, Any, cast
10
11 import torch
12 import torch.distributed
@@ -87,8 +87,10 @@ class Worker(WorkerBase):
87 # Buffers saved before sleep
88 self._sleep_saved_buffers: dict[str, torch.Tensor] = {}
89
90 - # Torch profiler. Enabled and configured through env vars:
90 + # Torch/CUDA profiler. Enabled and configured through env vars:
91 # VLLM_TORCH_PROFILER_DIR=/path/to/save/trace
92 + # VLLM_TORCH_CUDA_PROFILE=1
93 + self.profiler: Any | None = None
94 if envs.VLLM_TORCH_PROFILER_DIR:
95 worker_name = f"{vllm_config.instance_id}-rank-{self.rank}"
96 self.profiler = TorchProfilerWrapper(
@@ -146,17 +148,17 @@ class Worker(WorkerBase):
148 assert allocator.get_current_usage() == 0, (
149 "Sleep mode can only be used for one instance per process."
150 )
149 - context = allocator.use_memory_pool(tag=tag)
151 + return allocator.use_memory_pool(tag=tag)
152 else:
151 - context = nullcontext()
152 - return context
153 + return nullcontext()
154
155 def initialize_cache(self, num_gpu_blocks: int, num_cpu_blocks: int) -> None:
156 self.cache_config.num_gpu_blocks = num_gpu_blocks
157 self.cache_config.num_cpu_blocks = num_cpu_blocks
158
159 def init_device(self):
159 - if self.device_config.device.type == "cuda":
160 + device = self.device_config.device
161 + if isinstance(device, torch.device) and device.type == "cuda":
162 # This env var set by Ray causes exceptions with graph building.
163 os.environ.pop("NCCL_ASYNC_ERROR_HANDLING", None)
164 if (
@@ -375,23 +377,21 @@ class Worker(WorkerBase):
377 from vllm.device_allocator.cumem import CuMemAllocator
378
379 allocator = CuMemAllocator.get_instance()
378 - context = allocator.use_memory_pool(tag="kv_cache")
380 + with allocator.use_memory_pool(tag="kv_cache"):
381 + self.model_runner.initialize_kv_cache(kv_cache_config)
382 else:
380 - context = nullcontext()
381 - with context:
383 self.model_runner.initialize_kv_cache(kv_cache_config)
384
385 def compile_or_warm_up_model(self) -> None:
386 # warm up sizes that are not in cudagraph capture sizes,
387 # but users still want to compile for better performance,
388 # e.g. for the max-num-batched token size in chunked prefill.
388 - warmup_sizes = self.vllm_config.compilation_config.compile_sizes.copy()
389 + compile_sizes = self.vllm_config.compilation_config.compile_sizes
390 + warmup_sizes = compile_sizes.copy() if compile_sizes is not None else []
391 if not self.model_config.enforce_eager:
390 - warmup_sizes = [
391 - x
392 - for x in warmup_sizes
393 - if x not in self.vllm_config.compilation_config.cudagraph_capture_sizes
394 - ]
392 + capture_sizes = self.vllm_config.compilation_config.cudagraph_capture_sizes
393 + if capture_sizes is not None:
394 + warmup_sizes = [x for x in warmup_sizes if x not in capture_sizes]
395 # We skip EPLB here since we don't want to record dummy metrics
396 for size in sorted(warmup_sizes, reverse=True):
397 logger.info("Compile and warming up model for size %d", size)
@@ -532,12 +532,12 @@ class Worker(WorkerBase):
532 )
533 }
534 if forward_pass and not get_pp_group().is_first_rank:
535 - intermediate_tensors = IntermediateTensors(
536 - get_pp_group().recv_tensor_dict(
537 - all_gather_group=get_tp_group(),
538 - all_gather_tensors=all_gather_tensors,
539 - )
535 + tensor_dict = get_pp_group().recv_tensor_dict(
536 + all_gather_group=get_tp_group(),
537 + all_gather_tensors=all_gather_tensors,
538 )
539 + assert tensor_dict is not None
540 + intermediate_tensors = IntermediateTensors(tensor_dict)
541
542 with self.annotate_profile(scheduler_output):
543 output = self.model_runner.execute_model(
@@ -605,7 +605,7 @@ class Worker(WorkerBase):
605 assert self.model_runner.eplb_state is not None
606 self.model_runner.eplb_state.rearrange(
607 execute_shuffle=True,
608 - global_expert_load=None,
608 + global_expert_loads=None,
609 rank_mapping=rank_mapping,
610 )
611 torch.cuda.synchronize()
@@ -661,7 +661,7 @@ class Worker(WorkerBase):
661
662 def _reconfigure_moe(
663 self, old_ep_size: int, new_ep_size: int
664 - ) -> torch.Tensor | None:
664 + ) -> list[torch.Tensor] | None:
665 """
666 Reconfigure MoE modules with provided reconfig_request
667
@@ -728,26 +728,29 @@ class Worker(WorkerBase):
728 num_local_physical_experts = num_local_experts
729 assert self.model_runner.eplb_state is not None
730 new_physical_experts = (
731 - self.model_runner.eplb_state.physical_to_logical_map.shape[1]
731 + self.model_runner.eplb_state.physical_to_logical_map.shape[1] # type: ignore[attr-defined]
732 )
733 parallel_config.eplb_config.num_redundant_experts = (
734 new_physical_experts
735 - - self.model_runner.eplb_state.logical_replica_count.shape[1]
735 + - self.model_runner.eplb_state.logical_replica_count.shape[1] # type: ignore[attr-defined]
736 )
737 global_expert_loads = None
738 else:
739 - num_local_physical_experts = torch.tensor(
739 + num_local_physical_experts_tensor = torch.tensor(
740 [num_local_experts], dtype=torch.int32, device="cpu"
741 )
742 torch.distributed.broadcast(
743 - num_local_physical_experts, group=get_ep_group().cpu_group, group_src=0
743 + num_local_physical_experts_tensor,
744 + group=get_ep_group().cpu_group,
745 + group_src=0,
746 )
745 - num_local_physical_experts = num_local_physical_experts.item()
747 + num_local_physical_experts = int(num_local_physical_experts_tensor.item())
748 new_physical_experts = num_local_physical_experts * new_ep_size
749 assert self.model_runner.eplb_state is not None
748 - global_expert_loads = self.model_runner.eplb_state.rearrange(
750 + global_expert_loads_any = self.model_runner.eplb_state.rearrange(
751 execute_shuffle=False
752 )
753 + global_expert_loads = cast(list[torch.Tensor], global_expert_loads_any)
754 parallel_config.eplb_config.num_redundant_experts = (
755 new_physical_experts - global_expert_loads[0].shape[1]
756 )
@@ -849,8 +852,9 @@ def init_worker_distributed_environment(
852 init_batch_invariance()
853 set_custom_all_reduce(not parallel_config.disable_custom_all_reduce)
854
855 + init_method = distributed_init_method or "env://"
856 init_distributed_environment(
853 - parallel_config.world_size, rank, distributed_init_method, local_rank, backend
857 + parallel_config.world_size, rank, init_method, local_rank, backend
858 )
859
860 ensure_model_parallel_initialized(
vllm/v1/worker/kv_connector_model_runner_mixin.py
+1 -1
@@ -59,7 +59,7 @@ class KVConnectorModelRunnerMixin:
59 @staticmethod
60 def ensure_kv_transfer_shutdown() -> None:
61 # has_kv_transfer_group can be None during interpreter shutdown.
62 - if has_kv_transfer_group and has_kv_transfer_group():
62 + if has_kv_transfer_group and has_kv_transfer_group(): # type: ignore[truthy-function]
63 ensure_kv_transfer_shutdown()
64
65 @staticmethod
vllm/v1/worker/tpu_model_runner.py
+22 -6
@@ -572,7 +572,10 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
572 format. Layers that do not need KV cache are not included.
573 """
574
575 - layers = get_layers_from_vllm_config(self.vllm_config, AttentionLayerBase)
575 + layers = get_layers_from_vllm_config(
576 + self.vllm_config,
577 + AttentionLayerBase, # type: ignore[type-abstract]
578 + )
579 block_size = self.vllm_config.cache_config.block_size
580 cache_dtype_str = self.vllm_config.cache_config.cache_dtype
581
@@ -725,7 +728,11 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
728 req_id = self.input_batch.req_ids[i]
729 assert req_id is not None
730 num_tokens = scheduler_output.num_scheduled_tokens[req_id]
728 - if not use_max_model_len and num_tokens > self.most_model_len:
731 + if (
732 + not use_max_model_len
733 + and self.most_model_len is not None
734 + and num_tokens > self.most_model_len
735 + ):
736 use_max_model_len = True
737 num_scheduled_tokens_per_req.append(num_tokens)
738 if use_max_model_len:
@@ -737,6 +744,7 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
744 else:
745 end_index = num_reqs
746 else:
747 + assert self.num_reqs_most_model_len is not None
748 if len(num_scheduled_tokens_per_req) > self.num_reqs_most_model_len:
749 num_scheduled_tokens_per_req = num_scheduled_tokens_per_req[
750 : self.num_reqs_most_model_len
@@ -829,6 +837,7 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
837 ].to(self.device)
838 seq_lens = self.seq_lens_cpu[: self.num_reqs_max_model_len].to(self.device)
839 else:
840 + assert self.num_reqs_most_model_len is not None
841 block_tables = self.block_table_cpu[
842 : self.num_reqs_most_model_len, : self.num_blocks_per_most_len_req
843 ]
@@ -931,6 +940,8 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
940
941 for mm_input_id in encoder_input_ids:
942 mm_feature = req_state.mm_features[mm_input_id]
943 + if mm_feature.data is None:
944 + continue
945 mm_hash = mm_feature.identifier
946 mm_kwargs.append(mm_feature.data)
947 mm_hashes_pos.append((mm_hash, mm_feature.mm_position))
@@ -1114,7 +1125,7 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
1125 ) -> ModelRunnerOutput:
1126 if self.scheduler_output is None:
1127 # Nothing to do (PP non-final rank case), output isn't used.
1117 - return None # noqa
1128 + return None # type: ignore[return-value]
1129 scheduler_output = self.scheduler_output
1130 mm_embed_inputs = self.mm_embed_inputs
1131 self.scheduler_output = None
@@ -1696,7 +1707,8 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
1707 ) -> None:
1708 # Profile with multimodal encoder & encoder cache.
1709 if self.supports_mm_inputs:
1699 - if self.model_config.multimodal_config.skip_mm_profiling:
1710 + mm_config = self.model_config.multimodal_config
1711 + if mm_config is not None and mm_config.skip_mm_profiling:
1712 logger.info(
1713 "Skipping memory profiling for multimodal encoder and "
1714 "encoder cache."
@@ -2166,5 +2178,9 @@ def replace_set_lora(model):
2178 if isinstance(module, BaseLayerWithLoRA):
2179 module._original_set_lora = module.set_lora
2180 module._original_reset_lora = module.reset_lora
2169 - module.set_lora = _tpu_set_lora.__get__(module, module.__class__)
2170 - module.reset_lora = _tpu_reset_lora.__get__(module, module.__class__)
2181 + module.set_lora = _tpu_set_lora.__get__( # type: ignore[method-assign]
2182 + module, module.__class__
2183 + )
2184 + module.reset_lora = _tpu_reset_lora.__get__( # type: ignore[method-assign]
2185 + module, module.__class__
2186 + )
vllm/v1/worker/tpu_worker.py
+2 -3
@@ -141,8 +141,7 @@ class TPUWorker:
141
142 # Set random seed.
143 set_random_seed(self.model_config.seed)
144 - if self.model_config.seed is not None:
145 - xm.set_rng_state(self.model_config.seed, self.device)
144 + xm.set_rng_state(self.model_config.seed, self.device)
145
146 # Increase the cache size limit, which is the maximum number of
147 # dynamo graphs that can be compiled.
@@ -332,7 +331,7 @@ class TPUWorker:
331 world_size=parallel_config.world_size,
332 rank=rank,
333 local_rank=local_rank,
335 - distributed_init_method=distributed_init_method,
334 + distributed_init_method=distributed_init_method or "env://",
335 backend=current_platform.dist_backend,
336 )
337 ensure_model_parallel_initialized(
vllm/v1/worker/utils.py
+5 -3
@@ -280,7 +280,7 @@ def bind_kv_cache(
280 kv_caches: dict[str, torch.Tensor],
281 forward_context: dict[str, "Attention"],
282 runner_kv_caches: list[torch.Tensor],
283 - num_attn_module: int | None = 1,
283 + num_attn_module: int = 1,
284 ) -> None:
285 """
286 Bind the allocated KV cache to both ModelRunner and forward context so
@@ -362,5 +362,7 @@ def is_residual_scattered_for_sp(
362 or vllm_config.compilation_config.use_inductor_graph_partition
363 ):
364 return True
365 -
366 - return num_input_tokens in vllm_config.compilation_config.compile_sizes
365 + compile_sizes = vllm_config.compilation_config.compile_sizes
366 + if compile_sizes is None:
367 + return False
368 + return num_input_tokens in compile_sizes
vllm/v1/worker/worker_base.py
+2
@@ -315,10 +315,12 @@ class WorkerWrapperBase:
315
316 def initialize_from_config(self, kv_cache_configs: list[Any]) -> None:
317 kv_cache_config = kv_cache_configs[self.global_rank]
318 + assert self.vllm_config is not None
319 with set_current_vllm_config(self.vllm_config):
320 self.worker.initialize_from_config(kv_cache_config) # type: ignore
321
322 def init_device(self):
323 + assert self.vllm_config is not None
324 with set_current_vllm_config(self.vllm_config):
325 # To make vLLM config available during device initialization
326 self.worker.init_device() # type: ignore
vllm/v1/worker/xpu_worker.py
+8 -1
@@ -1,6 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import os
4 +from typing import Any
5
6 import torch
7 import torch.distributed
@@ -37,6 +38,7 @@ class XPUWorker(Worker):
38
39 # Torch profiler. Enabled and configured through env vars:
40 # VLLM_TORCH_PROFILER_DIR=/path/to/save/trace
41 + self.profiler: Any | None = None
42 if envs.VLLM_TORCH_PROFILER_DIR:
43 torch_profiler_trace_dir = envs.VLLM_TORCH_PROFILER_DIR
44 worker_name = f"{vllm_config.instance_id}-rank-{self.rank}"
@@ -148,7 +150,12 @@ class XPUWorker(Worker):
150 return int(available_kv_cache_memory)
151
152 def init_device(self):
151 - if self.device_config.device.type == "xpu" and current_platform.is_xpu():
153 + device = self.device_config.device
154 + if (
155 + isinstance(device, torch.device)
156 + and device.type == "xpu"
157 + and current_platform.is_xpu()
158 + ):
159 self.device = torch.device(f"xpu:{self.local_rank}")
160 current_platform.set_device(self.device)
161 current_platform.check_if_supports_dtype(self.model_config.dtype)