@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 8fcaaf6a16
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 14, 05:30 UTC

Update `Optional[x]` -> `x | None` and `Union[x, y]` to `x | y` (#26633)

Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>

Harry Mellor committed Oct 12, 2025 at 17:51 UTC 8fcaaf6a165e661f63fc51be906bc05b0767332f
944 files changed +9491 -10122
benchmarks/backend_request_func.py
+13 -14
@@ -8,7 +8,6 @@ import sys
8 import time
9 import traceback
10 from dataclasses import dataclass, field
11 -from typing import Optional, Union
11
12 import aiohttp
13 import huggingface_hub.constants
@@ -28,13 +27,13 @@ class RequestFuncInput:
27 prompt_len: int
28 output_len: int
29 model: str
31 - model_name: Optional[str] = None
32 - logprobs: Optional[int] = None
33 - extra_body: Optional[dict] = None
34 - multi_modal_content: Optional[dict | list[dict]] = None
30 + model_name: str | None = None
31 + logprobs: int | None = None
32 + extra_body: dict | None = None
33 + multi_modal_content: dict | list[dict] | None = None
34 ignore_eos: bool = False
36 - language: Optional[str] = None
37 - request_id: Optional[str] = None
35 + language: str | None = None
36 + request_id: str | None = None
37
38
39 @dataclass
@@ -52,7 +51,7 @@ class RequestFuncOutput:
51
52 async def async_request_tgi(
53 request_func_input: RequestFuncInput,
55 - pbar: Optional[tqdm] = None,
54 + pbar: tqdm | None = None,
55 ) -> RequestFuncOutput:
56 api_url = request_func_input.api_url
57 assert api_url.endswith("generate_stream")
@@ -133,7 +132,7 @@ async def async_request_tgi(
132
133 async def async_request_trt_llm(
134 request_func_input: RequestFuncInput,
136 - pbar: Optional[tqdm] = None,
135 + pbar: tqdm | None = None,
136 ) -> RequestFuncOutput:
137 api_url = request_func_input.api_url
138 assert api_url.endswith("generate_stream")
@@ -204,7 +203,7 @@ async def async_request_trt_llm(
203
204 async def async_request_deepspeed_mii(
205 request_func_input: RequestFuncInput,
207 - pbar: Optional[tqdm] = None,
206 + pbar: tqdm | None = None,
207 ) -> RequestFuncOutput:
208 api_url = request_func_input.api_url
209 assert api_url.endswith(("completions", "profile")), (
@@ -267,7 +266,7 @@ async def async_request_deepspeed_mii(
266
267 async def async_request_openai_completions(
268 request_func_input: RequestFuncInput,
270 - pbar: Optional[tqdm] = None,
269 + pbar: tqdm | None = None,
270 ) -> RequestFuncOutput:
271 api_url = request_func_input.api_url
272 assert api_url.endswith(("completions", "profile")), (
@@ -367,7 +366,7 @@ async def async_request_openai_completions(
366
367 async def async_request_openai_chat_completions(
368 request_func_input: RequestFuncInput,
370 - pbar: Optional[tqdm] = None,
369 + pbar: tqdm | None = None,
370 ) -> RequestFuncOutput:
371 api_url = request_func_input.api_url
372 assert api_url.endswith(("chat/completions", "profile")), (
@@ -476,7 +475,7 @@ async def async_request_openai_chat_completions(
475
476 async def async_request_openai_audio(
477 request_func_input: RequestFuncInput,
479 - pbar: Optional[tqdm] = None,
478 + pbar: tqdm | None = None,
479 ) -> RequestFuncOutput:
480 # Lazy import without PlaceholderModule to avoid vllm dep.
481 import soundfile
@@ -610,7 +609,7 @@ def get_tokenizer(
609 tokenizer_mode: str = "auto",
610 trust_remote_code: bool = False,
611 **kwargs,
613 -) -> Union[PreTrainedTokenizer, PreTrainedTokenizerFast]:
612 +) -> PreTrainedTokenizer | PreTrainedTokenizerFast:
613 if pretrained_model_name_or_path is not None and not os.path.exists(
614 pretrained_model_name_or_path
615 ):
benchmarks/benchmark_prefix_caching.py
+2 -3
@@ -32,7 +32,6 @@ import dataclasses
32 import json
33 import random
34 import time
35 -from typing import Optional
35
36 from transformers import PreTrainedTokenizerBase
37
@@ -80,7 +79,7 @@ def sample_requests_from_dataset(
79 num_requests: int,
80 tokenizer: PreTrainedTokenizerBase,
81 input_length_range: tuple[int, int],
83 - fixed_output_len: Optional[int],
82 + fixed_output_len: int | None,
83 ) -> list[Request]:
84 if fixed_output_len is not None and fixed_output_len < 4:
85 raise ValueError("output_len too small")
@@ -128,7 +127,7 @@ def sample_requests_from_random(
127 num_requests: int,
128 tokenizer: PreTrainedTokenizerBase,
129 input_length_range: tuple[int, int],
131 - fixed_output_len: Optional[int],
130 + fixed_output_len: int | None,
131 prefix_len: int,
132 ) -> list[Request]:
133 requests = []
benchmarks/benchmark_prioritization.py
+1 -2
@@ -7,7 +7,6 @@ import dataclasses
7 import json
8 import random
9 import time
10 -from typing import Optional
10
11 from transformers import AutoTokenizer, PreTrainedTokenizerBase
12
@@ -24,7 +23,7 @@ def sample_requests(
23 dataset_path: str,
24 num_requests: int,
25 tokenizer: PreTrainedTokenizerBase,
27 - fixed_output_len: Optional[int],
26 + fixed_output_len: int | None,
27 ) -> list[tuple[str, int, int, int]]:
28 if fixed_output_len is not None and fixed_output_len < 4:
29 raise ValueError("output_len too small")
benchmarks/benchmark_serving_structured_output.py
+3 -4
@@ -32,7 +32,6 @@ import uuid
32 import warnings
33 from collections.abc import AsyncGenerator
34 from dataclasses import dataclass
35 -from typing import Optional
35
36 import datasets
37 import numpy as np
@@ -316,7 +315,7 @@ def calculate_metrics(
315 tokenizer: PreTrainedTokenizerBase,
316 selected_percentile_metrics: list[str],
317 selected_percentiles: list[float],
319 - goodput_config_dict: Optional[dict[str, float]] = None,
318 + goodput_config_dict: dict[str, float] | None = None,
319 ) -> tuple[BenchmarkMetrics, list[int]]:
320 actual_output_lens: list[int] = []
321 total_input = 0
@@ -436,9 +435,9 @@ async def benchmark(
435 selected_percentile_metrics: list[str],
436 selected_percentiles: list[str],
437 ignore_eos: bool,
439 - max_concurrency: Optional[int],
438 + max_concurrency: int | None,
439 structured_output_ratio: float,
441 - goodput_config_dict: Optional[dict[str, float]] = None,
440 + goodput_config_dict: dict[str, float] | None = None,
441 ):
442 if backend in ASYNC_REQUEST_FUNCS:
443 request_func = ASYNC_REQUEST_FUNCS[backend]
benchmarks/benchmark_utils.py
+8 -8
@@ -6,7 +6,7 @@ import math
6 import os
7 import time
8 from types import TracebackType
9 -from typing import Any, Optional, Union
9 +from typing import Any
10
11
12 def convert_to_pytorch_benchmark_format(
@@ -92,7 +92,7 @@ class TimeCollector:
92 def __init__(self, scale: int) -> None:
93 self.cnt: int = 0
94 self._sum: int = 0
95 - self._max: Optional[int] = None
95 + self._max: int | None = None
96 self.scale = scale
97 self.start_time: int = time.monotonic_ns()
98
@@ -104,13 +104,13 @@ class TimeCollector:
104 else:
105 self._max = max(self._max, v)
106
107 - def avg(self) -> Union[float, str]:
107 + def avg(self) -> float | str:
108 return self._sum * 1.0 / self.cnt / self.scale if self.cnt > 0 else "N/A"
109
110 - def max(self) -> Union[float, str]:
110 + def max(self) -> float | str:
111 return self._max / self.scale if self._max else "N/A"
112
113 - def dump_avg_max(self) -> list[Union[float, str]]:
113 + def dump_avg_max(self) -> list[float | str]:
114 return [self.avg(), self.max()]
115
116 def __enter__(self) -> None:
@@ -118,8 +118,8 @@ class TimeCollector:
118
119 def __exit__(
120 self,
121 - exc_type: Optional[type[BaseException]],
122 - exc_value: Optional[BaseException],
123 - exc_traceback: Optional[TracebackType],
121 + exc_type: type[BaseException] | None,
122 + exc_value: BaseException | None,
123 + exc_traceback: TracebackType | None,
124 ) -> None:
125 self.collect(time.monotonic_ns() - self.start_time)
benchmarks/cutlass_benchmarks/sparse_benchmarks.py
+1 -2
@@ -6,8 +6,7 @@ import copy
6 import itertools
7 import pickle as pkl
8 import time
9 -from collections.abc import Iterable
10 -from typing import Callable
9 +from collections.abc import Callable, Iterable
10
11 import torch
12 import torch.utils.benchmark as TBenchmark
benchmarks/cutlass_benchmarks/w8a8_benchmarks.py
+5 -6
@@ -6,8 +6,7 @@ import copy
6 import itertools
7 import pickle as pkl
8 import time
9 -from collections.abc import Iterable
10 -from typing import Callable, Optional
9 +from collections.abc import Callable, Iterable
10
11 import torch
12 import torch.utils.benchmark as TBenchmark
@@ -53,7 +52,7 @@ def bench_int8(
52 n: int,
53 label: str,
54 sub_label: str,
56 - bench_kernels: Optional[list[str]] = None,
55 + bench_kernels: list[str] | None = None,
56 ) -> Iterable[TMeasurement]:
57 """Benchmark INT8-based kernels."""
58 assert dtype == torch.int8
@@ -108,7 +107,7 @@ def bench_fp8(
107 n: int,
108 label: str,
109 sub_label: str,
111 - bench_kernels: Optional[list[str]] = None,
110 + bench_kernels: list[str] | None = None,
111 ) -> Iterable[TMeasurement]:
112 """Benchmark FP8-based kernels."""
113 assert dtype == torch.float8_e4m3fn
@@ -183,7 +182,7 @@ def bench(
182 n: int,
183 label: str,
184 sub_label: str,
186 - bench_kernels: Optional[list[str]] = None,
185 + bench_kernels: list[str] | None = None,
186 ) -> Iterable[TMeasurement]:
187 if dtype == torch.int8:
188 return bench_int8(dtype, m, k, n, label, sub_label, bench_kernels)
@@ -201,7 +200,7 @@ def print_timers(timers: Iterable[TMeasurement]):
200 def run(
201 dtype: torch.dtype,
202 MKNs: Iterable[tuple[int, int, int]],
204 - bench_kernels: Optional[list[str]] = None,
203 + bench_kernels: list[str] | None = None,
204 ) -> Iterable[TMeasurement]:
205 results = []
206 for m, k, n in MKNs:
benchmarks/fused_kernels/layernorm_rms_benchmarks.py
+4 -5
@@ -3,10 +3,9 @@
3
4 import pickle as pkl
5 import time
6 -from collections.abc import Iterable
6 +from collections.abc import Callable, Iterable
7 from dataclasses import dataclass
8 from itertools import product
9 -from typing import Callable, Optional
9
10 import torch
11 import torch.utils.benchmark as TBenchmark
@@ -51,7 +50,7 @@ def get_bench_params() -> list[bench_params_t]:
50 def unfused_int8_impl(
51 rms_norm_layer: RMSNorm,
52 x: torch.Tensor,
54 - residual: Optional[torch.Tensor],
53 + residual: torch.Tensor | None,
54 quant_dtype: torch.dtype,
55 ):
56 # Norm
@@ -68,7 +67,7 @@ def unfused_int8_impl(
67 def unfused_fp8_impl(
68 rms_norm_layer: RMSNorm,
69 x: torch.Tensor,
71 - residual: Optional[torch.Tensor],
70 + residual: torch.Tensor | None,
71 quant_dtype: torch.dtype,
72 ):
73 # Norm
@@ -85,7 +84,7 @@ def unfused_fp8_impl(
84 def fused_impl(
85 rms_norm_layer: RMSNorm, # this stores the weights
86 x: torch.Tensor,
88 - residual: Optional[torch.Tensor],
87 + residual: torch.Tensor | None,
88 quant_dtype: torch.dtype,
89 ):
90 out, _ = ops.rms_norm_dynamic_per_token_quant(
benchmarks/kernels/bench_per_token_quant_fp8.py
+1 -1
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import itertools
4 -from typing import Callable
4 +from collections.abc import Callable
5 from unittest.mock import patch
6
7 import pandas as pd
benchmarks/kernels/benchmark_device_communicators.py
+3 -3
@@ -22,8 +22,8 @@ Example:
22 import json
23 import os
24 import time
25 +from collections.abc import Callable
26 from contextlib import nullcontext
26 -from typing import Callable, Optional
27
28 import torch
29 import torch.distributed as dist
@@ -264,12 +264,12 @@ class CommunicatorBenchmark:
264 def benchmark_allreduce_single(
265 self,
266 sequence_length: int,
267 - allreduce_fn: Callable[[torch.Tensor], Optional[torch.Tensor]],
267 + allreduce_fn: Callable[[torch.Tensor], torch.Tensor | None],
268 should_use_fn: Callable[[torch.Tensor], bool],
269 context,
270 num_warmup: int,
271 num_trials: int,
272 - ) -> Optional[float]:
272 + ) -> float | None:
273 """Benchmark method with CUDA graph optimization."""
274 try:
275 # Create test tensor (2D: sequence_length x hidden_size)
benchmarks/kernels/benchmark_lora.py
+11 -10
@@ -6,11 +6,12 @@ import copy
6 import json
7 import pickle
8 import time
9 +from collections.abc import Callable
10 from dataclasses import dataclass
11 from enum import Enum, auto
12 from itertools import product
13 from pathlib import Path
13 -from typing import Any, Callable, Optional
14 +from typing import Any
15
16 import torch
17 import torch.utils.benchmark as TBenchmark
@@ -158,7 +159,7 @@ def ref_group_gemm(
159 seq_lens_cpu: torch.Tensor,
160 prompt_lora_mapping_cpu: torch.Tensor,
161 scaling: float,
161 - add_inputs: Optional[bool],
162 + add_inputs: bool | None,
163 ):
164 """
165 Torch group gemm reference implementation to test correctness of
@@ -316,8 +317,8 @@ class BenchmarkContext:
317 lora_rank: int
318 sort_by_lora_id: bool
319 dtype: torch.dtype
319 - seq_length: Optional[int] = None
320 - num_slices: Optional[int] = None # num_slices for slice based ops
320 + seq_length: int | None = None
321 + num_slices: int | None = None # num_slices for slice based ops
322
323 def with_seq_length(self, seq_length: int) -> "BenchmarkContext":
324 ctx = copy.copy(self)
@@ -561,7 +562,7 @@ class BenchmarkTensors:
562 }
563
564 def bench_fn_kwargs(
564 - self, op_type: OpType, add_inputs: Optional[bool] = None
565 + self, op_type: OpType, add_inputs: bool | None = None
566 ) -> dict[str, Any]:
567 if op_type.is_shrink_fn():
568 assert add_inputs is None
@@ -575,7 +576,7 @@ class BenchmarkTensors:
576 raise ValueError(f"Unrecognized optype {self}")
577
578 def test_correctness(
578 - self, op_type: OpType, expand_fn_add_inputs: Optional[bool]
579 + self, op_type: OpType, expand_fn_add_inputs: bool | None
580 ) -> bool:
581 """
582 Test correctness of op_type implementation against a grouped gemm
@@ -611,8 +612,8 @@ def bench_optype(
612 ctx: BenchmarkContext,
613 arg_pool_size: int,
614 op_type: OpType,
614 - cuda_graph_nops: Optional[int] = None,
615 - expand_fn_add_inputs: Optional[bool] = None,
615 + cuda_graph_nops: int | None = None,
616 + expand_fn_add_inputs: bool | None = None,
617 test_correctness: bool = False,
618 ) -> TMeasurement:
619 assert arg_pool_size >= 1
@@ -679,7 +680,7 @@ def bench_torch_mm(
680 ctx: BenchmarkContext,
681 arg_pool_size: int,
682 op_type: OpType,
682 - cuda_graph_nops: Optional[int] = None,
683 + cuda_graph_nops: int | None = None,
684 ) -> TMeasurement:
685 """
686 Benchmark basic torch.mm as a roofline.
@@ -744,7 +745,7 @@ def use_cuda_graph_recommendation() -> str:
745 """
746
747
747 -def print_timers(timers: list[TMeasurement], args: Optional[argparse.Namespace] = None):
748 +def print_timers(timers: list[TMeasurement], args: argparse.Namespace | None = None):
749 compare = TBenchmark.Compare(timers)
750 compare.print()
751
benchmarks/kernels/benchmark_machete.py
+15 -16
@@ -8,10 +8,9 @@ import math
8 import os
9 import pickle as pkl
10 import time
11 -from collections.abc import Iterable
11 +from collections.abc import Callable, Iterable
12 from dataclasses import dataclass
13 from itertools import product
14 -from typing import Callable, Optional
14
15 import pandas as pd
16 import torch
@@ -63,23 +62,23 @@ class BenchmarkTensors:
62 a: torch.Tensor
63
64 w_q: torch.Tensor
66 - group_size: Optional[int]
65 + group_size: int | None
66 wtype: ScalarType
67 w_g_s: torch.Tensor
69 - w_g_zp: Optional[torch.Tensor]
70 - w_ch_s: Optional[torch.Tensor]
71 - w_tok_s: Optional[torch.Tensor]
68 + w_g_zp: torch.Tensor | None
69 + w_ch_s: torch.Tensor | None
70 + w_tok_s: torch.Tensor | None
71
72
73 @dataclass
74 class TypeConfig:
75 act_type: torch.dtype
76 weight_type: ScalarType
78 - output_type: Optional[torch.dtype]
79 - group_scale_type: Optional[torch.dtype]
80 - group_zero_type: Optional[torch.dtype]
81 - channel_scale_type: Optional[torch.dtype]
82 - token_scale_type: Optional[torch.dtype]
77 + output_type: torch.dtype | None
78 + group_scale_type: torch.dtype | None
79 + group_zero_type: torch.dtype | None
80 + channel_scale_type: torch.dtype | None
81 + token_scale_type: torch.dtype | None
82
83
84 def rand_data(shape, dtype=torch.float16, scale=1):
@@ -93,8 +92,8 @@ def quantize_and_pack(
92 atype: torch.dtype,
93 w: torch.Tensor,
94 wtype: ScalarType,
96 - stype: Optional[torch.dtype],
97 - group_size: Optional[int],
95 + stype: torch.dtype | None,
96 + group_size: int | None,
97 zero_points: bool = False,
98 ):
99 assert wtype.is_integer(), "TODO: support floating point weights"
@@ -113,7 +112,7 @@ def quantize_and_pack(
112
113
114 def create_bench_tensors(
116 - shape: tuple[int, int, int], types: TypeConfig, group_size: Optional[int]
115 + shape: tuple[int, int, int], types: TypeConfig, group_size: int | None
116 ) -> list[BenchmarkTensors]:
117 m, n, k = shape
118
@@ -331,8 +330,8 @@ def bench_fns(label: str, sub_label: str, description: str, fns: list[Callable])
330 return res
331
332
334 -_SWEEP_SCHEDULES_RESULTS: Optional[pd.DataFrame] = None
335 -_SWEEP_SCHEDULES_RESULTS_CSV: Optional[str] = None
333 +_SWEEP_SCHEDULES_RESULTS: pd.DataFrame | None = None
334 +_SWEEP_SCHEDULES_RESULTS_CSV: str | None = None
335
336
337 def bench(
benchmarks/kernels/benchmark_paged_attention.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import random
5 import time
6 -from typing import Optional
6
7 import torch
8
@@ -37,7 +36,7 @@ def main(
36 seed: int,
37 do_profile: bool,
38 device: str = "cuda",
40 - kv_cache_dtype: Optional[str] = None,
39 + kv_cache_dtype: str | None = None,
40 ) -> None:
41 current_platform.seed_everything(seed)
42
benchmarks/kernels/benchmark_per_token_group_quant.py
+1 -1
@@ -3,8 +3,8 @@
3
4 import argparse
5 import math
6 +from collections.abc import Callable
7 from contextlib import contextmanager
7 -from typing import Callable
8 from unittest.mock import patch
9
10 import torch
benchmarks/kernels/benchmark_reshape_and_cache.py
-2
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import random
4 import time
5
benchmarks/kernels/benchmark_reshape_and_cache_flash.py
-2
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import random
4 import time
5
benchmarks/kernels/benchmark_rmsnorm.py
+5 -6
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import itertools
5 -from typing import Optional, Union
5
6 import torch
7 from flashinfer.norm import fused_add_rmsnorm, rmsnorm
@@ -21,8 +20,8 @@ class HuggingFaceRMSNorm(nn.Module):
20 def forward(
21 self,
22 x: torch.Tensor,
24 - residual: Optional[torch.Tensor] = None,
25 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
23 + residual: torch.Tensor | None = None,
24 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
25 orig_dtype = x.dtype
26 x = x.to(torch.float32)
27 if residual is not None:
@@ -41,7 +40,7 @@ class HuggingFaceRMSNorm(nn.Module):
40 def rmsnorm_naive(
41 x: torch.Tensor,
42 weight: torch.Tensor,
44 - residual: Optional[torch.Tensor] = None,
43 + residual: torch.Tensor | None = None,
44 eps: float = 1e-6,
45 ):
46 naive_norm = HuggingFaceRMSNorm(x.shape[-1], eps=eps)
@@ -65,7 +64,7 @@ def rmsnorm_naive(
64 def rmsnorm_flashinfer(
65 x: torch.Tensor,
66 weight: torch.Tensor,
68 - residual: Optional[torch.Tensor] = None,
67 + residual: torch.Tensor | None = None,
68 eps: float = 1e-6,
69 ):
70 orig_shape = x.shape
@@ -89,7 +88,7 @@ def rmsnorm_flashinfer(
88 def rmsnorm_vllm(
89 x: torch.Tensor,
90 weight: torch.Tensor,
92 - residual: Optional[torch.Tensor] = None,
91 + residual: torch.Tensor | None = None,
92 eps: float = 1e-6,
93 ):
94 orig_shape = x.shape
benchmarks/kernels/benchmark_rope.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from itertools import accumulate
5 -from typing import Optional
5
6 import nvtx
7 import torch
@@ -18,7 +17,7 @@ def benchmark_rope_kernels_multi_lora(
17 seq_len: int,
18 num_heads: int,
19 head_size: int,
21 - rotary_dim: Optional[int],
20 + rotary_dim: int | None,
21 dtype: torch.dtype,
22 seed: int,
23 device: str,
benchmarks/kernels/benchmark_trtllm_decode_attention.py
+1 -4
@@ -4,7 +4,6 @@
4 import csv
5 import os
6 from datetime import datetime
7 -from typing import Optional
7
8 import flashinfer
9 import torch
@@ -28,9 +27,7 @@ def to_float8(x, dtype=torch.float8_e4m3fn):
27 @torch.no_grad()
28 def benchmark_decode(
29 dtype: torch.dtype,
31 - quant_dtypes: tuple[
32 - Optional[torch.dtype], Optional[torch.dtype], Optional[torch.dtype]
33 - ],
30 + quant_dtypes: tuple[torch.dtype | None, torch.dtype | None, torch.dtype | None],
31 batch_size: int,
32 max_seq_len: int,
33 num_heads: tuple[int, int] = (64, 8),
benchmarks/kernels/benchmark_trtllm_prefill_attention.py
+1 -4
@@ -4,7 +4,6 @@
4 import csv
5 import os
6 from datetime import datetime
7 -from typing import Optional
7
8 import flashinfer
9 import torch
@@ -28,9 +27,7 @@ def to_float8(x, dtype=torch.float8_e4m3fn):
27 @torch.no_grad()
28 def benchmark_prefill(
29 dtype: torch.dtype,
31 - quant_dtypes: tuple[
32 - Optional[torch.dtype], Optional[torch.dtype], Optional[torch.dtype]
33 - ],
30 + quant_dtypes: tuple[torch.dtype | None, torch.dtype | None, torch.dtype | None],
31 batch_size: int,
32 max_seq_len: int,
33 num_heads: tuple[int, int] = (64, 8),
benchmarks/kernels/utils.py
+3 -3
@@ -2,8 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import dataclasses
5 -from collections.abc import Iterable
6 -from typing import Any, Callable, Optional
5 +from collections.abc import Callable, Iterable
6 +from typing import Any
7
8 import torch
9 import torch.utils.benchmark as TBenchmark
@@ -55,7 +55,7 @@ class Bench:
55
56 def __init__(
57 self,
58 - cuda_graph_params: Optional[CudaGraphBenchParams],
58 + cuda_graph_params: CudaGraphBenchParams | None,
59 label: str,
60 sub_label: str,
61 description: str,
benchmarks/multi_turn/bench_dataset.py
+11 -11
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from abc import ABC, abstractmethod
4 from statistics import mean
5 -from typing import Any, NamedTuple, Optional, Union
5 +from typing import Any, NamedTuple
6
7 import numpy as np # type: ignore
8 import pandas as pd # type: ignore
@@ -35,8 +35,8 @@ class Distribution(ABC):
35 class UniformDistribution(Distribution):
36 def __init__(
37 self,
38 - min_val: Union[int, float],
39 - max_val: Union[int, float],
38 + min_val: int | float,
39 + max_val: int | float,
40 is_integer: bool = True,
41 ) -> None:
42 self.min_val = min_val
@@ -56,7 +56,7 @@ class UniformDistribution(Distribution):
56
57
58 class ConstantDistribution(Distribution):
59 - def __init__(self, value: Union[int, float]) -> None:
59 + def __init__(self, value: int | float) -> None:
60 self.value = value
61 self.max_val = value
62
@@ -68,7 +68,7 @@ class ConstantDistribution(Distribution):
68
69
70 class ZipfDistribution(Distribution):
71 - def __init__(self, alpha: float, max_val: Optional[int] = None) -> None:
71 + def __init__(self, alpha: float, max_val: int | None = None) -> None:
72 self.alpha = alpha
73 self.max_val = max_val
74
@@ -83,7 +83,7 @@ class ZipfDistribution(Distribution):
83
84
85 class PoissonDistribution(Distribution):
86 - def __init__(self, alpha: float, max_val: Optional[int] = None) -> None:
86 + def __init__(self, alpha: float, max_val: int | None = None) -> None:
87 self.alpha = alpha
88 self.max_val = max_val
89
@@ -100,11 +100,11 @@ class PoissonDistribution(Distribution):
100 class LognormalDistribution(Distribution):
101 def __init__(
102 self,
103 - mean: Optional[float] = None,
104 - sigma: Optional[float] = None,
105 - average: Optional[int] = None,
106 - median_ratio: Optional[float] = None,
107 - max_val: Optional[int] = None,
103 + mean: float | None = None,
104 + sigma: float | None = None,
105 + average: int | None = None,
106 + median_ratio: float | None = None,
107 + max_val: int | None = None,
108 ) -> None:
109 self.average = average
110 self.median_ratio = median_ratio
benchmarks/multi_turn/benchmark_serving_multi_turn.py
+5 -5
@@ -13,7 +13,7 @@ from datetime import datetime
13 from enum import Enum
14 from http import HTTPStatus
15 from statistics import mean
16 -from typing import NamedTuple, Union
16 +from typing import NamedTuple
17
18 import aiohttp # type: ignore
19 import numpy as np # type: ignore
@@ -169,7 +169,7 @@ class MovingAverage:
169 class DebugStats:
170 def __init__(self, logger: logging.Logger, window_size: int) -> None:
171 self.logger = logger
172 - self.metrics: dict[str, Union[MovingAverage, MetricStats]] = {
172 + self.metrics: dict[str, MovingAverage | MetricStats] = {
173 "moving_avg_ttft_ms": MovingAverage(window_size),
174 "moving_avg_tpot_ms": MovingAverage(window_size),
175 "ttft_ms": MetricStats(),
@@ -636,7 +636,7 @@ async def client_main(
636
637 if args.verbose:
638 curr_time_sec: float = time.perf_counter()
639 - time_since_last_turn: Union[str, float] = "N/A"
639 + time_since_last_turn: str | float = "N/A"
640 if conv_id in time_of_last_turn:
641 time_since_last_turn = round(
642 curr_time_sec - time_of_last_turn[conv_id], 3
@@ -928,13 +928,13 @@ async def main_mp(
928 f"{num_clients_finished} out of {bench_args.num_clients} clients finished, collected {len(client_metrics)} measurements, runtime {runtime_sec:.3f} sec{Color.RESET}" # noqa: E501
929 )
930
931 - rps: Union[str, float] = round(len(client_metrics) / runtime_sec, 3)
931 + rps: str | float = round(len(client_metrics) / runtime_sec, 3)
932 if len(client_metrics) < (5 * bench_args.num_clients):
933 # Do not estimate the RPS if the number of samples is very low
934 # (threshold can be tuned if needed)
935 rps = "N/A"
936
937 - runtime_left_sec: Union[str, float] = round(
937 + runtime_left_sec: str | float = round(
938 (runtime_sec / finished_convs) * (total_convs - finished_convs), 3
939 )
940 if percent < 0.05:
benchmarks/multi_turn/convert_sharegpt_to_openai.py
+9 -9
@@ -13,7 +13,7 @@ import argparse
13 import json
14 import random
15 from statistics import mean
16 -from typing import Any, Optional
16 +from typing import Any
17
18 import pandas as pd # type: ignore
19 import tqdm # type: ignore
@@ -25,7 +25,7 @@ def has_non_english_chars(text: str) -> bool:
25
26
27 def content_is_valid(
28 - content: str, min_content_len: Optional[int], max_content_len: Optional[int]
28 + content: str, min_content_len: int | None, max_content_len: int | None
29 ) -> bool:
30 if min_content_len and len(content) < min_content_len:
31 return False
@@ -37,7 +37,7 @@ def content_is_valid(
37
38
39 def print_stats(
40 - conversations: "list[dict[Any, Any]]", tokenizer: Optional[AutoTokenizer] = None
40 + conversations: "list[dict[Any, Any]]", tokenizer: AutoTokenizer | None = None
41 ) -> None:
42 # Collect statistics
43 stats = []
@@ -109,12 +109,12 @@ def convert_sharegpt_to_openai(
109 seed: int,
110 input_file: str,
111 output_file: str,
112 - max_items: Optional[int],
113 - min_content_len: Optional[int] = None,
114 - max_content_len: Optional[int] = None,
115 - min_turns: Optional[int] = None,
116 - max_turns: Optional[int] = None,
117 - model: Optional[str] = None,
112 + max_items: int | None,
113 + min_content_len: int | None = None,
114 + max_content_len: int | None = None,
115 + min_turns: int | None = None,
116 + max_turns: int | None = None,
117 + model: str | None = None,
118 ) -> None:
119 if min_turns and max_turns:
120 assert min_turns <= max_turns
csrc/cutlass_extensions/vllm_cutlass_library_extension.py
+6 -9
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import enum
5 -from typing import Union
5
6 from cutlass_library import *
7
@@ -22,7 +21,7 @@ class MixedInputKernelScheduleType(enum.Enum):
21 TmaWarpSpecializedCooperative = enum_auto()
22
23
25 -VLLMDataTypeNames: dict[Union[VLLMDataType, DataType], str] = {
24 +VLLMDataTypeNames: dict[VLLMDataType | DataType, str] = {
25 **DataTypeNames, # type: ignore
26 **{
27 VLLMDataType.u4b8: "u4b8",
@@ -30,7 +29,7 @@ VLLMDataTypeNames: dict[Union[VLLMDataType, DataType], str] = {
29 },
30 }
31
33 -VLLMDataTypeTag: dict[Union[VLLMDataType, DataType], str] = {
32 +VLLMDataTypeTag: dict[VLLMDataType | DataType, str] = {
33 **DataTypeTag, # type: ignore
34 **{
35 VLLMDataType.u4b8: "cutlass::vllm_uint4b8_t",
@@ -38,7 +37,7 @@ VLLMDataTypeTag: dict[Union[VLLMDataType, DataType], str] = {
37 },
38 }
39
41 -VLLMDataTypeSize: dict[Union[VLLMDataType, DataType], int] = {
40 +VLLMDataTypeSize: dict[VLLMDataType | DataType, int] = {
41 **DataTypeSize, # type: ignore
42 **{
43 VLLMDataType.u4b8: 4,
@@ -46,7 +45,7 @@ VLLMDataTypeSize: dict[Union[VLLMDataType, DataType], int] = {
45 },
46 }
47
49 -VLLMDataTypeVLLMScalarTypeTag: dict[Union[VLLMDataType, DataType], str] = {
48 +VLLMDataTypeVLLMScalarTypeTag: dict[VLLMDataType | DataType, str] = {
49 VLLMDataType.u4b8: "vllm::kU4B8",
50 VLLMDataType.u8b128: "vllm::kU8B128",
51 DataType.u4: "vllm::kU4",
@@ -57,7 +56,7 @@ VLLMDataTypeVLLMScalarTypeTag: dict[Union[VLLMDataType, DataType], str] = {
56 DataType.bf16: "vllm::kBfloat16",
57 }
58
60 -VLLMDataTypeTorchDataTypeTag: dict[Union[VLLMDataType, DataType], str] = {
59 +VLLMDataTypeTorchDataTypeTag: dict[VLLMDataType | DataType, str] = {
60 DataType.u8: "at::ScalarType::Byte",
61 DataType.s8: "at::ScalarType::Char",
62 DataType.e4m3: "at::ScalarType::Float8_e4m3fn",
@@ -67,9 +66,7 @@ VLLMDataTypeTorchDataTypeTag: dict[Union[VLLMDataType, DataType], str] = {
66 DataType.f32: "at::ScalarType::Float",
67 }
68
70 -VLLMKernelScheduleTag: dict[
71 - Union[MixedInputKernelScheduleType, KernelScheduleType], str
72 -] = {
69 +VLLMKernelScheduleTag: dict[MixedInputKernelScheduleType | KernelScheduleType, str] = {
70 **KernelScheduleTag, # type: ignore
71 **{
72 MixedInputKernelScheduleType.TmaWarpSpecialized: "cutlass::gemm::KernelTmaWarpSpecialized", # noqa: E501
csrc/quantization/machete/generate.py
+2 -3
@@ -9,7 +9,6 @@ from collections.abc import Iterable
9 from copy import deepcopy
10 from dataclasses import dataclass, fields
11 from functools import reduce
12 -from typing import Optional, Union
12
13 import jinja2
14 from vllm_cutlass_library_extension import (
@@ -259,7 +258,7 @@ class ScheduleConfig:
258 @dataclass(frozen=True)
259 class TypeConfig:
260 a: DataType
262 - b: Union[DataType, VLLMDataType]
261 + b: DataType | VLLMDataType
262 b_group_scale: DataType
263 b_group_zeropoint: DataType
264 b_channel_scale: DataType
@@ -280,7 +279,7 @@ class PrepackTypeConfig:
279 class ImplConfig:
280 types: TypeConfig
281 schedules: list[ScheduleConfig]
283 - heuristic: list[tuple[Optional[str], ScheduleConfig]]
282 + heuristic: list[tuple[str | None, ScheduleConfig]]
283
284
285 def generate_sch_sig(schedule_config: ScheduleConfig) -> str:
docs/contributing/model/transcription.md
+7 -7
@@ -16,7 +16,7 @@ Declare supported languages and capabilities:
16
17 ??? code "supported_languages and supports_transcription_only"
18 ```python
19 - from typing import ClassVar, Mapping, Optional, Literal
19 + from typing import ClassVar, Mapping, Literal
20 import numpy as np
21 import torch
22 from torch import nn
@@ -81,10 +81,10 @@ Return a dict containing `multi_modal_data` with the audio, and either a `prompt
81 audio: np.ndarray,
82 stt_config: SpeechToTextConfig,
83 model_config: ModelConfig,
84 - language: Optional[str],
84 + language: str | None,
85 task_type: Literal["transcribe", "translate"],
86 request_prompt: str,
87 - to_language: Optional[str],
87 + to_language: str | None,
88 ) -> PromptType:
89 # Example with a free-form instruction prompt
90 task_word = "Transcribe" if task_type == "transcribe" else "Translate"
@@ -117,10 +117,10 @@ Return a dict with separate `encoder_prompt` and `decoder_prompt` entries:
117 audio: np.ndarray,
118 stt_config: SpeechToTextConfig,
119 model_config: ModelConfig,
120 - language: Optional[str],
120 + language: str | None,
121 task_type: Literal["transcribe", "translate"],
122 request_prompt: str,
123 - to_language: Optional[str],
123 + to_language: str | None,
124 ) -> PromptType:
125 if language is None:
126 raise ValueError("Language must be specified")
@@ -150,7 +150,7 @@ If your model requires a language and you want a default, override this method (
150 ??? code "validate_language()"
151 ```python
152 @classmethod
153 - def validate_language(cls, language: Optional[str]) -> Optional[str]:
153 + def validate_language(cls, language: str | None) -> str | None:
154 if language is None:
155 logger.warning(
156 "Defaulting to language='en'. If you wish to transcribe audio in a different language, pass the `language` field.")
@@ -175,7 +175,7 @@ Provide a fast duration→token estimate to improve streaming usage statistics:
175 audio_duration_s: float,
176 stt_config: SpeechToTextConfig,
177 model_config: ModelConfig,
178 - ) -> Optional[int]:
178 + ) -> int | None:
179 # Return None if unknown; otherwise return an estimate.
180 return int(audio_duration_s * stt_config.sample_rate // 320) # example
181 ```
docs/design/logits_processors.md
+3 -3
@@ -174,7 +174,7 @@ The previous sections alluded to the interfaces which vLLM logits processors mus
174 from collections.abc import Sequence
175 from dataclasses import dataclass
176 from enum import Enum, auto
177 - from typing import TYPE_CHECKING, Optional
177 + from typing import TYPE_CHECKING
178
179 import torch
180
@@ -244,7 +244,7 @@ The previous sections alluded to the interfaces which vLLM logits processors mus
244 @abstractmethod
245 def update_state(
246 self,
247 - batch_update: Optional["BatchUpdate"],
247 + batch_update: "BatchUpdate" | None,
248 ) -> None:
249 """Called when there are new output tokens, prior
250 to each forward pass.
@@ -274,7 +274,7 @@ A vLLM logits processor must subclass `LogitsProcessor` and define (at minimum)
274 * Return `True` if the logits processor is argmax invariant (never changes what is the highest-logit-value token ID for a given request), `False` if the logits processor may modify argmax
275 * `is_argmax_invariant()` is evaluated once at startup; if `True`, vLLM will skip applying this logits processor in a given step when all requests use greedy sampling
276
277 -* `update_state(self, batch_update: Optional["BatchUpdate"]) -> None`:
277 +* `update_state(self, batch_update: "BatchUpdate" | None) -> None`:
278 * Consume a `BatchUpdate` data structure representing persistent batch state changes at the beginning of the current engine step
279 * Use the `BatchUpdate` members to update logits processor internal state
280 * **Note:** batch update data structure may be `None`, signaling no change to the batch constituents. In this case, the LogitsProcessor might still want to update its state based on the updated `output_token_ids` lists that it could have retained when they were added.
docs/features/custom_logitsprocs.md
+1 -2
@@ -93,7 +93,6 @@ The contrived example below implements a custom logits processor which consumes
93 ??? code "Example custom logits processor definition"
94
95 ``` python
96 - from typing import Optional
96 import torch
97 from vllm.config import VllmConfig
98 from vllm.sampling_params import SamplingParams
@@ -112,7 +111,7 @@ The contrived example below implements a custom logits processor which consumes
111 """Never impacts greedy sampling"""
112 return False
113
115 - def update_state(self, batch_update: Optional[BatchUpdate]):
114 + def update_state(self, batch_update: BatchUpdate | None):
115 if not batch_update:
116 return
117
examples/offline_inference/audio_language.py
+6 -6
@@ -10,7 +10,7 @@ on HuggingFace model repository.
10
11 import os
12 from dataclasses import asdict
13 -from typing import Any, NamedTuple, Optional
13 +from typing import Any, NamedTuple
14
15 from huggingface_hub import snapshot_download
16 from transformers import AutoTokenizer
@@ -30,11 +30,11 @@ question_per_audio_count = {
30
31 class ModelRequestData(NamedTuple):
32 engine_args: EngineArgs
33 - prompt: Optional[str] = None
34 - prompt_token_ids: Optional[dict[str, list[int]]] = None
35 - multi_modal_data: Optional[dict[str, Any]] = None
36 - stop_token_ids: Optional[list[int]] = None
37 - lora_requests: Optional[list[LoRARequest]] = None
33 + prompt: str | None = None
34 + prompt_token_ids: dict[str, list[int]] | None = None
35 + multi_modal_data: dict[str, Any] | None = None
36 + stop_token_ids: list[int] | None = None
37 + lora_requests: list[LoRARequest] | None = None
38
39
40 # NOTE: The default `max_num_seqs` and `max_model_len` may result in OOM on
examples/offline_inference/kv_load_failure_recovery/rogue_shared_storage_connector.py
+2 -2
@@ -3,7 +3,7 @@
3 # ruff: noqa: E501
4 import logging
5 from dataclasses import dataclass, field
6 -from typing import TYPE_CHECKING, Optional
6 +from typing import TYPE_CHECKING
7
8 from vllm.config import VllmConfig
9 from vllm.distributed.kv_transfer.kv_connector.v1.base import (
@@ -81,7 +81,7 @@ class RogueSharedStorageConnector(SharedStorageConnector):
81
82 def get_finished(
83 self, finished_req_ids: set[str]
84 - ) -> tuple[Optional[set[str]], Optional[set[str]]]:
84 + ) -> tuple[set[str] | None, set[str] | None]:
85 if self._async_load:
86 meta = self._get_connector_metadata()
87 assert isinstance(meta, RogueSharedStorageConnectorMetadata)
examples/offline_inference/logits_processor/custom.py
+1 -3
@@ -33,8 +33,6 @@ Output: ' in the hands of the people.\n\nThe future of AI is in the'
33 ------------------------------------------------------------
34 """
35
36 -from typing import Optional
37 -
36 import torch
37
38 from vllm import LLM, SamplingParams
@@ -58,7 +56,7 @@ class DummyLogitsProcessor(LogitsProcessor):
56 def is_argmax_invariant(self) -> bool:
57 return False
58
61 - def update_state(self, batch_update: Optional[BatchUpdate]):
59 + def update_state(self, batch_update: BatchUpdate | None):
60 process_dict_updates(
61 self.req_info,
62 batch_update,
examples/offline_inference/logits_processor/custom_req.py
+3 -3
@@ -39,7 +39,7 @@ Output: ' in the hands of the people.\n\nThe future of AI is in the'
39 ------------------------------------------------------------
40 """
41
42 -from typing import Any, Optional
42 +from typing import Any
43
44 import torch
45
@@ -82,7 +82,7 @@ class WrappedPerReqLogitsProcessor(AdapterLogitsProcessor):
82 def new_req_logits_processor(
83 self,
84 params: SamplingParams,
85 - ) -> Optional[RequestLogitsProcessor]:
85 + ) -> RequestLogitsProcessor | None:
86 """This method returns a new request-level logits processor, customized
87 to the `target_token` value associated with a particular request.
88
@@ -96,7 +96,7 @@ class WrappedPerReqLogitsProcessor(AdapterLogitsProcessor):
96 Returns:
97 `Callable` request logits processor, or None
98 """
99 - target_token: Optional[Any] = params.extra_args and params.extra_args.get(
99 + target_token: Any | None = params.extra_args and params.extra_args.get(
100 "target_token"
101 )
102 if target_token is None:
examples/offline_inference/logits_processor/custom_req_init.py
+1 -3
@@ -41,8 +41,6 @@ which indicates that the logits processor is running. However, on a non-"cuda"
41 device, the first and third requests would not repeat the same token.
42 """
43
44 -from typing import Optional
45 -
44 import torch
45
46 from vllm import LLM, SamplingParams
@@ -91,7 +89,7 @@ class WrappedPerReqLogitsProcessor(AdapterLogitsProcessor):
89 def new_req_logits_processor(
90 self,
91 params: SamplingParams,
94 - ) -> Optional[RequestLogitsProcessor]:
92 + ) -> RequestLogitsProcessor | None:
93 """This method returns a new request-level logits processor, customized
94 to the `target_token` value associated with a particular request.
95
examples/offline_inference/lora_with_quantization_inference.py
+3 -4
@@ -8,7 +8,6 @@ Requires HuggingFace credentials for access.
8 """
9
10 import gc
11 -from typing import Optional
11
12 import torch
13 from huggingface_hub import snapshot_download
@@ -19,7 +18,7 @@ from vllm.lora.request import LoRARequest
18
19 def create_test_prompts(
20 lora_path: str,
22 -) -> list[tuple[str, SamplingParams, Optional[LoRARequest]]]:
21 +) -> list[tuple[str, SamplingParams, LoRARequest | None]]:
22 return [
23 # this is an example of using quantization without LoRA
24 (
@@ -56,7 +55,7 @@ def create_test_prompts(
55
56 def process_requests(
57 engine: LLMEngine,
59 - test_prompts: list[tuple[str, SamplingParams, Optional[LoRARequest]]],
58 + test_prompts: list[tuple[str, SamplingParams, LoRARequest | None]],
59 ):
60 """Continuously process a list of prompts and handle the outputs."""
61 request_id = 0
@@ -78,7 +77,7 @@ def process_requests(
77
78
79 def initialize_engine(
81 - model: str, quantization: str, lora_repo: Optional[str]
80 + model: str, quantization: str, lora_repo: str | None
81 ) -> LLMEngine:
82 """Initialize the LLMEngine."""
83
examples/offline_inference/multilora_inference.py
+2 -4
@@ -7,8 +7,6 @@ for offline inference.
7 Requires HuggingFace credentials for access to Llama2.
8 """
9
10 -from typing import Optional
11 -
10 from huggingface_hub import snapshot_download
11
12 from vllm import EngineArgs, LLMEngine, RequestOutput, SamplingParams
@@ -17,7 +15,7 @@ from vllm.lora.request import LoRARequest
15
16 def create_test_prompts(
17 lora_path: str,
20 -) -> list[tuple[str, SamplingParams, Optional[LoRARequest]]]:
18 +) -> list[tuple[str, SamplingParams, LoRARequest | None]]:
19 """Create a list of test prompts with their sampling parameters.
20
21 2 requests for base model, 4 requests for the LoRA. We define 2
@@ -68,7 +66,7 @@ def create_test_prompts(
66
67 def process_requests(
68 engine: LLMEngine,
71 - test_prompts: list[tuple[str, SamplingParams, Optional[LoRARequest]]],
69 + test_prompts: list[tuple[str, SamplingParams, LoRARequest | None]],
70 ):
71 """Continuously process a list of prompts and handle the outputs."""
72 request_id = 0
examples/offline_inference/prithvi_geospatial_mae.py
+1 -2
@@ -3,7 +3,6 @@
3 import argparse
4 import datetime
5 import os
6 -from typing import Union
6
7 import albumentations
8 import numpy as np
@@ -160,7 +159,7 @@ def load_example(
159 file_paths: list[str],
160 mean: list[float] = None,
161 std: list[float] = None,
163 - indices: Union[list[int], None] = None,
162 + indices: list[int] | None = None,
163 ):
164 """Build an input example by loading images in *file_paths*.
165
examples/offline_inference/rlhf_utils.py
+4 -3
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import gc
4 -from typing import Callable, Optional, TypedDict
4 +from collections.abc import Callable
5 +from typing import TypedDict
6
7 import torch
8 import zmq
@@ -71,7 +72,7 @@ class WorkerExtension:
72
73
74 def rebuild_ipc(
74 - handle: tuple[Callable, tuple], device_id: Optional[int] = None
75 + handle: tuple[Callable, tuple], device_id: int | None = None
76 ) -> torch.Tensor:
77 func, args = handle
78 list_args = list(args)
@@ -109,7 +110,7 @@ class ColocateWorkerExtension:
110 self._zmq_ctx = zmq.Context()
111 socket = self._zmq_ctx.socket(zmq.REP)
112 socket.connect(zmq_handles[self.report_device_id()])
112 - buffer: Optional[torch.Tensor] = None
113 + buffer: torch.Tensor | None = None
114 while True:
115 payload: tuple[Callable, tuple] | list[FlattenedTensorMetadata] | None = (
116 socket.recv_pyobj()
examples/offline_inference/vision_language.py
+3 -3
@@ -12,7 +12,7 @@ import os
12 import random
13 from contextlib import contextmanager
14 from dataclasses import asdict
15 -from typing import NamedTuple, Optional
15 +from typing import NamedTuple
16
17 from huggingface_hub import snapshot_download
18 from transformers import AutoTokenizer
@@ -28,8 +28,8 @@ from vllm.utils import FlexibleArgumentParser
28 class ModelRequestData(NamedTuple):
29 engine_args: EngineArgs
30 prompts: list[str]
31 - stop_token_ids: Optional[list[int]] = None
32 - lora_requests: Optional[list[LoRARequest]] = None
31 + stop_token_ids: list[int] | None = None
32 + lora_requests: list[LoRARequest] | None = None
33
34
35 # NOTE: The default `max_num_seqs` and `max_model_len` may result in OOM on
examples/offline_inference/vision_language_multi_image.py
+6 -6
@@ -9,7 +9,7 @@ using the chat template defined by the model.
9 import os
10 from argparse import Namespace
11 from dataclasses import asdict
12 -from typing import NamedTuple, Optional
12 +from typing import NamedTuple
13
14 from huggingface_hub import snapshot_download
15 from PIL.Image import Image
@@ -41,9 +41,9 @@ class ModelRequestData(NamedTuple):
41 engine_args: EngineArgs
42 prompt: str
43 image_data: list[Image]
44 - stop_token_ids: Optional[list[int]] = None
45 - chat_template: Optional[str] = None
46 - lora_requests: Optional[list[LoRARequest]] = None
44 + stop_token_ids: list[int] | None = None
45 + chat_template: str | None = None
46 + lora_requests: list[LoRARequest] | None = None
47
48
49 # NOTE: The default `max_num_seqs` and `max_model_len` may result in OOM on
@@ -1251,7 +1251,7 @@ model_example_map = {
1251 }
1252
1253
1254 -def run_generate(model, question: str, image_urls: list[str], seed: Optional[int]):
1254 +def run_generate(model, question: str, image_urls: list[str], seed: int | None):
1255 req_data = model_example_map[model](question, image_urls)
1256
1257 engine_args = asdict(req_data.engine_args) | {"seed": args.seed}
@@ -1277,7 +1277,7 @@ def run_generate(model, question: str, image_urls: list[str], seed: Optional[int
1277 print("-" * 50)
1278
1279
1280 -def run_chat(model: str, question: str, image_urls: list[str], seed: Optional[int]):
1280 +def run_chat(model: str, question: str, image_urls: list[str], seed: int | None):
1281 req_data = model_example_map[model](question, image_urls)
1282
1283 # Disable other modalities to save memory
examples/offline_inference/vision_language_pooling.py
+8 -8
@@ -11,7 +11,7 @@ on HuggingFace model repository.
11 from argparse import Namespace
12 from dataclasses import asdict
13 from pathlib import Path
14 -from typing import Literal, NamedTuple, Optional, TypedDict, Union, get_args
14 +from typing import Literal, NamedTuple, TypeAlias, TypedDict, get_args
15
16 from PIL.Image import Image
17
@@ -47,15 +47,15 @@ class TextImagesQuery(TypedDict):
47
48
49 QueryModality = Literal["text", "image", "text+image", "text+images"]
50 -Query = Union[TextQuery, ImageQuery, TextImageQuery, TextImagesQuery]
50 +Query: TypeAlias = TextQuery | ImageQuery | TextImageQuery | TextImagesQuery
51
52
53 class ModelRequestData(NamedTuple):
54 engine_args: EngineArgs
55 - prompt: Optional[str] = None
56 - image: Optional[Image] = None
57 - query: Optional[str] = None
58 - documents: Optional[ScoreMultiModalParam] = None
55 + prompt: str | None = None
56 + image: Image | None = None
57 + query: str | None = None
58 + documents: ScoreMultiModalParam | None = None
59
60
61 def run_clip(query: Query) -> ModelRequestData:
@@ -281,7 +281,7 @@ def get_query(modality: QueryModality):
281 raise ValueError(msg)
282
283
284 -def run_encode(model: str, modality: QueryModality, seed: Optional[int]):
284 +def run_encode(model: str, modality: QueryModality, seed: int | None):
285 query = get_query(modality)
286 req_data = model_example_map[model](query)
287
@@ -311,7 +311,7 @@ def run_encode(model: str, modality: QueryModality, seed: Optional[int]):
311 print("-" * 50)
312
313
314 -def run_score(model: str, modality: QueryModality, seed: Optional[int]):
314 +def run_score(model: str, modality: QueryModality, seed: int | None):
315 query = get_query(modality)
316 req_data = model_example_map[model](query)
317
examples/online_serving/disaggregated_serving/disagg_proxy_demo.py
+7 -10
@@ -23,7 +23,7 @@ import logging
23 import os
24 import sys
25 from abc import ABC, abstractmethod
26 -from typing import Callable, Optional
26 +from collections.abc import Callable
27
28 import aiohttp
29 import requests
@@ -49,12 +49,9 @@ class Proxy:
49 decode_instances: list[str],
50 model: str,
51 scheduling_policy: SchedulingPolicy,
52 - custom_create_completion: Optional[
53 - Callable[[Request], StreamingResponse]
54 - ] = None,
55 - custom_create_chat_completion: Optional[
56 - Callable[[Request], StreamingResponse]
57 - ] = None,
52 + custom_create_completion: Callable[[Request], StreamingResponse] | None = None,
53 + custom_create_chat_completion: Callable[[Request], StreamingResponse]
54 + | None = None,
55 ):
56 self.prefill_instances = prefill_instances
57 self.decode_instances = decode_instances
@@ -348,9 +345,9 @@ class ProxyServer:
345 def __init__(
346 self,
347 args: argparse.Namespace,
351 - scheduling_policy: Optional[SchedulingPolicy] = None,
352 - create_completion: Optional[Callable[[Request], StreamingResponse]] = None,
353 - create_chat_completion: Optional[Callable[[Request], StreamingResponse]] = None,
348 + scheduling_policy: SchedulingPolicy | None = None,
349 + create_completion: Callable[[Request], StreamingResponse] | None = None,
350 + create_chat_completion: Callable[[Request], StreamingResponse] | None = None,
351 ):
352 self.validate_parsed_serve_args(args)
353 self.port = args.port
examples/online_serving/kv_events_subscriber.py
+6 -6
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, Optional, Union
3 +from typing import Any
4
5 import msgspec
6 import zmq
@@ -25,16 +25,16 @@ class KVCacheEvent(
25
26 class BlockStored(KVCacheEvent):
27 block_hashes: list[ExternalBlockHash]
28 - parent_block_hash: Optional[ExternalBlockHash]
28 + parent_block_hash: ExternalBlockHash | None
29 token_ids: list[int]
30 block_size: int
31 - lora_id: Optional[int]
32 - medium: Optional[str]
31 + lora_id: int | None
32 + medium: str | None
33
34
35 class BlockRemoved(KVCacheEvent):
36 block_hashes: list[ExternalBlockHash]
37 - medium: Optional[str]
37 + medium: str | None
38
39
40 class AllBlocksCleared(KVCacheEvent):
@@ -42,7 +42,7 @@ class AllBlocksCleared(KVCacheEvent):
42
43
44 class KVEventBatch(EventBatch):
45 - events: list[Union[BlockStored, BlockRemoved, AllBlocksCleared]]
45 + events: list[BlockStored | BlockRemoved | AllBlocksCleared]
46
47
48 def process_event(event_batch):
examples/online_serving/multi_instance_data_parallel.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import asyncio
4 -from typing import Optional
4
5 from vllm.engine.arg_utils import AsyncEngineArgs
6 from vllm.engine.async_llm_engine import AsyncLLMEngine
@@ -43,7 +42,7 @@ async def main():
42 )
43
44 prompt = "Who won the 2004 World Series?"
46 - final_output: Optional[RequestOutput] = None
45 + final_output: RequestOutput | None = None
46 async for output in engine_client.generate(
47 prompt=prompt,
48 sampling_params=sampling_params,
examples/online_serving/pooling/cohere_rerank_client.py
+1 -3
@@ -8,8 +8,6 @@ Note that `pip install cohere` is needed to run this example.
8 run: vllm serve BAAI/bge-reranker-base
9 """
10
11 -from typing import Union
12 -
11 import cohere
12 from cohere import Client, ClientV2
13
@@ -25,7 +23,7 @@ documents = [
23
24
25 def cohere_rerank(
28 - client: Union[Client, ClientV2], model: str, query: str, documents: list[str]
26 + client: Client | ClientV2, model: str, query: str, documents: list[str]
27 ) -> dict:
28 return client.rerank(model=model, query=query, documents=documents)
29
examples/online_serving/pooling/openai_chat_embedding_client_for_multimodal.py
+2 -2
@@ -9,7 +9,7 @@ Refer to each `run_*` function for the command to run the server for that model.
9 import argparse
10 import base64
11 import io
12 -from typing import Literal, Union
12 +from typing import Literal
13
14 from openai import OpenAI
15 from openai._types import NOT_GIVEN, NotGiven
@@ -29,7 +29,7 @@ def create_chat_embeddings(
29 *,
30 messages: list[ChatCompletionMessageParam],
31 model: str,
32 - encoding_format: Union[Literal["base64", "float"], NotGiven] = NOT_GIVEN,
32 + encoding_format: Literal["base64", "float"] | NotGiven = NOT_GIVEN,
33 ) -> CreateEmbeddingResponse:
34 """
35 Convenience function for accessing vLLM's Chat Embeddings API,
examples/online_serving/structured_outputs/structured_outputs.py
+2 -8
@@ -1,21 +1,15 @@
1 # ruff: noqa: E501
2 # SPDX-License-Identifier: Apache-2.0
3 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4 -
5 -from __future__ import annotations
6 -
4 import argparse
5 import asyncio
6 import enum
7 import os
11 -from typing import TYPE_CHECKING, Any, Literal
8 +from typing import Any, Literal
9
10 import openai
11 import pydantic
15 -
16 -if TYPE_CHECKING:
17 - from openai.types.chat import ChatCompletionChunk
18 -
12 +from openai.types.chat import ChatCompletionChunk
13
14 ConstraintsFormat = Literal[
15 "choice",
pyproject.toml
-6
@@ -84,12 +84,6 @@ ignore = [
84 "B007",
85 # f-string format
86 "UP032",
87 - # Can remove once 3.10+ is the minimum Python version
88 - "UP007",
89 - "UP027",
90 - "UP035",
91 - "UP038",
92 - "UP045",
87 ]
88
89 [tool.ruff.format]
tests/benchmarks/test_random_dataset.py
+3 -3
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import random
4 -from typing import Any, NamedTuple, Optional, cast
4 +from typing import Any, NamedTuple, cast
5
6 import numpy as np
7 import pytest
@@ -185,8 +185,8 @@ def _collect_mm_samples(
185 output_len: int = 5,
186 base_items_per_request: int = 2,
187 num_mm_items_range_ratio: float = 0.0,
188 - limit_mm_per_prompt: Optional[dict[str, int]] = None,
189 - bucket_config: Optional[dict[tuple[int, int, int], float]] = None,
188 + limit_mm_per_prompt: dict[str, int] | None = None,
189 + bucket_config: dict[tuple[int, int, int], float] | None = None,
190 enable_multimodal_chat: bool = False,
191 ) -> list[SampleRequest]:
192 if limit_mm_per_prompt is None:
tests/ci_envs.py
+5 -4
@@ -5,13 +5,14 @@ These envs only work for a small part of the tests, fix what you need!
5 """
6
7 import os
8 -from typing import TYPE_CHECKING, Any, Callable, Optional
8 +from collections.abc import Callable
9 +from typing import TYPE_CHECKING, Any
10
11 if TYPE_CHECKING:
12 VLLM_CI_NO_SKIP: bool = False
12 - VLLM_CI_DTYPE: Optional[str] = None
13 - VLLM_CI_HEAD_DTYPE: Optional[str] = None
14 - VLLM_CI_HF_DTYPE: Optional[str] = None
13 + VLLM_CI_DTYPE: str | None = None
14 + VLLM_CI_HEAD_DTYPE: str | None = None
15 + VLLM_CI_HF_DTYPE: str | None = None
16
17 environment_variables: dict[str, Callable[[], Any]] = {
18 # A model family has many models with the same architecture.
tests/compile/backend.py
+2 -3
@@ -2,9 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import weakref
5 -from collections.abc import Sequence
5 +from collections.abc import Callable, Sequence
6 from copy import deepcopy
7 -from typing import Callable, Union
7
8 from torch import fx
9 from torch._ops import OpOverload
@@ -44,7 +43,7 @@ class TestBackend:
43 Inductor config is default-initialized from VllmConfig.CompilationConfig.
44 """
45
47 - def __init__(self, *passes: Union[InductorPass, Callable[[fx.Graph], None]]):
46 + def __init__(self, *passes: InductorPass | Callable[[fx.Graph], None]):
47 self.custom_passes = list(passes)
48 compile_config = get_current_vllm_config().compilation_config
49 self.inductor_config = compile_config.inductor_compile_config
tests/compile/piecewise/test_toy_llama.py
+3 -3
@@ -10,7 +10,7 @@ initialized randomly with a fixed seed.
10 """
11
12 from dataclasses import dataclass
13 -from typing import Any, Optional
13 +from typing import Any
14
15 import pytest
16 import torch
@@ -162,7 +162,7 @@ class LlamaDecoderLayer(nn.Module):
162 self,
163 positions: torch.Tensor,
164 hidden_states: torch.Tensor,
165 - residual: Optional[torch.Tensor],
165 + residual: torch.Tensor | None,
166 ) -> tuple[torch.Tensor, torch.Tensor]:
167 """
168 For tractable computation:
@@ -217,7 +217,7 @@ class LlamaModel(nn.Module):
217
218 def forward(
219 self,
220 - input_ids: Optional[torch.Tensor],
220 + input_ids: torch.Tensor | None,
221 positions: torch.Tensor,
222 ) -> torch.Tensor:
223 hidden_states = self.embedding_tokens(input_ids)
tests/compile/test_basic_correctness.py
-2
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import dataclasses
4
5 import pytest
tests/compile/test_full_graph.py
+2 -4
@@ -1,11 +1,9 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import logging
5 import tempfile
8 -from typing import Any, Union
6 +from typing import Any
7
8 import pytest
9 import torch
@@ -217,7 +215,7 @@ def test_inductor_graph_partition_attn_fusion(caplog_vllm):
215
216
217 def run_model(
220 - compile_config: Union[int, CompilationConfig],
218 + compile_config: int | CompilationConfig,
219 model: str,
220 model_kwargs: dict[str, Any],
221 ):
tests/compile/test_fusion_attn.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import copy
4 -from typing import Optional
4
5 import pytest
6 import torch._dynamo
@@ -41,8 +40,8 @@ FP8_DTYPE = current_platform.fp8_dtype()
40 FP4_DTYPE = torch.uint8
41
42 # globals needed for string-import custom Dynamo backend field
44 -backend: Optional[TestBackend] = None
45 -backend_unfused: Optional[TestBackend] = None
43 +backend: TestBackend | None = None
44 +backend_unfused: TestBackend | None = None
45
46
47 class AttentionQuantPatternModel(torch.nn.Module):
tests/compile/test_wrapper.py
+3 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -10,7 +9,7 @@ from vllm.config import CompilationLevel
9
10
11 class MyMod(torch.nn.Module):
13 - def forward(self, x: torch.Tensor, cache: Optional[torch.Tensor] = None):
12 + def forward(self, x: torch.Tensor, cache: torch.Tensor | None = None):
13 if cache is not None:
14 return x + cache
15 return x * 2
@@ -24,11 +23,11 @@ class MyWrapper(TorchCompileWrapperWithCustomDispatcher):
23 compiled_callable, compilation_level=CompilationLevel.DYNAMO_ONCE
24 )
25
27 - def forward(self, x: torch.Tensor, cache: Optional[torch.Tensor] = None):
26 + def forward(self, x: torch.Tensor, cache: torch.Tensor | None = None):
27 # this is the function to be compiled
28 return self.model(x, cache)
29
31 - def __call__(self, x: torch.Tensor, cache: Optional[torch.Tensor] = None):
30 + def __call__(self, x: torch.Tensor, cache: torch.Tensor | None = None):
31 # let torch.compile compile twice
32 if len(self.compiled_codes) == 2:
33 dispatch_id = 0 if cache is None else 1
tests/conftest.py
+73 -75
@@ -21,7 +21,7 @@ import threading
21 from collections.abc import Generator
22 from contextlib import nullcontext
23 from enum import Enum
24 -from typing import Any, Callable, Optional, TypedDict, TypeVar, Union, cast
24 +from typing import Any, Callable, TypedDict, TypeVar, cast
25
26 import numpy as np
27 import pytest
@@ -68,7 +68,7 @@ _SYS_MSG = os.path.join(_TEST_DIR, "system_messages", "sonnet3.5_nov2024.txt")
68
69 _M = TypeVar("_M")
70
71 -_PromptMultiModalInput = Union[list[_M], list[list[_M]]]
71 +_PromptMultiModalInput = list[_M] | list[list[_M]]
72
73 PromptImageInput = _PromptMultiModalInput[Image.Image]
74 PromptAudioInput = _PromptMultiModalInput[tuple[np.ndarray, int]]
@@ -267,7 +267,7 @@ class HfRunner:
267
268 return "cpu" if current_platform.is_cpu() else current_platform.device_type
269
270 - def wrap_device(self, x: _T, device: Optional[str] = None) -> _T:
270 + def wrap_device(self, x: _T, device: str | None = None) -> _T:
271 if x is None or isinstance(x, (bool,)):
272 return x
273
@@ -287,14 +287,14 @@ class HfRunner:
287 model_name: str,
288 dtype: str = "auto",
289 *,
290 - model_kwargs: Optional[dict[str, Any]] = None,
290 + model_kwargs: dict[str, Any] | None = None,
291 trust_remote_code: bool = True,
292 is_sentence_transformer: bool = False,
293 is_cross_encoder: bool = False,
294 skip_tokenizer_init: bool = False,
295 auto_cls: type[_BaseAutoModelClass] = AutoModelForCausalLM,
296 # Set this to avoid hanging issue
297 - default_torch_num_threads: Optional[int] = None,
297 + default_torch_num_threads: int | None = None,
298 ) -> None:
299 init_ctx = (
300 nullcontext()
@@ -319,7 +319,7 @@ class HfRunner:
319 model_name: str,
320 dtype: str = "auto",
321 *,
322 - model_kwargs: Optional[dict[str, Any]] = None,
322 + model_kwargs: dict[str, Any] | None = None,
323 trust_remote_code: bool = True,
324 is_sentence_transformer: bool = False,
325 is_cross_encoder: bool = False,
@@ -406,11 +406,11 @@ class HfRunner:
406
407 def get_inputs(
408 self,
409 - prompts: Union[list[str], list[list[int]]],
410 - images: Optional[PromptImageInput] = None,
411 - videos: Optional[PromptVideoInput] = None,
412 - audios: Optional[PromptAudioInput] = None,
413 - ) -> list[Union[BatchFeature, BatchEncoding, dict[str, torch.Tensor]]]:
409 + prompts: list[str] | list[list[int]],
410 + images: PromptImageInput | None = None,
411 + videos: PromptVideoInput | None = None,
412 + audios: PromptAudioInput | None = None,
413 + ) -> list[BatchFeature | BatchEncoding | dict[str, torch.Tensor]]:
414 if images is not None:
415 assert len(prompts) == len(images)
416
@@ -420,9 +420,7 @@ class HfRunner:
420 if audios is not None:
421 assert len(prompts) == len(audios)
422
423 - all_inputs: list[
424 - Union[BatchFeature, BatchEncoding, dict[str, torch.Tensor]]
425 - ] = []
423 + all_inputs: list[BatchFeature | BatchEncoding | dict[str, torch.Tensor]] = []
424 for i, prompt in enumerate(prompts):
425 if isinstance(prompt, str):
426 processor_kwargs: dict[str, Any] = {
@@ -494,10 +492,10 @@ class HfRunner:
492
493 def generate(
494 self,
497 - prompts: Union[list[str], list[list[int]]],
498 - images: Optional[PromptImageInput] = None,
499 - videos: Optional[PromptVideoInput] = None,
500 - audios: Optional[PromptAudioInput] = None,
495 + prompts: list[str] | list[list[int]],
496 + images: PromptImageInput | None = None,
497 + videos: PromptVideoInput | None = None,
498 + audios: PromptAudioInput | None = None,
499 **kwargs: Any,
500 ) -> list[tuple[list[list[int]], list[str]]]:
501 all_inputs = self.get_inputs(
@@ -522,11 +520,11 @@ class HfRunner:
520
521 def generate_greedy(
522 self,
525 - prompts: Union[list[str], list[list[int]]],
523 + prompts: list[str] | list[list[int]],
524 max_tokens: int,
527 - images: Optional[PromptImageInput] = None,
528 - videos: Optional[PromptVideoInput] = None,
529 - audios: Optional[PromptAudioInput] = None,
525 + images: PromptImageInput | None = None,
526 + videos: PromptVideoInput | None = None,
527 + audios: PromptAudioInput | None = None,
528 **kwargs: Any,
529 ) -> list[tuple[list[int], str]]:
530 outputs = self.generate(
@@ -546,9 +544,9 @@ class HfRunner:
544 prompts: list[str],
545 beam_width: int,
546 max_tokens: int,
549 - images: Optional[PromptImageInput] = None,
550 - videos: Optional[PromptVideoInput] = None,
551 - audios: Optional[PromptAudioInput] = None,
547 + images: PromptImageInput | None = None,
548 + videos: PromptVideoInput | None = None,
549 + audios: PromptAudioInput | None = None,
550 ) -> list[tuple[list[list[int]], list[str]]]:
551 outputs = self.generate(
552 prompts,
@@ -574,9 +572,9 @@ class HfRunner:
572 self,
573 prompts: list[str],
574 max_tokens: int,
577 - images: Optional[PromptImageInput] = None,
578 - videos: Optional[PromptVideoInput] = None,
579 - audios: Optional[PromptAudioInput] = None,
575 + images: PromptImageInput | None = None,
576 + videos: PromptVideoInput | None = None,
577 + audios: PromptAudioInput | None = None,
578 **kwargs: Any,
579 ) -> list[list[torch.Tensor]]:
580 all_inputs = self.get_inputs(
@@ -624,7 +622,7 @@ class HfRunner:
622 def _hidden_states_to_logprobs(
623 self,
624 hidden_states: tuple[tuple[torch.Tensor, ...], ...],
627 - num_logprobs: Optional[int],
625 + num_logprobs: int | None,
626 ) -> tuple[list[dict[int, float]], int]:
627 seq_logprobs = self._hidden_states_to_seq_logprobs(hidden_states)
628 output_len = len(hidden_states)
@@ -652,10 +650,10 @@ class HfRunner:
650 self,
651 prompts: list[str],
652 max_tokens: int,
655 - num_logprobs: Optional[int],
656 - images: Optional[PromptImageInput] = None,
657 - audios: Optional[PromptAudioInput] = None,
658 - videos: Optional[PromptVideoInput] = None,
653 + num_logprobs: int | None,
654 + images: PromptImageInput | None = None,
655 + audios: PromptAudioInput | None = None,
656 + videos: PromptVideoInput | None = None,
657 **kwargs: Any,
658 ) -> list[TokensTextLogprobs]:
659 all_inputs = self.get_inputs(
@@ -734,20 +732,20 @@ class VllmRunner:
732 model_name: str,
733 runner: RunnerOption = "auto",
734 convert: ConvertOption = "auto",
737 - tokenizer_name: Optional[str] = None,
735 + tokenizer_name: str | None = None,
736 tokenizer_mode: str = "auto",
737 trust_remote_code: bool = True,
740 - seed: Optional[int] = 0,
741 - max_model_len: Optional[int] = 1024,
738 + seed: int | None = 0,
739 + max_model_len: int | None = 1024,
740 dtype: str = "auto",
741 disable_log_stats: bool = True,
742 tensor_parallel_size: int = 1,
743 block_size: int = 16 if not torch.xpu.is_available() else 64,
746 - enable_chunked_prefill: Optional[bool] = False,
744 + enable_chunked_prefill: bool | None = False,
745 swap_space: int = 4,
748 - enforce_eager: Optional[bool] = False,
746 + enforce_eager: bool | None = False,
747 # Set this to avoid hanging issue
750 - default_torch_num_threads: Optional[int] = None,
748 + default_torch_num_threads: int | None = None,
749 **kwargs,
750 ) -> None:
751 init_ctx = (
@@ -785,10 +783,10 @@ class VllmRunner:
783
784 def get_inputs(
785 self,
788 - prompts: Union[list[str], list[torch.Tensor], list[list[int]]],
789 - images: Optional[PromptImageInput] = None,
790 - videos: Optional[PromptVideoInput] = None,
791 - audios: Optional[PromptAudioInput] = None,
786 + prompts: list[str] | list[torch.Tensor] | list[list[int]],
787 + images: PromptImageInput | None = None,
788 + videos: PromptVideoInput | None = None,
789 + audios: PromptAudioInput | None = None,
790 ) -> list[dict[str, Any]]:
791 if any(
792 x is not None and len(x) != len(prompts) for x in [images, videos, audios]
@@ -824,11 +822,11 @@ class VllmRunner:
822
823 def generate(
824 self,
827 - prompts: Union[list[str], list[torch.Tensor], list[list[int]]],
825 + prompts: list[str] | list[torch.Tensor] | list[list[int]],
826 sampling_params: SamplingParams,
829 - images: Optional[PromptImageInput] = None,
830 - videos: Optional[PromptVideoInput] = None,
831 - audios: Optional[PromptAudioInput] = None,
827 + images: PromptImageInput | None = None,
828 + videos: PromptVideoInput | None = None,
829 + audios: PromptAudioInput | None = None,
830 **kwargs: Any,
831 ) -> list[tuple[list[list[int]], list[str]]]:
832 inputs = self.get_inputs(prompts, images=images, videos=videos, audios=audios)
@@ -871,11 +869,11 @@ class VllmRunner:
869 self,
870 prompts: list[str],
871 sampling_params: SamplingParams,
874 - images: Optional[PromptImageInput] = None,
875 - audios: Optional[PromptAudioInput] = None,
876 - videos: Optional[PromptVideoInput] = None,
872 + images: PromptImageInput | None = None,
873 + audios: PromptAudioInput | None = None,
874 + videos: PromptVideoInput | None = None,
875 **kwargs: Any,
878 - ) -> Union[list[TokensTextLogprobs], list[TokensTextLogprobsPromptLogprobs]]:
876 + ) -> list[TokensTextLogprobs] | list[TokensTextLogprobsPromptLogprobs]:
877 inputs = self.get_inputs(prompts, images=images, videos=videos, audios=audios)
878
879 req_outputs = self.llm.generate(
@@ -894,11 +892,11 @@ class VllmRunner:
892
893 def generate_greedy(
894 self,
897 - prompts: Union[list[str], list[torch.Tensor], list[list[int]]],
895 + prompts: list[str] | list[torch.Tensor] | list[list[int]],
896 max_tokens: int,
899 - images: Optional[PromptImageInput] = None,
900 - videos: Optional[PromptVideoInput] = None,
901 - audios: Optional[PromptAudioInput] = None,
897 + images: PromptImageInput | None = None,
898 + videos: PromptVideoInput | None = None,
899 + audios: PromptAudioInput | None = None,
900 **kwargs: Any,
901 ) -> list[tuple[list[int], str]]:
902 greedy_params = SamplingParams(temperature=0.0, max_tokens=max_tokens)
@@ -916,15 +914,15 @@ class VllmRunner:
914 self,
915 prompts: list[str],
916 max_tokens: int,
919 - num_logprobs: Optional[int],
920 - num_prompt_logprobs: Optional[int] = None,
921 - images: Optional[PromptImageInput] = None,
922 - audios: Optional[PromptAudioInput] = None,
923 - videos: Optional[PromptVideoInput] = None,
924 - stop_token_ids: Optional[list[int]] = None,
925 - stop: Optional[list[str]] = None,
917 + num_logprobs: int | None,
918 + num_prompt_logprobs: int | None = None,
919 + images: PromptImageInput | None = None,
920 + audios: PromptAudioInput | None = None,
921 + videos: PromptVideoInput | None = None,
922 + stop_token_ids: list[int] | None = None,
923 + stop: list[str] | None = None,
924 **kwargs: Any,
927 - ) -> Union[list[TokensTextLogprobs], list[TokensTextLogprobsPromptLogprobs]]:
925 + ) -> list[TokensTextLogprobs] | list[TokensTextLogprobsPromptLogprobs]:
926 greedy_logprobs_params = SamplingParams(
927 temperature=0.0,
928 max_tokens=max_tokens,
@@ -957,7 +955,7 @@ class VllmRunner:
955 perplexities = []
956 for output in outputs:
957 output = cast(TokensTextLogprobsPromptLogprobs, output)
960 - token_datas = cast(list[Optional[dict[int, Logprob]]], output[3])
958 + token_datas = cast(list[dict[int, Logprob] | None], output[3])
959 assert token_datas[0] is None
960 token_log_probs = []
961 for token_data in token_datas[1:]:
@@ -976,10 +974,10 @@ class VllmRunner:
974 prompts: list[str],
975 beam_width: int,
976 max_tokens: int,
979 - images: Optional[PromptImageInput] = None,
980 - videos: Optional[PromptVideoInput] = None,
981 - audios: Optional[PromptAudioInput] = None,
982 - concurrency_limit: Optional[int] = None,
977 + images: PromptImageInput | None = None,
978 + videos: PromptVideoInput | None = None,
979 + audios: PromptAudioInput | None = None,
980 + concurrency_limit: int | None = None,
981 ) -> list[tuple[list[list[int]], list[str]]]:
982 inputs = self.get_inputs(prompts, images=images, videos=videos, audios=audios)
983
@@ -1002,9 +1000,9 @@ class VllmRunner:
1000 def embed(
1001 self,
1002 prompts: list[str],
1005 - images: Optional[PromptImageInput] = None,
1006 - videos: Optional[PromptVideoInput] = None,
1007 - audios: Optional[PromptAudioInput] = None,
1003 + images: PromptImageInput | None = None,
1004 + videos: PromptVideoInput | None = None,
1005 + audios: PromptAudioInput | None = None,
1006 *args,
1007 **kwargs,
1008 ) -> list[list[float]]:
@@ -1023,8 +1021,8 @@ class VllmRunner:
1021
1022 def score(
1023 self,
1026 - text_1: Union[str, list[str]],
1027 - text_2: Union[str, list[str]],
1024 + text_1: list[str] | str,
1025 + text_2: list[str] | str,
1026 *args,
1027 **kwargs,
1028 ) -> list[float]:
@@ -1226,8 +1224,8 @@ def _find_free_port() -> int:
1224 class LocalAssetServer:
1225 address: str
1226 port: int
1229 - server: Optional[http.server.ThreadingHTTPServer]
1230 - thread: Optional[threading.Thread]
1227 + server: http.server.ThreadingHTTPServer | None
1228 + thread: threading.Thread | None
1229
1230 def __init__(self, address: str = "127.0.0.1") -> None:
1231 self.address = address
tests/detokenizer/test_stop_strings.py
+3 -3
@@ -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 Any, Optional
4 +from typing import Any
5
6 import pytest
7
@@ -15,8 +15,8 @@ def _test_stopping(
15 llm: LLM,
16 expected_output: str,
17 expected_reason: Any,
18 - stop: Optional[list[str]] = None,
19 - stop_token_ids: Optional[list[int]] = None,
18 + stop: list[str] | None = None,
19 + stop_token_ids: list[int] | None = None,
20 include_in_output: bool = False,
21 ) -> None:
22 output = llm.generate(
tests/distributed/conftest.py
+3 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import random
4 -from typing import Optional, Union
4
5 import msgspec
6 import msgspec.msgpack
@@ -78,8 +77,8 @@ class MockSubscriber:
77
78 def __init__(
79 self,
81 - pub_endpoints: Union[str, list[str]],
82 - replay_endpoints: Optional[Union[str, list[str]]] = None,
80 + pub_endpoints: str | list[str],
81 + replay_endpoints: str | list[str] | None = None,
82 topic: str = "",
83 decode_type=SampleBatch,
84 ):
@@ -111,7 +110,7 @@ class MockSubscriber:
110 self.last_seq = -1
111 self.decoder = msgspec.msgpack.Decoder(type=decode_type)
112
114 - def receive_one(self, timeout=1000) -> Union[tuple[int, SampleBatch], None]:
113 + def receive_one(self, timeout=1000) -> tuple[int, SampleBatch] | None:
114 """Receive a single message with timeout"""
115 if not self.sub.poll(timeout):
116 return None
tests/distributed/test_comm_ops.py
+2 -3
@@ -5,9 +5,8 @@
5 Run `pytest tests/distributed/test_comm_ops.py`.
6 """
7
8 -from __future__ import annotations
9 -
10 -from typing import Any, Callable
8 +from collections.abc import Callable
9 +from typing import Any
10
11 import pytest
12 import ray
tests/distributed/test_context_parallel.py
+3 -3
@@ -11,7 +11,7 @@ WARNING: This test runs in both single-node (4 GPUs) and multi-node
11 import json
12 import os
13 from dataclasses import dataclass
14 -from typing import Literal, NamedTuple, Optional
14 +from typing import Literal, NamedTuple
15
16 import pytest
17
@@ -36,7 +36,7 @@ class ParallelSetup(NamedTuple):
36
37 class CPTestOptions(NamedTuple):
38 multi_node_only: bool
39 - load_format: Optional[str] = None
39 + load_format: str | None = None
40
41
42 @dataclass
@@ -54,7 +54,7 @@ class CPTestSettings:
54 dcp_base: int = 1,
55 multi_node_only: bool = False,
56 runner: RunnerOption = "auto",
57 - load_format: Optional[str] = None,
57 + load_format: str | None = None,
58 ):
59 parallel_setups = []
60 for eager_mode_val in [False]:
tests/distributed/test_expert_parallel.py
+10 -10
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import Literal, NamedTuple, Optional
5 +from typing import Literal, NamedTuple
6
7 import pytest
8
@@ -22,9 +22,9 @@ class ParallelSetup(NamedTuple):
22
23 class EPTestOptions(NamedTuple):
24 trust_remote_code: bool
25 - tokenizer_mode: Optional[str]
26 - load_format: Optional[str] = None
27 - hf_overrides: Optional[str] = None
25 + tokenizer_mode: str | None
26 + load_format: str | None = None
27 + hf_overrides: str | None = None
28
29
30 @dataclass
@@ -40,9 +40,9 @@ class EPTestSettings:
40 tp_base: int = 2,
41 runner: RunnerOption = "auto",
42 trust_remote_code: bool = False,
43 - tokenizer_mode: Optional[str] = None,
44 - load_format: Optional[str] = None,
45 - hf_overrides: Optional[str] = None,
43 + tokenizer_mode: str | None = None,
44 + load_format: str | None = None,
45 + hf_overrides: str | None = None,
46 ):
47 return EPTestSettings(
48 parallel_setups=[
@@ -72,9 +72,9 @@ class EPTestSettings:
72 tp_base: int = 2,
73 runner: RunnerOption = "auto",
74 trust_remote_code: bool = False,
75 - tokenizer_mode: Optional[str] = None,
76 - load_format: Optional[str] = None,
77 - hf_overrides: Optional[str] = None,
75 + tokenizer_mode: str | None = None,
76 + load_format: str | None = None,
77 + hf_overrides: str | None = None,
78 ):
79 return EPTestSettings(
80 parallel_setups=[
tests/distributed/test_pipeline_parallel.py
+4 -4
@@ -11,7 +11,7 @@ WARNING: This test runs in both single-node (4 GPUs) and multi-node
11 import json
12 import os
13 from dataclasses import dataclass
14 -from typing import Literal, NamedTuple, Optional
14 +from typing import Literal, NamedTuple
15
16 import pytest
17
@@ -35,7 +35,7 @@ class ParallelSetup(NamedTuple):
35
36 class PPTestOptions(NamedTuple):
37 multi_node_only: bool
38 - load_format: Optional[str] = None
38 + load_format: str | None = None
39
40
41 @dataclass
@@ -52,7 +52,7 @@ class PPTestSettings:
52 pp_base: int = 2,
53 multi_node_only: bool = False,
54 runner: RunnerOption = "auto",
55 - load_format: Optional[str] = None,
55 + load_format: str | None = None,
56 ):
57 return PPTestSettings(
58 parallel_setups=[
@@ -76,7 +76,7 @@ class PPTestSettings:
76 pp_base: int = 2,
77 runner: RunnerOption = "auto",
78 multi_node_only: bool = False,
79 - load_format: Optional[str] = None,
79 + load_format: str | None = None,
80 ):
81 return PPTestSettings(
82 parallel_setups=[
tests/distributed/test_pp_cudagraph.py
+1 -7
@@ -1,16 +1,10 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
5 -from typing import TYPE_CHECKING
6 -
3 import pytest
4 +from typing_extensions import LiteralString
5
6 from ..utils import compare_two_settings, create_new_process_for_each_test
7
11 -if TYPE_CHECKING:
12 - from typing_extensions import LiteralString
13 -
8
9 @pytest.mark.parametrize(
10 "PP_SIZE, MODEL_NAME",
tests/distributed/test_sequence_parallel.py
+5 -5
@@ -11,7 +11,7 @@ WARNING: This test runs in both single-node (4 GPUs) and multi-node
11 import json
12 import os
13 from dataclasses import dataclass
14 -from typing import Literal, NamedTuple, Optional
14 +from typing import Literal, NamedTuple
15
16 import pytest
17
@@ -36,7 +36,7 @@ class ParallelSetup(NamedTuple):
36
37 class SPTestOptions(NamedTuple):
38 multi_node_only: bool
39 - load_format: Optional[str] = None
39 + load_format: str | None = None
40
41
42 @dataclass
@@ -53,7 +53,7 @@ class SPTestSettings:
53 pp_base: int = 1,
54 multi_node_only: bool = False,
55 runner: RunnerOption = "auto",
56 - load_format: Optional[str] = None,
56 + load_format: str | None = None,
57 ):
58 parallel_setups = []
59 for eager_mode_val in [False, True]:
@@ -84,7 +84,7 @@ class SPTestSettings:
84 pp_base: int = 1,
85 runner: RunnerOption = "auto",
86 multi_node_only: bool = False,
87 - load_format: Optional[str] = None,
87 + load_format: str | None = None,
88 ):
89 parallel_setups = []
90 for eager_mode_val in [False, True]:
@@ -115,7 +115,7 @@ class SPTestSettings:
115 pp_base: int = 1,
116 runner: RunnerOption = "auto",
117 multi_node_only: bool = False,
118 - load_format: Optional[str] = None,
118 + load_format: str | None = None,
119 ):
120 parallel_setups = []
121 for fusion_val in [False, True]:
tests/engine/test_arg_utils.py
+8 -8
@@ -5,7 +5,7 @@ import json
5 from argparse import ArgumentError
6 from contextlib import nullcontext
7 from dataclasses import dataclass, field
8 -from typing import Annotated, Literal, Optional, Union
8 +from typing import Annotated, Literal
9
10 import pytest
11
@@ -115,9 +115,9 @@ class NestedConfig:
115 class DummyConfig:
116 regular_bool: bool = True
117 """Regular bool with default True"""
118 - optional_bool: Optional[bool] = None
118 + optional_bool: bool | None = None
119 """Optional bool with default None"""
120 - optional_literal: Optional[Literal["x", "y"]] = None
120 + optional_literal: Literal["x", "y"] | None = None
121 """Optional literal with default None"""
122 tuple_n: tuple[int, ...] = field(default_factory=lambda: (1, 2, 3))
123 """Tuple with variable length"""
@@ -127,7 +127,7 @@ class DummyConfig:
127 """List with variable length"""
128 list_literal: list[Literal[1, 2]] = field(default_factory=list)
129 """List with literal choices"""
130 - list_union: list[Union[str, type[object]]] = field(default_factory=list)
130 + list_union: list[str | type[object]] = field(default_factory=list)
131 """List with union type"""
132 literal_literal: Literal[Literal[1], Literal[2]] = 1
133 """Literal of literals with default 1"""
@@ -152,11 +152,11 @@ def test_is_not_builtin(type_hint, expected):
152 ("type_hint", "expected"),
153 [
154 (Annotated[int, "annotation"], {int}),
155 - (Optional[int], {int, type(None)}),
156 - (Annotated[Optional[int], "annotation"], {int, type(None)}),
157 - (Optional[Annotated[int, "annotation"]], {int, type(None)}),
155 + (int | None, {int, type(None)}),
156 + (Annotated[int | None, "annotation"], {int, type(None)}),
157 + (Annotated[int, "annotation"] | None, {int, type(None)}),
158 ],
159 - ids=["Annotated", "Optional", "Annotated_Optional", "Optional_Annotated"],
159 + ids=["Annotated", "or_None", "Annotated_or_None", "or_None_Annotated"],
160 )
161 def test_get_type_hints(type_hint, expected):
162 assert get_type_hints(type_hint) == expected
tests/entrypoints/openai/test_async_tokenization.py
+1 -1
@@ -3,7 +3,7 @@
3
4 import asyncio
5 import random
6 -from typing import Callable
6 +from collections.abc import Callable
7
8 import openai
9 import pytest
tests/entrypoints/openai/test_chat.py
+1 -2
@@ -3,7 +3,6 @@
3
4 # imports for structured outputs tests
5 import json
6 -from typing import Optional
6
7 import jsonschema
8 import openai # use the official client for correctness check
@@ -176,7 +175,7 @@ async def test_too_many_chat_logprobs(client: openai.AsyncOpenAI, model_name: st
175 [(MODEL_NAME, 1), (MODEL_NAME, 0), (MODEL_NAME, -1), (MODEL_NAME, None)],
176 )
177 async def test_prompt_logprobs_chat(
179 - client: openai.AsyncOpenAI, model_name: str, prompt_logprobs: Optional[int]
178 + client: openai.AsyncOpenAI, model_name: str, prompt_logprobs: int | None
179 ):
180 params: dict = {
181 "messages": [
tests/entrypoints/openai/test_completion_with_function_calling.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import datetime
5 -from typing import Union
5
6 import openai # use the official client for correctness check
7 import pytest
@@ -166,7 +165,7 @@ async def test_function_tool_use(
165 client: openai.AsyncOpenAI,
166 model_name: str,
167 stream: bool,
169 - tool_choice: Union[str, dict],
168 + tool_choice: str | dict,
169 enable_thinking: bool,
170 ):
171 if not stream:
tests/entrypoints/openai/test_lora_resolvers.py
+5 -6
@@ -4,7 +4,6 @@
4 from contextlib import suppress
5 from dataclasses import dataclass, field
6 from http import HTTPStatus
7 -from typing import Optional
7 from unittest.mock import AsyncMock, MagicMock
8
9 import pytest
@@ -38,13 +37,13 @@ class MockModelConfig:
37 trust_remote_code: bool = False
38 tokenizer_mode: str = "auto"
39 max_model_len: int = 100
41 - tokenizer_revision: Optional[str] = None
40 + tokenizer_revision: str | None = None
41 multimodal_config: MultiModalConfig = field(default_factory=MultiModalConfig)
42 hf_config: MockHFConfig = field(default_factory=MockHFConfig)
44 - logits_processor_pattern: Optional[str] = None
45 - diff_sampling_param: Optional[dict] = None
43 + logits_processor_pattern: str | None = None
44 + diff_sampling_param: dict | None = None
45 allowed_local_media_path: str = ""
47 - allowed_media_domains: Optional[list[str]] = None
46 + allowed_media_domains: list[str] | None = None
47 encoder_config = None
48 generation_config: str = "auto"
49 skip_tokenizer_init: bool = False
@@ -56,7 +55,7 @@ class MockModelConfig:
55 class MockLoRAResolver(LoRAResolver):
56 async def resolve_lora(
57 self, base_model_name: str, lora_name: str
59 - ) -> Optional[LoRARequest]:
58 + ) -> LoRARequest | None:
59 if lora_name == "test-lora":
60 return LoRARequest(
61 lora_name="test-lora",
tests/entrypoints/openai/test_serving_chat.py
+2 -7
@@ -1,16 +1,14 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -
4 -from __future__ import annotations
5 -
3 import asyncio
4 from contextlib import suppress
5 from dataclasses import dataclass, field
9 -from typing import TYPE_CHECKING, Any
6 +from typing import Any
7 from unittest.mock import AsyncMock, MagicMock
8
9 import pytest
10 import pytest_asyncio
11 +from openai import OpenAI
12
13 from vllm.config.multimodal import MultiModalConfig
14 from vllm.entrypoints.openai.protocol import ChatCompletionRequest
@@ -21,9 +19,6 @@ from vllm.v1.engine.async_llm import AsyncLLM
19
20 from ...utils import RemoteOpenAIServer
21
24 -if TYPE_CHECKING:
25 - from openai import OpenAI
26 -
22 GPT_OSS_MODEL_NAME = "openai/gpt-oss-20b"
23
24
tests/entrypoints/openai/tool_parsers/utils.py
+4 -5
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable
5 -from typing import Union
5
6 from vllm.entrypoints.openai.protocol import (
7 ChatCompletionRequest,
@@ -84,10 +83,10 @@ class StreamingToolReconstructor:
83 def run_tool_extraction(
84 tool_parser: ToolParser,
85 model_output: str,
87 - request: Union[ChatCompletionRequest, None] = None,
86 + request: ChatCompletionRequest | None = None,
87 streaming: bool = False,
88 assert_one_tool_per_delta: bool = True,
90 -) -> tuple[Union[str, None], list[ToolCall]]:
89 +) -> tuple[str | None, list[ToolCall]]:
90 if streaming:
91 reconstructor = run_tool_extraction_streaming(
92 tool_parser,
@@ -105,7 +104,7 @@ def run_tool_extraction(
104 def run_tool_extraction_nonstreaming(
105 tool_parser: ToolParser,
106 model_output: str,
108 - request: Union[ChatCompletionRequest, None] = None,
107 + request: ChatCompletionRequest | None = None,
108 ) -> ExtractedToolCallInformation:
109 request = request or ChatCompletionRequest(messages=[], model="test-model")
110 return tool_parser.extract_tool_calls(model_output, request)
@@ -114,7 +113,7 @@ def run_tool_extraction_nonstreaming(
113 def run_tool_extraction_streaming(
114 tool_parser: ToolParser,
115 model_deltas: Iterable[str],
117 - request: Union[ChatCompletionRequest, None] = None,
116 + request: ChatCompletionRequest | None = None,
117 assert_one_tool_per_delta: bool = True,
118 ) -> StreamingToolReconstructor:
119 request = request or ChatCompletionRequest(messages=[], model="test-model")
tests/entrypoints/pooling/openai/test_embedding_dimensions.py
+2 -4
@@ -4,8 +4,6 @@
4 Run `pytest tests/entrypoints/openai/test_embedding_dimensions.py`.
5 """
6
7 -from typing import Optional
8 -
7 import openai
8 import pytest
9
@@ -103,14 +101,14 @@ async def test_matryoshka(
101 run_embedding_correctness_test(hf_model, prompts, vllm_outputs, dimensions)
102
103 if model_info.is_matryoshka:
106 - valid_dimensions: list[Optional[int]] = [None]
104 + valid_dimensions: list[int | None] = [None]
105 if model_info.matryoshka_dimensions is not None:
106 valid_dimensions += model_info.matryoshka_dimensions[:2]
107
108 for dimensions in valid_dimensions:
109 await make_request_and_correctness_test(dimensions)
110
113 - invalid_dimensions: list[Optional[int]] = [-1]
111 + invalid_dimensions: list[int | None] = [-1]
112 if model_info.matryoshka_dimensions is not None:
113 assert 5 not in model_info.matryoshka_dimensions
114 invalid_dimensions.append(5)
tests/entrypoints/test_api_server_process_manager.py
+2 -3
@@ -5,7 +5,6 @@ import multiprocessing
5 import socket
6 import threading
7 import time
8 -from typing import Optional
8 from unittest.mock import patch
9
10 import pytest
@@ -105,7 +104,7 @@ def test_wait_for_completion_or_failure(api_server_args):
104 assert len(manager.processes) == 3
105
106 # Create a result capture for the thread
108 - result: dict[str, Optional[Exception]] = {"exception": None}
107 + result: dict[str, Exception | None] = {"exception": None}
108
109 def run_with_exception_capture():
110 try:
@@ -218,7 +217,7 @@ def test_external_process_monitoring(api_server_args):
217 assert len(manager.processes) == 3
218
219 # Create a result capture for the thread
221 - result: dict[str, Optional[Exception]] = {"exception": None}
220 + result: dict[str, Exception | None] = {"exception": None}
221
222 def run_with_exception_capture():
223 try:
tests/entrypoints/test_chat_utils.py
+7 -7
@@ -3,7 +3,7 @@
3
4 import warnings
5 from collections.abc import Mapping
6 -from typing import Literal, Optional
6 +from typing import Literal
7
8 import pytest
9 from mistral_common.tokens.tokenizers.base import SpecialTokenPolicy
@@ -152,9 +152,9 @@ def audio_url():
152
153
154 def _assert_mm_data_is_image_input(
155 - mm_data: Optional[MultiModalDataDict],
155 + mm_data: MultiModalDataDict | None,
156 image_count: int,
157 - skipped_image_indices: Optional[list] = None,
157 + skipped_image_indices: list | None = None,
158 ) -> None:
159 assert mm_data is not None
160 assert set(mm_data.keys()) == {"image"}
@@ -169,9 +169,9 @@ def _assert_mm_data_is_image_input(
169
170
171 def _assert_mm_uuids(
172 - mm_uuids: Optional[MultiModalUUIDDict],
172 + mm_uuids: MultiModalUUIDDict | None,
173 media_count: int,
174 - expected_uuids: list[Optional[str]],
174 + expected_uuids: list[str | None],
175 modality: str = "image",
176 ) -> None:
177 if len(expected_uuids) > 0:
@@ -193,9 +193,9 @@ MultiModalDataCounts = Mapping[ModalityType, int]
193
194
195 def _assert_mm_data_inputs(
196 - mm_data: Optional[MultiModalDataDict],
196 + mm_data: MultiModalDataDict | None,
197 data_count: MultiModalDataCounts,
198 - skipped_media_indices: Optional[dict[str, list]] = None, # modality -> list[int]
198 + skipped_media_indices: dict[str, list] | None = None, # modality -> list[int]
199 ) -> None:
200 assert mm_data is not None
201 assert set(data_count.keys()) == (set(mm_data.keys()))
tests/entrypoints/test_renderer.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import io
5 from dataclasses import dataclass
6 -from typing import Optional
6 from unittest.mock import AsyncMock, MagicMock
7
8 import pybase64
@@ -17,7 +16,7 @@ from vllm.inputs.data import is_embeds_prompt
16 @dataclass
17 class MockModelConfig:
18 max_model_len: int = 100
20 - encoder_config: Optional[dict] = None
19 + encoder_config: dict | None = None
20
21
22 class MockTokenizerResult:
tests/evals/gsm8k/gsm8k_eval.py
+6 -7
@@ -12,7 +12,6 @@ import json
12 import os
13 import time
14 from collections.abc import Generator
15 -from typing import Optional, Union
15
16 import aiohttp
17 import numpy as np
@@ -23,7 +22,7 @@ from tqdm.asyncio import tqdm
22 INVALID = -9999999
23
24
26 -def download_and_cache_file(url: str, filename: Optional[str] = None) -> str:
25 +def download_and_cache_file(url: str, filename: str | None = None) -> str:
26 """Download and cache a file from a URL."""
27 if filename is None:
28 filename = os.path.join("/tmp", url.split("/")[-1])
@@ -81,9 +80,9 @@ async def call_vllm_api(
80 prompt: str,
81 temperature: float,
82 max_tokens: int,
84 - stop: Optional[list[str]] = None,
85 - url: Optional[str] = None,
86 - seed: Optional[int] = None,
83 + stop: list[str] | None = None,
84 + url: str | None = None,
85 + seed: int | None = None,
86 ) -> str:
87 """Call vLLM's OpenAI-compatible completions endpoint."""
88 data = {
@@ -112,8 +111,8 @@ def evaluate_gsm8k(
111 host: str = "http://127.0.0.1",
112 port: int = 8000,
113 temperature: float = 0.0,
115 - seed: Optional[int] = 42,
116 -) -> dict[str, Union[float, int]]:
114 + seed: int | None = 42,
115 +) -> dict[str, float | int]:
116 """
117 Evaluate GSM8K accuracy using vLLM serve endpoint.
118
tests/kernels/attention/test_aiter_flash_attn.py
+5 -6
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import pytest
6 import torch
@@ -27,8 +26,8 @@ def ref_paged_attn(
26 kv_lens: list[int],
27 block_tables: torch.Tensor,
28 scale: float,
30 - sliding_window: Optional[int] = None,
31 - soft_cap: Optional[float] = None,
29 + sliding_window: int | None = None,
30 + soft_cap: float | None = None,
31 ) -> torch.Tensor:
32 num_seqs = len(query_lens)
33 block_tables = block_tables.cpu().numpy()
@@ -94,12 +93,12 @@ def test_varlen_with_paged_kv(
93 seq_lens: list[tuple[int, int]],
94 num_heads: tuple[int, int],
95 head_size: int,
97 - sliding_window: Optional[int],
96 + sliding_window: int | None,
97 dtype: torch.dtype,
98 block_size: int,
100 - soft_cap: Optional[float],
99 + soft_cap: float | None,
100 num_blocks: int,
102 - q_dtype: Optional[torch.dtype],
101 + q_dtype: torch.dtype | None,
102 ) -> None:
103 torch.set_default_device("cuda")
104 current_platform.seed_everything(0)
tests/kernels/attention/test_attention.py
+3 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import random
5 -from typing import Optional
5
6 import pytest
7 import torch
@@ -50,7 +49,7 @@ def ref_masked_attention(
49 key: torch.Tensor,
50 value: torch.Tensor,
51 scale: float,
53 - attn_mask: Optional[torch.Tensor] = None,
52 + attn_mask: torch.Tensor | None = None,
53 ) -> torch.Tensor:
54 attn_weights = scale * torch.einsum("qhd,khd->hqk", query, key).float()
55 if attn_mask is not None:
@@ -69,7 +68,7 @@ def ref_single_query_cached_kv_attention(
68 block_tables: torch.Tensor,
69 seq_lens: torch.Tensor,
70 scale: float,
72 - alibi_slopes: Optional[torch.Tensor],
71 + alibi_slopes: torch.Tensor | None,
72 ) -> None:
73 num_query_heads = query.shape[1]
74 num_kv_heads = value_cache.shape[1]
@@ -415,7 +414,7 @@ def ref_multi_query_kv_attention(
414 key: torch.Tensor,
415 value: torch.Tensor,
416 scale: float,
418 - alibi_bias: Optional[list[torch.Tensor]],
417 + alibi_bias: list[torch.Tensor] | None,
418 dtype: torch.dtype,
419 ) -> torch.Tensor:
420 num_seqs = len(cu_seq_lens) - 1
tests/kernels/attention/test_cascade_flash_attn.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import pytest
6 import torch
@@ -85,7 +84,7 @@ def test_cascade(
84 head_size: int,
85 dtype: torch.dtype,
86 block_size: int,
88 - soft_cap: Optional[float],
87 + soft_cap: float | None,
88 num_blocks: int,
89 fa_version: int,
90 ) -> None:
tests/kernels/attention/test_cutlass_mla_decode.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import math
4 import random
5 -from typing import Optional
5
6 import pytest
7 import torch
@@ -17,7 +16,7 @@ def cal_diff(
16 y: torch.Tensor,
17 name: str,
18 use_fp8: bool = False,
20 - diff_threshold: Optional[float] = None,
19 + diff_threshold: float | None = None,
20 ) -> None:
21 x, y = x.double(), y.double()
22 cos_diff = 1 - 2 * (x * y).sum().item() / max((x * x + y * y).sum().item(), 1e-12)
tests/kernels/attention/test_flash_attn.py
+8 -9
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import pytest
6 import torch
@@ -34,8 +33,8 @@ def ref_paged_attn(
33 kv_lens: list[int],
34 block_tables: torch.Tensor,
35 scale: float,
37 - sliding_window: Optional[int] = None,
38 - soft_cap: Optional[float] = None,
36 + sliding_window: int | None = None,
37 + soft_cap: float | None = None,
38 ) -> torch.Tensor:
39 num_seqs = len(query_lens)
40 block_tables = block_tables.cpu().numpy()
@@ -103,11 +102,11 @@ def test_flash_attn_with_paged_kv(
102 head_size: int,
103 dtype: torch.dtype,
104 block_size: int,
106 - soft_cap: Optional[float],
105 + soft_cap: float | None,
106 num_blocks: int,
108 - sliding_window: Optional[int],
107 + sliding_window: int | None,
108 fa_version: int,
110 - q_dtype: Optional[torch.dtype],
109 + q_dtype: torch.dtype | None,
110 ) -> None:
111 torch.set_default_device("cuda")
112 if not is_fa_version_supported(fa_version):
@@ -221,13 +220,13 @@ def test_varlen_with_paged_kv(
220 seq_lens: list[tuple[int, int]],
221 num_heads: tuple[int, int],
222 head_size: int,
224 - sliding_window: Optional[int],
223 + sliding_window: int | None,
224 dtype: torch.dtype,
225 block_size: int,
227 - soft_cap: Optional[float],
226 + soft_cap: float | None,
227 num_blocks: int,
228 fa_version: int,
230 - q_dtype: Optional[torch.dtype],
229 + q_dtype: torch.dtype | None,
230 ) -> None:
231 torch.set_default_device("cuda")
232 if not is_fa_version_supported(fa_version):
tests/kernels/attention/test_flashinfer.py
+8 -9
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import flashinfer
6 import pytest
@@ -26,8 +25,8 @@ def ref_paged_attn(
25 kv_lens: list[int],
26 block_tables: torch.Tensor,
27 scale: float,
29 - sliding_window: Optional[int] = None,
30 - soft_cap: Optional[float] = None,
28 + sliding_window: int | None = None,
29 + soft_cap: float | None = None,
30 ) -> torch.Tensor:
31 num_seqs = len(query_lens)
32 block_tables = block_tables.cpu().numpy()
@@ -90,8 +89,8 @@ def test_flashinfer_decode_with_paged_kv(
89 head_size: int,
90 dtype: torch.dtype,
91 block_size: int,
93 - soft_cap: Optional[float],
94 - sliding_window: Optional[int],
92 + soft_cap: float | None,
93 + sliding_window: int | None,
94 ) -> None:
95 torch.set_default_device("cuda")
96 current_platform.seed_everything(0)
@@ -185,8 +184,8 @@ def test_flashinfer_prefill_with_paged_kv(
184 head_size: int,
185 dtype: torch.dtype,
186 block_size: int,
188 - soft_cap: Optional[float],
189 - sliding_window: Optional[int],
187 + soft_cap: float | None,
188 + sliding_window: int | None,
189 ) -> None:
190 torch.set_default_device("cuda")
191 current_platform.seed_everything(0)
@@ -288,7 +287,7 @@ def test_flashinfer_prefill_with_paged_fp8_kv(
287 head_size: int,
288 dtype: torch.dtype,
289 block_size: int,
291 - soft_cap: Optional[float],
290 + soft_cap: float | None,
291 ) -> None:
292 pytest.skip("TODO: fix the accuracy issue")
293 torch.set_default_device("cuda")
@@ -398,7 +397,7 @@ def test_flashinfer_decode_with_paged_fp8_kv(
397 head_size: int,
398 dtype: torch.dtype,
399 block_size: int,
401 - soft_cap: Optional[float],
400 + soft_cap: float | None,
401 ) -> None:
402 # test doesn't work for num_heads = (16,16)
403 torch.set_default_device("cuda")
tests/kernels/attention/test_flashinfer_trtllm_attention.py
+4 -9
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import flashinfer
5 import pytest
@@ -68,9 +67,7 @@ NUM_BLOCKS = 32768 # Large enough to test overflow in index calculation.
67 @torch.inference_mode
68 def test_flashinfer_trtllm_decode_with_baseline(
69 dtype: torch.dtype,
71 - quant_dtypes: tuple[
72 - Optional[torch.dtype], Optional[torch.dtype], Optional[torch.dtype]
73 - ],
70 + quant_dtypes: tuple[torch.dtype | None, torch.dtype | None, torch.dtype | None],
71 batch_size: int,
72 max_seq_lens: tuple[int, int],
73 num_heads: tuple[int, int],
@@ -78,7 +75,7 @@ def test_flashinfer_trtllm_decode_with_baseline(
75 kv_layout: str,
76 block_size: int,
77 window_left: int,
81 - soft_cap: Optional[float],
78 + soft_cap: float | None,
79 has_sinks: bool,
80 ) -> None:
81 torch.set_default_device("cuda")
@@ -267,9 +264,7 @@ def test_flashinfer_trtllm_decode_with_baseline(
264 @torch.inference_mode
265 def test_flashinfer_trtllm_prefill_with_baseline(
266 dtype: torch.dtype,
270 - quant_dtypes: tuple[
271 - Optional[torch.dtype], Optional[torch.dtype], Optional[torch.dtype]
272 - ],
267 + quant_dtypes: tuple[torch.dtype | None, torch.dtype | None, torch.dtype | None],
268 batch_size: int,
269 max_seq_lens: tuple[int, int],
270 num_heads: tuple[int, int],
@@ -277,7 +272,7 @@ def test_flashinfer_trtllm_prefill_with_baseline(
272 kv_layout: str,
273 block_size: int,
274 window_left: int,
280 - soft_cap: Optional[float],
275 + soft_cap: float | None,
276 has_sinks: bool,
277 ) -> None:
278 torch.set_default_device("cuda")
tests/kernels/attention/test_merge_attn_states.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import pytest
5 import torch
@@ -20,7 +19,7 @@ def merge_attn_states_torch(
19 prefix_lse: torch.Tensor, # [NUM_HEADS, NUM_TOKENS]
20 suffix_output: torch.Tensor, # [NUM_TOKENS, NUM_HEADS, HEAD_SIZE]
21 suffix_lse: torch.Tensor, # [NUM_HEADS, NUM_TOKENS]
23 - output_lse: Optional[torch.Tensor] = None, # [NUM_HEADS, NUM_TOKENS]
22 + output_lse: torch.Tensor | None = None, # [NUM_HEADS, NUM_TOKENS]
23 ):
24 p_lse = prefix_lse
25 s_lse = suffix_lse
tests/kernels/attention/test_triton_unified_attention.py
+5 -6
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import pytest
6 import torch
@@ -32,8 +31,8 @@ def ref_paged_attn(
31 kv_lens: list[int],
32 block_tables: torch.Tensor,
33 scale: float,
35 - sliding_window: Optional[int] = None,
36 - soft_cap: Optional[float] = None,
34 + sliding_window: int | None = None,
35 + soft_cap: float | None = None,
36 ) -> torch.Tensor:
37 num_seqs = len(query_lens)
38 block_tables = block_tables.cpu().numpy()
@@ -98,12 +97,12 @@ def test_triton_unified_attn(
97 seq_lens: list[tuple[int, int]],
98 num_heads: tuple[int, int],
99 head_size: int,
101 - sliding_window: Optional[int],
100 + sliding_window: int | None,
101 dtype: torch.dtype,
102 block_size: int,
104 - soft_cap: Optional[float],
103 + soft_cap: float | None,
104 num_blocks: int,
106 - q_dtype: Optional[torch.dtype],
105 + q_dtype: torch.dtype | None,
106 ) -> None:
107 torch.set_default_device("cuda")
108
tests/kernels/core/test_fused_quant_layernorm.py
+15 -16
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import pytest
6 import torch
@@ -31,13 +30,13 @@ EPS = 1e-6
30 ## Helpers
31
32
34 -def as_float32_tensor(x: Union[float, torch.tensor]) -> torch.tensor:
33 +def as_float32_tensor(x: float | torch.Tensor) -> torch.Tensor:
34 return torch.as_tensor(x, dtype=torch.float32, device="cuda")
35
36
37 def ref_rms_norm(
39 - rms_norm_layer: RMSNorm, x: torch.Tensor, residual: Optional[torch.Tensor]
40 -) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
38 + rms_norm_layer: RMSNorm, x: torch.Tensor, residual: torch.Tensor | None
39 +) -> tuple[torch.Tensor, torch.Tensor | None]:
40 if residual is not None:
41 residual = residual.clone()
42 out, residual = rms_norm_layer.forward_native(x, residual)
@@ -51,9 +50,9 @@ def ref_dynamic_per_token_quant(
50 rms_norm_layer: RMSNorm,
51 x: torch.Tensor,
52 quant_dtype: torch.dtype,
54 - residual: Optional[torch.Tensor],
55 - scale_ub: Optional[torch.Tensor],
56 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
53 + residual: torch.Tensor | None,
54 + scale_ub: torch.Tensor | None,
55 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
56 if scale_ub is not None:
57 assert quant_dtype == torch.float8_e4m3fn
58
@@ -76,9 +75,9 @@ def ref_impl(
75 rms_norm_layer: RMSNorm,
76 x: torch.Tensor,
77 quant_dtype: torch.dtype,
79 - residual: Optional[torch.Tensor],
80 - scale_ub: Optional[torch.Tensor],
81 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
78 + residual: torch.Tensor | None,
79 + scale_ub: torch.Tensor | None,
80 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
81 return ref_dynamic_per_token_quant(
82 rms_norm_layer, x, quant_dtype, residual, scale_ub
83 )
@@ -88,9 +87,9 @@ def ops_dynamic_per_token_quant(
87 weight: torch.Tensor,
88 x: torch.Tensor,
89 quant_dtype: torch.dtype,
91 - residual: Optional[torch.Tensor],
92 - scale_ub: Optional[torch.Tensor],
93 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
90 + residual: torch.Tensor | None,
91 + scale_ub: torch.Tensor | None,
92 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
93 if residual is not None:
94 residual = residual.clone()
95 out, scales = ops.rms_norm_dynamic_per_token_quant(
@@ -103,9 +102,9 @@ def ops_impl(
102 weight: torch.Tensor,
103 x: torch.Tensor,
104 quant_dtype: torch.dtype,
106 - residual: Optional[torch.Tensor],
107 - scale_ub: Optional[torch.Tensor],
108 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
105 + residual: torch.Tensor | None,
106 + scale_ub: torch.Tensor | None,
107 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
108 return ops_dynamic_per_token_quant(weight, x, quant_dtype, residual, scale_ub)
109
110
tests/kernels/core/test_pos_encoding.py
+2 -2
@@ -1,8 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 +from collections.abc import Callable
5 from itertools import product
5 -from typing import Callable, Optional
6
7 import pytest
8 import torch
@@ -68,7 +68,7 @@ def test_rotary_embedding(
68 seq_len: int,
69 num_heads: int,
70 head_size: int,
71 - rotary_dim: Optional[int],
71 + rotary_dim: int | None,
72 dtype: torch.dtype,
73 seed: int,
74 device: str,
tests/kernels/core/test_rotary_embedding.py
+1 -3
@@ -4,8 +4,6 @@
4 Tests for miscellaneous utilities
5 """
6
7 -from typing import Optional
8 -
7 import pytest
8 import torch
9
@@ -17,7 +15,7 @@ def rotary_embedding_opcheck(
15 rot,
16 positions: torch.Tensor,
17 query: torch.Tensor,
20 - key: Optional[torch.Tensor] = None,
18 + key: torch.Tensor | None = None,
19 ):
20 cos_sin_cache = rot.cos_sin_cache.to(query.device, dtype=query.dtype)
21
tests/kernels/mamba/test_causal_conv1d.py
+10 -11
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import pytest
6 import torch
@@ -19,11 +18,11 @@ from vllm.platforms import current_platform
18 def causal_conv1d_ref(
19 x: torch.Tensor,
20 weight: torch.Tensor,
22 - bias: Optional[torch.Tensor] = None,
23 - initial_states: Optional[torch.Tensor] = None,
21 + bias: torch.Tensor | None = None,
22 + initial_states: torch.Tensor | None = None,
23 return_final_states: bool = False,
25 - final_states_out: Optional[torch.Tensor] = None,
26 - activation: Optional[str] = "silu",
24 + final_states_out: torch.Tensor | None = None,
25 + activation: str | None = "silu",
26 ):
27 """
28 x: (batch, dim, seqlen)
@@ -117,12 +116,12 @@ def causal_conv1d_update_ref(
116 def causal_conv1d_opcheck_fn(
117 x: torch.Tensor,
118 weight: torch.Tensor,
120 - bias: Optional[torch.Tensor] = None,
121 - cu_seq_len: Optional[torch.Tensor] = None,
122 - cache_indices: Optional[torch.Tensor] = None,
123 - has_initial_state: Optional[torch.Tensor] = None,
124 - conv_states: Optional[torch.Tensor] = None,
125 - activation: Optional[str] = "silu",
119 + bias: torch.Tensor | None = None,
120 + cu_seq_len: torch.Tensor | None = None,
121 + cache_indices: torch.Tensor | None = None,
122 + has_initial_state: torch.Tensor | None = None,
123 + conv_states: torch.Tensor | None = None,
124 + activation: str | None = "silu",
125 pad_slot_id: int = PAD_SLOT_ID,
126 ):
127 """
tests/kernels/moe/modular_kernel_tools/common.py
+17 -17
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import Any, Optional, Union
4 +from typing import Any
5
6 import torch
7
@@ -35,7 +35,7 @@ from .mk_objects import (
35 from .parallel_utils import ProcessGroupInfo
36
37
38 -def _describe_tensor(t: Optional[torch.Tensor], name: str) -> str:
38 +def _describe_tensor(t: torch.Tensor | None, name: str) -> str:
39 if t is None:
40 return f"{name} : None"
41 else:
@@ -44,21 +44,21 @@ def _describe_tensor(t: Optional[torch.Tensor], name: str) -> str:
44
45 @dataclass
46 class Config:
47 - Ms: Union[list[int], int]
47 + Ms: list[int] | int
48 K: int
49 N: int
50 E: int
51 - topks: Union[list[int], int]
51 + topks: list[int] | int
52 dtype: torch.dtype
53 - quant_config: Optional[TestMoEQuantConfig]
53 + quant_config: TestMoEQuantConfig | None
54
55 prepare_finalize_type: mk.FusedMoEPrepareAndFinalize
56 fused_experts_type: mk.FusedMoEPermuteExpertsUnpermute
57
58 - fused_moe_chunk_size: Optional[int]
58 + fused_moe_chunk_size: int | None
59 world_size: int
60
61 - torch_trace_dir_path: Optional[str] = None
61 + torch_trace_dir_path: str | None = None
62
63 def __post_init__(self):
64 if self.quant_config is None:
@@ -93,7 +93,7 @@ class Config:
93 return self.Ms
94
95 @property
96 - def quant_dtype(self) -> Union[torch.dtype, str, None]:
96 + def quant_dtype(self) -> torch.dtype | str | None:
97 assert self.quant_config is not None
98 return self.quant_config.quant_dtype
99
@@ -112,7 +112,7 @@ class Config:
112 return self.quant_config.per_out_ch_quant
113
114 @property
115 - def quant_block_shape(self) -> Optional[list[int]]:
115 + def quant_block_shape(self) -> list[int] | None:
116 assert self.quant_config is not None
117 return self.quant_config.block_shape
118
@@ -209,7 +209,7 @@ class Config:
209 info = prepare_finalize_info(self.prepare_finalize_type)
210 return info.backend
211
212 - def is_valid(self) -> tuple[bool, Optional[str]]:
212 + def is_valid(self) -> tuple[bool, str | None]:
213 # Check prepare-finalize and fused-experts compatibility
214 if self.is_batched_prepare_finalize():
215 if not self.is_batched_fused_experts():
@@ -280,10 +280,10 @@ class Config:
280 class WeightTensors:
281 w1: torch.Tensor
282 w2: torch.Tensor
283 - w1_scale: Optional[torch.Tensor]
284 - w2_scale: Optional[torch.Tensor]
285 - w1_gs: Optional[torch.Tensor] = None
286 - w2_gs: Optional[torch.Tensor] = None
283 + w1_scale: torch.Tensor | None
284 + w2_scale: torch.Tensor | None
285 + w1_gs: torch.Tensor | None = None
286 + w2_gs: torch.Tensor | None = None
287
288 def describe(self):
289 s = ""
@@ -351,11 +351,11 @@ class WeightTensors:
351 @dataclass
352 class RankTensors:
353 hidden_states: torch.Tensor
354 - hidden_states_scale: Optional[torch.Tensor]
354 + hidden_states_scale: torch.Tensor | None
355
356 topk_weights: torch.Tensor
357 topk_ids: torch.Tensor
358 - expert_map: Optional[torch.Tensor]
358 + expert_map: torch.Tensor | None
359
360 def describe(self):
361 s = ""
@@ -370,7 +370,7 @@ class RankTensors:
370 @staticmethod
371 def make_hidden_states(
372 config: Config,
373 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
373 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
374 """
375 Return hidden_states
376 """
tests/kernels/moe/modular_kernel_tools/make_feature_matrix.py
+2 -3
@@ -4,7 +4,6 @@
4 import copy
5 from enum import Enum
6 from itertools import product
7 -from typing import Optional
7
8 import torch
9 from tqdm import tqdm
@@ -82,7 +81,7 @@ def make_feature_matrix(csv_file_path: str):
81 import pandas as pd
82
83 def add_to_results(
85 - config: Config, success: Result, results_df: Optional[pd.DataFrame] = None
84 + config: Config, success: Result, results_df: pd.DataFrame | None = None
85 ):
86 config_dict = asdict(config)
87 config_dict["prepare_finalize_type"] = config_dict[
@@ -121,7 +120,7 @@ def make_feature_matrix(csv_file_path: str):
120 product(Ms, Ks, Ns, Es, TOPKs, DTYPEs, PF_TYPES, FE_TYPES, Q_TYPES)
121 )
122
124 - results_df: Optional[pd.DataFrame] = None
123 + results_df: pd.DataFrame | None = None
124 for m, k, n, e, topks, dtype, pf_type, experts_type, quant_config in tqdm(
125 combinations
126 ):
tests/kernels/moe/modular_kernel_tools/mk_objects.py
+11 -12
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import Optional, Union
4
5 import torch
6
@@ -43,25 +42,25 @@ from vllm.utils.flashinfer import has_flashinfer_cutlass_fused_moe
42
43 @dataclass
44 class TestMoEQuantConfig:
46 - quant_dtype: Union[torch.dtype, str, None]
45 + quant_dtype: torch.dtype | str | None
46 per_out_ch_quant: bool
47 per_act_token_quant: bool
49 - block_shape: Optional[list[int]]
48 + block_shape: list[int] | None
49
50
51 @dataclass
52 class PrepareFinalizeInfo:
53 activation_format: mk.FusedMoEActivationFormat
55 - supported_dtypes: list[Union[torch.dtype, str]]
54 + supported_dtypes: list[torch.dtype | str]
55 blocked_quantization_support: bool
57 - backend: Optional[str]
56 + backend: str | None
57 supports_apply_weight_on_input: bool = True
58
59
60 @dataclass
61 class ExpertInfo:
62 activation_format: mk.FusedMoEActivationFormat
64 - supported_dtypes: list[Union[torch.dtype, str]]
63 + supported_dtypes: list[torch.dtype | str]
64 blocked_quantization_support: bool
65 supports_chunking: bool
66 supports_expert_map: bool
@@ -78,7 +77,7 @@ MK_FUSED_EXPERT_TYPES: list[mk.FusedMoEPermuteExpertsUnpermute] = []
77
78 standard_format = mk.FusedMoEActivationFormat.Standard
79 batched_format = mk.FusedMoEActivationFormat.BatchedExperts
81 -common_float_types: list[Union[torch.dtype, str]] = [
80 +common_float_types: list[torch.dtype | str] = [
81 torch.float8_e4m3fn,
82 torch.bfloat16,
83 torch.float16,
@@ -92,9 +91,9 @@ fp8_types = [torch.float8_e4m3fn]
91 def register_prepare_and_finalize(
92 kind,
93 activation_format: mk.FusedMoEActivationFormat,
95 - supported_dtypes: list[Union[torch.dtype, str]],
94 + supported_dtypes: list[torch.dtype | str],
95 blocked_quantization_support: bool,
97 - backend: Optional[str],
96 + backend: str | None,
97 force_multigpu: bool = False,
98 supports_apply_weight_on_input: bool = True,
99 ):
@@ -121,7 +120,7 @@ def register_prepare_and_finalize(
120 def register_experts(
121 kind,
122 activation_format: mk.FusedMoEActivationFormat,
124 - supported_dtypes: list[Union[torch.dtype, str]],
123 + supported_dtypes: list[torch.dtype | str],
124 blocked_quantization_support: bool,
125 supports_chunking: bool,
126 supports_expert_map: bool,
@@ -340,7 +339,7 @@ if cutlass_fp4_supported():
339 supports_expert_map=False,
340 )
341
343 -MK_QUANT_CONFIGS: list[Optional[TestMoEQuantConfig]] = [
342 +MK_QUANT_CONFIGS: list[TestMoEQuantConfig | None] = [
343 None,
344 # per-channel / per-column weights and per-tensor activations
345 TestMoEQuantConfig(
@@ -395,7 +394,7 @@ if cutlass_fp4_supported() or has_flashinfer_cutlass_fused_moe():
394
395 def make_prepare_finalize(
396 prepare_finalize_type: mk.FusedMoEPrepareAndFinalize,
398 - backend: Optional[str],
397 + backend: str | None,
398 moe: FusedMoEConfig,
399 quant_config: FusedMoEQuantConfig,
400 ) -> mk.FusedMoEPrepareAndFinalize:
tests/kernels/moe/modular_kernel_tools/parallel_utils.py
+6 -5
@@ -3,11 +3,12 @@
3 import dataclasses
4 import os
5 import traceback
6 -from typing import Any, Callable, Optional
6 +from collections.abc import Callable
7 +from typing import Any, Concatenate
8
9 import torch
10 from torch.multiprocessing import spawn # pyright: ignore[reportPrivateImportUsage]
10 -from typing_extensions import Concatenate, ParamSpec
11 +from typing_extensions import ParamSpec
12
13 from vllm.config import VllmConfig, set_current_vllm_config
14 from vllm.distributed import init_distributed_environment, initialize_model_parallel
@@ -58,9 +59,9 @@ def _worker_parallel_launch(
59 world_local_size: int,
60 node_rank: int,
61 init_method: str,
61 - worker: Callable[Concatenate[ProcessGroupInfo, Optional[VllmConfig], Any, P], None],
62 - vllm_config: Optional[VllmConfig],
63 - env_dict: Optional[dict],
62 + worker: Callable[Concatenate[ProcessGroupInfo, VllmConfig | None, Any, P], None],
63 + vllm_config: VllmConfig | None,
64 + env_dict: dict | None,
65 *args: P.args,
66 **kwargs: P.kwargs,
67 ) -> None:
tests/kernels/moe/modular_kernel_tools/profile_modular_kernel.py
+2 -1
@@ -2,8 +2,9 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import copy
5 +from collections.abc import Callable
6 from itertools import product
6 -from typing import Any, Callable
7 +from typing import Any
8
9 import torch
10
tests/kernels/moe/parallel_utils.py
+11 -10
@@ -7,12 +7,13 @@ DeepEP test utilities
7 import dataclasses
8 import os
9 import traceback
10 -from typing import Callable, Optional
10 +from collections.abc import Callable
11 +from typing import Concatenate
12
13 import torch
14 from torch.distributed import ProcessGroup
15 from torch.multiprocessing import spawn # pyright: ignore[reportPrivateImportUsage]
15 -from typing_extensions import Concatenate, ParamSpec
16 +from typing_extensions import ParamSpec
17
18 from vllm.utils import get_open_port, has_deep_ep
19
@@ -126,8 +127,8 @@ def make_deepep_ht_a2a(
127 pgi: ProcessGroupInfo,
128 dp_size: int,
129 ht_args: DeepEPHTArgs,
129 - q_dtype: Optional[torch.dtype] = None,
130 - block_shape: Optional[list[int]] = None,
130 + q_dtype: torch.dtype | None = None,
131 + block_shape: list[int] | None = None,
132 ):
133 import deep_ep
134
@@ -153,8 +154,8 @@ def make_deepep_ll_a2a(
154 pg: ProcessGroup,
155 pgi: ProcessGroupInfo,
156 deepep_ll_args: DeepEPLLArgs,
156 - q_dtype: Optional[torch.dtype] = None,
157 - block_shape: Optional[list[int]] = None,
157 + q_dtype: torch.dtype | None = None,
158 + block_shape: list[int] | None = None,
159 ):
160 import deep_ep
161
@@ -185,10 +186,10 @@ def make_deepep_a2a(
186 pg: ProcessGroup,
187 pgi: ProcessGroupInfo,
188 dp_size: int,
188 - deepep_ht_args: Optional[DeepEPHTArgs],
189 - deepep_ll_args: Optional[DeepEPLLArgs],
190 - q_dtype: Optional[torch.dtype] = None,
191 - block_shape: Optional[list[int]] = None,
189 + deepep_ht_args: DeepEPHTArgs | None,
190 + deepep_ll_args: DeepEPLLArgs | None,
191 + q_dtype: torch.dtype | None = None,
192 + block_shape: list[int] | None = None,
193 ):
194 if deepep_ht_args is not None:
195 assert deepep_ll_args is None
tests/kernels/moe/test_batched_moe.py
+3 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 import pytest
7 import torch
@@ -55,7 +54,7 @@ vllm_config.scheduler_config.max_model_len = 8192
54 @dataclass
55 class BatchedMMConfig:
56 in_dtype: torch.dtype
58 - quant_dtype: Optional[torch.dtype]
57 + quant_dtype: torch.dtype | None
58 out_dtype: torch.dtype
59 num_experts: int
60 max_tokens_per_expert: int
@@ -115,7 +114,7 @@ def test_batched_mm(
114 K: int,
115 N: int,
116 dtype: torch.dtype,
118 - block_shape: Optional[list[int]],
117 + block_shape: list[int] | None,
118 per_act_token_quant: bool,
119 ):
120 current_platform.seed_everything(7)
@@ -242,7 +241,7 @@ def test_fused_moe_batched_experts(
241 topk: int,
242 dtype: torch.dtype,
243 per_act_token_quant: bool,
245 - block_shape: Optional[list[int]],
244 + block_shape: list[int] | None,
245 input_scales: bool,
246 ):
247 current_platform.seed_everything(7)
tests/kernels/moe/test_count_expert_num_tokens.py
+1 -2
@@ -5,7 +5,6 @@ Tests compute_expert_num_tokens kernels
5 """
6
7 import dataclasses
8 -from typing import Optional
8
9 import pytest
10 import torch
@@ -16,7 +15,7 @@ from vllm.model_executor.layers.fused_moe.utils import count_expert_num_tokens
15 @dataclasses.dataclass
16 class TestTensors:
17 topk_ids: torch.Tensor
19 - expert_map: Optional[torch.Tensor] = None
18 + expert_map: torch.Tensor | None = None
19
20 def to_device(self, device: str):
21 self.topk_ids = self.topk_ids.to(device=device)
tests/kernels/moe/test_cutlass_moe.py
+11 -12
@@ -3,7 +3,6 @@
3 import copy
4 import dataclasses
5 from math import prod
6 -from typing import Optional
6
7 import pytest
8 import torch
@@ -85,16 +84,16 @@ class MOETensors:
84 @dataclasses.dataclass
85 class MOETensors8Bit(MOETensors):
86 # quantized
88 - a_q: Optional[torch.Tensor] = None # a -> a_q
89 - w1_q: Optional[torch.Tensor] = None # w1 -> w1_q
90 - w2_q: Optional[torch.Tensor] = None # w2 -> w2_q
91 - a_scale: Optional[torch.Tensor] = None
92 - w1_scale: Optional[torch.Tensor] = None
93 - w2_scale: Optional[torch.Tensor] = None
87 + a_q: torch.Tensor | None = None # a -> a_q
88 + w1_q: torch.Tensor | None = None # w1 -> w1_q
89 + w2_q: torch.Tensor | None = None # w2 -> w2_q
90 + a_scale: torch.Tensor | None = None
91 + w1_scale: torch.Tensor | None = None
92 + w2_scale: torch.Tensor | None = None
93 # dequantized
95 - a_d: Optional[torch.Tensor] = None # a -> a_q -> a_d
96 - w1_d: Optional[torch.Tensor] = None # w1 -> w1_q -> w1_d
97 - w2_d: Optional[torch.Tensor] = None # w2 -> w2_q -> w2_d
94 + a_d: torch.Tensor | None = None # a -> a_q -> a_d
95 + w1_d: torch.Tensor | None = None # w1 -> w1_q -> w1_d
96 + w2_d: torch.Tensor | None = None # w2 -> w2_q -> w2_d
97
98 @staticmethod
99 def make_moe_tensors_8bit(
@@ -209,7 +208,7 @@ def run_8_bit(
208 topk_ids: torch.Tensor,
209 per_act_token: bool,
210 per_out_ch: bool,
212 - num_local_experts: Optional[int] = None,
211 + num_local_experts: int | None = None,
212 ) -> torch.Tensor:
213 assert not any(
214 [
@@ -280,7 +279,7 @@ def test_cutlass_moe_8_bit_no_graph(
279 per_act_token: bool,
280 per_out_ch: bool,
281 monkeypatch,
283 - ep_size: Optional[int] = None,
282 + ep_size: int | None = None,
283 ):
284 current_platform.seed_everything(7)
285 monkeypatch.setenv("VLLM_FUSED_MOE_CHUNK_SIZE", "8192")
tests/kernels/moe/test_deepep_deepgemm_moe.py
+6 -7
@@ -7,7 +7,6 @@ fp8 block-quantized case.
7 """
8
9 import dataclasses
10 -from typing import Optional
10
11 import pytest
12 import torch.distributed
@@ -92,13 +91,13 @@ class TestConfig:
91 block_size: list[int]
92 # configs for testing low-latency kernels
93 low_latency: bool
95 - use_fp8_dispatch: Optional[bool] = False
94 + use_fp8_dispatch: bool | None = False
95
96
97 @dataclasses.dataclass
98 class TestTensors:
99 rank_tokens: torch.Tensor # all ranks make this many tokens
101 - rank_token_scales: Optional[torch.Tensor]
100 + rank_token_scales: torch.Tensor | None
101 topk: torch.Tensor
102 topk_weights: torch.Tensor
103 config: TestConfig
@@ -143,7 +142,7 @@ def make_ll_modular_kernel(
142 max_tokens_per_rank: int,
143 dp_size: int,
144 hidden_size: int,
146 - q_dtype: Optional[torch.dtype],
145 + q_dtype: torch.dtype | None,
146 test_config: TestConfig,
147 quant_config: FusedMoEQuantConfig,
148 ) -> FusedMoEModularKernel:
@@ -179,7 +178,7 @@ def make_ht_modular_kernel(
178 pgi: ProcessGroupInfo,
179 dp_size: int,
180 num_local_experts: int,
182 - q_dtype: Optional[torch.dtype],
181 + q_dtype: torch.dtype | None,
182 test_config: TestConfig,
183 quant_config: FusedMoEQuantConfig,
184 ) -> FusedMoEModularKernel:
@@ -249,8 +248,8 @@ def deepep_deepgemm_moe_impl(
248 test_tensors: TestTensors,
249 w1: torch.Tensor,
250 w2: torch.Tensor,
252 - w1_scale: Optional[torch.Tensor],
253 - w2_scale: Optional[torch.Tensor],
251 + w1_scale: torch.Tensor | None,
252 + w2_scale: torch.Tensor | None,
253 ) -> torch.Tensor:
254 test_config = test_tensors.config
255 num_experts = test_config.num_experts
tests/kernels/moe/test_deepep_moe.py
+18 -21
@@ -5,7 +5,6 @@ Test deepep dispatch-combine logic
5 """
6
7 import dataclasses
8 -from typing import Optional, Union
8
9 import pytest
10 import torch.distributed
@@ -90,7 +89,7 @@ class TestConfig:
89 @dataclasses.dataclass
90 class TestTensors:
91 rank_tokens: torch.Tensor # all ranks make this many tokens
93 - rank_token_scales: Optional[torch.Tensor]
92 + rank_token_scales: torch.Tensor | None
93 topk: torch.Tensor
94 topk_weights: torch.Tensor
95 config: TestConfig
@@ -128,12 +127,12 @@ def make_modular_kernel(
127 dp_size: int,
128 num_experts: int,
129 num_local_experts: int,
131 - q_dtype: Optional[torch.dtype],
130 + q_dtype: torch.dtype | None,
131 use_fp8_dispatch: bool,
132 quant_config: FusedMoEQuantConfig,
133 ) -> FusedMoEModularKernel:
135 - ht_args: Optional[DeepEPHTArgs] = None
136 - ll_args: Optional[DeepEPLLArgs] = None
134 + ht_args: DeepEPHTArgs | None = None
135 + ll_args: DeepEPLLArgs | None = None
136
137 if low_latency_mode:
138 ll_args = DeepEPLLArgs(
@@ -148,16 +147,14 @@ def make_modular_kernel(
147 )
148 ht_args = DeepEPHTArgs(num_local_experts=num_local_experts)
149
151 - a2a: Union[DeepEPHTPrepareAndFinalize, DeepEPLLPrepareAndFinalize] = (
152 - make_deepep_a2a(
153 - pg=pg,
154 - pgi=pgi,
155 - dp_size=dp_size,
156 - q_dtype=q_dtype,
157 - block_shape=None,
158 - deepep_ht_args=ht_args,
159 - deepep_ll_args=ll_args,
160 - )
150 + a2a: DeepEPHTPrepareAndFinalize | DeepEPLLPrepareAndFinalize = make_deepep_a2a(
151 + pg=pg,
152 + pgi=pgi,
153 + dp_size=dp_size,
154 + q_dtype=q_dtype,
155 + block_shape=None,
156 + deepep_ht_args=ht_args,
157 + deepep_ll_args=ll_args,
158 )
159
160 num_dispatchers = pgi.world_size // dp_size
@@ -184,8 +181,8 @@ def deep_ep_moe_impl(
181 test_tensors: TestTensors,
182 w1: torch.Tensor,
183 w2: torch.Tensor,
187 - w1_scale: Optional[torch.Tensor],
188 - w2_scale: Optional[torch.Tensor],
184 + w1_scale: torch.Tensor | None,
185 + w2_scale: torch.Tensor | None,
186 num_experts: int,
187 use_fp8_dispatch: bool,
188 per_act_token_quant: bool,
@@ -281,8 +278,8 @@ def torch_moe_impl(
278 test_tensors: TestTensors,
279 w1: torch.Tensor,
280 w2: torch.Tensor,
284 - w1_scale: Optional[torch.Tensor],
285 - w2_scale: Optional[torch.Tensor],
281 + w1_scale: torch.Tensor | None,
282 + w2_scale: torch.Tensor | None,
283 using_fp8_dispatch: bool,
284 per_act_token_quant: bool,
285 ):
@@ -340,8 +337,8 @@ def _deep_ep_moe(
337 config: TestConfig,
338 w1: torch.Tensor,
339 w2: torch.Tensor,
343 - w1_scale: Optional[torch.Tensor],
344 - w2_scale: Optional[torch.Tensor],
340 + w1_scale: torch.Tensor | None,
341 + w2_scale: torch.Tensor | None,
342 use_fp8_dispatch: bool,
343 per_act_token_quant: bool,
344 ):
tests/kernels/moe/test_modular_kernel_combinations.py
+5 -5
@@ -5,7 +5,7 @@ import copy
5 import textwrap
6 import traceback
7 from itertools import product
8 -from typing import Any, Optional
8 +from typing import Any
9
10 import pytest
11 import torch
@@ -245,10 +245,10 @@ def test_modular_kernel_combinations_multigpu(
245 n: int,
246 e: int,
247 dtype: torch.dtype,
248 - quant_config: Optional[TestMoEQuantConfig],
248 + quant_config: TestMoEQuantConfig | None,
249 prepare_finalize_type: mk.FusedMoEPrepareAndFinalize,
250 fused_experts_type: mk.FusedMoEPermuteExpertsUnpermute,
251 - chunk_size: Optional[int],
251 + chunk_size: int | None,
252 world_size: int,
253 pytestconfig,
254 ):
@@ -287,10 +287,10 @@ def test_modular_kernel_combinations_singlegpu(
287 n: int,
288 e: int,
289 dtype: torch.dtype,
290 - quant_config: Optional[TestMoEQuantConfig],
290 + quant_config: TestMoEQuantConfig | None,
291 prepare_finalize_type: mk.FusedMoEPrepareAndFinalize,
292 fused_experts_type: mk.FusedMoEPermuteExpertsUnpermute,
293 - chunk_size: Optional[int],
293 + chunk_size: int | None,
294 world_size: int,
295 pytestconfig,
296 ):
tests/kernels/moe/test_moe.py
+4 -4
@@ -6,7 +6,7 @@ Run `pytest tests/kernels/test_moe.py`.
6 """
7
8 import functools
9 -from typing import Callable, Optional, Union
9 +from collections.abc import Callable
10
11 import pytest
12 import torch
@@ -80,7 +80,7 @@ vllm_config.scheduler_config.max_model_len = 8192
80
81
82 def run_moe_test(
83 - baseline: Union[Callable, torch.Tensor],
83 + baseline: Callable | torch.Tensor,
84 moe_fn: Callable,
85 a: torch.Tensor,
86 w1: torch.Tensor,
@@ -88,7 +88,7 @@ def run_moe_test(
88 score: torch.Tensor,
89 topk: int,
90 global_num_experts: int = -1,
91 - expert_map: Optional[torch.Tensor] = None,
91 + expert_map: torch.Tensor | None = None,
92 padding: bool = False,
93 use_compile: bool = False,
94 use_cudagraph: bool = False,
@@ -212,7 +212,7 @@ def test_fused_moe(
212 score: torch.Tensor,
213 topk: int,
214 global_num_experts: int = -1,
215 - expert_map: Optional[torch.Tensor] = None,
215 + expert_map: torch.Tensor | None = None,
216 ) -> torch.Tensor:
217 topk_weights, topk_ids, _ = fused_topk(a, score, topk, False)
218 return m_fused_moe_fn(
tests/kernels/moe/test_moe_align_block_size.py
+1 -3
@@ -5,8 +5,6 @@
5 Run `pytest tests/kernels/moe/test_moe_align_block_size.py`.
6 """
7
8 -from typing import Optional
9 -
8 import pytest
9 import torch
10
@@ -94,7 +92,7 @@ def torch_moe_align_block_size(
92 topk_ids: torch.Tensor,
93 block_size: int,
94 num_experts: int,
97 - expert_map: Optional[torch.Tensor] = None,
95 + expert_map: torch.Tensor | None = None,
96 pad_sorted_ids: bool = False,
97 ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
98 """
tests/kernels/moe/test_moe_permute_unpermute.py
+3 -5
@@ -5,8 +5,6 @@
5 Run `pytest tests/kernels/test_moe_permute_unpermute.py`.
6 """
7
8 -from typing import Optional
9 -
8 import numpy as np
9 import pytest
10 import torch
@@ -34,8 +32,8 @@ def torch_permute(
32 n_expert: int,
33 n_local_expert: int,
34 start_expert: int,
37 - expert_map: Optional[torch.Tensor] = None,
38 - align_block_size: Optional[int] = None,
35 + expert_map: torch.Tensor | None = None,
36 + align_block_size: int | None = None,
37 fill_invalid_expert: int = -1,
38 ) -> list[torch.Tensor]:
39 n_token, n_hidden = hidden_states.shape[0], hidden_states.shape[1]
@@ -210,7 +208,7 @@ def test_moe_permute_unpermute(
208 n_expert: int,
209 ep_size: int,
210 dtype: torch.dtype,
213 - align_block_size: Optional[int],
211 + align_block_size: int | None,
212 ):
213 if not moe_permute_unpermute_supported():
214 pytest.skip("moe_permute_unpermute is not supported on this platform.")
tests/kernels/moe/test_ocp_mx_moe.py
+6 -7
@@ -4,7 +4,6 @@
4 import importlib.metadata
5 from dataclasses import dataclass
6 from importlib.util import find_spec
7 -from typing import Optional
7
8 import pytest
9 import torch
@@ -103,7 +102,7 @@ def test_mxfp4_loading_and_execution_moe(vllm_runner, model_case: ModelCase):
102 assert output
103
104
106 -def swiglu(x, alpha: float = 1.702, beta: float = 1.0, limit: Optional[float] = None):
105 +def swiglu(x, alpha: float = 1.702, beta: float = 1.0, limit: float | None = None):
106 # Note we add an extra bias of 1 to the linear layer
107 x_glu, x_linear = torch.chunk(x, 2, dim=-1)
108 if limit is not None:
@@ -510,7 +509,7 @@ def test_trtllm_gen_mxfp4_fused_moe(
509 hidden_size: int,
510 alpha: float,
511 beta: float,
513 - limit: Optional[float],
512 + limit: float | None,
513 act_type: str,
514 transpose_optimized: bool,
515 ):
@@ -660,7 +659,7 @@ def test_flashinfer_cutlass_mxfp4_fused_moe(
659 hidden_size: int,
660 alpha: float,
661 beta: float,
663 - limit: Optional[float],
662 + limit: float | None,
663 ):
664 torch.manual_seed(42)
665 device = "cuda:0"
@@ -811,9 +810,9 @@ def test_flashinfer_cutlass_mxfp4_mxfp8_fused_moe(
810 num_tokens: int,
811 intermediate_size: int,
812 hidden_size: int,
814 - alpha: Optional[float],
815 - beta: Optional[float],
816 - limit: Optional[float],
813 + alpha: float | None,
814 + beta: float | None,
815 + limit: float | None,
816 ):
817 torch.manual_seed(42)
818 device = "cuda:0"
tests/kernels/moe/test_pplx_cutlass_moe.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import pytest
6 import torch
@@ -73,7 +72,7 @@ def pplx_cutlass_moe(
72 out_dtype,
73 per_act_token: bool,
74 per_out_ch: bool,
76 - group_name: Optional[str],
75 + group_name: str | None,
76 ):
77 from vllm.model_executor.layers.fused_moe.pplx_prepare_finalize import (
78 PplxPrepareAndFinalize,
tests/kernels/moe/test_pplx_moe.py
+29 -35
@@ -9,7 +9,7 @@ import copy
9 import itertools
10 import textwrap
11 import traceback
12 -from typing import Callable, Optional, Union
12 +from collections.abc import Callable
13
14 import pytest
15 import torch
@@ -89,7 +89,7 @@ def torch_prepare(
89 a: torch.Tensor,
90 topk_ids: torch.Tensor,
91 num_experts: int,
92 - max_num_tokens: Optional[int] = None,
92 + max_num_tokens: int | None = None,
93 ) -> tuple[torch.Tensor, torch.Tensor]:
94 assert topk_ids.dim() == 2
95 assert topk_ids.shape[0] == a.shape[0]
@@ -214,10 +214,10 @@ def create_pplx_prepare_finalize(
214 dp_size: int,
215 world_size: int,
216 in_dtype: torch.dtype,
217 - quant_dtype: Optional[torch.dtype],
218 - block_shape: Optional[list[int]],
217 + quant_dtype: torch.dtype | None,
218 + block_shape: list[int] | None,
219 per_act_token_quant: bool,
220 - group_name: Optional[str],
220 + group_name: str | None,
221 ):
222 from vllm.model_executor.layers.fused_moe.pplx_prepare_finalize import (
223 PplxPrepareAndFinalize,
@@ -274,18 +274,14 @@ def chunk_by_rank(t: torch.Tensor, r: int, w: int) -> torch.Tensor:
274 return t[(r * chunk) : (r + 1) * chunk]
275
276
277 -def maybe_chunk_by_rank(
278 - t: Optional[torch.Tensor], r: int, w: int
279 -) -> Optional[torch.Tensor]:
277 +def maybe_chunk_by_rank(t: torch.Tensor | None, r: int, w: int) -> torch.Tensor | None:
278 if t is not None:
279 return chunk_by_rank(t, r, w)
280 else:
281 return t
282
283
286 -def chunk_scales_by_rank(
287 - t: Optional[torch.Tensor], r: int, w: int
288 -) -> Optional[torch.Tensor]:
284 +def chunk_scales_by_rank(t: torch.Tensor | None, r: int, w: int) -> torch.Tensor | None:
285 if t is not None and t.numel() > 1:
286 chunk = rank_chunk(t.shape[0], r, w)
287 return t[(r * chunk) : (r + 1) * chunk]
@@ -293,9 +289,7 @@ def chunk_scales_by_rank(
289 return t
290
291
296 -def chunk_scales(
297 - t: Optional[torch.Tensor], start: int, end: int
298 -) -> Optional[torch.Tensor]:
292 +def chunk_scales(t: torch.Tensor | None, start: int, end: int) -> torch.Tensor | None:
293 if t is not None and t.numel() > 1:
294 return t[start:end]
295 else:
@@ -313,10 +307,10 @@ def pplx_prepare_finalize(
307 topk_weight: torch.Tensor,
308 topk_ids: torch.Tensor,
309 num_experts: int,
316 - quant_dtype: Optional[torch.dtype],
317 - block_shape: Optional[list[int]],
310 + quant_dtype: torch.dtype | None,
311 + block_shape: list[int] | None,
312 per_act_token_quant: bool,
319 - group_name: Optional[str],
313 + group_name: str | None,
314 ) -> torch.Tensor:
315 assert torch.cuda.current_device() == pgi.local_rank
316
@@ -409,8 +403,8 @@ def _pplx_prepare_finalize(
403 score: torch.Tensor,
404 topk: torch.Tensor,
405 num_experts: int,
412 - quant_dtype: Optional[torch.dtype],
413 - block_shape: Optional[list[int]],
406 + quant_dtype: torch.dtype | None,
407 + block_shape: list[int] | None,
408 per_act_token_quant: bool,
409 use_internode: bool,
410 ):
@@ -479,7 +473,7 @@ def test_pplx_prepare_finalize_slow(
473 dtype: torch.dtype,
474 world_dp_size: tuple[int, int],
475 per_act_token_quant: bool,
482 - block_shape: Optional[list[int]],
476 + block_shape: list[int] | None,
477 use_internode: bool,
478 ):
479 if dtype == torch.float8_e4m3fn:
@@ -521,7 +515,7 @@ def test_pplx_prepare_finalize_slow(
515
516
517 def pplx_moe(
524 - group_name: Optional[str],
518 + group_name: str | None,
519 rank: int,
520 world_size: int,
521 dp_size: int,
@@ -530,17 +524,17 @@ def pplx_moe(
524 w2: torch.Tensor,
525 topk_weight: torch.Tensor,
526 topk_ids: torch.Tensor,
533 - w1_scale: Optional[torch.Tensor] = None,
534 - w2_scale: Optional[torch.Tensor] = None,
535 - a1_scale: Optional[torch.Tensor] = None,
536 - a2_scale: Optional[torch.Tensor] = None,
537 - quant_dtype: Optional[torch.dtype] = None,
527 + w1_scale: torch.Tensor | None = None,
528 + w2_scale: torch.Tensor | None = None,
529 + a1_scale: torch.Tensor | None = None,
530 + a2_scale: torch.Tensor | None = None,
531 + quant_dtype: torch.dtype | None = None,
532 per_act_token_quant=False,
539 - block_shape: Optional[list[int]] = None,
533 + block_shape: list[int] | None = None,
534 use_compile: bool = False,
535 use_cudagraphs: bool = True,
542 - shared_experts: Optional[torch.nn.Module] = None,
543 -) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
536 + shared_experts: torch.nn.Module | None = None,
537 +) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
538 num_tokens, hidden_dim = a.shape
539 num_experts = w1.shape[0]
540 topk = topk_ids.shape[1]
@@ -657,13 +651,13 @@ def _pplx_moe(
651 score: torch.Tensor,
652 topk: int,
653 num_experts: int,
660 - w1_s: Optional[torch.Tensor] = None,
661 - w2_s: Optional[torch.Tensor] = None,
662 - quant_dtype: Optional[torch.dtype] = None,
654 + w1_s: torch.Tensor | None = None,
655 + w2_s: torch.Tensor | None = None,
656 + quant_dtype: torch.dtype | None = None,
657 per_act_token_quant: bool = False,
664 - block_shape: Optional[list[int]] = None,
658 + block_shape: list[int] | None = None,
659 use_internode: bool = False,
666 - shared_experts: Optional[torch.nn.Module] = None,
660 + shared_experts: torch.nn.Module | None = None,
661 ):
662 try:
663 if use_internode:
@@ -812,7 +806,7 @@ def test_pplx_moe_slow(
806 dtype: torch.dtype,
807 world_dp_size: tuple[int, int],
808 per_act_token_quant: bool,
815 - block_shape: Optional[list[int]],
809 + block_shape: list[int] | None,
810 use_internode: bool,
811 ):
812 current_platform.seed_everything(7)
tests/kernels/moe/utils.py
+44 -45
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional, Union
3
4 import torch
5
@@ -27,13 +26,13 @@ def triton_moe(
26 w2: torch.Tensor,
27 topk_weight: torch.Tensor,
28 topk_ids: torch.Tensor,
30 - w1_scale: Optional[torch.Tensor] = None,
31 - w2_scale: Optional[torch.Tensor] = None,
32 - a1_scale: Optional[torch.Tensor] = None,
33 - a2_scale: Optional[torch.Tensor] = None,
34 - quant_dtype: Optional[torch.dtype] = None,
29 + w1_scale: torch.Tensor | None = None,
30 + w2_scale: torch.Tensor | None = None,
31 + a1_scale: torch.Tensor | None = None,
32 + a2_scale: torch.Tensor | None = None,
33 + quant_dtype: torch.dtype | None = None,
34 per_act_token_quant=False,
36 - block_shape: Optional[list[int]] = None,
35 + block_shape: list[int] | None = None,
36 ) -> torch.Tensor:
37 quant_config = FusedMoEQuantConfig.make(
38 quant_dtype,
@@ -54,13 +53,13 @@ def batched_moe(
53 w2: torch.Tensor,
54 topk_weight: torch.Tensor,
55 topk_ids: torch.Tensor,
57 - w1_scale: Optional[torch.Tensor] = None,
58 - w2_scale: Optional[torch.Tensor] = None,
59 - a1_scale: Optional[torch.Tensor] = None,
60 - a2_scale: Optional[torch.Tensor] = None,
61 - quant_dtype: Optional[torch.dtype] = None,
56 + w1_scale: torch.Tensor | None = None,
57 + w2_scale: torch.Tensor | None = None,
58 + a1_scale: torch.Tensor | None = None,
59 + a2_scale: torch.Tensor | None = None,
60 + quant_dtype: torch.dtype | None = None,
61 per_act_token_quant: bool = False,
63 - block_shape: Optional[list[int]] = None,
62 + block_shape: list[int] | None = None,
63 ) -> torch.Tensor:
64 max_num_tokens = round_up(a.shape[0], 64)
65
@@ -94,13 +93,13 @@ def naive_batched_moe(
93 w2: torch.Tensor,
94 topk_weight: torch.Tensor,
95 topk_ids: torch.Tensor,
97 - w1_scale: Optional[torch.Tensor] = None,
98 - w2_scale: Optional[torch.Tensor] = None,
99 - a1_scale: Optional[torch.Tensor] = None,
100 - a2_scale: Optional[torch.Tensor] = None,
101 - quant_dtype: Optional[torch.dtype] = None,
96 + w1_scale: torch.Tensor | None = None,
97 + w2_scale: torch.Tensor | None = None,
98 + a1_scale: torch.Tensor | None = None,
99 + a2_scale: torch.Tensor | None = None,
100 + quant_dtype: torch.dtype | None = None,
101 per_act_token_quant: bool = False,
103 - block_shape: Optional[list[int]] = None,
102 + block_shape: list[int] | None = None,
103 ) -> torch.Tensor:
104 max_num_tokens = round_up(a.shape[0], 64)
105
@@ -129,8 +128,8 @@ def naive_batched_moe(
128
129
130 def chunk_scales(
132 - scales: Optional[torch.Tensor], start: int, end: int
133 -) -> Optional[torch.Tensor]:
131 + scales: torch.Tensor | None, start: int, end: int
132 +) -> torch.Tensor | None:
133 if scales is not None:
134 if scales.numel() == 1:
135 return scales
@@ -144,10 +143,10 @@ def make_quantized_test_activations(
143 m: int,
144 k: int,
145 in_dtype: torch.dtype,
147 - quant_dtype: Optional[torch.dtype] = None,
148 - block_shape: Optional[list[int]] = None,
146 + quant_dtype: torch.dtype | None = None,
147 + block_shape: list[int] | None = None,
148 per_act_token_quant: bool = False,
150 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
149 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
150 a = torch.randn((E, m, k), device="cuda", dtype=in_dtype) / 10
151 a_q = a
152 a_scale = None
@@ -172,11 +171,11 @@ def make_quantized_test_activations(
171
172 def moe_quantize_weights(
173 w: torch.Tensor,
175 - w_s: Optional[torch.Tensor],
176 - quant_dtype: Union[torch.dtype, str, None],
174 + w_s: torch.Tensor | None,
175 + quant_dtype: torch.dtype | str | None,
176 per_token_quant: bool,
178 - block_shape: Optional[list[int]],
179 -) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[torch.Tensor]]:
177 + block_shape: list[int] | None,
178 +) -> tuple[torch.Tensor, torch.Tensor | None, torch.Tensor | None]:
179 assert (
180 quant_dtype == torch.float8_e4m3fn
181 or quant_dtype == torch.int8
@@ -220,10 +219,10 @@ def make_test_weight(
219 rows: int,
220 cols: int,
221 in_dtype: torch.dtype = torch.bfloat16,
223 - quant_dtype: Union[torch.dtype, str, None] = None,
224 - block_shape: Optional[list[int]] = None,
222 + quant_dtype: torch.dtype | str | None = None,
223 + block_shape: list[int] | None = None,
224 per_out_ch_quant: bool = False,
226 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor], Optional[torch.Tensor]]:
225 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None, torch.Tensor | None]:
226 w_16 = torch.randn((e, rows, cols), device="cuda", dtype=in_dtype) / 15
227 w_gs = None
228
@@ -262,12 +261,12 @@ def make_test_weights(
261 n: int,
262 k: int,
263 in_dtype: torch.dtype = torch.bfloat16,
265 - quant_dtype: Union[torch.dtype, str, None] = None,
266 - block_shape: Optional[list[int]] = None,
264 + quant_dtype: torch.dtype | str | None = None,
265 + block_shape: list[int] | None = None,
266 per_out_ch_quant: bool = False,
267 ) -> tuple[
269 - tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor], Optional[torch.Tensor]],
270 - tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor], Optional[torch.Tensor]],
268 + tuple[torch.Tensor, torch.Tensor, torch.Tensor | None, torch.Tensor | None],
269 + tuple[torch.Tensor, torch.Tensor, torch.Tensor | None, torch.Tensor | None],
270 ]:
271 return (
272 make_test_weight(
@@ -295,9 +294,9 @@ def make_test_quant_config(
294 n: int,
295 k: int,
296 in_dtype: torch.dtype,
298 - quant_dtype: Union[torch.dtype, str, None] = None,
297 + quant_dtype: torch.dtype | str | None = None,
298 per_act_token_quant: bool = False,
300 - block_shape: Optional[list[int]] = None,
299 + block_shape: list[int] | None = None,
300 ) -> tuple[torch.Tensor, torch.Tensor, FusedMoEQuantConfig]:
301 (_, w1, w1_s, w1_gs), (_, w2, w2_s, w2_gs) = make_test_weights(
302 e,
@@ -310,8 +309,8 @@ def make_test_quant_config(
309 )
310
311 # Hacky/trivial scales for nvfp4.
313 - a1_gscale: Optional[torch.Tensor] = None
314 - a2_gscale: Optional[torch.Tensor] = None
312 + a1_gscale: torch.Tensor | None = None
313 + a2_gscale: torch.Tensor | None = None
314 if quant_dtype == "nvfp4":
315 a1_gscale = torch.ones((e,), device="cuda", dtype=torch.float32)
316 a2_gscale = torch.ones((e,), device="cuda", dtype=torch.float32)
@@ -348,9 +347,9 @@ def fused_moe(
347 score: torch.Tensor,
348 topk: int,
349 renormalize: bool = False,
351 - quant_config: Optional[FusedMoEQuantConfig] = None,
350 + quant_config: FusedMoEQuantConfig | None = None,
351 global_num_experts: int = -1,
353 - expert_map: Optional[torch.Tensor] = None,
352 + expert_map: torch.Tensor | None = None,
353 ) -> torch.Tensor:
354 topk_weights, topk_ids, _ = fused_topk(
355 hidden_states, score.float(), topk, renormalize
@@ -378,7 +377,7 @@ class BaselineMM(torch.nn.Module):
377 self.b = b.to(dtype=torch.float32)
378 self.out_dtype = out_dtype
379
381 - def forward(self, a: torch.Tensor) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
380 + def forward(self, a: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor | None]:
381 return torch.mm(a.to(dtype=torch.float32), self.b).to(self.out_dtype), None
382
383
@@ -422,8 +421,8 @@ class RealMLP(torch.nn.Module):
421 quant_config=None,
422 reduce_results: bool = True,
423 prefix: str = "",
425 - w1_s: Optional[torch.Tensor] = None,
426 - w2_s: Optional[torch.Tensor] = None,
424 + w1_s: torch.Tensor | None = None,
425 + w2_s: torch.Tensor | None = None,
426 ) -> None:
427 from vllm.model_executor.layers.linear import (
428 MergedColumnParallelLinear,
@@ -481,7 +480,7 @@ def make_shared_experts(
480 N: int,
481 K: int,
482 in_dtype: torch.dtype = torch.bfloat16,
484 - quant_dtype: Union[torch.dtype, str, None] = None,
483 + quant_dtype: torch.dtype | str | None = None,
484 ) -> torch.nn.Module:
485 from vllm.model_executor.layers.quantization.fp8 import Fp8Config
486
tests/kernels/quant_utils.py
+14 -15
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import torch
6
@@ -15,13 +14,13 @@ ROCM_FP8FNUZ_MAX = 224.0
14 FP8_DTYPE = current_platform.fp8_dtype()
15
16
18 -def as_float32_tensor(x: Union[float, torch.tensor]) -> torch.tensor:
17 +def as_float32_tensor(x: float | torch.Tensor) -> torch.Tensor:
18 return torch.as_tensor(x, dtype=torch.float32, device="cuda")
19
20
21 def ref_dynamic_per_token_quant(
23 - x: torch.tensor, quant_dtype: torch.dtype, scale_ub: Optional[torch.tensor] = None
24 -) -> tuple[torch.tensor, torch.tensor]:
22 + x: torch.Tensor, quant_dtype: torch.dtype, scale_ub: torch.Tensor | None = None
23 +) -> tuple[torch.Tensor, torch.Tensor]:
24 assert quant_dtype in [torch.int8, FP8_DTYPE]
25 if scale_ub is not None:
26 assert quant_dtype == FP8_DTYPE
@@ -76,8 +75,8 @@ def ref_dynamic_per_token_quant(
75 # ref_dynamic_per_token_quant, when we have a dynamic_per_tensor int8 quant
76 # kernel
77 def ref_dynamic_per_tensor_fp8_quant(
79 - x: torch.tensor,
80 -) -> tuple[torch.tensor, torch.tensor]:
78 + x: torch.Tensor,
79 +) -> tuple[torch.Tensor, torch.Tensor]:
80 fp8_traits = torch.finfo(FP8_DTYPE)
81 fp8_traits_max = (
82 ROCM_FP8FNUZ_MAX
@@ -250,10 +249,10 @@ def per_block_cast_to_int8(
249
250 def dequant(
251 t: torch.Tensor,
253 - scale: Optional[torch.Tensor],
254 - block_shape: Optional[list[int]],
252 + scale: torch.Tensor | None,
253 + block_shape: list[int] | None,
254 per_act_token_quant: bool,
256 - out_dtype: Optional[torch.dtype] = torch.float32,
255 + out_dtype: torch.dtype | None = torch.float32,
256 ) -> torch.Tensor:
257 if scale is not None:
258 f32 = torch.float32
@@ -267,10 +266,10 @@ def dequant(
266
267 def batched_dequant(
268 t: torch.Tensor,
270 - scale: Optional[torch.Tensor],
271 - block_shape: Optional[list[int]],
269 + scale: torch.Tensor | None,
270 + block_shape: list[int] | None,
271 per_act_token_quant: bool,
273 - out_dtype: Optional[torch.dtype] = torch.float32,
272 + out_dtype: torch.dtype | None = torch.float32,
273 ) -> torch.Tensor:
274 if scale is not None:
275 assert t.shape[0] == scale.shape[0]
@@ -289,9 +288,9 @@ def native_batched_masked_quant_matmul(
288 B: torch.Tensor,
289 C: torch.Tensor,
290 num_expert_tokens: torch.Tensor,
292 - A_scale: Optional[torch.Tensor] = None,
293 - B_scale: Optional[torch.Tensor] = None,
294 - block_shape: Optional[list[int]] = None,
291 + A_scale: torch.Tensor | None = None,
292 + B_scale: torch.Tensor | None = None,
293 + block_shape: list[int] | None = None,
294 per_act_token_quant: bool = False,
295 ) -> torch.Tensor:
296 num_expert_tokens_cpu = num_expert_tokens.clone()
tests/kernels/quantization/test_cutlass_w4a8.py
+10 -11
@@ -6,7 +6,6 @@ Run `pytest tests/kernels/quantization/test_cutlass_w4a8.py`.
6 """
7
8 from dataclasses import dataclass
9 -from typing import Optional
9
10 import pytest
11 import torch
@@ -60,10 +59,10 @@ SCHEDULES = [
59 class TypeConfig:
60 act_type: torch.dtype
61 weight_type: ScalarType
63 - output_type: Optional[torch.dtype]
64 - group_scale_type: Optional[torch.dtype]
65 - channel_scale_type: Optional[torch.dtype]
66 - token_scale_type: Optional[torch.dtype]
62 + output_type: torch.dtype | None
63 + group_scale_type: torch.dtype | None
64 + channel_scale_type: torch.dtype | None
65 + token_scale_type: torch.dtype | None
66
67
68 @dataclass
@@ -80,7 +79,7 @@ class Tensors:
79 # (Act Type, Weight Type, Output Type, Scale Type, ZeroPoints,
80 # Ch Scales Type, Tok Scales Type)
81 TestTypeTuple = tuple[
83 - list[torch.dtype], ScalarType, Optional[torch.dtype], Optional[torch.dtype], bool
82 + list[torch.dtype], ScalarType, torch.dtype | None, torch.dtype | None, bool
83 ]
84 TEST_TYPES = [
85 *(
@@ -116,8 +115,8 @@ def cutlass_quantize_and_pack(
115 atype: torch.dtype,
116 w: torch.Tensor,
117 wtype: ScalarType,
119 - stype: Optional[torch.dtype],
120 - group_size: Optional[int],
118 + stype: torch.dtype | None,
119 + group_size: int | None,
120 zero_points: bool = False,
121 ):
122 assert wtype.is_integer(), "TODO: support floating point weights"
@@ -143,7 +142,7 @@ def cutlass_quantize_and_pack(
142
143
144 def create_test_tensors(
146 - shape: tuple[int, int, int], types: TypeConfig, group_size: Optional[int]
145 + shape: tuple[int, int, int], types: TypeConfig, group_size: int | None
146 ) -> Tensors:
147 m, n, k = shape
148
@@ -185,8 +184,8 @@ def create_test_tensors(
184 def mm_test_helper(
185 types: TypeConfig,
186 tensors: Tensors,
188 - group_size: Optional[int] = None,
189 - schedule: Optional[str] = None,
187 + group_size: int | None = None,
188 + schedule: str | None = None,
189 ):
190 # CUTLASS upstream uses fp8 with fastaccum as reference
191 # https://github.com/NVIDIA/cutlass/blob/main/examples/55_hopper_mixed_dtype_gemm/55_hopper_int4_fp8_gemm.cu#L406
tests/kernels/quantization/test_machete_mm.py
+20 -21
@@ -7,7 +7,6 @@ Run `pytest tests/kernels/quantization/test_machete_mm.py`.
7
8 import math
9 from dataclasses import dataclass, fields
10 -from typing import Optional
10
11 import pytest
12 import torch
@@ -50,11 +49,11 @@ MNK_SHAPES = [
49 class TypeConfig:
50 act_type: torch.dtype
51 weight_type: ScalarType
53 - output_type: Optional[torch.dtype]
54 - group_scale_type: Optional[torch.dtype]
55 - group_zero_type: Optional[torch.dtype]
56 - channel_scale_type: Optional[torch.dtype]
57 - token_scale_type: Optional[torch.dtype]
52 + output_type: torch.dtype | None
53 + group_scale_type: torch.dtype | None
54 + group_zero_type: torch.dtype | None
55 + channel_scale_type: torch.dtype | None
56 + token_scale_type: torch.dtype | None
57
58
59 @dataclass
@@ -63,10 +62,10 @@ class Tensors:
62 a_ref: torch.Tensor
63 a: torch.Tensor
64 w_q: torch.Tensor
66 - w_g_s: Optional[torch.Tensor]
67 - w_g_zp: Optional[torch.Tensor]
68 - w_ch_s: Optional[torch.Tensor]
69 - w_tok_s: Optional[torch.Tensor]
65 + w_g_s: torch.Tensor | None
66 + w_g_zp: torch.Tensor | None
67 + w_ch_s: torch.Tensor | None
68 + w_tok_s: torch.Tensor | None
69
70
71 # (Act Type, Weight Type, Output Type, Scale Type, ZeroPoints,
@@ -74,7 +73,7 @@ class Tensors:
73 # NOTE: None "Scale Type" means the act type is floating point
74 # None "Output Type" means the output type is the same as the act type
75 TestTypeTuple = tuple[
77 - list[torch.dtype], ScalarType, Optional[torch.dtype], Optional[torch.dtype], bool
76 + list[torch.dtype], ScalarType, torch.dtype | None, torch.dtype | None, bool
77 ]
78 TEST_TYPES = [
79 # GPTQ style
@@ -139,11 +138,11 @@ def rand_data(shape, dtype=torch.float16, scale=1, offset=0):
138 return torch.randint(-8, 7, shape, dtype=dtype, device="cuda")
139
140
142 -def maybe_convert_zeropoints(zps: Optional[torch.Tensor], s: torch.Tensor):
141 +def maybe_convert_zeropoints(zps: torch.Tensor | None, s: torch.Tensor):
142 return zps if zps is None else -1 * s * (zps.to(s.dtype))
143
144
146 -def group_size_valid(shape: tuple[int, int, int], group_size: Optional[int]) -> bool:
145 +def group_size_valid(shape: tuple[int, int, int], group_size: int | None) -> bool:
146 return group_size is None or group_size == -1 or shape[2] % group_size == 0
147
148
@@ -151,8 +150,8 @@ def machete_quantize_and_pack(
150 atype: torch.dtype,
151 w: torch.Tensor,
152 wtype: ScalarType,
154 - stype: Optional[torch.dtype],
155 - group_size: Optional[int],
153 + stype: torch.dtype | None,
154 + group_size: int | None,
155 zero_points: bool = False,
156 ):
157 assert wtype.is_integer(), "TODO: support floating point weights"
@@ -178,8 +177,8 @@ def machete_quantize_and_pack(
177 def create_test_tensors(
178 shape: tuple[int, int, int],
179 types: TypeConfig,
181 - group_size: Optional[int],
182 - subset_stride_factor: Optional[int] = None,
180 + group_size: int | None,
181 + subset_stride_factor: int | None = None,
182 ) -> Tensors:
183 m, n, k = shape
184 factor = subset_stride_factor or 1
@@ -243,8 +242,8 @@ def create_test_tensors(
242 def machete_mm_test_helper(
243 types: TypeConfig,
244 tensors: Tensors,
246 - group_size: Optional[int] = None,
247 - schedule: Optional[str] = None,
245 + group_size: int | None = None,
246 + schedule: str | None = None,
247 ):
248 output_ref = torch.matmul(tensors.a_ref, tensors.w_ref)
249 output_ref_type = output_ref.dtype
@@ -294,7 +293,7 @@ def machete_mm_test_helper(
293 @pytest.mark.parametrize("shape", MNK_SHAPES, ids=lambda x: "x".join(str(v) for v in x))
294 @pytest.mark.parametrize("types", TEST_TYPES)
295 def test_machete_all_schedules(shape, types: TypeConfig):
297 - group_sizes: list[Optional[int]] = []
296 + group_sizes: list[int | None] = []
297 if types.group_scale_type is None:
298 group_sizes = [None]
299 else:
@@ -323,7 +322,7 @@ def test_machete_all_schedules(shape, types: TypeConfig):
322 @pytest.mark.parametrize("shape", MNK_SHAPES, ids=lambda x: "x".join(str(v) for v in x))
323 @pytest.mark.parametrize("types", TEST_TYPES)
324 def test_machete_heuristic(shape, types: TypeConfig):
326 - group_sizes: list[Optional[int]] = []
325 + group_sizes: list[int | None] = []
326 if types.group_scale_type is None:
327 group_sizes = [None]
328 else:
tests/kernels/quantization/test_triton_scaled_mm.py
+1 -2
@@ -6,7 +6,6 @@ Run `pytest tests/kernels/quantization/test_triton_scaled_mm.py`.
6 """
7
8 import importlib
9 -from typing import Optional
9
10 import pytest
11 import torch
@@ -27,7 +26,7 @@ def torch_scaled_mm(
26 scale_a: torch.Tensor,
27 scale_b: torch.Tensor,
28 out_dtype: type[torch.dtype],
30 - bias: Optional[torch.Tensor] = None,
29 + bias: torch.Tensor | None = None,
30 ) -> torch.Tensor:
31 out = torch.mm(a.to(torch.float32), b.to(torch.float32))
32 out = scale_a * out
tests/kernels/test_onednn.py
+2 -4
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Integration tests for FlexAttention backend vs default backend"""
4
5 -from typing import Optional
6 -
5 import pytest
6 import torch
7
@@ -38,8 +36,8 @@ def ref_int8_scaled_mm(
36 b: torch.Tensor,
37 scale_a: torch.Tensor,
38 scale_b: torch.Tensor,
41 - azp: Optional[torch.Tensor],
42 - bias: Optional[torch.Tensor],
39 + azp: torch.Tensor | None,
40 + bias: torch.Tensor | None,
41 output_type: torch.dtype,
42 ):
43 if azp is not None:
tests/kernels/utils.py
+54 -56
@@ -7,7 +7,7 @@ import random
7 import unittest
8 from collections.abc import Sequence
9 from numbers import Number
10 -from typing import Any, NamedTuple, Optional, Union
10 +from typing import Any, NamedTuple
11
12 import pytest
13 import torch
@@ -96,10 +96,10 @@ class PackedQKVInputs(NamedTuple):
96 query: torch.Tensor
97 key: torch.Tensor
98 value: torch.Tensor
99 - q_start_loc_list: Optional[list[int]]
100 - kv_start_loc_list: Optional[list[int]]
101 - q_seq_lens: Optional[list[int]]
102 - kv_seq_lens: Optional[list[int]]
99 + q_start_loc_list: list[int] | None
100 + kv_start_loc_list: list[int] | None
101 + q_seq_lens: list[int] | None
102 + kv_seq_lens: list[int] | None
103
104
105 class PackedQKVO(NamedTuple):
@@ -115,7 +115,7 @@ class PackedQKVO(NamedTuple):
115 x head_size) known-correct attention output
116 """
117
118 - packed_qkv: Optional[PackedQKVInputs]
118 + packed_qkv: PackedQKVInputs | None
119 ideal_output: torch.Tensor
120
121
@@ -149,12 +149,12 @@ class PhaseTestParameters(NamedTuple):
149 """
150
151 packed_qkvo: PackedQKVO
152 - kv_mmap: Optional[KVMemoryMap]
152 + kv_mmap: KVMemoryMap | None
153
154
155 def maybe_make_int_tensor(
156 - _list: Optional[list[int]],
157 - device: Union[torch.device, str],
156 + _list: list[int] | None,
157 + device: torch.device | str,
158 ) -> torch.Tensor:
159 """
160 Convert Python int list to a 1D int torch.Tensor on `device`
@@ -170,8 +170,8 @@ def maybe_make_int_tensor(
170
171
172 def maybe_make_long_tensor(
173 - _list: Optional[list[int]],
174 - device: Union[torch.device, str],
173 + _list: list[int] | None,
174 + device: torch.device | str,
175 ) -> torch.Tensor:
176 """
177 Convert Python int list to a 1D long torch.Tensor on `device`
@@ -186,7 +186,7 @@ def maybe_make_long_tensor(
186 )
187
188
189 -def maybe_max(_list: Optional[list]) -> Optional[Number]:
189 +def maybe_max(_list: list | None) -> Number | None:
190 """
191 Returns:
192
@@ -241,9 +241,9 @@ def ref_masked_attention(
241 key: torch.Tensor,
242 value: torch.Tensor,
243 scale: float,
244 - custom_mask: Optional[torch.Tensor] = None,
245 - q_seq_lens: Optional[list] = None,
246 - kv_seq_lens: Optional[list] = None,
244 + custom_mask: torch.Tensor | None = None,
245 + q_seq_lens: list | None = None,
246 + kv_seq_lens: list | None = None,
247 ) -> torch.Tensor:
248 """
249 "Golden" masked attention reference. Supports two types of masking:
@@ -302,11 +302,11 @@ def ref_masked_attention(
302 def make_qkv(
303 batch_size: int,
304 max_q_seq_len: int,
305 - max_kv_seq_len: Optional[int],
305 + max_kv_seq_len: int | None,
306 num_heads: int,
307 head_size: int,
308 - device: Union[torch.device, str],
309 - force_kv_seq_lens: Optional[list[int]] = None,
308 + device: torch.device | str,
309 + force_kv_seq_lens: list[int] | None = None,
310 attn_type: AttentionType = AttentionType.ENCODER_DECODER,
311 force_max_len: bool = False,
312 ) -> tuple[QKVInputs, QKVInputs, QKVInputs]:
@@ -436,7 +436,7 @@ def make_qkv(
436
437
438 def pack_tensor(
439 - unpacked_tensor: torch.Tensor, seq_lens: list[int], device: Union[torch.device, str]
439 + unpacked_tensor: torch.Tensor, seq_lens: list[int], device: torch.device | str
440 ) -> tuple[torch.Tensor, list[int]]:
441 """
442 Pack a batch_size x padded_seq_len x num_heads x head_size tensor into an
@@ -470,7 +470,7 @@ def pack_tensor(
470 return packed_tensor, start_loc_list
471
472
473 -def pack_qkv(qkv: QKVInputs, device: Union[torch.device, str]) -> PackedQKVInputs:
473 +def pack_qkv(qkv: QKVInputs, device: torch.device | str) -> PackedQKVInputs:
474 """
475 Individually pack each of Q, K and V, each with dimensions batch_size x
476 padded_seq_len x num_heads x head_size, into respective number_of_tokens x
@@ -594,19 +594,19 @@ def make_alibi_bias(
594
595
596 def _make_metadata_tensors(
597 - seq_lens: Optional[list[int]],
598 - context_lens: Optional[list[int]],
599 - encoder_seq_lens: Optional[list[int]],
600 - device: Union[torch.device, str],
597 + seq_lens: list[int] | None,
598 + context_lens: list[int] | None,
599 + encoder_seq_lens: list[int] | None,
600 + device: torch.device | str,
601 ) -> tuple[
602 torch.Tensor,
603 torch.Tensor,
604 Any,
605 Any,
606 - Optional[torch.Tensor],
606 + torch.Tensor | None,
607 torch.Tensor,
608 torch.Tensor,
609 - Optional[int],
609 + int | None,
610 ]:
611 """
612 Build scalar & tensor values required to build attention metadata structure.
@@ -678,7 +678,7 @@ def make_kv_cache(
678 num_heads: int,
679 head_size: int,
680 block_size: int,
681 - device: Union[torch.device, str],
681 + device: torch.device | str,
682 backend: str,
683 default_val: float = 0.0,
684 ) -> torch.Tensor:
@@ -726,18 +726,18 @@ def _num_tokens_to_min_blocks(num_tokens: int, block_size: int) -> int:
726 return (num_tokens + block_size) // block_size
727
728
729 -def make_empty_slot_mapping_tensor(device: Union[torch.device, str]):
729 +def make_empty_slot_mapping_tensor(device: torch.device | str):
730 return maybe_make_long_tensor([], device)
731
732
733 -def make_empty_block_tables_tensor(device: Union[torch.device, str]):
733 +def make_empty_block_tables_tensor(device: torch.device | str):
734 return torch.tensor([], device=device)
735
736
737 def split_slot_mapping(
738 slot_mapping_list: torch.Tensor,
739 seq_lens: list[int],
740 - device: Union[torch.device, str],
740 + device: torch.device | str,
741 ):
742 """
743 Split a slot mapping into valid prefill- and decode-phase slot mappings.
@@ -799,7 +799,7 @@ def split_slot_mapping(
799 def make_block_tables_slot_mapping(
800 block_size: int,
801 seq_lens: list[int],
802 - device: Union[torch.device, str],
802 + device: torch.device | str,
803 block_base_addr: int = 0,
804 ) -> tuple[torch.Tensor, list[int], int]:
805 """
@@ -880,11 +880,11 @@ def make_block_tables_slot_mapping(
880 def make_test_metadata(
881 attn_backend: _Backend,
882 is_prompt: bool,
883 - seq_lens: Optional[list[int]],
884 - decoder_test_params: Optional[PhaseTestParameters],
885 - device: Union[torch.device, str],
886 - encoder_test_params: Optional[PhaseTestParameters] = None,
887 - cross_test_params: Optional[PhaseTestParameters] = None,
883 + seq_lens: list[int] | None,
884 + decoder_test_params: PhaseTestParameters | None,
885 + device: torch.device | str,
886 + encoder_test_params: PhaseTestParameters | None = None,
887 + cross_test_params: PhaseTestParameters | None = None,
888 ) -> AttentionMetadata:
889 """
890 Construct fake attention metadata for a given test phase
@@ -1142,16 +1142,16 @@ def torch_experts(
1142 topk_weight: torch.Tensor,
1143 topk_ids: torch.Tensor,
1144 global_num_experts: int = -1,
1145 - b_bias1: Optional[torch.Tensor] = None,
1146 - b_bias2: Optional[torch.Tensor] = None,
1147 - expert_map: Optional[torch.Tensor] = None,
1148 - w1_scale: Optional[torch.Tensor] = None,
1149 - w2_scale: Optional[torch.Tensor] = None,
1150 - a1_scale: Optional[torch.Tensor] = None,
1151 - a2_scale: Optional[torch.Tensor] = None,
1152 - quant_dtype: Optional[torch.dtype] = None,
1145 + b_bias1: torch.Tensor | None = None,
1146 + b_bias2: torch.Tensor | None = None,
1147 + expert_map: torch.Tensor | None = None,
1148 + w1_scale: torch.Tensor | None = None,
1149 + w2_scale: torch.Tensor | None = None,
1150 + a1_scale: torch.Tensor | None = None,
1151 + a2_scale: torch.Tensor | None = None,
1152 + quant_dtype: torch.dtype | None = None,
1153 per_act_token_quant=False,
1154 - block_shape: Optional[list[int]] = None,
1154 + block_shape: list[int] | None = None,
1155 apply_router_weights_on_input: bool = False,
1156 ) -> torch.Tensor:
1157 assert (
@@ -1261,10 +1261,10 @@ def torch_moe(
1261 w2: torch.Tensor,
1262 score: torch.Tensor,
1263 topk: int,
1264 - b_bias1: Optional[torch.Tensor] = None,
1265 - b_bias2: Optional[torch.Tensor] = None,
1264 + b_bias1: torch.Tensor | None = None,
1265 + b_bias2: torch.Tensor | None = None,
1266 global_num_experts: int = -1,
1267 - expert_map: Optional[torch.Tensor] = None,
1267 + expert_map: torch.Tensor | None = None,
1268 ) -> torch.Tensor:
1269 score = torch.softmax(score, dim=-1, dtype=torch.float32)
1270 topk_weight, topk_ids = torch.topk(score, topk)
@@ -1298,15 +1298,13 @@ def torch_moe_single(a, w, score, topk):
1298 # A special version of op check that has a restricted default set of test_utils
1299 # and a patched version of allclose that supports fp8 types.
1300 def opcheck(
1301 - op: Union[
1302 - torch._ops.OpOverload,
1303 - torch._ops.OpOverloadPacket,
1304 - torch._library.custom_ops.CustomOpDef,
1305 - ],
1301 + op: torch._ops.OpOverload
1302 + | torch._ops.OpOverloadPacket
1303 + | torch._library.custom_ops.CustomOpDef,
1304 args: tuple[Any, ...],
1307 - kwargs: Optional[dict[str, Any]] = None,
1305 + kwargs: dict[str, Any] | None = None,
1306 *,
1309 - test_utils: Union[str, Sequence[str]] = ALL_OPCHECK_TEST_UTILS,
1307 + test_utils: str | Sequence[str] = ALL_OPCHECK_TEST_UTILS,
1308 raise_exception: bool = True,
1309 cond: bool = True,
1310 ) -> dict[str, str]:
@@ -1338,7 +1336,7 @@ def baseline_scaled_mm(
1336 scale_a: torch.Tensor,
1337 scale_b: torch.Tensor,
1338 out_dtype: type[torch.dtype],
1341 - bias: Optional[torch.Tensor] = None,
1339 + bias: torch.Tensor | None = None,
1340 ) -> torch.Tensor:
1341 # We treat N-dimensional group scaling as extended numpy-style broadcasting
1342 # in numpy simply stretches dimensions with an extent of 1 to match
tests/lora/test_layers.py
+3 -4
@@ -4,7 +4,6 @@
4 import random
5 from copy import deepcopy
6 from dataclasses import dataclass
7 -from typing import Optional
7 from unittest.mock import patch
8
9 import pytest
@@ -106,7 +105,7 @@ def skip_cuda_with_stage_false(request):
105
106 def get_random_id_to_index(
107 num_loras: int, num_slots: int, log: bool = True
109 -) -> list[Optional[int]]:
108 +) -> list[int | None]:
109 """Creates a random lora_id_to_index mapping.
110
111 Args:
@@ -122,7 +121,7 @@ def get_random_id_to_index(
121 "num_loras must be less than or equal to num_slots."
122 )
123
125 - slots: list[Optional[int]] = [None] * num_slots
124 + slots: list[int | None] = [None] * num_slots
125 random_slot_selections = (torch.randperm(num_slots)[:num_loras]).tolist()
126 for lora_id, slot_idx in enumerate(random_slot_selections, start=1):
127 slots[slot_idx] = lora_id
@@ -134,7 +133,7 @@ def get_random_id_to_index(
133
134
135 def populate_loras(
137 - id_to_index: list[Optional[int]],
136 + id_to_index: list[int | None],
137 layer: BaseLayerWithLoRA,
138 layer_weights: torch.Tensor,
139 generate_embeddings_tensor: int = 0,
tests/lora/test_llama_tp.py
+2 -5
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import subprocess
4 import sys
5 -from typing import Union
5
6 import vllm
7 from vllm import LLM
@@ -27,7 +26,7 @@ def do_sample(
26 llm: vllm.LLM,
27 lora_path: str,
28 lora_id: int,
30 - tensorizer_config_dict: Union[dict, None] = None,
29 + tensorizer_config_dict: dict | None = None,
30 ) -> list[str]:
31 prompts = [
32 "[user] Write a SQL query to answer the question based on the table schema.\n\n context: CREATE TABLE table_name_74 (icao VARCHAR, airport VARCHAR)\n\n question: Name the ICAO for lilongwe international airport [/user] [assistant]", # noqa: E501
@@ -73,9 +72,7 @@ def do_sample(
72 return generated_texts
73
74
76 -def generate_and_test(
77 - llm, sql_lora_files, tensorizer_config_dict: Union[dict, None] = None
78 -):
75 +def generate_and_test(llm, sql_lora_files, tensorizer_config_dict: dict | None = None):
76 print("lora adapter created")
77 print("lora 1")
78 assert (
tests/lora/test_qwen2vl.py
+3 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import Optional
4
5 import pytest
6
@@ -20,7 +19,7 @@ class TestConfig:
19 max_loras: int = 2
20 max_lora_rank: int = 16
21 max_model_len: int = 4096
23 - mm_processor_kwargs: Optional[dict[str, int]] = None
22 + mm_processor_kwargs: dict[str, int] | None = None
23
24 def __post_init__(self):
25 if self.mm_processor_kwargs is None:
@@ -61,7 +60,7 @@ class Qwen2VLTester:
60 self,
61 images: list[ImageAsset],
62 expected_outputs: list[str],
64 - lora_id: Optional[int] = None,
63 + lora_id: int | None = None,
64 temperature: float = 0,
65 max_tokens: int = 5,
66 ):
@@ -92,7 +91,7 @@ class Qwen2VLTester:
91 self,
92 images: list[ImageAsset],
93 expected_outputs: list[list[str]],
95 - lora_id: Optional[int] = None,
94 + lora_id: int | None = None,
95 temperature: float = 0,
96 beam_width: int = 2,
97 max_tokens: int = 5,
tests/lora/test_resolver.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import pytest
6
@@ -14,7 +13,7 @@ class DummyLoRAResolver(LoRAResolver):
13
14 async def resolve_lora(
15 self, base_model_name: str, lora_name: str
17 - ) -> Optional[LoRARequest]:
16 + ) -> LoRARequest | None:
17 if lora_name == "test_lora":
18 return LoRARequest(
19 lora_name=lora_name,
tests/lora/test_utils.py
+2 -2
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections import OrderedDict
5 -from typing import NamedTuple, Optional
5 +from typing import NamedTuple
6 from unittest.mock import patch
7
8 import pytest
@@ -21,7 +21,7 @@ class LoRANameParserTestConfig(NamedTuple):
21 name: str
22 module_name: str
23 is_lora_a: bool
24 - weights_mapper: Optional[WeightsMapper] = None
24 + weights_mapper: WeightsMapper | None = None
25
26
27 def test_parse_fine_tuned_lora_name_valid():
tests/lora/utils.py
+2 -3
@@ -4,7 +4,6 @@
4 import json
5 import os
6 from dataclasses import dataclass
7 -from typing import Optional, Union
7
8 import torch
9 from safetensors.torch import save_file
@@ -81,7 +80,7 @@ class DummyLoRAManager:
80 module_name: str,
81 input_dim: int,
82 output_dims: list[int],
84 - noop_lora_index: Optional[list[int]] = None,
83 + noop_lora_index: list[int] | None = None,
84 rank: int = 8,
85 ):
86 base_loras: list[LoRALayerWeights] = []
@@ -113,7 +112,7 @@ def assert_close(a, b):
112 @dataclass
113 class PunicaTensors:
114 inputs_tensor: torch.Tensor
116 - lora_weights: Union[torch.Tensor, list[torch.Tensor]]
115 + lora_weights: torch.Tensor | list[torch.Tensor]
116 our_out_tensor: torch.Tensor
117 ref_out_tensor: torch.Tensor
118 b_seq_start_loc: torch.Tensor
tests/model_executor/model_loader/tensorizer_loader/conftest.py
+1 -1
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Callable
3 +from collections.abc import Callable
4
5 import pytest
6
tests/model_executor/test_enabled_custom_ops.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import pytest
5 import torch
@@ -76,7 +75,7 @@ class Relu3(ReLUSquaredActivation):
75 ],
76 )
77 def test_enabled_ops(
79 - env: Optional[str],
78 + env: str | None,
79 torch_level: int,
80 use_inductor: bool,
81 ops_enabled: list[int],
tests/models/language/generation/test_common.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import pytest
5 import torch
@@ -138,7 +137,7 @@ def test_models(
137 example_prompts, max_tokens, num_logprobs
138 )
139
141 - prompt_embeds: Optional[list[torch.Tensor]] = [] if use_prompt_embeds else None
140 + prompt_embeds: list[torch.Tensor] | None = [] if use_prompt_embeds else None
141
142 prompt_token_ids = []
143 for prompt in example_prompts:
tests/models/language/generation/test_hybrid.py
+1 -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 Callable
4 +from collections.abc import Callable
5
6 import pytest
7
tests/models/language/generation_ppl_test/ppl_utils.py
+2 -2
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 # Adapted from https://huggingface.co/docs/transformers/perplexity
4 -from typing import Optional, cast
4 +from typing import cast
5
6 import pytest
7 import torch
@@ -85,7 +85,7 @@ def wikitext_ppl_test(
85 n_tokens = 0
86 for output in outputs:
87 output = cast(TokensTextLogprobsPromptLogprobs, output)
88 - token_datas = cast(list[Optional[dict[int, Logprob]]], output[3])
88 + token_datas = cast(list[dict[int, Logprob] | None], output[3])
89
90 assert token_datas[0] is None
91 token_log_probs = []
tests/models/language/pooling/embed_utils.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Sequence
4 -from typing import Optional
4
5 import pytest
6
@@ -13,7 +12,7 @@ def run_embedding_correctness_test(
12 hf_model: "HfRunner",
13 inputs: list[str],
14 vllm_outputs: Sequence[list[float]],
16 - dimensions: Optional[int] = None,
15 + dimensions: int | None = None,
16 ):
17 hf_outputs = hf_model.encode(inputs)
18 if dimensions:
tests/models/language/pooling/test_embedding.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import pytest
5
@@ -66,7 +65,7 @@ def test_models(
65 pooling_type="MEAN", normalize=False
66 )
67
69 - max_model_len: Optional[int] = 512
68 + max_model_len: int | None = 512
69 if model in [
70 "sentence-transformers/all-MiniLM-L12-v2",
71 "sentence-transformers/stsb-roberta-base-v2",
tests/models/language/pooling/test_gritlm.py
-2
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import numpy as np
4 import openai
5 import pytest
tests/models/language/pooling_mteb_test/mteb_utils.py
+3 -4
@@ -3,7 +3,6 @@
3
4 import tempfile
5 from collections.abc import Sequence
6 -from typing import Optional
6
7 import mteb
8 import numpy as np
@@ -51,7 +50,7 @@ class VllmMtebEncoder(mteb.Encoder):
50
51 def predict(
52 self,
54 - sentences: list[tuple[str, str, Optional[str]]], # query, corpus, prompt
53 + sentences: list[tuple[str, str, str | None]], # query, corpus, prompt
54 *args,
55 **kwargs,
56 ) -> np.ndarray:
@@ -100,7 +99,7 @@ class ScoreClientMtebEncoder(mteb.Encoder):
99
100 def predict(
101 self,
103 - sentences: list[tuple[str, str, Optional[str]]], # query, corpus, prompt
102 + sentences: list[tuple[str, str, str | None]], # query, corpus, prompt
103 *args,
104 **kwargs,
105 ) -> np.ndarray:
@@ -294,7 +293,7 @@ def mteb_test_rerank_models_hf(
293 original_predict = hf_model.predict
294
295 def _predict(
297 - sentences: list[tuple[str, str, Optional[str]]], # query, corpus, prompt
296 + sentences: list[tuple[str, str, str | None]], # query, corpus, prompt
297 *args,
298 **kwargs,
299 ):
tests/models/language/pooling_mteb_test/test_bge_reranker_v2_gemma.py
+2 -2
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, Optional
3 +from typing import Any
4
5 import numpy as np
6 import pytest
@@ -111,7 +111,7 @@ class GemmaMtebEncoder(VllmMtebEncoder):
111
112 def predict(
113 self,
114 - sentences: list[tuple[str, str, Optional[str]]], # query, corpus, prompt
114 + sentences: list[tuple[str, str, str | None]], # query, corpus, prompt
115 *args,
116 **kwargs,
117 ) -> np.ndarray:
tests/models/multimodal/generation/test_granite_speech.py
+3 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Optional
5
6 import pytest
7 from transformers import AutoModelForSpeechSeq2Seq
@@ -18,8 +17,8 @@ HF_AUDIO_PROMPT = "<|start_of_role|>system<|end_of_role|>Knowledge Cutoff Date:
17
18
19 def vllm_to_hf_output(
21 - vllm_output: tuple[list[int], str, Optional[SampleLogprobs]],
22 -) -> tuple[list[int], str, Optional[SampleLogprobs]]:
20 + vllm_output: tuple[list[int], str, SampleLogprobs | None],
21 +) -> tuple[list[int], str, SampleLogprobs | None]:
22 """Sanitize hf output to be comparable with vllm output."""
23 output_ids, output_str, out_logprobs = vllm_output
24
@@ -46,7 +45,7 @@ def run_test(
45 max_tokens: int,
46 num_logprobs: int,
47 tensor_parallel_size: int,
49 - distributed_executor_backend: Optional[str] = None,
48 + distributed_executor_backend: str | None = None,
49 ):
50 """Inference result should be the same between hf and vllm.
51
tests/models/multimodal/generation/test_phi4_multimodal.py
+2 -3
@@ -3,7 +3,6 @@
3
4 import os
5 from collections.abc import Sequence
6 -from typing import Optional
6
7 import librosa
8 import pytest
@@ -57,7 +56,7 @@ if current_platform.is_rocm():
56 def run_test(
57 hf_runner: type[HfRunner],
58 vllm_runner: type[VllmRunner],
60 - inputs: Sequence[tuple[list[str], PromptImageInput, Optional[PromptAudioInput]]],
59 + inputs: Sequence[tuple[list[str], PromptImageInput, PromptAudioInput | None]],
60 model: str,
61 *,
62 max_model_len: int,
@@ -66,7 +65,7 @@ def run_test(
65 num_logprobs: int,
66 mm_limit: int,
67 tensor_parallel_size: int,
69 - distributed_executor_backend: Optional[str] = None,
68 + distributed_executor_backend: str | None = None,
69 ):
70 """Inference result should be the same between hf and vllm.
71
tests/models/multimodal/generation/test_phi4mm.py
+3 -4
@@ -3,7 +3,6 @@
3
4 import os
5 from collections.abc import Sequence
6 -from typing import Optional
6
7 import librosa
8 import pytest
@@ -48,7 +47,7 @@ models = [model_path]
47
48
49 def vllm_to_hf_output(
51 - vllm_output: tuple[list[int], str, Optional[SampleLogprobs]], model: str
50 + vllm_output: tuple[list[int], str, SampleLogprobs | None], model: str
51 ):
52 """Sanitize vllm output to be comparable with hf output."""
53 _, output_str, out_logprobs = vllm_output
@@ -79,7 +78,7 @@ if current_platform.is_rocm():
78 def run_test(
79 hf_runner: type[HfRunner],
80 vllm_runner: type[VllmRunner],
82 - inputs: Sequence[tuple[list[str], PromptImageInput, Optional[PromptAudioInput]]],
81 + inputs: Sequence[tuple[list[str], PromptImageInput, PromptAudioInput | None]],
82 model: str,
83 *,
84 max_model_len: int,
@@ -88,7 +87,7 @@ def run_test(
87 num_logprobs: int,
88 mm_limit: int,
89 tensor_parallel_size: int,
91 - distributed_executor_backend: Optional[str] = None,
90 + distributed_executor_backend: str | None = None,
91 ):
92 """Inference result should be the same between hf and vllm.
93
tests/models/multimodal/generation/test_pixtral.py
+2 -2
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import json
4 from dataclasses import asdict
5 -from typing import TYPE_CHECKING, Any, Optional
5 +from typing import TYPE_CHECKING, Any
6
7 import pytest
8 from mistral_common.multimodal import download_image
@@ -117,7 +117,7 @@ FIXTURE_LOGPROBS_CHAT = {
117 MISTRAL_SMALL_3_1_ID: FIXTURES_PATH / "mistral_small_3_chat.json",
118 }
119
120 -OutputsLogprobs = list[tuple[list[int], str, Optional[SampleLogprobs]]]
120 +OutputsLogprobs = list[tuple[list[int], str, SampleLogprobs | None]]
121
122
123 # For the test author to store golden output in JSON
tests/models/multimodal/generation/test_qwen2_vl.py
+3 -3
@@ -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 Any, Optional, TypedDict, Union
4 +from typing import Any, TypedDict
5
6 import numpy.typing as npt
7 import pytest
@@ -83,7 +83,7 @@ class Qwen2VLPromptVideoEmbeddingInput(TypedDict):
83
84
85 def batch_make_image_embeddings(
86 - image_batches: list[Union[Image.Image, list[Image.Image]]],
86 + image_batches: list[Image.Image | list[Image.Image]],
87 processor,
88 llm: VllmRunner,
89 ) -> list[Qwen2VLPromptImageEmbeddingInput]:
@@ -272,7 +272,7 @@ def run_embedding_input_test(
272 num_logprobs: int,
273 mm_limit: int,
274 tensor_parallel_size: int,
275 - distributed_executor_backend: Optional[str] = None,
275 + distributed_executor_backend: str | None = None,
276 ):
277 """Inference result should be the same between
278 original image/video input and image/video embeddings input.
tests/models/multimodal/generation/test_whisper.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import pytest
5
@@ -92,7 +91,7 @@ def run_test(
91 model: str,
92 *,
93 tensor_parallel_size: int,
95 - distributed_executor_backend: Optional[str] = None,
94 + distributed_executor_backend: str | None = None,
95 ) -> None:
96 prompt_list = PROMPTS * 10
97 expected_list = EXPECTED[model] * 10
tests/models/multimodal/generation/vlm_utils/builders.py
+7 -10
@@ -2,9 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Helpers for building inputs that can be leveraged for different test types."""
4
5 -from collections.abc import Iterable
5 +from collections.abc import Callable, Iterable
6 from pathlib import PosixPath
7 -from typing import Callable, Optional, Union
7
8 import torch
9
@@ -47,9 +46,9 @@ def replace_test_placeholder(
46
47 def get_model_prompts(
48 base_prompts: Iterable[str],
50 - img_idx_to_prompt: Optional[Callable[[int], str]],
51 - video_idx_to_prompt: Optional[Callable[[int], str]],
52 - audio_idx_to_prompt: Optional[Callable[[int], str]],
49 + img_idx_to_prompt: Callable[[int], str] | None,
50 + video_idx_to_prompt: Callable[[int], str] | None,
51 + audio_idx_to_prompt: Callable[[int], str] | None,
52 prompt_formatter: Callable[[str], str],
53 ) -> list[str]:
54 """Given a model-agnostic base prompt and test configuration for a model(s)
@@ -93,7 +92,7 @@ def build_single_image_inputs_from_test_info(
92 test_info: VLMTestInfo,
93 image_assets: ImageTestAssets,
94 size_wrapper: ImageSizeWrapper,
96 - tmp_path: Optional[PosixPath] = None,
95 + tmp_path: PosixPath | None = None,
96 ) -> list[PromptWithMultiModalInput]:
97 if test_info.prompt_formatter is None:
98 raise ValueError("Prompt formatter must be set to build single image inputs")
@@ -147,7 +146,7 @@ def build_multi_image_inputs_from_test_info(
146 test_info: VLMTestInfo,
147 image_assets: ImageTestAssets,
148 size_wrapper: ImageSizeWrapper,
150 - tmp_path: Optional[PosixPath] = None,
149 + tmp_path: PosixPath | None = None,
150 ) -> list[PromptWithMultiModalInput]:
151 if test_info.prompt_formatter is None:
152 raise ValueError("Prompt formatter must be set to build multi image inputs")
@@ -266,9 +265,7 @@ def build_video_inputs_from_test_info(
265 ]
266
267
269 -def apply_image_size_scaling(
270 - image, size: Union[float, tuple[int, int]], size_type: SizeType
271 -):
268 +def apply_image_size_scaling(image, size: float | tuple[int, int], size_type: SizeType):
269 """Applies a size scaler to one image; this can be an image size factor,
270 which scales the image while maintaining the aspect ratio"""
271 # Special case for embeddings; if it's a tensor, it's only valid if we
tests/models/multimodal/generation/vlm_utils/core.py
+11 -10
@@ -2,7 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Core test implementation to be shared across modalities."""
4
5 -from typing import Any, Callable, Optional
5 +from collections.abc import Callable
6 +from typing import Any
7
8 import torch
9 from transformers.models.auto.auto_factory import _BaseAutoModelClass
@@ -27,21 +28,21 @@ def run_test(
28 enforce_eager: bool,
29 max_model_len: int,
30 max_num_seqs: int,
30 - hf_output_post_proc: Optional[Callable[[RunnerOutput, str], Any]],
31 - vllm_output_post_proc: Optional[Callable[[RunnerOutput, str], Any]],
31 + hf_output_post_proc: Callable[[RunnerOutput, str], Any] | None,
32 + vllm_output_post_proc: Callable[[RunnerOutput, str], Any] | None,
33 auto_cls: type[_BaseAutoModelClass],
34 use_tokenizer_eos: bool,
35 comparator: Callable[..., None],
35 - get_stop_token_ids: Optional[Callable[[AnyTokenizer], list[int]]],
36 - stop_str: Optional[list[str]],
36 + get_stop_token_ids: Callable[[AnyTokenizer], list[int]] | None,
37 + stop_str: list[str] | None,
38 limit_mm_per_prompt: dict[str, int],
38 - vllm_runner_kwargs: Optional[dict[str, Any]],
39 - hf_model_kwargs: Optional[dict[str, Any]],
40 - patch_hf_runner: Optional[Callable[[HfRunner], HfRunner]],
39 + vllm_runner_kwargs: dict[str, Any] | None,
40 + hf_model_kwargs: dict[str, Any] | None,
41 + patch_hf_runner: Callable[[HfRunner], HfRunner] | None,
42 runner: RunnerOption = "auto",
42 - distributed_executor_backend: Optional[str] = None,
43 + distributed_executor_backend: str | None = None,
44 tensor_parallel_size: int = 1,
44 - vllm_embeddings: Optional[torch.Tensor] = None,
45 + vllm_embeddings: torch.Tensor | None = None,
46 ):
47 """Modality agnostic test executor for comparing HF/vLLM outputs."""
48 # In the case of embeddings, vLLM takes separate input tensors
tests/models/multimodal/generation/vlm_utils/custom_inputs.py
+1 -1
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Custom input builders for edge-cases in different models."""
4
5 -from typing import Callable
5 +from collections.abc import Callable
6
7 from vllm.assets.image import ImageAsset
8 from vllm.multimodal.image import rescale_image_size
tests/models/multimodal/generation/vlm_utils/model_utils.py
+10 -11
@@ -7,7 +7,6 @@ typically specific to a small subset of models.
7
8 import types
9 from pathlib import PosixPath
10 -from typing import Optional, Union
10
11 import numpy as np
12 import numpy.typing as npt
@@ -58,7 +57,7 @@ def fuyu_vllm_to_hf_output(vllm_output: RunnerOutput, model: str) -> RunnerOutpu
57
58 def qwen_vllm_to_hf_output(
59 vllm_output: RunnerOutput, model: str
61 -) -> tuple[list[int], str, Optional[SampleLogprobs]]:
60 +) -> tuple[list[int], str, SampleLogprobs | None]:
61 """Sanitize vllm output [qwen models] to be comparable with hf output."""
62 output_ids, output_str, out_logprobs = vllm_output
63
@@ -69,7 +68,7 @@ def qwen_vllm_to_hf_output(
68
69 def qwen2_vllm_to_hf_output(
70 vllm_output: RunnerOutput, model: str
72 -) -> tuple[list[int], str, Optional[SampleLogprobs]]:
71 +) -> tuple[list[int], str, SampleLogprobs | None]:
72 """Sanitize vllm output [qwen2 models] to be comparable with hf output."""
73 output_ids, output_str, out_logprobs = vllm_output
74
@@ -80,7 +79,7 @@ def qwen2_vllm_to_hf_output(
79
80 def kimiv_vl_vllm_to_hf_output(
81 vllm_output: RunnerOutput, model: str
83 -) -> tuple[list[int], str, Optional[SampleLogprobs]]:
82 +) -> tuple[list[int], str, SampleLogprobs | None]:
83 """Sanitize vllm output [kimi_vl models] to be comparable with hf output."""
84 output_ids, output_str, out_logprobs = vllm_output
85
@@ -99,7 +98,7 @@ def llava_image_vllm_to_hf_output(
98
99 def llava_video_vllm_to_hf_output(
100 vllm_output: RunnerOutput, model: str
102 -) -> tuple[list[int], str, Optional[SampleLogprobs]]:
101 +) -> tuple[list[int], str, SampleLogprobs | None]:
102 config = AutoConfig.from_pretrained(model)
103 mm_token_id = config.video_token_index
104 return _llava_vllm_to_hf_output(vllm_output, model, mm_token_id)
@@ -263,7 +262,7 @@ def get_llava_embeddings(image_assets: ImageTestAssets):
262
263 ####### Prompt path encoders for models that need models on disk
264 def qwen_prompt_path_encoder(
266 - tmp_path: PosixPath, prompt: str, assets: Union[list[ImageAsset], ImageTestAssets]
265 + tmp_path: PosixPath, prompt: str, assets: list[ImageAsset] | ImageTestAssets
266 ) -> str:
267 """Given a temporary dir path, export one or more image assets into the
268 tempdir & replace its contents with the local path to the string so that
@@ -440,7 +439,7 @@ def h2ovl_patch_hf_runner(hf_model: HfRunner) -> HfRunner:
439 self.max_num = self.config.max_dynamic_patch
440 self.image_size = self.vision_config.image_size
441
443 - def __call__(self, text: str, images: Union[Image, list[Image]], **kwargs):
442 + def __call__(self, text: str, images: Image | list[Image], **kwargs):
443 from vllm.model_executor.models.h2ovl import (
444 IMG_CONTEXT,
445 IMG_END,
@@ -499,7 +498,7 @@ def skyworkr1v_patch_hf_runner(hf_model: HfRunner) -> HfRunner:
498 self.max_num = self.config.max_dynamic_patch
499 self.image_size = self.vision_config.image_size
500
502 - def __call__(self, text: str, images: Union[Image, list[Image]], **kwargs):
501 + def __call__(self, text: str, images: Image | list[Image], **kwargs):
502 from vllm.model_executor.models.skyworkr1v import (
503 IMG_CONTEXT,
504 IMG_END,
@@ -560,8 +559,8 @@ def internvl_patch_hf_runner(hf_model: HfRunner) -> HfRunner:
559 def __call__(
560 self,
561 text: str,
563 - images: Union[Image, list[Image]] = None,
564 - videos: Union[npt.NDArray, list[npt.NDArray]] = None,
562 + images: Image | list[Image] = None,
563 + videos: npt.NDArray | list[npt.NDArray] = None,
564 **kwargs,
565 ):
566 from vllm.model_executor.models.internvl import (
@@ -650,7 +649,7 @@ def _internvl_generate(
649 self,
650 pixel_values: torch.FloatTensor,
651 input_ids: torch.FloatTensor,
653 - attention_mask: Optional[torch.LongTensor] = None,
652 + attention_mask: torch.LongTensor | None = None,
653 **generate_kwargs,
654 ) -> torch.LongTensor:
655 """Generate method for InternVL2 model without fixed use_cache."""
tests/models/multimodal/generation/vlm_utils/types.py
+30 -30
@@ -2,10 +2,10 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Types for writing multimodal model tests."""
4
5 -from collections.abc import Iterable
5 +from collections.abc import Callable, Iterable
6 from enum import Enum
7 from pathlib import PosixPath
8 -from typing import Any, Callable, NamedTuple, Optional, Union
8 +from typing import Any, NamedTuple
9
10 import torch
11 from pytest import MarkDecorator
@@ -52,16 +52,16 @@ VIDEO_BASE_PROMPT = f"{TEST_VIDEO_PLACEHOLDER}Why is this video funny?"
52
53 IMAGE_SIZE_FACTORS = [(), (1.0,), (1.0, 1.0, 1.0), (0.25, 0.5, 1.0)]
54 EMBEDDING_SIZE_FACTORS = [(), (1.0,), (1.0, 1.0, 1.0)]
55 -RunnerOutput = tuple[list[int], str, Optional[SampleLogprobs]]
55 +RunnerOutput = tuple[list[int], str, SampleLogprobs | None]
56
57
58 class PromptWithMultiModalInput(NamedTuple):
59 """Holds the multimodal input for a single test case."""
60
61 prompts: list[str]
62 - image_data: Optional[PromptImageInput] = None
63 - video_data: Optional[PromptVideoInput] = None
64 - audio_data: Optional[PromptAudioInput] = None
62 + image_data: PromptImageInput | None = None
63 + video_data: PromptVideoInput | None = None
64 + audio_data: PromptAudioInput | None = None
65
66
67 class VLMTestType(Enum):
@@ -87,17 +87,17 @@ class ImageSizeWrapper(NamedTuple):
87 type: SizeType
88 # A size factor is a wrapper of 0+ floats,
89 # while a fixed size contains an iterable of integer pairs
90 - data: Union[Iterable[float], Iterable[tuple[int, int]]]
90 + data: Iterable[float] | Iterable[tuple[int, int]]
91
92
93 class VLMTestInfo(NamedTuple):
94 """Holds the configuration for 1+ tests for one model architecture."""
95
96 models: list[str]
97 - test_type: Union[VLMTestType, Iterable[VLMTestType]]
97 + test_type: VLMTestType | Iterable[VLMTestType]
98
99 # Should be None only if this is a CUSTOM_INPUTS test
100 - prompt_formatter: Optional[Callable[[str], str]] = None
100 + prompt_formatter: Callable[[str], str] | None = None
101 img_idx_to_prompt: Callable[[int], str] = lambda idx: "<image>\n"
102 video_idx_to_prompt: Callable[[int], str] = lambda idx: "<video>\n"
103 audio_idx_to_prompt: Callable[[int], str] = lambda idx: "<audio>\n"
@@ -111,9 +111,9 @@ class VLMTestInfo(NamedTuple):
111
112 # Function for converting ImageAssets to image embeddings;
113 # We need to define this explicitly for embedding tests
114 - convert_assets_to_embeddings: Optional[
115 - Callable[[ImageTestAssets], list[torch.Tensor]]
116 - ] = None
114 + convert_assets_to_embeddings: (
115 + Callable[[ImageTestAssets], list[torch.Tensor]] | None
116 + ) = None
117
118 # Exposed options for vLLM runner; we change these in a several tests,
119 # but the defaults are derived from VllmRunner & the engine defaults
@@ -123,25 +123,25 @@ class VLMTestInfo(NamedTuple):
123 max_num_seqs: int = 256
124 runner: RunnerOption = "auto"
125 tensor_parallel_size: int = 1
126 - vllm_runner_kwargs: Optional[dict[str, Any]] = None
126 + vllm_runner_kwargs: dict[str, Any] | None = None
127
128 # Optional callable which gets a list of token IDs from the model tokenizer
129 - get_stop_token_ids: Optional[Callable[[AnyTokenizer], list[int]]] = None
129 + get_stop_token_ids: Callable[[AnyTokenizer], list[int]] | None = None
130 # Optional list of strings to stop generation, useful when stop tokens are
131 # not special tokens in the tokenizer
132 - stop_str: Optional[list[str]] = None
132 + stop_str: list[str] | None = None
133
134 # Exposed options for HF runner
135 - hf_model_kwargs: Optional[dict[str, Any]] = None
135 + hf_model_kwargs: dict[str, Any] | None = None
136 # Indicates we should explicitly pass the EOS from the tokenizer
137 use_tokenizer_eos: bool = False
138 auto_cls: type[_BaseAutoModelClass] = AutoModelForCausalLM
139 - patch_hf_runner: Optional[Callable[[HfRunner], HfRunner]] = None
139 + patch_hf_runner: Callable[[HfRunner], HfRunner] | None = None
140
141 # Post processors that if defined, will run oun the outputs of the
142 # vLLM and HF runner, respectively (useful for sanitization, etc).
143 - vllm_output_post_proc: Optional[Callable[[RunnerOutput, str], Any]] = None
144 - hf_output_post_proc: Optional[Callable[[RunnerOutput, str], Any]] = None
143 + vllm_output_post_proc: Callable[[RunnerOutput, str], Any] | None = None
144 + hf_output_post_proc: Callable[[RunnerOutput, str], Any] | None = None
145
146 # Consumes the output of the callables above and checks if they're equal
147 comparator: Callable[..., None] = check_logprobs_close
@@ -152,7 +152,7 @@ class VLMTestInfo(NamedTuple):
152 max_tokens: int = 128
153 num_logprobs: int = 5
154 dtype: str = "auto"
155 - distributed_executor_backend: Optional[str] = None
155 + distributed_executor_backend: str | None = None
156 # Only expanded in video tests
157 num_video_frames: int = 16
158
@@ -162,19 +162,19 @@ class VLMTestInfo(NamedTuple):
162 # once per tests (much like concatenating and wrapping in one parametrize
163 # call)
164 image_size_factors: Iterable[Iterable[float]] = IMAGE_SIZE_FACTORS
165 - image_sizes: Optional[Iterable[Iterable[tuple[int, int]]]] = None
165 + image_sizes: Iterable[Iterable[tuple[int, int]]] | None = None
166
167 # Hack for updating a prompt to take into a local path; currently only used
168 # for Qwen-VL, which requires encoding the image path / url into the prompt
169 # for HF runner
170 - prompt_path_encoder: Optional[
171 - Callable[[PosixPath, str, Union[list[ImageAsset], ImageTestAssets]], str]
172 - ] = None # noqa: E501
170 + prompt_path_encoder: (
171 + Callable[[PosixPath, str, list[ImageAsset] | ImageTestAssets], str] | None
172 + ) = None # noqa: E501
173
174 # Allows configuring a test to run with custom inputs
175 - custom_test_opts: Optional[list[CustomTestOptions]] = None
175 + custom_test_opts: list[CustomTestOptions] | None = None
176
177 - marks: Optional[list[MarkDecorator]] = None
177 + marks: list[MarkDecorator] | None = None
178
179 def get_non_parametrized_runner_kwargs(self):
180 """Returns a dictionary of expandable kwargs for items that are used
@@ -207,10 +207,10 @@ class ExpandableVLMTestArgs(NamedTuple):
207 max_tokens: int
208 num_logprobs: int
209 dtype: str
210 - distributed_executor_backend: Optional[str]
210 + distributed_executor_backend: str | None
211 # Sizes are used for everything except for custom input tests
212 - size_wrapper: Optional[ImageSizeWrapper] = None
212 + size_wrapper: ImageSizeWrapper | None = None
213 # Video only
214 - num_video_frames: Optional[int] = None
214 + num_video_frames: int | None = None
215 # Custom inputs only
216 - custom_test_opts: Optional[CustomTestOptions] = None
216 + custom_test_opts: CustomTestOptions | None = None
tests/models/multimodal/pooling/test_dse_qwen2_vl.py
+1 -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 Callable
4 +from collections.abc import Callable
5
6 import pytest
7 import torch
tests/models/multimodal/pooling/test_jinavl_reranker.py
+2 -3
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Union
3
4 import pytest
5 from transformers import AutoModel
@@ -32,7 +31,7 @@ def vllm_reranker(
31 def create_image_param(url: str) -> ChatCompletionContentPartImageParam:
32 return {"type": "image_url", "image_url": {"url": f"{url}"}}
33
35 - query: Union[list[str], ScoreMultiModalParam]
34 + query: list[str] | ScoreMultiModalParam
35 if query_type == "text":
36 query = query_strs
37 elif query_type == "image":
@@ -40,7 +39,7 @@ def vllm_reranker(
39 content=[create_image_param(url) for url in query_strs]
40 )
41
43 - documents: Union[list[str], ScoreMultiModalParam]
42 + documents: list[str] | ScoreMultiModalParam
43 if doc_type == "text":
44 documents = document_strs
45 elif doc_type == "image":
tests/models/multimodal/processing/test_common.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from functools import partial
5 -from typing import Optional, Union
5
6 import numpy as np
7 import pytest
@@ -247,7 +246,7 @@ MM_DATA_PATCHES = {
246 def _test_processing_correctness_one(
247 model_config: ModelConfig,
248 tokenizer: AnyTokenizer,
250 - prompt: Union[str, list[int]],
249 + prompt: str | list[int],
250 mm_data: MultiModalDataDict,
251 baseline_processor: BaseMultiModalProcessor,
252 cached_processor: BaseMultiModalProcessor,
@@ -441,7 +440,7 @@ def _assert_inputs_equal(
440 a: MultiModalInputs,
441 b: MultiModalInputs,
442 *,
444 - ignore_mm_keys: Optional[set[str]] = None,
443 + ignore_mm_keys: set[str] | None = None,
444 msg: str = "",
445 ):
446 if ignore_mm_keys is None:
tests/models/multimodal/processing/test_h2ovl.py
+1 -2
@@ -3,7 +3,6 @@
3 """Tests for H2OVL's multimodal preprocessing kwargs."""
4
5 from collections.abc import Mapping
6 -from typing import Optional
6
7 import pytest
8 from PIL import Image
@@ -149,7 +148,7 @@ def test_processor_override(
148 size_factors: list[int],
149 min_dynamic_patch: int,
150 max_dynamic_patch: int,
152 - dynamic_image_size: Optional[bool],
151 + dynamic_image_size: bool | None,
152 kwargs_on_init: bool,
153 ):
154 mm_processor_kwargs = {
tests/models/multimodal/processing/test_internvl.py
+1 -2
@@ -3,7 +3,6 @@
3 """Tests for InternVL's multimodal preprocessing kwargs."""
4
5 from collections.abc import Mapping
6 -from typing import Optional
6
7 import pytest
8 from PIL import Image
@@ -103,7 +102,7 @@ def test_processor_override(
102 size_factors: list[int],
103 min_dynamic_patch: int,
104 max_dynamic_patch: int,
106 - dynamic_image_size: Optional[bool],
105 + dynamic_image_size: bool | None,
106 kwargs_on_init: bool,
107 ):
108 mm_processor_kwargs = {
tests/models/multimodal/processing/test_nemotron_vl.py
+1 -2
@@ -3,7 +3,6 @@
3 """Tests for Nemotron-Nano-VL's multimodal preprocessing kwargs."""
4
5 from collections.abc import Mapping
6 -from typing import Optional
6
7 import pytest
8 from PIL import Image
@@ -105,7 +104,7 @@ def test_processor_override(
104 size_factors: list[int],
105 min_dynamic_patch: int,
106 max_dynamic_patch: int,
108 - dynamic_image_size: Optional[bool],
107 + dynamic_image_size: bool | None,
108 kwargs_on_init: bool,
109 ):
110 mm_processor_kwargs = {
tests/models/multimodal/processing/test_tensor_schema.py
+8 -8
@@ -4,7 +4,7 @@ import tempfile
4 from collections.abc import Iterable
5 from contextlib import contextmanager
6 from functools import partial
7 -from typing import Any, Union
7 +from typing import Any, TypeAlias
8
9 import numpy as np
10 import pytest
@@ -55,15 +55,15 @@ REPO_ID_TO_SKIP = {
55 }
56
57 ImageInput = list[Image.Image]
58 -VideoInput = Union[
59 - list[Image.Image], list[np.ndarray], list[tuple[np.ndarray, dict[str, Any]]]
60 -]
58 +VideoInput: TypeAlias = (
59 + list[Image.Image] | list[np.ndarray] | list[tuple[np.ndarray, dict[str, Any]]]
60 +)
61 AudioInput = list[tuple[np.ndarray, int]]
62
63
64 def _resize_data(
65 - _data: Union[Image.Image, np.ndarray], size_factor: float
66 -) -> Union[Image.Image, np.ndarray]:
65 + _data: Image.Image | np.ndarray, size_factor: float
66 +) -> Image.Image | np.ndarray:
67 assert size_factor <= 1, "Size factor must be less than 1"
68 # Image input
69 if isinstance(_data, Image.Image):
@@ -88,8 +88,8 @@ def _resize_data(
88
89
90 def resize_mm_data(
91 - data: Union[ImageInput, VideoInput, AudioInput], size_factors: tuple[float, ...]
92 -) -> Union[ImageInput, VideoInput, AudioInput]:
91 + data: ImageInput | VideoInput | AudioInput, size_factors: tuple[float, ...]
92 +) -> ImageInput | VideoInput | AudioInput:
93 size_factors = size_factors[: len(data)]
94 if is_list_of(data, (Image.Image, np.ndarray, list)):
95 return [_resize_data(d, s) for d, s in zip(data, size_factors)]
tests/models/quantization/test_awq.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import pytest
6 import torch
@@ -30,7 +29,7 @@ def run_awq_test(
29 max_tokens: int,
30 num_logprobs: int,
31 tensor_parallel_size: int,
33 - distributed_executor_backend: Optional[str] = None,
32 + distributed_executor_backend: str | None = None,
33 ):
34 images = [asset.pil_image for asset in image_assets]
35
tests/models/registry.py
+10 -10
@@ -3,7 +3,7 @@
3
4 from collections.abc import Mapping, Set
5 from dataclasses import dataclass, field
6 -from typing import Any, Literal, Optional
6 +from typing import Any, Literal
7
8 import pytest
9 import torch
@@ -21,29 +21,29 @@ class _HfExamplesInfo:
21 extras: Mapping[str, str] = field(default_factory=dict)
22 """Extra models to use for testing this architecture."""
23
24 - tokenizer: Optional[str] = None
24 + tokenizer: str | None = None
25 """Set the tokenizer to load for this architecture."""
26
27 tokenizer_mode: TokenizerMode = "auto"
28 """Set the tokenizer type for this architecture."""
29
30 - speculative_model: Optional[str] = None
30 + speculative_model: str | None = None
31 """
32 The default model to use for testing this architecture, which is only used
33 for speculative decoding.
34 """
35
36 - min_transformers_version: Optional[str] = None
36 + min_transformers_version: str | None = None
37 """
38 The minimum version of HF Transformers that is required to run this model.
39 """
40
41 - max_transformers_version: Optional[str] = None
41 + max_transformers_version: str | None = None
42 """
43 The maximum version of HF Transformers that this model runs on.
44 """
45
46 - transformers_version_reason: Optional[str] = None
46 + transformers_version_reason: str | None = None
47 """
48 The reason for the minimum/maximum version requirement.
49 """
@@ -82,19 +82,19 @@ class _HfExamplesInfo:
82 hf_overrides: dict[str, Any] = field(default_factory=dict)
83 """The ``hf_overrides`` required to load the model."""
84
85 - max_model_len: Optional[int] = None
85 + max_model_len: int | None = None
86 """
87 The maximum model length to use for this model. Some models default to a
88 length that is too large to fit into memory in CI.
89 """
90
91 - revision: Optional[str] = None
91 + revision: str | None = None
92 """
93 The specific revision (commit hash, tag, or branch) to use for the model.
94 If not specified, the default revision will be used.
95 """
96
97 - max_num_seqs: Optional[int] = None
97 + max_num_seqs: int | None = None
98 """Maximum number of sequences to be processed in a single iteration."""
99
100 use_original_num_layers: bool = False
@@ -109,7 +109,7 @@ class _HfExamplesInfo:
109 on_fail: Literal["error", "skip", "return"],
110 check_min_version: bool = True,
111 check_max_version: bool = True,
112 - ) -> Optional[str]:
112 + ) -> str | None:
113 """
114 If the installed transformers version does not meet the requirements,
115 perform the given action.
tests/models/test_transformers.py
+4 -4
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Test the functionality of the Transformers backend."""
4
5 -from typing import Any, Optional, Union
5 +from typing import Any
6
7 import pytest
8
@@ -21,12 +21,12 @@ def get_model(arch: str) -> str:
21
22
23 def check_implementation(
24 - runner_ref: type[Union[HfRunner, VllmRunner]],
24 + runner_ref: type[HfRunner | VllmRunner],
25 runner_test: type[VllmRunner],
26 example_prompts: list[str],
27 model: str,
28 - kwargs_ref: Optional[dict[str, Any]] = None,
29 - kwargs_test: Optional[dict[str, Any]] = None,
28 + kwargs_ref: dict[str, Any] | None = None,
29 + kwargs_test: dict[str, Any] | None = None,
30 **kwargs,
31 ):
32 if kwargs_ref is None:
tests/models/utils.py
+19 -19
@@ -4,7 +4,7 @@
4 import warnings
5 from collections.abc import Sequence
6 from dataclasses import dataclass
7 -from typing import Any, Optional, Union
7 +from typing import Any
8
9 import torch
10 import torch.nn.functional as F
@@ -57,7 +57,7 @@ def check_outputs_equal(
57 #
58 # Assumes prompt logprobs were not requested.
59 TokensTextLogprobs = tuple[
60 - list[int], str, Optional[Union[list[dict[int, float]], SampleLogprobs]]
60 + list[int], str, list[dict[int, float]] | SampleLogprobs | None
61 ]
62
63 # Allow for tokens to be represented as str's rather than IDs;
@@ -68,7 +68,7 @@ TokensTextLogprobs = tuple[
68 #
69 # Assumes prompt logprobs were not requested.
70 TextTextLogprobs = tuple[
71 - list[str], str, Optional[Union[list[dict[str, float]], list[dict[str, Logprob]]]]
71 + list[str], str, list[dict[str, float]] | list[dict[str, Logprob]] | None
72 ]
73
74 # Representation of generated sequence as a tuple of
@@ -81,18 +81,18 @@ TextTextLogprobs = tuple[
81 TokensTextLogprobsPromptLogprobs = tuple[
82 list[int],
83 str,
84 - Optional[Union[list[dict[int, float]], SampleLogprobs]],
85 - Optional[Union[list[Optional[dict[int, float]]], PromptLogprobs]],
84 + list[dict[int, float]] | SampleLogprobs | None,
85 + list[dict[int, float] | None] | PromptLogprobs | None,
86 ]
87
88
89 def check_logprobs_close(
90 *,
91 outputs_0_lst: Sequence[
92 - Union[TokensTextLogprobs, TokensTextLogprobsPromptLogprobs, TextTextLogprobs]
92 + TokensTextLogprobs | TokensTextLogprobsPromptLogprobs | TextTextLogprobs
93 ],
94 outputs_1_lst: Sequence[
95 - Union[TokensTextLogprobs, TokensTextLogprobsPromptLogprobs, TextTextLogprobs]
95 + TokensTextLogprobs | TokensTextLogprobsPromptLogprobs | TextTextLogprobs
96 ],
97 name_0: str,
98 name_1: str,
@@ -273,9 +273,9 @@ def build_model_context(
273 model_id: str,
274 runner: RunnerOption = "auto",
275 dtype: ModelDType = "auto",
276 - model_config_kwargs: Optional[dict[str, Any]] = None,
277 - mm_processor_kwargs: Optional[dict[str, Any]] = None,
278 - limit_mm_per_prompt: Optional[dict[str, int]] = None,
276 + model_config_kwargs: dict[str, Any] | None = None,
277 + mm_processor_kwargs: dict[str, Any] | None = None,
278 + limit_mm_per_prompt: dict[str, int] | None = None,
279 mm_processor_cache_gb: int = 0,
280 ):
281 """Creates an InputProcessingContext for a given model.
@@ -369,18 +369,18 @@ class ModelInfo:
369 name: str
370 architecture: str = ""
371 dtype: str = "auto"
372 - max_model_len: Optional[int] = None
372 + max_model_len: int | None = None
373 hf_dtype: str = "float32"
374 - hf_overrides: Optional[dict[str, Any]] = None
374 + hf_overrides: dict[str, Any] | None = None
375 default_pooling_type: str = ""
376 enable_test: bool = True
377
378
379 @dataclass
380 class EmbedModelInfo(ModelInfo):
381 - mteb_score: Optional[float] = None
381 + mteb_score: float | None = None
382 is_matryoshka: bool = False
383 - matryoshka_dimensions: Optional[list[int]] = None
383 + matryoshka_dimensions: list[int] | None = None
384
385
386 @dataclass
@@ -395,7 +395,7 @@ class LASTPoolingEmbedModelInfo(EmbedModelInfo):
395
396 @dataclass
397 class RerankModelInfo(ModelInfo):
398 - mteb_score: Optional[float] = None
398 + mteb_score: float | None = None
399
400
401 @dataclass
@@ -411,14 +411,14 @@ class LASTPoolingRerankModelInfo(RerankModelInfo):
411 @dataclass
412 class GenerateModelInfo(ModelInfo):
413 hf_dtype: str = "auto"
414 - hf_ppl: Optional[float] = None
414 + hf_ppl: float | None = None
415
416
417 def dummy_hf_overrides(
418 hf_config: PretrainedConfig,
419 *,
420 model_arch: str = "",
421 - exist_overrides: Optional[dict[str, Any]] = None,
421 + exist_overrides: dict[str, Any] | None = None,
422 use_original_num_layers: bool = False,
423 ) -> PretrainedConfig:
424 """
@@ -507,8 +507,8 @@ def dummy_hf_overrides(
507
508 def check_transformers_version(
509 model: str,
510 - min_transformers_version: Optional[str] = None,
511 - max_transformers_version: Optional[str] = None,
510 + min_transformers_version: str | None = None,
511 + max_transformers_version: str | None = None,
512 ):
513 from .registry import _HfExamplesInfo
514
tests/multimodal/test_cache.py
+3 -4
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import numpy as np
5 import pytest
@@ -32,7 +31,7 @@ def _dummy_elem(
31 key: str,
32 size: int,
33 *,
35 - rng: Optional[np.random.RandomState] = None,
34 + rng: np.random.RandomState | None = None,
35 ):
36 if rng is None:
37 data = torch.empty((size,), dtype=torch.int8)
@@ -51,7 +50,7 @@ def _dummy_item(
50 modality: str,
51 size_by_key: dict[str, int],
52 *,
54 - rng: Optional[np.random.RandomState] = None,
53 + rng: np.random.RandomState | None = None,
54 ):
55 return MultiModalKwargsItem.from_elems(
56 [_dummy_elem(modality, key, size, rng=rng) for key, size in size_by_key.items()]
@@ -61,7 +60,7 @@ def _dummy_item(
60 def _dummy_items(
61 size_by_key_modality: dict[str, dict[str, int]],
62 *,
64 - rng: Optional[np.random.RandomState] = None,
63 + rng: np.random.RandomState | None = None,
64 ):
65 return MultiModalKwargsItems.from_seq(
66 [
tests/multimodal/test_processing.py
+2 -2
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from contextlib import nullcontext
5 -from typing import Optional, cast
5 +from typing import cast
6
7 import numpy as np
8 import pytest
@@ -1003,7 +1003,7 @@ class DummyProcessor:
1003 self,
1004 a: int = 0,
1005 c: int = 0,
1006 - return_tensors: Optional[str] = None,
1006 + return_tensors: str | None = None,
1007 ) -> dict[str, int]:
1008 return dict(a=a, c=c)
1009
tests/plugins/prithvi_io_processor_plugin/prithvi_io_processor/prithvi_processor.py
+4 -6
@@ -1,15 +1,13 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import base64
5 import datetime
6 import os
7 import tempfile
8 import urllib.request
9 from collections.abc import Sequence
12 -from typing import Any, Union
10 +from typing import Any
11
12 import albumentations
13 import numpy as np
@@ -160,11 +158,11 @@ def read_geotiff(
158
159
160 def load_image(
163 - data: Union[list[str]],
161 + data: list[str],
162 path_type: str,
163 mean: list[float] | None = None,
164 std: list[float] | None = None,
167 - indices: Union[list[int], None] | None = None,
165 + indices: list[int] | None | None = None,
166 ):
167 """Build an input example by loading images in *file_paths*.
168
@@ -280,7 +278,7 @@ class PrithviMultimodalDataProcessor(IOProcessor):
278 prompt: IOProcessorInput,
279 request_id: str | None = None,
280 **kwargs,
283 - ) -> Union[PromptType, Sequence[PromptType]]:
281 + ) -> PromptType | Sequence[PromptType]:
282 image_data = dict(prompt)
283
284 if request_id:
tests/plugins/prithvi_io_processor_plugin/prithvi_io_processor/types.py
+3 -3
@@ -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 Any, Literal, Optional, TypedDict, Union
4 +from typing import Any, Literal, TypedDict
5
6 import albumentations
7 from pydantic import BaseModel
@@ -38,7 +38,7 @@ class ImagePrompt(BaseModel):
38 """
39
40
41 -MultiModalPromptType = Union[ImagePrompt]
41 +MultiModalPromptType = ImagePrompt
42
43
44 class ImageRequestOutput(BaseModel):
@@ -54,4 +54,4 @@ class ImageRequestOutput(BaseModel):
54 type: Literal["path", "b64_json"]
55 format: str
56 data: str
57 - request_id: Optional[str] = None
57 + request_id: str | None = None
tests/plugins/vllm_add_dummy_model/vllm_add_dummy_model/my_gemma_embedding.py
+3 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable
5 -from typing import Optional, Union
5
6 import torch
7 import torch.nn as nn
@@ -44,9 +43,9 @@ class MyGemma2Embedding(nn.Module):
43 self,
44 input_ids: torch.Tensor,
45 positions: torch.Tensor,
47 - intermediate_tensors: Optional[IntermediateTensors] = None,
48 - inputs_embeds: Optional[torch.Tensor] = None,
49 - ) -> Union[torch.Tensor, IntermediateTensors]:
46 + intermediate_tensors: IntermediateTensors | None = None,
47 + inputs_embeds: torch.Tensor | None = None,
48 + ) -> torch.Tensor | IntermediateTensors:
49 hidden_states = self.model(
50 input_ids,
51 positions,
tests/plugins/vllm_add_dummy_model/vllm_add_dummy_model/my_llava.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -20,7 +19,7 @@ from vllm.multimodal import MULTIMODAL_REGISTRY
19 dummy_inputs=LlavaDummyInputsBuilder,
20 )
21 class MyLlava(LlavaForConditionalGeneration):
23 - def compute_logits(self, hidden_states: torch.Tensor) -> Optional[torch.Tensor]:
22 + def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None:
23 # this dummy model always predicts the first token
24 logits = super().compute_logits(hidden_states)
25 if logits is not None:
tests/plugins/vllm_add_dummy_model/vllm_add_dummy_model/my_opt.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -9,7 +8,7 @@ from vllm.model_executor.models.opt import OPTForCausalLM
8
9
10 class MyOPTForCausalLM(OPTForCausalLM):
12 - def compute_logits(self, hidden_states: torch.Tensor) -> Optional[torch.Tensor]:
11 + def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None:
12 # this dummy model always predicts the first token
13 logits = super().compute_logits(hidden_states)
14 if logits is not None:
tests/plugins/vllm_add_dummy_platform/vllm_add_dummy_platform/__init__.py
+1 -3
@@ -1,10 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
6 -
7 -def dummy_platform_plugin() -> Optional[str]:
5 +def dummy_platform_plugin() -> str | None:
6 return "vllm_add_dummy_platform.dummy_platform.DummyPlatform"
7
8
tests/quantization/test_blackwell_moe.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import json
5 import os
6 -from typing import Optional
6
7 import pytest
8
@@ -30,7 +29,7 @@ def set_test_environment():
29 dummy_hf_overrides = {"num_layers": 4, "num_hidden_layers": 4}
30
31
33 -def can_initialize(model: str, extra_args: Optional[list[str]] = None):
32 +def can_initialize(model: str, extra_args: list[str] | None = None):
33 # Server arguments
34 extra_args = extra_args if extra_args is not None else []
35 server_args = [
tests/quantization/test_compressed_tensors.py
+1 -3
@@ -5,8 +5,6 @@
5 Run `pytest tests/quantization/test_compressed_tensors.py`.
6 """
7
8 -from typing import Optional
9 -
8 import pytest
9 import torch
10 from compressed_tensors.quantization import QuantizationType
@@ -104,7 +102,7 @@ def test_compressed_tensors_w8a8_static_setup(vllm_runner, model_args):
102 down_proj = layer.mlp.down_proj
103
104 # assert zp for symmetric and asymmetric cases
107 - def zp_valid(zp: Optional[torch.Tensor]):
105 + def zp_valid(zp: torch.Tensor | None):
106 if is_symmetric:
107 return zp is None
108
tests/quantization/test_quark.py
+2 -3
@@ -11,7 +11,6 @@ import importlib.metadata
11 import os
12 from dataclasses import dataclass
13 from importlib.util import find_spec
14 -from typing import Optional
14
15 import huggingface_hub
16 import lm_eval
@@ -156,8 +155,8 @@ class AccuracyTestConfig:
155 def get_model_args(
156 self,
157 tp_size: int,
159 - model_max_len: Optional[int] = None,
160 - kwargs: Optional[dict] = None,
158 + model_max_len: int | None = None,
159 + kwargs: dict | None = None,
160 ) -> dict:
161 if kwargs is None:
162 kwargs = {}
tests/quantization/test_register_quantization_config.py
+8 -8
@@ -7,7 +7,7 @@ See https://github.com/vllm-project/vllm/issues/11926 for more details.
7 Run `pytest tests/quantization/test_register_quantization_config.py`.
8 """
9
10 -from typing import Any, Optional
10 +from typing import Any
11
12 import pytest
13 import torch
@@ -37,10 +37,10 @@ class FakeQuantLinearMethod(UnquantizedLinearMethod):
37
38 def apply(
39 self,
40 - layer: "torch.nn.Module",
41 - x: "torch.Tensor",
42 - bias: Optional["torch.Tensor"] = None,
43 - ) -> "torch.Tensor":
40 + layer: torch.nn.Module,
41 + x: torch.Tensor,
42 + bias: torch.Tensor | None = None,
43 + ) -> torch.Tensor:
44 """Perform fake quantization before the linear layer."""
45
46 # Calculate the scales dynamically
@@ -72,7 +72,7 @@ class CustomQuantConfig(QuantizationConfig):
72 """Name of the quantization method."""
73 return "custom_quant"
74
75 - def get_supported_act_dtypes(self) -> list["torch.dtype"]:
75 + def get_supported_act_dtypes(self) -> list[torch.dtype]:
76 """List of supported activation dtypes."""
77 return [torch.float16, torch.bfloat16]
78
@@ -92,8 +92,8 @@ class CustomQuantConfig(QuantizationConfig):
92 return CustomQuantConfig(num_bits=config.get("num_bits", 8))
93
94 def get_quant_method(
95 - self, layer: "torch.nn.Module", prefix: str
96 - ) -> Optional["FakeQuantLinearMethod"]:
95 + self, layer: torch.nn.Module, prefix: str
96 + ) -> FakeQuantLinearMethod | None:
97 """Get the quantize method to use for the quantized layer."""
98 if isinstance(layer, LinearBase):
99 return FakeQuantLinearMethod(num_bits=self.num_bits)
tests/reasoning/utils.py
+8 -9
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 from vllm.entrypoints.openai.protocol import ChatCompletionRequest, DeltaMessage
6 from vllm.reasoning import ReasoningParser
@@ -34,9 +33,9 @@ class StreamingReasoningReconstructor:
33 def run_reasoning_extraction(
34 reasoning_parser: ReasoningParser,
35 model_output: list[str],
37 - request: Union[ChatCompletionRequest, None] = None,
36 + request: ChatCompletionRequest | None = None,
37 streaming: bool = False,
39 -) -> tuple[Optional[str], Optional[str]]:
38 +) -> tuple[str | None, str | None]:
39 if streaming:
40 reconstructor = run_reasoning_extraction_streaming(
41 reasoning_parser,
@@ -57,9 +56,9 @@ def run_reasoning_extraction(
56 def run_reasoning_extraction_mistral(
57 reasoning_parser: ReasoningParser,
58 model_output: list[int],
60 - request: Union[ChatCompletionRequest, None] = None,
59 + request: ChatCompletionRequest | None = None,
60 streaming: bool = False,
62 -) -> tuple[Optional[str], Optional[str]]:
61 +) -> tuple[str | None, str | None]:
62 assert isinstance(reasoning_parser.model_tokenizer, MistralTokenizer), type(
63 reasoning_parser.model_tokenizer
64 )
@@ -86,8 +85,8 @@ def run_reasoning_extraction_mistral(
85 def run_reasoning_extraction_nonstreaming(
86 reasoning_parser: ReasoningParser,
87 model_output: list[str],
89 - request: Union[ChatCompletionRequest, None] = None,
90 -) -> tuple[Optional[str], Optional[str]]:
88 + request: ChatCompletionRequest | None = None,
89 +) -> tuple[str | None, str | None]:
90 request = request or ChatCompletionRequest(messages=[], model="test-model")
91 return reasoning_parser.extract_reasoning_content(
92 model_output="".join(model_output), request=request
@@ -97,7 +96,7 @@ def run_reasoning_extraction_nonstreaming(
96 def run_reasoning_extraction_streaming(
97 reasoning_parser: ReasoningParser,
98 model_deltas: list[str],
100 - request: Union[ChatCompletionRequest, None] = None,
99 + request: ChatCompletionRequest | None = None,
100 ) -> StreamingReasoningReconstructor:
101 request = request or ChatCompletionRequest(messages=[], model="test-model")
102 reconstructor = StreamingReasoningReconstructor()
@@ -129,7 +128,7 @@ def run_reasoning_extraction_streaming(
128 def run_reasoning_extraction_streaming_mistral(
129 reasoning_parser: ReasoningParser,
130 model_deltas: list[int],
132 - request: Union[ChatCompletionRequest, None] = None,
131 + request: ChatCompletionRequest | None = None,
132 ) -> StreamingReasoningReconstructor:
133 assert isinstance(reasoning_parser.model_tokenizer, MistralTokenizer), type(
134 reasoning_parser.model_tokenizer
tests/samplers/test_no_bad_words.py
+3 -5
@@ -6,8 +6,6 @@ Run `pytest tests/samplers/test_no_bad_words.py`.
6
7 """
8
9 -from typing import Optional
10 -
9 from transformers import AutoTokenizer
10
11 from vllm import LLM, SamplingParams
@@ -18,7 +16,7 @@ def _generate(
16 prompt: str,
17 num_prompt_tokens: int,
18 temperature: float = 0,
21 - bad_words: Optional[list[str]] = None,
19 + bad_words: list[str] | None = None,
20 ) -> list[int]:
21 sampling_params = SamplingParams(
22 temperature=temperature,
@@ -60,7 +58,7 @@ class TestOneTokenBadWord:
58 output_token_ids = self._generate(llm, bad_words=[self.TARGET_TOKEN])
59 assert self.target_token_id not in output_token_ids
60
63 - def _generate(self, llm: LLM, bad_words: Optional[list[str]] = None) -> list[int]:
61 + def _generate(self, llm: LLM, bad_words: list[str] | None = None) -> list[int]:
62 return _generate(
63 llm=llm,
64 prompt=self.PROMPT,
@@ -155,7 +153,7 @@ class TestTwoTokenBadWord:
153 self.neighbour_token_id2 in output_token_ids
154 )
155
158 - def _generate(self, llm: LLM, bad_words: Optional[list[str]] = None) -> list[int]:
156 + def _generate(self, llm: LLM, bad_words: list[str] | None = None) -> list[int]:
157 return _generate(
158 llm=llm,
159 prompt=self.PROMPT,
tests/tokenization/test_detokenize.py
+2 -2
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Generator
5 -from typing import Any, Optional
5 +from typing import Any
6
7 import pytest
8 from transformers import AutoTokenizer, PreTrainedTokenizer, PreTrainedTokenizerFast
@@ -52,7 +52,7 @@ def _run_incremental_decode(
52 skip_special_tokens: bool,
53 starting_index: int,
54 spaces_between_special_tokens: bool = True,
55 - fast: Optional[bool] = None,
55 + fast: bool | None = None,
56 ):
57 prompt_token_ids = all_input_ids[:starting_index]
58
tests/tokenization/test_tokenizer_registry.py
+8 -10
@@ -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, Any, Optional, Union
4 +from typing import TYPE_CHECKING, Any
5
6 from vllm.transformers_utils.tokenizer import get_tokenizer
7 from vllm.transformers_utils.tokenizer_base import TokenizerBase, TokenizerRegistry
@@ -61,11 +61,11 @@ class TestTokenizer(TokenizerBase):
61
62 def __call__(
63 self,
64 - text: Union[str, list[str], list[int]],
65 - text_pair: Optional[str] = None,
64 + text: str | list[str] | list[int],
65 + text_pair: str | None = None,
66 add_special_tokens: bool = False,
67 truncation: bool = False,
68 - max_length: Optional[int] = None,
68 + max_length: int | None = None,
69 ):
70 raise NotImplementedError()
71
@@ -79,17 +79,17 @@ class TestTokenizer(TokenizerBase):
79 self,
80 text: str,
81 truncation: bool = False,
82 - max_length: Optional[int] = None,
82 + max_length: int | None = None,
83 ) -> list[int]:
84 raise NotImplementedError()
85
86 - def encode(self, text: str, add_special_tokens: Optional[bool] = None) -> list[int]:
86 + def encode(self, text: str, add_special_tokens: bool | None = None) -> list[int]:
87 raise NotImplementedError()
88
89 def apply_chat_template(
90 self,
91 messages: list["ChatCompletionMessageParam"],
92 - tools: Optional[list[dict[str, Any]]] = None,
92 + tools: list[dict[str, Any]] | None = None,
93 **kwargs,
94 ) -> list[int]:
95 raise NotImplementedError()
@@ -97,9 +97,7 @@ class TestTokenizer(TokenizerBase):
97 def convert_tokens_to_string(self, tokens: list[str]) -> str:
98 raise NotImplementedError()
99
100 - def decode(
101 - self, ids: Union[list[int], int], skip_special_tokens: bool = True
102 - ) -> str:
100 + def decode(self, ids: list[int] | int, skip_special_tokens: bool = True) -> str:
101 raise NotImplementedError()
102
103 def convert_ids_to_tokens(
tests/tool_use/mistral/utils.py
+3 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 from typing_extensions import TypedDict
6
@@ -9,9 +8,9 @@ from typing_extensions import TypedDict
8 class ServerConfig(TypedDict, total=False):
9 model: str
10 arguments: list[str]
12 - system_prompt: Optional[str]
13 - supports_parallel: Optional[bool]
14 - supports_rocm: Optional[bool]
11 + system_prompt: str | None
12 + supports_parallel: bool | None
13 + supports_rocm: bool | None
14
15
16 ARGS: list[str] = ["--max-model-len", "1024"]
tests/tool_use/test_jamba_tool_parser.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import json
5 from collections.abc import Generator
6 -from typing import Optional
6
7 import partial_json_parser
8 import pytest
@@ -248,7 +247,7 @@ def test_extract_tool_calls_streaming(
247 function_names: list[str] = []
248 function_args_strs: list[str] = []
249 tool_call_idx: int = -1
251 - tool_call_ids: list[Optional[str]] = []
250 + tool_call_ids: list[str | None] = []
251
252 for delta_message in stream_delta_message_generator(
253 jamba_tool_parser, jamba_tokenizer, model_output
tests/tool_use/test_parallel_tool_calls.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import json
5 -from typing import Optional
5
6 import openai
7 import pytest
@@ -80,7 +79,7 @@ async def test_parallel_tool_calls(
79 stream=True,
80 )
81
83 - role_name: Optional[str] = None
82 + role_name: str | None = None
83 finish_reason_count: int = 0
84
85 tool_call_names: list[str] = []
tests/tool_use/test_qwen3coder_tool_parser.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import json
5 from collections.abc import Generator
6 -from typing import Optional
6
7 import pytest
8
@@ -107,7 +106,7 @@ def stream_delta_message_generator(
106 qwen3_tool_parser,
107 qwen3_tokenizer: AnyTokenizer,
108 model_output: str,
110 - request: Optional[ChatCompletionRequest] = None,
109 + request: ChatCompletionRequest | None = None,
110 ) -> Generator[DeltaMessage, None, None]:
111 all_token_ids = qwen3_tokenizer.encode(model_output, add_special_tokens=False)
112
tests/tool_use/test_seed_oss_tool_parser.py
+1 -2
@@ -4,7 +4,6 @@
4
5 import json
6 from collections.abc import Generator
7 -from typing import Optional
7
8 import pytest
9
@@ -259,7 +258,7 @@ def stream_delta_message_generator(
258 seed_oss_tool_parser: SeedOssToolParser,
259 seed_oss_tokenizer: AnyTokenizer,
260 model_output: str,
262 - request: Optional[ChatCompletionRequest] = None,
261 + request: ChatCompletionRequest | None = None,
262 ) -> Generator[DeltaMessage, None, None]:
263 all_token_ids = seed_oss_tokenizer.encode(model_output, add_special_tokens=False)
264
tests/tool_use/test_tool_calls.py
+3 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import json
5 -from typing import Optional
5
6 import openai
7 import pytest
@@ -58,10 +57,10 @@ async def test_tool_call_and_choice(client: openai.AsyncOpenAI):
57
58 assert stop_reason == "tool_calls"
59
61 - function_name: Optional[str] = None
60 + function_name: str | None = None
61 function_args_str: str = ""
63 - tool_call_id: Optional[str] = None
64 - role_name: Optional[str] = None
62 + tool_call_id: str | None = None
63 + role_name: str | None = None
64 finish_reason_count: int = 0
65
66 # make the same request, streaming
tests/tool_use/test_xlam_tool_parser.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import json
5 from collections.abc import Generator
6 -from typing import Optional
6
7 import pytest
8
@@ -52,7 +51,7 @@ def stream_delta_message_generator(
51 xlam_tool_parser: xLAMToolParser,
52 xlam_tokenizer: AnyTokenizer,
53 model_output: str,
55 - request: Optional[ChatCompletionRequest] = None,
54 + request: ChatCompletionRequest | None = None,
55 ) -> Generator[DeltaMessage, None, None]:
56 all_token_ids = xlam_tokenizer.encode(model_output, add_special_tokens=False)
57
tests/tool_use/utils.py
+5 -5
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from copy import deepcopy
5 -from typing import Any, Optional
5 +from typing import Any
6
7 from openai.types.chat import ChatCompletionMessageParam, ChatCompletionToolParam
8 from typing_extensions import TypedDict
@@ -13,10 +13,10 @@ from tests.utils import VLLM_PATH
13 class ServerConfig(TypedDict, total=False):
14 model: str
15 arguments: list[str]
16 - system_prompt: Optional[str]
17 - supports_parallel: Optional[bool]
18 - supports_rocm: Optional[bool]
19 - extended: Optional[bool] # tests do not run in CI automatically
16 + system_prompt: str | None
17 + supports_parallel: bool | None
18 + supports_rocm: bool | None
19 + extended: bool | None # tests do not run in CI automatically
20
21
22 def patch_system_prompt(
tests/transformers_utils/test_config_parser_registry.py
+3 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from pathlib import Path
5 -from typing import Optional, Union
5
6 import pytest
7 from transformers import PretrainedConfig
@@ -15,10 +14,10 @@ from vllm.transformers_utils.config_parser_base import ConfigParserBase
14 class CustomConfigParser(ConfigParserBase):
15 def parse(
16 self,
18 - model: Union[str, Path],
17 + model: str | Path,
18 trust_remote_code: bool,
20 - revision: Optional[str] = None,
21 - code_revision: Optional[str] = None,
19 + revision: str | None = None,
20 + code_revision: str | None = None,
21 **kwargs,
22 ) -> tuple[dict, PretrainedConfig]:
23 raise NotImplementedError
tests/utils.py
+24 -23
@@ -15,10 +15,11 @@ import sys
15 import tempfile
16 import time
17 import warnings
18 +from collections.abc import Callable
19 from contextlib import ExitStack, contextmanager, suppress
20 from multiprocessing import Process
21 from pathlib import Path
21 -from typing import Any, Callable, Literal, Optional, Union
22 +from typing import Any, Literal
23 from unittest.mock import patch
24
25 import cloudpickle
@@ -94,7 +95,7 @@ class RemoteOpenAIServer:
95 DUMMY_API_KEY = "token-abc123" # vLLM's OpenAI server does not need API key
96
97 def _start_server(
97 - self, model: str, vllm_serve_args: list[str], env_dict: Optional[dict[str, str]]
98 + self, model: str, vllm_serve_args: list[str], env_dict: dict[str, str] | None
99 ) -> None:
100 """Subclasses override this method to customize server process launch"""
101 env = os.environ.copy()
@@ -117,11 +118,11 @@ class RemoteOpenAIServer:
118 model: str,
119 vllm_serve_args: list[str],
120 *,
120 - env_dict: Optional[dict[str, str]] = None,
121 - seed: Optional[int] = 0,
121 + env_dict: dict[str, str] | None = None,
122 + seed: int | None = 0,
123 auto_port: bool = True,
123 - max_wait_seconds: Optional[float] = None,
124 - override_hf_configs: Optional[dict[str, Any]] = None,
124 + max_wait_seconds: float | None = None,
125 + override_hf_configs: dict[str, Any] | None = None,
126 ) -> None:
127 if auto_port:
128 if "-p" in vllm_serve_args or "--port" in vllm_serve_args:
@@ -186,7 +187,7 @@ class RemoteOpenAIServer:
187 # force kill if needed
188 self.proc.kill()
189
189 - def _poll(self) -> Optional[int]:
190 + def _poll(self) -> int | None:
191 """Subclasses override this method to customize process polling"""
192 return self.proc.poll()
193
@@ -251,7 +252,7 @@ class RemoteOpenAIServerCustom(RemoteOpenAIServer):
252 """Launch test server with custom child process"""
253
254 def _start_server(
254 - self, model: str, vllm_serve_args: list[str], env_dict: Optional[dict[str, str]]
255 + self, model: str, vllm_serve_args: list[str], env_dict: dict[str, str] | None
256 ) -> None:
257 self.proc: Process = Process(
258 target=self.child_process_fxn, args=(env_dict, model, vllm_serve_args)
@@ -262,12 +263,12 @@ class RemoteOpenAIServerCustom(RemoteOpenAIServer):
263 self,
264 model: str,
265 vllm_serve_args: list[str],
265 - child_process_fxn: Callable[[Optional[dict[str, str]], str, list[str]], None],
266 + child_process_fxn: Callable[[dict[str, str] | None, str, list[str]], None],
267 *,
267 - env_dict: Optional[dict[str, str]] = None,
268 - seed: Optional[int] = 0,
268 + env_dict: dict[str, str] | None = None,
269 + seed: int | None = 0,
270 auto_port: bool = True,
270 - max_wait_seconds: Optional[float] = None,
271 + max_wait_seconds: float | None = None,
272 ) -> None:
273 """Store custom child process function then invoke superclass
274 constructor which will indirectly launch it."""
@@ -281,7 +282,7 @@ class RemoteOpenAIServerCustom(RemoteOpenAIServer):
282 max_wait_seconds=max_wait_seconds,
283 )
284
284 - def _poll(self) -> Optional[int]:
285 + def _poll(self) -> int | None:
286 return self.proc.exitcode
287
288 def __exit__(self, exc_type, exc_value, traceback):
@@ -547,11 +548,11 @@ def compare_two_settings(
548 model: str,
549 arg1: list[str],
550 arg2: list[str],
550 - env1: Optional[dict[str, str]] = None,
551 - env2: Optional[dict[str, str]] = None,
551 + env1: dict[str, str] | None = None,
552 + env2: dict[str, str] | None = None,
553 *,
554 method: str = "generate",
554 - max_wait_seconds: Optional[float] = None,
555 + max_wait_seconds: float | None = None,
556 ) -> None:
557 """
558 Launch API server with two different sets of arguments/environments
@@ -577,10 +578,10 @@ def compare_two_settings(
578 def compare_all_settings(
579 model: str,
580 all_args: list[list[str]],
580 - all_envs: list[Optional[dict[str, str]]],
581 + all_envs: list[dict[str, str] | None],
582 *,
583 method: str = "generate",
583 - max_wait_seconds: Optional[float] = None,
584 + max_wait_seconds: float | None = None,
585 ) -> None:
586 """
587 Launch API server with several different sets of arguments/environments
@@ -785,8 +786,8 @@ def get_physical_device_indices(devices):
786 def wait_for_gpu_memory_to_clear(
787 *,
788 devices: list[int],
788 - threshold_bytes: Optional[int] = None,
789 - threshold_ratio: Optional[float] = None,
789 + threshold_bytes: int | None = None,
790 + threshold_ratio: float | None = None,
791 timeout_s: float = 120,
792 ) -> None:
793 assert threshold_bytes is not None or threshold_ratio is not None
@@ -1002,7 +1003,7 @@ def spawn_new_process_for_each_test(f: Callable[_P, None]) -> Callable[_P, None]
1003
1004
1005 def create_new_process_for_each_test(
1005 - method: Optional[Literal["spawn", "fork"]] = None,
1006 + method: Literal["spawn", "fork"] | None = None,
1007 ) -> Callable[[Callable[_P, None]], Callable[_P, None]]:
1008 """Creates a decorator that runs each test function in a new process.
1009
@@ -1098,9 +1099,9 @@ async def completions_with_server_args(
1099 prompts: list[str],
1100 model_name: str,
1101 server_cli_args: list[str],
1101 - num_logprobs: Optional[int],
1102 + num_logprobs: int | None,
1103 max_wait_seconds: int = 240,
1103 - max_tokens: Union[int, list] = 5,
1104 + max_tokens: int | list = 5,
1105 ) -> list[Completion]:
1106 """Construct a remote OpenAI server, obtain an async client to the
1107 server & invoke the completions API to obtain completions.
tests/v1/attention/test_attention_backends.py
+2 -3
@@ -3,7 +3,6 @@
3 """Tests for v1 attention backends without GPUModelRunner dependency."""
4
5 from functools import partial
6 -from typing import Optional, Union
6
7 import pytest
8 import torch
@@ -202,7 +201,7 @@ def run_attention_backend(
201 key: torch.Tensor,
202 value: torch.Tensor,
203 kv_cache: torch.Tensor,
205 - sliding_window: Optional[int] = None,
204 + sliding_window: int | None = None,
205 ) -> torch.Tensor:
206 """Run attention computation using the specified backend's AttentionImpl."""
207
@@ -289,7 +288,7 @@ def run_attention_backend(
288 def _test_backend_correctness(
289 batch_spec: BatchSpec,
290 model: str,
292 - backend_to_test: list[Union[_Backend, str]],
291 + backend_to_test: list[_Backend | str],
292 mask_mod,
293 *,
294 block_size: int = 16,
tests/v1/attention/test_mla_backends.py
+2 -4
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Tests for v1 MLA backends without GPUModelRunner dependency."""
4
5 -from typing import Optional, Union
6 -
5 import pytest
6 import torch
7
@@ -81,8 +79,8 @@ def create_and_prepopulate_kv_cache(
79 num_blocks: int,
80 common_attn_metadata: CommonAttentionMetadata,
81 randomize_blocks: bool = True,
84 - kv_cache_dtype: Optional[str] = None,
85 - scale: Union[float, torch.Tensor] = 1.0,
82 + kv_cache_dtype: str | None = None,
83 + scale: float | torch.Tensor = 1.0,
84 ) -> torch.Tensor:
85 """Create and prepopulate an MLA KV cache with context data.
86
tests/v1/attention/utils.py
+3 -4
@@ -3,7 +3,6 @@
3 """Utility functions for attention-related v1 tests."""
4
5 from dataclasses import dataclass
6 -from typing import Optional, Union
6
7 import pytest
8 import torch
@@ -150,14 +149,14 @@ def create_vllm_config(
149 model_name: str = "meta-llama/Meta-Llama-3-8B",
150 tensor_parallel_size: int = 1,
151 max_model_len: int = 1024,
153 - dtype: Union[ModelDType, torch.dtype] = "auto",
152 + dtype: ModelDType | torch.dtype = "auto",
153 num_gpu_blocks: int = 1000,
154 block_size: int = 16,
155 max_num_seqs: int = 256,
156 max_num_batched_tokens: int = 8192,
157 enable_chunked_prefill: bool = True,
158 add_mock_model_methods: bool = True,
160 - hf_config_override: Optional[dict] = None,
159 + hf_config_override: dict | None = None,
160 ) -> VllmConfig:
161 """Create a VllmConfig for testing with reasonable defaults."""
162
@@ -252,7 +251,7 @@ class BackendConfig:
251 name: str
252 env_vars: dict
253 comp_config: dict # compilation config
255 - specific_gpu_arch: Optional[tuple] = None
254 + specific_gpu_arch: tuple | None = None
255
256
257 # Define all backend configurations of full cudagraph to be tested
tests/v1/core/test_kv_cache_utils.py
+4 -4
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import importlib
4 -from typing import Callable, Optional
4 +from collections.abc import Callable
5
6 import pytest
7 import torch
@@ -62,9 +62,9 @@ def make_request(
62 prompt_token_ids: list[int],
63 block_size: int = 3,
64 hash_fn: Callable = hash,
65 - mm_positions: Optional[list[PlaceholderRange]] = None,
66 - mm_hashes: Optional[list[str]] = None,
67 - cache_salt: Optional[str] = None,
65 + mm_positions: list[PlaceholderRange] | None = None,
66 + mm_hashes: list[str] | None = None,
67 + cache_salt: str | None = None,
68 ):
69 mm_features = []
70 if mm_positions is not None:
tests/v1/core/test_prefix_caching.py
+5 -5
@@ -3,7 +3,7 @@
3 """Compare the with and without prefix caching."""
4
5 import copy
6 -from typing import Callable, Optional
6 +from collections.abc import Callable
7
8 import pytest
9 import torch
@@ -55,10 +55,10 @@ def make_request(
55 prompt_token_ids: list[int],
56 block_size: int,
57 hash_fn: Callable,
58 - mm_positions: Optional[list[PlaceholderRange]] = None,
59 - mm_hashes: Optional[list[str]] = None,
60 - prompt_logprobs: Optional[int] = None,
61 - cache_salt: Optional[str] = None,
58 + mm_positions: list[PlaceholderRange] | None = None,
59 + mm_hashes: list[str] | None = None,
60 + prompt_logprobs: int | None = None,
61 + cache_salt: str | None = None,
62 ):
63 mm_features = []
64 if mm_positions is not None:
tests/v1/core/test_scheduler.py
+10 -13
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import dataclasses
4 -from typing import Optional
4 from unittest.mock import Mock
5
6 import pytest
@@ -78,9 +77,7 @@ def test_get_num_unfinished_requests():
77 (True, 5),
78 ],
79 )
81 -def test_schedule(
82 - enable_prefix_caching: Optional[bool], prompt_logprobs: Optional[int]
83 -):
80 +def test_schedule(enable_prefix_caching: bool | None, prompt_logprobs: int | None):
81 """Test scheduling.
82 Two cases: default APC/no prompt logprobs; APC=True + prompt logprobs
83 """
@@ -595,7 +592,7 @@ def test_check_stop_min_tokens():
592 ],
593 )
594 def test_schedule_concurrent_batches(
598 - enable_prefix_caching: Optional[bool], prompt_logprobs: Optional[int]
595 + enable_prefix_caching: bool | None, prompt_logprobs: int | None
596 ):
597 scheduler = create_scheduler(
598 max_num_batched_tokens=1024,
@@ -1323,14 +1320,14 @@ def create_scheduler_with_priority(
1320 model: str = "facebook/opt-125m",
1321 max_num_seqs: int = 16,
1322 max_num_batched_tokens: int = 8192,
1326 - enable_prefix_caching: Optional[bool] = None,
1323 + enable_prefix_caching: bool | None = None,
1324 long_prefill_token_threshold: int = 0,
1325 disable_chunked_mm_input: bool = False,
1326 use_kv_connector: bool = False,
1327 num_blocks: int = 10000,
1328 block_size: int = 16,
1332 - max_model_len: Optional[int] = None,
1333 - num_speculative_tokens: Optional[int] = None,
1329 + max_model_len: int | None = None,
1330 + num_speculative_tokens: int | None = None,
1331 ) -> Scheduler:
1332 """Create scheduler with priority policy enabled.
1333
@@ -1385,7 +1382,7 @@ def create_scheduler_with_priority(
1382 else None
1383 )
1384
1388 - speculative_config: Optional[SpeculativeConfig] = None
1385 + speculative_config: SpeculativeConfig | None = None
1386 if num_speculative_tokens is not None:
1387 speculative_config = SpeculativeConfig(
1388 model="ngram", num_speculative_tokens=num_speculative_tokens
@@ -1420,12 +1417,12 @@ def create_scheduler_with_priority(
1417 def create_requests_with_priority(
1418 num_requests: int,
1419 priorities: list[int],
1423 - arrival_times: Optional[list[float]] = None,
1420 + arrival_times: list[float] | None = None,
1421 num_tokens: int = 10,
1425 - mm_positions: Optional[list[list[PlaceholderRange]]] = None,
1422 + mm_positions: list[list[PlaceholderRange]] | None = None,
1423 max_tokens: int = 16,
1427 - stop_token_ids: Optional[list[int]] = None,
1428 - prompt_logprobs: Optional[int] = None,
1424 + stop_token_ids: list[int] | None = None,
1425 + prompt_logprobs: int | None = None,
1426 starting_idx: int = 0,
1427 ):
1428 """Create requests with specified priorities and arrival times."""
tests/v1/core/utils.py
+8 -9
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional, Union
3
4 import torch
5
@@ -37,17 +36,17 @@ def create_scheduler(
36 model: str = "facebook/opt-125m",
37 max_num_seqs: int = 16,
38 max_num_batched_tokens: int = 8192,
40 - enable_prefix_caching: Optional[bool] = None,
39 + enable_prefix_caching: bool | None = None,
40 long_prefill_token_threshold: int = 0,
41 disable_chunked_mm_input: bool = False,
42 use_kv_connector: bool = False,
43 num_blocks: int = 10000,
44 block_size: int = 16,
46 - max_model_len: Optional[int] = None,
47 - num_speculative_tokens: Optional[int] = None,
45 + max_model_len: int | None = None,
46 + num_speculative_tokens: int | None = None,
47 skip_tokenizer_init: bool = False,
48 async_scheduling: bool = False,
50 -) -> Union[Scheduler, AsyncScheduler]:
49 +) -> Scheduler | AsyncScheduler:
50 """Create scheduler under test.
51
52 Args:
@@ -102,7 +101,7 @@ def create_scheduler(
101 else None
102 )
103
105 - speculative_config: Optional[SpeculativeConfig] = None
104 + speculative_config: SpeculativeConfig | None = None
105 if num_speculative_tokens is not None:
106 speculative_config = SpeculativeConfig(
107 model="ngram", num_speculative_tokens=num_speculative_tokens
@@ -141,10 +140,10 @@ _none_hash_initialized = False
140 def create_requests(
141 num_requests: int,
142 num_tokens: int = 10,
144 - mm_positions: Optional[list[list[PlaceholderRange]]] = None,
143 + mm_positions: list[list[PlaceholderRange]] | None = None,
144 max_tokens: int = 16,
146 - stop_token_ids: Optional[list[int]] = None,
147 - prompt_logprobs: Optional[int] = None,
145 + stop_token_ids: list[int] | None = None,
146 + prompt_logprobs: int | None = None,
147 same_prompt: bool = False,
148 block_size: int = 16,
149 ) -> list[Request]:
tests/v1/distributed/test_async_llm_dp.py
+5 -6
@@ -5,7 +5,6 @@ import asyncio
5 import os
6 from contextlib import ExitStack
7 from dataclasses import dataclass
8 -from typing import Optional
8
9 import pytest
10
@@ -35,8 +34,8 @@ async def generate(
34 prompt: PromptType,
35 output_kind: RequestOutputKind,
36 max_tokens: int,
38 - prompt_logprobs: Optional[int] = None,
39 - data_parallel_rank: Optional[int] = None,
37 + prompt_logprobs: int | None = None,
38 + data_parallel_rank: int | None = None,
39 ) -> tuple[int, str]:
40 # Ensure generate doesn't complete too fast for cancellation test.
41 await asyncio.sleep(0.2)
@@ -91,9 +90,9 @@ async def test_load(
90
91 def record(
92 self,
94 - scheduler_stats: Optional[SchedulerStats],
95 - iteration_stats: Optional[IterationStats],
96 - mm_cache_stats: Optional[MultiModalCacheStats] = None,
93 + scheduler_stats: SchedulerStats | None,
94 + iteration_stats: IterationStats | None,
95 + mm_cache_stats: MultiModalCacheStats | None = None,
96 engine_idx: int = 0,
97 ):
98 if iteration_stats:
tests/v1/distributed/test_internal_lb_dp.py
+3 -3
@@ -5,7 +5,7 @@ import os
5 import threading
6 import time
7 import traceback
8 -from typing import Optional, cast
8 +from typing import cast
9
10 import openai # use the official client for correctness check
11 import pytest
@@ -46,7 +46,7 @@ class MultinodeInternalLBServerManager:
46 self.tp_size = tp_size
47 self.api_server_count = api_server_count
48 self.base_server_args = base_server_args
49 - self.servers: list[Optional[tuple[RemoteOpenAIServer, list[str]]]] = [None] * (
49 + self.servers: list[tuple[RemoteOpenAIServer, list[str]] | None] = [None] * (
50 dp_size // dp_per_node
51 )
52 self.server_threads: list[threading.Thread] = []
@@ -175,7 +175,7 @@ class APIOnlyServerManager:
175 self.tp_size = tp_size
176 self.api_server_count = api_server_count
177 self.base_server_args = base_server_args
178 - self.servers: list[Optional[tuple[RemoteOpenAIServer, list[str]]]] = [None] * 2
178 + self.servers: list[tuple[RemoteOpenAIServer, list[str]] | None] = [None] * 2
179 self.server_threads: list[threading.Thread] = []
180
181 def __enter__(self) -> list[tuple[RemoteOpenAIServer, list[str]]]:
tests/v1/e2e/test_min_tokens.py
+3 -5
@@ -13,8 +13,6 @@ Covers:
13 5) Multiple stop conditions
14 """
15
16 -from typing import Optional, Union
17 -
16 import pytest
17
18 from vllm import LLM, SamplingParams
@@ -33,9 +31,9 @@ class MinTokensTestCase:
31 name: str,
32 min_tokens: int,
33 max_tokens: int,
36 - stop: Optional[Union[str, list[str]]] = None,
37 - expected_min_len: Optional[int] = None,
38 - expected_exact_len: Optional[int] = None,
34 + stop: str | list[str] | None = None,
35 + expected_min_len: int | None = None,
36 + expected_exact_len: int | None = None,
37 ):
38 self.name = name
39 self.min_tokens = min_tokens
tests/v1/e2e/test_spec_decode.py
+2 -4
@@ -1,9 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import random
6 -from typing import Any, Union
4 +from typing import Any
5
6 import pytest
7 import torch
@@ -34,7 +32,7 @@ def get_test_prompts(mm_enabled: bool):
32 for kind in random_prompt_type_choices:
33 word_choices = ["test", "temp", "hello", "where"]
34 word = random.choice(word_choices)
37 - prompt: Union[str, list[dict[str, Any]]] = ""
35 + prompt: str | list[dict[str, Any]] = ""
36 if kind == "repeat":
37 prompt = f"""
38 please repeat the word '{word}' 10 times.
tests/v1/engine/test_async_llm.py
+4 -5
@@ -3,7 +3,6 @@
3
4 import asyncio
5 from contextlib import ExitStack
6 -from typing import Optional
6 from unittest.mock import MagicMock
7
8 import pytest
@@ -53,8 +52,8 @@ async def generate(
52 output_kind: RequestOutputKind,
53 max_tokens: int,
54 n: int = 1,
56 - prompt_logprobs: Optional[int] = None,
57 - cancel_after: Optional[int] = None,
55 + prompt_logprobs: int | None = None,
56 + cancel_after: int | None = None,
57 ) -> tuple[int, str]:
58 # Ensure generate doesn't complete too fast for cancellation test.
59 await asyncio.sleep(0.2)
@@ -545,9 +544,9 @@ async def collect_outputs(
544 prompt: PromptType,
545 sampling_params: SamplingParams,
546 outputs_list: list[RequestOutput],
548 -) -> Optional[RequestOutput]:
547 +) -> RequestOutput | None:
548 """Helper to collect outputs and return the final one."""
550 - final_output: Optional[RequestOutput] = None
549 + final_output: RequestOutput | None = None
550 async for output in engine.generate(
551 request_id=request_id, prompt=prompt, sampling_params=sampling_params
552 ):
tests/v1/engine/test_engine_core_client.py
+5 -7
@@ -8,7 +8,7 @@ import time
8 import uuid
9 from dataclasses import dataclass
10 from threading import Thread
11 -from typing import Any, Optional, Union
11 +from typing import Any
12 from unittest.mock import MagicMock
13
14 import pytest
@@ -41,7 +41,7 @@ PROMPT_TOKENS = TOKENIZER(PROMPT).input_ids
41
42
43 def make_request(
44 - params: SamplingParams, prompt_tokens_ids: Optional[list[int]] = None
44 + params: SamplingParams, prompt_tokens_ids: list[int] | None = None
45 ) -> EngineCoreRequest:
46 if not prompt_tokens_ids:
47 prompt_tokens_ids = PROMPT_TOKENS
@@ -113,9 +113,7 @@ async def loop_until_fully_done_async(client: EngineCoreClient, outputs: dict):
113
114
115 # Dummy utility function to monkey-patch into engine core.
116 -def echo(
117 - self, msg: str, err_msg: Optional[str] = None, sleep: Optional[float] = None
118 -) -> str:
116 +def echo(self, msg: str, err_msg: str | None = None, sleep: float | None = None) -> str:
117 print(f"echo util function called: {msg}, {err_msg}")
118 if sleep is not None:
119 time.sleep(sleep)
@@ -317,7 +315,7 @@ def echo_dc(
315 self,
316 msg: str,
317 return_list: bool = False,
320 -) -> Union[MyDataclass, list[MyDataclass]]:
318 +) -> MyDataclass | list[MyDataclass]:
319 print(f"echo dc util function called: {msg}")
320 val = None if msg is None else MyDataclass(msg)
321 # Return dataclass to verify support for returning custom types
@@ -330,7 +328,7 @@ def echo_dc_dict(
328 self,
329 msg: str,
330 return_dict: bool = False,
333 -) -> Union[MyDataclass, dict[str, MyDataclass]]:
331 +) -> MyDataclass | dict[str, MyDataclass]:
332 print(f"echo dc dict util function called: {msg}")
333 val = None if msg is None else MyDataclass(msg)
334 # Return dict of dataclasses to verify support for returning dicts
tests/v1/engine/test_llm_engine.py
+2 -2
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import random
4 from typing import TYPE_CHECKING
5
@@ -13,6 +11,8 @@ from vllm.v1.metrics.reader import Counter, Gauge, Histogram, Metric, Vector
11
12 if TYPE_CHECKING:
13 from tests.conftest import VllmRunner
14 +else:
15 + VllmRunner = object
16
17 MODEL = "facebook/opt-125m"
18 DTYPE = "half"
tests/v1/engine/test_output_processor.py
+8 -9
@@ -3,7 +3,6 @@
3
4 import math
5 import time
6 -from typing import Optional
6
7 import pytest
8
@@ -118,13 +117,13 @@ def test_incremental_detokenization(
117
118 def _validate_logprobs(
119 gen_tokens: dict[str, list[int]],
121 - gen_logprobs: dict[str, Optional[SampleLogprobs]],
122 - gen_prompt_logprobs: dict[str, Optional[PromptLogprobs]],
120 + gen_logprobs: dict[str, SampleLogprobs | None],
121 + gen_prompt_logprobs: dict[str, PromptLogprobs | None],
122 gen_cumulative_logprob: dict[str, float],
123 dtv: DummyOutputProcessorTestVectors,
124 request_id_list: list[str],
126 - num_sample_logprobs: Optional[int],
127 - num_prompt_logprobs: Optional[int],
125 + num_sample_logprobs: int | None,
126 + num_prompt_logprobs: int | None,
127 ) -> None:
128 for req_idx, req_id in enumerate(request_id_list):
129 new_tokens = gen_tokens[req_id]
@@ -413,8 +412,8 @@ def _validate_logprobs(
412 @pytest.mark.parametrize("num_prompt_logprobs", [None, NUM_PROMPT_LOGPROBS_UNDER_TEST])
413 def test_logprobs_processor(
414 request_output_kind: RequestOutputKind,
416 - num_sample_logprobs: Optional[int],
417 - num_prompt_logprobs: Optional[int],
415 + num_sample_logprobs: int | None,
416 + num_prompt_logprobs: int | None,
417 dummy_test_vectors,
418 ):
419 output_processor = OutputProcessor(dummy_test_vectors.tokenizer, log_stats=False)
@@ -530,7 +529,7 @@ def test_logprobs_processor(
529 )
530 def test_stop_token(
531 include_stop_str_in_output: bool,
533 - num_sample_logprobs: Optional[int],
532 + num_sample_logprobs: int | None,
533 stop_token_type: str,
534 ignore_eos: bool,
535 dummy_test_vectors,
@@ -696,7 +695,7 @@ def test_stop_token(
695 @pytest.mark.parametrize("num_sample_logprobs", [None, NUM_SAMPLE_LOGPROBS_UNDER_TEST])
696 def test_stop_string(
697 include_stop_str_in_output: bool,
699 - num_sample_logprobs: Optional[int],
698 + num_sample_logprobs: int | None,
699 dummy_test_vectors,
700 ):
701 output_processor = OutputProcessor(dummy_test_vectors.tokenizer, log_stats=False)
tests/v1/engine/utils.py
+7 -8
@@ -3,7 +3,7 @@
3
4 import random
5 from dataclasses import dataclass
6 -from typing import Optional, Union
6 +from typing import TypeAlias
7
8 import torch
9 from transformers import PreTrainedTokenizer, PreTrainedTokenizerFast
@@ -12,7 +12,7 @@ from vllm.engine.arg_utils import EngineArgs
12 from vllm.v1.engine import EngineCoreOutput, FinishReason
13 from vllm.v1.outputs import LogprobsLists, LogprobsTensors
14
15 -GeneralTokenizerType = Union[PreTrainedTokenizer, PreTrainedTokenizerFast]
15 +GeneralTokenizerType: TypeAlias = PreTrainedTokenizer | PreTrainedTokenizerFast
16
17 # Number of sample logprobs to request when testing sample logprobs
18 NUM_SAMPLE_LOGPROBS_UNDER_TEST = 5
@@ -332,16 +332,15 @@ class MockEngineCore:
332 # For each request, for each sampled token offset,
333 # a tuple of
334 # (list of topk token ids, list of sample logprob vals, rank)
335 - generated_logprobs_raw: Optional[
336 - list[list[tuple[list[int], list[float], int]]]
337 - ] = None,
335 + generated_logprobs_raw: list[list[tuple[list[int], list[float], int]]]
336 + | None = None,
337 # For each request, a tuple of
338 # (prompt logprob val matrix, prompt logprob tok id matrix);
339 # each matrix has dimensions
340 # (num prompt toks) x (num prompt logprobs+1)
342 - prompt_logprobs_raw: Optional[list[LogprobsTensors]] = None,
343 - eos_token_id: Optional[int] = None,
344 - stop_token_ids: Optional[list[int]] = None,
341 + prompt_logprobs_raw: list[LogprobsTensors] | None = None,
342 + eos_token_id: int | None = None,
343 + stop_token_ids: list[int] | None = None,
344 ignore_eos: bool = False,
345 ) -> None:
346 self.num_requests = len(tokens_list)
tests/v1/entrypoints/llm/test_struct_output_generate.py
+2 -2
@@ -2,8 +2,6 @@
2 # SPDX-License-Identifier: Apache-2.0
3 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4
5 -from __future__ import annotations
6 -
5 import json
6 from dataclasses import fields
7 from enum import Enum
@@ -30,6 +28,8 @@ from vllm.sampling_params import (
28
29 if TYPE_CHECKING:
30 from vllm.config.model import TokenizerMode
31 +else:
32 + TokenizerMode = str
33
34 NGRAM_SPEC_CONFIG = {
35 "model": "[ngram]",
tests/v1/entrypoints/openai/test_completion.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import openai # use the official client for correctness check
6 import pytest
@@ -195,7 +194,7 @@ async def test_too_many_completion_logprobs(
194 [(MODEL_NAME, -1), (MODEL_NAME, 0), (MODEL_NAME, 1), (MODEL_NAME, None)],
195 )
196 async def test_prompt_logprobs_completion(
198 - client: openai.AsyncOpenAI, model_name: str, prompt_logprobs: Optional[int]
197 + client: openai.AsyncOpenAI, model_name: str, prompt_logprobs: int | None
198 ):
199 params: dict = {
200 "prompt": ["A robot may not injure another robot", "My name is"],
tests/v1/executor/test_executor.py
+6 -5
@@ -3,7 +3,8 @@
3
4 import asyncio
5 import os
6 -from typing import Any, Callable, Optional, Union
6 +from collections.abc import Callable
7 +from typing import Any
8
9 import pytest
10
@@ -20,12 +21,12 @@ class Mock: ...
21 class CustomMultiprocExecutor(MultiprocExecutor):
22 def collective_rpc(
23 self,
23 - method: Union[str, Callable],
24 - timeout: Optional[float] = None,
24 + method: str | Callable,
25 + timeout: float | None = None,
26 args: tuple = (),
26 - kwargs: Optional[dict] = None,
27 + kwargs: dict | None = None,
28 non_block: bool = False,
28 - unique_reply_rank: Optional[int] = None,
29 + unique_reply_rank: int | None = None,
30 ) -> list[Any]:
31 # Drop marker to show that this was run
32 with open(".marker", "w"):
tests/v1/kv_connector/unit/test_kv_load_failure_recovery.py
+1 -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 Callable
4 +from collections.abc import Callable
5 from unittest.mock import Mock
6
7 import pytest
tests/v1/kv_connector/unit/test_nixl_connector.py
+2 -3
@@ -9,7 +9,6 @@ import textwrap
9 import time
10 import uuid
11 from collections import defaultdict
12 -from typing import Optional
12 from unittest.mock import patch
13
14 import pytest
@@ -154,7 +153,7 @@ class FakeNixlWrapper:
153 local_block_descs_ids: list[int],
154 remote_xfer_side_handle: int,
155 remote_block_descs_ids: list[int],
157 - notif_msg: Optional[bytes] = None,
156 + notif_msg: bytes | None = None,
157 ) -> int:
158 return uuid.uuid4().int
159
@@ -982,7 +981,7 @@ class FakePlatform(Platform):
981 return {"oot": ("oot",)}
982
983 @classmethod
985 - def get_nixl_memory_type(cls) -> Optional[str]:
984 + def get_nixl_memory_type(cls) -> str | None:
985 """
986 Returns the nixl memory type for the current platform.
987 """
tests/v1/kv_connector/unit/test_output_aggreagator.py
+3 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from concurrent.futures import Future
4 -from typing import Optional
4
5 import pytest
6
@@ -14,9 +13,9 @@ pytestmark = pytest.mark.cpu_test
13 class DummyModelRunnerOutput(ModelRunnerOutput):
14 def __init__(
15 self,
17 - finished_sending: Optional[set[str]] = None,
18 - finished_recving: Optional[set[str]] = None,
19 - invalid_block_ids: Optional[set[int]] = None,
16 + finished_sending: set[str] | None = None,
17 + finished_recving: set[str] | None = None,
18 + invalid_block_ids: set[int] | None = None,
19 ):
20 self.kv_connector_output = KVConnectorOutput(
21 finished_sending=finished_sending,
tests/v1/kv_connector/unit/utils.py
+7 -6
@@ -2,8 +2,9 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import tempfile
4 from collections import defaultdict
5 +from collections.abc import Callable
6 from itertools import count
6 -from typing import Any, Callable, Optional
7 +from typing import Any
8
9 import torch
10
@@ -147,7 +148,7 @@ _none_hash_initialized = False
148
149
150 def create_request(
150 - request_id: Optional[int] = None,
151 + request_id: int | None = None,
152 num_tokens: int = 10,
153 common_prefix_len=0,
154 max_tokens: int = 16,
@@ -168,7 +169,7 @@ def create_request(
169 init_none_hash(hash_fn)
170 _none_hash_initialized = True
171
171 - kv_transfer_params: Optional[dict[str, Any]] = None
172 + kv_transfer_params: dict[str, Any] | None = None
173
174 if do_remote_decode:
175 assert not do_remote_prefill
@@ -205,9 +206,9 @@ def create_request(
206
207 def create_model_runner_output(
208 reqs: list[Request],
208 - finished_sending: Optional[set[str]] = None,
209 - finished_recving: Optional[set[str]] = None,
210 - invalid_block_ids: Optional[set[int]] = None,
209 + finished_sending: set[str] | None = None,
210 + finished_recving: set[str] | None = None,
211 + invalid_block_ids: set[int] | None = None,
212 use_eos: bool = False,
213 token_id: int = 0,
214 ) -> ModelRunnerOutput:
tests/v1/kv_offload/test_cpu_manager.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 import numpy as np
7
@@ -29,7 +28,7 @@ def to_hashes(int_hashes: list[int]) -> list[BlockHash]:
28
29
30 def verify_store_output(
32 - prepare_store_output: Optional[PrepareStoreOutput],
31 + prepare_store_output: PrepareStoreOutput | None,
32 expected_prepare_store_output: ExpectedPrepareStoreOutput,
33 ):
34 assert prepare_store_output is not None
tests/v1/logits_processors/test_correctness.py
+4 -4
@@ -3,7 +3,7 @@
3
4 import random
5 from collections.abc import Callable
6 -from typing import NamedTuple, Optional, Union
6 +from typing import NamedTuple, TypeAlias
7
8 import numpy as np
9 import pytest
@@ -48,7 +48,7 @@ REQS_PER_LOGITPROC = 50
48 STR_NO_LOGITPROC = "none"
49
50 # LogitsProcessor subclass or "none"
51 -LogitprocType = Union[type[LogitsProcessor], str]
51 +LogitprocType: TypeAlias = type[LogitsProcessor] | str
52
53
54 class LogitsProcsRequestParams:
@@ -435,7 +435,7 @@ class LogitsprocTestHelpers(NamedTuple):
435 """Supports setting up and validating logitsprocs unit tests."""
436
437 eval_fxn: Callable
438 - gen_request_fxn: Optional[Callable] = None
438 + gen_request_fxn: Callable | None = None
439
440
441 logitsprocs_test_mapping = {
@@ -471,7 +471,7 @@ def _generate_fake_step_update(
471 workload_params: list[LogitsProcsRequestParams],
472 wdx: int,
473 batch_update_builder: BatchUpdateBuilder,
474 -) -> tuple[Optional[BatchUpdate], int, int]:
474 +) -> tuple[BatchUpdate | None, int, int]:
475 batch_size = len(persistent_batch)
476 workload_size = len(workload_params)
477 workload_reqs_remaining = workload_size - wdx
tests/v1/logits_processors/test_custom_offline.py
+2 -2
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import random
4 import sys
5 -from typing import Any, Union
5 +from typing import Any
6
7 import pytest
8
@@ -159,7 +159,7 @@ def test_custom_logitsprocs(monkeypatch, logitproc_source: CustomLogitprocSource
159 _run_test({}, logitproc_loaded=True)
160 return
161
162 - kwargs: dict[str, list[Union[str, type[LogitsProcessor]]]] = {}
162 + kwargs: dict[str, list[str | type[LogitsProcessor]]] = {}
163 if logitproc_source == CustomLogitprocSource.LOGITPROC_SOURCE_FQCN:
164 # Scenario: load logitproc based on fully-qualified class name (FQCN)
165 # Inject dummy module which defines logitproc
tests/v1/logits_processors/test_custom_online.py
+3 -3
@@ -4,7 +4,7 @@
4 import os
5 import random
6 import sys
7 -from typing import Any, Optional
7 +from typing import Any
8
9 import openai
10 import pytest
@@ -25,7 +25,7 @@ from tests.v1.logits_processors.utils import entry_points as fake_entry_points
25
26
27 def _server_with_logitproc_entrypoint(
28 - env_dict: Optional[dict[str, str]],
28 + env_dict: dict[str, str] | None,
29 model: str,
30 vllm_serve_args: list[str],
31 ) -> None:
@@ -48,7 +48,7 @@ def _server_with_logitproc_entrypoint(
48
49
50 def _server_with_logitproc_module(
51 - env_dict: Optional[dict[str, str]],
51 + env_dict: dict[str, str] | None,
52 model: str,
53 vllm_serve_args: list[str],
54 ) -> None:
tests/v1/logits_processors/utils.py
+4 -4
@@ -3,7 +3,7 @@
3
4 import types
5 from enum import Enum, auto
6 -from typing import Any, Optional
6 +from typing import Any
7
8 import torch
9
@@ -61,7 +61,7 @@ class DummyLogitsProcessor(LogitsProcessor):
61 """Never impacts greedy sampling"""
62 return False
63
64 - def update_state(self, batch_update: Optional[BatchUpdate]):
64 + def update_state(self, batch_update: BatchUpdate | None):
65 process_dict_updates(
66 self.req_info,
67 batch_update,
@@ -145,7 +145,7 @@ class WrappedPerReqLogitsProcessor(AdapterLogitsProcessor):
145 def new_req_logits_processor(
146 self,
147 params: SamplingParams,
148 - ) -> Optional[RequestLogitsProcessor]:
148 + ) -> RequestLogitsProcessor | None:
149 """This method returns a new request-level logits processor, customized
150 to the `target_token` value associated with a particular request.
151
@@ -159,7 +159,7 @@ class WrappedPerReqLogitsProcessor(AdapterLogitsProcessor):
159 Returns:
160 `Callable` request logits processor, or None
161 """
162 - target_token: Optional[Any] = params.extra_args and params.extra_args.get(
162 + target_token: Any | None = params.extra_args and params.extra_args.get(
163 "target_token"
164 )
165 if target_token is None:
tests/v1/sample/test_rejection_sampler.py
+14 -14
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, Optional
3 +from typing import Any
4
5 import pytest
6 import torch
@@ -24,7 +24,7 @@ def rejection_sampler():
24 def create_logits_tensor(
25 output_token_ids: list[list[int]],
26 vocab_size: int = 100,
27 - token_idx_to_override: Optional[int] = None,
27 + token_idx_to_override: int | None = None,
28 ) -> torch.Tensor:
29 """Helper function to create logits tensor that
30 will produce desired token ids on argmax"""
@@ -43,18 +43,18 @@ def create_logits_tensor(
43
44 def create_sampling_metadata(
45 all_greedy: bool,
46 - output_token_ids: Optional[list[list[int]]] = None,
47 - prompt_token_ids: Optional[torch.Tensor] = None,
48 - spec_token_ids: Optional[torch.Tensor] = None,
49 - temperature: Optional[torch.Tensor] = None,
50 - top_k: Optional[torch.Tensor] = None,
51 - top_p: Optional[torch.Tensor] = None,
52 - generators: Optional[dict[int, Any]] = None,
53 - frequency_penalties: Optional[list[float]] = None,
54 - presence_penalties: Optional[list[float]] = None,
55 - repetition_penalties: Optional[list[float]] = None,
56 - bad_words_token_ids: Optional[dict[int, list[list[int]]]] = None,
57 - allowed_token_ids_mask: Optional[torch.Tensor] = None,
46 + output_token_ids: list[list[int]] | None = None,
47 + prompt_token_ids: torch.Tensor | None = None,
48 + spec_token_ids: torch.Tensor | None = None,
49 + temperature: torch.Tensor | None = None,
50 + top_k: torch.Tensor | None = None,
51 + top_p: torch.Tensor | None = None,
52 + generators: dict[int, Any] | None = None,
53 + frequency_penalties: list[float] | None = None,
54 + presence_penalties: list[float] | None = None,
55 + repetition_penalties: list[float] | None = None,
56 + bad_words_token_ids: dict[int, list[list[int]]] | None = None,
57 + allowed_token_ids_mask: torch.Tensor | None = None,
58 ) -> SamplingMetadata:
59 """Create a v1 sampling metadata object with all_greedy set
60 to the given value. Either all greedy or all random sampling
tests/v1/sample/utils.py
+4 -4
@@ -3,7 +3,7 @@
3
4 from collections.abc import Iterator
5 from enum import Enum
6 -from typing import NamedTuple, Optional
6 +from typing import NamedTuple
7
8 import regex as re
9 import torch
@@ -23,7 +23,7 @@ class BatchLogprobsComposition(Enum):
23 SAMPLE_PROMPT = 3
24
25
26 -BatchLogprobsSpecType = list[tuple[Optional[int], Optional[int]]]
26 +BatchLogprobsSpecType = list[tuple[int | None, int | None]]
27
28
29 def get_test_batch(
@@ -222,8 +222,8 @@ def create_allowed_token_ids(
222 vocab_size: int,
223 num_allowed_token_ids: int,
224 device: torch.device,
225 -) -> Optional[torch.Tensor]:
226 - mask: Optional[torch.Tensor] = None
225 +) -> torch.Tensor | None:
226 + mask: torch.Tensor | None = None
227 for i in range(batch_size):
228 if i % 2 == 1:
229 continue
tests/v1/spec_decode/test_eagle.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4 from unittest import mock
5
6 import pytest
@@ -39,7 +38,7 @@ eagle3_dir = "yuhuili/EAGLE3-LLaMA3.1-Instruct-8B"
38 def _create_proposer(
39 method: str,
40 num_speculative_tokens: int,
42 - speculative_token_tree: Optional[list[tuple[int, ...]]] = None,
41 + speculative_token_tree: list[tuple[int, ...]] | None = None,
42 ) -> EagleProposer:
43 model_config = ModelConfig(model=model_dir, runner="generate", max_model_len=100)
44
tests/v1/spec_decode/test_tree_attention.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import math
5 -from typing import Optional
5
6 import torch
7
@@ -37,7 +36,7 @@ def forward_attention(
36 slot_mapping: torch.Tensor,
37 seqlen_k: int,
38 backend: _Backend,
40 - spec_token_tree: Optional[str] = None,
39 + spec_token_tree: str | None = None,
40 num_spec_tokens: int = 0,
41 ) -> torch.Tensor:
42 batch_size, q_len, num_heads, dim_per_head = q.shape
tests/v1/test_serial_utils.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections import UserDict
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 import msgspec
7 import numpy as np
@@ -100,7 +99,7 @@ def test_encode_decode(monkeypatch: pytest.MonkeyPatch):
99
100
101 class MyRequest(msgspec.Struct):
103 - mm: Optional[list[MultiModalKwargsItems]]
102 + mm: list[MultiModalKwargsItems] | None
103
104
105 def test_multimodal_kwargs():
tests/v1/tpu/test_basic.py
+2 -2
@@ -5,8 +5,6 @@
5 Run `pytest tests/v1/tpu/test_basic.py`.
6 """
7
8 -from __future__ import annotations
9 -
8 from typing import TYPE_CHECKING
9
10 import pytest
@@ -16,6 +14,8 @@ from vllm.platforms import current_platform
14
15 if TYPE_CHECKING:
16 from tests.conftest import VllmRunner
17 +else:
18 + VllmRunner = object
19
20 MODELS = [
21 "Qwen/Qwen2.5-1.5B-Instruct",
tests/v1/tpu/test_perf.py
+2 -2
@@ -5,8 +5,6 @@
5 Run `pytest tests/v1/tpu/test_perf.py`.
6 """
7
8 -from __future__ import annotations
9 -
8 import time
9 from dataclasses import dataclass
10 from typing import TYPE_CHECKING
@@ -20,6 +18,8 @@ from vllm.transformers_utils.tokenizer import get_tokenizer
18
19 if TYPE_CHECKING:
20 from tests.conftest import VllmRunner
21 +else:
22 + VllmRunner = object
23
24
25 @dataclass
tests/v1/tracing/test_tracing.py
-2
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 # ruff: noqa
4 # type: ignore
5 -from __future__ import annotations
6 -
5 import threading
6 from collections.abc import Iterable
7 from concurrent import futures
tests/v1/worker/test_gpu_input_batch.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import inspect
5 from collections.abc import Sequence
6 -from typing import Optional
6
7 import numpy as np
8 import pytest
@@ -271,7 +270,7 @@ def test_sampling_metadata_in_input_batch(device: str, batch_size: int):
270 reqs, req_ids_retained, input_batch.req_id_to_index, device=torch.device(device)
271 )
272
274 - def same(t1: Optional[torch.Tensor], t2: Optional[torch.Tensor]) -> bool:
273 + def same(t1: torch.Tensor | None, t2: torch.Tensor | None) -> bool:
274 return (t1 is None and t2 is None) or (
275 t1 is not None and t2 is not None and torch.allclose(t1, t2)
276 )
tests/v1/worker/test_worker_memory_snapshot.py
+2 -3
@@ -4,8 +4,7 @@
4 import multiprocessing as mp
5 import os
6 import tempfile
7 -from multiprocessing import Queue
8 -from typing import Optional
7 +from multiprocessing.queues import Queue
8 from unittest.mock import patch
9
10 import pytest
@@ -16,7 +15,7 @@ from vllm.utils import MemorySnapshot
15 from vllm.v1.worker.gpu_worker import Worker, init_worker_distributed_environment
16
17 # Global queue to track operation order across processes
19 -_QUEUE: Optional[Queue] = None
18 +_QUEUE: Queue | None = None
19
20
21 def track_operation(operation: str, rank: int):
tests/vllm_test_utils/vllm_test_utils/blame.py
+1 -2
@@ -5,8 +5,7 @@ import contextlib
5 import dataclasses
6 import sys
7 import traceback
8 -from collections.abc import Generator
9 -from typing import Callable
8 +from collections.abc import Callable, Generator
9
10
11 @dataclasses.dataclass
tests/vllm_test_utils/vllm_test_utils/monitor.py
+2 -2
@@ -5,8 +5,8 @@ import contextlib
5 import dataclasses
6 import sys
7 import traceback
8 -from collections.abc import Generator
9 -from typing import Callable, Generic, TypeVar
8 +from collections.abc import Callable, Generator
9 +from typing import Generic, TypeVar
10
11 _T = TypeVar("_T")
12
tools/check_init_lazy_imports.py
-2
@@ -5,8 +5,6 @@ i.e: appears only within the ``if typing.TYPE_CHECKING:`` guard,
5 **except** for a short whitelist.
6 """
7
8 -from __future__ import annotations
9 -
8 import ast
9 import pathlib
10 import sys
tools/enforce_regex_import.py
-2
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import subprocess
4 from pathlib import Path
5
tools/pre_commit/mypy.py
+2 -3
@@ -20,7 +20,6 @@ Args:
20
21 import subprocess
22 import sys
23 -from typing import Optional
23
24 import regex as re
25
@@ -96,8 +95,8 @@ def group_files(changed_files: list[str]) -> dict[str, list[str]]:
95
96 def mypy(
97 targets: list[str],
99 - python_version: Optional[str],
100 - follow_imports: Optional[str],
98 + python_version: str | None,
99 + follow_imports: str | None,
100 file_group: str,
101 ) -> int:
102 """
tools/profiler/visualize_layerwise_profile.py
+2 -2
@@ -7,7 +7,7 @@ import json
7 import math
8 import os
9 from pathlib import Path
10 -from typing import Any, Optional
10 +from typing import Any
11
12 import matplotlib.pyplot as plt
13 import pandas as pd
@@ -373,7 +373,7 @@ def plot_trace_df(
373 traces_df: pd.DataFrame,
374 plot_metric: str,
375 plot_title: str,
376 - output: Optional[Path] = None,
376 + output: Path | None = None,
377 ):
378 def get_phase_description(traces_df: pd.DataFrame, phase: str) -> str:
379 phase_df = traces_df.query(f'phase == "{phase}"')
vllm/_bc_linter.py
+2 -3
@@ -1,9 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 # vllm/_bc_linter.py
4 -from __future__ import annotations
5 -
6 -from typing import Any, Callable, TypeVar, overload
4 +from collections.abc import Callable
5 +from typing import Any, TypeVar, overload
6
7 T = TypeVar("T")
8
vllm/_custom_ops.py
+103 -105
@@ -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, Literal, Optional, Union
4 +from typing import TYPE_CHECKING, Literal
5
6 import torch
7
@@ -37,7 +37,7 @@ def paged_attention_v1(
37 seq_lens: torch.Tensor,
38 block_size: int,
39 max_seq_len: int,
40 - alibi_slopes: Optional[torch.Tensor],
40 + alibi_slopes: torch.Tensor | None,
41 kv_cache_dtype: str,
42 k_scale: torch.Tensor,
43 v_scale: torch.Tensor,
@@ -84,7 +84,7 @@ def paged_attention_v2(
84 seq_lens: torch.Tensor,
85 block_size: int,
86 max_seq_len: int,
87 - alibi_slopes: Optional[torch.Tensor],
87 + alibi_slopes: torch.Tensor | None,
88 kv_cache_dtype: str,
89 k_scale: torch.Tensor,
90 v_scale: torch.Tensor,
@@ -132,14 +132,14 @@ def paged_attention_rocm(
132 scale: float,
133 block_tables: torch.Tensor,
134 seq_lens: torch.Tensor,
135 - query_start_loc: Optional[torch.Tensor],
135 + query_start_loc: torch.Tensor | None,
136 block_size: int,
137 max_seq_len: int,
138 - alibi_slopes: Optional[torch.Tensor],
138 + alibi_slopes: torch.Tensor | None,
139 kv_cache_dtype: str,
140 k_scale: torch.Tensor,
141 v_scale: torch.Tensor,
142 - fp8_out_scale: Optional[torch.Tensor] = None,
142 + fp8_out_scale: torch.Tensor | None = None,
143 mfma_type: str = "fp8" if envs.VLLM_ROCM_FP8_MFMA_PAGE_ATTN else "f16",
144 ) -> None:
145 torch.ops._rocm_C.paged_attention(
@@ -186,7 +186,7 @@ def merge_attn_states(
186 prefix_lse: torch.Tensor,
187 suffix_output: torch.Tensor,
188 suffix_lse: torch.Tensor,
189 - output_lse: Optional[torch.Tensor] = None,
189 + output_lse: torch.Tensor | None = None,
190 ) -> None:
191 torch.ops._C.merge_attn_states(
192 output, output_lse, prefix_output, prefix_lse, suffix_output, suffix_lse
@@ -314,7 +314,7 @@ def convert_vertical_slash_indexes_mergehead(
314 def rotary_embedding(
315 positions: torch.Tensor,
316 query: torch.Tensor,
317 - key: Optional[torch.Tensor],
317 + key: torch.Tensor | None,
318 head_size: int,
319 cos_sin_cache: torch.Tensor,
320 is_neox: bool,
@@ -408,8 +408,8 @@ def rms_norm_dynamic_per_token_quant(
408 weight: torch.Tensor,
409 epsilon: float,
410 quant_dtype: torch.dtype,
411 - scale_ub: Optional[torch.Tensor] = None,
412 - residual: Optional[torch.Tensor] = None,
411 + scale_ub: torch.Tensor | None = None,
412 + residual: torch.Tensor | None = None,
413 ) -> tuple[torch.Tensor, torch.Tensor]:
414 output = torch.empty_like(input, dtype=quant_dtype)
415 scales = torch.empty(
@@ -527,14 +527,14 @@ if hasattr(torch.ops._C, "gptq_marlin_24_gemm"):
527 @register_fake("_C::gptq_marlin_gemm")
528 def _gptq_marlin_gemm_fake(
529 a: torch.Tensor,
530 - c: Optional[torch.Tensor],
530 + c: torch.Tensor | None,
531 b_q_weight: torch.Tensor,
532 - b_bias: Optional[torch.Tensor],
532 + b_bias: torch.Tensor | None,
533 b_scales: torch.Tensor,
534 - global_scale: Optional[torch.Tensor],
535 - b_zeros: Optional[torch.Tensor],
536 - g_idx: Optional[torch.Tensor],
537 - perm: Optional[torch.Tensor],
534 + global_scale: torch.Tensor | None,
535 + b_zeros: torch.Tensor | None,
536 + g_idx: torch.Tensor | None,
537 + perm: torch.Tensor | None,
538 workspace: torch.Tensor,
539 b_q_type_id: int,
540 size_m: torch.SymInt,
@@ -582,13 +582,13 @@ if hasattr(torch.ops._C, "gptq_marlin_24_gemm"):
582 # b_q Should be the tensor returned by machete_prepack_B
583 b_q: torch.Tensor,
584 b_type: ScalarType,
585 - out_type: Optional[torch.dtype] = None,
586 - b_group_scales: Optional[torch.Tensor] = None,
587 - b_group_zeros: Optional[torch.Tensor] = None,
588 - b_group_size: Optional[int] = None,
589 - b_channel_scales: Optional[torch.Tensor] = None,
590 - a_token_scales: Optional[torch.Tensor] = None,
591 - schedule: Optional[str] = None,
585 + out_type: torch.dtype | None = None,
586 + b_group_scales: torch.Tensor | None = None,
587 + b_group_zeros: torch.Tensor | None = None,
588 + b_group_size: int | None = None,
589 + b_channel_scales: torch.Tensor | None = None,
590 + a_token_scales: torch.Tensor | None = None,
591 + schedule: str | None = None,
592 ) -> torch.Tensor:
593 m = a.size(0)
594 n = b_q.size(1)
@@ -599,7 +599,7 @@ if hasattr(torch.ops._C, "gptq_marlin_24_gemm"):
599 b_q_weight: torch.Tensor,
600 a_type: torch.dtype,
601 b_type: ScalarType,
602 - group_scales_type: Optional[torch.dtype],
602 + group_scales_type: torch.dtype | None,
603 ) -> torch.Tensor:
604 return torch.empty_like(b_q_weight, memory_format=torch.contiguous_format)
605
@@ -612,8 +612,8 @@ if hasattr(torch.ops._C, "gptq_marlin_24_gemm"):
612 b_group_size: int,
613 b_channel_scales: torch.Tensor,
614 a_token_scales: torch.Tensor,
615 - out_type: Optional[torch.dtype] = None,
616 - maybe_schedule: Optional[str] = None,
615 + out_type: torch.dtype | None = None,
616 + maybe_schedule: str | None = None,
617 ) -> torch.Tensor:
618 m = a.size(0)
619 n = b_q.size(1)
@@ -636,7 +636,7 @@ if hasattr(torch.ops._C, "allspark_w8a16_gemm"):
636 a: torch.Tensor,
637 b_qweight: torch.Tensor,
638 b_scales: torch.Tensor,
639 - b_qzeros: Optional[torch.Tensor],
639 + b_qzeros: torch.Tensor | None,
640 n: torch.SymInt,
641 group_size: torch.SymInt,
642 sm_count: torch.SymInt,
@@ -657,7 +657,7 @@ if hasattr(torch.ops._C, "ggml_dequantize"):
657 quant_type: int,
658 m: torch.SymInt,
659 n: torch.SymInt,
660 - dtype: Optional[torch.dtype] = None,
660 + dtype: torch.dtype | None = None,
661 ) -> torch.Tensor:
662 return torch.empty((m, n), dtype=torch.float16, device=W.device)
663
@@ -760,7 +760,7 @@ def cutlass_scaled_mm(
760 scale_a: torch.Tensor,
761 scale_b: torch.Tensor,
762 out_dtype: torch.dtype,
763 - bias: Optional[torch.Tensor] = None,
763 + bias: torch.Tensor | None = None,
764 ) -> torch.Tensor:
765 """
766 `cutlass_scaled_mm` implements a fused version of
@@ -812,8 +812,8 @@ def cutlass_scaled_mm_azp(
812 scale_b: torch.Tensor,
813 out_dtype: torch.dtype,
814 azp_adj: torch.Tensor,
815 - azp: Optional[torch.Tensor] = None,
816 - bias: Optional[torch.Tensor] = None,
815 + azp: torch.Tensor | None = None,
816 + bias: torch.Tensor | None = None,
817 ) -> torch.Tensor:
818 """
819 :param azp_adj: In the per-tensor case, this should include the azp.
@@ -890,7 +890,7 @@ def cutlass_scaled_sparse_mm(
890 scale_a: torch.Tensor,
891 scale_b: torch.Tensor,
892 out_dtype: torch.dtype,
893 - bias: Optional[torch.Tensor] = None,
893 + bias: torch.Tensor | None = None,
894 ) -> torch.Tensor:
895 """
896 Performs a scaled sparse matrix multiplication using Cutlass.
@@ -940,7 +940,7 @@ def get_cutlass_moe_mm_data(
940 num_experts: int,
941 n: int,
942 k: int,
943 - blockscale_offsets: Optional[torch.Tensor] = None,
943 + blockscale_offsets: torch.Tensor | None = None,
944 ):
945 """
946 Prepare data necessary to perform CUTLASS grouped matrix multiplications
@@ -986,7 +986,7 @@ def get_cutlass_moe_mm_problem_sizes(
986 num_experts: int,
987 n: int,
988 k: int,
989 - blockscale_offsets: Optional[torch.Tensor] = None,
989 + blockscale_offsets: torch.Tensor | None = None,
990 ):
991 """
992 Compute only the per-expert problem sizes needed by the two grouped matrix
@@ -1195,14 +1195,14 @@ def awq_marlin_moe_repack(
1195
1196 def gptq_marlin_gemm(
1197 a: torch.Tensor,
1198 - c: Optional[torch.Tensor],
1198 + c: torch.Tensor | None,
1199 b_q_weight: torch.Tensor,
1200 - b_bias: Optional[torch.Tensor],
1200 + b_bias: torch.Tensor | None,
1201 b_scales: torch.Tensor,
1202 - global_scale: Optional[torch.Tensor],
1203 - b_zeros: Optional[torch.Tensor],
1204 - g_idx: Optional[torch.Tensor],
1205 - perm: Optional[torch.Tensor],
1202 + global_scale: torch.Tensor | None,
1203 + b_zeros: torch.Tensor | None,
1204 + g_idx: torch.Tensor | None,
1205 + perm: torch.Tensor | None,
1206 workspace: torch.Tensor,
1207 b_q_type: ScalarType,
1208 size_m: int,
@@ -1239,11 +1239,11 @@ def gptq_marlin_gemm(
1239 def machete_supported_schedules(
1240 a_type: torch.dtype,
1241 b_type: ScalarType,
1242 - group_scales_type: Optional[torch.dtype],
1243 - group_zeros_type: Optional[torch.dtype] = None,
1244 - channel_scales_type: Optional[torch.dtype] = None,
1245 - token_scales_type: Optional[torch.dtype] = None,
1246 - out_type: Optional[torch.dtype] = None,
1242 + group_scales_type: torch.dtype | None,
1243 + group_zeros_type: torch.dtype | None = None,
1244 + channel_scales_type: torch.dtype | None = None,
1245 + token_scales_type: torch.dtype | None = None,
1246 + out_type: torch.dtype | None = None,
1247 ) -> list[str]:
1248 return torch.ops._C.machete_supported_schedules(
1249 a_type,
@@ -1261,13 +1261,13 @@ def machete_mm(
1261 # b_q Should be the tensor returned by machete_prepack_B
1262 b_q: torch.Tensor,
1263 b_type: ScalarType,
1264 - out_type: Optional[torch.dtype] = None,
1265 - b_group_scales: Optional[torch.Tensor] = None,
1266 - b_group_zeros: Optional[torch.Tensor] = None,
1267 - b_group_size: Optional[int] = None,
1268 - b_channel_scales: Optional[torch.Tensor] = None,
1269 - a_token_scales: Optional[torch.Tensor] = None,
1270 - schedule: Optional[str] = None,
1264 + out_type: torch.dtype | None = None,
1265 + b_group_scales: torch.Tensor | None = None,
1266 + b_group_zeros: torch.Tensor | None = None,
1267 + b_group_size: int | None = None,
1268 + b_channel_scales: torch.Tensor | None = None,
1269 + a_token_scales: torch.Tensor | None = None,
1270 + schedule: str | None = None,
1271 ) -> torch.Tensor:
1272 return torch.ops._C.machete_mm(
1273 a,
@@ -1287,7 +1287,7 @@ def machete_prepack_B(
1287 b_q_weight: torch.Tensor,
1288 a_type: torch.dtype,
1289 b_type: ScalarType,
1290 - group_scales_type: Optional[torch.dtype],
1290 + group_scales_type: torch.dtype | None,
1291 ) -> torch.Tensor:
1292 return torch.ops._C.machete_prepack_B(
1293 b_q_weight, a_type, b_type.id, group_scales_type
@@ -1303,8 +1303,8 @@ def cutlass_w4a8_mm(
1303 b_group_size: int,
1304 b_channel_scales: torch.Tensor,
1305 a_token_scales: torch.Tensor,
1306 - out_type: Optional[torch.dtype] = None,
1307 - maybe_schedule: Optional[str] = None,
1306 + out_type: torch.dtype | None = None,
1307 + maybe_schedule: str | None = None,
1308 ) -> torch.Tensor:
1309 return torch.ops._C.cutlass_w4a8_mm(
1310 a,
@@ -1458,11 +1458,11 @@ def scaled_fp4_experts_quant(
1458 # fp8
1459 def scaled_fp8_quant(
1460 input: torch.Tensor,
1461 - scale: Optional[torch.Tensor] = None,
1462 - num_token_padding: Optional[int] = None,
1463 - scale_ub: Optional[torch.Tensor] = None,
1461 + scale: torch.Tensor | None = None,
1462 + num_token_padding: int | None = None,
1463 + scale_ub: torch.Tensor | None = None,
1464 use_per_token_if_dynamic: bool = False,
1465 - output: Optional[torch.Tensor] = None,
1465 + output: torch.Tensor | None = None,
1466 ) -> tuple[torch.Tensor, torch.Tensor]:
1467 """
1468 Quantize input tensor to FP8 and return quantized tensor and scale.
@@ -1489,7 +1489,7 @@ def scaled_fp8_quant(
1489 """
1490 # This code assumes batch_dim and num_tokens are flattened
1491 assert input.ndim == 2
1492 - shape: Union[tuple[int, int], torch.Size] = input.shape
1492 + shape: tuple[int, int] | torch.Size = input.shape
1493 # For ROCm on MI300, the output fp8 dtype is torch.float_e3m3fnuz
1494 out_dtype: torch.dtype = current_platform.fp8_dtype()
1495 if num_token_padding:
@@ -1520,7 +1520,7 @@ def scaled_fp8_quant(
1520 def allspark_repack_weight(
1521 qweight: torch.Tensor,
1522 scale: torch.Tensor,
1523 - zero_point: Optional[torch.Tensor] = None,
1523 + zero_point: torch.Tensor | None = None,
1524 has_zp: bool = False,
1525 ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
1526 """
@@ -1576,7 +1576,7 @@ def allspark_w8a16_gemm(
1576 a: torch.Tensor,
1577 b_qweight: torch.Tensor,
1578 b_scales: torch.Tensor,
1579 - b_qzeros: Optional[torch.Tensor],
1579 + b_qzeros: torch.Tensor | None,
1580 n: int,
1581 group_size: int,
1582 sm_count: int,
@@ -1603,10 +1603,10 @@ def allspark_w8a16_gemm(
1603 # int8
1604 def scaled_int8_quant(
1605 input: torch.Tensor,
1606 - scale: Optional[torch.Tensor] = None,
1607 - azp: Optional[torch.Tensor] = None,
1606 + scale: torch.Tensor | None = None,
1607 + azp: torch.Tensor | None = None,
1608 symmetric: bool = True,
1609 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
1609 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
1610 """
1611 Quantize the input tensor to int8 and return the quantized tensor and scale, and maybe azp.
1612
@@ -1643,7 +1643,7 @@ def scaled_int8_quant(
1643
1644 # gguf
1645 def ggml_dequantize(
1646 - W: torch.Tensor, quant_type: int, m: int, n: int, dtype: Optional[torch.dtype]
1646 + W: torch.Tensor, quant_type: int, m: int, n: int, dtype: torch.dtype | None
1647 ) -> torch.Tensor:
1648 return torch.ops._C.ggml_dequantize(W, quant_type, m, n, dtype)
1649
@@ -1713,13 +1713,13 @@ def selective_scan_fwd(
1713 A: torch.Tensor,
1714 B: torch.Tensor,
1715 C: torch.Tensor,
1716 - D_: Optional[torch.Tensor],
1717 - z_: Optional[torch.Tensor],
1718 - delta_bias_: Optional[torch.Tensor],
1716 + D_: torch.Tensor | None,
1717 + z_: torch.Tensor | None,
1718 + delta_bias_: torch.Tensor | None,
1719 delta_softplus: bool,
1720 - query_start_loc: Optional[torch.Tensor],
1721 - cache_indices: Optional[torch.Tensor],
1722 - has_initial_state: Optional[torch.Tensor],
1720 + query_start_loc: torch.Tensor | None,
1721 + cache_indices: torch.Tensor | None,
1722 + has_initial_state: torch.Tensor | None,
1723 ssm_states: torch.Tensor,
1724 pad_slot_id: int,
1725 ):
@@ -1794,8 +1794,8 @@ def moe_wna16_gemm(
1794 output: torch.Tensor,
1795 b_qweight: torch.Tensor,
1796 b_scales: torch.Tensor,
1797 - b_qzeros: Optional[torch.Tensor],
1798 - topk_weights: Optional[torch.Tensor],
1797 + b_qzeros: torch.Tensor | None,
1798 + topk_weights: torch.Tensor | None,
1799 sorted_token_ids: torch.Tensor,
1800 experts_ids: torch.Tensor,
1801 num_tokens_post_pad: torch.Tensor,
@@ -1864,14 +1864,14 @@ def grouped_topk(
1864
1865 def moe_wna16_marlin_gemm(
1866 input: torch.Tensor,
1867 - output: Optional[torch.Tensor],
1867 + output: torch.Tensor | None,
1868 b_qweight: torch.Tensor,
1869 - b_bias: Optional[torch.Tensor],
1869 + b_bias: torch.Tensor | None,
1870 b_scales: torch.Tensor,
1871 - global_scale: Optional[torch.Tensor],
1872 - b_qzeros: Optional[torch.Tensor],
1873 - g_idx: Optional[torch.Tensor],
1874 - perm: Optional[torch.Tensor],
1871 + global_scale: torch.Tensor | None,
1872 + b_qzeros: torch.Tensor | None,
1873 + g_idx: torch.Tensor | None,
1874 + perm: torch.Tensor | None,
1875 workspace: torch.Tensor,
1876 sorted_token_ids: torch.Tensor,
1877 expert_ids: torch.Tensor,
@@ -1950,12 +1950,12 @@ if hasattr(torch.ops, "_moe_C") and hasattr(torch.ops._moe_C, "marlin_gemm_moe")
1950 @register_fake("_moe_C::moe_wna16_marlin_gemm")
1951 def moe_wna16_marlin_gemm_fake(
1952 input: torch.Tensor,
1953 - output: Optional[torch.Tensor],
1953 + output: torch.Tensor | None,
1954 b_qweight: torch.Tensor,
1955 b_scales: torch.Tensor,
1956 - b_qzeros: Optional[torch.Tensor],
1957 - g_idx: Optional[torch.Tensor],
1958 - perm: Optional[torch.Tensor],
1956 + b_qzeros: torch.Tensor | None,
1957 + g_idx: torch.Tensor | None,
1958 + perm: torch.Tensor | None,
1959 workspace: torch.Tensor,
1960 sorted_token_ids: torch.Tensor,
1961 expert_ids: torch.Tensor,
@@ -2068,7 +2068,7 @@ def gather_and_maybe_dequant_cache(
2068 batch_size: int,
2069 kv_cache_dtype: str,
2070 scale: torch.Tensor,
2071 - seq_starts: Optional[torch.Tensor] = None,
2071 + seq_starts: torch.Tensor | None = None,
2072 ) -> None:
2073 torch.ops._C_cache_ops.gather_and_maybe_dequant_cache(
2074 src_cache,
@@ -2088,7 +2088,7 @@ def cp_gather_cache(
2088 block_table: torch.Tensor,
2089 cu_seq_lens: torch.Tensor,
2090 batch_size: int,
2091 - seq_starts: Optional[torch.Tensor] = None,
2091 + seq_starts: torch.Tensor | None = None,
2092 ) -> None:
2093 torch.ops._C_cache_ops.cp_gather_cache(
2094 src_cache, dst, block_table, cu_seq_lens, batch_size, seq_starts
@@ -2187,9 +2187,7 @@ def free_shared_buffer(ptr: int) -> None:
2187
2188
2189 # quick all reduce
2190 -def init_custom_qr(
2191 - rank: int, world_size: int, qr_max_size: Optional[int] = None
2192 -) -> int:
2190 +def init_custom_qr(rank: int, world_size: int, qr_max_size: int | None = None) -> int:
2191 return torch.ops._C_custom_ar.init_custom_qr(rank, world_size, qr_max_size)
2192
2193
@@ -2247,7 +2245,7 @@ def flash_mla_with_kvcache(
2245 head_dim_v: int,
2246 tile_scheduler_metadata: torch.Tensor,
2247 num_splits: torch.Tensor,
2250 - softmax_scale: Optional[float] = None,
2248 + softmax_scale: float | None = None,
2249 causal: bool = False,
2250 ) -> tuple[torch.Tensor, torch.Tensor]:
2251 """
@@ -2324,7 +2322,7 @@ if hasattr(torch.ops._C, "weight_packed_linear"):
2322 def weight_packed_linear_fake(
2323 mat1: torch.Tensor,
2324 mat2: torch.Tensor,
2327 - bias: Optional[torch.Tensor],
2325 + bias: torch.Tensor | None,
2326 is_vnni: bool,
2327 ) -> torch.Tensor:
2328 return torch.empty(
@@ -2344,11 +2342,11 @@ if hasattr(torch.ops._C, "fused_experts_cpu"):
2342 inplace: bool,
2343 use_int8_w8a8: bool,
2344 use_fp8_w8a16: bool,
2347 - w1_scale: Optional[torch.Tensor],
2348 - w2_scale: Optional[torch.Tensor],
2349 - block_size: Optional[list[int]],
2350 - a1_scale: Optional[torch.Tensor],
2351 - a2_scale: Optional[torch.Tensor],
2345 + w1_scale: torch.Tensor | None,
2346 + w2_scale: torch.Tensor | None,
2347 + block_size: list[int] | None,
2348 + a1_scale: torch.Tensor | None,
2349 + a2_scale: torch.Tensor | None,
2350 is_vnni: bool,
2351 ) -> torch.Tensor:
2352 return torch.empty_like(hidden_states)
@@ -2361,7 +2359,7 @@ if hasattr(torch.ops._C, "int8_scaled_mm_with_quant"):
2359 mat1: torch.Tensor,
2360 mat2: torch.Tensor,
2361 scales2: torch.Tensor,
2364 - bias: Optional[torch.Tensor],
2362 + bias: torch.Tensor | None,
2363 out_dtype: torch.dtype,
2364 is_vnni: bool,
2365 ) -> torch.Tensor:
@@ -2372,7 +2370,7 @@ if hasattr(torch.ops._C, "int8_scaled_mm_with_quant"):
2370
2371 class CPUDNNLGEMMHandler:
2372 def __init__(self) -> None:
2375 - self.handler: Optional[int] = None
2373 + self.handler: int | None = None
2374 self.n = -1
2375 self.k = -1
2376
@@ -2403,7 +2401,7 @@ def create_onednn_mm(
2401 def onednn_mm(
2402 dnnl_handler: CPUDNNLGEMMHandler,
2403 x: torch.Tensor,
2406 - bias: Optional[torch.Tensor],
2404 + bias: torch.Tensor | None,
2405 ) -> torch.Tensor:
2406 output = torch.empty((*x.shape[0:-1], dnnl_handler.n), dtype=x.dtype)
2407 torch.ops._C.onednn_mm(
@@ -2431,8 +2429,8 @@ def create_onednn_scaled_mm(
2429
2430 def onednn_scaled_int8_quant(
2431 input: torch.Tensor,
2434 - scale: Optional[torch.Tensor] = None,
2435 - azp: Optional[torch.Tensor] = None,
2432 + scale: torch.Tensor | None = None,
2433 + azp: torch.Tensor | None = None,
2434 symmetric: bool = True,
2435 ):
2436 """
@@ -2471,10 +2469,10 @@ def onednn_scaled_mm(
2469 dnnl_handler: CPUDNNLGEMMHandler,
2470 x: torch.Tensor,
2471 output: torch.Tensor,
2474 - input_scale: Optional[torch.Tensor],
2475 - input_zp: Optional[torch.Tensor],
2476 - input_zp_adj: Optional[torch.Tensor],
2477 - bias: Optional[torch.Tensor],
2472 + input_scale: torch.Tensor | None,
2473 + input_zp: torch.Tensor | None,
2474 + input_zp_adj: torch.Tensor | None,
2475 + bias: torch.Tensor | None,
2476 ) -> torch.Tensor:
2477 torch.ops._C.onednn_scaled_mm(
2478 output, x, input_scale, input_zp, input_zp_adj, bias, dnnl_handler.handler
vllm/_ipex_ops.py
+19 -20
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import torch
6
@@ -65,7 +64,7 @@ class ipex_ops:
64 context_lens: torch.Tensor,
65 block_size: int,
66 max_context_len: int,
68 - alibi_slopes: Optional[torch.Tensor],
67 + alibi_slopes: torch.Tensor | None,
68 kv_cache_dtype: str,
69 k_scale: float,
70 v_scale: float,
@@ -107,7 +106,7 @@ class ipex_ops:
106 context_lens: torch.Tensor,
107 block_size: int,
108 max_context_len: int,
110 - alibi_slopes: Optional[torch.Tensor],
109 + alibi_slopes: torch.Tensor | None,
110 kv_cache_dtype: str,
111 k_scale: float,
112 v_scale: float,
@@ -174,7 +173,7 @@ class ipex_ops:
173 out: torch.Tensor,
174 seqlen_q: torch.Tensor,
175 seqlen_k: torch.Tensor,
177 - alibi_slopes: Optional[torch.Tensor],
176 + alibi_slopes: torch.Tensor | None,
177 max_seqlen_q: int,
178 max_seqlen_k: int,
179 pdropout: float,
@@ -254,8 +253,8 @@ class ipex_ops:
253 value_cache: torch.Tensor,
254 slot_mapping: torch.Tensor,
255 kv_cache_dtype: str,
257 - k_scale: Optional[torch.Tensor] = None,
258 - v_scale: Optional[torch.Tensor] = None,
256 + k_scale: torch.Tensor | None = None,
257 + v_scale: torch.Tensor | None = None,
258 k_scale_float: float = 1.0,
259 v_scale_float: float = 1.0,
260 ) -> None:
@@ -283,10 +282,10 @@ class ipex_ops:
282 softmax_scale: float,
283 causal: bool,
284 block_table: torch.Tensor,
286 - alibi_slopes: Optional[torch.Tensor],
287 - window_size: Optional[list[int]] = None,
288 - softcap: Optional[float] = 0.0,
289 - cu_seqlens_k: Optional[torch.Tensor] = None,
285 + alibi_slopes: torch.Tensor | None,
286 + window_size: list[int] | None = None,
287 + softcap: float | None = 0.0,
288 + cu_seqlens_k: torch.Tensor | None = None,
289 # The following parameters are not used in ipex kernel currently,
290 # we keep API compatible to CUDA's.
291 scheduler_metadata=None,
@@ -295,7 +294,7 @@ class ipex_ops:
294 k_descale=None,
295 v_descale=None,
296 num_splits=0,
298 - s_aux: Optional[torch.Tensor] = None,
297 + s_aux: torch.Tensor | None = None,
298 ):
299 if cu_seqlens_k is None:
300 # cu_seqlens_k is not used in ipex kernel.
@@ -344,10 +343,10 @@ class ipex_ops:
343 cache_seqlens: torch.Tensor,
344 qkv_dtype=torch.bfloat16,
345 headdim_v=None,
347 - cu_seqlens_q: Optional[torch.Tensor] = None,
348 - cu_seqlens_k_new: Optional[torch.Tensor] = None,
349 - cache_leftpad: Optional[torch.Tensor] = None,
350 - page_size: Optional[int] = None,
346 + cu_seqlens_q: torch.Tensor | None = None,
347 + cu_seqlens_k_new: torch.Tensor | None = None,
348 + cache_leftpad: torch.Tensor | None = None,
349 + page_size: int | None = None,
350 max_seqlen_k_new=0,
351 causal=False,
352 window_size=(-1, -1), # -1 means infinite context window
@@ -382,11 +381,11 @@ class ipex_ops:
381 @staticmethod
382 def scaled_fp8_quant(
383 input: torch.Tensor,
385 - scale: Optional[torch.Tensor] = None,
386 - num_token_padding: Optional[int] = None,
387 - scale_ub: Optional[torch.Tensor] = None,
384 + scale: torch.Tensor | None = None,
385 + num_token_padding: int | None = None,
386 + scale_ub: torch.Tensor | None = None,
387 use_per_token_if_dynamic: bool = False,
389 - output: Optional[torch.Tensor] = None,
388 + output: torch.Tensor | None = None,
389 ) -> tuple[torch.Tensor, torch.Tensor]:
390 """
391 Quantize input tensor to FP8 and return quantized tensor and scale.
@@ -414,7 +413,7 @@ class ipex_ops:
413 """
414 # This code assumes batch_dim and num_tokens are flattened
415 assert input.ndim == 2
417 - shape: Union[tuple[int, int], torch.Size] = input.shape
416 + shape: tuple[int, int] | torch.Size = input.shape
417 out_dtype: torch.dtype = current_platform.fp8_dtype()
418 if num_token_padding:
419 shape = (max(num_token_padding, input.shape[0]), shape[1])
vllm/assets/base.py
+1 -2
@@ -3,7 +3,6 @@
3
4 from functools import lru_cache
5 from pathlib import Path
6 -from typing import Optional
6
7 import vllm.envs as envs
8 from vllm.connections import global_http_connection
@@ -20,7 +19,7 @@ def get_cache_dir() -> Path:
19
20
21 @lru_cache
23 -def get_vllm_public_assets(filename: str, s3_prefix: Optional[str] = None) -> Path:
22 +def get_vllm_public_assets(filename: str, s3_prefix: str | None = None) -> Path:
23 """
24 Download an asset file from ``s3://vllm-public-assets``
25 and return the path to the downloaded file.
vllm/assets/video.py
+2 -2
@@ -3,7 +3,7 @@
3
4 from dataclasses import dataclass
5 from functools import lru_cache
6 -from typing import Any, ClassVar, Literal, Optional
6 +from typing import Any, ClassVar, Literal
7
8 import cv2
9 import numpy as np
@@ -137,7 +137,7 @@ class VideoAsset:
137 ret = video_get_metadata(self.video_path, self.num_frames)
138 return ret
139
140 - def get_audio(self, sampling_rate: Optional[float] = None) -> npt.NDArray:
140 + def get_audio(self, sampling_rate: float | None = None) -> npt.NDArray:
141 """
142 Read audio data from the video asset, used in Qwen2.5-Omni examples.
143
vllm/attention/backends/abstract.py
+20 -20
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from abc import ABC, abstractmethod
5 -from typing import Generic, Optional, Protocol, TypeVar, Union
5 +from typing import Generic, Protocol, TypeVar
6
7 import torch
8
@@ -65,7 +65,7 @@ class AttentionBackend(ABC):
65 raise NotImplementedError
66
67 @classmethod
68 - def get_supported_kernel_block_size(cls) -> list[Union[int, MultipleOf]]:
68 + def get_supported_kernel_block_size(cls) -> list[int | MultipleOf]:
69 return cls.get_impl_cls().get_supported_kernel_block_size()
70
71 @classmethod
@@ -158,18 +158,18 @@ class AttentionImpl(ABC, Generic[T]):
158 num_heads: int,
159 head_size: int,
160 scale: float,
161 - num_kv_heads: Optional[int] = None,
162 - alibi_slopes: Optional[list[float]] = None,
163 - sliding_window: Optional[int] = None,
161 + num_kv_heads: int | None = None,
162 + alibi_slopes: list[float] | None = None,
163 + sliding_window: int | None = None,
164 kv_cache_dtype: str = "auto",
165 - logits_soft_cap: Optional[float] = None,
165 + logits_soft_cap: float | None = None,
166 attn_type: str = AttentionType.DECODER,
167 - kv_sharing_target_layer_name: Optional[str] = None,
167 + kv_sharing_target_layer_name: str | None = None,
168 ) -> None:
169 raise NotImplementedError
170
171 @staticmethod
172 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
172 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
173 # TODO: implement this function for all backends.
174 return [MultipleOf(1)]
175
@@ -182,9 +182,9 @@ class AttentionImpl(ABC, Generic[T]):
182 value: torch.Tensor,
183 kv_cache: torch.Tensor,
184 attn_metadata: T,
185 - output: Optional[torch.Tensor] = None,
186 - output_scale: Optional[torch.Tensor] = None,
187 - output_block_scale: Optional[torch.Tensor] = None,
185 + output: torch.Tensor | None = None,
186 + output_scale: torch.Tensor | None = None,
187 + output_block_scale: torch.Tensor | None = None,
188 ) -> torch.Tensor:
189 raise NotImplementedError
190
@@ -208,21 +208,21 @@ class MLAAttentionImpl(AttentionImpl[T], Generic[T]):
208 head_size: int,
209 scale: float,
210 num_kv_heads: int,
211 - alibi_slopes: Optional[list[float]],
212 - sliding_window: Optional[int],
211 + alibi_slopes: list[float] | None,
212 + sliding_window: int | None,
213 kv_cache_dtype: str,
214 - logits_soft_cap: Optional[float],
214 + logits_soft_cap: float | None,
215 attn_type: str,
216 - kv_sharing_target_layer_name: Optional[str],
216 + kv_sharing_target_layer_name: str | None,
217 # MLA Specific Arguments
218 - q_lora_rank: Optional[int],
218 + q_lora_rank: int | None,
219 kv_lora_rank: int,
220 qk_nope_head_dim: int,
221 qk_rope_head_dim: int,
222 qk_head_dim: int,
223 v_head_dim: int,
224 kv_b_proj: ColumnParallelLinear,
225 - indexer: Optional[object] = None,
225 + indexer: object | None = None,
226 ) -> None:
227 raise NotImplementedError
228
@@ -235,9 +235,9 @@ class MLAAttentionImpl(AttentionImpl[T], Generic[T]):
235 k_pe: torch.Tensor,
236 kv_cache: torch.Tensor,
237 attn_metadata: T,
238 - output: Optional[torch.Tensor] = None,
239 - output_scale: Optional[torch.Tensor] = None,
240 - output_block_scale: Optional[torch.Tensor] = None,
238 + output: torch.Tensor | None = None,
239 + output_scale: torch.Tensor | None = None,
240 + output_block_scale: torch.Tensor | None = None,
241 ) -> torch.Tensor:
242 raise NotImplementedError
243
vllm/attention/backends/registry.py
+2 -3
@@ -3,7 +3,6 @@
3 """Attention backend registry"""
4
5 import enum
6 -from typing import Optional
6
7 from vllm.utils import resolve_obj_by_qualname
8
@@ -53,7 +52,7 @@ BACKEND_MAP = {
52 }
53
54
56 -def register_attn_backend(backend: _Backend, class_path: Optional[str] = None):
55 +def register_attn_backend(backend: _Backend, class_path: str | None = None):
56 """
57 Decorator: register a custom attention backend into BACKEND_MAPPING.
58 - If class_path is provided, use it.
@@ -98,7 +97,7 @@ def backend_to_class(backend: _Backend) -> type:
97 return resolve_obj_by_qualname(backend_class_name)
98
99
101 -def backend_name_to_enum(backend_name: str) -> Optional[_Backend]:
100 +def backend_name_to_enum(backend_name: str) -> _Backend | None:
101 """
102 Convert a string backend name to a _Backend enum value.
103
vllm/attention/backends/utils.py
+1 -2
@@ -3,7 +3,6 @@
3 """Attention backend utils"""
4
5 from dataclasses import dataclass
6 -from typing import Optional
6
7 from vllm.config import ModelConfig
8 from vllm.logger import init_logger
@@ -15,7 +14,7 @@ PAD_SLOT_ID = -1
14
15 @dataclass
16 class MLADims:
18 - q_lora_rank: Optional[int]
17 + q_lora_rank: int | None
18 kv_lora_rank: int
19 qk_nope_head_dim: int
20 qk_rope_head_dim: int
vllm/attention/layer.py
+27 -26
@@ -2,7 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Attention layer."""
4
5 -from typing import Callable, Optional, cast
5 +from collections.abc import Callable
6 +from typing import cast
7
8 import torch
9 import torch.nn as nn
@@ -128,16 +129,16 @@ class Attention(nn.Module, AttentionLayerBase):
129 num_heads: int,
130 head_size: int,
131 scale: float,
131 - num_kv_heads: Optional[int] = None,
132 - alibi_slopes: Optional[list[float]] = None,
133 - cache_config: Optional[CacheConfig] = None,
134 - quant_config: Optional[QuantizationConfig] = None,
135 - logits_soft_cap: Optional[float] = None,
136 - per_layer_sliding_window: Optional[int] = None,
132 + num_kv_heads: int | None = None,
133 + alibi_slopes: list[float] | None = None,
134 + cache_config: CacheConfig | None = None,
135 + quant_config: QuantizationConfig | None = None,
136 + logits_soft_cap: float | None = None,
137 + per_layer_sliding_window: int | None = None,
138 prefix: str = "",
139 attn_type: str = AttentionType.DECODER,
139 - kv_sharing_target_layer_name: Optional[str] = None,
140 - attn_backend: Optional[type[AttentionBackend]] = None,
140 + kv_sharing_target_layer_name: str | None = None,
141 + attn_backend: type[AttentionBackend] | None = None,
142 **extra_impl_args,
143 ) -> None:
144 """
@@ -191,7 +192,7 @@ class Attention(nn.Module, AttentionLayerBase):
192
193 # The output scale on host memory. This should be the input scale of
194 # the quant op after this attention layer.
194 - self._o_scale_float: Optional[float] = None
195 + self._o_scale_float: float | None = None
196
197 self.num_heads = num_heads
198 self.head_size = head_size
@@ -319,7 +320,7 @@ class Attention(nn.Module, AttentionLayerBase):
320 # For some alternate attention backends like MLA the attention output
321 # shape does not match the query shape, so we optionally let the model
322 # definition specify the output tensor shape.
322 - output_shape: Optional[torch.Size] = None,
323 + output_shape: torch.Size | None = None,
324 ) -> torch.Tensor:
325 """
326 The KV cache is stored inside this class and is accessed via
@@ -427,7 +428,7 @@ class MultiHeadAttention(nn.Module):
428 num_heads: int,
429 head_size: int,
430 scale: float,
430 - num_kv_heads: Optional[int] = None,
431 + num_kv_heads: int | None = None,
432 # This has no effect, it is only here to make it easier to swap
433 # between Attention and MultiHeadAttention
434 prefix: str = "",
@@ -582,14 +583,14 @@ class MLAAttention(nn.Module, AttentionLayerBase):
583 qk_nope_head_dim: int,
584 qk_rope_head_dim: int,
585 v_head_dim: int,
585 - q_lora_rank: Optional[int],
586 + q_lora_rank: int | None,
587 kv_lora_rank: int,
588 kv_b_proj: ColumnParallelLinear,
588 - cache_config: Optional[CacheConfig] = None,
589 - quant_config: Optional[QuantizationConfig] = None,
589 + cache_config: CacheConfig | None = None,
590 + quant_config: QuantizationConfig | None = None,
591 prefix: str = "",
592 use_sparse: bool = False,
592 - indexer: Optional[object] = None,
593 + indexer: object | None = None,
594 ):
595 super().__init__()
596 self.num_heads = num_heads
@@ -670,7 +671,7 @@ class MLAAttention(nn.Module, AttentionLayerBase):
671 self._q_scale_float = 1.0
672 self._k_scale_float = 1.0
673 self._v_scale_float = 1.0
673 - self._o_scale_float: Optional[float] = None
674 + self._o_scale_float: float | None = None
675
676 self.use_sparse = use_sparse
677
@@ -688,7 +689,7 @@ class MLAAttention(nn.Module, AttentionLayerBase):
689 q: torch.Tensor,
690 kv_c_normed: torch.Tensor,
691 k_pe: torch.Tensor,
691 - output_shape: Optional[torch.Size] = None,
692 + output_shape: torch.Size | None = None,
693 ) -> torch.Tensor:
694 if self.use_direct_call:
695 forward_context: ForwardContext = get_forward_context()
@@ -888,8 +889,8 @@ def unified_attention_with_output(
889 value: torch.Tensor,
890 output: torch.Tensor,
891 layer_name: str,
891 - output_scale: Optional[torch.Tensor] = None,
892 - output_block_scale: Optional[torch.Tensor] = None,
892 + output_scale: torch.Tensor | None = None,
893 + output_block_scale: torch.Tensor | None = None,
894 ) -> None:
895 wait_for_kv_layer_from_connector(layer_name)
896 forward_context: ForwardContext = get_forward_context()
@@ -919,8 +920,8 @@ def unified_attention_with_output_fake(
920 value: torch.Tensor,
921 output: torch.Tensor,
922 layer_name: str,
922 - output_scale: Optional[torch.Tensor] = None,
923 - output_block_scale: Optional[torch.Tensor] = None,
923 + output_scale: torch.Tensor | None = None,
924 + output_block_scale: torch.Tensor | None = None,
925 ) -> None:
926 return
927
@@ -978,8 +979,8 @@ def unified_mla_attention_with_output(
979 k_pe: torch.Tensor,
980 output: torch.Tensor,
981 layer_name: str,
981 - output_scale: Optional[torch.Tensor] = None,
982 - output_block_scale: Optional[torch.Tensor] = None,
982 + output_scale: torch.Tensor | None = None,
983 + output_block_scale: torch.Tensor | None = None,
984 ) -> None:
985 wait_for_kv_layer_from_connector(layer_name)
986 forward_context: ForwardContext = get_forward_context()
@@ -1009,8 +1010,8 @@ def unified_mla_attention_with_output_fake(
1010 k_pe: torch.Tensor,
1011 output: torch.Tensor,
1012 layer_name: str,
1012 - output_scale: Optional[torch.Tensor] = None,
1013 - output_block_scale: Optional[torch.Tensor] = None,
1013 + output_scale: torch.Tensor | None = None,
1014 + output_block_scale: torch.Tensor | None = None,
1015 ) -> None:
1016 return
1017
vllm/attention/layers/chunked_local_attention.py
+6 -6
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import functools
4 -from typing import ClassVar, Optional
4 +from typing import ClassVar
5
6 import torch
7
@@ -60,11 +60,11 @@ class ChunkedLocalAttention(Attention):
60 head_size: int,
61 scale: float,
62 attention_chunk_size: int,
63 - num_kv_heads: Optional[int] = None,
64 - alibi_slopes: Optional[list[float]] = None,
65 - cache_config: Optional[CacheConfig] = None,
66 - quant_config: Optional[QuantizationConfig] = None,
67 - kv_sharing_target_layer_name: Optional[str] = None,
63 + num_kv_heads: int | None = None,
64 + alibi_slopes: list[float] | None = None,
65 + cache_config: CacheConfig | None = None,
66 + quant_config: QuantizationConfig | None = None,
67 + kv_sharing_target_layer_name: str | None = None,
68 prefix: str = "",
69 ):
70 dtype = torch.get_default_dtype()
vllm/attention/layers/cross_attention.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import functools
4 from copy import copy
5 -from typing import Optional
5
6 import numpy as np
7 import torch
@@ -138,8 +137,8 @@ class CrossAttention(Attention):
137 num_heads: int,
138 head_size: int,
139 scale: float,
141 - cache_config: Optional[CacheConfig] = None,
142 - attn_type: Optional[str] = None,
140 + cache_config: CacheConfig | None = None,
141 + attn_type: str | None = None,
142 **kwargs,
143 ):
144 dtype = torch.get_default_dtype()
vllm/attention/layers/encoder_only_attention.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import functools
4 from copy import copy
5 -from typing import Optional
5
6 import torch
7
@@ -60,8 +59,8 @@ class EncoderOnlyAttention(Attention):
59 num_heads: int,
60 head_size: int,
61 scale: float,
63 - cache_config: Optional[CacheConfig] = None,
64 - attn_type: Optional[str] = None,
62 + cache_config: CacheConfig | None = None,
63 + attn_type: str | None = None,
64 **kwargs,
65 ):
66 dtype = torch.get_default_dtype()
vllm/attention/ops/flashmla.py
+9 -10
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 # adapted from: https://github.com/deepseek-ai/FlashMLA/blob/main/flash_mla/flash_mla_interface.py
4 -from typing import Optional
4
5 import torch
6
@@ -31,7 +30,7 @@ else:
30 _flashmla_extension_C_AVAILABLE = False
31
32
34 -def _is_flashmla_available() -> tuple[bool, Optional[str]]:
33 +def _is_flashmla_available() -> tuple[bool, str | None]:
34 if not _flashmla_C_AVAILABLE:
35 return (
36 False,
@@ -49,7 +48,7 @@ def _is_flashmla_available() -> tuple[bool, Optional[str]]:
48 return True, None
49
50
52 -def is_flashmla_dense_supported() -> tuple[bool, Optional[str]]:
51 +def is_flashmla_dense_supported() -> tuple[bool, str | None]:
52 """
53 Return: is_supported_flag, unsupported_reason (optional).
54 """
@@ -61,7 +60,7 @@ def is_flashmla_dense_supported() -> tuple[bool, Optional[str]]:
60 return True, None
61
62
64 -def is_flashmla_sparse_supported() -> tuple[bool, Optional[str]]:
63 +def is_flashmla_sparse_supported() -> tuple[bool, str | None]:
64 """
65 Return: is_supported_flag, unsupported_reason (optional).
66 """
@@ -80,9 +79,9 @@ def get_mla_metadata(
79 cache_seqlens: torch.Tensor,
80 num_q_tokens_per_head_k: int,
81 num_heads_k: int,
83 - num_heads_q: Optional[int] = None,
82 + num_heads_q: int | None = None,
83 is_fp8_kvcache: bool = False,
85 - topk: Optional[int] = None,
84 + topk: int | None = None,
85 ) -> tuple[torch.Tensor, torch.Tensor]:
86 """
87 Arguments:
@@ -121,12 +120,12 @@ def flash_mla_with_kvcache(
120 head_dim_v: int,
121 tile_scheduler_metadata: torch.Tensor,
122 num_splits: torch.Tensor,
124 - softmax_scale: Optional[float] = None,
123 + softmax_scale: float | None = None,
124 causal: bool = False,
126 - descale_q: Optional[torch.Tensor] = None,
127 - descale_k: Optional[torch.Tensor] = None,
125 + descale_q: torch.Tensor | None = None,
126 + descale_k: torch.Tensor | None = None,
127 is_fp8_kvcache: bool = False,
129 - indices: Optional[torch.Tensor] = None,
128 + indices: torch.Tensor | None = None,
129 ) -> tuple[torch.Tensor, torch.Tensor]:
130 """
131 Arguments:
vllm/attention/ops/merge_attn_states.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -13,7 +12,7 @@ def merge_attn_states(
12 prefix_lse: torch.Tensor,
13 suffix_output: torch.Tensor,
14 suffix_lse: torch.Tensor,
16 - output_lse: Optional[torch.Tensor] = None,
15 + output_lse: torch.Tensor | None = None,
16 ) -> None:
17 # NOTE(DefTruth): Currently, custom merge_attn_states CUDA kernel
18 # is not support for FP8 dtype, fallback to use Triton kernel.
vllm/attention/ops/paged_attn.py
+5 -6
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 import torch
7
@@ -27,7 +26,7 @@ class PagedAttentionMetadata:
26
27 # (batch_size,). The length of sequences (entire tokens seen so far) per
28 # sequence.
30 - seq_lens_tensor: Optional[torch.Tensor]
29 + seq_lens_tensor: torch.Tensor | None
30 # Maximum sequence length in the batch. 0 if it is prefill-only batch.
31 max_decode_seq_len: int
32 # (batch_size, max_blocks_per_seq).
@@ -36,7 +35,7 @@ class PagedAttentionMetadata:
35 # in the kv cache. Each block can contain up to block_size tokens.
36 # 2nd dimensions are padded up to max_blocks_per_seq if it is cuda-graph
37 # captured.
39 - block_tables: Optional[torch.Tensor]
38 + block_tables: torch.Tensor | None
39
40
41 class PagedAttention:
@@ -102,7 +101,7 @@ class PagedAttention:
101 kv_cache_dtype: str,
102 num_kv_heads: int,
103 scale: float,
105 - alibi_slopes: Optional[torch.Tensor],
104 + alibi_slopes: torch.Tensor | None,
105 k_scale: torch.Tensor,
106 v_scale: torch.Tensor,
107 tp_rank: int = 0,
@@ -211,8 +210,8 @@ class PagedAttention:
210 query_start_loc: torch.Tensor,
211 seq_lens_tensor: torch.Tensor,
212 max_query_len: int,
214 - alibi_slopes: Optional[torch.Tensor],
215 - sliding_window: Optional[int],
213 + alibi_slopes: torch.Tensor | None,
214 + sliding_window: int | None,
215 k_scale: torch.Tensor,
216 v_scale: torch.Tensor,
217 ) -> torch.Tensor:
vllm/attention/ops/rocm_aiter_mla.py
+9 -10
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -30,9 +29,9 @@ def aiter_mla_decode_fwd(
29 sm_scale: float,
30 qo_indptr: torch.Tensor,
31 max_seqlen_qo: int,
33 - kv_indptr: Optional[torch.Tensor] = None,
34 - kv_indices: Optional[torch.Tensor] = None,
35 - kv_last_page_lens: Optional[torch.Tensor] = None,
32 + kv_indptr: torch.Tensor | None = None,
33 + kv_indices: torch.Tensor | None = None,
34 + kv_last_page_lens: torch.Tensor | None = None,
35 logit_cap: float = 0.0,
36 ):
37 torch.ops.vllm.rocm_aiter_mla_decode_fwd(
@@ -55,9 +54,9 @@ def mla_decode_fwd_impl(
54 o: torch.Tensor,
55 qo_indptr: torch.Tensor,
56 max_seqlen_qo: int,
58 - kv_indptr: Optional[torch.Tensor] = None,
59 - kv_indices: Optional[torch.Tensor] = None,
60 - kv_last_page_lens: Optional[torch.Tensor] = None,
57 + kv_indptr: torch.Tensor | None = None,
58 + kv_indices: torch.Tensor | None = None,
59 + kv_last_page_lens: torch.Tensor | None = None,
60 sm_scale: float = 1.0,
61 logit_cap: float = 0.0,
62 ) -> None:
@@ -83,9 +82,9 @@ def mla_decode_fwd_fake(
82 o: torch.Tensor,
83 qo_indptr: torch.Tensor,
84 max_seqlen_qo: int,
86 - kv_indptr: Optional[torch.Tensor] = None,
87 - kv_indices: Optional[torch.Tensor] = None,
88 - kv_last_page_lens: Optional[torch.Tensor] = None,
85 + kv_indptr: torch.Tensor | None = None,
86 + kv_indices: torch.Tensor | None = None,
87 + kv_last_page_lens: torch.Tensor | None = None,
88 sm_scale: float = 1.0,
89 logit_cap: float = 0.0,
90 ) -> None:
vllm/attention/ops/rocm_aiter_paged_attn.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import aiter as rocm_aiter
5 import torch
@@ -62,7 +61,7 @@ class AITERPagedAttention(PagedAttention):
61 kv_cache_dtype: str,
62 num_kv_heads: int,
63 scale: float,
65 - alibi_slopes: Optional[torch.Tensor],
64 + alibi_slopes: torch.Tensor | None,
65 k_scale: torch.Tensor,
66 v_scale: torch.Tensor,
67 tp_rank: int = 0,
vllm/attention/ops/triton_merge_attn_states.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -15,7 +14,7 @@ def merge_attn_states(
14 prefix_lse: torch.Tensor,
15 suffix_output: torch.Tensor,
16 suffix_lse: torch.Tensor,
18 - output_lse: Optional[torch.Tensor] = None,
17 + output_lse: torch.Tensor | None = None,
18 ) -> None:
19 num_tokens = output.shape[0]
20 num_query_heads = output.shape[1]
vllm/attention/selector.py
+9 -10
@@ -6,7 +6,6 @@ from collections.abc import Generator
6 from contextlib import contextmanager
7 from dataclasses import dataclass
8 from functools import cache
9 -from typing import Optional, Union
9
10 import torch
11
@@ -19,7 +18,7 @@ from vllm.utils import STR_BACKEND_ENV_VAR, resolve_obj_by_qualname
18 logger = init_logger(__name__)
19
20
22 -def get_env_variable_attn_backend() -> Optional[_Backend]:
21 +def get_env_variable_attn_backend() -> _Backend | None:
22 """
23 Get the backend override specified by the vLLM attention
24 backend environment variable, if one is specified.
@@ -40,10 +39,10 @@ def get_env_variable_attn_backend() -> Optional[_Backend]:
39 #
40 # THIS SELECTION TAKES PRECEDENCE OVER THE
41 # VLLM_ATTENTION_BACKEND ENVIRONMENT VARIABLE
43 -forced_attn_backend: Optional[_Backend] = None
42 +forced_attn_backend: _Backend | None = None
43
44
46 -def global_force_attn_backend(attn_backend: Optional[_Backend]) -> None:
45 +def global_force_attn_backend(attn_backend: _Backend | None) -> None:
46 """
47 Force all attention operations to use a specified backend.
48
@@ -58,7 +57,7 @@ def global_force_attn_backend(attn_backend: Optional[_Backend]) -> None:
57 forced_attn_backend = attn_backend
58
59
61 -def get_global_forced_attn_backend() -> Optional[_Backend]:
60 +def get_global_forced_attn_backend() -> _Backend | None:
61 """
62 Get the currently-forced choice of attention backend,
63 or None if auto-selection is currently enabled.
@@ -77,7 +76,7 @@ class _IsSupported:
76
77
78 def is_attn_backend_supported(
80 - attn_backend: Union[str, type[AttentionBackend]],
79 + attn_backend: str | type[AttentionBackend],
80 head_size: int,
81 dtype: torch.dtype,
82 *,
@@ -127,7 +126,7 @@ def is_attn_backend_supported(
126 def get_attn_backend(
127 head_size: int,
128 dtype: torch.dtype,
130 - kv_cache_dtype: Optional[str],
129 + kv_cache_dtype: str | None,
130 block_size: int,
131 use_mla: bool = False,
132 has_sink: bool = False,
@@ -154,7 +153,7 @@ def get_attn_backend(
153 def _cached_get_attn_backend(
154 head_size: int,
155 dtype: torch.dtype,
157 - kv_cache_dtype: Optional[str],
156 + kv_cache_dtype: str | None,
157 block_size: int,
158 use_v1: bool = False,
159 use_mla: bool = False,
@@ -167,12 +166,12 @@ def _cached_get_attn_backend(
166 # THIS SELECTION OVERRIDES THE VLLM_ATTENTION_BACKEND
167 # ENVIRONMENT VARIABLE.
168 selected_backend = None
170 - backend_by_global_setting: Optional[_Backend] = get_global_forced_attn_backend()
169 + backend_by_global_setting: _Backend | None = get_global_forced_attn_backend()
170 if backend_by_global_setting is not None:
171 selected_backend = backend_by_global_setting
172 else:
173 # Check the environment variable and override if specified
175 - backend_by_env_var: Optional[str] = envs.VLLM_ATTENTION_BACKEND
174 + backend_by_env_var: str | None = envs.VLLM_ATTENTION_BACKEND
175 if backend_by_env_var is not None:
176 if backend_by_env_var.endswith("_VLLM_V1"):
177 logger.warning(
vllm/attention/utils/fa_utils.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 from vllm import envs
5 from vllm.logger import init_logger
@@ -21,7 +20,7 @@ elif current_platform.is_xpu():
20 get_scheduler_metadata = ops.get_scheduler_metadata
21
22
24 -def get_flash_attn_version(requires_alibi: bool = False) -> Optional[int]:
23 +def get_flash_attn_version(requires_alibi: bool = False) -> int | None:
24 # import here to avoid circular dependencies
25 from vllm.platforms import current_platform
26
vllm/beam_search.py
+8 -8
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import TYPE_CHECKING, Any, Optional, Union
5 +from typing import TYPE_CHECKING, Any, Optional
6
7 from vllm.logprobs import Logprob
8 from vllm.lora.request import LoRARequest
@@ -22,13 +22,13 @@ class BeamSearchSequence:
22 # The tokens include the prompt.
23 tokens: list[int]
24 logprobs: list[dict[int, Logprob]]
25 - lora_request: Optional[LoRARequest] = None
25 + lora_request: LoRARequest | None = None
26 cum_logprob: float = 0.0
27 - text: Optional[str] = None
28 - finish_reason: Optional[str] = None
29 - stop_reason: Union[int, str, None] = None
27 + text: str | None = None
28 + finish_reason: str | None = None
29 + stop_reason: int | str | None = None
30 multi_modal_data: Optional["MultiModalDataDict"] = None
31 - mm_processor_kwargs: Optional[dict[str, Any]] = None
31 + mm_processor_kwargs: dict[str, Any] | None = None
32
33
34 @dataclass
@@ -45,8 +45,8 @@ class BeamSearchInstance:
45 def __init__(
46 self,
47 prompt_tokens: list[int],
48 - lora_request: Optional[LoRARequest] = None,
49 - logprobs: Optional[list[dict[int, Logprob]]] = None,
48 + lora_request: LoRARequest | None = None,
49 + logprobs: list[dict[int, Logprob]] | None = None,
50 **kwargs,
51 ):
52 self.beams: list[BeamSearchSequence] = [
vllm/benchmarks/datasets.py
+33 -33
@@ -21,13 +21,13 @@ import logging
21 import math
22 import random
23 from abc import ABC, abstractmethod
24 -from collections.abc import Iterator, Mapping
24 +from collections.abc import Callable, Iterator, Mapping
25 from contextlib import suppress
26 from copy import deepcopy
27 from dataclasses import dataclass
28 from functools import cache
29 from io import BytesIO
30 -from typing import Any, Callable, Optional, Union, cast
30 +from typing import Any, cast
31
32 import numpy as np
33 from PIL import Image
@@ -75,12 +75,12 @@ class SampleRequest:
75 Represents a single inference request for benchmarking.
76 """
77
78 - prompt: Union[str, list[str]]
78 + prompt: str | list[str]
79 prompt_len: int
80 expected_output_len: int
81 - multi_modal_data: Optional[Union[MultiModalDataDict, dict, list[dict]]] = None
82 - lora_request: Optional[LoRARequest] = None
83 - request_id: Optional[str] = None
81 + multi_modal_data: MultiModalDataDict | dict | list[dict] | None = None
82 + lora_request: LoRARequest | None = None
83 + request_id: str | None = None
84
85
86 # -----------------------------------------------------------------------------
@@ -94,7 +94,7 @@ class BenchmarkDataset(ABC):
94
95 def __init__(
96 self,
97 - dataset_path: Optional[str] = None,
97 + dataset_path: str | None = None,
98 random_seed: int = DEFAULT_SEED,
99 disable_shuffle: bool = False,
100 **kwargs,
@@ -119,7 +119,7 @@ class BenchmarkDataset(ABC):
119 def apply_multimodal_chat_transformation(
120 self,
121 prompt: str,
122 - mm_content: Optional[Union[MultiModalDataDict, dict, list[dict]]] = None,
122 + mm_content: MultiModalDataDict | dict | list[dict] | None = None,
123 ) -> list[dict]:
124 """
125 Transform a prompt and optional multimodal content into a chat format.
@@ -154,9 +154,9 @@ class BenchmarkDataset(ABC):
154
155 def get_random_lora_request(
156 self,
157 - max_loras: Optional[int] = None,
158 - lora_path: Optional[str] = None,
159 - ) -> Optional[LoRARequest]:
157 + max_loras: int | None = None,
158 + lora_path: str | None = None,
159 + ) -> LoRARequest | None:
160 """
161 Optionally select a random LoRA request.
162
@@ -384,7 +384,7 @@ def gen_prompt_decode_to_target_len(
384 target_token_len: int,
385 max_retry: int = 10,
386 add_special_tokens: bool = False,
387 - rng: Optional[np.random.Generator] = None,
387 + rng: np.random.Generator | None = None,
388 ) -> tuple[str, list[int]]:
389 """
390 Ensure decoded-then-encoded prompt length matches the target token length.
@@ -1054,9 +1054,9 @@ class ShareGPTDataset(BenchmarkDataset):
1054 self,
1055 tokenizer: PreTrainedTokenizerBase,
1056 num_requests: int,
1057 - lora_path: Optional[str] = None,
1058 - max_loras: Optional[int] = None,
1059 - output_len: Optional[int] = None,
1057 + lora_path: str | None = None,
1058 + max_loras: int | None = None,
1059 + output_len: int | None = None,
1060 enable_multimodal_chat: bool = False,
1061 request_id_prefix: str = "",
1062 no_oversample: bool = False,
@@ -1766,9 +1766,9 @@ class CustomDataset(BenchmarkDataset):
1766 self,
1767 tokenizer: PreTrainedTokenizerBase,
1768 num_requests: int,
1769 - lora_path: Optional[str] = None,
1770 - max_loras: Optional[int] = None,
1771 - output_len: Optional[int] = None,
1769 + lora_path: str | None = None,
1770 + max_loras: int | None = None,
1771 + output_len: int | None = None,
1772 enable_multimodal_chat: bool = False,
1773 skip_chat_template: bool = False,
1774 request_id_prefix: str = "",
@@ -1997,8 +1997,8 @@ class BurstGPTDataset(BenchmarkDataset):
1997 self,
1998 tokenizer: PreTrainedTokenizerBase,
1999 num_requests: int,
2000 - max_loras: Optional[int] = None,
2001 - lora_path: Optional[str] = None,
2000 + max_loras: int | None = None,
2001 + lora_path: str | None = None,
2002 request_id_prefix: str = "",
2003 no_oversample: bool = False,
2004 **kwargs,
@@ -2034,15 +2034,15 @@ class BurstGPTDataset(BenchmarkDataset):
2034 class HuggingFaceDataset(BenchmarkDataset):
2035 """Base class for datasets hosted on HuggingFace."""
2036
2037 - SUPPORTED_DATASET_PATHS: Union[set[str], dict[str, Callable]] = set()
2037 + SUPPORTED_DATASET_PATHS: set[str] | dict[str, Callable] = set()
2038
2039 def __init__(
2040 self,
2041 dataset_path: str,
2042 dataset_split: str,
2043 no_stream: bool = False,
2044 - dataset_subset: Optional[str] = None,
2045 - hf_name: Optional[str] = None,
2044 + dataset_subset: str | None = None,
2045 + hf_name: str | None = None,
2046 **kwargs,
2047 ) -> None:
2048 super().__init__(dataset_path=dataset_path, **kwargs)
@@ -2083,7 +2083,7 @@ class ConversationDataset(HuggingFaceDataset):
2083 self,
2084 tokenizer: PreTrainedTokenizerBase,
2085 num_requests: int,
2086 - output_len: Optional[int] = None,
2086 + output_len: int | None = None,
2087 enable_multimodal_chat: bool = False,
2088 request_id_prefix: str = "",
2089 no_oversample: bool = False,
@@ -2152,7 +2152,7 @@ class VisionArenaDataset(HuggingFaceDataset):
2152 self,
2153 tokenizer: PreTrainedTokenizerBase,
2154 num_requests: int,
2155 - output_len: Optional[int] = None,
2155 + output_len: int | None = None,
2156 enable_multimodal_chat: bool = False,
2157 request_id_prefix: str = "",
2158 no_oversample: bool = False,
@@ -2206,7 +2206,7 @@ class MMVUDataset(HuggingFaceDataset):
2206 self,
2207 tokenizer: PreTrainedTokenizerBase,
2208 num_requests: int,
2209 - output_len: Optional[int] = None,
2209 + output_len: int | None = None,
2210 enable_multimodal_chat: bool = False,
2211 request_id_prefix: str = "",
2212 no_oversample: bool = False,
@@ -2267,7 +2267,7 @@ class InstructCoderDataset(HuggingFaceDataset):
2267 self,
2268 tokenizer: PreTrainedTokenizerBase,
2269 num_requests: int,
2270 - output_len: Optional[int] = None,
2270 + output_len: int | None = None,
2271 enable_multimodal_chat: bool = False,
2272 skip_chat_template: bool = False,
2273 request_id_prefix: str = "",
@@ -2331,7 +2331,7 @@ class MTBenchDataset(HuggingFaceDataset):
2331 self,
2332 tokenizer: PreTrainedTokenizerBase,
2333 num_requests: int,
2334 - output_len: Optional[int] = None,
2334 + output_len: int | None = None,
2335 enable_multimodal_chat: bool = False,
2336 skip_chat_template: bool = False,
2337 request_id_prefix: str = "",
@@ -2397,7 +2397,7 @@ class BlazeditDataset(HuggingFaceDataset):
2397 self,
2398 tokenizer: PreTrainedTokenizerBase,
2399 num_requests: int,
2400 - output_len: Optional[int] = None,
2400 + output_len: int | None = None,
2401 skip_chat_template: bool = False,
2402 request_id_prefix: str = "",
2403 no_oversample: bool = False,
@@ -2478,7 +2478,7 @@ class AIMODataset(HuggingFaceDataset):
2478 self,
2479 tokenizer: PreTrainedTokenizerBase,
2480 num_requests: int,
2481 - output_len: Optional[int] = None,
2481 + output_len: int | None = None,
2482 request_id_prefix: str = "",
2483 no_oversample: bool = False,
2484 **kwargs,
@@ -2660,7 +2660,7 @@ class ASRDataset(HuggingFaceDataset):
2660 self,
2661 tokenizer: PreTrainedTokenizerBase,
2662 num_requests: int,
2663 - output_len: Optional[int] = None,
2663 + output_len: int | None = None,
2664 request_id_prefix: str = "",
2665 no_oversample: bool = False,
2666 **kwargs,
@@ -2738,7 +2738,7 @@ class MLPerfDataset(HuggingFaceDataset):
2738 self,
2739 tokenizer: PreTrainedTokenizerBase,
2740 num_requests: int,
2741 - output_len: Optional[int] = None,
2741 + output_len: int | None = None,
2742 request_id_prefix: str = "",
2743 no_oversample: bool = False,
2744 **kwargs,
@@ -2902,7 +2902,7 @@ class MMStarDataset(HuggingFaceDataset):
2902 self,
2903 tokenizer: PreTrainedTokenizerBase,
2904 num_requests: int,
2905 - output_len: Optional[int] = None,
2905 + output_len: int | None = None,
2906 enable_multimodal_chat: bool = False,
2907 request_id_prefix: str = "",
2908 no_oversample: bool = False,
vllm/benchmarks/latency.py
+2 -2
@@ -7,7 +7,7 @@ import dataclasses
7 import json
8 import os
9 import time
10 -from typing import Any, Optional
10 +from typing import Any
11
12 import numpy as np
13 from tqdm import tqdm
@@ -127,7 +127,7 @@ def main(args: argparse.Namespace):
127 ),
128 )
129
130 - def run_to_completion(profile_dir: Optional[str] = None):
130 + def run_to_completion(profile_dir: str | None = None):
131 if profile_dir:
132 llm.start_profile()
133 llm_generate()
vllm/benchmarks/lib/endpoint_request_func.py
+20 -20
@@ -10,7 +10,7 @@ import time
10 import traceback
11 from collections.abc import Awaitable
12 from dataclasses import dataclass, field
13 -from typing import Any, Literal, Optional, Protocol, Union
13 +from typing import Any, Literal, Protocol
14
15 import aiohttp
16 import regex as re
@@ -69,14 +69,14 @@ class RequestFuncInput:
69 prompt_len: int
70 output_len: int
71 model: str
72 - model_name: Optional[str] = None
73 - logprobs: Optional[int] = None
74 - extra_headers: Optional[dict] = None
75 - extra_body: Optional[dict] = None
76 - multi_modal_content: Optional[Union[dict, list[dict]]] = None
72 + model_name: str | None = None
73 + logprobs: int | None = None
74 + extra_headers: dict | None = None
75 + extra_body: dict | None = None
76 + multi_modal_content: dict | list[dict] | None = None
77 ignore_eos: bool = False
78 - language: Optional[str] = None
79 - request_id: Optional[str] = None
78 + language: str | None = None
79 + request_id: str | None = None
80
81
82 @dataclass
@@ -100,14 +100,14 @@ class RequestFunc(Protocol):
100 self,
101 request_func_input: RequestFuncInput,
102 session: aiohttp.ClientSession,
103 - pbar: Optional[tqdm] = None,
103 + pbar: tqdm | None = None,
104 ) -> Awaitable[RequestFuncOutput]: ...
105
106
107 def _validate_api_url(
108 api_url: str,
109 api_name: str,
110 - expected_suffixes: Union[str, set[str]],
110 + expected_suffixes: str | set[str],
111 ) -> None:
112 if isinstance(expected_suffixes, str):
113 expected_suffixes = {expected_suffixes}
@@ -141,7 +141,7 @@ def _update_headers_common(
141 async def async_request_openai_completions(
142 request_func_input: RequestFuncInput,
143 session: aiohttp.ClientSession,
144 - pbar: Optional[tqdm] = None,
144 + pbar: tqdm | None = None,
145 ) -> RequestFuncOutput:
146 """The async request function for the OpenAI Completions API.
147
@@ -279,7 +279,7 @@ def _get_chat_content(
279 async def async_request_openai_chat_completions(
280 request_func_input: RequestFuncInput,
281 session: aiohttp.ClientSession,
282 - pbar: Optional[tqdm] = None,
282 + pbar: tqdm | None = None,
283 mm_position: Literal["first", "last"] = "last",
284 ) -> RequestFuncOutput:
285 api_url = request_func_input.api_url
@@ -376,7 +376,7 @@ async def async_request_openai_chat_completions(
376 async def async_request_openai_audio(
377 request_func_input: RequestFuncInput,
378 session: aiohttp.ClientSession,
379 - pbar: Optional[tqdm] = None,
379 + pbar: tqdm | None = None,
380 ) -> RequestFuncOutput:
381 # Lazy import without PlaceholderModule to avoid vllm dep.
382 import soundfile
@@ -489,7 +489,7 @@ async def _run_openai_embeddings(
489 api_url: str,
490 payload: dict[str, Any],
491 headers: dict[str, Any],
492 - pbar: Optional[tqdm] = None,
492 + pbar: tqdm | None = None,
493 ) -> RequestFuncOutput:
494 output = RequestFuncOutput()
495 st = time.perf_counter()
@@ -517,7 +517,7 @@ async def _run_openai_embeddings(
517 async def async_request_openai_embeddings(
518 request_func_input: RequestFuncInput,
519 session: aiohttp.ClientSession,
520 - pbar: Optional[tqdm] = None,
520 + pbar: tqdm | None = None,
521 ) -> RequestFuncOutput:
522 api_url = request_func_input.api_url
523 _validate_api_url(api_url, "OpenAI Embeddings API", "embeddings")
@@ -548,7 +548,7 @@ async def async_request_openai_embeddings(
548 async def async_request_openai_embeddings_chat(
549 request_func_input: RequestFuncInput,
550 session: aiohttp.ClientSession,
551 - pbar: Optional[tqdm] = None,
551 + pbar: tqdm | None = None,
552 mm_position: Literal["first", "last"] = "last",
553 ) -> RequestFuncOutput:
554 api_url = request_func_input.api_url
@@ -627,7 +627,7 @@ def _preprocess_vlm2vec(request_func_input: RequestFuncInput):
627 async def async_request_openai_embeddings_clip(
628 request_func_input: RequestFuncInput,
629 session: aiohttp.ClientSession,
630 - pbar: Optional[tqdm] = None,
630 + pbar: tqdm | None = None,
631 ) -> RequestFuncOutput:
632 _preprocess_clip(request_func_input)
633
@@ -641,7 +641,7 @@ async def async_request_openai_embeddings_clip(
641 async def async_request_openai_embeddings_vlm2vec(
642 request_func_input: RequestFuncInput,
643 session: aiohttp.ClientSession,
644 - pbar: Optional[tqdm] = None,
644 + pbar: tqdm | None = None,
645 ) -> RequestFuncOutput:
646 _preprocess_vlm2vec(request_func_input)
647
@@ -656,7 +656,7 @@ async def async_request_openai_embeddings_vlm2vec(
656 async def async_request_infinity_embeddings(
657 request_func_input: RequestFuncInput,
658 session: aiohttp.ClientSession,
659 - pbar: Optional[tqdm] = None,
659 + pbar: tqdm | None = None,
660 ) -> RequestFuncOutput:
661 api_url = request_func_input.api_url
662 _validate_api_url(api_url, "Infinity Embeddings API", "embeddings")
@@ -697,7 +697,7 @@ async def async_request_infinity_embeddings(
697 async def async_request_infinity_embeddings_clip(
698 request_func_input: RequestFuncInput,
699 session: aiohttp.ClientSession,
700 - pbar: Optional[tqdm] = None,
700 + pbar: tqdm | None = None,
701 ) -> RequestFuncOutput:
702 _preprocess_clip(request_func_input)
703
vllm/benchmarks/serve.py
+15 -15
@@ -31,7 +31,7 @@ from collections.abc import AsyncGenerator, Iterable
31 from dataclasses import dataclass
32 from datetime import datetime
33 from enum import Enum
34 -from typing import Any, Literal, Optional
34 +from typing import Any, Literal
35
36 import aiohttp
37 import numpy as np
@@ -107,9 +107,9 @@ class EmbedBenchmarkMetrics:
107
108
109 def _get_current_request_rate(
110 - ramp_up_strategy: Optional[Literal["linear", "exponential"]],
111 - ramp_up_start_rps: Optional[int],
112 - ramp_up_end_rps: Optional[int],
110 + ramp_up_strategy: Literal["linear", "exponential"] | None,
111 + ramp_up_start_rps: int | None,
112 + ramp_up_end_rps: int | None,
113 request_index: int,
114 total_requests: int,
115 request_rate: float,
@@ -135,9 +135,9 @@ async def get_request(
135 input_requests: list[SampleRequest],
136 request_rate: float,
137 burstiness: float = 1.0,
138 - ramp_up_strategy: Optional[Literal["linear", "exponential"]] = None,
139 - ramp_up_start_rps: Optional[int] = None,
140 - ramp_up_end_rps: Optional[int] = None,
138 + ramp_up_strategy: Literal["linear", "exponential"] | None = None,
139 + ramp_up_start_rps: int | None = None,
140 + ramp_up_end_rps: int | None = None,
141 ) -> AsyncGenerator[tuple[SampleRequest, float], None]:
142 """
143 Asynchronously generates requests at a specified rate
@@ -474,7 +474,7 @@ async def benchmark(
474 model_name: str,
475 tokenizer: PreTrainedTokenizerBase,
476 input_requests: list[SampleRequest],
477 - logprobs: Optional[int],
477 + logprobs: int | None,
478 request_rate: float,
479 burstiness: float,
480 disable_tqdm: bool,
@@ -483,13 +483,13 @@ async def benchmark(
483 selected_percentiles: list[float],
484 ignore_eos: bool,
485 goodput_config_dict: dict[str, float],
486 - max_concurrency: Optional[int],
487 - lora_modules: Optional[Iterable[str]],
488 - extra_headers: Optional[dict],
489 - extra_body: Optional[dict],
490 - ramp_up_strategy: Optional[Literal["linear", "exponential"]] = None,
491 - ramp_up_start_rps: Optional[int] = None,
492 - ramp_up_end_rps: Optional[int] = None,
486 + max_concurrency: int | None,
487 + lora_modules: Iterable[str] | None,
488 + extra_headers: dict | None,
489 + extra_body: dict | None,
490 + ramp_up_strategy: Literal["linear", "exponential"] | None = None,
491 + ramp_up_start_rps: int | None = None,
492 + ramp_up_end_rps: int | None = None,
493 ready_check_timeout_sec: int = 600,
494 ):
495 try:
vllm/benchmarks/throughput.py
+7 -7
@@ -9,7 +9,7 @@ import os
9 import random
10 import time
11 import warnings
12 -from typing import Any, Optional, Union
12 +from typing import Any
13
14 import torch
15 import uvloop
@@ -43,7 +43,7 @@ def run_vllm(
43 engine_args: EngineArgs,
44 do_profile: bool,
45 disable_detokenize: bool = False,
46 -) -> tuple[float, Optional[list[RequestOutput]]]:
46 +) -> tuple[float, list[RequestOutput] | None]:
47 from vllm import LLM, SamplingParams
48
49 llm = LLM(**dataclasses.asdict(engine_args))
@@ -56,7 +56,7 @@ def run_vllm(
56 " prompt_len and expected_output_len for all requests."
57 )
58 # Add the requests to the engine.
59 - prompts: list[Union[TextPrompt, TokensPrompt]] = []
59 + prompts: list[TextPrompt | TokensPrompt] = []
60 sampling_params: list[SamplingParams] = []
61 for request in requests:
62 prompt = (
@@ -79,7 +79,7 @@ def run_vllm(
79 detokenize=not disable_detokenize,
80 )
81 )
82 - lora_requests: Optional[list[LoRARequest]] = None
82 + lora_requests: list[LoRARequest] | None = None
83 if engine_args.enable_lora:
84 lora_requests = [request.lora_request for request in requests]
85
@@ -197,9 +197,9 @@ async def run_vllm_async(
197 )
198
199 # Add the requests to the engine.
200 - prompts: list[Union[TextPrompt, TokensPrompt]] = []
200 + prompts: list[TextPrompt | TokensPrompt] = []
201 sampling_params: list[SamplingParams] = []
202 - lora_requests: list[Optional[LoRARequest]] = []
202 + lora_requests: list[LoRARequest | None] = []
203 for request in requests:
204 prompt = (
205 TokensPrompt(prompt_token_ids=request.prompt["prompt_token_ids"])
@@ -696,7 +696,7 @@ def main(args: argparse.Namespace):
696 )
697 requests = get_requests(args, tokenizer)
698 is_multi_modal = any(request.multi_modal_data is not None for request in requests)
699 - request_outputs: Optional[list[RequestOutput]] = None
699 + request_outputs: list[RequestOutput] | None = None
700 if args.backend == "vllm":
701 if args.async_engine:
702 elapsed_time = uvloop.run(
vllm/compilation/backends.py
+9 -8
@@ -7,9 +7,9 @@ import hashlib
7 import os
8 import pprint
9 import time
10 -from collections.abc import Sequence
10 +from collections.abc import Callable, Sequence
11 from contextlib import contextmanager
12 -from typing import Any, Callable, Optional
12 +from typing import Any
13
14 import torch
15 import torch.fx as fx
@@ -75,7 +75,7 @@ class CompilerManager:
75 """
76
77 def __init__(self, compilation_config: CompilationConfig):
78 - self.cache: dict[tuple[Optional[int], int, str], Any] = dict()
78 + self.cache: dict[tuple[int | None, int, str], Any] = dict()
79 self.is_cache_updated = False
80 self.compilation_config = compilation_config
81 self.compiler = make_compiler(compilation_config)
@@ -84,7 +84,7 @@ class CompilerManager:
84 return self.compiler.compute_hash(vllm_config)
85
86 @contextmanager
87 - def compile_context(self, runtime_shape: Optional[int] = None):
87 + def compile_context(self, runtime_shape: int | None = None):
88 """Provide compilation context for the duration of compilation to set
89 any torch global properties we want to scope to a single Inductor
90 compilation (e.g. partition rules, pass context)."""
@@ -145,8 +145,8 @@ class CompilerManager:
145 graph: fx.GraphModule,
146 example_inputs: list[Any],
147 graph_index: int,
148 - runtime_shape: Optional[int] = None,
149 - ) -> Optional[Callable]:
148 + runtime_shape: int | None = None,
149 + ) -> Callable | None:
150 if (runtime_shape, graph_index, self.compiler.name) not in self.cache:
151 return None
152 handle = self.cache[(runtime_shape, graph_index, self.compiler.name)]
@@ -178,7 +178,7 @@ class CompilerManager:
178 compilation_config: CompilationConfig,
179 graph_index: int = 0,
180 num_graphs: int = 1,
181 - runtime_shape: Optional[int] = None,
181 + runtime_shape: int | None = None,
182 ) -> Any:
183 if graph_index == 0:
184 # before compiling the first graph, record the start time
@@ -656,7 +656,8 @@ class VllmBackend:
656
657 graph_path = os.path.join(local_cache_dir, "computation_graph.py")
658 if not os.path.exists(graph_path):
659 - # code adapted from https://github.com/thuml/depyf/blob/dab831108a752d1facc00acdd6d4243891845c37/depyf/explain/patched_lazy_format_graph_code.py#L30 # noqa
659 + # code adapted from
660 + # https://github.com/thuml/depyf/blob/dab831108a752d1facc00acdd6d4243891845c37/depyf/explain/patched_lazy_format_graph_code.py#L30
661 # use `print_readable` because it can include submodules
662 src = (
663 "from __future__ import annotations\nimport torch\n"
vllm/compilation/base_static_graph.py
+2 -1
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Protocol
4 +from collections.abc import Callable
5 +from typing import Any, Protocol
6
7 from vllm.config import CUDAGraphMode, VllmConfig
8
vllm/compilation/collective_fusion.py
+9 -10
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from importlib.util import find_spec
4 -from typing import Optional
4
5 import torch
6 import torch._inductor.pattern_matcher as pm
@@ -432,7 +431,7 @@ class AsyncTPPass(VllmPatternMatcherPass):
431
432 self.dump_patterns(config, self.patterns)
433
435 - def is_applicable_for_shape(self, shape: Optional[int]) -> bool:
434 + def is_applicable_for_shape(self, shape: int | None) -> bool:
435 # only do replace for specific shapes
436 tp_size = get_tensor_model_parallel_world_size()
437 return shape is not None and shape % tp_size == 0
@@ -485,10 +484,10 @@ if flashinfer_comm is not None:
484 max_token_num: int,
485 pattern_code: int,
486 fuse_rms_quant: bool,
488 - norm_out: Optional[torch.Tensor] = None,
489 - quant_out: Optional[torch.Tensor] = None,
490 - scale_out: Optional[torch.Tensor] = None,
491 - scale_factor: Optional[torch.Tensor] = None,
487 + norm_out: torch.Tensor | None = None,
488 + quant_out: torch.Tensor | None = None,
489 + scale_out: torch.Tensor | None = None,
490 + scale_factor: torch.Tensor | None = None,
491 ) -> None:
492 num_tokens, hidden_size = allreduce_in.shape
493 element_size = allreduce_in.element_size()
@@ -589,10 +588,10 @@ if flashinfer_comm is not None:
588 max_token_num: int,
589 pattern_code: int,
590 fuse_rms_quant: bool,
592 - norm_out: Optional[torch.Tensor] = None,
593 - quant_out: Optional[torch.Tensor] = None,
594 - scale_out: Optional[torch.Tensor] = None,
595 - scale_factor: Optional[torch.Tensor] = None,
591 + norm_out: torch.Tensor | None = None,
592 + quant_out: torch.Tensor | None = None,
593 + scale_out: torch.Tensor | None = None,
594 + scale_factor: torch.Tensor | None = None,
595 ) -> None:
596 pass
597
vllm/compilation/compiler_interface.py
+17 -16
@@ -4,8 +4,9 @@ import contextlib
4 import copy
5 import hashlib
6 import os
7 +from collections.abc import Callable
8 from contextlib import ExitStack
8 -from typing import Any, Callable, Optional
9 +from typing import Any
10 from unittest.mock import patch
11
12 import torch
@@ -62,9 +63,9 @@ class CompilerInterface:
63 graph: fx.GraphModule,
64 example_inputs: list[Any],
65 compiler_config: dict[str, Any],
65 - runtime_shape: Optional[int] = None,
66 - key: Optional[str] = None,
67 - ) -> tuple[Optional[Callable], Optional[Any]]:
66 + runtime_shape: int | None = None,
67 + key: str | None = None,
68 + ) -> tuple[Callable | None, Any | None]:
69 """
70 Compile the graph with the given example inputs and compiler config,
71 with a runtime shape. If the `runtime_shape` is None, it means
@@ -97,7 +98,7 @@ class CompilerInterface:
98 graph: fx.GraphModule,
99 example_inputs: list[Any],
100 graph_index: int,
100 - runtime_shape: Optional[int] = None,
101 + runtime_shape: int | None = None,
102 ) -> Callable:
103 """
104 Load the compiled function from the handle.
@@ -191,9 +192,9 @@ class InductorStandaloneAdaptor(CompilerInterface):
192 graph: fx.GraphModule,
193 example_inputs: list[Any],
194 compiler_config: dict[str, Any],
194 - runtime_shape: Optional[int] = None,
195 - key: Optional[str] = None,
196 - ) -> tuple[Optional[Callable], Optional[Any]]:
195 + runtime_shape: int | None = None,
196 + key: str | None = None,
197 + ) -> tuple[Callable | None, Any | None]:
198 compilation_counter.num_inductor_compiles += 1
199 current_config = {}
200 if compiler_config is not None:
@@ -229,7 +230,7 @@ class InductorStandaloneAdaptor(CompilerInterface):
230 graph: fx.GraphModule,
231 example_inputs: list[Any],
232 graph_index: int,
232 - runtime_shape: Optional[int] = None,
233 + runtime_shape: int | None = None,
234 ) -> Callable:
235 assert isinstance(handle, tuple)
236 assert isinstance(handle[0], str)
@@ -293,9 +294,9 @@ class InductorAdaptor(CompilerInterface):
294 graph: fx.GraphModule,
295 example_inputs: list[Any],
296 compiler_config: dict[str, Any],
296 - runtime_shape: Optional[int] = None,
297 - key: Optional[str] = None,
298 - ) -> tuple[Optional[Callable], Optional[Any]]:
297 + runtime_shape: int | None = None,
298 + key: str | None = None,
299 + ) -> tuple[Callable | None, Any | None]:
300 compilation_counter.num_inductor_compiles += 1
301 from torch._inductor.compile_fx import compile_fx
302
@@ -492,7 +493,7 @@ class InductorAdaptor(CompilerInterface):
493 graph: fx.GraphModule,
494 example_inputs: list[Any],
495 graph_index: int,
495 - runtime_shape: Optional[int] = None,
496 + runtime_shape: int | None = None,
497 ) -> Callable:
498 assert isinstance(handle, tuple)
499 assert isinstance(handle[0], str)
@@ -610,9 +611,9 @@ class EagerAdaptor(CompilerInterface):
611 graph: fx.GraphModule,
612 example_inputs: list[Any],
613 compiler_config: dict[str, Any],
613 - runtime_shape: Optional[int] = None,
614 - key: Optional[str] = None,
615 - ) -> tuple[Optional[Callable], Optional[Any]]:
614 + runtime_shape: int | None = None,
615 + key: str | None = None,
616 + ) -> tuple[Callable | None, Any | None]:
617 compilation_counter.num_eager_compiles += 1
618 # we don't need to compile the graph, just return the graph itself.
619 # It does not support caching, return None for the handle.
vllm/compilation/cuda_graph.py
+6 -5
@@ -2,8 +2,9 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import dataclasses
5 +from collections.abc import Callable
6 from contextlib import ExitStack
6 -from typing import Any, Callable, Optional
7 +from typing import Any
8 from unittest.mock import patch
9
10 import torch
@@ -24,12 +25,12 @@ logger = init_logger(__name__)
25 @dataclasses.dataclass
26 class CUDAGraphEntry:
27 batch_descriptor: BatchDescriptor
27 - cudagraph: Optional[torch.cuda.CUDAGraph] = None
28 - output: Optional[Any] = None
28 + cudagraph: torch.cuda.CUDAGraph | None = None
29 + output: Any | None = None
30
31 # for cudagraph debugging, track the input addresses
32 # during capture, and check if they are the same during replay
32 - input_addresses: Optional[list[int]] = None
33 + input_addresses: list[int] | None = None
34
35
36 @dataclasses.dataclass
@@ -69,7 +70,7 @@ class CUDAGraphWrapper:
70 runnable: Callable,
71 vllm_config: VllmConfig,
72 runtime_mode: CUDAGraphMode,
72 - cudagraph_options: Optional[CUDAGraphOptions] = None,
73 + cudagraph_options: CUDAGraphOptions | None = None,
74 ):
75 self.runnable = runnable
76 self.vllm_config = vllm_config
vllm/compilation/decorators.py
+12 -11
@@ -6,7 +6,8 @@ import hashlib
6 import inspect
7 import os
8 import sys
9 -from typing import Callable, Optional, TypeVar, Union, overload
9 +from collections.abc import Callable
10 +from typing import TypeVar, overload
11 from unittest.mock import patch
12
13 import torch
@@ -61,14 +62,14 @@ def _should_ignore_torch_compile(cls) -> bool:
62 @overload
63 def support_torch_compile(
64 *,
64 - enable_if: Optional[Callable[[VllmConfig], bool]] = None,
65 + enable_if: Callable[[VllmConfig], bool] | None = None,
66 ) -> Callable[[_T], _T]: ...
67
68
69 @overload
70 def support_torch_compile(
71 *,
71 - dynamic_arg_dims: Optional[dict[str, Union[int, list[int]]]],
72 + dynamic_arg_dims: dict[str, int | list[int]] | None,
73 ) -> Callable[[_T], _T]: ...
74
75
@@ -77,11 +78,11 @@ def support_torch_compile(cls: _T) -> _T: ...
78
79
80 def support_torch_compile(
80 - cls: Optional[_T] = None,
81 + cls: _T | None = None,
82 *,
82 - dynamic_arg_dims: Optional[dict[str, Union[int, list[int]]]] = None,
83 - enable_if: Optional[Callable[[VllmConfig], bool]] = None,
84 -) -> Union[Callable[[_T], _T], _T]:
83 + dynamic_arg_dims: dict[str, int | list[int]] | None = None,
84 + enable_if: Callable[[VllmConfig], bool] | None = None,
85 +) -> Callable[[_T], _T] | _T:
86 """
87 A decorator to add support for compiling the forward method of a class.
88
@@ -147,9 +148,9 @@ def support_torch_compile(
148 for k, v in sig.parameters.items():
149 if v.annotation in [
150 torch.Tensor,
150 - Optional[torch.Tensor],
151 + torch.Tensor | None,
152 IntermediateTensors,
152 - Optional[IntermediateTensors],
153 + IntermediateTensors | None,
154 ]:
155 inferred_dynamic_arg_dims[k] = 0
156
@@ -209,8 +210,8 @@ def _verify_source_unchanged(source_info, vllm_config) -> None:
210
211 def _support_torch_compile(
212 cls: _T,
212 - dynamic_arg_dims: dict[str, Union[int, list[int]]],
213 - enable_if: Optional[Callable[[VllmConfig], bool]] = None,
213 + dynamic_arg_dims: dict[str, int | list[int]],
214 + enable_if: Callable[[VllmConfig], bool] | None = None,
215 ) -> _T:
216 """
217 A decorator to add support for compiling the forward method of a class.
vllm/compilation/fix_functionalization.py
+5 -6
@@ -3,7 +3,6 @@
3
4 import operator
5 from collections.abc import Iterable
6 -from typing import Optional, Union
6
7 import torch
8 from torch._higher_order_ops.auto_functionalize import auto_functionalized
@@ -150,7 +149,7 @@ class FixFunctionalizationPass(VllmInductorPass):
149 )
150 self.nodes_to_remove.clear()
151
153 - def _remove(self, node_or_nodes: Union[torch.fx.Node, Iterable[torch.fx.Node]]):
152 + def _remove(self, node_or_nodes: torch.fx.Node | Iterable[torch.fx.Node]):
153 """
154 Stage a node (or nodes) for removal at the end of the pass.
155 """
@@ -163,8 +162,8 @@ class FixFunctionalizationPass(VllmInductorPass):
162 self,
163 graph: torch.fx.Graph,
164 node: torch.fx.Node,
166 - mutated_args: dict[int, Union[torch.fx.Node, str]],
167 - args: Optional[tuple[Union[torch.fx.Node, str], ...]] = None,
165 + mutated_args: dict[int, torch.fx.Node | str],
166 + args: tuple[torch.fx.Node | str, ...] | None = None,
167 ):
168 """
169 De-functionalize a node by replacing it with a call to the original.
@@ -176,7 +175,7 @@ class FixFunctionalizationPass(VllmInductorPass):
175 self._remove(node)
176
177 def replace_users_with_mutated_args(
179 - self, node: torch.fx.Node, mutated_args: dict[int, Union[torch.fx.Node, str]]
178 + self, node: torch.fx.Node, mutated_args: dict[int, torch.fx.Node | str]
179 ):
180 """
181 Replace all getitem users of the auto-functionalized node with the
@@ -207,7 +206,7 @@ class FixFunctionalizationPass(VllmInductorPass):
206 self,
207 graph: torch.fx.Graph,
208 node: torch.fx.Node,
210 - args: Optional[tuple[Union[torch.fx.Node, str], ...]] = None,
209 + args: tuple[torch.fx.Node | str, ...] | None = None,
210 ):
211 """
212 Insert a new defunctionalized node into the graph before node.
vllm/compilation/fx_utils.py
+3 -6
@@ -3,7 +3,6 @@
3
4 import operator
5 from collections.abc import Iterable, Iterator
6 -from typing import Optional
6
7 from torch import fx
8 from torch._higher_order_ops.auto_functionalize import auto_functionalized
@@ -19,9 +18,7 @@ def is_auto_func(node: fx.Node, op: OpOverload) -> bool:
18
19
20 # Returns the first specified node with the given op (if it exists)
22 -def find_specified_fn_maybe(
23 - nodes: Iterable[fx.Node], op: OpOverload
24 -) -> Optional[fx.Node]:
21 +def find_specified_fn_maybe(nodes: Iterable[fx.Node], op: OpOverload) -> fx.Node | None:
22 for node in nodes:
23 if node.target == op:
24 return node
@@ -36,7 +33,7 @@ def find_specified_fn(nodes: Iterable[fx.Node], op: OpOverload) -> fx.Node:
33
34
35 # Returns the first auto_functionalized node with the given op (if it exists)
39 -def find_auto_fn_maybe(nodes: Iterable[fx.Node], op: OpOverload) -> Optional[fx.Node]:
36 +def find_auto_fn_maybe(nodes: Iterable[fx.Node], op: OpOverload) -> fx.Node | None:
37 for node in nodes:
38 if is_func(node, auto_functionalized) and node.args[0] == op: # noqa
39 return node
@@ -52,7 +49,7 @@ def find_auto_fn(nodes: Iterable[fx.Node], op: OpOverload) -> fx.Node:
49
50 # Returns the getitem node that extracts the idx-th element from node
51 # (if it exists)
55 -def find_getitem_maybe(node: fx.Node, idx: int) -> Optional[fx.Node]:
52 +def find_getitem_maybe(node: fx.Node, idx: int) -> fx.Node | None:
53 for user in node.users:
54 if is_func(user, operator.getitem) and user.args[1] == idx:
55 return user
vllm/compilation/inductor_pass.py
+7 -8
@@ -6,8 +6,9 @@ import hashlib
6 import inspect
7 import json
8 import types
9 +from collections.abc import Callable
10 from contextlib import contextmanager
10 -from typing import Any, Callable, Optional, Union
11 +from typing import Any
12
13 import torch
14 from torch import fx
@@ -27,7 +28,7 @@ _pass_context = None
28
29
30 class PassContext:
30 - def __init__(self, runtime_shape: Optional[int]):
31 + def __init__(self, runtime_shape: int | None):
32 self.runtime_shape = runtime_shape
33
34
@@ -38,7 +39,7 @@ def get_pass_context() -> PassContext:
39
40
41 @contextmanager
41 -def pass_context(runtime_shape: Optional[int]):
42 +def pass_context(runtime_shape: int | None):
43 """A context manager that stores the current pass context,
44 usually it is a list of sizes to specialize.
45 """
@@ -67,7 +68,7 @@ class InductorPass(CustomGraphPass):
68 return InductorPass.hash_source(self)
69
70 @staticmethod
70 - def hash_source(*srcs: Union[str, Any]):
71 + def hash_source(*srcs: str | Any):
72 """
73 Utility method to hash the sources of functions or objects.
74 :param srcs: strings or objects to add to the hash.
@@ -95,7 +96,7 @@ class InductorPass(CustomGraphPass):
96 encoded = json.dumps(dict_, sort_keys=True).encode("utf-8")
97 return hashlib.sha256(encoded).hexdigest()
98
98 - def is_applicable_for_shape(self, shape: Optional[int]):
99 + def is_applicable_for_shape(self, shape: int | None):
100 return True
101
102
@@ -105,9 +106,7 @@ class CallableInductorPass(InductorPass):
106 implementation of the UUID.
107 """
108
108 - def __init__(
109 - self, callable: Callable[[fx.Graph], None], uuid: Optional[Any] = None
110 - ):
109 + def __init__(self, callable: Callable[[fx.Graph], None], uuid: Any | None = None):
110 self.callable = callable
111 self._uuid = self.hash_source(callable) if uuid is None else uuid
112
vllm/compilation/noop_elimination.py
+2 -5
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable
5 -from typing import Union
5
6 import torch.fx
7 from torch import SymInt
@@ -105,9 +104,7 @@ class NoOpEliminationPass(VllmInductorPass):
104 logger.debug("Removed %s no-op reshapes and slices", count)
105
106 # ---------------------- Shape comparison helpers ----------------------
108 - def dims_equivalent(
109 - self, dim: Union[int, SymInt], i_dim: Union[int, SymInt]
110 - ) -> bool:
107 + def dims_equivalent(self, dim: int | SymInt, i_dim: int | SymInt) -> bool:
108 """
109 This function checks if two dimensions are equivalent.
110 :param dim: The dimension arg to reshape/slice
@@ -127,7 +124,7 @@ class NoOpEliminationPass(VllmInductorPass):
124 return False
125
126 def all_dims_equivalent(
130 - self, dims: Iterable[Union[int, SymInt]], i_dims: Iterable[Union[int, SymInt]]
127 + self, dims: Iterable[int | SymInt], i_dims: Iterable[int | SymInt]
128 ) -> bool:
129 dims_ = list(dims)
130 i_dims_ = list(i_dims)
vllm/compilation/partition_rules.py
+2 -4
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import contextlib
5 from typing import TYPE_CHECKING
6
@@ -16,7 +14,7 @@ if TYPE_CHECKING:
14 logger = init_logger(__name__)
15
16
19 -def resolve_defined_ops(op_names: list[str]) -> list[torch._ops.OpOverload]:
17 +def resolve_defined_ops(op_names: list[str]) -> list["torch._ops.OpOverload"]:
18 """Resolve operator names to OpOverload objects.
19
20 Skips operators that fail to resolve (e.g., operators not registered or
@@ -49,7 +47,7 @@ def resolve_defined_ops(op_names: list[str]) -> list[torch._ops.OpOverload]:
47
48
49 @contextlib.contextmanager
52 -def inductor_partition_rule_context(overloads: list[torch._ops.OpOverload]):
50 +def inductor_partition_rule_context(overloads: list["torch._ops.OpOverload"]):
51 """Context manager to temporarily register Inductor partition rules.
52
53 Registers custom partition rules for specified operators, forcing the
vllm/compilation/piecewise_backend.py
+2 -1
@@ -2,7 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import dataclasses
5 -from typing import Any, Callable
5 +from collections.abc import Callable
6 +from typing import Any
7
8 import torch.fx as fx
9
vllm/compilation/sequence_parallelism.py
+3 -4
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5 import torch._inductor.pattern_matcher as pm
@@ -27,7 +26,7 @@ class _RMSNormAndQuantOpHelper:
26 epsilon: float,
27 dtype: torch.dtype,
28 device: str,
30 - quant_op: Optional[torch._ops.OpOverload] = None,
29 + quant_op: torch._ops.OpOverload | None = None,
30 **kwargs,
31 ):
32 self.epsilon = epsilon
@@ -110,7 +109,7 @@ class _SequenceParallelPatternHelper(_RMSNormAndQuantOpHelper):
109 epsilon: float,
110 dtype: torch.dtype,
111 device: str,
113 - quant_op: Optional[torch._ops.OpOverload] = None,
112 + quant_op: torch._ops.OpOverload | None = None,
113 **kwargs,
114 ):
115 super().__init__(epsilon, dtype, device, quant_op=quant_op, **kwargs)
@@ -483,7 +482,7 @@ class SequenceParallelismPass(VllmPatternMatcherPass):
482 ).register(self.patterns)
483 self.dump_patterns(config, self.patterns)
484
486 - def is_applicable_for_shape(self, shape: Optional[int]) -> bool:
485 + def is_applicable_for_shape(self, shape: int | None) -> bool:
486 tp_size = get_tensor_model_parallel_world_size()
487 return shape is not None and shape % tp_size == 0
488
vllm/compilation/torch25_custom_graph_pass.py
+2 -2
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from abc import ABC, abstractmethod
4 -from typing import Any, Optional
4 +from typing import Any
5
6 import torch
7
@@ -23,7 +23,7 @@ class Torch25CustomGraphPass(ABC): # noqa (redefinition)
23 """
24
25 @abstractmethod
26 - def uuid(self) -> Optional[Any]:
26 + def uuid(self) -> Any | None:
27 """
28 Return an ID to uniquely identify your custom pass implementation.
29 Return None to skip inductor code caching entirely.
vllm/compilation/vllm_inductor_pass.py
+2 -2
@@ -3,7 +3,7 @@
3 import functools
4 import operator
5 import time
6 -from typing import ClassVar, Optional
6 +from typing import ClassVar
7
8 import regex as re
9 import torch
@@ -24,7 +24,7 @@ class VllmInductorPass(InductorPass):
24 It provides timing, logging, and dumping utilities.
25 """
26
27 - dump_prefix: ClassVar[Optional[int]] = None
27 + dump_prefix: ClassVar[int | None] = None
28 """Keep track of pass index for debug dump ordering."""
29
30 def __init__(self, config: VllmConfig):
vllm/compilation/wrapper.py
+2 -2
@@ -4,9 +4,9 @@
4 import os
5 import sys
6 from abc import abstractmethod
7 +from collections.abc import Callable
8 from contextlib import contextmanager
9 from types import CodeType
9 -from typing import Callable, Optional
10
11 import torch
12
@@ -31,7 +31,7 @@ class TorchCompileWrapperWithCustomDispatcher:
31 """
32
33 def __init__(
34 - self, compiled_callable: Optional[Callable] = None, compilation_level: int = 0
34 + self, compiled_callable: Callable | None = None, compilation_level: int = 0
35 ):
36 vllm_config = get_current_vllm_config()
37 self.vllm_config = vllm_config
vllm/config/cache.py
+10 -10
@@ -3,7 +3,7 @@
3
4 import hashlib
5 from dataclasses import field
6 -from typing import TYPE_CHECKING, Any, Literal, Optional
6 +from typing import TYPE_CHECKING, Any, Literal
7
8 from pydantic import Field, SkipValidation, field_validator
9 from pydantic.dataclasses import dataclass
@@ -58,13 +58,13 @@ class CacheConfig:
58 is_attention_free: bool = False
59 """Whether the model is attention-free. This is primarily set in
60 `ModelConfig` and that value should be manually duplicated here."""
61 - num_gpu_blocks_override: Optional[int] = None
61 + num_gpu_blocks_override: int | None = None
62 """Number of GPU blocks to use. This overrides the profiled `num_gpu_blocks`
63 if specified. Does nothing if `None`. Used for testing preemption."""
64 - sliding_window: Optional[int] = None
64 + sliding_window: int | None = None
65 """Sliding window size for the KV cache. This is primarily set in
66 `ModelConfig` and that value should be manually duplicated here."""
67 - enable_prefix_caching: Optional[bool] = None
67 + enable_prefix_caching: bool | None = None
68 """Whether to enable prefix caching. Enabled by default for V1."""
69 prefix_caching_hash_algo: PrefixCachingHashAlgo = "sha256"
70 """Set the hash algorithm for prefix caching:\n
@@ -84,12 +84,12 @@ class CacheConfig:
84 """This enables dynamic calculation of `k_scale` and `v_scale` when
85 kv_cache_dtype is fp8. If `False`, the scales will be loaded from the model
86 checkpoint if available. Otherwise, the scales will default to 1.0."""
87 - cpu_kvcache_space_bytes: Optional[int] = None
87 + cpu_kvcache_space_bytes: int | None = None
88 """(CPU backend only) CPU key-value cache space."""
89 - mamba_page_size_padded: Optional[int] = None
89 + mamba_page_size_padded: int | None = None
90 """ Optional override for mamba page size; used by hybrid mamba/attention
91 models to ensure exact alignment with attention page size."""
92 - mamba_block_size: Optional[int] = None
92 + mamba_block_size: int | None = None
93 """Size of a contiguous cache block in number of tokens for mamba cache."""
94 mamba_cache_dtype: MambaDType = "auto"
95 """The data type to use for the Mamba cache (both the conv as well as the
@@ -101,9 +101,9 @@ class CacheConfig:
101 for the ssm state will be determined by mamba_cache_dtype."""
102
103 # Will be set after profiling.
104 - num_gpu_blocks: Optional[int] = field(default=None, init=False)
104 + num_gpu_blocks: int | None = field(default=None, init=False)
105 """The number of blocks to allocate for GPU memory."""
106 - num_cpu_blocks: Optional[int] = field(default=None, init=False)
106 + num_cpu_blocks: int | None = field(default=None, init=False)
107 """The number of blocks to allocate for CPU memory."""
108
109 kv_sharing_fast_prefill: bool = False
@@ -116,7 +116,7 @@ class CacheConfig:
116 necessary for implementing this optimization in some models (e.g. Gemma3n)
117 """
118
119 - kv_cache_memory_bytes: Optional[int] = None
119 + kv_cache_memory_bytes: int | None = None
120 """Size of KV Cache per GPU in bytes. By default, this is set to None
121 and vllm can automatically infer the kv cache size based on
122 gpu_memory_utilization. However, users may want to manually specify
vllm/config/compilation.py
+10 -9
@@ -4,9 +4,10 @@
4 import enum
5 import hashlib
6 from collections import Counter
7 +from collections.abc import Callable
8 from dataclasses import asdict, field
9 from pathlib import Path
9 -from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, Union
10 +from typing import TYPE_CHECKING, Any, ClassVar
11
12 from pydantic import TypeAdapter, field_validator
13 from pydantic.dataclasses import dataclass
@@ -168,7 +169,7 @@ class CompilationConfig:
169 """
170
171 # Top-level Compilation control
171 - level: Optional[int] = None
172 + level: int | None = None
173 """The level of compilation:
174
175 - None: If None, we will select the default compilation level.
@@ -177,7 +178,7 @@ class CompilationConfig:
178 - 1: dynamo as is.
179 - 2: dynamo once.
180 - 3: piecewise compilation."""
180 - debug_dump_path: Optional[Path] = None
181 + debug_dump_path: Path | None = None
182 """The path to dump the debug information."""
183 cache_dir: str = ""
184 """The directory to store the compiled graph, to accelerate Inductor
@@ -208,7 +209,7 @@ class CompilationConfig:
209 By default, all custom ops are enabled when running without Inductor and
210 disabled when running with Inductor: level>=PIECEWISE and use_inductor=True.
211 Inductor generates (fused) Triton kernels for disabled custom ops."""
211 - splitting_ops: Optional[list[str]] = None
212 + splitting_ops: list[str] | None = None
213 """A list of ops to exclude from cudagraphs, used in piecewise compilation.
214
215 The behavior depends on use_inductor_graph_partition:
@@ -238,7 +239,7 @@ class CompilationConfig:
239 are compiled using configurations in inductor_compile_config.
240
241 This setting is ignored if level<PIECEWISE."""
241 - compile_sizes: Optional[list[Union[int, str]]] = None
242 + compile_sizes: list[int | str] | None = None
243 """Sizes to compile for inductor. In addition
244 to integers, it also supports "cudagraph_capture_sizes" to
245 specify the sizes for cudagraph capture."""
@@ -253,7 +254,7 @@ class CompilationConfig:
254 constructor, e.g. `CompilationConfig(inductor_passes={"a": func})`."""
255
256 # CudaGraph compilation
256 - cudagraph_mode: Optional[CUDAGraphMode] = None
257 + cudagraph_mode: CUDAGraphMode | None = None
258 """
259 The mode of the cudagraph:
260
@@ -308,7 +309,7 @@ class CompilationConfig:
309 It means the first several runs will be treated as warmup runs.
310 Only after that, the execution will be recorded, and the recorded
311 cudagraph will be used for subsequent runs."""
311 - cudagraph_capture_sizes: Optional[list[int]] = None
312 + cudagraph_capture_sizes: list[int] | None = None
313 """Sizes to capture cudagraph.
314 - None (default): capture sizes are inferred from vllm config.
315 - list[int]: capture sizes are specified as given."""
@@ -320,7 +321,7 @@ class CompilationConfig:
321 internally managed buffer. Default is False.
322 Note that this flag is only effective when cudagraph_mode is PIECEWISE.
323 """
323 - full_cuda_graph: Optional[bool] = False
324 + full_cuda_graph: bool | None = False
325 """whether to use a full cuda graph for the entire forward pass rather than
326 splitting certain operations such as attention into subgraphs. Thus this
327 flag cannot be used together with splitting_ops. This may provide
@@ -544,7 +545,7 @@ class CompilationConfig:
545 "(where 'op' is the registered op name)"
546 )
547
547 - def init_backend(self, vllm_config: "VllmConfig") -> Union[str, Callable]:
548 + def init_backend(self, vllm_config: "VllmConfig") -> str | Callable:
549 if self.level == CompilationLevel.NO_COMPILATION:
550 raise ValueError("No compilation level is set.")
551
vllm/config/device.py
+2 -2
@@ -3,7 +3,7 @@
3
4 import hashlib
5 from dataclasses import field
6 -from typing import Any, Literal, Optional, Union
6 +from typing import Any, Literal
7
8 import torch
9 from pydantic import ConfigDict, SkipValidation
@@ -19,7 +19,7 @@ Device = Literal["auto", "cuda", "cpu", "tpu", "xpu"]
19 class DeviceConfig:
20 """Configuration for the device to use for vLLM execution."""
21
22 - device: SkipValidation[Optional[Union[Device, torch.device]]] = "auto"
22 + device: SkipValidation[Device | torch.device | None] = "auto"
23 """Device type for vLLM execution.
24 This parameter is deprecated and will be
25 removed in a future release.
vllm/config/kv_events.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 from pydantic.dataclasses import dataclass
6
@@ -26,7 +25,7 @@ class KVEventsConfig:
25 """The zmq endpoint to use for publishing kv events.
26 """
27
29 - replay_endpoint: Optional[str] = None
28 + replay_endpoint: str | None = None
29 """The zmq endpoint to use for replaying kv events.
30 """
31
vllm/config/kv_transfer.py
+7 -7
@@ -4,7 +4,7 @@
4 import hashlib
5 import uuid
6 from dataclasses import field
7 -from typing import Any, Literal, Optional, get_args
7 +from typing import Any, Literal, get_args
8
9 from pydantic.dataclasses import dataclass
10
@@ -20,14 +20,14 @@ KVRole = Literal[KVProducer, KVConsumer]
20 class KVTransferConfig:
21 """Configuration for distributed KV cache transfer."""
22
23 - kv_connector: Optional[str] = None
23 + kv_connector: str | None = None
24 """The KV connector for vLLM to transmit KV caches between vLLM instances.
25 """
26
27 - engine_id: Optional[str] = None
27 + engine_id: str | None = None
28 """The engine id for KV transfers."""
29
30 - kv_buffer_device: Optional[str] = "cuda"
30 + kv_buffer_device: str | None = "cuda"
31 """The device used by kv connector to buffer the KV cache. Choices are
32 'cuda' and 'cpu'."""
33
@@ -35,11 +35,11 @@ class KVTransferConfig:
35 """The buffer size for TorchDistributedConnector. Measured in number of
36 bytes. Recommended value: 1e9 (about 1GB)."""
37
38 - kv_role: Optional[KVRole] = None
38 + kv_role: KVRole | None = None
39 """Whether this vLLM instance produces, consumes KV cache, or both. Choices
40 are 'kv_producer', 'kv_consumer', and 'kv_both'."""
41
42 - kv_rank: Optional[int] = None
42 + kv_rank: int | None = None
43 """The rank of this vLLM instance in the KV cache transfer. Typical value:
44 0 for prefill instance, 1 for decode instance.
45 Currently only 1P1D is supported."""
@@ -57,7 +57,7 @@ class KVTransferConfig:
57 kv_connector_extra_config: dict[str, Any] = field(default_factory=dict)
58 """any extra config that the connector may need."""
59
60 - kv_connector_module_path: Optional[str] = None
60 + kv_connector_module_path: str | None = None
61 """The Python module path to dynamically load the KV connector from.
62 Only supported in V1."""
63
vllm/config/load.py
+9 -13
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import hashlib
5 -from typing import TYPE_CHECKING, Any, Optional, Union
5 +from typing import TYPE_CHECKING, Any
6
7 from pydantic import Field, field_validator
8 from pydantic.dataclasses import dataclass
@@ -25,7 +25,7 @@ logger = init_logger(__name__)
25 class LoadConfig:
26 """Configuration for loading the model weights."""
27
28 - load_format: Union[str, LoadFormats] = "auto"
28 + load_format: str | LoadFormats = "auto"
29 """The format of the model weights to load:\n
30 - "auto" will try to load the weights in the safetensors format and fall
31 back to the pytorch bin format if safetensors format is not available.\n
@@ -48,7 +48,7 @@ class LoadConfig:
48 - "mistral" will load weights from consolidated safetensors files used by
49 Mistral models.
50 - Other custom values can be supported via plugins."""
51 - download_dir: Optional[str] = None
51 + download_dir: str | None = None
52 """Directory to download and load the weights, default to the default
53 cache directory of Hugging Face."""
54 safetensors_load_strategy: str = "lazy"
@@ -64,23 +64,19 @@ class LoadConfig:
64 was quantized using torchao and saved using safetensors.
65 Needs torchao >= 0.14.0
66 """
67 - model_loader_extra_config: Union[dict, TensorizerConfig] = Field(
68 - default_factory=dict
69 - )
67 + model_loader_extra_config: dict | TensorizerConfig = Field(default_factory=dict)
68 """Extra config for model loader. This will be passed to the model loader
69 corresponding to the chosen load_format."""
72 - device: Optional[str] = None
70 + device: str | None = None
71 """Device to which model weights will be loaded, default to
72 device_config.device"""
75 - ignore_patterns: Union[list[str], str] = Field(
76 - default_factory=lambda: ["original/**/*"]
77 - )
73 + ignore_patterns: list[str] | str = Field(default_factory=lambda: ["original/**/*"])
74 """The list of patterns to ignore when loading the model. Default to
75 "original/**/*" to avoid repeated loading of llama's checkpoints."""
76 use_tqdm_on_load: bool = True
77 """Whether to enable tqdm for showing progress bar when loading model
78 weights."""
83 - pt_load_map_location: Union[str, dict[str, str]] = "cpu"
79 + pt_load_map_location: str | dict[str, str] = "cpu"
80 """
81 pt_load_map_location: the map location for loading pytorch checkpoint, to
82 support loading checkpoints can only be loaded on certain devices like
@@ -115,8 +111,8 @@ class LoadConfig:
111
112 @field_validator("ignore_patterns", mode="after")
113 def _validate_ignore_patterns(
118 - cls, ignore_patterns: Union[list[str], str]
119 - ) -> Union[list[str], str]:
114 + cls, ignore_patterns: list[str] | str
115 + ) -> list[str] | str:
116 if ignore_patterns != ["original/**/*"] and len(ignore_patterns) > 0:
117 logger.info(
118 "Ignoring the following patterns when downloading weights: %s",
vllm/config/lora.py
+4 -4
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import hashlib
5 -from typing import TYPE_CHECKING, Any, ClassVar, Literal, Optional, Union
5 +from typing import TYPE_CHECKING, Any, ClassVar, Literal
6
7 import torch
8 from pydantic import ConfigDict, Field, model_validator
@@ -42,10 +42,10 @@ class LoRAConfig:
42 parallelism. Enabling this will use the fully sharded layers. At high
43 sequence length, max rank or tensor parallel size, this is likely faster.
44 """
45 - max_cpu_loras: Optional[int] = None
45 + max_cpu_loras: int | None = None
46 """Maximum number of LoRAs to store in CPU memory. Must be >= than
47 `max_loras`."""
48 - lora_dtype: Union[torch.dtype, LoRADType] = "auto"
48 + lora_dtype: torch.dtype | LoRADType = "auto"
49 """Data type for LoRA. If auto, will default to base model dtype."""
50 lora_extra_vocab_size: LoRAExtraVocabSize = Field(
51 default=256,
@@ -60,7 +60,7 @@ class LoRAConfig:
60 lora_vocab_padding_size: ClassVar[int] = (
61 current_platform.get_lora_vocab_padding_size()
62 )
63 - default_mm_loras: Optional[dict[str, str]] = None
63 + default_mm_loras: dict[str, str] | None = None
64 """Dictionary mapping specific modalities to LoRA model paths; this field
65 is only applicable to multimodal models and should be leveraged when a
66 model always expects a LoRA to be active when a given modality is present.
vllm/config/model.py
+62 -72
@@ -4,18 +4,10 @@
4 import hashlib
5 import json
6 import warnings
7 +from collections.abc import Callable
8 from dataclasses import InitVar, field
9 from importlib.util import find_spec
9 -from typing import (
10 - TYPE_CHECKING,
11 - Any,
12 - Callable,
13 - Literal,
14 - Optional,
15 - Union,
16 - cast,
17 - get_args,
18 -)
10 +from typing import TYPE_CHECKING, Any, Literal, cast, get_args
11
12 import torch
13 from pydantic import ConfigDict, SkipValidation, field_validator, model_validator
@@ -89,7 +81,7 @@ ModelDType = Literal["auto", "half", "float16", "bfloat16", "float", "float32"]
81 LogprobsMode = Literal[
82 "raw_logits", "raw_logprobs", "processed_logits", "processed_logprobs"
83 ]
92 -HfOverrides = Union[dict[str, Any], Callable[[PretrainedConfig], PretrainedConfig]]
84 +HfOverrides = dict[str, Any] | Callable[[PretrainedConfig], PretrainedConfig]
85 ModelImpl = Literal["auto", "vllm", "transformers", "terratorch"]
86
87 _RUNNER_TASKS: dict[RunnerType, list[TaskOption]] = {
@@ -121,7 +113,7 @@ class ModelConfig:
113 """Convert the model using adapters defined in
114 [vllm.model_executor.models.adapters][]. The most common use case is to
115 adapt a text generation model to be used for pooling tasks."""
124 - task: Optional[TaskOption] = None
116 + task: TaskOption | None = None
117 """[DEPRECATED] The task to use the model for. If the model supports more
118 than one model runner, this is used to select which model runner to run.
119
@@ -139,7 +131,7 @@ class ModelConfig:
131 trust_remote_code: bool = False
132 """Trust remote code (e.g., from HuggingFace) when downloading the model
133 and tokenizer."""
142 - dtype: Union[ModelDType, torch.dtype] = "auto"
134 + dtype: ModelDType | torch.dtype = "auto"
135 """Data type for model weights and activations:\n
136 - "auto" will use FP16 precision for FP32 and FP16 models, and BF16
137 precision for BF16 models.\n
@@ -148,33 +140,33 @@ class ModelConfig:
140 - "bfloat16" for a balance between precision and range.\n
141 - "float" is shorthand for FP32 precision.\n
142 - "float32" for FP32 precision."""
151 - seed: Optional[int] = None
143 + seed: int | None = None
144 """Random seed for reproducibility. Initialized to None in V0, but
145 initialized to 0 in V1."""
154 - hf_config_path: Optional[str] = None
146 + hf_config_path: str | None = None
147 """Name or path of the Hugging Face config to use. If unspecified, model
148 name or path will be used."""
149 allowed_local_media_path: str = ""
150 """Allowing API requests to read local images or videos from directories
151 specified by the server file system. This is a security risk. Should only
152 be enabled in trusted environments."""
161 - allowed_media_domains: Optional[list[str]] = None
153 + allowed_media_domains: list[str] | None = None
154 """If set, only media URLs that belong to this domain can be used for
155 multi-modal inputs. """
164 - revision: Optional[str] = None
156 + revision: str | None = None
157 """The specific model version to use. It can be a branch name, a tag name,
158 or a commit id. If unspecified, will use the default version."""
167 - code_revision: Optional[str] = None
159 + code_revision: str | None = None
160 """The specific revision to use for the model code on the Hugging Face Hub.
161 It can be a branch name, a tag name, or a commit id. If unspecified, will
162 use the default version."""
163 rope_scaling: dict[str, Any] = field(default_factory=dict)
164 """RoPE scaling configuration. For example,
165 `{"rope_type":"dynamic","factor":2.0}`."""
174 - rope_theta: Optional[float] = None
166 + rope_theta: float | None = None
167 """RoPE theta. Use with `rope_scaling`. In some cases, changing the RoPE
168 theta improves the performance of the scaled model."""
177 - tokenizer_revision: Optional[str] = None
169 + tokenizer_revision: str | None = None
170 """The specific revision to use for the tokenizer on the Hugging Face Hub.
171 It can be a branch name, a tag name, or a commit id. If unspecified, will
172 use the default version."""
@@ -187,9 +179,9 @@ class ModelConfig:
179 - 1k -> 1000\n
180 - 1K -> 1024\n
181 - 25.6k -> 25,600"""
190 - spec_target_max_model_len: Optional[int] = None
182 + spec_target_max_model_len: int | None = None
183 """Specify the maximum length for spec decoding draft models."""
192 - quantization: SkipValidation[Optional[QuantizationMethods]] = None
184 + quantization: SkipValidation[QuantizationMethods | None] = None
185 """Method used to quantize the weights. If `None`, we first check the
186 `quantization_config` attribute in the model config file. If that is
187 `None`, we assume the model weights are not quantized and use `dtype` to
@@ -230,7 +222,7 @@ class ModelConfig:
222 """If `True`, enables passing text embeddings as inputs via the
223 `prompt_embeds` key. Note that enabling this will double the time required
224 for graph compilation."""
233 - served_model_name: Optional[Union[str, list[str]]] = None
225 + served_model_name: str | list[str] | None = None
226 """The model name(s) used in the API. If multiple names are provided, the
227 server will respond to any of the provided names. The model name in the
228 model field of a response will be the first name in this list. If not
@@ -238,20 +230,20 @@ class ModelConfig:
230 that this name(s) will also be used in `model_name` tag content of
231 prometheus metrics, if multiple names provided, metrics tag will take the
232 first one."""
241 - config_format: Union[str, ConfigFormat] = "auto"
233 + config_format: str | ConfigFormat = "auto"
234 """The format of the model config to load:\n
235 - "auto" will try to load the config in hf format if available else it
236 will try to load in mistral format.\n
237 - "hf" will load the config in hf format.\n
238 - "mistral" will load the config in mistral format."""
247 - hf_token: Optional[Union[bool, str]] = None
239 + hf_token: bool | str | None = None
240 """The token to use as HTTP bearer authorization for remote files . If
241 `True`, will use the token generated when running `huggingface-cli login`
242 (stored in `~/.huggingface`)."""
243 hf_overrides: HfOverrides = field(default_factory=dict)
244 """If a dictionary, contains arguments to be forwarded to the Hugging Face
245 config. If a callable, it is called to update the HuggingFace config."""
254 - logits_processor_pattern: Optional[str] = None
246 + logits_processor_pattern: str | None = None
247 """Optional regex pattern specifying valid logits processor qualified names
248 that can be passed with the `logits_processors` extra completion argument.
249 Defaults to `None`, which allows no processors."""
@@ -269,7 +261,7 @@ class ModelConfig:
261 `--generation-config vllm`, only the override parameters are used."""
262 enable_sleep_mode: bool = False
263 """Enable sleep mode for the engine (only cuda platform is supported)."""
272 - model_impl: Union[str, ModelImpl] = "auto"
264 + model_impl: str | ModelImpl = "auto"
265 """Which implementation of the model to use:\n
266 - "auto" will try to use the vLLM implementation, if it exists, and fall
267 back to the Transformers implementation if no vLLM implementation is
@@ -278,36 +270,36 @@ class ModelConfig:
270 - "transformers" will use the Transformers model implementation.\n
271 - "terratorch" will use the TerraTorch model implementation.
272 """
281 - override_attention_dtype: Optional[str] = None
273 + override_attention_dtype: str | None = None
274 """Override dtype for attention"""
283 - logits_processors: Optional[list[Union[str, type[LogitsProcessor]]]] = None
275 + logits_processors: list[str | type[LogitsProcessor]] | None = None
276 """One or more logits processors' fully-qualified class names or class
277 definitions"""
286 - io_processor_plugin: Optional[str] = None
278 + io_processor_plugin: str | None = None
279 """IOProcessor plugin name to load at model startup"""
280
281 # Pooler config
290 - pooler_config: Optional[PoolerConfig] = None
282 + pooler_config: PoolerConfig | None = None
283 """Pooler config which controls the behaviour of output pooling in pooling
284 models."""
293 - override_pooler_config: Optional[Union[dict, PoolerConfig]] = None
285 + override_pooler_config: dict | PoolerConfig | None = None
286 """[DEPRECATED] Use `pooler_config` instead. This field will be removed in
287 v0.12.0 or v1.0.0, whichever is sooner."""
288
289 # Multimodal config and init vars
298 - multimodal_config: Optional[MultiModalConfig] = None
290 + multimodal_config: MultiModalConfig | None = None
291 """Configuration for multimodal model. If `None`, this will be inferred
292 from the architecture of `self.model`."""
301 - limit_mm_per_prompt: InitVar[Optional[dict[str, Union[int, dict[str, int]]]]] = None
302 - media_io_kwargs: InitVar[Optional[dict[str, dict[str, Any]]]] = None
303 - mm_processor_kwargs: InitVar[Optional[dict[str, Any]]] = None
304 - mm_processor_cache_gb: InitVar[Optional[float]] = None
305 - mm_processor_cache_type: InitVar[Optional[MMCacheType]] = None
306 - mm_shm_cache_max_object_size_mb: InitVar[Optional[int]] = None
307 - mm_encoder_tp_mode: InitVar[Optional[MMEncoderTPMode]] = None
308 - interleave_mm_strings: InitVar[Optional[bool]] = None
309 - skip_mm_profiling: InitVar[Optional[bool]] = None
310 - video_pruning_rate: InitVar[Optional[float]] = None
293 + limit_mm_per_prompt: InitVar[dict[str, int | dict[str, int]] | None] = None
294 + media_io_kwargs: InitVar[dict[str, dict[str, Any]] | None] = None
295 + mm_processor_kwargs: InitVar[dict[str, Any] | None] = None
296 + mm_processor_cache_gb: InitVar[float | None] = None
297 + mm_processor_cache_type: InitVar[MMCacheType | None] = None
298 + mm_shm_cache_max_object_size_mb: InitVar[int | None] = None
299 + mm_encoder_tp_mode: InitVar[MMEncoderTPMode | None] = None
300 + interleave_mm_strings: InitVar[bool | None] = None
301 + skip_mm_profiling: InitVar[bool | None] = None
302 + video_pruning_rate: InitVar[float | None] = None
303
304 def compute_hash(self) -> str:
305 """
@@ -369,7 +361,7 @@ class ModelConfig:
361
362 def _update_nested(
363 self,
372 - target: Union["PretrainedConfig", dict[str, Any]],
364 + target: PretrainedConfig | dict[str, Any],
365 updates: dict[str, Any],
366 ) -> None:
367 """Recursively updates a config or dict with nested updates."""
@@ -397,7 +389,7 @@ class ModelConfig:
389
390 def _apply_dict_overrides(
391 self,
400 - config: "PretrainedConfig",
392 + config: PretrainedConfig,
393 overrides: dict[str, Any],
394 ) -> None:
395 """Apply dict overrides, handling both nested configs and dict values."""
@@ -415,16 +407,16 @@ class ModelConfig:
407 def __post_init__(
408 self,
409 # Multimodal config init vars
418 - limit_mm_per_prompt: Optional[dict[str, int]],
419 - media_io_kwargs: Optional[dict[str, dict[str, Any]]],
420 - mm_processor_kwargs: Optional[dict[str, Any]],
421 - mm_processor_cache_gb: Optional[float],
422 - mm_processor_cache_type: Optional[MMCacheType],
423 - mm_shm_cache_max_object_size_mb: Optional[int],
424 - mm_encoder_tp_mode: Optional[MMEncoderTPMode],
425 - interleave_mm_strings: Optional[bool],
426 - skip_mm_profiling: Optional[bool],
427 - video_pruning_rate: Optional[float],
410 + limit_mm_per_prompt: dict[str, int] | None,
411 + media_io_kwargs: dict[str, dict[str, Any]] | None,
412 + mm_processor_kwargs: dict[str, Any] | None,
413 + mm_processor_cache_gb: float | None,
414 + mm_processor_cache_type: MMCacheType | None,
415 + mm_shm_cache_max_object_size_mb: int | None,
416 + mm_encoder_tp_mode: MMEncoderTPMode | None,
417 + interleave_mm_strings: bool | None,
418 + skip_mm_profiling: bool | None,
419 + video_pruning_rate: float | None,
420 ) -> None:
421 # Set the default seed to 0 in V1.
422 # NOTE(woosuk): In V0, we set the default seed to None because the
@@ -1209,7 +1201,7 @@ class ModelConfig:
1201 "Supported models implement the `SupportsPP` interface."
1202 )
1203
1212 - def get_sliding_window(self) -> Optional[int]:
1204 + def get_sliding_window(self) -> int | None:
1205 """Get the sliding window size from the HF text config if present."""
1206 return getattr(self.hf_text_config, "sliding_window", None)
1207
@@ -1479,7 +1471,7 @@ class ModelConfig:
1471 f"{block_type.value} layers"
1472 )
1473
1482 - def get_mamba_chunk_size(self) -> Optional[int]:
1474 + def get_mamba_chunk_size(self) -> int | None:
1475 """
1476 Returns the mamba chunk size if it exists
1477 """
@@ -1715,9 +1707,7 @@ class ModelConfig:
1707 return max_model_len
1708
1709
1718 -def get_served_model_name(
1719 - model: str, served_model_name: Optional[Union[str, list[str]]]
1720 -):
1710 +def get_served_model_name(model: str, served_model_name: str | list[str] | None):
1711 """
1712 If the input is a non-empty list, the first model_name in
1713 `served_model_name` is taken.
@@ -1761,9 +1751,9 @@ def iter_architecture_defaults():
1751 def try_match_architecture_defaults(
1752 architecture: str,
1753 *,
1764 - runner_type: Optional[RunnerType] = None,
1765 - convert_type: Optional[ConvertType] = None,
1766 -) -> Optional[tuple[str, tuple[RunnerType, ConvertType]]]:
1754 + runner_type: RunnerType | None = None,
1755 + convert_type: ConvertType | None = None,
1756 +) -> tuple[str, tuple[RunnerType, ConvertType]] | None:
1757 for suffix, (
1758 default_runner_type,
1759 default_convert_type,
@@ -1817,7 +1807,7 @@ def _find_dtype(
1807 model_id: str,
1808 config: PretrainedConfig,
1809 *,
1820 - revision: Optional[str],
1810 + revision: str | None,
1811 ):
1812 # NOTE: getattr(config, "torch_dtype", torch.float32) is not correct
1813 # because config.torch_dtype can be None.
@@ -1902,10 +1892,10 @@ def _resolve_auto_dtype(
1892 def _get_and_verify_dtype(
1893 model_id: str,
1894 config: PretrainedConfig,
1905 - dtype: Union[str, torch.dtype],
1895 + dtype: str | torch.dtype,
1896 *,
1897 is_pooling_model: bool,
1908 - revision: Optional[str] = None,
1898 + revision: str | None = None,
1899 ) -> torch.dtype:
1900 config_dtype = _find_dtype(model_id, config, revision=revision)
1901 model_type = config.model_type
@@ -1947,7 +1937,7 @@ def _get_and_verify_dtype(
1937 def _get_head_dtype(
1938 config: PretrainedConfig, dtype: torch.dtype, runner_type: str
1939 ) -> torch.dtype:
1950 - head_dtype: Optional[Union[str, torch.dtype]] = getattr(config, "head_dtype", None)
1940 + head_dtype: str | torch.dtype | None = getattr(config, "head_dtype", None)
1941
1942 if head_dtype == "model":
1943 return dtype
@@ -1970,12 +1960,12 @@ def _get_head_dtype(
1960
1961 def _get_and_verify_max_len(
1962 hf_config: PretrainedConfig,
1973 - tokenizer_config: Optional[dict],
1974 - max_model_len: Optional[int],
1963 + tokenizer_config: dict | None,
1964 + max_model_len: int | None,
1965 disable_sliding_window: bool,
1976 - sliding_window: Optional[int],
1977 - spec_target_max_model_len: Optional[int] = None,
1978 - encoder_config: Optional[Any] = None,
1966 + sliding_window: int | None,
1967 + spec_target_max_model_len: int | None = None,
1968 + encoder_config: Any | None = None,
1969 ) -> int:
1970 """Get and verify the model's maximum length."""
1971 derived_max_model_len = float("inf")
vllm/config/multimodal.py
+14 -14
@@ -4,7 +4,7 @@
4 import hashlib
5 from collections.abc import Mapping
6 from dataclasses import field
7 -from typing import Any, Literal, Optional, Union
7 +from typing import Any, Literal, TypeAlias
8
9 from pydantic import ConfigDict, Field, field_validator
10 from pydantic.dataclasses import dataclass
@@ -23,31 +23,31 @@ class BaseDummyOptions:
23 class VideoDummyOptions(BaseDummyOptions):
24 """Options for generating dummy video data during profiling."""
25
26 - num_frames: Optional[int] = Field(None, gt=0)
27 - width: Optional[int] = Field(None, gt=0)
28 - height: Optional[int] = Field(None, gt=0)
26 + num_frames: int | None = Field(None, gt=0)
27 + width: int | None = Field(None, gt=0)
28 + height: int | None = Field(None, gt=0)
29
30
31 @dataclass(config=ConfigDict(extra="forbid"))
32 class ImageDummyOptions(BaseDummyOptions):
33 """Options for generating dummy image data during profiling."""
34
35 - width: Optional[int] = Field(None, gt=0)
36 - height: Optional[int] = Field(None, gt=0)
35 + width: int | None = Field(None, gt=0)
36 + height: int | None = Field(None, gt=0)
37
38
39 @dataclass(config=ConfigDict(extra="forbid"))
40 class AudioDummyOptions(BaseDummyOptions):
41 """Options for generating dummy audio data during profiling."""
42
43 - length: Optional[int] = Field(None, gt=0)
43 + length: int | None = Field(None, gt=0)
44
45
46 MMEncoderTPMode = Literal["weights", "data"]
47 MMCacheType = Literal["shm", "lru"]
48 -DummyOptions = Union[
49 - BaseDummyOptions, VideoDummyOptions, ImageDummyOptions, AudioDummyOptions
50 -]
48 +DummyOptions: TypeAlias = (
49 + BaseDummyOptions | VideoDummyOptions | ImageDummyOptions | AudioDummyOptions
50 +)
51
52
53 @config
@@ -75,7 +75,7 @@ class MultiModalConfig:
75 """Additional args passed to process media inputs, keyed by modalities.
76 For example, to set num_frames for video, set
77 `--media-io-kwargs '{"video": {"num_frames": 40} }'`"""
78 - mm_processor_kwargs: Optional[dict[str, object]] = None
78 + mm_processor_kwargs: dict[str, object] | None = None
79 """Arguments to be forwarded to the model's processor for multi-modal data,
80 e.g., image processor. Overrides for the multi-modal processor obtained
81 from `transformers.AutoProcessor.from_pretrained`.
@@ -123,7 +123,7 @@ class MultiModalConfig:
123 This reduces engine startup time but shifts the responsibility to users for
124 estimating the peak memory usage of the activation of multimodal encoder and
125 embedding cache."""
126 - video_pruning_rate: Optional[float] = None
126 + video_pruning_rate: float | None = None
127 """Sets pruning rate for video pruning via Efficient Video Sampling.
128 Value sits in range [0;1) and determines fraction of media tokens
129 from each video to be pruned.
@@ -132,7 +132,7 @@ class MultiModalConfig:
132 @field_validator("limit_per_prompt", mode="before")
133 @classmethod
134 def _validate_limit_per_prompt(
135 - cls, value: dict[str, Union[int, dict[str, int]]]
135 + cls, value: dict[str, int | dict[str, int]]
136 ) -> dict[str, DummyOptions]:
137 for k, v in value.items():
138 # Handle legacy format where only count is specified
@@ -179,7 +179,7 @@ class MultiModalConfig:
179 return 999
180 return limit_data.count
181
182 - def get_dummy_options(self, modality: str) -> Optional[BaseDummyOptions]:
182 + def get_dummy_options(self, modality: str) -> BaseDummyOptions | None:
183 """
184 Get the configurable dummy data options for a modality.
185 Returns None if no options are configured for this modality.
vllm/config/observability.py
+4 -4
@@ -3,7 +3,7 @@
3
4 import hashlib
5 from functools import cached_property
6 -from typing import Any, Literal, Optional, cast
6 +from typing import Any, Literal, cast
7
8 from pydantic.dataclasses import dataclass
9
@@ -18,7 +18,7 @@ DetailedTraceModules = Literal["model", "worker", "all"]
18 class ObservabilityConfig:
19 """Configuration for observability - metrics and tracing."""
20
21 - show_hidden_metrics_for_version: Optional[str] = None
21 + show_hidden_metrics_for_version: str | None = None
22 """Enable deprecated Prometheus metrics that have been hidden since the
23 specified version. For example, if a previously deprecated metric has been
24 hidden since the v0.7.0 release, you use
@@ -33,10 +33,10 @@ class ObservabilityConfig:
33 return False
34 return version._prev_minor_version_was(self.show_hidden_metrics_for_version)
35
36 - otlp_traces_endpoint: Optional[str] = None
36 + otlp_traces_endpoint: str | None = None
37 """Target URL to which OpenTelemetry traces will be sent."""
38
39 - collect_detailed_traces: Optional[list[DetailedTraceModules]] = None
39 + collect_detailed_traces: list[DetailedTraceModules] | None = None
40 """It makes sense to set this only if `--otlp-traces-endpoint` is set. If
41 set, it will collect detailed traces for the specified modules. This
42 involves use of possibly costly and or blocking operations and hence might
vllm/config/parallel.py
+13 -13
@@ -3,7 +3,7 @@
3
4 import hashlib
5 import os
6 -from typing import TYPE_CHECKING, Any, Literal, Optional, Union
6 +from typing import TYPE_CHECKING, Any, Literal
7
8 import torch
9 from pydantic import Field, model_validator
@@ -75,7 +75,7 @@ class ParallelConfig:
75 """Number of local data parallel groups."""
76 data_parallel_rank: int = 0
77 """Rank of the data parallel group."""
78 - data_parallel_rank_local: Optional[int] = None
78 + data_parallel_rank_local: int | None = None
79 """Local rank of the data parallel group,
80 set only in SPMD mode."""
81 data_parallel_master_ip: str = "127.0.0.1"
@@ -113,24 +113,24 @@ class ParallelConfig:
113 with 4 experts and 2 ranks, rank 0 will have experts [0, 2] and rank 1
114 will have experts [1, 3]. This strategy can help improve load balancing
115 for grouped expert models with no redundant experts."""
116 - num_redundant_experts: Optional[int] = None
116 + num_redundant_experts: int | None = None
117 """`num_redundant_experts` is deprecated and has been replaced with
118 `eplb_config.num_redundant_experts`. This will be removed in v0.12.0.
119 Please use `eplb_config.num_redundant_experts` instead."""
120 - eplb_window_size: Optional[int] = None
120 + eplb_window_size: int | None = None
121 """`eplb_window_size` is deprecated and has been replaced with
122 `eplb_config.window_size`. This will be removed in v0.12.0.
123 Please use `eplb_config.window_size` instead."""
124 - eplb_step_interval: Optional[int] = None
124 + eplb_step_interval: int | None = None
125 """`eplb_step_interval` is deprecated and has been replaced with
126 `eplb_config.step_interval`. This will be removed in v0.12.0.
127 Please use `eplb_config.step_interval` instead."""
128 - eplb_log_balancedness: Optional[bool] = None
128 + eplb_log_balancedness: bool | None = None
129 """`eplb_log_balancedness` is deprecated and has been replaced with
130 `eplb_config.log_balancedness`. This will be removed in v0.12.0.
131 Please use `eplb_config.log_balancedness` instead."""
132
133 - max_parallel_loading_workers: Optional[int] = None
133 + max_parallel_loading_workers: int | None = None
134 """Maximum number of parallel loading workers when loading model
135 sequentially in multiple batches. To avoid RAM OOM when using tensor
136 parallel and large models."""
@@ -159,15 +159,15 @@ class ParallelConfig:
159 ray_workers_use_nsight: bool = False
160 """Whether to profile Ray workers with nsight, see https://docs.ray.io/en/latest/ray-observability/user-guides/profiling.html#profiling-nsight-profiler."""
161
162 - ray_runtime_env: Optional[RuntimeEnv] = None
162 + ray_runtime_env: RuntimeEnv | None = None
163 """Ray runtime environment to pass to distributed workers."""
164
165 - placement_group: Optional[PlacementGroup] = None
165 + placement_group: PlacementGroup | None = None
166 """ray distributed model workers placement group."""
167
168 - distributed_executor_backend: Optional[
169 - Union[str, DistributedExecutorBackend, type[ExecutorBase]]
170 - ] = None
168 + distributed_executor_backend: (
169 + str | DistributedExecutorBackend | type[ExecutorBase] | None
170 + ) = None
171 """Backend to use for distributed model
172 workers, either "ray" or "mp" (multiprocessing). If the product
173 of pipeline_parallel_size and tensor_parallel_size is less than
@@ -306,7 +306,7 @@ class ParallelConfig:
306 )
307
308 max_retries = 5
309 - last_exc: Optional[Exception] = None
309 + last_exc: Exception | None = None
310 for _ in range(max_retries):
311 try:
312 # use gloo since the engine process might not have cuda device
vllm/config/pooler.py
+11 -11
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import hashlib
5 -from typing import Any, Optional
5 +from typing import Any
6
7 from pydantic.dataclasses import dataclass
8
@@ -14,23 +14,23 @@ from vllm.config.utils import config
14 class PoolerConfig:
15 """Controls the behavior of output pooling in pooling models."""
16
17 - pooling_type: Optional[str] = None
17 + pooling_type: str | None = None
18 """
19 The pooling method of the pooling model. This should be a key in
20 [`vllm.model_executor.layers.pooler.PoolingType`][].
21 """
22
23 ## for embeddings models
24 - normalize: Optional[bool] = None
24 + normalize: bool | None = None
25 """
26 Whether to normalize the embeddings outputs. Defaults to True.
27 """
28 - dimensions: Optional[int] = None
28 + dimensions: int | None = None
29 """
30 Reduce the dimensions of embeddings if model
31 support matryoshka representation. Defaults to None.
32 """
33 - enable_chunked_processing: Optional[bool] = None
33 + enable_chunked_processing: bool | None = None
34 """
35 Whether to enable chunked processing for long inputs that exceed the model's
36 maximum position embeddings. When enabled, long inputs will be split into
@@ -38,7 +38,7 @@ class PoolerConfig:
38 This allows embedding models to handle arbitrarily long text without CUDA
39 errors. Defaults to False.
40 """
41 - max_embed_len: Optional[int] = None
41 + max_embed_len: int | None = None
42 """
43 Maximum input length allowed for embedding generation. When set, allows
44 inputs longer than max_embed_len to be accepted for embedding models.
@@ -48,29 +48,29 @@ class PoolerConfig:
48 """
49
50 ## for classification models
51 - activation: Optional[bool] = None
51 + activation: bool | None = None
52 """
53 Whether to apply activation function to the classification outputs.
54 Defaults to True.
55 """
56 - logit_bias: Optional[float] = None
56 + logit_bias: float | None = None
57 """
58 If provided, apply classification logit biases. Defaults to None.
59 """
60
61 ## for reward models
62 - softmax: Optional[bool] = None
62 + softmax: bool | None = None
63 """
64 Whether to apply softmax to the reward outputs.
65 Defaults to True.
66 """
67 - step_tag_id: Optional[int] = None
67 + step_tag_id: int | None = None
68 """
69 If set, only the score corresponding to the ``step_tag_id`` in the
70 generated sentence should be returned. Otherwise, the scores for all tokens
71 are returned.
72 """
73 - returned_token_ids: Optional[list[int]] = None
73 + returned_token_ids: list[int] | None = None
74 """
75 A list of indices for the vocabulary dimensions to be extracted,
76 such as the token IDs of ``good_token`` and ``bad_token`` in the
vllm/config/scheduler.py
+2 -2
@@ -3,7 +3,7 @@
3
4 import hashlib
5 from dataclasses import InitVar, field
6 -from typing import Any, Literal, Union
6 +from typing import Any, Literal
7
8 from pydantic import SkipValidation, model_validator
9 from pydantic.dataclasses import dataclass
@@ -133,7 +133,7 @@ class SchedulerConfig:
133
134 # scheduler class or path. "vllm.core.scheduler.Scheduler" (default)
135 # or "mod.custom_class".
136 - scheduler_cls: Union[str, type[object]] = "vllm.core.scheduler.Scheduler"
136 + scheduler_cls: str | type[object] = "vllm.core.scheduler.Scheduler"
137 """The scheduler class to use. "vllm.core.scheduler.Scheduler" is the
138 default scheduler. Can be a class directly or the path to a class of form
139 "mod.custom_class"."""
vllm/config/speculative.py
+15 -15
@@ -3,7 +3,7 @@
3
4 import ast
5 import hashlib
6 -from typing import TYPE_CHECKING, Any, Literal, Optional
6 +from typing import TYPE_CHECKING, Any, Literal
7
8 from pydantic import SkipValidation, model_validator
9 from pydantic.dataclasses import dataclass
@@ -59,16 +59,16 @@ MTP_MODEL_TYPES = (
59 class SpeculativeConfig:
60 """Configuration for speculative decoding."""
61
62 - enforce_eager: Optional[bool] = None
62 + enforce_eager: bool | None = None
63 """Override the default enforce_eager from model_config"""
64 # General speculative decoding control
65 num_speculative_tokens: SkipValidation[int] = None # type: ignore
66 """The number of speculative tokens, if provided. It will default to the
67 number in the draft model config if present, otherwise, it is required."""
68 - model: Optional[str] = None
68 + model: str | None = None
69 """The name of the draft model, eagle head, or additional weights, if
70 provided."""
71 - method: Optional[SpeculativeMethod] = None
71 + method: SpeculativeMethod | None = None
72 """The name of the speculative method to use. If users provide and set the
73 `model` param, the speculative method type will be detected automatically
74 if possible, if `model` param is not provided, the method name must be
@@ -76,7 +76,7 @@ class SpeculativeConfig:
76
77 If using `ngram` method, the related configuration `prompt_lookup_max` and
78 `prompt_lookup_min` should be considered."""
79 - draft_tensor_parallel_size: Optional[int] = None
79 + draft_tensor_parallel_size: int | None = None
80 """The degree of the tensor parallelism for the draft model. Can only be 1
81 or the same as the target model's tensor parallel size."""
82 disable_logprobs: bool = True
@@ -85,24 +85,24 @@ class SpeculativeConfig:
85 according to the log probability settings in SamplingParams."""
86
87 # Draft model configuration
88 - quantization: Optional[me_quant.QuantizationMethods] = None
88 + quantization: me_quant.QuantizationMethods | None = None
89 """Quantization method that was used to quantize the draft model weights.
90 If `None`, we assume the model weights are not quantized. Note that it only
91 takes effect when using the draft model-based speculative method."""
92 - max_model_len: Optional[int] = None
92 + max_model_len: int | None = None
93 """The maximum model length of the draft model. Used when testing the
94 ability to skip speculation for some sequences."""
95 - revision: Optional[str] = None
95 + revision: str | None = None
96 """The specific model version to use for the draft model. It can be a
97 branch name, a tag name, or a commit id. If unspecified, will use the
98 default version."""
99 - code_revision: Optional[str] = None
99 + code_revision: str | None = None
100 """The specific revision to use for the draft model code on Hugging Face
101 Hub. It can be a branch name, a tag name, or a commit id. If unspecified,
102 will use the default version."""
103
104 # Advanced control
105 - disable_by_batch_size: Optional[int] = None
105 + disable_by_batch_size: int | None = None
106 """Disable speculative decoding for new incoming requests when the number
107 of enqueued requests is larger than this value, if provided."""
108 disable_padded_drafter_batch: bool = False
@@ -112,14 +112,14 @@ class SpeculativeConfig:
112 only affects the EAGLE method of speculation."""
113
114 # Ngram proposer configuration
115 - prompt_lookup_max: Optional[int] = None
115 + prompt_lookup_max: int | None = None
116 """Maximum size of ngram token window when using Ngram proposer, required
117 when method is set to ngram."""
118 - prompt_lookup_min: Optional[int] = None
118 + prompt_lookup_min: int | None = None
119 """Minimum size of ngram token window when using Ngram proposer, if
120 provided. Defaults to 1."""
121
122 - speculative_token_tree: Optional[str] = None
122 + speculative_token_tree: str | None = None
123 """Specifies the tree structure for speculative token generation.
124 """
125 # required configuration params passed from engine
@@ -449,7 +449,7 @@ class SpeculativeConfig:
449
450 @staticmethod
451 def _maybe_override_draft_max_model_len(
452 - speculative_max_model_len: Optional[int],
452 + speculative_max_model_len: int | None,
453 draft_max_model_len: int,
454 target_max_model_len: int,
455 ) -> int:
@@ -488,7 +488,7 @@ class SpeculativeConfig:
488 @staticmethod
489 def _verify_and_get_draft_tp(
490 target_parallel_config: ParallelConfig,
491 - speculative_draft_tensor_parallel_size: Optional[int],
491 + speculative_draft_tensor_parallel_size: int | None,
492 draft_hf_config: PretrainedConfig,
493 ) -> int:
494 """
vllm/config/speech_to_text.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 from pydantic.dataclasses import dataclass
6
@@ -28,7 +27,7 @@ class SpeechToTextConfig:
27 splitting long audio. This helps maintain context across chunk boundaries
28 and improves transcription quality at split points."""
29
31 - min_energy_split_window_size: Optional[int] = 1600
30 + min_energy_split_window_size: int | None = 1600
31 """Window size in samples for finding low-energy (quiet) regions to split
32 audio chunks. The algorithm looks for the quietest moment within this
33 window to minimize cutting through speech. Default 1600 samples ≈ 100ms
vllm/config/vllm.py
+16 -16
@@ -10,7 +10,7 @@ from contextlib import contextmanager
10 from dataclasses import field, replace
11 from functools import lru_cache
12 from pathlib import Path
13 -from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
13 +from typing import TYPE_CHECKING, Any, TypeVar
14
15 import torch
16 from pydantic import ConfigDict
@@ -69,17 +69,17 @@ class VllmConfig:
69 """Device configuration."""
70 load_config: LoadConfig = field(default_factory=LoadConfig)
71 """Load configuration."""
72 - lora_config: Optional[LoRAConfig] = None
72 + lora_config: LoRAConfig | None = None
73 """LoRA configuration."""
74 - speculative_config: Optional[SpeculativeConfig] = None
74 + speculative_config: SpeculativeConfig | None = None
75 """Speculative decoding configuration."""
76 structured_outputs_config: StructuredOutputsConfig = field(
77 default_factory=StructuredOutputsConfig
78 )
79 """Structured outputs configuration."""
80 - observability_config: Optional[ObservabilityConfig] = None
80 + observability_config: ObservabilityConfig | None = None
81 """Observability configuration."""
82 - quant_config: Optional[QuantizationConfig] = None
82 + quant_config: QuantizationConfig | None = None
83 """Quantization configuration."""
84 compilation_config: CompilationConfig = field(default_factory=CompilationConfig)
85 """`torch.compile` and cudagraph capture configuration for the model.
@@ -96,14 +96,14 @@ class VllmConfig:
96 You can specify the full compilation config like so:
97 `{"level": 3, "cudagraph_capture_sizes": [1, 2, 4, 8]}`
98 """
99 - kv_transfer_config: Optional[KVTransferConfig] = None
99 + kv_transfer_config: KVTransferConfig | None = None
100 """The configurations for distributed KV cache transfer."""
101 - kv_events_config: Optional[KVEventsConfig] = None
101 + kv_events_config: KVEventsConfig | None = None
102 """The configurations for event publishing."""
103 # some opaque config, only used to provide additional information
104 # for the hash computation, mainly used for testing, debugging or out of
105 # tree config registration.
106 - additional_config: Union[dict, SupportsHash] = field(default_factory=dict)
106 + additional_config: dict | SupportsHash = field(default_factory=dict)
107 """Additional config for specified platform. Different platforms may
108 support different configs. Make sure the configs are valid for the platform
109 you are using. Contents must be hashable."""
@@ -212,7 +212,7 @@ class VllmConfig:
212 @staticmethod
213 def _get_quantization_config(
214 model_config: ModelConfig, load_config: LoadConfig
215 - ) -> Optional[QuantizationConfig]:
215 + ) -> QuantizationConfig | None:
216 """Get the quantization config."""
217 from vllm.platforms import current_platform
218
@@ -245,7 +245,7 @@ class VllmConfig:
245 @staticmethod
246 def get_quantization_config(
247 model_config: ModelConfig, load_config: LoadConfig
248 - ) -> Optional[QuantizationConfig]:
248 + ) -> QuantizationConfig | None:
249 import copy
250
251 # For some reason, the _ version of this modifies the model_config
@@ -257,7 +257,7 @@ class VllmConfig:
257 def with_hf_config(
258 self,
259 hf_config: PretrainedConfig,
260 - architectures: Optional[list[str]] = None,
260 + architectures: list[str] | None = None,
261 ) -> "VllmConfig":
262 if architectures is not None:
263 hf_config = copy.deepcopy(hf_config)
@@ -740,7 +740,7 @@ class VllmConfig:
740 f"Model: {self.model_config.model}"
741 )
742
743 - def compile_debug_dump_path(self) -> Optional[Path]:
743 + def compile_debug_dump_path(self) -> Path | None:
744 """Returns a rank-aware path for dumping
745 torch.compile debug information.
746 """
@@ -790,13 +790,13 @@ class VllmConfig:
790 )
791
792
793 -_current_vllm_config: Optional[VllmConfig] = None
794 -_current_prefix: Optional[str] = None
793 +_current_vllm_config: VllmConfig | None = None
794 +_current_prefix: str | None = None
795
796
797 @contextmanager
798 def set_current_vllm_config(
799 - vllm_config: VllmConfig, check_compile=False, prefix: Optional[str] = None
799 + vllm_config: VllmConfig, check_compile=False, prefix: str | None = None
800 ):
801 """
802 Temporarily set the current vLLM config.
@@ -866,7 +866,7 @@ T = TypeVar("T")
866 def get_layers_from_vllm_config(
867 vllm_config: VllmConfig,
868 layer_type: type[T],
869 - layer_names: Optional[list[str]] = None,
869 + layer_names: list[str] | None = None,
870 ) -> dict[str, T]:
871 """
872 Get layers from the vLLM config.
vllm/connections.py
+14 -15
@@ -3,7 +3,6 @@
3
4 from collections.abc import Mapping, MutableMapping
5 from pathlib import Path
6 -from typing import Optional
6 from urllib.parse import urlparse
7
8 import aiohttp
@@ -20,8 +19,8 @@ class HTTPConnection:
19
20 self.reuse_client = reuse_client
21
23 - self._sync_client: Optional[requests.Session] = None
24 - self._async_client: Optional[aiohttp.ClientSession] = None
22 + self._sync_client: requests.Session | None = None
23 + self._async_client: aiohttp.ClientSession | None = None
24
25 def get_sync_client(self) -> requests.Session:
26 if self._sync_client is None or not self.reuse_client:
@@ -53,8 +52,8 @@ class HTTPConnection:
52 url: str,
53 *,
54 stream: bool = False,
56 - timeout: Optional[float] = None,
57 - extra_headers: Optional[Mapping[str, str]] = None,
55 + timeout: float | None = None,
56 + extra_headers: Mapping[str, str] | None = None,
57 allow_redirects: bool = True,
58 ):
59 self._validate_http_url(url)
@@ -74,8 +73,8 @@ class HTTPConnection:
73 self,
74 url: str,
75 *,
77 - timeout: Optional[float] = None,
78 - extra_headers: Optional[Mapping[str, str]] = None,
76 + timeout: float | None = None,
77 + extra_headers: Mapping[str, str] | None = None,
78 allow_redirects: bool = True,
79 ):
80 self._validate_http_url(url)
@@ -91,7 +90,7 @@ class HTTPConnection:
90 )
91
92 def get_bytes(
94 - self, url: str, *, timeout: Optional[float] = None, allow_redirects: bool = True
93 + self, url: str, *, timeout: float | None = None, allow_redirects: bool = True
94 ) -> bytes:
95 with self.get_response(
96 url, timeout=timeout, allow_redirects=allow_redirects
@@ -104,7 +103,7 @@ class HTTPConnection:
103 self,
104 url: str,
105 *,
107 - timeout: Optional[float] = None,
106 + timeout: float | None = None,
107 allow_redirects: bool = True,
108 ) -> bytes:
109 async with await self.get_async_response(
@@ -114,7 +113,7 @@ class HTTPConnection:
113
114 return await r.read()
115
117 - def get_text(self, url: str, *, timeout: Optional[float] = None) -> str:
116 + def get_text(self, url: str, *, timeout: float | None = None) -> str:
117 with self.get_response(url, timeout=timeout) as r:
118 r.raise_for_status()
119
@@ -124,14 +123,14 @@ class HTTPConnection:
123 self,
124 url: str,
125 *,
127 - timeout: Optional[float] = None,
126 + timeout: float | None = None,
127 ) -> str:
128 async with await self.get_async_response(url, timeout=timeout) as r:
129 r.raise_for_status()
130
131 return await r.text()
132
134 - def get_json(self, url: str, *, timeout: Optional[float] = None) -> str:
133 + def get_json(self, url: str, *, timeout: float | None = None) -> str:
134 with self.get_response(url, timeout=timeout) as r:
135 r.raise_for_status()
136
@@ -141,7 +140,7 @@ class HTTPConnection:
140 self,
141 url: str,
142 *,
144 - timeout: Optional[float] = None,
143 + timeout: float | None = None,
144 ) -> str:
145 async with await self.get_async_response(url, timeout=timeout) as r:
146 r.raise_for_status()
@@ -153,7 +152,7 @@ class HTTPConnection:
152 url: str,
153 save_path: Path,
154 *,
156 - timeout: Optional[float] = None,
155 + timeout: float | None = None,
156 chunk_size: int = 128,
157 ) -> Path:
158 with self.get_response(url, timeout=timeout) as r:
@@ -170,7 +169,7 @@ class HTTPConnection:
169 url: str,
170 save_path: Path,
171 *,
173 - timeout: Optional[float] = None,
172 + timeout: float | None = None,
173 chunk_size: int = 128,
174 ) -> Path:
175 async with await self.get_async_response(url, timeout=timeout) as r:
vllm/device_allocator/cumem.py
+7 -6
@@ -11,8 +11,9 @@
11 import dataclasses
12 import gc
13 import os
14 +from collections.abc import Callable
15 from contextlib import contextmanager
15 -from typing import Any, Callable, Optional, Union
16 +from typing import Any
17
18 import torch
19
@@ -22,7 +23,7 @@ from vllm.utils import is_pin_memory_available
23 logger = init_logger(__name__)
24
25
25 -def find_loaded_library(lib_name) -> Optional[str]:
26 +def find_loaded_library(lib_name) -> str | None:
27 """
28 According to according to https://man7.org/linux/man-pages/man5/proc_pid_maps.5.html,
29 the file `/proc/self/maps` contains the memory maps of the process, which includes the
@@ -78,7 +79,7 @@ HandleType = tuple[int, int, int, int]
79 class AllocationData:
80 handle: HandleType
81 tag: str
81 - cpu_backup_tensor: Optional[torch.Tensor] = None
82 + cpu_backup_tensor: torch.Tensor | None = None
83
84
85 def create_and_map(allocation_handle: HandleType) -> None:
@@ -197,7 +198,7 @@ class CuMemAllocator:
198 )
199 return data.handle
200
200 - def sleep(self, offload_tags: Optional[Union[tuple[str, ...], str]] = None) -> None:
201 + def sleep(self, offload_tags: tuple[str, ...] | str | None = None) -> None:
202 """
203 Put the allocator in sleep mode.
204 All data in the memory allocation with the specified tag will be
@@ -247,7 +248,7 @@ class CuMemAllocator:
248 gc.collect()
249 torch.cuda.empty_cache()
250
250 - def wake_up(self, tags: Optional[list[str]] = None) -> None:
251 + def wake_up(self, tags: list[str] | None = None) -> None:
252 """
253 Wake up the allocator from sleep mode.
254 All data that is previously offloaded will be loaded back to GPU
@@ -272,7 +273,7 @@ class CuMemAllocator:
273 data.cpu_backup_tensor = None
274
275 @contextmanager
275 - def use_memory_pool(self, tag: Optional[str] = None):
276 + def use_memory_pool(self, tag: str | None = None):
277 """
278 A context manager to use the memory pool.
279 All memory allocation created inside the context will be allocated
vllm/distributed/communication_op.py
+3 -3
@@ -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 Any, Optional, Union
4 +from typing import Any
5
6 import torch
7 import torch.distributed
@@ -30,13 +30,13 @@ def tensor_model_parallel_reduce_scatter(
30
31 def tensor_model_parallel_gather(
32 input_: torch.Tensor, dst: int = 0, dim: int = -1
33 -) -> Optional[torch.Tensor]:
33 +) -> torch.Tensor | None:
34 """Gather the input tensor across model parallel group."""
35 return get_tp_group().gather(input_, dst, dim)
36
37
38 def broadcast_tensor_dict(
39 - tensor_dict: Optional[dict[Any, Union[torch.Tensor, Any]]] = None, src: int = 0
39 + tensor_dict: dict[Any, torch.Tensor | Any] | None = None, src: int = 0
40 ):
41 if not torch.distributed.is_initialized():
42 return tensor_dict
vllm/distributed/device_communicators/all2all.py
+2 -2
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, Optional
3 +from typing import Any
4
5 import torch
6 import torch.distributed as dist
@@ -368,7 +368,7 @@ class DeepEPLLAll2AllManager(DeepEPAll2AllManagerBase):
368 return handle
369
370 # DeepEP LL uses RDMA so no SMs are used for communication
371 - def max_sms_used(self) -> Optional[int]:
371 + def max_sms_used(self) -> int | None:
372 return 0
373
374
vllm/distributed/device_communicators/all_reduce_utils.py
+4 -4
@@ -10,7 +10,7 @@ import sys
10 import tempfile
11 from collections.abc import Sequence
12 from itertools import product
13 -from typing import Any, Optional
13 +from typing import Any
14
15 import torch
16 import torch.distributed as dist
@@ -86,7 +86,7 @@ def producer(
86 producer_queue,
87 consumer_queue,
88 result_queue,
89 - cuda_visible_devices: Optional[str] = None,
89 + cuda_visible_devices: str | None = None,
90 ):
91 if cuda_visible_devices is not None:
92 update_environment_variables({"CUDA_VISIBLE_DEVICES": cuda_visible_devices})
@@ -120,7 +120,7 @@ def consumer(
120 producer_queue,
121 consumer_queue,
122 result_queue,
123 - cuda_visible_devices: Optional[str] = None,
123 + cuda_visible_devices: str | None = None,
124 ):
125 if cuda_visible_devices is not None:
126 update_environment_variables({"CUDA_VISIBLE_DEVICES": cuda_visible_devices})
@@ -253,7 +253,7 @@ def can_actually_p2p(
253 # e.g. used by different vllm engines. The device id in the cache file is a
254 # **local** device id, i.e. from 0 to num_dev-1, where num_dev is the number
255 # of visible devices in the vllm engine.
256 -_gpu_p2p_access_cache: Optional[dict[str, bool]] = None
256 +_gpu_p2p_access_cache: dict[str, bool] | None = None
257
258
259 def gpu_p2p_access_check(src: int, tgt: int) -> bool:
vllm/distributed/device_communicators/base_device_communicator.py
+11 -12
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import threading
4 -from typing import Optional, Union
4 from weakref import WeakValueDictionary
5
6 import torch
@@ -75,7 +74,7 @@ class All2AllManagerBase:
74 def set_num_sms(self, num_sms: int):
75 pass
76
78 - def max_sms_used(self) -> Optional[int]:
77 + def max_sms_used(self) -> int | None:
78 return None # None means it could use the whole GPU
79
80 def combine(self, hidden_states: torch.Tensor, is_sequence_parallel: bool = False):
@@ -96,8 +95,8 @@ class DeviceCommunicatorBase:
95 def __init__(
96 self,
97 cpu_group: ProcessGroup,
99 - device: Optional[torch.device] = None,
100 - device_group: Optional[ProcessGroup] = None,
98 + device: torch.device | None = None,
99 + device_group: ProcessGroup | None = None,
100 unique_name: str = "",
101 ):
102 self.device = device or torch.device("cpu")
@@ -123,7 +122,7 @@ class DeviceCommunicatorBase:
122
123 self.is_ep_communicator = "ep" in unique_name
124 self.use_all2all = self.is_ep_communicator and use_ep
126 - self.all2all_manager: Optional[All2AllManagerBase] = None
125 + self.all2all_manager: All2AllManagerBase | None = None
126
127 def all_reduce(self, input_: torch.Tensor) -> torch.Tensor:
128 dist.all_reduce(input_, group=self.device_group)
@@ -156,10 +155,10 @@ class DeviceCommunicatorBase:
155
156 def all_gatherv(
157 self,
159 - input_: Union[torch.Tensor, list[torch.Tensor]],
158 + input_: torch.Tensor | list[torch.Tensor],
159 dim: int = 0,
161 - sizes: Optional[list[int]] = None,
162 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
160 + sizes: list[int] | None = None,
161 + ) -> torch.Tensor | list[torch.Tensor]:
162 raise NotImplementedError
163
164 def reduce_scatter(self, input_: torch.Tensor, dim: int = -1) -> torch.Tensor:
@@ -196,13 +195,13 @@ class DeviceCommunicatorBase:
195 return output_tensor.movedim(0, dim).contiguous()
196
197 def reduce_scatterv(
199 - self, input_: torch.Tensor, dim: int = -1, sizes: Optional[list[int]] = None
198 + self, input_: torch.Tensor, dim: int = -1, sizes: list[int] | None = None
199 ) -> torch.Tensor:
200 raise NotImplementedError
201
202 def gather(
203 self, input_: torch.Tensor, dst: int = 0, dim: int = -1
205 - ) -> Optional[torch.Tensor]:
204 + ) -> torch.Tensor | None:
205 """
206 NOTE: We assume that the input tensor is on the same device across
207 all the ranks.
@@ -231,7 +230,7 @@ class DeviceCommunicatorBase:
230 output_tensor = None
231 return output_tensor
232
234 - def send(self, tensor: torch.Tensor, dst: Optional[int] = None) -> None:
233 + def send(self, tensor: torch.Tensor, dst: int | None = None) -> None:
234 """Sends a tensor to the destination rank in a blocking way"""
235 """NOTE: `dst` is the local rank of the destination rank."""
236 if dst is None:
@@ -239,7 +238,7 @@ class DeviceCommunicatorBase:
238 torch.distributed.send(tensor, self.ranks[dst], self.device_group)
239
240 def recv(
242 - self, size: torch.Size, dtype: torch.dtype, src: Optional[int] = None
241 + self, size: torch.Size, dtype: torch.dtype, src: int | None = None
242 ) -> torch.Tensor:
243 """Receives a tensor from the source rank."""
244 """NOTE: `src` is the local rank of the source rank."""
vllm/distributed/device_communicators/cpu_communicator.py
+12 -12
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import os
5 -from typing import Any, Optional, Union
5 +from typing import Any
6
7 import torch
8 from torch.distributed import ProcessGroup
@@ -18,8 +18,8 @@ class CpuCommunicator(DeviceCommunicatorBase):
18 def __init__(
19 self,
20 cpu_group: ProcessGroup,
21 - device: Optional[torch.device] = None,
22 - device_group: Optional[ProcessGroup] = None,
21 + device: torch.device | None = None,
22 + device_group: ProcessGroup | None = None,
23 unique_name: str = "",
24 ):
25 super().__init__(cpu_group, device, device_group, unique_name)
@@ -38,7 +38,7 @@ class CpuCommunicator(DeviceCommunicatorBase):
38
39 def gather(
40 self, input_: torch.Tensor, dst: int = 0, dim: int = -1
41 - ) -> Optional[torch.Tensor]:
41 + ) -> torch.Tensor | None:
42 """
43 NOTE: We assume that the input tensor is on the same device across
44 all the ranks.
@@ -99,7 +99,7 @@ class CpuCommunicator(DeviceCommunicatorBase):
99
100 def send_tensor_dict(
101 self,
102 - tensor_dict: dict[str, Union[torch.Tensor, Any]],
102 + tensor_dict: dict[str, torch.Tensor | Any],
103 dst: int,
104 ) -> None:
105 return self.dist_module.send_tensor_dict(tensor_dict, dst)
@@ -107,7 +107,7 @@ class CpuCommunicator(DeviceCommunicatorBase):
107 def recv_tensor_dict(
108 self,
109 src: int,
110 - ) -> dict[str, Union[torch.Tensor, Any]]:
110 + ) -> dict[str, torch.Tensor | Any]:
111 return self.dist_module.recv_tensor_dict(src)
112
113
@@ -140,16 +140,16 @@ class _CPUSHMDistributed:
140 return handle
141
142 def all_reduce(
143 - self, input: torch.Tensor, group: Optional[ProcessGroup] = None
143 + self, input: torch.Tensor, group: ProcessGroup | None = None
144 ) -> None:
145 torch.ops._C.shm_allreduce(self.handle, input)
146
147 def gather(
148 self,
149 input: torch.Tensor,
150 - gather_list: Optional[list[torch.Tensor]],
150 + gather_list: list[torch.Tensor] | None,
151 dst: int = -1,
152 - group: Optional[ProcessGroup] = None,
152 + group: ProcessGroup | None = None,
153 ) -> None:
154 # Note: different from the torch gather, here we use local dst rank.
155 torch.ops._C.shm_gather(
@@ -163,13 +163,13 @@ class _CPUSHMDistributed:
163 self,
164 output: torch.Tensor,
165 input: torch.Tensor,
166 - group: Optional[ProcessGroup] = None,
166 + group: ProcessGroup | None = None,
167 ) -> None:
168 torch.ops._C.shm_all_gather(self.handle, input, output)
169
170 def send_tensor_dict(
171 self,
172 - tensor_dict: dict[str, Union[torch.Tensor, Any]],
172 + tensor_dict: dict[str, torch.Tensor | Any],
173 dst: int,
174 ) -> None:
175 key_list = list(tensor_dict.keys())
@@ -191,7 +191,7 @@ class _CPUSHMDistributed:
191 def recv_tensor_dict(
192 self,
193 src: int,
194 - ) -> dict[str, Union[torch.Tensor, Any]]:
194 + ) -> dict[str, torch.Tensor | Any]:
195 tensor_list = torch.ops._C.shm_recv_tensor_list(self.handle, src)
196
197 value_list: list[torch.Tensor] = tensor_list[:-1]
vllm/distributed/device_communicators/cuda_communicator.py
+12 -13
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import torch
6 from torch.distributed import ProcessGroup
@@ -26,8 +25,8 @@ class CudaCommunicator(DeviceCommunicatorBase):
25 def __init__(
26 self,
27 cpu_group: ProcessGroup,
29 - device: Optional[torch.device] = None,
30 - device_group: Optional[ProcessGroup] = None,
28 + device: torch.device | None = None,
29 + device_group: ProcessGroup | None = None,
30 unique_name: str = "",
31 ):
32 super().__init__(cpu_group, device, device_group, unique_name)
@@ -54,7 +53,7 @@ class CudaCommunicator(DeviceCommunicatorBase):
53 )
54 from vllm.distributed.device_communicators.symm_mem import SymmMemCommunicator
55
57 - self.pynccl_comm: Optional[PyNcclCommunicator] = None
56 + self.pynccl_comm: PyNcclCommunicator | None = None
57 if self.world_size > 1:
58 self.pynccl_comm = PyNcclCommunicator(
59 group=self.cpu_group,
@@ -63,9 +62,9 @@ class CudaCommunicator(DeviceCommunicatorBase):
62 if is_symmetric_memory_enabled():
63 register_nccl_symmetric_ops(self.pynccl_comm)
64
66 - self.ca_comm: Optional[CustomAllreduce] = None
67 - self.qr_comm: Optional[QuickAllReduce] = None
68 - self.symm_mem_comm: Optional[SymmMemCommunicator] = None
65 + self.ca_comm: CustomAllreduce | None = None
66 + self.qr_comm: QuickAllReduce | None = None
67 + self.symm_mem_comm: SymmMemCommunicator | None = None
68 if use_torch_symm_mem and current_platform.is_cuda():
69 self.symm_mem_comm = SymmMemCommunicator(
70 group=self.cpu_group,
@@ -201,7 +200,7 @@ class CudaCommunicator(DeviceCommunicatorBase):
200 return output.movedim(0, dim).contiguous()
201
202 def reduce_scatterv(
204 - self, input_: torch.Tensor, dim: int = -1, sizes: Optional[list[int]] = None
203 + self, input_: torch.Tensor, dim: int = -1, sizes: list[int] | None = None
204 ):
205 world_size = self.world_size
206 pynccl_comm = self.pynccl_comm
@@ -235,7 +234,7 @@ class CudaCommunicator(DeviceCommunicatorBase):
234 # Reshape before returning
235 return output.movedim(0, dim).contiguous()
236
238 - def send(self, tensor: torch.Tensor, dst: Optional[int] = None) -> None:
237 + def send(self, tensor: torch.Tensor, dst: int | None = None) -> None:
238 """Sends a tensor to the destination rank in a blocking way"""
239 """NOTE: `dst` is the local rank of the destination rank."""
240 if dst is None:
@@ -248,7 +247,7 @@ class CudaCommunicator(DeviceCommunicatorBase):
247 torch.distributed.send(tensor, self.ranks[dst], self.device_group)
248
249 def recv(
251 - self, size: torch.Size, dtype: torch.dtype, src: Optional[int] = None
250 + self, size: torch.Size, dtype: torch.dtype, src: int | None = None
251 ) -> torch.Tensor:
252 """Receives a tensor from the source rank."""
253 """NOTE: `src` is the local rank of the source rank."""
@@ -274,9 +273,9 @@ class CudaCommunicator(DeviceCommunicatorBase):
273
274 def all_gatherv(
275 self,
277 - input_: Union[torch.Tensor, list[torch.Tensor]],
276 + input_: torch.Tensor | list[torch.Tensor],
277 dim: int = 0,
279 - sizes: Optional[list[int]] = None,
278 + sizes: list[int] | None = None,
279 ):
280 if dim != 0:
281 raise NotImplementedError("only dim 0 all-gatherv is supported")
@@ -289,7 +288,7 @@ class CudaCommunicator(DeviceCommunicatorBase):
288 if sizes is not None and all(s == sizes[0] for s in sizes):
289 sizes = None
290
292 - def _all_gather_single(input_: torch.Tensor, sizes: Optional[list[int]] = None):
291 + def _all_gather_single(input_: torch.Tensor, sizes: list[int] | None = None):
292 input_size = input_.size()
293 if sizes is not None:
294 assert len(sizes) == world_size
vllm/distributed/device_communicators/cuda_wrapper.py
+3 -3
@@ -7,7 +7,7 @@ convenient for use when we just need to call a few functions.
7
8 import ctypes
9 from dataclasses import dataclass
10 -from typing import Any, Optional
10 +from typing import Any
11
12 # this line makes it possible to directly load `libcudart.so` using `ctypes`
13 import torch # noqa
@@ -36,7 +36,7 @@ class Function:
36 argtypes: list[Any]
37
38
39 -def find_loaded_library(lib_name) -> Optional[str]:
39 +def find_loaded_library(lib_name) -> str | None:
40 """
41 According to according to https://man7.org/linux/man-pages/man5/proc_pid_maps.5.html,
42 the file `/proc/self/maps` contains the memory maps of the process, which includes the
@@ -113,7 +113,7 @@ class CudaRTLibrary:
113 # to the corresponding dictionary
114 path_to_dict_mapping: dict[str, dict[str, Any]] = {}
115
116 - def __init__(self, so_file: Optional[str] = None):
116 + def __init__(self, so_file: str | None = None):
117 if so_file is None:
118 so_file = find_loaded_library("libcudart")
119 if so_file is None:
vllm/distributed/device_communicators/custom_all_reduce.py
+6 -7
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from contextlib import contextmanager
5 -from typing import Optional, Union
5
6 import torch
7 import torch.distributed as dist
@@ -55,7 +54,7 @@ class CustomAllreduce:
54 def __init__(
55 self,
56 group: ProcessGroup,
58 - device: Union[int, str, torch.device],
57 + device: int | str | torch.device,
58 max_size=8192 * 1024,
59 symm_mem_enabled=False,
60 ) -> None:
@@ -260,7 +259,7 @@ class CustomAllreduce:
259 )
260 return out
261
263 - def custom_all_reduce(self, input: torch.Tensor) -> Optional[torch.Tensor]:
262 + def custom_all_reduce(self, input: torch.Tensor) -> torch.Tensor | None:
263 """The main allreduce API that provides support for cuda graph."""
264 # When custom allreduce is disabled, this will be None.
265 if self.disabled or not self.should_custom_ar(input):
@@ -292,8 +291,8 @@ class CustomAllreduce:
291 @staticmethod
292 def create_shared_buffer(
293 size_in_bytes: int,
295 - group: Optional[ProcessGroup] = None,
296 - uncached: Optional[bool] = False,
294 + group: ProcessGroup | None = None,
295 + uncached: bool | None = False,
296 ) -> list[int]:
297 pointer, handle = ops.allocate_shared_buffer_and_handle(size_in_bytes)
298
@@ -313,8 +312,8 @@ class CustomAllreduce:
312 @staticmethod
313 def free_shared_buffer(
314 pointers: list[int],
316 - group: Optional[ProcessGroup] = None,
317 - rank: Optional[int] = None,
315 + group: ProcessGroup | None = None,
316 + rank: int | None = None,
317 ) -> None:
318 if rank is None:
319 rank = dist.get_rank(group=group)
vllm/distributed/device_communicators/pynccl.py
+3 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 # ===================== import region =====================
6 import torch
@@ -59,9 +58,9 @@ def register_nccl_symmetric_ops(pynccl_comm):
58 class PyNcclCommunicator:
59 def __init__(
60 self,
62 - group: Union[ProcessGroup, StatelessProcessGroup],
63 - device: Union[int, str, torch.device],
64 - library_path: Optional[str] = None,
61 + group: ProcessGroup | StatelessProcessGroup,
62 + device: int | str | torch.device,
63 + library_path: str | None = None,
64 ):
65 """
66 Args:
vllm/distributed/device_communicators/pynccl_allocator.py
+2 -2
@@ -3,7 +3,7 @@
3 import atexit
4 import contextlib
5 import tempfile
6 -from typing import Any, Optional
6 +from typing import Any
7
8 import torch
9 from packaging import version
@@ -141,7 +141,7 @@ class nccl_symm_mem_context:
141 or version.parse(torch.__version__) < version.parse("2.8.0.a0")
142 )
143 if self.disabled:
144 - self.pynccl_comm: Optional[PyNcclCommunicator] = None
144 + self.pynccl_comm: PyNcclCommunicator | None = None
145 self._mem_pool_ctx: contextlib.AbstractContextManager[Any] = (
146 contextlib.nullcontext()
147 )
vllm/distributed/device_communicators/pynccl_wrapper.py
+2 -2
@@ -25,7 +25,7 @@
25 import ctypes
26 import platform
27 from dataclasses import dataclass
28 -from typing import Any, Optional
28 +from typing import Any
29
30 import torch
31 from torch.distributed import ReduceOp
@@ -305,7 +305,7 @@ class NCCLLibrary:
305 # to the corresponding dictionary
306 path_to_dict_mapping: dict[str, dict[str, Any]] = {}
307
308 - def __init__(self, so_file: Optional[str] = None):
308 + def __init__(self, so_file: str | None = None):
309 so_file = so_file or find_nccl_library()
310
311 try:
vllm/distributed/device_communicators/quick_all_reduce.py
+1 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from enum import Enum
5 -from typing import Union
5
6 import torch
7 import torch.distributed as dist
@@ -58,9 +57,7 @@ class QuickAllReduce:
57 (torch.bfloat16, 8): [16 * MB, 2048 * MB, 2048 * MB, 2048 * MB],
58 }
59
61 - def __init__(
62 - self, group: ProcessGroup, device: Union[int, str, torch.device]
63 - ) -> None:
60 + def __init__(self, group: ProcessGroup, device: int | str | torch.device) -> None:
61 """
62 Custom allreduce provides non-destructive acceleration and is
63 available for CUDA and ROCm MI300 series.
vllm/distributed/device_communicators/ray_communicator.py
+6 -6
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import uuid
4 -from typing import Any, Optional
4 +from typing import Any
5
6 import ray
7 import torch
@@ -27,15 +27,15 @@ class RayPPCommunicator(Communicator):
27 This class is not thread-safe.
28 """
29
30 - _comm: Optional[DeviceCommunicatorBase]
30 + _comm: DeviceCommunicatorBase | None
31
32 def __init__(
33 self,
34 world_size: int,
35 comm_id: Any,
36 - rank: Optional[int],
36 + rank: int | None,
37 actor_handles: list["ray.actor.ActorHandle"],
38 - cuda_stream: Optional[torch.cuda.Stream],
38 + cuda_stream: torch.cuda.Stream | None,
39 use_communication_streams: bool = False,
40 ):
41 """
@@ -56,7 +56,7 @@ class RayPPCommunicator(Communicator):
56 This is not supported.
57 """
58 self._world_size = world_size
59 - self._rank: Optional[int] = None
59 + self._rank: int | None = None
60 self._actor_handles = actor_handles
61 if use_communication_streams:
62 raise NotImplementedError("use_communication_streams is not supported")
@@ -143,7 +143,7 @@ class RayPPCommunicator(Communicator):
143 else:
144 raise ValueError(f"Actor {actor} not found in communicator group")
145
146 - def get_self_rank(self) -> Optional[int]:
146 + def get_self_rank(self) -> int | None:
147 """
148 Return this actor's rank.
149 """
vllm/distributed/device_communicators/shm_broadcast.py
+15 -15
@@ -7,7 +7,7 @@ from contextlib import contextmanager
7 from dataclasses import dataclass, field
8 from multiprocessing import shared_memory
9 from threading import Event
10 -from typing import Any, Optional, Union
10 +from typing import Any
11 from unittest.mock import patch
12
13 import torch
@@ -80,7 +80,7 @@ class ShmRingBuffer:
80 n_reader: int,
81 max_chunk_bytes: int,
82 max_chunks: int,
83 - name: Optional[str] = None,
83 + name: str | None = None,
84 ):
85 """
86 A shared memory ring buffer implementation for broadcast communication.
@@ -213,9 +213,9 @@ class ShmRingBuffer:
213 class Handle:
214 local_reader_ranks: list[int] = field(default_factory=list)
215
216 - buffer_handle: Optional[tuple[int, int, int, str]] = None
217 - local_subscribe_addr: Optional[str] = None
218 - remote_subscribe_addr: Optional[str] = None
216 + buffer_handle: tuple[int, int, int, str] | None = None
217 + local_subscribe_addr: str | None = None
218 + remote_subscribe_addr: str | None = None
219 remote_addr_ipv6: bool = False
220
221
@@ -224,10 +224,10 @@ class MessageQueue:
224 self,
225 n_reader, # number of all readers
226 n_local_reader, # number of local readers through shared memory
227 - local_reader_ranks: Optional[list[int]] = None,
227 + local_reader_ranks: list[int] | None = None,
228 max_chunk_bytes: int = 1024 * 1024 * 10,
229 max_chunks: int = 10,
230 - connect_ip: Optional[str] = None,
230 + connect_ip: str | None = None,
231 ):
232 if local_reader_ranks is None:
233 local_reader_ranks = list(range(n_local_reader))
@@ -384,7 +384,7 @@ class MessageQueue:
384 assert recv == b"READY"
385
386 @contextmanager
387 - def acquire_write(self, timeout: Optional[float] = None):
387 + def acquire_write(self, timeout: float | None = None):
388 assert self._is_writer, "Only writers can acquire write"
389 start_time = time.monotonic()
390 n_warning = 1
@@ -444,8 +444,8 @@ class MessageQueue:
444 @contextmanager
445 def acquire_read(
446 self,
447 - timeout: Optional[float] = None,
448 - cancel: Optional[Event] = None,
447 + timeout: float | None = None,
448 + cancel: Event | None = None,
449 indefinite: bool = False,
450 ):
451 assert self._is_local_reader, "Only readers can acquire read"
@@ -502,7 +502,7 @@ class MessageQueue:
502 self._read_spin_timer.record_activity()
503 break
504
505 - def enqueue(self, obj, timeout: Optional[float] = None):
505 + def enqueue(self, obj, timeout: float | None = None):
506 """Write to message queue with optional timeout (in seconds)"""
507 assert self._is_writer, "Only writers can enqueue"
508 serialized_obj = pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL)
@@ -520,8 +520,8 @@ class MessageQueue:
520
521 def dequeue(
522 self,
523 - timeout: Optional[float] = None,
524 - cancel: Optional[Event] = None,
523 + timeout: float | None = None,
524 + cancel: Event | None = None,
525 indefinite: bool = False,
526 ):
527 """Read from message queue with optional timeout (in seconds)"""
@@ -542,7 +542,7 @@ class MessageQueue:
542 return obj
543
544 @staticmethod
545 - def recv(socket: zmq.Socket, timeout: Optional[float]) -> Any:
545 + def recv(socket: zmq.Socket, timeout: float | None) -> Any:
546 timeout_ms = None if timeout is None else int(timeout * 1000)
547 if not socket.poll(timeout=timeout_ms):
548 raise TimeoutError
@@ -558,7 +558,7 @@ class MessageQueue:
558
559 @staticmethod
560 def create_from_process_group(
561 - pg: Union[ProcessGroup, StatelessProcessGroup],
561 + pg: ProcessGroup | StatelessProcessGroup,
562 max_chunk_bytes,
563 max_chunks,
564 writer_rank=0,
vllm/distributed/device_communicators/shm_object_storage.py
+8 -10
@@ -3,13 +3,13 @@
3
4 import pickle
5 from abc import ABC, abstractmethod
6 -from collections.abc import Iterable
6 +from collections.abc import Callable, Iterable
7 from contextlib import contextmanager
8 from dataclasses import dataclass
9 from itertools import chain
10 from multiprocessing import shared_memory
11 from multiprocessing.synchronize import Lock as LockType
12 -from typing import Any, Callable, Optional, Union
12 +from typing import Any
13 from unittest.mock import patch
14
15 import torch
@@ -109,7 +109,7 @@ class SingleWriterShmRingBuffer:
109 def __init__(
110 self,
111 data_buffer_size: int,
112 - name: Optional[str] = None,
112 + name: str | None = None,
113 create: bool = False,
114 ):
115 self.data_buffer_size = data_buffer_size
@@ -252,7 +252,7 @@ class SingleWriterShmRingBuffer:
252 def free_buf(
253 self,
254 is_free_fn: Callable[[int, memoryview], bool],
255 - nbytes: Optional[int] = None,
255 + nbytes: int | None = None,
256 ) -> Iterable[int]:
257 """
258 Free a buffer of the given size. This is a no-op in shared memory,
@@ -340,9 +340,7 @@ class MsgpackSerde(ObjectSerde):
340 self.mm_decoder = MsgpackDecoder(MultiModalKwargsItem)
341 self._mm_kwargs_item_cls = MultiModalKwargsItem
342
343 - def serialize(
344 - self, value: Any
345 - ) -> tuple[Union[bytes, list[bytes]], int, bytes, int]:
343 + def serialize(self, value: Any) -> tuple[bytes | list[bytes], int, bytes, int]:
344 len_arr = None
345 if isinstance(value, (torch.Tensor, self._mm_kwargs_item_cls)):
346 type_name = type(value).__name__
@@ -396,7 +394,7 @@ class ShmObjectStorageHandle:
394 n_readers: int
395 ring_buffer_handle: tuple[int, str]
396 serde_class: type[ObjectSerde]
399 - reader_lock: Optional[LockType]
397 + reader_lock: LockType | None
398
399
400 class SingleWriterShmObjectStorage:
@@ -444,7 +442,7 @@ class SingleWriterShmObjectStorage:
442 n_readers: int,
443 ring_buffer: SingleWriterShmRingBuffer,
444 serde_class: type[ObjectSerde] = MsgpackSerde,
447 - reader_lock: Optional[LockType] = None,
445 + reader_lock: LockType | None = None,
446 ):
447 """
448 Initialize the object storage.
@@ -492,7 +490,7 @@ class SingleWriterShmObjectStorage:
490
491 def copy_to_buffer(
492 self,
495 - data: Union[bytes, list[bytes]],
493 + data: bytes | list[bytes],
494 data_bytes: int,
495 metadata: bytes,
496 md_bytes: int,
vllm/distributed/device_communicators/symm_mem.py
+5 -6
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional, Union
3
4 import torch
5 import torch.distributed as dist
@@ -31,10 +30,10 @@ class SymmMemCommunicator:
30 def __init__(
31 self,
32 group: ProcessGroup,
34 - device: Union[int, str, torch.device],
33 + device: int | str | torch.device,
34 # add options for testing
36 - force_multimem: Optional[bool] = None,
37 - max_size_override: Optional[int] = None,
35 + force_multimem: bool | None = None,
36 + max_size_override: int | None = None,
37 ):
38 self.disabled = True
39
@@ -108,8 +107,8 @@ class SymmMemCommunicator:
107 return inp_size < self.max_size
108
109 def all_reduce(
111 - self, inp: torch.Tensor, *, out: Optional[torch.Tensor] = None
112 - ) -> Optional[torch.Tensor]:
110 + self, inp: torch.Tensor, *, out: torch.Tensor | None = None
111 + ) -> torch.Tensor | None:
112 if not self.should_use_symm_mem(inp):
113 return None
114 if out is None:
vllm/distributed/device_communicators/tpu_communicator.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import os
5 -from typing import Optional
5
6 import torch
7 from torch.distributed import ProcessGroup
@@ -39,8 +38,8 @@ class TpuCommunicator(DeviceCommunicatorBase):
38 def __init__(
39 self,
40 cpu_group: ProcessGroup,
42 - device: Optional[torch.device] = None,
43 - device_group: Optional[ProcessGroup] = None,
41 + device: torch.device | None = None,
42 + device_group: ProcessGroup | None = None,
43 unique_name: str = "",
44 ):
45 super().__init__(cpu_group, device, device_group, unique_name)
vllm/distributed/device_communicators/xpu_communicator.py
+3 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6 import torch.distributed as dist
@@ -19,8 +18,8 @@ class XpuCommunicator(DeviceCommunicatorBase):
18 def __init__(
19 self,
20 cpu_group: ProcessGroup,
22 - device: Optional[torch.device] = None,
23 - device_group: Optional[ProcessGroup] = None,
21 + device: torch.device | None = None,
22 + device_group: ProcessGroup | None = None,
23 unique_name: str = "",
24 ):
25 super().__init__(cpu_group, device, device_group, unique_name)
@@ -45,7 +44,7 @@ class XpuCommunicator(DeviceCommunicatorBase):
44
45 def gather(
46 self, input_: torch.Tensor, dst: int = 0, dim: int = -1
48 - ) -> Optional[torch.Tensor]:
47 + ) -> torch.Tensor | None:
48 assert -input_.dim() <= dim < input_.dim(), (
49 f"Invalid dim ({dim}) for input tensor with shape {input_.size()}"
50 )
vllm/distributed/eplb/eplb_state.py
+7 -8
@@ -29,7 +29,6 @@ physical experts.
29 import time
30 from collections.abc import Sequence
31 from dataclasses import dataclass
32 -from typing import Optional, Union
32
33 import torch
34 from torch.distributed import ProcessGroup, all_reduce
@@ -186,9 +185,9 @@ class EplbState:
185 model: MixtureOfExperts,
186 device: torch.device,
187 parallel_config: ParallelConfig,
189 - global_expert_load: Optional[torch.Tensor] = None,
190 - old_global_expert_indices: Optional[torch.Tensor] = None,
191 - rank_mapping: Optional[dict[int, int]] = None,
188 + global_expert_load: torch.Tensor | None = None,
189 + old_global_expert_indices: torch.Tensor | None = None,
190 + rank_mapping: dict[int, int] | None = None,
191 ) -> "EplbState":
192 """
193 Build the initial EPLB state.
@@ -439,9 +438,9 @@ class EplbState:
438 model: MixtureOfExperts,
439 is_profile: bool = False,
440 execute_shuffle: bool = True,
442 - global_expert_load: Optional[torch.Tensor] = None,
443 - rank_mapping: Optional[dict[int, int]] = None,
444 - ) -> Optional[torch.Tensor]:
441 + global_expert_load: torch.Tensor | None = None,
442 + rank_mapping: dict[int, int] | None = None,
443 + ) -> torch.Tensor | None:
444 """
445 Rearrange the experts according to the current load.
446 """
@@ -611,7 +610,7 @@ class EplbState:
610
611
612 def _node_count_with_rank_mapping(
614 - pg: Union[ProcessGroup, StatelessProcessGroup],
613 + pg: ProcessGroup | StatelessProcessGroup,
614 rank_mapping: dict[int, int],
615 ) -> int:
616 if isinstance(pg, ProcessGroup):
vllm/distributed/eplb/rebalance_execute.py
+1 -2
@@ -8,7 +8,6 @@ This involves the exchange of expert weights between GPUs.
8
9 from collections.abc import Iterable, MutableSequence, Sequence
10 from functools import partial
11 -from typing import Optional
11
12 import torch
13 from torch.distributed import (
@@ -253,7 +252,7 @@ def rearrange_expert_weights_inplace(
252 expert_weights: Sequence[Iterable[torch.Tensor]],
253 ep_group: ProcessGroup,
254 is_profile: bool = False,
256 - rank_mapping: Optional[dict[int, int]] = None,
255 + rank_mapping: dict[int, int] | None = None,
256 ) -> None:
257 """
258 Rearranges the expert weights in place according to the new expert indices.
vllm/distributed/kv_events.py
+15 -14
@@ -6,10 +6,11 @@ import threading
6 import time
7 from abc import ABC, abstractmethod
8 from collections import deque
9 +from collections.abc import Callable
10 from dataclasses import asdict
11 from itertools import count
12 from queue import Queue
12 -from typing import Any, Callable, Optional, Union
13 +from typing import Any
14
15 import msgspec
16 import zmq
@@ -29,7 +30,7 @@ class EventBatch(
30 ):
31 ts: float
32 events: list[Any]
32 - data_parallel_rank: Optional[int] = None
33 + data_parallel_rank: int | None = None
34
35
36 class KVCacheEvent(
@@ -47,16 +48,16 @@ MEDIUM_GPU = "GPU"
48
49 class BlockStored(KVCacheEvent):
50 block_hashes: list[ExternalBlockHash]
50 - parent_block_hash: Optional[ExternalBlockHash]
51 + parent_block_hash: ExternalBlockHash | None
52 token_ids: list[int]
53 block_size: int
53 - lora_id: Optional[int]
54 - medium: Optional[str]
54 + lora_id: int | None
55 + medium: str | None
56
57
58 class BlockRemoved(KVCacheEvent):
59 block_hashes: list[ExternalBlockHash]
59 - medium: Optional[str]
60 + medium: str | None
61
62
63 class AllBlocksCleared(KVCacheEvent):
@@ -64,7 +65,7 @@ class AllBlocksCleared(KVCacheEvent):
65
66
67 class KVEventBatch(EventBatch):
67 - events: list[Union[BlockStored, BlockRemoved, AllBlocksCleared]]
68 + events: list[BlockStored | BlockRemoved | AllBlocksCleared]
69
70
71 class EventPublisher(ABC):
@@ -139,7 +140,7 @@ class ZmqEventPublisher(EventPublisher):
140 self,
141 data_parallel_rank: int,
142 endpoint: str = "tcp://*:5557",
142 - replay_endpoint: Optional[str] = None,
143 + replay_endpoint: str | None = None,
144 buffer_steps: int = 10_000,
145 hwm: int = 100_000,
146 max_queue_size: int = 100_000,
@@ -147,13 +148,13 @@ class ZmqEventPublisher(EventPublisher):
148 ) -> None:
149 # Storage
150 super().__init__(data_parallel_rank)
150 - self._event_queue = Queue[Optional[EventBatch]](maxsize=max_queue_size)
151 + self._event_queue = Queue[EventBatch | None](maxsize=max_queue_size)
152 self._buffer = deque[tuple[int, bytes]](maxlen=buffer_steps)
153
154 # ZMQ sockets
155 self._ctx = zmq.Context.instance()
155 - self._pub: Optional[zmq.Socket] = None
156 - self._replay: Optional[zmq.Socket] = None
156 + self._pub: zmq.Socket | None = None
157 + self._replay: zmq.Socket | None = None
158 self._dp_rank = data_parallel_rank
159
160 self._endpoint = self.offset_endpoint_port(endpoint, self._dp_rank)
@@ -303,8 +304,8 @@ class ZmqEventPublisher(EventPublisher):
304
305 @staticmethod
306 def offset_endpoint_port(
306 - endpoint: Optional[str], data_parallel_rank: int
307 - ) -> Optional[str]:
307 + endpoint: str | None, data_parallel_rank: int
308 + ) -> str | None:
309 """Helper function to offset the port in an endpoint by
310 the data parallel rank.
311
@@ -349,7 +350,7 @@ class EventPublisherFactory:
350
351 @classmethod
352 def create(
352 - cls, config: Optional[KVEventsConfig], data_parallel_rank: int = 0
353 + cls, config: KVEventsConfig | None, data_parallel_rank: int = 0
354 ) -> EventPublisher:
355 """Create publisher from a config mapping."""
356 if not config:
vllm/distributed/kv_transfer/kv_connector/factory.py
+2 -1
@@ -2,7 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import importlib
5 -from typing import TYPE_CHECKING, Callable
5 +from collections.abc import Callable
6 +from typing import TYPE_CHECKING
7
8 import vllm.envs as envs
9 from vllm.distributed.kv_transfer.kv_connector.base import (
vllm/distributed/kv_transfer/kv_connector/utils.py
+5 -5
@@ -7,7 +7,7 @@ KV cache helper for store.
7 from collections import defaultdict
8 from collections.abc import Sequence
9 from concurrent.futures import CancelledError, Future
10 -from typing import Literal, Optional, Union, cast
10 +from typing import Literal, cast
11
12 import torch
13
@@ -136,7 +136,7 @@ class KVOutputAggregator:
136 # Aggregate kv_connector_output from all workers
137
138 def update_finished_set(
139 - req_ids: Optional[set[str]],
139 + req_ids: set[str] | None,
140 remaining_count_dict: dict[str, int],
141 finished_set: set[str],
142 ) -> None:
@@ -197,7 +197,7 @@ class KVOutputAggregator:
197 to the respective list of outputs."""
198 result_future: Future[ModelRunnerOutput] = Future()
199
200 - outputs: list[Optional[ModelRunnerOutput]] = [None] * len(output_futures)
200 + outputs: list[ModelRunnerOutput | None] = [None] * len(output_futures)
201
202 def make_callback(idx):
203 def callback(fut):
@@ -230,8 +230,8 @@ class KVOutputAggregator:
230 def _make_src_and_dst_indices(
231 src_block_ids: list[int],
232 dst_block_ids: list[int],
233 - src_device: Union[torch.device, str],
234 - dst_device: Union[torch.device, str],
233 + src_device: torch.device | str,
234 + dst_device: torch.device | str,
235 ) -> tuple[torch.Tensor, torch.Tensor]:
236 src_indices = torch.tensor(src_block_ids, device=src_device, dtype=torch.int64)
237 dst_indices = torch.tensor(dst_block_ids, device=dst_device, dtype=torch.int64)
vllm/distributed/kv_transfer/kv_connector/v1/base.py
+9 -9
@@ -37,8 +37,8 @@ The class provides the following primitives:
37
38 import enum
39 from abc import ABC, abstractmethod
40 -from collections.abc import Iterable
41 -from typing import TYPE_CHECKING, Any, Callable, Literal, Optional
40 +from collections.abc import Callable, Iterable
41 +from typing import TYPE_CHECKING, Any, Literal, Optional
42
43 import torch
44
@@ -93,7 +93,7 @@ class KVConnectorBase_V1(ABC):
93 "Initializing KVConnectorBase_V1. This API is experimental and "
94 "subject to change in the future as we iterate the design."
95 )
96 - self._connector_metadata: Optional[KVConnectorMetadata] = None
96 + self._connector_metadata: KVConnectorMetadata | None = None
97 self._vllm_config = vllm_config
98 self._role = role
99
@@ -222,7 +222,7 @@ class KVConnectorBase_V1(ABC):
222
223 def get_finished(
224 self, finished_req_ids: set[str]
225 - ) -> tuple[Optional[set[str]], Optional[set[str]]]:
225 + ) -> tuple[set[str] | None, set[str] | None]:
226 """
227 Notifies worker-side connector ids of requests that have
228 finished generating tokens on the worker.
@@ -281,7 +281,7 @@ class KVConnectorBase_V1(ABC):
281 self,
282 request: "Request",
283 num_computed_tokens: int,
284 - ) -> tuple[Optional[int], bool]:
284 + ) -> tuple[int | None, bool]:
285 """
286 Get number of new tokens that can be loaded from the
287 external KV cache beyond the num_computed_tokens.
@@ -361,7 +361,7 @@ class KVConnectorBase_V1(ABC):
361 self,
362 request: "Request",
363 block_ids: list[int],
364 - ) -> tuple[bool, Optional[dict[str, Any]]]:
364 + ) -> tuple[bool, dict[str, Any] | None]:
365 """
366 Called exactly once when a request has finished, before its blocks are
367 freed.
@@ -388,7 +388,7 @@ class KVConnectorBase_V1(ABC):
388 return ()
389
390 @classmethod
391 - def get_required_kvcache_layout(cls, vllm_config: "VllmConfig") -> Optional[str]:
391 + def get_required_kvcache_layout(cls, vllm_config: "VllmConfig") -> str | None:
392 """
393 Get the required KV cache layout for this connector.
394 Args:
@@ -406,7 +406,7 @@ class KVConnectorBase_V1(ABC):
406 )
407 return None
408
409 - def get_finished_count(self) -> Optional[int]:
409 + def get_finished_count(self) -> int | None:
410 """
411 Get the count of requests expected to complete send/receive operations
412 via this connector.
@@ -419,7 +419,7 @@ class KVConnectorBase_V1(ABC):
419
420 @classmethod
421 def build_kv_connector_stats(
422 - cls, data: Optional[dict[str, Any]] = None
422 + cls, data: dict[str, Any] | None = None
423 ) -> Optional["KVConnectorStats"]:
424 """
425 KVConnectorStats resolution method. This method allows dynamically
vllm/distributed/kv_transfer/kv_connector/v1/lmcache_connector.py
+4 -4
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import TYPE_CHECKING, Any, Optional
3 +from typing import TYPE_CHECKING, Any
4
5 import torch
6 from lmcache.integration.vllm.vllm_v1_adapter import LMCacheConnectorV1Impl
@@ -96,7 +96,7 @@ class LMCacheConnectorV1(KVConnectorBase_V1):
96
97 def get_finished(
98 self, finished_req_ids: set[str]
99 - ) -> tuple[Optional[set[str]], Optional[set[str]]]:
99 + ) -> tuple[set[str] | None, set[str] | None]:
100 """
101 Notifies worker-side connector ids of requests that have
102 finished generating tokens.
@@ -117,7 +117,7 @@ class LMCacheConnectorV1(KVConnectorBase_V1):
117 self,
118 request: "Request",
119 num_computed_tokens: int,
120 - ) -> tuple[Optional[int], bool]:
120 + ) -> tuple[int | None, bool]:
121 """
122 Get number of new tokens that can be loaded from the
123 external KV cache beyond the num_computed_tokens.
@@ -161,7 +161,7 @@ class LMCacheConnectorV1(KVConnectorBase_V1):
161 self,
162 request: "Request",
163 block_ids: list[int],
164 - ) -> tuple[bool, Optional[dict[str, Any]]]:
164 + ) -> tuple[bool, dict[str, Any] | None]:
165 """
166 Called when a request has finished, before its blocks are freed.
167
vllm/distributed/kv_transfer/kv_connector/v1/metrics.py
+3 -3
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass, field
4 -from typing import Any, Optional, Union
4 +from typing import Any
5
6 from vllm.config.kv_transfer import KVTransferConfig
7 from vllm.distributed.kv_transfer.kv_connector.factory import KVConnectorFactory
@@ -32,7 +32,7 @@ class KVConnectorStats:
32 """
33 raise NotImplementedError
34
35 - def reduce(self) -> dict[str, Union[int, float]]:
35 + def reduce(self) -> dict[str, int | float]:
36 """
37 Reduce the observations collected during a time interval to one or
38 more representative values (eg avg/median/sum of the series).
@@ -58,7 +58,7 @@ class KVConnectorLogging:
58 self.reset()
59
60 def reset(self):
61 - self.transfer_stats_accumulator: Optional[KVConnectorStats] = None
61 + self.transfer_stats_accumulator: KVConnectorStats | None = None
62
63 def observe(self, transfer_stats_data: dict[str, Any]):
64 # Should not be called when a KVConnector is not configured.
vllm/distributed/kv_transfer/kv_connector/v1/multi_connector.py
+11 -11
@@ -3,7 +3,7 @@
3 import copy
4 from collections.abc import Iterable
5 from dataclasses import dataclass
6 -from typing import TYPE_CHECKING, Any, Optional
6 +from typing import TYPE_CHECKING, Any
7
8 import torch
9
@@ -33,7 +33,7 @@ logger = init_logger(__name__)
33 @dataclass
34 class MultiKVConnectorMetadata(KVConnectorMetadata):
35 metadata: tuple[KVConnectorMetadata, ...]
36 - extra_async_saves: Optional[dict[str, int]] = None
36 + extra_async_saves: dict[str, int] | None = None
37
38
39 @dataclass
@@ -130,7 +130,7 @@ class MultiConnector(KVConnectorBase_V1):
130 c.clear_connector_metadata()
131
132 def shutdown(self):
133 - exception: Optional[Exception] = None
133 + exception: Exception | None = None
134 for c in self._connectors:
135 try:
136 c.shutdown()
@@ -169,7 +169,7 @@ class MultiConnector(KVConnectorBase_V1):
169
170 def get_finished(
171 self, finished_req_ids: set[str]
172 - ) -> tuple[Optional[set[str]], Optional[set[str]]]:
172 + ) -> tuple[set[str] | None, set[str] | None]:
173 finished_sending: set[str] = set()
174 finished_recving: set[str] = set()
175 for c in self._connectors:
@@ -207,7 +207,7 @@ class MultiConnector(KVConnectorBase_V1):
207 self,
208 request: "Request",
209 num_computed_tokens: int,
210 - ) -> tuple[Optional[int], bool]:
210 + ) -> tuple[int | None, bool]:
211 to_return = (0, False)
212 for i, c in enumerate(self._connectors):
213 toks, load_async = c.get_num_new_matched_tokens(
@@ -258,7 +258,7 @@ class MultiConnector(KVConnectorBase_V1):
258 self,
259 request: "Request",
260 blocks: list[int],
261 - ) -> tuple[bool, Optional[dict[str, Any]]]:
261 + ) -> tuple[bool, dict[str, Any] | None]:
262 async_saves = 0
263 kv_txfer_params = None
264 for c in self._connectors:
@@ -286,7 +286,7 @@ class MultiConnector(KVConnectorBase_V1):
286 yield from c.take_events()
287
288 @classmethod
289 - def get_required_kvcache_layout(cls, vllm_config: "VllmConfig") -> Optional[str]:
289 + def get_required_kvcache_layout(cls, vllm_config: "VllmConfig") -> str | None:
290 """
291 Get the required KV cache layout for this connector.
292 Args:
@@ -323,17 +323,17 @@ class MultiConnector(KVConnectorBase_V1):
323
324 @classmethod
325 def build_kv_connector_stats(
326 - cls, data: Optional[dict[str, Any]] = None
327 - ) -> Optional[KVConnectorStats]:
326 + cls, data: dict[str, Any] | None = None
327 + ) -> KVConnectorStats | None:
328 return (
329 MultiKVConnectorStats(data=data)
330 if data is not None
331 else MultiKVConnectorStats()
332 )
333
334 - def get_kv_connector_stats(self) -> Optional[MultiKVConnectorStats]:
334 + def get_kv_connector_stats(self) -> MultiKVConnectorStats | None:
335 # Group connector stats by connector type.
336 - stats_by_connector: Optional[MultiKVConnectorStats] = None
336 + stats_by_connector: MultiKVConnectorStats | None = None
337 for c in self._connectors:
338 stats = c.get_kv_connector_stats()
339 if stats is None:
vllm/distributed/kv_transfer/kv_connector/v1/nixl_connector.py
+16 -16
@@ -13,7 +13,7 @@ from collections import defaultdict
13 from collections.abc import Iterator
14 from concurrent.futures import Future, ThreadPoolExecutor
15 from dataclasses import dataclass
16 -from typing import TYPE_CHECKING, Any, Optional, Union
16 +from typing import TYPE_CHECKING, Any
17
18 import msgspec
19 import numpy as np
@@ -153,10 +153,10 @@ class NixlConnector(KVConnectorBase_V1):
153 self.engine_id: EngineId = vllm_config.kv_transfer_config.engine_id
154
155 if role == KVConnectorRole.SCHEDULER:
156 - self.connector_scheduler: Optional[NixlConnectorScheduler] = (
156 + self.connector_scheduler: NixlConnectorScheduler | None = (
157 NixlConnectorScheduler(vllm_config, self.engine_id)
158 )
159 - self.connector_worker: Optional[NixlConnectorWorker] = None
159 + self.connector_worker: NixlConnectorWorker | None = None
160 elif role == KVConnectorRole.WORKER:
161 self.connector_scheduler = None
162 self.connector_worker = NixlConnectorWorker(vllm_config, self.engine_id)
@@ -189,7 +189,7 @@ class NixlConnector(KVConnectorBase_V1):
189
190 def get_num_new_matched_tokens(
191 self, request: "Request", num_computed_tokens: int
192 - ) -> tuple[Optional[int], bool]:
192 + ) -> tuple[int | None, bool]:
193 assert self.connector_scheduler is not None
194 return self.connector_scheduler.get_num_new_matched_tokens(
195 request, num_computed_tokens
@@ -214,7 +214,7 @@ class NixlConnector(KVConnectorBase_V1):
214 self,
215 request: "Request",
216 block_ids: list[int],
217 - ) -> tuple[bool, Optional[dict[str, Any]]]:
217 + ) -> tuple[bool, dict[str, Any] | None]:
218 assert self.connector_scheduler is not None
219 return self.connector_scheduler.request_finished(request, block_ids)
220
@@ -234,14 +234,14 @@ class NixlConnector(KVConnectorBase_V1):
234 assert self.connector_worker is not None
235 return self.connector_worker.get_finished()
236
237 - def get_kv_connector_stats(self) -> Optional[KVConnectorStats]:
237 + def get_kv_connector_stats(self) -> KVConnectorStats | None:
238 assert self.connector_worker is not None
239 return self.connector_worker.get_kv_connector_stats()
240
241 @classmethod
242 def build_kv_connector_stats(
243 - cls, data: Optional[dict[str, Any]] = None
244 - ) -> Optional[KVConnectorStats]:
243 + cls, data: dict[str, Any] | None = None
244 + ) -> KVConnectorStats | None:
245 return (
246 NixlKVConnectorStats(data=data)
247 if data is not None
@@ -445,7 +445,7 @@ class NixlConnectorScheduler:
445 self,
446 request: "Request",
447 block_ids: list[int],
448 - ) -> tuple[bool, Optional[dict[str, Any]]]:
448 + ) -> tuple[bool, dict[str, Any] | None]:
449 """
450 Once a request is finished, determine whether request blocks
451 should be freed now or will be sent asynchronously and freed later.
@@ -584,7 +584,7 @@ class NixlConnectorWorker:
584 )
585
586 # Note: host xfer buffer ops when use_host_buffer is True
587 - self.copy_blocks: Optional[CopyBlocksOp] = None
587 + self.copy_blocks: CopyBlocksOp | None = None
588
589 # Map of engine_id -> kv_caches_base_addr. For TP case, each local
590 # rank will still only pull from a single remote TP worker.
@@ -615,7 +615,7 @@ class NixlConnectorWorker:
615 self._reqs_to_process: set[ReqId] = set()
616
617 # Background thread for handling new handshake requests.
618 - self._nixl_handshake_listener_t: Optional[threading.Thread] = None
618 + self._nixl_handshake_listener_t: threading.Thread | None = None
619 # Background thread for initializing new NIXL handshakes.
620 self._handshake_initiation_executor = ThreadPoolExecutor(
621 # NIXL is not guaranteed to be thread-safe, limit 1 worker.
@@ -635,7 +635,7 @@ class NixlConnectorWorker:
635 # TODO(mgoin): remove this once we have hybrid memory allocator
636 # Optimization for models with local attention (Llama 4)
637 # List of block window sizes for each layer for local attention
638 - self.block_window_per_layer: list[Optional[int]] = []
638 + self.block_window_per_layer: list[int | None] = []
639 self.use_mla = self.model_config.use_mla
640
641 backend = get_attn_backend(
@@ -1472,7 +1472,7 @@ class NixlConnectorWorker:
1472 self._recving_transfers[request_id].append((handle, time.perf_counter()))
1473
1474 def _get_block_descs_ids(
1475 - self, engine_id: str, block_ids: list[int], layer_idx: Optional[int] = None
1475 + self, engine_id: str, block_ids: list[int], layer_idx: int | None = None
1476 ) -> np.ndarray:
1477 """
1478 Get the descs ids for a set of block ids.
@@ -1518,7 +1518,7 @@ class NixlConnectorWorker:
1518 block_len = self.block_len_per_layer[layer_idx]
1519 return block_len
1520
1521 - def get_kv_connector_stats(self) -> Optional[KVConnectorStats]:
1521 + def get_kv_connector_stats(self) -> KVConnectorStats | None:
1522 """
1523 Get the KV transfer stats for the connector.
1524 """
@@ -1559,7 +1559,7 @@ def zmq_ctx(socket_type: Any, addr: str) -> Iterator[zmq.Socket]:
1559 if socket_type not in (zmq.ROUTER, zmq.REQ):
1560 raise ValueError(f"Unexpected socket type: {socket_type}")
1561
1562 - ctx: Optional[zmq.Context] = None
1562 + ctx: zmq.Context | None = None
1563 try:
1564 ctx = zmq.Context() # type: ignore[attr-defined]
1565 yield make_zmq_socket(
@@ -1611,7 +1611,7 @@ class NixlKVConnectorStats(KVConnectorStats):
1611 accumulator.extend(v)
1612 return self
1613
1614 - def reduce(self) -> dict[str, Union[int, float]]:
1614 + def reduce(self) -> dict[str, int | float]:
1615 # Compute compact representative stats suitable for CLI logging
1616 if self.is_empty():
1617 return {
vllm/distributed/kv_transfer/kv_connector/v1/offloading_connector.py
+6 -6
@@ -4,7 +4,7 @@ from collections import defaultdict
4 from collections.abc import Iterable, Iterator
5 from dataclasses import dataclass
6 from itertools import islice
7 -from typing import Any, Optional
7 +from typing import Any
8
9 import torch
10
@@ -46,8 +46,8 @@ class OffloadingConnector(KVConnectorBase_V1):
46
47 spec = OffloadingSpecFactory.create_spec(vllm_config)
48
49 - self.connector_scheduler: Optional[OffloadingConnectorScheduler] = None
50 - self.connector_worker: Optional[OffloadingConnectorWorker] = None
49 + self.connector_scheduler: OffloadingConnectorScheduler | None = None
50 + self.connector_worker: OffloadingConnectorWorker | None = None
51 if role == KVConnectorRole.SCHEDULER:
52 self.connector_scheduler = OffloadingConnectorScheduler(spec)
53 elif role == KVConnectorRole.WORKER:
@@ -113,7 +113,7 @@ class OffloadingConnector(KVConnectorBase_V1):
113 self,
114 request: "Request",
115 block_ids: list[int],
116 - ) -> tuple[bool, Optional[dict[str, Any]]]:
116 + ) -> tuple[bool, dict[str, Any] | None]:
117 assert self.connector_scheduler is not None
118 return self.connector_scheduler.request_finished(request, block_ids)
119
@@ -148,7 +148,7 @@ class OffloadingConnectorScheduler:
148 self,
149 req: Request,
150 start_idx: int = 0,
151 - end_idx: Optional[int] = None,
151 + end_idx: int | None = None,
152 ) -> Iterable[BlockHash]:
153 return islice(
154 req.block_hashes,
@@ -354,7 +354,7 @@ class OffloadingConnectorScheduler:
354 self,
355 request: Request,
356 block_ids: list[int],
357 - ) -> tuple[bool, Optional[dict[str, Any]]]:
357 + ) -> tuple[bool, dict[str, Any] | None]:
358 """
359 Called when a request has finished, before its blocks are freed.
360
vllm/distributed/kv_transfer/kv_connector/v1/p2p/p2p_nccl_connector.py
+3 -3
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import TYPE_CHECKING, Any, Optional
5 +from typing import TYPE_CHECKING, Any
6
7 import regex as re
8 import torch
@@ -304,7 +304,7 @@ class P2pNcclConnector(KVConnectorBase_V1):
304
305 def get_finished(
306 self, finished_req_ids: set[str], **kwargs: Any
307 - ) -> tuple[Optional[set[str]], Optional[set[str]]]:
307 + ) -> tuple[set[str] | None, set[str] | None]:
308 """
309 Notifies worker-side connector ids of requests that have
310 finished generating tokens.
@@ -466,7 +466,7 @@ class P2pNcclConnector(KVConnectorBase_V1):
466 self,
467 request: "Request",
468 block_ids: list[int],
469 - ) -> tuple[bool, Optional[dict[str, Any]]]:
469 + ) -> tuple[bool, dict[str, Any] | None]:
470 """
471 Called when a request has finished, before its blocks are freed.
472
vllm/distributed/kv_transfer/kv_connector/v1/p2p/p2p_nccl_engine.py
+6 -7
@@ -5,11 +5,10 @@ import logging
5 import os
6 import threading
7 import time
8 -import typing
8 from collections import deque
9 from contextlib import contextmanager
10 from dataclasses import dataclass
12 -from typing import Any, Optional
11 +from typing import Any
12
13 import msgpack
14 import torch
@@ -77,7 +76,7 @@ class P2pNcclEngine:
76 config: KVTransferConfig,
77 hostname: str = "",
78 port_offset: int = 0,
80 - library_path: Optional[str] = None,
79 + library_path: str | None = None,
80 ) -> None:
81 self.config = config
82 self.rank = port_offset
@@ -187,7 +186,7 @@ class P2pNcclEngine:
186 self.nccl_num_channels,
187 )
188
190 - def create_connect(self, remote_address: typing.Optional[str] = None):
189 + def create_connect(self, remote_address: str | None = None):
190 assert remote_address is not None
191 if remote_address not in self.socks:
192 sock = self.context.socket(zmq.DEALER)
@@ -224,7 +223,7 @@ class P2pNcclEngine:
223 self,
224 tensor_id: str,
225 tensor: torch.Tensor,
227 - remote_address: typing.Optional[str] = None,
226 + remote_address: str | None = None,
227 ) -> bool:
228 if remote_address is None:
229 with self.recv_store_cv:
@@ -296,7 +295,7 @@ class P2pNcclEngine:
295 def recv_tensor(
296 self,
297 tensor_id: str,
299 - remote_address: typing.Optional[str] = None,
298 + remote_address: str | None = None,
299 ) -> torch.Tensor:
300 if self.send_type == "PUT" or self.send_type == "PUT_ASYNC":
301 start_time = time.time()
@@ -527,7 +526,7 @@ class P2pNcclEngine:
526
527 def get_finished(
528 self, finished_req_ids: set[str], no_compile_layers
530 - ) -> tuple[Optional[set[str]], Optional[set[str]]]:
529 + ) -> tuple[set[str] | None, set[str] | None]:
530 """
531 Notifies worker-side connector ids of requests that have
532 finished generating tokens.
vllm/distributed/kv_transfer/kv_connector/v1/shared_storage_connector.py
+2 -2
@@ -3,7 +3,7 @@
3 import hashlib
4 import os
5 from dataclasses import dataclass, field
6 -from typing import TYPE_CHECKING, Any, Optional
6 +from typing import TYPE_CHECKING, Any
7
8 import safetensors
9 import torch
@@ -249,7 +249,7 @@ class SharedStorageConnector(KVConnectorBase_V1):
249 self,
250 request: "Request",
251 num_computed_tokens: int,
252 - ) -> tuple[Optional[int], bool]:
252 + ) -> tuple[int | None, bool]:
253 """
254 Get number of new tokens that can be loaded from the
255 external KV cache beyond the num_computed_tokens.
vllm/distributed/kv_transfer/kv_lookup_buffer/base.py
+4 -5
@@ -14,7 +14,6 @@ These classes above are abstracted behind class `KVCacheBufferBase`.
14 """
15
16 from abc import ABC, abstractmethod
17 -from typing import Optional
17
18 import torch
19
@@ -98,8 +97,8 @@ class KVLookupBufferBase(KVCacheBufferBase):
97
98 @abstractmethod
99 def drop_select(
101 - self, input_tokens: Optional[torch.Tensor], roi: Optional[torch.Tensor]
102 - ) -> list[Optional[torch.Tensor]]:
100 + self, input_tokens: torch.Tensor | None, roi: torch.Tensor | None
101 + ) -> list[torch.Tensor | None]:
102 """Select and *drop* KV cache entries from the lookup buffer.
103
104 The functionality is similar to the following python statements
@@ -143,7 +142,7 @@ class KVStoreBufferBase(KVCacheBufferBase):
142 def put(
143 self,
144 key: str,
146 - value: Optional[torch.Tensor],
145 + value: torch.Tensor | None,
146 ) -> None:
147 """Store a key-value pair in the buffer.
148
@@ -163,7 +162,7 @@ class KVStoreBufferBase(KVCacheBufferBase):
162 def get(
163 self,
164 key: str,
166 - ) -> Optional[torch.Tensor]:
165 + ) -> torch.Tensor | None:
166 """Retrieve a value from the buffer by key.
167
168 Args:
vllm/distributed/kv_transfer/kv_lookup_buffer/mooncake_store.py
+3 -4
@@ -10,7 +10,6 @@ from this remote lookup buffer.
10 import json
11 import os
12 from dataclasses import dataclass
13 -from typing import Optional
13
14 import torch
15 from safetensors.torch import load as safetensors_load
@@ -110,7 +109,7 @@ class MooncakeStore(KVStoreBufferBase):
109 def put(
110 self,
111 key: str,
113 - value: Optional[torch.Tensor],
112 + value: torch.Tensor | None,
113 ) -> None:
114 # A message queue needs to be introduced before making it asynchronous.
115 if value is not None:
@@ -119,7 +118,7 @@ class MooncakeStore(KVStoreBufferBase):
118 def get(
119 self,
120 key: str,
122 - ) -> Optional[torch.Tensor]:
121 + ) -> torch.Tensor | None:
122 # A message queue needs to be introduced before making it asynchronous.
123 value = self._get_impl(key)
124 return value
@@ -142,7 +141,7 @@ class MooncakeStore(KVStoreBufferBase):
141 def _get_impl(
142 self,
143 key: str,
145 - ) -> Optional[torch.Tensor]:
144 + ) -> torch.Tensor | None:
145 """Get KVCache from Mooncake Store"""
146 try:
147 data = self.store.get(key)
vllm/distributed/kv_transfer/kv_lookup_buffer/simple_buffer.py
+5 -6
@@ -13,7 +13,6 @@ Key Features:
13
14 import threading
15 from collections import deque
16 -from typing import Optional, Union
16
17 import torch
18
@@ -46,7 +45,7 @@ class SimpleBuffer(KVLookupBufferBase):
45 self.buffer_cv = threading.Condition()
46 self.signal_pipe = signal_pipe
47 self.data_pipe = data_pipe
49 - self.request_handling_thread: Optional[threading.Thread] = None
48 + self.request_handling_thread: threading.Thread | None = None
49
50 self.normal_signal = torch.tensor([0], device="cpu")
51 self.end_signal = None
@@ -81,14 +80,14 @@ class SimpleBuffer(KVLookupBufferBase):
80
81 return 0
82
84 - def _send_tensor_and_dec_size(self, tensor: Optional[torch.Tensor]) -> None:
83 + def _send_tensor_and_dec_size(self, tensor: torch.Tensor | None) -> None:
84 assert tensor is not None, "Use self.data_pipe.send(None) instead"
85 self.buffer_size -= tensor.element_size() * tensor.numel()
86 if tensor.dtype == torch.bool:
87 tensor = tensor.float()
88 self.data_pipe.send_tensor(tensor)
89
91 - def _get_element_size(self, data: Optional[Union[list, torch.Tensor]]):
90 + def _get_element_size(self, data: list | torch.Tensor | None):
91 if isinstance(data, torch.Tensor):
92 return data.element_size() * data.numel()
93 if not data:
@@ -184,8 +183,8 @@ class SimpleBuffer(KVLookupBufferBase):
183 logger.debug("Closing drop_select_handler")
184
185 def drop_select(
187 - self, input_tokens: Optional[torch.Tensor], roi: Optional[torch.Tensor]
188 - ) -> list[Optional[torch.Tensor]]:
186 + self, input_tokens: torch.Tensor | None, roi: torch.Tensor | None
187 + ) -> list[torch.Tensor | None]:
188 assert self.request_handling_thread is None, (
189 "drop_select should be called by the KV cache consumer "
190 "(e.g. the decode vLLM instance)"
vllm/distributed/kv_transfer/kv_pipe/base.py
+2 -3
@@ -12,7 +12,6 @@ you can bypass this interface and directly start from `kv_lookup_buffer`.
12 """
13
14 from abc import ABC, abstractmethod
15 -from typing import Optional
15
16 import torch
17
@@ -24,7 +23,7 @@ class KVPipeBase(ABC):
23 """
24
25 @abstractmethod
27 - def send_tensor(self, tensor: Optional[torch.Tensor]) -> None:
26 + def send_tensor(self, tensor: torch.Tensor | None) -> None:
27 """Send a tensor, or None, via the pipe.
28
29 Need to support sending None -- important for error handling.
@@ -42,7 +41,7 @@ class KVPipeBase(ABC):
41 raise NotImplementedError
42
43 @abstractmethod
45 - def recv_tensor(self) -> Optional[torch.Tensor]:
44 + def recv_tensor(self) -> torch.Tensor | None:
45 """Receive a tensor (can be None) from the pipeline.
46
47 Returns:
vllm/distributed/kv_transfer/kv_pipe/mooncake_pipe.py
+6 -7
@@ -6,7 +6,6 @@ import os
6 import struct
7 from concurrent.futures import ThreadPoolExecutor
8 from dataclasses import dataclass
9 -from typing import Optional, Union
9
10 import torch
11 import zmq
@@ -26,7 +25,7 @@ NONE_INT = -150886311
25 class MooncakeTransferEngineConfig:
26 prefill_url: str
27 decode_url: str
29 - metadata_backend: Union[str, None]
28 + metadata_backend: str | None
29 metadata_server: str
30 protocol: str
31 device_name: str
@@ -143,7 +142,7 @@ class MooncakeTransferEngine:
142 metadata_server: str,
143 protocol: str,
144 device_name: str,
146 - metadata_backend: Union[str, None],
145 + metadata_backend: str | None,
146 ) -> None:
147 """Initialize the mooncake instance."""
148 if metadata_backend is None:
@@ -231,7 +230,7 @@ class MooncakePipe(KVPipeBase):
230 """MooncakeTransferEngine based Pipe implementation."""
231
232 def __init__(
234 - self, local_rank: int, config: KVTransferConfig, device: Optional[str] = None
233 + self, local_rank: int, config: KVTransferConfig, device: str | None = None
234 ):
235 """Initialize the mooncake pipe and set related parameters."""
236 self.config = config
@@ -243,7 +242,7 @@ class MooncakePipe(KVPipeBase):
242 self.device = self._select_device(device)
243
244 self.transfer_engine = MooncakeTransferEngine(self.kv_rank, self.local_rank)
246 - self.transport_thread: Optional[ThreadPoolExecutor] = None
245 + self.transport_thread: ThreadPoolExecutor | None = None
246 self.none_tensor = torch.tensor([NONE_INT], device=self.device)
247
248 def _select_device(self, device: str) -> torch.device:
@@ -267,7 +266,7 @@ class MooncakePipe(KVPipeBase):
266 data = self.transfer_engine.recv_bytes()
267 return safetensors_load(data)["tensor"].to(self.device)
268
270 - def send_tensor(self, tensor: Optional[torch.Tensor]) -> None:
269 + def send_tensor(self, tensor: torch.Tensor | None) -> None:
270 """Send tensor to the target process."""
271 if self.transport_thread is None:
272 self.transport_thread = ThreadPoolExecutor(max_workers=1)
@@ -275,7 +274,7 @@ class MooncakePipe(KVPipeBase):
274 assert len(tensor.shape) > 0
275 self.transport_thread.submit(self._send_impl, tensor)
276
278 - def recv_tensor(self) -> Optional[torch.Tensor]:
277 + def recv_tensor(self) -> torch.Tensor | None:
278 """Receive tensor from other processes."""
279 if self.transport_thread is None:
280 self.transport_thread = ThreadPoolExecutor(max_workers=1)
vllm/distributed/kv_transfer/kv_pipe/pynccl_pipe.py
+10 -10
@@ -15,8 +15,8 @@ Key Features:
15
16 import threading
17 import time
18 +from collections.abc import Callable
19 from concurrent.futures import ThreadPoolExecutor
19 -from typing import Callable, Optional
20
21 import torch
22
@@ -35,7 +35,7 @@ class BrokenPipeException(Exception):
35 super().__init__(self.message)
36
37
38 -Metadata = dict[str, Optional[torch.Tensor]]
38 +Metadata = dict[str, torch.Tensor | None]
39
40
41 class PyNcclPipe(KVPipeBase):
@@ -47,7 +47,7 @@ class PyNcclPipe(KVPipeBase):
47 self,
48 local_rank: int,
49 config: KVTransferConfig,
50 - device: Optional[str] = None,
50 + device: str | None = None,
51 port_offset: int = 0,
52 ):
53 self.config = config
@@ -77,7 +77,7 @@ class PyNcclPipe(KVPipeBase):
77 self.target_rank_for_recv = (self.kv_rank - 1) % self.kv_parallel_size
78
79 # transportation-related variables
80 - self.transport_thread: Optional[ThreadPoolExecutor] = None
80 + self.transport_thread: ThreadPoolExecutor | None = None
81 self.buffer_size = 0
82 self.buffer_size_lock = threading.Lock()
83 self.buffer_size_thresh = self.config.kv_buffer_size
@@ -115,7 +115,7 @@ class PyNcclPipe(KVPipeBase):
115 else:
116 return torch.device("cpu")
117
118 - def _make_metadata(self, tensor: Optional[torch.Tensor]) -> Metadata:
118 + def _make_metadata(self, tensor: torch.Tensor | None) -> Metadata:
119 """
120 Create the metadata as a dictionary based on the input tensor.
121
@@ -167,7 +167,7 @@ class PyNcclPipe(KVPipeBase):
167 """
168 return self.group.recv_obj(self.target_rank_for_recv)
169
170 - def _send_impl(self, tensor: Optional[torch.Tensor]) -> None:
170 + def _send_impl(self, tensor: torch.Tensor | None) -> None:
171 """
172 The actual implementation of sending the tensor and its metadata to the
173 target rank.
@@ -181,7 +181,7 @@ class PyNcclPipe(KVPipeBase):
181 if tensor is not None:
182 self.device_send_func(tensor.to(self.device), self.target_rank_for_send)
183
184 - def _recv_impl(self) -> Optional[torch.Tensor]:
184 + def _recv_impl(self) -> torch.Tensor | None:
185 """
186 The actual implementation of receiving a tensor and its metadata from
187 the target rank.
@@ -198,7 +198,7 @@ class PyNcclPipe(KVPipeBase):
198 return buffer
199
200 def send_tensor_wrapper(
201 - self, tensor: Optional[torch.Tensor], tensor_size: int
201 + self, tensor: torch.Tensor | None, tensor_size: int
202 ) -> None:
203 """
204 Wrapper for _send_impl to handle exceptions and update buffer size.
@@ -228,7 +228,7 @@ class PyNcclPipe(KVPipeBase):
228 logger.debug("KV cache transfer pipe is full. Waiting...")
229 time.sleep(0.05)
230
231 - def send_tensor(self, tensor: Optional[torch.Tensor]) -> None:
231 + def send_tensor(self, tensor: torch.Tensor | None) -> None:
232 """
233 Sends a tensor and its metadata to the destination rank in a
234 non-blocking way.
@@ -251,7 +251,7 @@ class PyNcclPipe(KVPipeBase):
251
252 self.transport_thread.submit(self.send_tensor_wrapper, tensor, tensor_size)
253
254 - def recv_tensor(self) -> Optional[torch.Tensor]:
254 + def recv_tensor(self) -> torch.Tensor | None:
255 """
256 Receives a tensor and its metadata from the source rank. Blocking call.
257
vllm/distributed/kv_transfer/kv_transfer_state.py
+3 -3
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import TYPE_CHECKING, Optional
3 +from typing import TYPE_CHECKING
4
5 from vllm import envs
6 from vllm.distributed.kv_transfer.kv_connector.base import KVConnectorBaseType
@@ -13,7 +13,7 @@ from vllm.distributed.kv_transfer.kv_connector.v1 import (
13 if TYPE_CHECKING:
14 from vllm.config import VllmConfig
15
16 -_KV_CONNECTOR_AGENT: Optional[KVConnectorBaseType] = None
16 +_KV_CONNECTOR_AGENT: KVConnectorBaseType | None = None
17
18
19 def get_kv_transfer_group() -> KVConnectorBaseType:
@@ -27,7 +27,7 @@ def has_kv_transfer_group() -> bool:
27 return _KV_CONNECTOR_AGENT is not None
28
29
30 -def is_v1_kv_transfer_group(connector: Optional[KVConnectorBaseType] = None) -> bool:
30 +def is_v1_kv_transfer_group(connector: KVConnectorBaseType | None = None) -> bool:
31 """Check if the KV connector is the v1 connector.
32 If the argument is None, it will check the global KV connector
33
vllm/distributed/parallel_state.py
+43 -44
@@ -28,11 +28,12 @@ import gc
28 import pickle
29 import weakref
30 from collections import namedtuple
31 +from collections.abc import Callable
32 from contextlib import contextmanager, nullcontext
33 from dataclasses import dataclass
34 from datetime import timedelta
35 from multiprocessing import shared_memory
35 -from typing import Any, Callable, Optional, Union
36 +from typing import Any, Optional
37 from unittest.mock import patch
38
39 import torch
@@ -65,7 +66,7 @@ TensorMetadata = namedtuple("TensorMetadata", ["device", "dtype", "size"])
66
67
68 def _split_tensor_dict(
68 - tensor_dict: dict[str, Union[torch.Tensor, Any]],
69 + tensor_dict: dict[str, torch.Tensor | Any],
70 ) -> tuple[list[tuple[str, Any]], list[torch.Tensor]]:
71 """Split the tensor dictionary into two parts:
72 1. A list of (key, value) pairs. If the value is a tensor, it is replaced
@@ -300,17 +301,17 @@ class GroupCoordinator:
301 cpu_group: ProcessGroup # group for CPU communication
302 device_group: ProcessGroup # group for device communication
303 # device communicator (if use_device_communicator=True)
303 - device_communicator: Optional[DeviceCommunicatorBase]
304 - mq_broadcaster: Optional[Any] # shared memory broadcaster
304 + device_communicator: DeviceCommunicatorBase | None
305 + mq_broadcaster: Any | None # shared memory broadcaster
306
307 def __init__(
308 self,
309 group_ranks: list[list[int]],
310 local_rank: int,
310 - torch_distributed_backend: Union[str, Backend],
311 + torch_distributed_backend: str | Backend,
312 use_device_communicator: bool, # whether to use device communicator
313 use_message_queue_broadcaster: bool = False,
313 - group_name: Optional[str] = None,
314 + group_name: str | None = None,
315 ):
316 group_name = group_name or "anonymous"
317 self.unique_name = _get_unique_name(group_name)
@@ -368,7 +369,7 @@ class GroupCoordinator:
369
370 from vllm.distributed.device_communicators.shm_broadcast import MessageQueue
371
371 - self.mq_broadcaster: Optional[MessageQueue] = None
372 + self.mq_broadcaster: MessageQueue | None = None
373 if use_message_queue_broadcaster and self.world_size > 1:
374 self.mq_broadcaster = MessageQueue.create_from_process_group(
375 self.cpu_group, 1 << 22, 6
@@ -419,9 +420,7 @@ class GroupCoordinator:
420 return self.ranks[(rank_in_group - 1) % world_size]
421
422 @contextmanager
422 - def graph_capture(
423 - self, graph_capture_context: Optional[GraphCaptureContext] = None
424 - ):
423 + def graph_capture(self, graph_capture_context: GraphCaptureContext | None = None):
424 if graph_capture_context is None:
425 stream = torch.cuda.Stream()
426 graph_capture_context = GraphCaptureContext(stream)
@@ -502,9 +501,9 @@ class GroupCoordinator:
501
502 def all_gatherv(
503 self,
505 - input_: Union[torch.Tensor, list[torch.Tensor]],
504 + input_: torch.Tensor | list[torch.Tensor],
505 dim: int = 0,
507 - sizes: Optional[list[int]] = None,
506 + sizes: list[int] | None = None,
507 ):
508 if self.device_communicator is None:
509 raise ValueError("No device communicator found")
@@ -527,7 +526,7 @@ class GroupCoordinator:
526 return self._reduce_scatter_out_place(input_, dim)
527
528 def reduce_scatterv(
530 - self, input_: torch.Tensor, dim: int = -1, sizes: Optional[list[int]] = None
529 + self, input_: torch.Tensor, dim: int = -1, sizes: list[int] | None = None
530 ) -> torch.Tensor:
531 if self.device_communicator is None:
532 raise ValueError("No device communicator found")
@@ -540,7 +539,7 @@ class GroupCoordinator:
539
540 def gather(
541 self, input_: torch.Tensor, dst: int = 0, dim: int = -1
543 - ) -> Optional[torch.Tensor]:
542 + ) -> torch.Tensor | None:
543 """
544 NOTE: We assume that the input tensor is on the same device across
545 all the ranks.
@@ -569,7 +568,7 @@ class GroupCoordinator:
568 )
569 return input_
570
572 - def broadcast_object(self, obj: Optional[Any] = None, src: int = 0):
571 + def broadcast_object(self, obj: Any | None = None, src: int = 0):
572 """Broadcast the input object.
573 NOTE: `src` is the local rank of the source rank.
574 """
@@ -594,7 +593,7 @@ class GroupCoordinator:
593 return recv[0]
594
595 def broadcast_object_list(
597 - self, obj_list: list[Any], src: int = 0, group: Optional[ProcessGroup] = None
596 + self, obj_list: list[Any], src: int = 0, group: ProcessGroup | None = None
597 ):
598 """Broadcast the input object list.
599 NOTE: `src` is the local rank of the source rank.
@@ -675,11 +674,11 @@ class GroupCoordinator:
674
675 def broadcast_tensor_dict(
676 self,
678 - tensor_dict: Optional[dict[str, Union[torch.Tensor, Any]]] = None,
677 + tensor_dict: dict[str, torch.Tensor | Any] | None = None,
678 src: int = 0,
680 - group: Optional[ProcessGroup] = None,
681 - metadata_group: Optional[ProcessGroup] = None,
682 - ) -> Optional[dict[str, Union[torch.Tensor, Any]]]:
679 + group: ProcessGroup | None = None,
680 + metadata_group: ProcessGroup | None = None,
681 + ) -> dict[str, torch.Tensor | Any] | None:
682 """Broadcast the input tensor dictionary.
683 NOTE: `src` is the local rank of the source rank.
684 """
@@ -757,11 +756,11 @@ class GroupCoordinator:
756
757 def send_tensor_dict(
758 self,
760 - tensor_dict: dict[str, Union[torch.Tensor, Any]],
761 - dst: Optional[int] = None,
759 + tensor_dict: dict[str, torch.Tensor | Any],
760 + dst: int | None = None,
761 all_gather_group: Optional["GroupCoordinator"] = None,
763 - all_gather_tensors: Optional[dict[str, bool]] = None,
764 - ) -> Optional[dict[str, Union[torch.Tensor, Any]]]:
762 + all_gather_tensors: dict[str, bool] | None = None,
763 + ) -> dict[str, torch.Tensor | Any] | None:
764 """Send the input tensor dictionary.
765 NOTE: `dst` is the local rank of the source rank.
766
@@ -845,10 +844,10 @@ class GroupCoordinator:
844
845 def recv_tensor_dict(
846 self,
848 - src: Optional[int] = None,
847 + src: int | None = None,
848 all_gather_group: Optional["GroupCoordinator"] = None,
850 - all_gather_tensors: Optional[dict[str, bool]] = None,
851 - ) -> Optional[dict[str, Union[torch.Tensor, Any]]]:
849 + all_gather_tensors: dict[str, bool] | None = None,
850 + ) -> dict[str, torch.Tensor | Any] | None:
851 """Recv the input tensor dictionary.
852 NOTE: `src` is the local rank of the source rank.
853
@@ -943,7 +942,7 @@ class GroupCoordinator:
942 """
943 torch.distributed.barrier(group=self.cpu_group)
944
946 - def send(self, tensor: torch.Tensor, dst: Optional[int] = None) -> None:
945 + def send(self, tensor: torch.Tensor, dst: int | None = None) -> None:
946 """Sends a tensor to the destination rank in a blocking way"""
947 """NOTE: `dst` is the local rank of the destination rank."""
948 if self.device_communicator is None:
@@ -951,7 +950,7 @@ class GroupCoordinator:
950 self.device_communicator.send(tensor, dst)
951
952 def recv(
954 - self, size: torch.Size, dtype: torch.dtype, src: Optional[int] = None
953 + self, size: torch.Size, dtype: torch.dtype, src: int | None = None
954 ) -> torch.Tensor:
955 """Receives a tensor from the source rank."""
956 """NOTE: `src` is the local rank of the source rank."""
@@ -997,8 +996,8 @@ class GroupCoordinator:
996 return hidden_states
997
998
1000 -_WORLD: Optional[GroupCoordinator] = None
1001 -_NODE_COUNT: Optional[int] = None
999 +_WORLD: GroupCoordinator | None = None
1000 +_NODE_COUNT: int | None = None
1001
1002
1003 def get_world_group() -> GroupCoordinator:
@@ -1023,7 +1022,7 @@ def init_model_parallel_group(
1022 local_rank: int,
1023 backend: str,
1024 use_message_queue_broadcaster: bool = False,
1026 - group_name: Optional[str] = None,
1025 + group_name: str | None = None,
1026 ) -> GroupCoordinator:
1027 return GroupCoordinator(
1028 group_ranks=group_ranks,
@@ -1035,7 +1034,7 @@ def init_model_parallel_group(
1034 )
1035
1036
1038 -_TP: Optional[GroupCoordinator] = None
1037 +_TP: GroupCoordinator | None = None
1038
1039
1040 def get_tp_group() -> GroupCoordinator:
@@ -1052,7 +1051,7 @@ def get_tensor_model_parallel_group():
1051 return get_tp_group()
1052
1053
1055 -_DCP: Optional[GroupCoordinator] = None
1054 +_DCP: GroupCoordinator | None = None
1055
1056
1057 def get_dcp_group() -> GroupCoordinator:
@@ -1063,9 +1062,9 @@ def get_dcp_group() -> GroupCoordinator:
1062 # kept for backward compatibility
1063 get_context_model_parallel_group = get_dcp_group
1064
1066 -_PP: Optional[GroupCoordinator] = None
1065 +_PP: GroupCoordinator | None = None
1066
1068 -_DP: Optional[GroupCoordinator] = None
1067 +_DP: GroupCoordinator | None = None
1068
1069
1070 def get_dp_group() -> GroupCoordinator:
@@ -1073,7 +1072,7 @@ def get_dp_group() -> GroupCoordinator:
1072 return _DP
1073
1074
1076 -_EP: Optional[GroupCoordinator] = None
1075 +_EP: GroupCoordinator | None = None
1076
1077
1078 def get_ep_group() -> GroupCoordinator:
@@ -1131,7 +1130,7 @@ def init_distributed_environment(
1130 distributed_init_method: str = "env://",
1131 local_rank: int = -1,
1132 backend: str = "nccl",
1134 - timeout: Optional[timedelta] = None,
1133 + timeout: timedelta | None = None,
1134 ):
1135 logger.debug(
1136 "world_size=%d rank=%d local_rank=%d distributed_init_method=%s backend=%s",
@@ -1208,8 +1207,8 @@ def init_distributed_environment(
1207 def initialize_model_parallel(
1208 tensor_model_parallel_size: int = 1,
1209 pipeline_model_parallel_size: int = 1,
1211 - decode_context_model_parallel_size: Optional[int] = 1,
1212 - backend: Optional[str] = None,
1210 + decode_context_model_parallel_size: int | None = 1,
1211 + backend: str | None = None,
1212 ) -> None:
1213 """
1214 Initialize model parallel groups.
@@ -1338,8 +1337,8 @@ def initialize_model_parallel(
1337 def ensure_model_parallel_initialized(
1338 tensor_model_parallel_size: int,
1339 pipeline_model_parallel_size: int,
1341 - decode_context_model_parallel_size: Optional[int] = 1,
1342 - backend: Optional[str] = None,
1340 + decode_context_model_parallel_size: int | None = 1,
1341 + backend: str | None = None,
1342 ) -> None:
1343 """Helper to initialize model parallel groups if they are not initialized,
1344 or ensure tensor-parallel and pipeline-parallel sizes are equal to expected
@@ -1504,7 +1503,7 @@ def cleanup_dist_env_and_memory(shutdown_ray: bool = False):
1503
1504
1505 def in_the_same_node_as(
1507 - pg: Union[ProcessGroup, StatelessProcessGroup], source_rank: int = 0
1506 + pg: ProcessGroup | StatelessProcessGroup, source_rank: int = 0
1507 ) -> list[bool]:
1508 """
1509 This is a collective operation that returns if each rank is in the same node
@@ -1624,7 +1623,7 @@ def is_global_first_rank() -> bool:
1623 return True
1624
1625
1627 -def _node_count(pg: Union[ProcessGroup, StatelessProcessGroup]) -> int:
1626 +def _node_count(pg: ProcessGroup | StatelessProcessGroup) -> int:
1627 """
1628 Returns the total number of nodes in the process group.
1629
vllm/distributed/tpu_distributed_utils.py
+3 -3
@@ -30,9 +30,9 @@ class XlaQKVParallelLinear(nn.Module):
30 self.q_weight: Parameter
31 self.k_weight: Parameter
32 self.v_weight: Parameter
33 - self.q_bias: Optional[Parameter]
34 - self.k_bias: Optional[Parameter]
35 - self.v_bias: Optional[Parameter]
33 + self.q_bias: Parameter | None
34 + self.k_bias: Parameter | None
35 + self.v_bias: Parameter | None
36 self._load_weights_from_qkv_linear(qkv_linear)
37 if mesh is not None:
38 self._shard_weight(mesh)
vllm/distributed/utils.py
+3 -3
@@ -15,7 +15,7 @@ import uuid
15 from collections import deque
16 from collections.abc import Sequence
17 from datetime import timedelta
18 -from typing import Any, Optional
18 +from typing import Any
19
20 import torch
21 from torch.distributed import ProcessGroup, TCPStore
@@ -150,7 +150,7 @@ class StatelessProcessGroup:
150 store: torch._C._distributed_c10d.Store
151
152 # stores a reference to the socket so that the file descriptor stays alive
153 - socket: Optional[socket.socket]
153 + socket: socket.socket | None
154
155 data_expiration_seconds: int = 3600 # 1 hour
156
@@ -197,7 +197,7 @@ class StatelessProcessGroup:
197 self.recv_src_counter[src] += 1
198 return obj
199
200 - def broadcast_obj(self, obj: Optional[Any], src: int) -> Any:
200 + def broadcast_obj(self, obj: Any | None, src: int) -> Any:
201 """Broadcast an object from a source rank to all other ranks.
202 It does not clean up after all ranks have received the object.
203 Use it for limited times, e.g., for initialization.
vllm/engine/arg_utils.py
+71 -68
@@ -7,15 +7,16 @@ import dataclasses
7 import functools
8 import json
9 import sys
10 +from collections.abc import Callable
11 from dataclasses import MISSING, dataclass, fields, is_dataclass
12 from itertools import permutations
13 +from types import UnionType
14 from typing import (
15 TYPE_CHECKING,
16 Annotated,
17 Any,
16 - Callable,
18 Literal,
18 - Optional,
19 + TypeAlias,
20 TypeVar,
21 Union,
22 cast,
@@ -98,8 +99,8 @@ logger = init_logger(__name__)
99
100 # object is used to allow for special typing forms
101 T = TypeVar("T")
101 -TypeHint = Union[type[Any], object]
102 -TypeHintT = Union[type[T], object]
102 +TypeHint: TypeAlias = type[Any] | object
103 +TypeHintT: TypeAlias = type[T] | object
104
105
106 def parse_type(return_type: Callable[[str], T]) -> Callable[[str], T]:
@@ -114,8 +115,8 @@ def parse_type(return_type: Callable[[str], T]) -> Callable[[str], T]:
115 return _parse_type
116
117
117 -def optional_type(return_type: Callable[[str], T]) -> Callable[[str], Optional[T]]:
118 - def _optional_type(val: str) -> Optional[T]:
118 +def optional_type(return_type: Callable[[str], T]) -> Callable[[str], T | None]:
119 + def _optional_type(val: str) -> T | None:
120 if val == "" or val == "None":
121 return None
122 return parse_type(return_type)(val)
@@ -123,7 +124,7 @@ def optional_type(return_type: Callable[[str], T]) -> Callable[[str], Optional[T
124 return _optional_type
125
126
126 -def union_dict_and_str(val: str) -> Optional[Union[str, dict[str, str]]]:
127 +def union_dict_and_str(val: str) -> str | dict[str, str] | None:
128 if not re.match(r"(?s)^\s*{.*}\s*$", val):
129 return str(val)
130 return optional_type(json.loads)(val)
@@ -174,7 +175,8 @@ def get_type_hints(type_hint: TypeHint) -> set[TypeHint]:
175
176 if origin is Annotated:
177 type_hints.update(get_type_hints(args[0]))
177 - elif origin is Union:
178 + elif origin in {Union, UnionType}:
179 + # Union for Union[X, Y] and UnionType for X | Y
180 for arg in args:
181 type_hints.update(get_type_hints(arg))
182 else:
@@ -195,7 +197,7 @@ NEEDS_HELP = (
197
198
199 @functools.lru_cache(maxsize=30)
198 -def _compute_kwargs(cls: ConfigType) -> dict[str, Any]:
200 +def _compute_kwargs(cls: ConfigType) -> dict[str, dict[str, Any]]:
201 # Save time only getting attr docs if we're generating help text
202 cls_docs = get_attr_docs(cls) if NEEDS_HELP else {}
203 kwargs = {}
@@ -262,7 +264,8 @@ def _compute_kwargs(cls: ConfigType) -> dict[str, Any]:
264 type_hint = get_type(type_hints, list)
265 types = get_args(type_hint)
266 list_type = types[0]
265 - if get_origin(list_type) is Union:
267 + if get_origin(list_type) in {Union, UnionType}:
268 + # Union for Union[X, Y] and UnionType for X | Y
269 msg = "List type must contain str if it is a Union."
270 assert str in get_args(list_type), msg
271 list_type = str
@@ -310,7 +313,7 @@ def _compute_kwargs(cls: ConfigType) -> dict[str, Any]:
313 return kwargs
314
315
313 -def get_kwargs(cls: ConfigType) -> dict[str, Any]:
316 +def get_kwargs(cls: ConfigType) -> dict[str, dict[str, Any]]:
317 """Return argparse kwargs for the given Config dataclass.
318
319 If `--help` or `mkdocs` are not present in the command line command, the
@@ -328,43 +331,43 @@ class EngineArgs:
331 """Arguments for vLLM engine."""
332
333 model: str = ModelConfig.model
331 - served_model_name: Optional[Union[str, list[str]]] = ModelConfig.served_model_name
332 - tokenizer: Optional[str] = ModelConfig.tokenizer
333 - hf_config_path: Optional[str] = ModelConfig.hf_config_path
334 + served_model_name: str | list[str] | None = ModelConfig.served_model_name
335 + tokenizer: str | None = ModelConfig.tokenizer
336 + hf_config_path: str | None = ModelConfig.hf_config_path
337 runner: RunnerOption = ModelConfig.runner
338 convert: ConvertOption = ModelConfig.convert
336 - task: Optional[TaskOption] = ModelConfig.task
339 + task: TaskOption | None = ModelConfig.task
340 skip_tokenizer_init: bool = ModelConfig.skip_tokenizer_init
341 enable_prompt_embeds: bool = ModelConfig.enable_prompt_embeds
342 tokenizer_mode: TokenizerMode = ModelConfig.tokenizer_mode
343 trust_remote_code: bool = ModelConfig.trust_remote_code
344 allowed_local_media_path: str = ModelConfig.allowed_local_media_path
342 - allowed_media_domains: Optional[list[str]] = ModelConfig.allowed_media_domains
343 - download_dir: Optional[str] = LoadConfig.download_dir
345 + allowed_media_domains: list[str] | None = ModelConfig.allowed_media_domains
346 + download_dir: str | None = LoadConfig.download_dir
347 safetensors_load_strategy: str = LoadConfig.safetensors_load_strategy
345 - load_format: Union[str, LoadFormats] = LoadConfig.load_format
348 + load_format: str | LoadFormats = LoadConfig.load_format
349 config_format: str = ModelConfig.config_format
350 dtype: ModelDType = ModelConfig.dtype
351 kv_cache_dtype: CacheDType = CacheConfig.cache_dtype
349 - seed: Optional[int] = ModelConfig.seed
350 - max_model_len: Optional[int] = ModelConfig.max_model_len
352 + seed: int | None = ModelConfig.seed
353 + max_model_len: int | None = ModelConfig.max_model_len
354 cuda_graph_sizes: list[int] = get_field(SchedulerConfig, "cuda_graph_sizes")
355 # Note: Specifying a custom executor backend by passing a class
356 # is intended for expert use only. The API may change without
357 # notice.
355 - distributed_executor_backend: Optional[
356 - Union[str, DistributedExecutorBackend, type[ExecutorBase]]
357 - ] = ParallelConfig.distributed_executor_backend
358 + distributed_executor_backend: (
359 + str | DistributedExecutorBackend | type[ExecutorBase] | None
360 + ) = ParallelConfig.distributed_executor_backend
361 # number of P/D disaggregation (or other disaggregation) workers
362 pipeline_parallel_size: int = ParallelConfig.pipeline_parallel_size
363 tensor_parallel_size: int = ParallelConfig.tensor_parallel_size
364 decode_context_parallel_size: int = ParallelConfig.decode_context_parallel_size
365 data_parallel_size: int = ParallelConfig.data_parallel_size
363 - data_parallel_rank: Optional[int] = None
364 - data_parallel_start_rank: Optional[int] = None
365 - data_parallel_size_local: Optional[int] = None
366 - data_parallel_address: Optional[str] = None
367 - data_parallel_rpc_port: Optional[int] = None
366 + data_parallel_rank: int | None = None
367 + data_parallel_start_rank: int | None = None
368 + data_parallel_size_local: int | None = None
369 + data_parallel_address: str | None = None
370 + data_parallel_rpc_port: int | None = None
371 data_parallel_hybrid_lb: bool = False
372 data_parallel_backend: str = ParallelConfig.data_parallel_backend
373 enable_expert_parallel: bool = ParallelConfig.enable_expert_parallel
@@ -385,11 +388,11 @@ class EngineArgs:
388 eplb_window_size: int = EPLBConfig.window_size
389 eplb_step_interval: int = EPLBConfig.step_interval
390 eplb_log_balancedness: bool = EPLBConfig.log_balancedness
388 - max_parallel_loading_workers: Optional[int] = (
391 + max_parallel_loading_workers: int | None = (
392 ParallelConfig.max_parallel_loading_workers
393 )
391 - block_size: Optional[BlockSize] = CacheConfig.block_size
392 - enable_prefix_caching: Optional[bool] = CacheConfig.enable_prefix_caching
394 + block_size: BlockSize | None = CacheConfig.block_size
395 + enable_prefix_caching: bool | None = CacheConfig.enable_prefix_caching
396 prefix_caching_hash_algo: PrefixCachingHashAlgo = (
397 CacheConfig.prefix_caching_hash_algo
398 )
@@ -398,62 +401,62 @@ class EngineArgs:
401 swap_space: float = CacheConfig.swap_space
402 cpu_offload_gb: float = CacheConfig.cpu_offload_gb
403 gpu_memory_utilization: float = CacheConfig.gpu_memory_utilization
401 - kv_cache_memory_bytes: Optional[int] = CacheConfig.kv_cache_memory_bytes
402 - max_num_batched_tokens: Optional[int] = SchedulerConfig.max_num_batched_tokens
404 + kv_cache_memory_bytes: int | None = CacheConfig.kv_cache_memory_bytes
405 + max_num_batched_tokens: int | None = SchedulerConfig.max_num_batched_tokens
406 max_num_partial_prefills: int = SchedulerConfig.max_num_partial_prefills
407 max_long_partial_prefills: int = SchedulerConfig.max_long_partial_prefills
408 long_prefill_token_threshold: int = SchedulerConfig.long_prefill_token_threshold
406 - max_num_seqs: Optional[int] = SchedulerConfig.max_num_seqs
409 + max_num_seqs: int | None = SchedulerConfig.max_num_seqs
410 max_logprobs: int = ModelConfig.max_logprobs
411 logprobs_mode: LogprobsMode = ModelConfig.logprobs_mode
412 disable_log_stats: bool = False
410 - revision: Optional[str] = ModelConfig.revision
411 - code_revision: Optional[str] = ModelConfig.code_revision
413 + revision: str | None = ModelConfig.revision
414 + code_revision: str | None = ModelConfig.code_revision
415 rope_scaling: dict[str, Any] = get_field(ModelConfig, "rope_scaling")
413 - rope_theta: Optional[float] = ModelConfig.rope_theta
414 - hf_token: Optional[Union[bool, str]] = ModelConfig.hf_token
416 + rope_theta: float | None = ModelConfig.rope_theta
417 + hf_token: bool | str | None = ModelConfig.hf_token
418 hf_overrides: HfOverrides = get_field(ModelConfig, "hf_overrides")
416 - tokenizer_revision: Optional[str] = ModelConfig.tokenizer_revision
417 - quantization: Optional[QuantizationMethods] = ModelConfig.quantization
419 + tokenizer_revision: str | None = ModelConfig.tokenizer_revision
420 + quantization: QuantizationMethods | None = ModelConfig.quantization
421 enforce_eager: bool = ModelConfig.enforce_eager
422 disable_custom_all_reduce: bool = ParallelConfig.disable_custom_all_reduce
420 - limit_mm_per_prompt: dict[str, Union[int, dict[str, int]]] = get_field(
423 + limit_mm_per_prompt: dict[str, int | dict[str, int]] = get_field(
424 MultiModalConfig, "limit_per_prompt"
425 )
426 interleave_mm_strings: bool = MultiModalConfig.interleave_mm_strings
427 media_io_kwargs: dict[str, dict[str, Any]] = get_field(
428 MultiModalConfig, "media_io_kwargs"
429 )
427 - mm_processor_kwargs: Optional[dict[str, Any]] = MultiModalConfig.mm_processor_kwargs
430 + mm_processor_kwargs: dict[str, Any] | None = MultiModalConfig.mm_processor_kwargs
431 disable_mm_preprocessor_cache: bool = False # DEPRECATED
432 mm_processor_cache_gb: float = MultiModalConfig.mm_processor_cache_gb
430 - mm_processor_cache_type: Optional[MMCacheType] = (
433 + mm_processor_cache_type: MMCacheType | None = (
434 MultiModalConfig.mm_processor_cache_type
435 )
436 mm_shm_cache_max_object_size_mb: int = (
437 MultiModalConfig.mm_shm_cache_max_object_size_mb
438 )
439 mm_encoder_tp_mode: MMEncoderTPMode = MultiModalConfig.mm_encoder_tp_mode
437 - io_processor_plugin: Optional[str] = None
440 + io_processor_plugin: str | None = None
441 skip_mm_profiling: bool = MultiModalConfig.skip_mm_profiling
442 video_pruning_rate: float = MultiModalConfig.video_pruning_rate
443 # LoRA fields
444 enable_lora: bool = False
445 max_loras: int = LoRAConfig.max_loras
446 max_lora_rank: int = LoRAConfig.max_lora_rank
444 - default_mm_loras: Optional[dict[str, str]] = LoRAConfig.default_mm_loras
447 + default_mm_loras: dict[str, str] | None = LoRAConfig.default_mm_loras
448 fully_sharded_loras: bool = LoRAConfig.fully_sharded_loras
446 - max_cpu_loras: Optional[int] = LoRAConfig.max_cpu_loras
447 - lora_dtype: Optional[Union[str, torch.dtype]] = LoRAConfig.lora_dtype
449 + max_cpu_loras: int | None = LoRAConfig.max_cpu_loras
450 + lora_dtype: str | torch.dtype | None = LoRAConfig.lora_dtype
451 lora_extra_vocab_size: int = LoRAConfig.lora_extra_vocab_size
452
453 ray_workers_use_nsight: bool = ParallelConfig.ray_workers_use_nsight
451 - num_gpu_blocks_override: Optional[int] = CacheConfig.num_gpu_blocks_override
454 + num_gpu_blocks_override: int | None = CacheConfig.num_gpu_blocks_override
455 num_lookahead_slots: int = SchedulerConfig.num_lookahead_slots
456 model_loader_extra_config: dict = get_field(LoadConfig, "model_loader_extra_config")
454 - ignore_patterns: Union[str, list[str]] = get_field(LoadConfig, "ignore_patterns")
457 + ignore_patterns: str | list[str] = get_field(LoadConfig, "ignore_patterns")
458
456 - enable_chunked_prefill: Optional[bool] = SchedulerConfig.enable_chunked_prefill
459 + enable_chunked_prefill: bool | None = SchedulerConfig.enable_chunked_prefill
460 disable_chunked_mm_input: bool = SchedulerConfig.disable_chunked_mm_input
461
462 disable_hybrid_kv_cache_manager: bool = (
@@ -465,35 +468,35 @@ class EngineArgs:
468 )
469 reasoning_parser: str = StructuredOutputsConfig.reasoning_parser
470 # Deprecated guided decoding fields
468 - guided_decoding_backend: Optional[str] = None
469 - guided_decoding_disable_fallback: Optional[bool] = None
470 - guided_decoding_disable_any_whitespace: Optional[bool] = None
471 - guided_decoding_disable_additional_properties: Optional[bool] = None
471 + guided_decoding_backend: str | None = None
472 + guided_decoding_disable_fallback: bool | None = None
473 + guided_decoding_disable_any_whitespace: bool | None = None
474 + guided_decoding_disable_additional_properties: bool | None = None
475
473 - logits_processor_pattern: Optional[str] = ModelConfig.logits_processor_pattern
476 + logits_processor_pattern: str | None = ModelConfig.logits_processor_pattern
477
475 - speculative_config: Optional[dict[str, Any]] = None
478 + speculative_config: dict[str, Any] | None = None
479
477 - show_hidden_metrics_for_version: Optional[str] = (
480 + show_hidden_metrics_for_version: str | None = (
481 ObservabilityConfig.show_hidden_metrics_for_version
482 )
480 - otlp_traces_endpoint: Optional[str] = ObservabilityConfig.otlp_traces_endpoint
481 - collect_detailed_traces: Optional[list[DetailedTraceModules]] = (
483 + otlp_traces_endpoint: str | None = ObservabilityConfig.otlp_traces_endpoint
484 + collect_detailed_traces: list[DetailedTraceModules] | None = (
485 ObservabilityConfig.collect_detailed_traces
486 )
487 scheduling_policy: SchedulerPolicy = SchedulerConfig.policy
485 - scheduler_cls: Union[str, type[object]] = SchedulerConfig.scheduler_cls
488 + scheduler_cls: str | type[object] = SchedulerConfig.scheduler_cls
489
487 - pooler_config: Optional[PoolerConfig] = ModelConfig.pooler_config
488 - override_pooler_config: Optional[Union[dict, PoolerConfig]] = (
490 + pooler_config: PoolerConfig | None = ModelConfig.pooler_config
491 + override_pooler_config: dict | PoolerConfig | None = (
492 ModelConfig.override_pooler_config
493 )
494 compilation_config: CompilationConfig = get_field(VllmConfig, "compilation_config")
495 worker_cls: str = ParallelConfig.worker_cls
496 worker_extension_cls: str = ParallelConfig.worker_extension_cls
497
495 - kv_transfer_config: Optional[KVTransferConfig] = None
496 - kv_events_config: Optional[KVEventsConfig] = None
498 + kv_transfer_config: KVTransferConfig | None = None
499 + kv_events_config: KVEventsConfig | None = None
500
501 generation_config: str = ModelConfig.generation_config
502 enable_sleep_mode: bool = ModelConfig.enable_sleep_mode
@@ -515,7 +518,7 @@ class EngineArgs:
518 # DEPRECATED
519 enable_multimodal_encoder_data_parallel: bool = False
520
518 - logits_processors: Optional[list[Union[str, type[LogitsProcessor]]]] = (
521 + logits_processors: list[str | type[LogitsProcessor]] | None = (
522 ModelConfig.logits_processors
523 )
524 """Custom logitproc types"""
@@ -1187,7 +1190,7 @@ class EngineArgs:
1190 target_parallel_config: ParallelConfig,
1191 enable_chunked_prefill: bool,
1192 disable_log_stats: bool,
1190 - ) -> Optional["SpeculativeConfig"]:
1193 + ) -> SpeculativeConfig | None:
1194 """Initializes and returns a SpeculativeConfig object based on
1195 `speculative_config`.
1196
@@ -1214,7 +1217,7 @@ class EngineArgs:
1217
1218 def create_engine_config(
1219 self,
1217 - usage_context: Optional[UsageContext] = None,
1220 + usage_context: UsageContext | None = None,
1221 headless: bool = False,
1222 ) -> VllmConfig:
1223 """
@@ -1282,7 +1285,7 @@ class EngineArgs:
1285 self.enable_chunked_prefill = False
1286 assert self.enable_chunked_prefill is not None
1287
1285 - sliding_window: Optional[int] = None
1288 + sliding_window: int | None = None
1289 if not is_interleaved(model_config.hf_text_config):
1290 # Only set CacheConfig.sliding_window if the model is all sliding
1291 # window. Otherwise CacheConfig.sliding_window will override the
vllm/engine/metrics.py
+13 -13
@@ -3,7 +3,7 @@
3
4 import time
5 from collections import Counter as CollectionsCounter
6 -from typing import Optional, Union, cast
6 +from typing import cast
7
8 import numpy as np
9 import prometheus_client
@@ -304,7 +304,7 @@ class _RayGaugeWrapper:
304 self,
305 name: str,
306 documentation: str = "",
307 - labelnames: Optional[list[str]] = None,
307 + labelnames: list[str] | None = None,
308 multiprocess_mode: str = "",
309 ):
310 del multiprocess_mode
@@ -317,7 +317,7 @@ class _RayGaugeWrapper:
317 self._gauge.set_default_tags(labels)
318 return self
319
320 - def set(self, value: Union[int, float]):
320 + def set(self, value: int | float):
321 return self._gauge.set(value)
322
323 def set_to_current_time(self):
@@ -330,7 +330,7 @@ class _RayCounterWrapper:
330 prometheus_client.Counter"""
331
332 def __init__(
333 - self, name: str, documentation: str = "", labelnames: Optional[list[str]] = None
333 + self, name: str, documentation: str = "", labelnames: list[str] | None = None
334 ):
335 labelnames_tuple = tuple(labelnames) if labelnames else None
336 self._counter = ray_metrics.Counter(
@@ -341,7 +341,7 @@ class _RayCounterWrapper:
341 self._counter.set_default_tags(labels)
342 return self
343
344 - def inc(self, value: Union[int, float] = 1.0):
344 + def inc(self, value: int | float = 1.0):
345 if value == 0:
346 return
347 return self._counter.inc(value)
@@ -355,8 +355,8 @@ class _RayHistogramWrapper:
355 self,
356 name: str,
357 documentation: str = "",
358 - labelnames: Optional[list[str]] = None,
359 - buckets: Optional[list[float]] = None,
358 + labelnames: list[str] | None = None,
359 + buckets: list[float] | None = None,
360 ):
361 labelnames_tuple = tuple(labelnames) if labelnames else None
362 boundaries = buckets if buckets else []
@@ -371,7 +371,7 @@ class _RayHistogramWrapper:
371 self._histogram.set_default_tags(labels)
372 return self
373
374 - def observe(self, value: Union[int, float]):
374 + def observe(self, value: int | float):
375 return self._histogram.observe(value)
376
377
@@ -451,8 +451,8 @@ class LoggingStatLogger(StatLoggerBase):
451
452 def __init__(self, local_interval: float, vllm_config: VllmConfig) -> None:
453 super().__init__(local_interval, vllm_config)
454 - self.last_prompt_throughput: Optional[float] = None
455 - self.last_generation_throughput: Optional[float] = None
454 + self.last_prompt_throughput: float | None = None
455 + self.last_generation_throughput: float | None = None
456
457 def log(self, stats: Stats) -> None:
458 """Called by LLMEngine.
@@ -539,11 +539,11 @@ class PrometheusStatLogger(StatLoggerBase):
539 labelnames=list(labels.keys()), vllm_config=vllm_config
540 )
541
542 - def _log_gauge(self, gauge, data: Union[int, float]) -> None:
542 + def _log_gauge(self, gauge, data: int | float) -> None:
543 # Convenience function for logging to gauge.
544 gauge.labels(**self.labels).set(data)
545
546 - def _log_counter(self, counter, data: Union[int, float]) -> None:
546 + def _log_counter(self, counter, data: int | float) -> None:
547 # Convenience function for logging to counter.
548 # Prevent ValueError from negative increment
549 if data < 0:
@@ -558,7 +558,7 @@ class PrometheusStatLogger(StatLoggerBase):
558 for label, count in data.items():
559 counter.labels(**{**self.labels, label_key: label}).inc(count)
560
561 - def _log_histogram(self, histogram, data: Union[list[int], list[float]]) -> None:
561 + def _log_histogram(self, histogram, data: list[int] | list[float]) -> None:
562 # Convenience function for logging list to histogram.
563 for datum in data:
564 histogram.labels(**self.labels).observe(datum)
vllm/engine/protocol.py
+16 -16
@@ -3,7 +3,7 @@
3
4 from abc import ABC, abstractmethod
5 from collections.abc import AsyncGenerator, Iterable, Mapping
6 -from typing import Any, Optional, Union
6 +from typing import Any
7
8 from vllm.config import ModelConfig, VllmConfig
9 from vllm.inputs.data import PromptType
@@ -28,7 +28,7 @@ class EngineClient(ABC):
28 vllm_config: VllmConfig
29 model_config: ModelConfig
30 processor: Processor
31 - io_processor: Optional[IOProcessor]
31 + io_processor: IOProcessor | None
32
33 @property
34 @abstractmethod
@@ -49,16 +49,16 @@ class EngineClient(ABC):
49 @abstractmethod
50 def generate(
51 self,
52 - prompt: Union[EngineCoreRequest, PromptType],
52 + prompt: EngineCoreRequest | PromptType,
53 sampling_params: SamplingParams,
54 request_id: str,
55 *,
56 - prompt_text: Optional[str] = None,
57 - lora_request: Optional[LoRARequest] = None,
58 - tokenization_kwargs: Optional[dict[str, Any]] = None,
59 - trace_headers: Optional[Mapping[str, str]] = None,
56 + prompt_text: str | None = None,
57 + lora_request: LoRARequest | None = None,
58 + tokenization_kwargs: dict[str, Any] | None = None,
59 + trace_headers: Mapping[str, str] | None = None,
60 priority: int = 0,
61 - data_parallel_rank: Optional[int] = None,
61 + data_parallel_rank: int | None = None,
62 ) -> AsyncGenerator[RequestOutput, None]:
63 """Generate outputs for a request."""
64 ...
@@ -69,16 +69,16 @@ class EngineClient(ABC):
69 prompt: PromptType,
70 pooling_params: PoolingParams,
71 request_id: str,
72 - lora_request: Optional[LoRARequest] = None,
73 - trace_headers: Optional[Mapping[str, str]] = None,
72 + lora_request: LoRARequest | None = None,
73 + trace_headers: Mapping[str, str] | None = None,
74 priority: int = 0,
75 - tokenization_kwargs: Optional[dict[str, Any]] = None,
75 + tokenization_kwargs: dict[str, Any] | None = None,
76 ) -> AsyncGenerator[PoolingRequestOutput, None]:
77 """Generate outputs for a request from a pooling model."""
78 ...
79
80 @abstractmethod
81 - async def abort(self, request_id: Union[str, Iterable[str]]) -> None:
81 + async def abort(self, request_id: str | Iterable[str]) -> None:
82 """Abort a request.
83
84 Args:
@@ -119,7 +119,7 @@ class EngineClient(ABC):
119 ...
120
121 @abstractmethod
122 - async def reset_prefix_cache(self, device: Optional[Device] = None) -> None:
122 + async def reset_prefix_cache(self, device: Device | None = None) -> None:
123 """Reset the prefix cache"""
124 ...
125
@@ -129,7 +129,7 @@ class EngineClient(ABC):
129 ...
130
131 @abstractmethod
132 - async def wake_up(self, tags: Optional[list[str]] = None) -> None:
132 + async def wake_up(self, tags: list[str] | None = None) -> None:
133 """Wake up the engine"""
134 ...
135
@@ -152,9 +152,9 @@ class EngineClient(ABC):
152 async def collective_rpc(
153 self,
154 method: str,
155 - timeout: Optional[float] = None,
155 + timeout: float | None = None,
156 args: tuple = (),
157 - kwargs: Optional[dict] = None,
157 + kwargs: dict | None = None,
158 ):
159 """Perform a collective RPC call to the given path."""
160 raise NotImplementedError
vllm/entrypoints/api_server.py
+3 -3
@@ -13,7 +13,7 @@ import json
13 import ssl
14 from argparse import Namespace
15 from collections.abc import AsyncGenerator
16 -from typing import Any, Optional
16 +from typing import Any
17
18 from fastapi import FastAPI, Request
19 from fastapi.responses import JSONResponse, Response, StreamingResponse
@@ -101,7 +101,7 @@ def build_app(args: Namespace) -> FastAPI:
101
102 async def init_app(
103 args: Namespace,
104 - llm_engine: Optional[AsyncLLMEngine] = None,
104 + llm_engine: AsyncLLMEngine | None = None,
105 ) -> FastAPI:
106 app = build_app(args)
107
@@ -120,7 +120,7 @@ async def init_app(
120
121
122 async def run_server(
123 - args: Namespace, llm_engine: Optional[AsyncLLMEngine] = None, **uvicorn_kwargs: Any
123 + args: Namespace, llm_engine: AsyncLLMEngine | None = None, **uvicorn_kwargs: Any
124 ) -> None:
125 logger.info("vLLM API server version %s", VLLM_VERSION)
126 logger.info("args: %s", args)
vllm/entrypoints/chat_utils.py
+104 -107
@@ -5,10 +5,10 @@ import asyncio
5 import json
6 from abc import ABC, abstractmethod
7 from collections import Counter, defaultdict, deque
8 -from collections.abc import Awaitable, Iterable
8 +from collections.abc import Awaitable, Callable, Iterable
9 from functools import cached_property, lru_cache, partial
10 from pathlib import Path
11 -from typing import Any, Callable, Generic, Literal, Optional, TypeVar, Union, cast
11 +from typing import Any, Generic, Literal, TypeAlias, TypeVar, cast
12
13 import jinja2
14 import jinja2.ext
@@ -40,7 +40,7 @@ from pydantic import BaseModel, ConfigDict, TypeAdapter
40 from transformers import PreTrainedTokenizer, PreTrainedTokenizerFast, ProcessorMixin
41
42 # pydantic needs the TypedDict from typing_extensions
43 -from typing_extensions import Required, TypeAlias, TypedDict
43 +from typing_extensions import Required, TypedDict
44
45 from vllm.config import ModelConfig
46 from vllm.logger import init_logger
@@ -76,7 +76,7 @@ class ChatCompletionContentPartAudioParam(TypedDict, total=False):
76
77
78 class ChatCompletionContentPartImageEmbedsParam(TypedDict, total=False):
79 - image_embeds: Optional[Union[str, dict[str, str]]]
79 + image_embeds: str | dict[str, str] | None
80 """
81 The image embeddings. It can be either:
82 - A single base64 string.
@@ -84,7 +84,7 @@ class ChatCompletionContentPartImageEmbedsParam(TypedDict, total=False):
84 """
85 type: Required[Literal["image_embeds"]]
86 """The type of the content part."""
87 - uuid: Optional[str]
87 + uuid: str | None
88 """
89 User-provided UUID of a media. User must guarantee that it is properly
90 generated and unique for different medias.
@@ -123,8 +123,8 @@ class CustomChatCompletionContentPILImageParam(TypedDict, total=False):
123 }
124 """
125
126 - image_pil: Optional[PILImage]
127 - uuid: Optional[str]
126 + image_pil: PILImage | None
127 + uuid: str | None
128 """
129 User-provided UUID of a media. User must guarantee that it is properly
130 generated and unique for different medias.
@@ -141,8 +141,8 @@ class CustomChatCompletionContentSimpleImageParam(TypedDict, total=False):
141 }
142 """
143
144 - image_url: Optional[str]
145 - uuid: Optional[str]
144 + image_url: str | None
145 + uuid: str | None
146 """
147 User-provided UUID of a media. User must guarantee that it is properly
148 generated and unique for different medias.
@@ -158,7 +158,7 @@ class CustomChatCompletionContentSimpleAudioParam(TypedDict, total=False):
158 }
159 """
160
161 - audio_url: Optional[str]
161 + audio_url: str | None
162
163
164 class CustomChatCompletionContentSimpleVideoParam(TypedDict, total=False):
@@ -170,8 +170,8 @@ class CustomChatCompletionContentSimpleVideoParam(TypedDict, total=False):
170 }
171 """
172
173 - video_url: Optional[str]
174 - uuid: Optional[str]
173 + video_url: str | None
174 + uuid: str | None
175 """
176 User-provided UUID of a media. User must guarantee that it is properly
177 generated and unique for different medias.
@@ -199,20 +199,20 @@ class CustomThinkCompletionContentParam(TypedDict, total=False):
199 """The thinking type."""
200
201
202 -ChatCompletionContentPartParam: TypeAlias = Union[
203 - OpenAIChatCompletionContentPartParam,
204 - ChatCompletionContentPartAudioParam,
205 - ChatCompletionContentPartInputAudioParam,
206 - ChatCompletionContentPartVideoParam,
207 - ChatCompletionContentPartRefusalParam,
208 - CustomChatCompletionContentPILImageParam,
209 - CustomChatCompletionContentSimpleImageParam,
210 - ChatCompletionContentPartImageEmbedsParam,
211 - CustomChatCompletionContentSimpleAudioParam,
212 - CustomChatCompletionContentSimpleVideoParam,
213 - str,
214 - CustomThinkCompletionContentParam,
215 -]
202 +ChatCompletionContentPartParam: TypeAlias = (
203 + OpenAIChatCompletionContentPartParam
204 + | ChatCompletionContentPartAudioParam
205 + | ChatCompletionContentPartInputAudioParam
206 + | ChatCompletionContentPartVideoParam
207 + | ChatCompletionContentPartRefusalParam
208 + | CustomChatCompletionContentPILImageParam
209 + | CustomChatCompletionContentSimpleImageParam
210 + | ChatCompletionContentPartImageEmbedsParam
211 + | CustomChatCompletionContentSimpleAudioParam
212 + | CustomChatCompletionContentSimpleVideoParam
213 + | str
214 + | CustomThinkCompletionContentParam
215 +)
216
217
218 class CustomChatCompletionMessageParam(TypedDict, total=False):
@@ -221,7 +221,7 @@ class CustomChatCompletionMessageParam(TypedDict, total=False):
221 role: Required[str]
222 """The role of the message's author."""
223
224 - content: Union[str, list[ChatCompletionContentPartParam]]
224 + content: str | list[ChatCompletionContentPartParam]
225 """The contents of the message."""
226
227 name: str
@@ -231,18 +231,18 @@ class CustomChatCompletionMessageParam(TypedDict, total=False):
231 same role.
232 """
233
234 - tool_call_id: Optional[str]
234 + tool_call_id: str | None
235 """Tool call that this message is responding to."""
236
237 - tool_calls: Optional[Iterable[ChatCompletionMessageToolCallParam]]
237 + tool_calls: Iterable[ChatCompletionMessageToolCallParam] | None
238 """The tool calls generated by the model, such as function calls."""
239
240
241 -ChatCompletionMessageParam = Union[
242 - OpenAIChatCompletionMessageParam,
243 - CustomChatCompletionMessageParam,
244 - OpenAIHarmonyMessage,
245 -]
241 +ChatCompletionMessageParam: TypeAlias = (
242 + OpenAIChatCompletionMessageParam
243 + | CustomChatCompletionMessageParam
244 + | OpenAIHarmonyMessage
245 +)
246
247
248 # TODO: Make fields ReadOnly once mypy supports it
@@ -250,16 +250,16 @@ class ConversationMessage(TypedDict, total=False):
250 role: Required[str]
251 """The role of the message's author."""
252
253 - content: Union[Optional[str], list[dict[str, str]]]
253 + content: str | None | list[dict[str, str]]
254 """The contents of the message"""
255
256 - tool_call_id: Optional[str]
256 + tool_call_id: str | None
257 """Tool call that this message is responding to."""
258
259 - name: Optional[str]
259 + name: str | None
260 """The name of the function to call"""
261
262 - tool_calls: Optional[Iterable[ChatCompletionMessageToolCallParam]]
262 + tool_calls: Iterable[ChatCompletionMessageToolCallParam] | None
263 """The tool calls generated by the model, such as function calls."""
264
265
@@ -294,7 +294,7 @@ def _is_attr_access(node: jinja2.nodes.Node, varname: str, key: str) -> bool:
294 def _is_var_or_elems_access(
295 node: jinja2.nodes.Node,
296 varname: str,
297 - key: Optional[str] = None,
297 + key: str | None = None,
298 ) -> bool:
299 if isinstance(node, jinja2.nodes.Filter):
300 return node.node is not None and _is_var_or_elems_access(
@@ -369,7 +369,7 @@ def _iter_nodes_assign_content_item(root: jinja2.nodes.Node):
369 break
370
371
372 -def _try_extract_ast(chat_template: str) -> Optional[jinja2.nodes.Template]:
372 +def _try_extract_ast(chat_template: str) -> jinja2.nodes.Template | None:
373 try:
374 jinja_compiled = hf_chat_utils._compile_jinja_template(chat_template)
375 return jinja_compiled.environment.parse(chat_template)
@@ -400,9 +400,9 @@ def _detect_content_format(
400
401
402 def resolve_mistral_chat_template(
403 - chat_template: Optional[str],
403 + chat_template: str | None,
404 **kwargs: Any,
405 -) -> Optional[str]:
405 +) -> str | None:
406 if chat_template is not None or kwargs.get("chat_template_kwargs") is not None:
407 raise ValueError(
408 "'chat_template' or 'chat_template_kwargs' cannot be overridden "
@@ -412,7 +412,7 @@ def resolve_mistral_chat_template(
412 return None
413
414
415 -_PROCESSOR_CHAT_TEMPLATES = dict[tuple[str, bool], Optional[str]]()
415 +_PROCESSOR_CHAT_TEMPLATES = dict[tuple[str, bool], str | None]()
416 """
417 Used in `_try_get_processor_chat_template` to avoid calling
418 `cached_get_processor` again if the processor fails to be loaded.
@@ -422,9 +422,9 @@ This is needed because `lru_cache` does not cache when an exception happens.
422
423
424 def _try_get_processor_chat_template(
425 - tokenizer: Union[PreTrainedTokenizer, PreTrainedTokenizerFast],
425 + tokenizer: PreTrainedTokenizer | PreTrainedTokenizerFast,
426 model_config: ModelConfig,
427 -) -> Optional[str]:
427 +) -> str | None:
428 cache_key = (tokenizer.name_or_path, model_config.trust_remote_code)
429 if cache_key in _PROCESSOR_CHAT_TEMPLATES:
430 return _PROCESSOR_CHAT_TEMPLATES[cache_key]
@@ -458,12 +458,12 @@ def _try_get_processor_chat_template(
458
459
460 def resolve_hf_chat_template(
461 - tokenizer: Union[PreTrainedTokenizer, PreTrainedTokenizerFast],
462 - chat_template: Optional[str],
463 - tools: Optional[list[dict[str, Any]]],
461 + tokenizer: PreTrainedTokenizer | PreTrainedTokenizerFast,
462 + chat_template: str | None,
463 + tools: list[dict[str, Any]] | None,
464 *,
465 model_config: ModelConfig,
466 -) -> Optional[str]:
466 +) -> str | None:
467 # 1st priority: The given chat template
468 if chat_template is not None:
469 return chat_template
@@ -505,8 +505,8 @@ def resolve_hf_chat_template(
505
506
507 def _resolve_chat_template_content_format(
508 - chat_template: Optional[str],
509 - tools: Optional[list[dict[str, Any]]],
508 + chat_template: str | None,
509 + tools: list[dict[str, Any]] | None,
510 tokenizer: AnyTokenizer,
511 *,
512 model_config: ModelConfig,
@@ -538,7 +538,7 @@ def _resolve_chat_template_content_format(
538
539 @lru_cache
540 def _log_chat_template_content_format(
541 - chat_template: Optional[str],
541 + chat_template: str | None,
542 given_format: ChatTemplateContentFormatOption,
543 detected_format: ChatTemplateContentFormatOption,
544 ):
@@ -561,8 +561,8 @@ def _log_chat_template_content_format(
561
562
563 def resolve_chat_template_content_format(
564 - chat_template: Optional[str],
565 - tools: Optional[list[dict[str, Any]]],
564 + chat_template: str | None,
565 + tools: list[dict[str, Any]] | None,
566 given_format: ChatTemplateContentFormatOption,
567 tokenizer: AnyTokenizer,
568 *,
@@ -604,8 +604,8 @@ class BaseMultiModalItemTracker(ABC, Generic[_T]):
604 self._model_config = model_config
605 self._tokenizer = tokenizer
606
607 - self._items_by_modality = defaultdict[str, list[Optional[_T]]](list)
608 - self._uuids_by_modality = defaultdict[str, list[Optional[str]]](list)
607 + self._items_by_modality = defaultdict[str, list[_T | None]](list)
608 + self._uuids_by_modality = defaultdict[str, list[str | None]](list)
609
610 @property
611 def model_config(self) -> ModelConfig:
@@ -637,9 +637,9 @@ class BaseMultiModalItemTracker(ABC, Generic[_T]):
637 def add(
638 self,
639 modality: ModalityStr,
640 - item: Optional[_T],
641 - uuid: Optional[str] = None,
642 - ) -> Optional[str]:
640 + item: _T | None,
641 + uuid: str | None = None,
642 + ) -> str | None:
643 """
644 Add a multi-modal item to the current prompt and returns the
645 placeholder string to use, if any.
@@ -657,7 +657,7 @@ class BaseMultiModalItemTracker(ABC, Generic[_T]):
657
658 return self.model_cls.get_placeholder_str(modality, num_items)
659
660 - def all_mm_uuids(self) -> Optional[MultiModalUUIDDict]:
660 + def all_mm_uuids(self) -> MultiModalUUIDDict | None:
661 if not self._items_by_modality:
662 return None
663 mm_uuids = {}
@@ -684,7 +684,7 @@ class BaseMultiModalItemTracker(ABC, Generic[_T]):
684
685
686 class MultiModalItemTracker(BaseMultiModalItemTracker[object]):
687 - def all_mm_data(self) -> Optional[MultiModalDataDict]:
687 + def all_mm_data(self) -> MultiModalDataDict | None:
688 if not self._items_by_modality:
689 return None
690 mm_inputs = {}
@@ -710,7 +710,7 @@ class MultiModalItemTracker(BaseMultiModalItemTracker[object]):
710
711
712 class AsyncMultiModalItemTracker(BaseMultiModalItemTracker[Awaitable[object]]):
713 - async def all_mm_data(self) -> Optional[MultiModalDataDict]:
713 + async def all_mm_data(self) -> MultiModalDataDict | None:
714 if not self._items_by_modality:
715 return None
716 mm_inputs = {}
@@ -756,7 +756,7 @@ class BaseMultiModalContentParser(ABC):
756 # }
757 self._placeholder_storage: dict[str, list] = defaultdict(list)
758
759 - def _add_placeholder(self, modality: ModalityStr, placeholder: Optional[str]):
759 + def _add_placeholder(self, modality: ModalityStr, placeholder: str | None):
760 mod_placeholder = MODALITY_PLACEHOLDERS_MAP[modality]
761 if placeholder:
762 self._placeholder_storage[mod_placeholder].append(placeholder)
@@ -765,35 +765,35 @@ class BaseMultiModalContentParser(ABC):
765 return dict(self._placeholder_storage)
766
767 @abstractmethod
768 - def parse_image(self, image_url: Optional[str], uuid: Optional[str] = None) -> None:
768 + def parse_image(self, image_url: str | None, uuid: str | None = None) -> None:
769 raise NotImplementedError
770
771 @abstractmethod
772 def parse_image_embeds(
773 self,
774 - image_embeds: Union[str, dict[str, str], None],
775 - uuid: Optional[str] = None,
774 + image_embeds: str | dict[str, str] | None,
775 + uuid: str | None = None,
776 ) -> None:
777 raise NotImplementedError
778
779 @abstractmethod
780 def parse_image_pil(
781 - self, image_pil: Optional[Image.Image], uuid: Optional[str] = None
781 + self, image_pil: Image.Image | None, uuid: str | None = None
782 ) -> None:
783 raise NotImplementedError
784
785 @abstractmethod
786 - def parse_audio(self, audio_url: Optional[str], uuid: Optional[str] = None) -> None:
786 + def parse_audio(self, audio_url: str | None, uuid: str | None = None) -> None:
787 raise NotImplementedError
788
789 @abstractmethod
790 def parse_input_audio(
791 - self, input_audio: Optional[InputAudio], uuid: Optional[str] = None
791 + self, input_audio: InputAudio | None, uuid: str | None = None
792 ) -> None:
793 raise NotImplementedError
794
795 @abstractmethod
796 - def parse_video(self, video_url: Optional[str], uuid: Optional[str] = None) -> None:
796 + def parse_video(self, video_url: str | None, uuid: str | None = None) -> None:
797 raise NotImplementedError
798
799
@@ -810,7 +810,7 @@ class MultiModalContentParser(BaseMultiModalContentParser):
810 allowed_media_domains=tracker.allowed_media_domains,
811 )
812
813 - def parse_image(self, image_url: Optional[str], uuid: Optional[str] = None) -> None:
813 + def parse_image(self, image_url: str | None, uuid: str | None = None) -> None:
814 image = self._connector.fetch_image(image_url) if image_url else None
815
816 placeholder = self._tracker.add("image", image, uuid)
@@ -818,8 +818,8 @@ class MultiModalContentParser(BaseMultiModalContentParser):
818
819 def parse_image_embeds(
820 self,
821 - image_embeds: Union[str, dict[str, str], None],
822 - uuid: Optional[str] = None,
821 + image_embeds: str | dict[str, str] | None,
822 + uuid: str | None = None,
823 ) -> None:
824 if isinstance(image_embeds, dict):
825 embeds = {
@@ -838,19 +838,19 @@ class MultiModalContentParser(BaseMultiModalContentParser):
838 self._add_placeholder("image", placeholder)
839
840 def parse_image_pil(
841 - self, image_pil: Optional[Image.Image], uuid: Optional[str] = None
841 + self, image_pil: Image.Image | None, uuid: str | None = None
842 ) -> None:
843 placeholder = self._tracker.add("image", image_pil, uuid)
844 self._add_placeholder("image", placeholder)
845
846 - def parse_audio(self, audio_url: Optional[str], uuid: Optional[str] = None) -> None:
846 + def parse_audio(self, audio_url: str | None, uuid: str | None = None) -> None:
847 audio = self._connector.fetch_audio(audio_url) if audio_url else None
848
849 placeholder = self._tracker.add("audio", audio, uuid)
850 self._add_placeholder("audio", placeholder)
851
852 def parse_input_audio(
853 - self, input_audio: Optional[InputAudio], uuid: Optional[str] = None
853 + self, input_audio: InputAudio | None, uuid: str | None = None
854 ) -> None:
855 if input_audio:
856 audio_data = input_audio.get("data", "")
@@ -865,7 +865,7 @@ class MultiModalContentParser(BaseMultiModalContentParser):
865
866 return self.parse_audio(audio_url, uuid)
867
868 - def parse_video(self, video_url: Optional[str], uuid: Optional[str] = None) -> None:
868 + def parse_video(self, video_url: str | None, uuid: str | None = None) -> None:
869 video = self._connector.fetch_video(video_url=video_url) if video_url else None
870
871 placeholder = self._tracker.add("video", video, uuid)
@@ -885,7 +885,7 @@ class AsyncMultiModalContentParser(BaseMultiModalContentParser):
885 allowed_media_domains=tracker.allowed_media_domains,
886 )
887
888 - def parse_image(self, image_url: Optional[str], uuid: Optional[str] = None) -> None:
888 + def parse_image(self, image_url: str | None, uuid: str | None = None) -> None:
889 image_coro = self._connector.fetch_image_async(image_url) if image_url else None
890
891 placeholder = self._tracker.add("image", image_coro, uuid)
@@ -893,10 +893,10 @@ class AsyncMultiModalContentParser(BaseMultiModalContentParser):
893
894 def parse_image_embeds(
895 self,
896 - image_embeds: Union[str, dict[str, str], None],
897 - uuid: Optional[str] = None,
896 + image_embeds: str | dict[str, str] | None,
897 + uuid: str | None = None,
898 ) -> None:
899 - future: asyncio.Future[Union[str, dict[str, str], None]] = asyncio.Future()
899 + future: asyncio.Future[str | dict[str, str] | None] = asyncio.Future()
900
901 if isinstance(image_embeds, dict):
902 embeds = {
@@ -916,9 +916,9 @@ class AsyncMultiModalContentParser(BaseMultiModalContentParser):
916 self._add_placeholder("image", placeholder)
917
918 def parse_image_pil(
919 - self, image_pil: Optional[Image.Image], uuid: Optional[str] = None
919 + self, image_pil: Image.Image | None, uuid: str | None = None
920 ) -> None:
921 - future: asyncio.Future[Optional[Image.Image]] = asyncio.Future()
921 + future: asyncio.Future[Image.Image | None] = asyncio.Future()
922 if image_pil:
923 future.set_result(image_pil)
924 else:
@@ -927,14 +927,14 @@ class AsyncMultiModalContentParser(BaseMultiModalContentParser):
927 placeholder = self._tracker.add("image", future, uuid)
928 self._add_placeholder("image", placeholder)
929
930 - def parse_audio(self, audio_url: Optional[str], uuid: Optional[str] = None) -> None:
930 + def parse_audio(self, audio_url: str | None, uuid: str | None = None) -> None:
931 audio_coro = self._connector.fetch_audio_async(audio_url) if audio_url else None
932
933 placeholder = self._tracker.add("audio", audio_coro, uuid)
934 self._add_placeholder("audio", placeholder)
935
936 def parse_input_audio(
937 - self, input_audio: Optional[InputAudio], uuid: Optional[str] = None
937 + self, input_audio: InputAudio | None, uuid: str | None = None
938 ) -> None:
939 if input_audio:
940 audio_data = input_audio.get("data", "")
@@ -949,7 +949,7 @@ class AsyncMultiModalContentParser(BaseMultiModalContentParser):
949
950 return self.parse_audio(audio_url, uuid)
951
952 - def parse_video(self, video_url: Optional[str], uuid: Optional[str] = None) -> None:
952 + def parse_video(self, video_url: str | None, uuid: str | None = None) -> None:
953 video = (
954 self._connector.fetch_video_async(video_url=video_url)
955 if video_url
@@ -960,7 +960,7 @@ class AsyncMultiModalContentParser(BaseMultiModalContentParser):
960 self._add_placeholder("video", placeholder)
961
962
963 -def validate_chat_template(chat_template: Optional[Union[Path, str]]):
963 +def validate_chat_template(chat_template: Path | str | None):
964 """Raises if the provided chat template appears invalid."""
965 if chat_template is None:
966 return
@@ -984,10 +984,10 @@ def validate_chat_template(chat_template: Optional[Union[Path, str]]):
984
985
986 def _load_chat_template(
987 - chat_template: Optional[Union[Path, str]],
987 + chat_template: Path | str | None,
988 *,
989 is_literal: bool = False,
990 -) -> Optional[str]:
990 +) -> str | None:
991 if chat_template is None:
992 return None
993
@@ -1024,10 +1024,10 @@ _cached_load_chat_template = lru_cache(_load_chat_template)
1024
1025
1026 def load_chat_template(
1027 - chat_template: Optional[Union[Path, str]],
1027 + chat_template: Path | str | None,
1028 *,
1029 is_literal: bool = False,
1030 -) -> Optional[str]:
1030 +) -> str | None:
1031 return _cached_load_chat_template(chat_template, is_literal=is_literal)
1032
1033
@@ -1107,7 +1107,7 @@ _AudioParser = TypeAdapter(ChatCompletionContentPartAudioParam).validate_python
1107 _VideoParser = TypeAdapter(ChatCompletionContentPartVideoParam).validate_python
1108
1109 _ResponsesInputImageParser = TypeAdapter(ResponseInputImageParam).validate_python
1110 -_ContentPart: TypeAlias = Union[str, dict[str, str], InputAudio, PILImage]
1110 +_ContentPart: TypeAlias = str | dict[str, str] | InputAudio | PILImage
1111
1112 # Define a mapping from part types to their corresponding parsing functions.
1113 MM_PARSER_MAP: dict[
@@ -1264,7 +1264,7 @@ def _parse_chat_message_content_part(
1264 *,
1265 wrap_dicts: bool,
1266 interleave_strings: bool,
1267 -) -> Optional[_ContentPart]:
1267 +) -> _ContentPart | None:
1268 """Parses a single part of a conversation. If wrap_dicts is True,
1269 structured dictionary pieces for texts and images will be
1270 wrapped in dictionaries, i.e., {"type": "text", "text", ...} and
@@ -1310,10 +1310,7 @@ def _parse_chat_message_content_part(
1310 mm_parser.parse_image(str_content, uuid)
1311 modality = "image"
1312 elif part_type == "image_embeds":
1313 - if content is not None:
1314 - content = cast(Union[str, dict[str, str]], content)
1315 - else:
1316 - content = None
1313 + content = cast(str | dict[str, str], content) if content is not None else None
1314 mm_parser.parse_image_embeds(content, uuid)
1315 modality = "image"
1316 elif part_type == "audio_url":
@@ -1411,8 +1408,8 @@ def parse_chat_messages(
1408 content_format: _ChatTemplateContentFormat,
1409 ) -> tuple[
1410 list[ConversationMessage],
1414 - Optional[MultiModalDataDict],
1415 - Optional[MultiModalUUIDDict],
1411 + MultiModalDataDict | None,
1412 + MultiModalUUIDDict | None,
1413 ]:
1414 conversation: list[ConversationMessage] = []
1415 mm_tracker = MultiModalItemTracker(model_config, tokenizer)
@@ -1443,8 +1440,8 @@ def parse_chat_messages_futures(
1440 content_format: _ChatTemplateContentFormat,
1441 ) -> tuple[
1442 list[ConversationMessage],
1446 - Awaitable[Optional[MultiModalDataDict]],
1447 - Optional[MultiModalUUIDDict],
1443 + Awaitable[MultiModalDataDict | None],
1444 + MultiModalUUIDDict | None,
1445 ]:
1446 conversation: list[ConversationMessage] = []
1447 mm_tracker = AsyncMultiModalItemTracker(model_config, tokenizer)
@@ -1498,7 +1495,7 @@ _cached_resolve_chat_template_kwargs = lru_cache(_resolve_chat_template_kwargs)
1495
1496
1497 def resolve_chat_template_kwargs(
1501 - tokenizer: Union[PreTrainedTokenizer, PreTrainedTokenizerFast],
1498 + tokenizer: PreTrainedTokenizer | PreTrainedTokenizerFast,
1499 chat_template: str,
1500 chat_template_kwargs: dict[str, Any],
1501 ) -> dict[str, Any]:
@@ -1518,10 +1515,10 @@ def resolve_chat_template_kwargs(
1515
1516
1517 def apply_hf_chat_template(
1521 - tokenizer: Union[PreTrainedTokenizer, PreTrainedTokenizerFast],
1518 + tokenizer: PreTrainedTokenizer | PreTrainedTokenizerFast,
1519 conversation: list[ConversationMessage],
1523 - chat_template: Optional[str],
1524 - tools: Optional[list[dict[str, Any]]],
1520 + chat_template: str | None,
1521 + tools: list[dict[str, Any]] | None,
1522 *,
1523 model_config: ModelConfig,
1524 tokenize: bool = False, # Different from HF's default
@@ -1569,8 +1566,8 @@ def apply_hf_chat_template(
1566 def apply_mistral_chat_template(
1567 tokenizer: MistralTokenizer,
1568 messages: list[ChatCompletionMessageParam],
1572 - chat_template: Optional[str],
1573 - tools: Optional[list[dict[str, Any]]],
1569 + chat_template: str | None,
1570 + tools: list[dict[str, Any]] | None,
1571 **kwargs: Any,
1572 ) -> list[int]:
1573 from mistral_common.exceptions import MistralCommonException
vllm/entrypoints/cli/benchmark/main.py
+2 -2
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import argparse
5 import typing
6
@@ -12,6 +10,8 @@ from vllm.entrypoints.utils import VLLM_SUBCMD_PARSER_EPILOG
10
11 if typing.TYPE_CHECKING:
12 from vllm.utils import FlexibleArgumentParser
13 +else:
14 + FlexibleArgumentParser = argparse.ArgumentParser
15
16
17 class BenchmarkSubcommand(CLISubcommand):
vllm/entrypoints/cli/collect_env.py
+2 -2
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import argparse
5 import typing
6
@@ -11,6 +9,8 @@ from vllm.entrypoints.cli.types import CLISubcommand
9
10 if typing.TYPE_CHECKING:
11 from vllm.utils import FlexibleArgumentParser
12 +else:
13 + FlexibleArgumentParser = argparse.ArgumentParser
14
15
16 class CollectEnvSubcommand(CLISubcommand):
vllm/entrypoints/cli/main.py
-2
@@ -5,8 +5,6 @@
5 Note that all future modules must be lazily loaded within main
6 to avoid certain eager import breakage."""
7
8 -from __future__ import annotations
9 -
8 import importlib.metadata
9 import sys
10
vllm/entrypoints/cli/openai.py
+2 -2
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import argparse
5 import os
6 import signal
@@ -16,6 +14,8 @@ from vllm.entrypoints.cli.types import CLISubcommand
14
15 if TYPE_CHECKING:
16 from vllm.utils import FlexibleArgumentParser
17 +else:
18 + FlexibleArgumentParser = argparse.ArgumentParser
19
20
21 def _register_signal_handlers():
vllm/entrypoints/cli/run_batch.py
+2 -2
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import argparse
5 import asyncio
6 import importlib.metadata
@@ -14,6 +12,8 @@ from vllm.logger import init_logger
12
13 if typing.TYPE_CHECKING:
14 from vllm.utils import FlexibleArgumentParser
15 +else:
16 + FlexibleArgumentParser = argparse.ArgumentParser
17
18 logger = init_logger(__name__)
19
vllm/entrypoints/cli/serve.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import argparse
5 import signal
6 -from typing import Optional
6
7 import uvloop
8
@@ -179,7 +178,7 @@ def run_multi_api_server(args: argparse.Namespace):
178 hybrid_dp_lb = parallel_config.data_parallel_hybrid_lb
179 assert external_dp_lb or hybrid_dp_lb or dp_rank == 0
180
182 - api_server_manager: Optional[APIServerProcessManager] = None
181 + api_server_manager: APIServerProcessManager | None = None
182
183 with launch_core_engines(
184 vllm_config, executor_class, log_stats, num_api_servers
vllm/entrypoints/cli/types.py
+2 -2
@@ -1,13 +1,13 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import argparse
5 import typing
6
7 if typing.TYPE_CHECKING:
8 from vllm.utils import FlexibleArgumentParser
9 +else:
10 + FlexibleArgumentParser = argparse.ArgumentParser
11
12
13 class CLISubcommand:
vllm/entrypoints/context.py
+8 -8
@@ -6,7 +6,7 @@ import json
6 import logging
7 from abc import ABC, abstractmethod
8 from contextlib import AsyncExitStack
9 -from typing import TYPE_CHECKING, Optional, Union
9 +from typing import TYPE_CHECKING, Union
10
11 from openai.types.responses.tool import Mcp
12 from openai_harmony import Author, Message, Role, StreamState, TextContent
@@ -82,7 +82,7 @@ class ConversationContext(ABC):
82 @abstractmethod
83 async def init_tool_sessions(
84 self,
85 - tool_server: Optional[ToolServer],
85 + tool_server: ToolServer | None,
86 exit_stack: AsyncExitStack,
87 request_id: str,
88 mcp_tools: dict[str, Mcp],
@@ -122,7 +122,7 @@ class SimpleContext(ConversationContext):
122
123 async def init_tool_sessions(
124 self,
125 - tool_server: Optional[ToolServer],
125 + tool_server: ToolServer | None,
126 exit_stack: AsyncExitStack,
127 request_id: str,
128 mcp_tools: dict[str, Mcp],
@@ -140,9 +140,9 @@ class HarmonyContext(ConversationContext):
140 available_tools: list[str],
141 ):
142 self._messages = messages
143 - self.finish_reason: Optional[str] = None
143 + self.finish_reason: str | None = None
144 self.available_tools = available_tools
145 - self._tool_sessions: dict[str, Union[ClientSession, Tool]] = {}
145 + self._tool_sessions: dict[str, ClientSession | Tool] = {}
146 self.called_tools: set[str] = set()
147
148 self.parser = get_streamable_parser_for_assistant()
@@ -164,7 +164,7 @@ class HarmonyContext(ConversationContext):
164 if self.parser.current_channel in {"analysis", "commentary"}:
165 self.num_reasoning_tokens += 1
166
167 - def append_output(self, output: Union[RequestOutput, list[Message]]) -> None:
167 + def append_output(self, output: RequestOutput | list[Message]) -> None:
168 if isinstance(output, RequestOutput):
169 output_token_ids = output.outputs[0].token_ids
170 self.parser = get_streamable_parser_for_assistant()
@@ -358,7 +358,7 @@ class HarmonyContext(ConversationContext):
358
359 async def init_tool_sessions(
360 self,
361 - tool_server: Optional[ToolServer],
361 + tool_server: ToolServer | None,
362 exit_stack: AsyncExitStack,
363 request_id: str,
364 mcp_tools: dict[str, Mcp],
@@ -446,7 +446,7 @@ class StreamingHarmonyContext(HarmonyContext):
446 def messages(self) -> list:
447 return self._messages
448
449 - def append_output(self, output: Union[RequestOutput, list[Message]]) -> None:
449 + def append_output(self, output: RequestOutput | list[Message]) -> None:
450 if isinstance(output, RequestOutput):
451 # append_output is called for each output token in streaming case,
452 # so we only want to add the prompt tokens once for each message.
vllm/entrypoints/harmony_utils.py
+5 -7
@@ -1,12 +1,10 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import datetime
5 import json
6 from collections.abc import Iterable, Sequence
9 -from typing import Literal, Union
7 +from typing import Literal
8
9 from openai.types.responses import (
10 ResponseFunctionToolCall,
@@ -122,7 +120,7 @@ def get_system_message(
120 return sys_msg
121
122
125 -def create_tool_definition(tool: Union[ChatCompletionToolsParam, Tool]):
123 +def create_tool_definition(tool: ChatCompletionToolsParam | Tool):
124 if isinstance(tool, ChatCompletionToolsParam):
125 return ToolDescription.new(
126 name=tool.function.name,
@@ -138,13 +136,13 @@ def create_tool_definition(tool: Union[ChatCompletionToolsParam, Tool]):
136
137 def get_developer_message(
138 instructions: str | None = None,
141 - tools: list[Union[Tool, ChatCompletionToolsParam]] | None = None,
139 + tools: list[Tool | ChatCompletionToolsParam] | None = None,
140 ) -> Message:
141 dev_msg_content = DeveloperContent.new()
142 if instructions is not None and not envs.VLLM_GPT_OSS_HARMONY_SYSTEM_INSTRUCTIONS:
143 dev_msg_content = dev_msg_content.with_instructions(instructions)
144 if tools is not None:
147 - function_tools: list[Union[Tool, ChatCompletionToolsParam]] = []
145 + function_tools: list[Tool | ChatCompletionToolsParam] = []
146 for tool in tools:
147 if tool.type in (
148 "web_search_preview",
@@ -178,7 +176,7 @@ def get_user_message(content: str) -> Message:
176
177 def parse_response_input(
178 response_msg: ResponseInputOutputItem,
181 - prev_responses: list[Union[ResponseOutputItem, ResponseReasoningItem]],
179 + prev_responses: list[ResponseOutputItem | ResponseReasoningItem],
180 ) -> Message:
181 if not isinstance(response_msg, dict):
182 response_msg = response_msg.model_dump()
vllm/entrypoints/launcher.py
+2 -2
@@ -5,7 +5,7 @@ import asyncio
5 import signal
6 import socket
7 from http import HTTPStatus
8 -from typing import Any, Optional
8 +from typing import Any
9
10 import uvicorn
11 from fastapi import FastAPI, Request, Response
@@ -26,7 +26,7 @@ logger = init_logger(__name__)
26
27 async def serve_http(
28 app: FastAPI,
29 - sock: Optional[socket.socket],
29 + sock: socket.socket | None,
30 enable_ssl_refresh: bool = False,
31 **uvicorn_kwargs: Any,
32 ):
vllm/entrypoints/llm.py
+113 -121
@@ -2,8 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import itertools
5 -from collections.abc import Sequence
6 -from typing import TYPE_CHECKING, Any, Callable, Optional, Union, cast
5 +from collections.abc import Callable, Sequence
6 +from typing import TYPE_CHECKING, Any, cast
7
8 import cloudpickle
9 import torch.nn as nn
@@ -191,36 +191,34 @@ class LLM:
191 *,
192 runner: RunnerOption = "auto",
193 convert: ConvertOption = "auto",
194 - tokenizer: Optional[str] = None,
194 + tokenizer: str | None = None,
195 tokenizer_mode: TokenizerMode = "auto",
196 skip_tokenizer_init: bool = False,
197 trust_remote_code: bool = False,
198 allowed_local_media_path: str = "",
199 - allowed_media_domains: Optional[list[str]] = None,
199 + allowed_media_domains: list[str] | None = None,
200 tensor_parallel_size: int = 1,
201 dtype: ModelDType = "auto",
202 - quantization: Optional[QuantizationMethods] = None,
203 - revision: Optional[str] = None,
204 - tokenizer_revision: Optional[str] = None,
205 - seed: Optional[int] = None,
202 + quantization: QuantizationMethods | None = None,
203 + revision: str | None = None,
204 + tokenizer_revision: str | None = None,
205 + seed: int | None = None,
206 gpu_memory_utilization: float = 0.9,
207 swap_space: float = 4,
208 cpu_offload_gb: float = 0,
209 enforce_eager: bool = False,
210 disable_custom_all_reduce: bool = False,
211 - hf_token: Optional[Union[bool, str]] = None,
212 - hf_overrides: Optional[HfOverrides] = None,
213 - mm_processor_kwargs: Optional[dict[str, Any]] = None,
214 - pooler_config: Optional[PoolerConfig] = None,
215 - override_pooler_config: Optional[PoolerConfig] = None,
216 - structured_outputs_config: Optional[
217 - Union[dict[str, Any], StructuredOutputsConfig]
218 - ] = None,
219 - kv_cache_memory_bytes: Optional[int] = None,
220 - compilation_config: Optional[
221 - Union[int, dict[str, Any], CompilationConfig]
222 - ] = None,
223 - logits_processors: Optional[list[Union[str, type[LogitsProcessor]]]] = None,
211 + hf_token: bool | str | None = None,
212 + hf_overrides: HfOverrides | None = None,
213 + mm_processor_kwargs: dict[str, Any] | None = None,
214 + pooler_config: PoolerConfig | None = None,
215 + override_pooler_config: PoolerConfig | None = None,
216 + structured_outputs_config: dict[str, Any]
217 + | StructuredOutputsConfig
218 + | None = None,
219 + kv_cache_memory_bytes: int | None = None,
220 + compilation_config: int | dict[str, Any] | CompilationConfig | None = None,
221 + logits_processors: list[str | type[LogitsProcessor]] | None = None,
222 **kwargs: Any,
223 ) -> None:
224 """LLM constructor."""
@@ -331,7 +329,7 @@ class LLM:
329 self.engine_class = type(self.llm_engine)
330
331 self.request_counter = Counter()
334 - self.default_sampling_params: Union[dict[str, Any], None] = None
332 + self.default_sampling_params: dict[str, Any] | None = None
333
334 supported_tasks = self.llm_engine.get_supported_tasks()
335 logger.info("Supported tasks: %s", supported_tasks)
@@ -367,14 +365,12 @@ class LLM:
365
366 def generate(
367 self,
370 - prompts: Union[PromptType, Sequence[PromptType]],
371 - sampling_params: Optional[
372 - Union[SamplingParams, Sequence[SamplingParams]]
373 - ] = None,
368 + prompts: PromptType | Sequence[PromptType],
369 + sampling_params: SamplingParams | Sequence[SamplingParams] | None = None,
370 *,
375 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
376 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
377 - priority: Optional[list[int]] = None,
371 + use_tqdm: bool | Callable[..., tqdm] = True,
372 + lora_request: list[LoRARequest] | LoRARequest | None = None,
373 + priority: list[int] | None = None,
374 ) -> list[RequestOutput]:
375 """Generates the completions for the input prompts.
376
@@ -437,8 +433,8 @@ class LLM:
433
434 def _get_modality_specific_lora_reqs(
435 self,
440 - prompts: Union[PromptType, Sequence[PromptType]],
441 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]],
436 + prompts: PromptType | Sequence[PromptType],
437 + lora_request: list[LoRARequest] | LoRARequest | None,
438 ):
439 # Grab the lora config off the vllm config on the engine,
440 # since this is the same for both v0 & v1.
@@ -474,8 +470,8 @@ class LLM:
470 def _resolve_single_prompt_mm_lora(
471 self,
472 prompt: PromptType,
477 - lora_request: Optional[LoRARequest],
478 - default_mm_loras: Optional[dict[str, str]],
473 + lora_request: LoRARequest | None,
474 + default_mm_loras: dict[str, str] | None,
475 ):
476 if (
477 not default_mm_loras
@@ -526,10 +522,10 @@ class LLM:
522
523 def collective_rpc(
524 self,
529 - method: Union[str, Callable[..., _R]],
530 - timeout: Optional[float] = None,
525 + method: str | Callable[..., _R],
526 + timeout: float | None = None,
527 args: tuple = (),
532 - kwargs: Optional[dict[str, Any]] = None,
528 + kwargs: dict[str, Any] | None = None,
529 ) -> list[_R]:
530 """
531 Execute an RPC call on all workers.
@@ -571,9 +567,9 @@ class LLM:
567
568 def _get_beam_search_lora_requests(
569 self,
574 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]],
575 - prompts: list[Union[TokensPrompt, TextPrompt]],
576 - ) -> list[Optional[LoRARequest]]:
570 + lora_request: list[LoRARequest] | LoRARequest | None,
571 + prompts: list[TokensPrompt | TextPrompt],
572 + ) -> list[LoRARequest | None]:
573 """Get the optional lora request corresponding to each prompt."""
574 if isinstance(lora_request, Sequence) and len(lora_request) != len(prompts):
575 raise ValueError(
@@ -587,11 +583,11 @@ class LLM:
583
584 def beam_search(
585 self,
590 - prompts: list[Union[TokensPrompt, TextPrompt]],
586 + prompts: list[TokensPrompt | TextPrompt],
587 params: BeamSearchParams,
592 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
588 + lora_request: list[LoRARequest] | LoRARequest | None = None,
589 use_tqdm: bool = False,
594 - concurrency_limit: Optional[int] = None,
590 + concurrency_limit: int | None = None,
591 ) -> list[BeamSearchOutput]:
592 """
593 Generate sequences using beam search.
@@ -770,16 +766,15 @@ class LLM:
766
767 def preprocess_chat(
768 self,
773 - messages: Union[
774 - list[ChatCompletionMessageParam], list[list[ChatCompletionMessageParam]]
775 - ],
776 - chat_template: Optional[str] = None,
769 + messages: list[ChatCompletionMessageParam]
770 + | list[list[ChatCompletionMessageParam]],
771 + chat_template: str | None = None,
772 chat_template_content_format: ChatTemplateContentFormatOption = "auto",
773 add_generation_prompt: bool = True,
774 continue_final_message: bool = False,
780 - tools: Optional[list[dict[str, Any]]] = None,
781 - chat_template_kwargs: Optional[dict[str, Any]] = None,
782 - mm_processor_kwargs: Optional[dict[str, Any]] = None,
775 + tools: list[dict[str, Any]] | None = None,
776 + chat_template_kwargs: dict[str, Any] | None = None,
777 + mm_processor_kwargs: dict[str, Any] | None = None,
778 ) -> list[TokensPrompt]:
779 """
780 Generate prompt for a chat conversation. The pre-processed
@@ -868,19 +863,18 @@ class LLM:
863
864 def chat(
865 self,
871 - messages: Union[
872 - list[ChatCompletionMessageParam], list[list[ChatCompletionMessageParam]]
873 - ],
874 - sampling_params: Optional[Union[SamplingParams, list[SamplingParams]]] = None,
875 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
876 - lora_request: Optional[LoRARequest] = None,
877 - chat_template: Optional[str] = None,
866 + messages: list[ChatCompletionMessageParam]
867 + | list[list[ChatCompletionMessageParam]],
868 + sampling_params: SamplingParams | list[SamplingParams] | None = None,
869 + use_tqdm: bool | Callable[..., tqdm] = True,
870 + lora_request: LoRARequest | None = None,
871 + chat_template: str | None = None,
872 chat_template_content_format: ChatTemplateContentFormatOption = "auto",
873 add_generation_prompt: bool = True,
874 continue_final_message: bool = False,
881 - tools: Optional[list[dict[str, Any]]] = None,
882 - chat_template_kwargs: Optional[dict[str, Any]] = None,
883 - mm_processor_kwargs: Optional[dict[str, Any]] = None,
875 + tools: list[dict[str, Any]] | None = None,
876 + chat_template_kwargs: dict[str, Any] | None = None,
877 + mm_processor_kwargs: dict[str, Any] | None = None,
878 ) -> list[RequestOutput]:
879 """
880 Generate responses for a chat conversation.
@@ -953,14 +947,14 @@ class LLM:
947
948 def encode(
949 self,
956 - prompts: Union[PromptType, Sequence[PromptType], DataPrompt],
957 - pooling_params: Optional[Union[PoolingParams, Sequence[PoolingParams]]] = None,
950 + prompts: PromptType | Sequence[PromptType] | DataPrompt,
951 + pooling_params: PoolingParams | Sequence[PoolingParams] | None = None,
952 *,
959 - truncate_prompt_tokens: Optional[int] = None,
960 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
961 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
953 + truncate_prompt_tokens: int | None = None,
954 + use_tqdm: bool | Callable[..., tqdm] = True,
955 + lora_request: list[LoRARequest] | LoRARequest | None = None,
956 pooling_task: PoolingTask = "encode",
963 - tokenization_kwargs: Optional[dict[str, Any]] = None,
957 + tokenization_kwargs: dict[str, Any] | None = None,
958 ) -> list[PoolingRequestOutput]:
959 """Apply pooling to the hidden states corresponding to the input
960 prompts.
@@ -1086,12 +1080,12 @@ class LLM:
1080
1081 def embed(
1082 self,
1089 - prompts: Union[PromptType, Sequence[PromptType]],
1083 + prompts: PromptType | Sequence[PromptType],
1084 *,
1091 - truncate_prompt_tokens: Optional[int] = None,
1092 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
1093 - pooling_params: Optional[Union[PoolingParams, Sequence[PoolingParams]]] = None,
1094 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
1085 + truncate_prompt_tokens: int | None = None,
1086 + use_tqdm: bool | Callable[..., tqdm] = True,
1087 + pooling_params: PoolingParams | Sequence[PoolingParams] | None = None,
1088 + lora_request: list[LoRARequest] | LoRARequest | None = None,
1089 ) -> list[EmbeddingRequestOutput]:
1090 """
1091 Generate an embedding vector for each prompt.
@@ -1135,11 +1129,11 @@ class LLM:
1129
1130 def classify(
1131 self,
1138 - prompts: Union[PromptType, Sequence[PromptType]],
1132 + prompts: PromptType | Sequence[PromptType],
1133 *,
1140 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
1141 - pooling_params: Optional[Union[PoolingParams, Sequence[PoolingParams]]] = None,
1142 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
1134 + use_tqdm: bool | Callable[..., tqdm] = True,
1135 + pooling_params: PoolingParams | Sequence[PoolingParams] | None = None,
1136 + lora_request: list[LoRARequest] | LoRARequest | None = None,
1137 ) -> list[ClassificationRequestOutput]:
1138 """
1139 Generate class logits for each prompt.
@@ -1181,13 +1175,13 @@ class LLM:
1175
1176 def reward(
1177 self,
1184 - prompts: Union[PromptType, Sequence[PromptType]],
1178 + prompts: PromptType | Sequence[PromptType],
1179 /,
1180 *,
1187 - truncate_prompt_tokens: Optional[int] = None,
1188 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
1189 - pooling_params: Optional[Union[PoolingParams, Sequence[PoolingParams]]] = None,
1190 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
1181 + truncate_prompt_tokens: int | None = None,
1182 + use_tqdm: bool | Callable[..., tqdm] = True,
1183 + pooling_params: PoolingParams | Sequence[PoolingParams] | None = None,
1184 + lora_request: list[LoRARequest] | LoRARequest | None = None,
1185 ) -> list[PoolingRequestOutput]:
1186 """
1187 Generate rewards for each prompt.
@@ -1220,12 +1214,12 @@ class LLM:
1214 def _embedding_score(
1215 self,
1216 tokenizer: AnyTokenizer,
1223 - text_1: list[Union[str, TextPrompt, TokensPrompt]],
1224 - text_2: list[Union[str, TextPrompt, TokensPrompt]],
1225 - truncate_prompt_tokens: Optional[int] = None,
1226 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
1227 - pooling_params: Optional[PoolingParams] = None,
1228 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
1217 + text_1: list[str | TextPrompt | TokensPrompt],
1218 + text_2: list[str | TextPrompt | TokensPrompt],
1219 + truncate_prompt_tokens: int | None = None,
1220 + use_tqdm: bool | Callable[..., tqdm] = True,
1221 + pooling_params: PoolingParams | None = None,
1222 + lora_request: list[LoRARequest] | LoRARequest | None = None,
1223 ) -> list[ScoringRequestOutput]:
1224 encoded_output: list[PoolingRequestOutput] = self.encode(
1225 text_1 + text_2,
@@ -1252,12 +1246,12 @@ class LLM:
1246 def _cross_encoding_score(
1247 self,
1248 tokenizer: AnyTokenizer,
1255 - data_1: Union[list[str], list[ScoreContentPartParam]],
1256 - data_2: Union[list[str], list[ScoreContentPartParam]],
1257 - truncate_prompt_tokens: Optional[int] = None,
1258 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
1259 - pooling_params: Optional[PoolingParams] = None,
1260 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
1249 + data_1: list[str] | list[ScoreContentPartParam],
1250 + data_2: list[str] | list[ScoreContentPartParam],
1251 + truncate_prompt_tokens: int | None = None,
1252 + use_tqdm: bool | Callable[..., tqdm] = True,
1253 + pooling_params: PoolingParams | None = None,
1254 + lora_request: list[LoRARequest] | LoRARequest | None = None,
1255 ) -> list[ScoringRequestOutput]:
1256 model_config = self.model_config
1257
@@ -1316,14 +1310,14 @@ class LLM:
1310
1311 def score(
1312 self,
1319 - data_1: Union[SingletonPrompt, Sequence[SingletonPrompt], ScoreMultiModalParam],
1320 - data_2: Union[SingletonPrompt, Sequence[SingletonPrompt], ScoreMultiModalParam],
1313 + data_1: SingletonPrompt | Sequence[SingletonPrompt] | ScoreMultiModalParam,
1314 + data_2: SingletonPrompt | Sequence[SingletonPrompt] | ScoreMultiModalParam,
1315 /,
1316 *,
1323 - truncate_prompt_tokens: Optional[int] = None,
1324 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
1325 - pooling_params: Optional[PoolingParams] = None,
1326 - lora_request: Optional[Union[list[LoRARequest], LoRARequest]] = None,
1317 + truncate_prompt_tokens: int | None = None,
1318 + use_tqdm: bool | Callable[..., tqdm] = True,
1319 + pooling_params: PoolingParams | None = None,
1320 + lora_request: list[LoRARequest] | LoRARequest | None = None,
1321 ) -> list[ScoringRequestOutput]:
1322 """Generate similarity scores for all pairs `<text,text_pair>` or
1323 `<multi-modal data, multi-modal data pair>`.
@@ -1391,9 +1385,9 @@ class LLM:
1385 if not model_config.is_multimodal_model:
1386
1387 def check_data_type(
1394 - data: Union[
1395 - SingletonPrompt, Sequence[SingletonPrompt], ScoreMultiModalParam
1396 - ],
1388 + data: SingletonPrompt
1389 + | Sequence[SingletonPrompt]
1390 + | ScoreMultiModalParam,
1391 ):
1392 if isinstance(data, dict) and "content" in data:
1393 raise ValueError(
@@ -1470,7 +1464,7 @@ class LLM:
1464 def stop_profile(self) -> None:
1465 self.llm_engine.stop_profile()
1466
1473 - def reset_prefix_cache(self, device: Optional[Device] = None) -> bool:
1467 + def reset_prefix_cache(self, device: Device | None = None) -> bool:
1468 return self.llm_engine.reset_prefix_cache(device)
1469
1470 def sleep(self, level: int = 1):
@@ -1495,7 +1489,7 @@ class LLM:
1489 self.reset_prefix_cache()
1490 self.llm_engine.sleep(level=level)
1491
1498 - def wake_up(self, tags: Optional[list[str]] = None):
1492 + def wake_up(self, tags: list[str] | None = None):
1493 """
1494 Wake up the engine from sleep mode. See the [sleep][vllm.LLM.sleep]
1495 method for more details.
@@ -1523,17 +1517,15 @@ class LLM:
1517
1518 def _validate_and_add_requests(
1519 self,
1526 - prompts: Union[PromptType, Sequence[PromptType], DataPrompt],
1527 - params: Union[
1528 - SamplingParams,
1529 - Sequence[SamplingParams],
1530 - PoolingParams,
1531 - Sequence[PoolingParams],
1532 - ],
1520 + prompts: PromptType | Sequence[PromptType] | DataPrompt,
1521 + params: SamplingParams
1522 + | Sequence[SamplingParams]
1523 + | PoolingParams
1524 + | Sequence[PoolingParams],
1525 *,
1534 - use_tqdm: Union[bool, Callable[..., tqdm]] = True,
1535 - lora_request: Optional[Union[Sequence[LoRARequest], LoRARequest]],
1536 - priority: Optional[list[int]] = None,
1526 + use_tqdm: bool | Callable[..., tqdm] = True,
1527 + lora_request: Sequence[LoRARequest] | LoRARequest | None,
1528 + priority: list[int] | None = None,
1529 ) -> None:
1530 if isinstance(prompts, (str, dict)):
1531 # Convert a single prompt to a list.
@@ -1575,8 +1567,8 @@ class LLM:
1567
1568 def _validate_mm_data_and_uuids(
1569 self,
1578 - multi_modal_data: Optional[Any], # MultiModalDataDict
1579 - multi_modal_uuids: Optional[Any], # MultiModalUUIDDict
1570 + multi_modal_data: Any | None, # MultiModalDataDict
1571 + multi_modal_uuids: Any | None, # MultiModalUUIDDict
1572 ):
1573 """
1574 Validate that if any multi-modal data is skipped (i.e. None),
@@ -1625,9 +1617,9 @@ class LLM:
1617 self,
1618 request_id: str,
1619 engine_prompt: PromptType,
1628 - params: Union[SamplingParams, PoolingParams],
1620 + params: SamplingParams | PoolingParams,
1621 *,
1630 - lora_request: Optional[LoRARequest],
1622 + lora_request: LoRARequest | None,
1623 priority: int,
1624 ) -> tuple[EngineCoreRequest, dict[str, Any]]:
1625 """Use the Processor to process inputs for LLMEngine."""
@@ -1651,8 +1643,8 @@ class LLM:
1643 def _add_request(
1644 self,
1645 prompt: PromptType,
1654 - params: Union[SamplingParams, PoolingParams],
1655 - lora_request: Optional[LoRARequest] = None,
1646 + params: SamplingParams | PoolingParams,
1647 + lora_request: LoRARequest | None = None,
1648 priority: int = 0,
1649 ) -> None:
1650 prompt_text, _, _ = get_prompt_components(prompt)
@@ -1677,8 +1669,8 @@ class LLM:
1669 )
1670
1671 def _run_engine(
1680 - self, *, use_tqdm: Union[bool, Callable[..., tqdm]] = True
1681 - ) -> list[Union[RequestOutput, PoolingRequestOutput]]:
1672 + self, *, use_tqdm: bool | Callable[..., tqdm] = True
1673 + ) -> list[RequestOutput | PoolingRequestOutput]:
1674 # Initialize tqdm.
1675 if use_tqdm:
1676 num_requests = self.llm_engine.get_num_unfinished_requests()
@@ -1691,7 +1683,7 @@ class LLM:
1683 )
1684
1685 # Run the engine.
1694 - outputs: list[Union[RequestOutput, PoolingRequestOutput]] = []
1686 + outputs: list[RequestOutput | PoolingRequestOutput] = []
1687 total_in_toks = 0
1688 total_out_toks = 0
1689 while self.llm_engine.has_unfinished_requests():
vllm/entrypoints/logger.py
+8 -9
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Optional, Union
5
6 import torch
7
@@ -15,17 +14,17 @@ logger = init_logger(__name__)
14
15
16 class RequestLogger:
18 - def __init__(self, *, max_log_len: Optional[int]) -> None:
17 + def __init__(self, *, max_log_len: int | None) -> None:
18 self.max_log_len = max_log_len
19
20 def log_inputs(
21 self,
22 request_id: str,
24 - prompt: Optional[str],
25 - prompt_token_ids: Optional[list[int]],
26 - prompt_embeds: Optional[torch.Tensor],
27 - params: Optional[Union[SamplingParams, PoolingParams, BeamSearchParams]],
28 - lora_request: Optional[LoRARequest],
23 + prompt: str | None,
24 + prompt_token_ids: list[int] | None,
25 + prompt_embeds: torch.Tensor | None,
26 + params: SamplingParams | PoolingParams | BeamSearchParams | None,
27 + lora_request: LoRARequest | None,
28 ) -> None:
29 max_log_len = self.max_log_len
30 if max_log_len is not None:
@@ -52,8 +51,8 @@ class RequestLogger:
51 self,
52 request_id: str,
53 outputs: str,
55 - output_token_ids: Optional[Sequence[int]],
56 - finish_reason: Optional[str] = None,
54 + output_token_ids: Sequence[int] | None,
55 + finish_reason: str | None = None,
56 is_streaming: bool = False,
57 delta: bool = False,
58 ) -> None:
vllm/entrypoints/openai/api_server.py
+20 -20
@@ -16,10 +16,10 @@ import socket
16 import tempfile
17 import uuid
18 from argparse import Namespace
19 -from collections.abc import AsyncGenerator, AsyncIterator, Awaitable
19 +from collections.abc import AsyncGenerator, AsyncIterator, Awaitable, Callable
20 from contextlib import asynccontextmanager
21 from http import HTTPStatus
22 -from typing import Annotated, Any, Callable, Literal, Optional
22 +from typing import Annotated, Any, Literal
23
24 import prometheus_client
25 import pydantic
@@ -166,8 +166,8 @@ async def build_async_engine_client(
166 args: Namespace,
167 *,
168 usage_context: UsageContext = UsageContext.OPENAI_API_SERVER,
169 - disable_frontend_multiprocessing: Optional[bool] = None,
170 - client_config: Optional[dict[str, Any]] = None,
169 + disable_frontend_multiprocessing: bool | None = None,
170 + client_config: dict[str, Any] | None = None,
171 ) -> AsyncIterator[EngineClient]:
172 if os.getenv("VLLM_WORKER_MULTIPROC_METHOD") == "forkserver":
173 # The executor is expected to be mp.
@@ -203,7 +203,7 @@ async def build_async_engine_client_from_engine_args(
203 *,
204 usage_context: UsageContext = UsageContext.OPENAI_API_SERVER,
205 disable_frontend_multiprocessing: bool = False,
206 - client_config: Optional[dict[str, Any]] = None,
206 + client_config: dict[str, Any] | None = None,
207 ) -> AsyncIterator[EngineClient]:
208 """
209 Create EngineClient, either:
@@ -227,7 +227,7 @@ async def build_async_engine_client_from_engine_args(
227
228 from vllm.v1.engine.async_llm import AsyncLLM
229
230 - async_llm: Optional[AsyncLLM] = None
230 + async_llm: AsyncLLM | None = None
231
232 # Don't mutate the input client_config
233 client_config = dict(client_config) if client_config else {}
@@ -308,35 +308,35 @@ def models(request: Request) -> OpenAIServingModels:
308 return request.app.state.openai_serving_models
309
310
311 -def responses(request: Request) -> Optional[OpenAIServingResponses]:
311 +def responses(request: Request) -> OpenAIServingResponses | None:
312 return request.app.state.openai_serving_responses
313
314
315 -def chat(request: Request) -> Optional[OpenAIServingChat]:
315 +def chat(request: Request) -> OpenAIServingChat | None:
316 return request.app.state.openai_serving_chat
317
318
319 -def completion(request: Request) -> Optional[OpenAIServingCompletion]:
319 +def completion(request: Request) -> OpenAIServingCompletion | None:
320 return request.app.state.openai_serving_completion
321
322
323 -def pooling(request: Request) -> Optional[OpenAIServingPooling]:
323 +def pooling(request: Request) -> OpenAIServingPooling | None:
324 return request.app.state.openai_serving_pooling
325
326
327 -def embedding(request: Request) -> Optional[OpenAIServingEmbedding]:
327 +def embedding(request: Request) -> OpenAIServingEmbedding | None:
328 return request.app.state.openai_serving_embedding
329
330
331 -def score(request: Request) -> Optional[ServingScores]:
331 +def score(request: Request) -> ServingScores | None:
332 return request.app.state.openai_serving_scores
333
334
335 -def classify(request: Request) -> Optional[ServingClassification]:
335 +def classify(request: Request) -> ServingClassification | None:
336 return request.app.state.openai_serving_classification
337
338
339 -def rerank(request: Request) -> Optional[ServingScores]:
339 +def rerank(request: Request) -> ServingScores | None:
340 return request.app.state.openai_serving_scores
341
342
@@ -542,8 +542,8 @@ async def create_responses(request: ResponsesRequest, raw_request: Request):
542 async def retrieve_responses(
543 response_id: str,
544 raw_request: Request,
545 - starting_after: Optional[int] = None,
546 - stream: Optional[bool] = False,
545 + starting_after: int | None = None,
546 + stream: bool | None = False,
547 ):
548 handler = responses(raw_request)
549 if handler is None:
@@ -1039,7 +1039,7 @@ if envs.VLLM_SERVER_DEV_MODE:
1039 # User-defined `method` is responsible for deserialization if needed.
1040 args: list[str] = body.get("args", [])
1041 kwargs: dict[str, str] = body.get("kwargs", {})
1042 - timeout: Optional[float] = body.get("timeout")
1042 + timeout: float | None = body.get("timeout")
1043 results = await engine_client(raw_request).collective_rpc(
1044 method=method, timeout=timeout, args=tuple(args), kwargs=kwargs
1045 )
@@ -1120,7 +1120,7 @@ async def is_scaling_elastic_ep(raw_request: Request):
1120 # TODO: RequestType = TypeForm[BaseModel] when recognized by type checkers
1121 # (requires typing_extensions >= 4.13)
1122 RequestType = Any
1123 -GetHandlerFn = Callable[[Request], Optional[OpenAIServing]]
1123 +GetHandlerFn = Callable[[Request], OpenAIServing | None]
1124 EndpointFn = Callable[[RequestType, Request], Awaitable[Any]]
1125
1126 # NOTE: Items defined earlier take higher priority
@@ -1236,7 +1236,7 @@ if envs.VLLM_ALLOW_RUNTIME_LORA_UPDATING:
1236 return Response(status_code=200, content=response)
1237
1238
1239 -def load_log_config(log_config_file: Optional[str]) -> Optional[dict]:
1239 +def load_log_config(log_config_file: str | None) -> dict | None:
1240 if not log_config_file:
1241 return None
1242 try:
@@ -1655,7 +1655,7 @@ async def init_app_state(
1655 )
1656
1657 if args.tool_server == "demo":
1658 - tool_server: Optional[ToolServer] = DemoToolServer()
1658 + tool_server: ToolServer | None = DemoToolServer()
1659 assert isinstance(tool_server, DemoToolServer)
1660 await tool_server.init_and_validate()
1661 elif args.tool_server:
vllm/entrypoints/openai/cli_args.py
+16 -16
@@ -11,7 +11,7 @@ import json
11 import ssl
12 from collections.abc import Sequence
13 from dataclasses import field
14 -from typing import Literal, Optional, Union
14 +from typing import Literal
15
16 from pydantic.dataclasses import dataclass
17
@@ -39,8 +39,8 @@ class LoRAParserAction(argparse.Action):
39 self,
40 parser: argparse.ArgumentParser,
41 namespace: argparse.Namespace,
42 - values: Optional[Union[str, Sequence[str]]],
43 - option_string: Optional[str] = None,
42 + values: str | Sequence[str] | None,
43 + option_string: str | None = None,
44 ):
45 if values is None:
46 values = []
@@ -73,11 +73,11 @@ class LoRAParserAction(argparse.Action):
73 class FrontendArgs:
74 """Arguments for the OpenAI-compatible frontend server."""
75
76 - host: Optional[str] = None
76 + host: str | None = None
77 """Host name."""
78 port: int = 8000
79 """Port number."""
80 - uds: Optional[str] = None
80 + uds: str | None = None
81 """Unix domain socket path. If set, host and port arguments are ignored."""
82 uvicorn_log_level: Literal[
83 "debug", "info", "warning", "error", "critical", "trace"
@@ -93,15 +93,15 @@ class FrontendArgs:
93 """Allowed methods."""
94 allowed_headers: list[str] = field(default_factory=lambda: ["*"])
95 """Allowed headers."""
96 - api_key: Optional[list[str]] = None
96 + api_key: list[str] | None = None
97 """If provided, the server will require one of these keys to be presented in
98 the header."""
99 - lora_modules: Optional[list[LoRAModulePath]] = None
99 + lora_modules: list[LoRAModulePath] | None = None
100 """LoRA modules configurations in either 'name=path' format or JSON format
101 or JSON list format. Example (old format): `'name=path'` Example (new
102 format): `{\"name\": \"name\", \"path\": \"lora_path\",
103 \"base_model_name\": \"id\"}`"""
104 - chat_template: Optional[str] = None
104 + chat_template: str | None = None
105 """The file path to the chat template, or the template in single-line form
106 for the specified model."""
107 chat_template_content_format: ChatTemplateContentFormatOption = "auto"
@@ -116,17 +116,17 @@ class FrontendArgs:
116 or the ones from tokenizer."""
117 response_role: str = "assistant"
118 """The role name to return if `request.add_generation_prompt=true`."""
119 - ssl_keyfile: Optional[str] = None
119 + ssl_keyfile: str | None = None
120 """The file path to the SSL key file."""
121 - ssl_certfile: Optional[str] = None
121 + ssl_certfile: str | None = None
122 """The file path to the SSL cert file."""
123 - ssl_ca_certs: Optional[str] = None
123 + ssl_ca_certs: str | None = None
124 """The CA certificates file."""
125 enable_ssl_refresh: bool = False
126 """Refresh SSL Context when SSL certificate files change"""
127 ssl_cert_reqs: int = int(ssl.CERT_NONE)
128 """Whether client certificate is required (see stdlib ssl module's)."""
129 - root_path: Optional[str] = None
129 + root_path: str | None = None
130 """FastAPI root_path when app is behind a path based routing proxy."""
131 middleware: list[str] = field(default_factory=lambda: [])
132 """Additional ASGI middleware to apply to the app. We accept multiple
@@ -149,7 +149,7 @@ class FrontendArgs:
149 exclude_tools_when_tool_choice_none: bool = False
150 """If specified, exclude tool definitions in prompts when
151 tool_choice='none'."""
152 - tool_call_parser: Optional[str] = None
152 + tool_call_parser: str | None = None
153 """Select the tool call parser depending on the model that you're using.
154 This is used to parse the model-generated tool call into OpenAI API format.
155 Required for `--enable-auto-tool-choice`. You can choose any option from
@@ -158,13 +158,13 @@ class FrontendArgs:
158 """Special the tool parser plugin write to parse the model-generated tool
159 into OpenAI API format, the name register in this plugin can be used in
160 `--tool-call-parser`."""
161 - tool_server: Optional[str] = None
161 + tool_server: str | None = None
162 """Comma-separated list of host:port pairs (IPv4, IPv6, or hostname).
163 Examples: 127.0.0.1:8000, [::1]:8000, localhost:1234. Or `demo` for demo
164 purpose."""
165 - log_config_file: Optional[str] = envs.VLLM_LOGGING_CONFIG_PATH
165 + log_config_file: str | None = envs.VLLM_LOGGING_CONFIG_PATH
166 """Path to logging config JSON file for both vllm and uvicorn"""
167 - max_log_len: Optional[int] = None
167 + max_log_len: int | None = None
168 """Max number of prompt characters or prompt ID numbers being printed in
169 log. The default of None means unlimited."""
170 disable_fastapi_docs: bool = False
vllm/entrypoints/openai/logits_processors.py
+4 -5
@@ -3,7 +3,6 @@
3
4 from collections.abc import Iterable
5 from functools import lru_cache, partial
6 -from typing import Optional, Union
6
7 import torch
8
@@ -16,8 +15,8 @@ class AllowedTokenIdsLogitsProcessor:
15 specific set of token ids."""
16
17 def __init__(self, allowed_ids: Iterable[int]):
19 - self.allowed_ids: Optional[list[int]] = list(allowed_ids)
20 - self.mask: Optional[torch.Tensor] = None
18 + self.allowed_ids: list[int] | None = list(allowed_ids)
19 + self.mask: torch.Tensor | None = None
20
21 def __call__(self, token_ids: list[int], logits: torch.Tensor) -> torch.Tensor:
22 if self.mask is None:
@@ -53,8 +52,8 @@ def logit_bias_logits_processor(
52
53
54 def get_logits_processors(
56 - logit_bias: Optional[Union[dict[int, float], dict[str, float]]],
57 - allowed_token_ids: Optional[list[int]],
55 + logit_bias: dict[int, float] | dict[str, float] | None,
56 + allowed_token_ids: list[int] | None,
57 tokenizer: AnyTokenizer,
58 ) -> list[LogitsProcessor]:
59 logits_processors: list[LogitsProcessor] = []
vllm/entrypoints/openai/protocol.py
+339 -339
@@ -6,7 +6,7 @@
6 import json
7 import time
8 from http import HTTPStatus
9 -from typing import Annotated, Any, ClassVar, Generic, Literal, Optional, TypeVar, Union
9 +from typing import Annotated, Any, ClassVar, Generic, Literal, TypeAlias, TypeVar
10
11 import regex as re
12 import torch
@@ -54,6 +54,7 @@ try: # For older openai versions (< 1.100.0)
54 except ImportError: # For newer openai versions (>= 1.100.0)
55 from openai.types.responses import ResponseFormatTextConfig as ResponseTextConfig
56
57 +
58 from openai.types.responses.response import IncompleteDetails, ToolChoice
59 from openai.types.responses.tool import Tool
60 from openai.types.shared import Metadata, Reasoning
@@ -67,7 +68,6 @@ from pydantic import (
68 field_validator,
69 model_validator,
70 )
70 -from typing_extensions import TypeAlias
71
72 from vllm import envs
73 from vllm.entrypoints.chat_utils import ChatCompletionMessageParam, make_tool_call_id
@@ -93,7 +93,7 @@ class OpenAIBaseModel(BaseModel):
93 model_config = ConfigDict(extra="allow")
94
95 # Cache class field names
96 - field_names: ClassVar[Optional[set[str]]] = None
96 + field_names: ClassVar[set[str] | None] = None
97
98 @model_validator(mode="wrap")
99 @classmethod
@@ -123,7 +123,7 @@ class OpenAIBaseModel(BaseModel):
123 class ErrorInfo(OpenAIBaseModel):
124 message: str
125 type: str
126 - param: Optional[str] = None
126 + param: str | None = None
127 code: int
128
129
@@ -142,7 +142,7 @@ class ModelPermission(OpenAIBaseModel):
142 allow_view: bool = True
143 allow_fine_tuning: bool = False
144 organization: str = "*"
145 - group: Optional[str] = None
145 + group: str | None = None
146 is_blocking: bool = False
147
148
@@ -151,9 +151,9 @@ class ModelCard(OpenAIBaseModel):
151 object: str = "model"
152 created: int = Field(default_factory=lambda: int(time.time()))
153 owned_by: str = "vllm"
154 - root: Optional[str] = None
155 - parent: Optional[str] = None
156 - max_model_len: Optional[int] = None
154 + root: str | None = None
155 + parent: str | None = None
156 + max_model_len: int | None = None
157 permission: list[ModelPermission] = Field(default_factory=list)
158
159
@@ -163,37 +163,35 @@ class ModelList(OpenAIBaseModel):
163
164
165 class PromptTokenUsageInfo(OpenAIBaseModel):
166 - cached_tokens: Optional[int] = None
166 + cached_tokens: int | None = None
167
168
169 class UsageInfo(OpenAIBaseModel):
170 prompt_tokens: int = 0
171 total_tokens: int = 0
172 - completion_tokens: Optional[int] = 0
173 - prompt_tokens_details: Optional[PromptTokenUsageInfo] = None
172 + completion_tokens: int | None = 0
173 + prompt_tokens_details: PromptTokenUsageInfo | None = None
174
175
176 class RequestResponseMetadata(BaseModel):
177 request_id: str
178 - final_usage_info: Optional[UsageInfo] = None
178 + final_usage_info: UsageInfo | None = None
179
180
181 class JsonSchemaResponseFormat(OpenAIBaseModel):
182 name: str
183 - description: Optional[str] = None
183 + description: str | None = None
184 # schema is the field in openai but that causes conflicts with pydantic so
185 # instead use json_schema with an alias
186 - json_schema: Optional[dict[str, Any]] = Field(default=None, alias="schema")
187 - strict: Optional[bool] = None
186 + json_schema: dict[str, Any] | None = Field(default=None, alias="schema")
187 + strict: bool | None = None
188
189
190 class StructuralTag(OpenAIBaseModel):
191 begin: str
192 # schema is the field, but that causes conflicts with pydantic so
193 # instead use structural_tag_schema with an alias
194 - structural_tag_schema: Optional[dict[str, Any]] = Field(
195 - default=None, alias="schema"
196 - )
194 + structural_tag_schema: dict[str, Any] | None = Field(default=None, alias="schema")
195 end: str
196
197
@@ -206,21 +204,21 @@ class StructuralTagResponseFormat(OpenAIBaseModel):
204 class ResponseFormat(OpenAIBaseModel):
205 # type must be "json_schema", "json_object", or "text"
206 type: Literal["text", "json_object", "json_schema"]
209 - json_schema: Optional[JsonSchemaResponseFormat] = None
207 + json_schema: JsonSchemaResponseFormat | None = None
208
209
212 -AnyResponseFormat = Union[ResponseFormat, StructuralTagResponseFormat]
210 +AnyResponseFormat: TypeAlias = ResponseFormat | StructuralTagResponseFormat
211
212
213 class StreamOptions(OpenAIBaseModel):
216 - include_usage: Optional[bool] = True
217 - continuous_usage_stats: Optional[bool] = False
214 + include_usage: bool | None = True
215 + continuous_usage_stats: bool | None = False
216
217
218 class FunctionDefinition(OpenAIBaseModel):
219 name: str
222 - description: Optional[str] = None
223 - parameters: Optional[dict[str, Any]] = None
220 + description: str | None = None
221 + parameters: dict[str, Any] | None = None
222
223
224 class ChatCompletionToolsParam(OpenAIBaseModel):
@@ -241,18 +239,18 @@ class ChatCompletionNamedToolChoiceParam(OpenAIBaseModel):
239 # see https://github.com/pydantic/pydantic/issues/3125
240 class LogitsProcessorConstructor(BaseModel):
241 qualname: str
244 - args: Optional[list[Any]] = None
245 - kwargs: Optional[dict[str, Any]] = None
242 + args: list[Any] | None = None
243 + kwargs: dict[str, Any] | None = None
244
245 model_config = ConfigDict(extra="forbid")
246
247
250 -LogitsProcessors = list[Union[str, LogitsProcessorConstructor]]
248 +LogitsProcessors = list[str | LogitsProcessorConstructor]
249
250
251 def get_logits_processors(
254 - processors: Optional[LogitsProcessors], pattern: Optional[str]
255 -) -> Optional[list[Any]]:
252 + processors: LogitsProcessors | None, pattern: str | None
253 +) -> list[Any] | None:
254 if processors and pattern:
255 logits_processors = []
256 for processor in processors:
@@ -284,16 +282,16 @@ def get_logits_processors(
282 return None
283
284
287 -ResponseInputOutputItem: TypeAlias = Union[
288 - ResponseInputItemParam, ResponseReasoningItem, ResponseFunctionToolCall
289 -]
285 +ResponseInputOutputItem: TypeAlias = (
286 + ResponseInputItemParam | ResponseReasoningItem | ResponseFunctionToolCall
287 +)
288
289
290 class ResponsesRequest(OpenAIBaseModel):
291 # Ordered by official OpenAI API documentation
292 # https://platform.openai.com/docs/api-reference/responses/create
295 - background: Optional[bool] = False
296 - include: Optional[
293 + background: bool | None = False
294 + include: (
295 list[
296 Literal[
297 "code_interpreter_call.outputs",
@@ -304,28 +302,29 @@ class ResponsesRequest(OpenAIBaseModel):
302 "reasoning.encrypted_content",
303 ],
304 ]
307 - ] = None
308 - input: Union[str, list[ResponseInputOutputItem]]
309 - instructions: Optional[str] = None
310 - max_output_tokens: Optional[int] = None
311 - max_tool_calls: Optional[int] = None
312 - metadata: Optional[Metadata] = None
313 - model: Optional[str] = None
314 - parallel_tool_calls: Optional[bool] = True
315 - previous_response_id: Optional[str] = None
316 - prompt: Optional[ResponsePrompt] = None
317 - reasoning: Optional[Reasoning] = None
305 + | None
306 + ) = None
307 + input: str | list[ResponseInputOutputItem]
308 + instructions: str | None = None
309 + max_output_tokens: int | None = None
310 + max_tool_calls: int | None = None
311 + metadata: Metadata | None = None
312 + model: str | None = None
313 + parallel_tool_calls: bool | None = True
314 + previous_response_id: str | None = None
315 + prompt: ResponsePrompt | None = None
316 + reasoning: Reasoning | None = None
317 service_tier: Literal["auto", "default", "flex", "scale", "priority"] = "auto"
319 - store: Optional[bool] = True
320 - stream: Optional[bool] = False
321 - temperature: Optional[float] = None
322 - text: Optional[ResponseTextConfig] = None
318 + store: bool | None = True
319 + stream: bool | None = False
320 + temperature: float | None = None
321 + text: ResponseTextConfig | None = None
322 tool_choice: ToolChoice = "auto"
323 tools: list[Tool] = Field(default_factory=list)
325 - top_logprobs: Optional[int] = 0
326 - top_p: Optional[float] = None
327 - truncation: Optional[Literal["auto", "disabled"]] = "disabled"
328 - user: Optional[str] = None
324 + top_logprobs: int | None = 0
325 + top_p: float | None = None
326 + truncation: Literal["auto", "disabled"] | None = "disabled"
327 + user: str | None = None
328
329 # --8<-- [start:responses-extra-params]
330 request_id: str = Field(
@@ -336,7 +335,7 @@ class ResponsesRequest(OpenAIBaseModel):
335 "through out the inference process and return in response."
336 ),
337 )
339 - mm_processor_kwargs: Optional[dict[str, Any]] = Field(
338 + mm_processor_kwargs: dict[str, Any] | None = Field(
339 default=None,
340 description=("Additional kwargs to pass to the HF processor."),
341 )
@@ -348,7 +347,7 @@ class ResponsesRequest(OpenAIBaseModel):
347 "if the served model does not use priority scheduling."
348 ),
349 )
351 - cache_salt: Optional[str] = Field(
350 + cache_salt: str | None = Field(
351 default=None,
352 description=(
353 "If specified, the prefix cache will be salted with the provided "
@@ -378,7 +377,7 @@ class ResponsesRequest(OpenAIBaseModel):
377 def to_sampling_params(
378 self,
379 default_max_tokens: int,
381 - default_sampling_params: Optional[dict] = None,
380 + default_sampling_params: dict | None = None,
381 ) -> SamplingParams:
382 if self.max_output_tokens is None:
383 max_tokens = default_max_tokens
@@ -465,58 +464,57 @@ class ChatCompletionRequest(OpenAIBaseModel):
464 # Ordered by official OpenAI API documentation
465 # https://platform.openai.com/docs/api-reference/chat/create
466 messages: list[ChatCompletionMessageParam]
468 - model: Optional[str] = None
469 - frequency_penalty: Optional[float] = 0.0
470 - logit_bias: Optional[dict[str, float]] = None
471 - logprobs: Optional[bool] = False
472 - top_logprobs: Optional[int] = 0
473 - max_tokens: Optional[int] = Field(
467 + model: str | None = None
468 + frequency_penalty: float | None = 0.0
469 + logit_bias: dict[str, float] | None = None
470 + logprobs: bool | None = False
471 + top_logprobs: int | None = 0
472 + max_tokens: int | None = Field(
473 default=None,
474 deprecated="max_tokens is deprecated in favor of "
475 "the max_completion_tokens field",
476 )
478 - max_completion_tokens: Optional[int] = None
479 - n: Optional[int] = 1
480 - presence_penalty: Optional[float] = 0.0
481 - response_format: Optional[AnyResponseFormat] = None
482 - seed: Optional[int] = Field(None, ge=_LONG_INFO.min, le=_LONG_INFO.max)
483 - stop: Optional[Union[str, list[str]]] = []
484 - stream: Optional[bool] = False
485 - stream_options: Optional[StreamOptions] = None
486 - temperature: Optional[float] = None
487 - top_p: Optional[float] = None
488 - tools: Optional[list[ChatCompletionToolsParam]] = None
489 - tool_choice: Optional[
490 - Union[
491 - Literal["none"],
492 - Literal["auto"],
493 - Literal["required"],
494 - ChatCompletionNamedToolChoiceParam,
495 - ]
496 - ] = "none"
497 - reasoning_effort: Optional[Literal["low", "medium", "high"]] = None
477 + max_completion_tokens: int | None = None
478 + n: int | None = 1
479 + presence_penalty: float | None = 0.0
480 + response_format: AnyResponseFormat | None = None
481 + seed: int | None = Field(None, ge=_LONG_INFO.min, le=_LONG_INFO.max)
482 + stop: str | list[str] | None = []
483 + stream: bool | None = False
484 + stream_options: StreamOptions | None = None
485 + temperature: float | None = None
486 + top_p: float | None = None
487 + tools: list[ChatCompletionToolsParam] | None = None
488 + tool_choice: (
489 + Literal["none"]
490 + | Literal["auto"]
491 + | Literal["required"]
492 + | ChatCompletionNamedToolChoiceParam
493 + | None
494 + ) = "none"
495 + reasoning_effort: Literal["low", "medium", "high"] | None = None
496 include_reasoning: bool = True
497
498 # NOTE this will be ignored by vLLM -- the model determines the behavior
501 - parallel_tool_calls: Optional[bool] = False
502 - user: Optional[str] = None
499 + parallel_tool_calls: bool | None = False
500 + user: str | None = None
501
502 # --8<-- [start:chat-completion-sampling-params]
505 - best_of: Optional[int] = None
503 + best_of: int | None = None
504 use_beam_search: bool = False
507 - top_k: Optional[int] = None
508 - min_p: Optional[float] = None
509 - repetition_penalty: Optional[float] = None
505 + top_k: int | None = None
506 + min_p: float | None = None
507 + repetition_penalty: float | None = None
508 length_penalty: float = 1.0
511 - stop_token_ids: Optional[list[int]] = []
509 + stop_token_ids: list[int] | None = []
510 include_stop_str_in_output: bool = False
511 ignore_eos: bool = False
512 min_tokens: int = 0
513 skip_special_tokens: bool = True
514 spaces_between_special_tokens: bool = True
517 - truncate_prompt_tokens: Optional[Annotated[int, Field(ge=-1)]] = None
518 - prompt_logprobs: Optional[int] = None
519 - allowed_token_ids: Optional[list[int]] = None
515 + truncate_prompt_tokens: Annotated[int, Field(ge=-1)] | None = None
516 + prompt_logprobs: int | None = None
517 + allowed_token_ids: list[int] | None = None
518 bad_words: list[str] = Field(default_factory=list)
519 # --8<-- [end:chat-completion-sampling-params]
520
@@ -556,7 +554,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
554 "default)."
555 ),
556 )
559 - documents: Optional[list[dict[str, str]]] = Field(
557 + documents: list[dict[str, str]] | None = Field(
558 default=None,
559 description=(
560 "A list of dicts representing documents that will be accessible to "
@@ -566,7 +564,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
564 '"title" and "text" keys.'
565 ),
566 )
569 - chat_template: Optional[str] = Field(
567 + chat_template: str | None = Field(
568 default=None,
569 description=(
570 "A Jinja template to use for this conversion. "
@@ -575,22 +573,22 @@ class ChatCompletionRequest(OpenAIBaseModel):
573 "does not define one."
574 ),
575 )
578 - chat_template_kwargs: Optional[dict[str, Any]] = Field(
576 + chat_template_kwargs: dict[str, Any] | None = Field(
577 default=None,
578 description=(
579 "Additional keyword args to pass to the template renderer. "
580 "Will be accessible by the chat template."
581 ),
582 )
585 - mm_processor_kwargs: Optional[dict[str, Any]] = Field(
583 + mm_processor_kwargs: dict[str, Any] | None = Field(
584 default=None,
585 description=("Additional kwargs to pass to the HF processor."),
586 )
589 - structured_outputs: Optional[StructuredOutputsParams] = Field(
587 + structured_outputs: StructuredOutputsParams | None = Field(
588 default=None,
589 description="Additional kwargs for structured outputs",
590 )
593 - guided_json: Optional[Union[str, dict, BaseModel]] = Field(
591 + guided_json: str | dict | BaseModel | None = Field(
592 default=None,
593 description=(
594 "`guided_json` is deprecated. "
@@ -598,7 +596,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
596 "Please pass `json` to `structured_outputs` instead."
597 ),
598 )
601 - guided_regex: Optional[str] = Field(
599 + guided_regex: str | None = Field(
600 default=None,
601 description=(
602 "`guided_regex` is deprecated. "
@@ -606,7 +604,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
604 "Please pass `regex` to `structured_outputs` instead."
605 ),
606 )
609 - guided_choice: Optional[list[str]] = Field(
607 + guided_choice: list[str] | None = Field(
608 default=None,
609 description=(
610 "`guided_choice` is deprecated. "
@@ -614,7 +612,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
612 "Please pass `choice` to `structured_outputs` instead."
613 ),
614 )
617 - guided_grammar: Optional[str] = Field(
615 + guided_grammar: str | None = Field(
616 default=None,
617 description=(
618 "`guided_grammar` is deprecated. "
@@ -622,7 +620,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
620 "Please pass `grammar` to `structured_outputs` instead."
621 ),
622 )
625 - structural_tag: Optional[str] = Field(
623 + structural_tag: str | None = Field(
624 default=None,
625 description=(
626 "`structural_tag` is deprecated. "
@@ -630,7 +628,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
628 "Please pass `structural_tag` to `structured_outputs` instead."
629 ),
630 )
633 - guided_decoding_backend: Optional[str] = Field(
631 + guided_decoding_backend: str | None = Field(
632 default=None,
633 description=(
634 "`guided_decoding_backend` is deprecated. "
@@ -638,7 +636,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
636 "Please remove it from your request."
637 ),
638 )
641 - guided_whitespace_pattern: Optional[str] = Field(
639 + guided_whitespace_pattern: str | None = Field(
640 default=None,
641 description=(
642 "`guided_whitespace_pattern` is deprecated. "
@@ -662,7 +660,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
660 "through out the inference process and return in response."
661 ),
662 )
665 - logits_processors: Optional[LogitsProcessors] = Field(
663 + logits_processors: LogitsProcessors | None = Field(
664 default=None,
665 description=(
666 "A list of either qualified names of logits processors, or "
@@ -675,7 +673,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
673 "{'param': 'value'}}."
674 ),
675 )
678 - return_tokens_as_token_ids: Optional[bool] = Field(
676 + return_tokens_as_token_ids: bool | None = Field(
677 default=None,
678 description=(
679 "If specified with 'logprobs', tokens are represented "
@@ -683,7 +681,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
681 "that are not JSON-encodable can be identified."
682 ),
683 )
686 - return_token_ids: Optional[bool] = Field(
684 + return_token_ids: bool | None = Field(
685 default=None,
686 description=(
687 "If specified, the result will include token IDs alongside the "
@@ -693,7 +691,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
691 "need to map generated text back to input tokens."
692 ),
693 )
696 - cache_salt: Optional[str] = Field(
694 + cache_salt: str | None = Field(
695 default=None,
696 description=(
697 "If specified, the prefix cache will be salted with the provided "
@@ -704,12 +702,12 @@ class ChatCompletionRequest(OpenAIBaseModel):
702 "to 256 bit). Not supported by vLLM engine V0."
703 ),
704 )
707 - kv_transfer_params: Optional[dict[str, Any]] = Field(
705 + kv_transfer_params: dict[str, Any] | None = Field(
706 default=None,
707 description="KVTransfer parameters used for disaggregated serving.",
708 )
709
712 - vllm_xargs: Optional[dict[str, Union[str, int, float]]] = Field(
710 + vllm_xargs: dict[str, str | int | float] | None = Field(
711 default=None,
712 description=(
713 "Additional request parameters with string or "
@@ -749,7 +747,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
747 def to_sampling_params(
748 self,
749 max_tokens: int,
752 - logits_processor_pattern: Optional[str],
750 + logits_processor_pattern: str | None,
751 default_sampling_params: dict,
752 ) -> SamplingParams:
753 # Default parameters
@@ -860,7 +858,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
858 extra_args=extra_args or None,
859 )
860
863 - def _get_json_schema_from_tool(self) -> Optional[Union[str, dict]]:
861 + def _get_json_schema_from_tool(self) -> str | dict | None:
862 # user has chosen to not use any tool
863 if self.tool_choice == "none" or self.tools is None:
864 return None
@@ -1098,44 +1096,44 @@ class ChatCompletionRequest(OpenAIBaseModel):
1096 class CompletionRequest(OpenAIBaseModel):
1097 # Ordered by official OpenAI API documentation
1098 # https://platform.openai.com/docs/api-reference/completions/create
1101 - model: Optional[str] = None
1102 - prompt: Optional[Union[list[int], list[list[int]], str, list[str]]] = None
1103 - best_of: Optional[int] = None
1104 - echo: Optional[bool] = False
1105 - frequency_penalty: Optional[float] = 0.0
1106 - logit_bias: Optional[dict[str, float]] = None
1107 - logprobs: Optional[int] = None
1108 - max_tokens: Optional[int] = 16
1099 + model: str | None = None
1100 + prompt: list[int] | list[list[int]] | str | list[str] | None = None
1101 + best_of: int | None = None
1102 + echo: bool | None = False
1103 + frequency_penalty: float | None = 0.0
1104 + logit_bias: dict[str, float] | None = None
1105 + logprobs: int | None = None
1106 + max_tokens: int | None = 16
1107 n: int = 1
1110 - presence_penalty: Optional[float] = 0.0
1111 - seed: Optional[int] = Field(None, ge=_LONG_INFO.min, le=_LONG_INFO.max)
1112 - stop: Optional[Union[str, list[str]]] = []
1113 - stream: Optional[bool] = False
1114 - stream_options: Optional[StreamOptions] = None
1115 - suffix: Optional[str] = None
1116 - temperature: Optional[float] = None
1117 - top_p: Optional[float] = None
1118 - user: Optional[str] = None
1108 + presence_penalty: float | None = 0.0
1109 + seed: int | None = Field(None, ge=_LONG_INFO.min, le=_LONG_INFO.max)
1110 + stop: str | list[str] | None = []
1111 + stream: bool | None = False
1112 + stream_options: StreamOptions | None = None
1113 + suffix: str | None = None
1114 + temperature: float | None = None
1115 + top_p: float | None = None
1116 + user: str | None = None
1117
1118 # --8<-- [start:completion-sampling-params]
1119 use_beam_search: bool = False
1122 - top_k: Optional[int] = None
1123 - min_p: Optional[float] = None
1124 - repetition_penalty: Optional[float] = None
1120 + top_k: int | None = None
1121 + min_p: float | None = None
1122 + repetition_penalty: float | None = None
1123 length_penalty: float = 1.0
1126 - stop_token_ids: Optional[list[int]] = []
1124 + stop_token_ids: list[int] | None = []
1125 include_stop_str_in_output: bool = False
1126 ignore_eos: bool = False
1127 min_tokens: int = 0
1128 skip_special_tokens: bool = True
1129 spaces_between_special_tokens: bool = True
1132 - truncate_prompt_tokens: Optional[Annotated[int, Field(ge=-1)]] = None
1133 - allowed_token_ids: Optional[list[int]] = None
1134 - prompt_logprobs: Optional[int] = None
1130 + truncate_prompt_tokens: Annotated[int, Field(ge=-1)] | None = None
1131 + allowed_token_ids: list[int] | None = None
1132 + prompt_logprobs: int | None = None
1133 # --8<-- [end:completion-sampling-params]
1134
1135 # --8<-- [start:completion-extra-params]
1138 - prompt_embeds: Optional[Union[bytes, list[bytes]]] = None
1136 + prompt_embeds: bytes | list[bytes] | None = None
1137 add_special_tokens: bool = Field(
1138 default=True,
1139 description=(
@@ -1143,7 +1141,7 @@ class CompletionRequest(OpenAIBaseModel):
1141 "the prompt."
1142 ),
1143 )
1146 - response_format: Optional[AnyResponseFormat] = Field(
1144 + response_format: AnyResponseFormat | None = Field(
1145 default=None,
1146 description=(
1147 "Similar to chat completion, this parameter specifies the format "
@@ -1151,11 +1149,11 @@ class CompletionRequest(OpenAIBaseModel):
1149 ", {'type': 'structural_tag'}, or {'type': 'text' } is supported."
1150 ),
1151 )
1154 - structured_outputs: Optional[StructuredOutputsParams] = Field(
1152 + structured_outputs: StructuredOutputsParams | None = Field(
1153 default=None,
1154 description="Additional kwargs for structured outputs",
1155 )
1158 - guided_json: Optional[Union[str, dict, BaseModel]] = Field(
1156 + guided_json: str | dict | BaseModel | None = Field(
1157 default=None,
1158 description=(
1159 "`guided_json` is deprecated. "
@@ -1163,7 +1161,7 @@ class CompletionRequest(OpenAIBaseModel):
1161 "Please pass `json` to `structured_outputs` instead."
1162 ),
1163 )
1166 - guided_regex: Optional[str] = Field(
1164 + guided_regex: str | None = Field(
1165 default=None,
1166 description=(
1167 "`guided_regex` is deprecated. "
@@ -1171,7 +1169,7 @@ class CompletionRequest(OpenAIBaseModel):
1169 "Please pass `regex` to `structured_outputs` instead."
1170 ),
1171 )
1174 - guided_choice: Optional[list[str]] = Field(
1172 + guided_choice: list[str] | None = Field(
1173 default=None,
1174 description=(
1175 "`guided_choice` is deprecated. "
@@ -1179,7 +1177,7 @@ class CompletionRequest(OpenAIBaseModel):
1177 "Please pass `choice` to `structured_outputs` instead."
1178 ),
1179 )
1182 - guided_grammar: Optional[str] = Field(
1180 + guided_grammar: str | None = Field(
1181 default=None,
1182 description=(
1183 "`guided_grammar` is deprecated. "
@@ -1187,7 +1185,7 @@ class CompletionRequest(OpenAIBaseModel):
1185 "Please pass `grammar` to `structured_outputs` instead."
1186 ),
1187 )
1190 - guided_decoding_backend: Optional[str] = Field(
1188 + guided_decoding_backend: str | None = Field(
1189 default=None,
1190 description=(
1191 "`guided_decoding_backend` is deprecated. "
@@ -1195,7 +1193,7 @@ class CompletionRequest(OpenAIBaseModel):
1193 "Please remove it from your request."
1194 ),
1195 )
1198 - guided_whitespace_pattern: Optional[str] = Field(
1196 + guided_whitespace_pattern: str | None = Field(
1197 default=None,
1198 description=(
1199 "`guided_whitespace_pattern` is deprecated. "
@@ -1219,7 +1217,7 @@ class CompletionRequest(OpenAIBaseModel):
1217 "through out the inference process and return in response."
1218 ),
1219 )
1222 - logits_processors: Optional[LogitsProcessors] = Field(
1220 + logits_processors: LogitsProcessors | None = Field(
1221 default=None,
1222 description=(
1223 "A list of either qualified names of logits processors, or "
@@ -1233,7 +1231,7 @@ class CompletionRequest(OpenAIBaseModel):
1231 ),
1232 )
1233
1236 - return_tokens_as_token_ids: Optional[bool] = Field(
1234 + return_tokens_as_token_ids: bool | None = Field(
1235 default=None,
1236 description=(
1237 "If specified with 'logprobs', tokens are represented "
@@ -1241,7 +1239,7 @@ class CompletionRequest(OpenAIBaseModel):
1239 "that are not JSON-encodable can be identified."
1240 ),
1241 )
1244 - return_token_ids: Optional[bool] = Field(
1242 + return_token_ids: bool | None = Field(
1243 default=None,
1244 description=(
1245 "If specified, the result will include token IDs alongside the "
@@ -1252,7 +1250,7 @@ class CompletionRequest(OpenAIBaseModel):
1250 ),
1251 )
1252
1255 - cache_salt: Optional[str] = Field(
1253 + cache_salt: str | None = Field(
1254 default=None,
1255 description=(
1256 "If specified, the prefix cache will be salted with the provided "
@@ -1264,12 +1262,12 @@ class CompletionRequest(OpenAIBaseModel):
1262 ),
1263 )
1264
1267 - kv_transfer_params: Optional[dict[str, Any]] = Field(
1265 + kv_transfer_params: dict[str, Any] | None = Field(
1266 default=None,
1267 description="KVTransfer parameters used for disaggregated serving.",
1268 )
1269
1272 - vllm_xargs: Optional[dict[str, Union[str, int, float]]] = Field(
1270 + vllm_xargs: dict[str, str | int | float] | None = Field(
1271 default=None,
1272 description=(
1273 "Additional request parameters with string or "
@@ -1291,7 +1289,7 @@ class CompletionRequest(OpenAIBaseModel):
1289 def to_beam_search_params(
1290 self,
1291 max_tokens: int,
1294 - default_sampling_params: Optional[dict] = None,
1292 + default_sampling_params: dict | None = None,
1293 ) -> BeamSearchParams:
1294 if default_sampling_params is None:
1295 default_sampling_params = {}
@@ -1312,8 +1310,8 @@ class CompletionRequest(OpenAIBaseModel):
1310 def to_sampling_params(
1311 self,
1312 max_tokens: int,
1315 - logits_processor_pattern: Optional[str],
1316 - default_sampling_params: Optional[dict] = None,
1313 + logits_processor_pattern: str | None,
1314 + default_sampling_params: dict | None = None,
1315 ) -> SamplingParams:
1316 if default_sampling_params is None:
1317 default_sampling_params = {}
@@ -1488,12 +1486,12 @@ class CompletionRequest(OpenAIBaseModel):
1486 class EmbeddingCompletionRequest(OpenAIBaseModel):
1487 # Ordered by official OpenAI API documentation
1488 # https://platform.openai.com/docs/api-reference/embeddings
1491 - model: Optional[str] = None
1492 - input: Union[list[int], list[list[int]], str, list[str]]
1489 + model: str | None = None
1490 + input: list[int] | list[list[int]] | str | list[str]
1491 encoding_format: Literal["float", "base64"] = "float"
1494 - dimensions: Optional[int] = None
1495 - user: Optional[str] = None
1496 - truncate_prompt_tokens: Optional[Annotated[int, Field(ge=-1)]] = None
1492 + dimensions: int | None = None
1493 + user: str | None = None
1494 + truncate_prompt_tokens: Annotated[int, Field(ge=-1)] | None = None
1495
1496 # --8<-- [start:embedding-extra-params]
1497 add_special_tokens: bool = Field(
@@ -1519,7 +1517,7 @@ class EmbeddingCompletionRequest(OpenAIBaseModel):
1517 "through out the inference process and return in response."
1518 ),
1519 )
1522 - normalize: Optional[bool] = None
1520 + normalize: bool | None = None
1521
1522 # --8<-- [end:embedding-extra-params]
1523
@@ -1532,13 +1530,13 @@ class EmbeddingCompletionRequest(OpenAIBaseModel):
1530
1531
1532 class EmbeddingChatRequest(OpenAIBaseModel):
1535 - model: Optional[str] = None
1533 + model: str | None = None
1534 messages: list[ChatCompletionMessageParam]
1535
1536 encoding_format: Literal["float", "base64"] = "float"
1539 - dimensions: Optional[int] = None
1540 - user: Optional[str] = None
1541 - truncate_prompt_tokens: Optional[Annotated[int, Field(ge=-1)]] = None
1537 + dimensions: int | None = None
1538 + user: str | None = None
1539 + truncate_prompt_tokens: Annotated[int, Field(ge=-1)] | None = None
1540
1541 # --8<-- [start:chat-embedding-extra-params]
1542 add_generation_prompt: bool = Field(
@@ -1560,7 +1558,7 @@ class EmbeddingChatRequest(OpenAIBaseModel):
1558 "default)."
1559 ),
1560 )
1563 - chat_template: Optional[str] = Field(
1561 + chat_template: str | None = Field(
1562 default=None,
1563 description=(
1564 "A Jinja template to use for this conversion. "
@@ -1569,14 +1567,14 @@ class EmbeddingChatRequest(OpenAIBaseModel):
1567 "does not define one."
1568 ),
1569 )
1572 - chat_template_kwargs: Optional[dict[str, Any]] = Field(
1570 + chat_template_kwargs: dict[str, Any] | None = Field(
1571 default=None,
1572 description=(
1573 "Additional keyword args to pass to the template renderer. "
1574 "Will be accessible by the chat template."
1575 ),
1576 )
1579 - mm_processor_kwargs: Optional[dict[str, Any]] = Field(
1577 + mm_processor_kwargs: dict[str, Any] | None = Field(
1578 default=None,
1579 description=("Additional kwargs to pass to the HF processor."),
1580 )
@@ -1596,7 +1594,7 @@ class EmbeddingChatRequest(OpenAIBaseModel):
1594 "through out the inference process and return in response."
1595 ),
1596 )
1599 - normalize: Optional[bool] = None
1597 + normalize: bool | None = None
1598 # --8<-- [end:chat-embedding-extra-params]
1599
1600 @model_validator(mode="before")
@@ -1617,7 +1615,7 @@ class EmbeddingChatRequest(OpenAIBaseModel):
1615 )
1616
1617
1620 -EmbeddingRequest = Union[EmbeddingCompletionRequest, EmbeddingChatRequest]
1618 +EmbeddingRequest: TypeAlias = EmbeddingCompletionRequest | EmbeddingChatRequest
1619
1620 PoolingCompletionRequest = EmbeddingCompletionRequest
1621 PoolingChatRequest = EmbeddingChatRequest
@@ -1626,7 +1624,7 @@ T = TypeVar("T")
1624
1625
1626 class IOProcessorRequest(OpenAIBaseModel, Generic[T]):
1629 - model: Optional[str] = None
1627 + model: str | None = None
1628
1629 priority: int = Field(default=0)
1630 """
@@ -1646,7 +1644,7 @@ class IOProcessorRequest(OpenAIBaseModel, Generic[T]):
1644
1645
1646 class IOProcessorResponse(OpenAIBaseModel, Generic[T]):
1649 - request_id: Optional[str] = None
1647 + request_id: str | None = None
1648 """
1649 The request_id associated with this response
1650 """
@@ -1659,18 +1657,20 @@ class IOProcessorResponse(OpenAIBaseModel, Generic[T]):
1657 """
1658
1659
1662 -PoolingRequest = Union[PoolingCompletionRequest, PoolingChatRequest, IOProcessorRequest]
1660 +PoolingRequest: TypeAlias = (
1661 + PoolingCompletionRequest | PoolingChatRequest | IOProcessorRequest
1662 +)
1663
1664
1665 class ScoreRequest(OpenAIBaseModel):
1666 - model: Optional[str] = None
1667 - text_1: Union[list[str], str, ScoreMultiModalParam]
1668 - text_2: Union[list[str], str, ScoreMultiModalParam]
1669 - truncate_prompt_tokens: Optional[Annotated[int, Field(ge=-1)]] = None
1666 + model: str | None = None
1667 + text_1: list[str] | str | ScoreMultiModalParam
1668 + text_2: list[str] | str | ScoreMultiModalParam
1669 + truncate_prompt_tokens: Annotated[int, Field(ge=-1)] | None = None
1670
1671 # --8<-- [start:score-extra-params]
1672
1673 - mm_processor_kwargs: Optional[dict[str, Any]] = Field(
1673 + mm_processor_kwargs: dict[str, Any] | None = Field(
1674 default=None,
1675 description=("Additional kwargs to pass to the HF processor."),
1676 )
@@ -1684,7 +1684,7 @@ class ScoreRequest(OpenAIBaseModel):
1684 ),
1685 )
1686
1687 - activation: Optional[bool] = None
1687 + activation: bool | None = None
1688
1689 # --8<-- [end:score-extra-params]
1690
@@ -1696,15 +1696,15 @@ class ScoreRequest(OpenAIBaseModel):
1696
1697
1698 class RerankRequest(OpenAIBaseModel):
1699 - model: Optional[str] = None
1700 - query: Union[str, ScoreMultiModalParam]
1701 - documents: Union[list[str], ScoreMultiModalParam]
1699 + model: str | None = None
1700 + query: str | ScoreMultiModalParam
1701 + documents: list[str] | ScoreMultiModalParam
1702 top_n: int = Field(default_factory=lambda: 0)
1703 - truncate_prompt_tokens: Optional[Annotated[int, Field(ge=-1)]] = None
1703 + truncate_prompt_tokens: Annotated[int, Field(ge=-1)] | None = None
1704
1705 # --8<-- [start:rerank-extra-params]
1706
1707 - mm_processor_kwargs: Optional[dict[str, Any]] = Field(
1707 + mm_processor_kwargs: dict[str, Any] | None = Field(
1708 default=None,
1709 description=("Additional kwargs to pass to the HF processor."),
1710 )
@@ -1718,7 +1718,7 @@ class RerankRequest(OpenAIBaseModel):
1718 ),
1719 )
1720
1721 - activation: Optional[bool] = None
1721 + activation: bool | None = None
1722
1723 # --8<-- [end:rerank-extra-params]
1724
@@ -1730,8 +1730,8 @@ class RerankRequest(OpenAIBaseModel):
1730
1731
1732 class RerankDocument(BaseModel):
1733 - text: Optional[str] = None
1734 - multi_modal: Optional[ScoreContentPartParam] = None
1733 + text: str | None = None
1734 + multi_modal: ScoreContentPartParam | None = None
1735
1736
1737 class RerankResult(BaseModel):
@@ -1753,17 +1753,17 @@ class RerankResponse(OpenAIBaseModel):
1753
1754 class CompletionLogProbs(OpenAIBaseModel):
1755 text_offset: list[int] = Field(default_factory=list)
1756 - token_logprobs: list[Optional[float]] = Field(default_factory=list)
1756 + token_logprobs: list[float | None] = Field(default_factory=list)
1757 tokens: list[str] = Field(default_factory=list)
1758 - top_logprobs: list[Optional[dict[str, float]]] = Field(default_factory=list)
1758 + top_logprobs: list[dict[str, float] | None] = Field(default_factory=list)
1759
1760
1761 class CompletionResponseChoice(OpenAIBaseModel):
1762 index: int
1763 text: str
1764 - logprobs: Optional[CompletionLogProbs] = None
1765 - finish_reason: Optional[str] = None
1766 - stop_reason: Optional[Union[int, str]] = Field(
1764 + logprobs: CompletionLogProbs | None = None
1765 + finish_reason: str | None = None
1766 + stop_reason: int | str | None = Field(
1767 default=None,
1768 description=(
1769 "The stop string or token id that caused the completion "
@@ -1771,9 +1771,9 @@ class CompletionResponseChoice(OpenAIBaseModel):
1771 "including encountering the EOS token"
1772 ),
1773 )
1774 - token_ids: Optional[list[int]] = None # For response
1775 - prompt_logprobs: Optional[list[Optional[dict[int, Logprob]]]] = None
1776 - prompt_token_ids: Optional[list[int]] = None # For prompt
1774 + token_ids: list[int] | None = None # For response
1775 + prompt_logprobs: list[dict[int, Logprob] | None] | None = None
1776 + prompt_token_ids: list[int] | None = None # For prompt
1777
1778
1779 class CompletionResponse(OpenAIBaseModel):
@@ -1782,14 +1782,12 @@ class CompletionResponse(OpenAIBaseModel):
1782 created: int = Field(default_factory=lambda: int(time.time()))
1783 model: str
1784 choices: list[CompletionResponseChoice]
1785 - service_tier: Optional[Literal["auto", "default", "flex", "scale", "priority"]] = (
1786 - None
1787 - )
1788 - system_fingerprint: Optional[str] = None
1785 + service_tier: Literal["auto", "default", "flex", "scale", "priority"] | None = None
1786 + system_fingerprint: str | None = None
1787 usage: UsageInfo
1788
1789 # vLLM-specific fields that are not in OpenAI spec
1792 - kv_transfer_params: Optional[dict[str, Any]] = Field(
1790 + kv_transfer_params: dict[str, Any] | None = Field(
1791 default=None, description="KVTransfer parameters."
1792 )
1793
@@ -1797,9 +1795,9 @@ class CompletionResponse(OpenAIBaseModel):
1795 class CompletionResponseStreamChoice(OpenAIBaseModel):
1796 index: int
1797 text: str
1800 - logprobs: Optional[CompletionLogProbs] = None
1801 - finish_reason: Optional[str] = None
1802 - stop_reason: Optional[Union[int, str]] = Field(
1798 + logprobs: CompletionLogProbs | None = None
1799 + finish_reason: str | None = None
1800 + stop_reason: int | str | None = Field(
1801 default=None,
1802 description=(
1803 "The stop string or token id that caused the completion "
@@ -1809,8 +1807,8 @@ class CompletionResponseStreamChoice(OpenAIBaseModel):
1807 )
1808 # not part of the OpenAI spec but for tracing the tokens
1809 # prompt tokens is put into choice to align with CompletionResponseChoice
1812 - prompt_token_ids: Optional[list[int]] = None
1813 - token_ids: Optional[list[int]] = None
1810 + prompt_token_ids: list[int] | None = None
1811 + token_ids: list[int] | None = None
1812
1813
1814 class CompletionStreamResponse(OpenAIBaseModel):
@@ -1819,13 +1817,13 @@ class CompletionStreamResponse(OpenAIBaseModel):
1817 created: int = Field(default_factory=lambda: int(time.time()))
1818 model: str
1819 choices: list[CompletionResponseStreamChoice]
1822 - usage: Optional[UsageInfo] = Field(default=None)
1820 + usage: UsageInfo | None = Field(default=None)
1821
1822
1823 class EmbeddingResponseData(OpenAIBaseModel):
1824 index: int
1825 object: str = "embedding"
1828 - embedding: Union[list[float], str]
1826 + embedding: list[float] | str
1827
1828
1829 class EmbeddingResponse(OpenAIBaseModel):
@@ -1840,7 +1838,7 @@ class EmbeddingResponse(OpenAIBaseModel):
1838 class PoolingResponseData(OpenAIBaseModel):
1839 index: int
1840 object: str = "pooling"
1843 - data: Union[list[list[float]], list[float], str]
1841 + data: list[list[float]] | list[float] | str
1842
1843
1844 class PoolingResponse(OpenAIBaseModel):
@@ -1868,10 +1866,10 @@ class ScoreResponse(OpenAIBaseModel):
1866
1867
1868 class ClassificationRequest(OpenAIBaseModel):
1871 - model: Optional[str] = None
1872 - input: Union[list[str], str]
1873 - truncate_prompt_tokens: Optional[int] = None
1874 - user: Optional[str] = None
1869 + model: str | None = None
1870 + input: list[str] | str
1871 + truncate_prompt_tokens: int | None = None
1872 + user: str | None = None
1873
1874 # --8<-- [start:classification-extra-params]
1875 priority: int = Field(
@@ -1883,7 +1881,7 @@ class ClassificationRequest(OpenAIBaseModel):
1881 ),
1882 )
1883
1886 - activation: Optional[bool] = None
1884 + activation: bool | None = None
1885
1886 # --8<-- [end:classification-extra-params]
1887
@@ -1896,7 +1894,7 @@ class ClassificationRequest(OpenAIBaseModel):
1894
1895 class ClassificationData(OpenAIBaseModel):
1896 index: int
1899 - label: Optional[str]
1897 + label: str | None
1898 probs: list[float]
1899 num_classes: int
1900
@@ -1922,16 +1920,16 @@ class ToolCall(OpenAIBaseModel):
1920
1921
1922 class DeltaFunctionCall(BaseModel):
1925 - name: Optional[str] = None
1926 - arguments: Optional[str] = None
1923 + name: str | None = None
1924 + arguments: str | None = None
1925
1926
1927 # a tool call delta where everything is optional
1928 class DeltaToolCall(OpenAIBaseModel):
1931 - id: Optional[str] = None
1932 - type: Optional[Literal["function"]] = None
1929 + id: str | None = None
1930 + type: Literal["function"] | None = None
1931 index: int
1934 - function: Optional[DeltaFunctionCall] = None
1932 + function: DeltaFunctionCall | None = None
1933
1934
1935 class ExtractedToolCallInformation(BaseModel):
@@ -1943,50 +1941,50 @@ class ExtractedToolCallInformation(BaseModel):
1941
1942 # content - per OpenAI spec, content AND tool calls can be returned rarely
1943 # But some models will do this intentionally
1946 - content: Optional[str] = None
1944 + content: str | None = None
1945
1946
1947 class ChatMessage(OpenAIBaseModel):
1948 role: str
1951 - content: Optional[str] = None
1952 - refusal: Optional[str] = None
1953 - annotations: Optional[OpenAIAnnotation] = None
1954 - audio: Optional[OpenAIChatCompletionAudio] = None
1955 - function_call: Optional[FunctionCall] = None
1949 + content: str | None = None
1950 + refusal: str | None = None
1951 + annotations: OpenAIAnnotation | None = None
1952 + audio: OpenAIChatCompletionAudio | None = None
1953 + function_call: FunctionCall | None = None
1954 tool_calls: list[ToolCall] = Field(default_factory=list)
1955
1956 # vLLM-specific fields that are not in OpenAI spec
1959 - reasoning_content: Optional[str] = None
1957 + reasoning_content: str | None = None
1958
1959
1960 class ChatCompletionLogProb(OpenAIBaseModel):
1961 token: str
1962 logprob: float = -9999.0
1965 - bytes: Optional[list[int]] = None
1963 + bytes: list[int] | None = None
1964
1965
1966 class ChatCompletionLogProbsContent(ChatCompletionLogProb):
1967 # Workaround: redefine fields name cache so that it's not
1968 # shared with the super class.
1971 - field_names: ClassVar[Optional[set[str]]] = None
1969 + field_names: ClassVar[set[str] | None] = None
1970 top_logprobs: list[ChatCompletionLogProb] = Field(default_factory=list)
1971
1972
1973 class ChatCompletionLogProbs(OpenAIBaseModel):
1976 - content: Optional[list[ChatCompletionLogProbsContent]] = None
1974 + content: list[ChatCompletionLogProbsContent] | None = None
1975
1976
1977 class ChatCompletionResponseChoice(OpenAIBaseModel):
1978 index: int
1979 message: ChatMessage
1982 - logprobs: Optional[ChatCompletionLogProbs] = None
1980 + logprobs: ChatCompletionLogProbs | None = None
1981 # per OpenAI spec this is the default
1984 - finish_reason: Optional[str] = "stop"
1982 + finish_reason: str | None = "stop"
1983 # not part of the OpenAI spec but included in vLLM for legacy reasons
1986 - stop_reason: Optional[Union[int, str]] = None
1984 + stop_reason: int | str | None = None
1985 # not part of the OpenAI spec but is useful for tracing the tokens
1986 # in agent scenarios
1989 - token_ids: Optional[list[int]] = None
1987 + token_ids: list[int] | None = None
1988
1989
1990 class ChatCompletionResponse(OpenAIBaseModel):
@@ -1995,35 +1993,33 @@ class ChatCompletionResponse(OpenAIBaseModel):
1993 created: int = Field(default_factory=lambda: int(time.time()))
1994 model: str
1995 choices: list[ChatCompletionResponseChoice]
1998 - service_tier: Optional[Literal["auto", "default", "flex", "scale", "priority"]] = (
1999 - None
2000 - )
2001 - system_fingerprint: Optional[str] = None
1996 + service_tier: Literal["auto", "default", "flex", "scale", "priority"] | None = None
1997 + system_fingerprint: str | None = None
1998 usage: UsageInfo
1999
2000 # vLLM-specific fields that are not in OpenAI spec
2005 - prompt_logprobs: Optional[list[Optional[dict[int, Logprob]]]] = None
2006 - prompt_token_ids: Optional[list[int]] = None
2007 - kv_transfer_params: Optional[dict[str, Any]] = Field(
2001 + prompt_logprobs: list[dict[int, Logprob] | None] | None = None
2002 + prompt_token_ids: list[int] | None = None
2003 + kv_transfer_params: dict[str, Any] | None = Field(
2004 default=None, description="KVTransfer parameters."
2005 )
2006
2007
2008 class DeltaMessage(OpenAIBaseModel):
2013 - role: Optional[str] = None
2014 - content: Optional[str] = None
2015 - reasoning_content: Optional[str] = None
2009 + role: str | None = None
2010 + content: str | None = None
2011 + reasoning_content: str | None = None
2012 tool_calls: list[DeltaToolCall] = Field(default_factory=list)
2013
2014
2015 class ChatCompletionResponseStreamChoice(OpenAIBaseModel):
2016 index: int
2017 delta: DeltaMessage
2022 - logprobs: Optional[ChatCompletionLogProbs] = None
2023 - finish_reason: Optional[str] = None
2024 - stop_reason: Optional[Union[int, str]] = None
2018 + logprobs: ChatCompletionLogProbs | None = None
2019 + finish_reason: str | None = None
2020 + stop_reason: int | str | None = None
2021 # not part of the OpenAI spec but for tracing the tokens
2026 - token_ids: Optional[list[int]] = None
2022 + token_ids: list[int] | None = None
2023
2024
2025 class ChatCompletionStreamResponse(OpenAIBaseModel):
@@ -2032,15 +2028,15 @@ class ChatCompletionStreamResponse(OpenAIBaseModel):
2028 created: int = Field(default_factory=lambda: int(time.time()))
2029 model: str
2030 choices: list[ChatCompletionResponseStreamChoice]
2035 - usage: Optional[UsageInfo] = Field(default=None)
2031 + usage: UsageInfo | None = Field(default=None)
2032 # not part of the OpenAI spec but for tracing the tokens
2037 - prompt_token_ids: Optional[list[int]] = None
2033 + prompt_token_ids: list[int] | None = None
2034
2035
2036 class TranscriptionResponseStreamChoice(OpenAIBaseModel):
2037 delta: DeltaMessage
2042 - finish_reason: Optional[str] = None
2043 - stop_reason: Optional[Union[int, str]] = None
2038 + finish_reason: str | None = None
2039 + stop_reason: int | str | None = None
2040
2041
2042 class TranscriptionStreamResponse(OpenAIBaseModel):
@@ -2049,7 +2045,7 @@ class TranscriptionStreamResponse(OpenAIBaseModel):
2045 created: int = Field(default_factory=lambda: int(time.time()))
2046 model: str
2047 choices: list[TranscriptionResponseStreamChoice]
2052 - usage: Optional[UsageInfo] = Field(default=None)
2048 + usage: UsageInfo | None = Field(default=None)
2049
2050
2051 class InputTokensDetails(OpenAIBaseModel):
@@ -2073,9 +2069,9 @@ class ResponsesResponse(OpenAIBaseModel):
2069 id: str = Field(default_factory=lambda: f"resp_{random_uuid()}")
2070 created_at: int = Field(default_factory=lambda: int(time.time()))
2071 # error: Optional[ResponseError] = None
2076 - incomplete_details: Optional[IncompleteDetails] = None
2077 - instructions: Optional[str] = None
2078 - metadata: Optional[Metadata] = None
2072 + incomplete_details: IncompleteDetails | None = None
2073 + instructions: str | None = None
2074 + metadata: Metadata | None = None
2075 model: str
2076 object: Literal["response"] = "response"
2077 output: list[ResponseOutputItem]
@@ -2086,24 +2082,24 @@ class ResponsesResponse(OpenAIBaseModel):
2082 top_p: float
2083 background: bool
2084 max_output_tokens: int
2089 - max_tool_calls: Optional[int] = None
2090 - previous_response_id: Optional[str] = None
2091 - prompt: Optional[ResponsePrompt] = None
2092 - reasoning: Optional[Reasoning] = None
2085 + max_tool_calls: int | None = None
2086 + previous_response_id: str | None = None
2087 + prompt: ResponsePrompt | None = None
2088 + reasoning: Reasoning | None = None
2089 service_tier: Literal["auto", "default", "flex", "scale", "priority"]
2090 status: ResponseStatus
2095 - text: Optional[ResponseTextConfig] = None
2096 - top_logprobs: Optional[int] = None
2091 + text: ResponseTextConfig | None = None
2092 + top_logprobs: int | None = None
2093 truncation: Literal["auto", "disabled"]
2098 - usage: Optional[ResponseUsage] = None
2099 - user: Optional[str] = None
2094 + usage: ResponseUsage | None = None
2095 + user: str | None = None
2096
2097 # --8<-- [start:responses-extra-params]
2098 # These are populated when enable_response_messages is set to True
2099 # NOTE: custom serialization is needed
2100 # see serialize_input_messages and serialize_output_messages
2105 - input_messages: Optional[list[ChatCompletionMessageParam]] = None
2106 - output_messages: Optional[list[ChatCompletionMessageParam]] = None
2101 + input_messages: list[ChatCompletionMessageParam] | None = None
2102 + output_messages: list[ChatCompletionMessageParam] | None = None
2103 # --8<-- [end:responses-extra-params]
2104
2105 # NOTE: openAI harmony doesn't serialize TextContent properly,
@@ -2150,11 +2146,11 @@ class ResponsesResponse(OpenAIBaseModel):
2146 created_time: int,
2147 output: list[ResponseOutputItem],
2148 status: ResponseStatus,
2153 - usage: Optional[ResponseUsage] = None,
2154 - input_messages: Optional[list[ChatCompletionMessageParam]] = None,
2155 - output_messages: Optional[list[ChatCompletionMessageParam]] = None,
2149 + usage: ResponseUsage | None = None,
2150 + input_messages: list[ChatCompletionMessageParam] | None = None,
2151 + output_messages: list[ChatCompletionMessageParam] | None = None,
2152 ) -> "ResponsesResponse":
2157 - incomplete_details: Optional[IncompleteDetails] = None
2153 + incomplete_details: IncompleteDetails | None = None
2154 if status == "incomplete":
2155 incomplete_details = IncompleteDetails(reason="max_output_tokens")
2156 # TODO: implement the other reason for incomplete_details,
@@ -2249,31 +2245,31 @@ class ResponseInProgressEvent(OpenAIResponseInProgressEvent):
2245 response: ResponsesResponse # type: ignore[override]
2246
2247
2252 -StreamingResponsesResponse: TypeAlias = Union[
2253 - "ResponseCreatedEvent",
2254 - "ResponseInProgressEvent",
2255 - "ResponseCompletedEvent",
2256 - ResponseOutputItemAddedEvent,
2257 - ResponseOutputItemDoneEvent,
2258 - ResponseContentPartAddedEvent,
2259 - ResponseContentPartDoneEvent,
2260 - ResponseReasoningTextDeltaEvent,
2261 - ResponseReasoningTextDoneEvent,
2262 - ResponseReasoningPartAddedEvent,
2263 - ResponseReasoningPartDoneEvent,
2264 - ResponseCodeInterpreterCallInProgressEvent,
2265 - ResponseCodeInterpreterCallCodeDeltaEvent,
2266 - ResponseWebSearchCallInProgressEvent,
2267 - ResponseWebSearchCallSearchingEvent,
2268 - ResponseWebSearchCallCompletedEvent,
2269 - ResponseCodeInterpreterCallCodeDoneEvent,
2270 - ResponseCodeInterpreterCallInterpretingEvent,
2271 - ResponseCodeInterpreterCallCompletedEvent,
2272 -]
2248 +StreamingResponsesResponse: TypeAlias = (
2249 + ResponseCreatedEvent
2250 + | ResponseInProgressEvent
2251 + | ResponseCompletedEvent
2252 + | ResponseOutputItemAddedEvent
2253 + | ResponseOutputItemDoneEvent
2254 + | ResponseContentPartAddedEvent
2255 + | ResponseContentPartDoneEvent
2256 + | ResponseReasoningTextDeltaEvent
2257 + | ResponseReasoningTextDoneEvent
2258 + | ResponseReasoningPartAddedEvent
2259 + | ResponseReasoningPartDoneEvent
2260 + | ResponseCodeInterpreterCallInProgressEvent
2261 + | ResponseCodeInterpreterCallCodeDeltaEvent
2262 + | ResponseWebSearchCallInProgressEvent
2263 + | ResponseWebSearchCallSearchingEvent
2264 + | ResponseWebSearchCallCompletedEvent
2265 + | ResponseCodeInterpreterCallCodeDoneEvent
2266 + | ResponseCodeInterpreterCallInterpretingEvent
2267 + | ResponseCodeInterpreterCallCompletedEvent
2268 +)
2269
2274 -BatchRequestInputBody = Union[
2275 - ChatCompletionRequest, EmbeddingRequest, ScoreRequest, RerankRequest
2276 -]
2270 +BatchRequestInputBody: TypeAlias = (
2271 + ChatCompletionRequest | EmbeddingRequest | ScoreRequest | RerankRequest
2272 +)
2273
2274
2275 class BatchRequestInput(OpenAIBaseModel):
@@ -2322,9 +2318,13 @@ class BatchResponseData(OpenAIBaseModel):
2318 request_id: str
2319
2320 # The body of the response.
2325 - body: Optional[
2326 - Union[ChatCompletionResponse, EmbeddingResponse, ScoreResponse, RerankResponse]
2327 - ] = None
2321 + body: (
2322 + ChatCompletionResponse
2323 + | EmbeddingResponse
2324 + | ScoreResponse
2325 + | RerankResponse
2326 + | None
2327 + ) = None
2328
2329
2330 class BatchRequestOutput(OpenAIBaseModel):
@@ -2338,15 +2338,15 @@ class BatchRequestOutput(OpenAIBaseModel):
2338 # inputs.
2339 custom_id: str
2340
2341 - response: Optional[BatchResponseData]
2341 + response: BatchResponseData | None
2342
2343 # For requests that failed with a non-HTTP error, this will contain more
2344 # information on the cause of the failure.
2345 - error: Optional[Any]
2345 + error: Any | None
2346
2347
2348 class TokenizeCompletionRequest(OpenAIBaseModel):
2349 - model: Optional[str] = None
2349 + model: str | None = None
2350 prompt: str
2351
2352 add_special_tokens: bool = Field(
@@ -2356,7 +2356,7 @@ class TokenizeCompletionRequest(OpenAIBaseModel):
2356 "the prompt."
2357 ),
2358 )
2359 - return_token_strs: Optional[bool] = Field(
2359 + return_token_strs: bool | None = Field(
2360 default=False,
2361 description=(
2362 "If true, also return the token strings corresponding to the token ids."
@@ -2365,7 +2365,7 @@ class TokenizeCompletionRequest(OpenAIBaseModel):
2365
2366
2367 class TokenizeChatRequest(OpenAIBaseModel):
2368 - model: Optional[str] = None
2368 + model: str | None = None
2369 messages: list[ChatCompletionMessageParam]
2370
2371 add_generation_prompt: bool = Field(
@@ -2376,7 +2376,7 @@ class TokenizeChatRequest(OpenAIBaseModel):
2376 "model."
2377 ),
2378 )
2379 - return_token_strs: Optional[bool] = Field(
2379 + return_token_strs: bool | None = Field(
2380 default=False,
2381 description=(
2382 "If true, also return the token strings corresponding to the token ids."
@@ -2402,7 +2402,7 @@ class TokenizeChatRequest(OpenAIBaseModel):
2402 "default)."
2403 ),
2404 )
2405 - chat_template: Optional[str] = Field(
2405 + chat_template: str | None = Field(
2406 default=None,
2407 description=(
2408 "A Jinja template to use for this conversion. "
@@ -2411,18 +2411,18 @@ class TokenizeChatRequest(OpenAIBaseModel):
2411 "does not define one."
2412 ),
2413 )
2414 - chat_template_kwargs: Optional[dict[str, Any]] = Field(
2414 + chat_template_kwargs: dict[str, Any] | None = Field(
2415 default=None,
2416 description=(
2417 "Additional keyword args to pass to the template renderer. "
2418 "Will be accessible by the chat template."
2419 ),
2420 )
2421 - mm_processor_kwargs: Optional[dict[str, Any]] = Field(
2421 + mm_processor_kwargs: dict[str, Any] | None = Field(
2422 default=None,
2423 description=("Additional kwargs to pass to the HF processor."),
2424 )
2425 - tools: Optional[list[ChatCompletionToolsParam]] = Field(
2425 + tools: list[ChatCompletionToolsParam] | None = Field(
2426 default=None,
2427 description=("A list of tools the model may call."),
2428 )
@@ -2438,18 +2438,18 @@ class TokenizeChatRequest(OpenAIBaseModel):
2438 return data
2439
2440
2441 -TokenizeRequest = Union[TokenizeCompletionRequest, TokenizeChatRequest]
2441 +TokenizeRequest: TypeAlias = TokenizeCompletionRequest | TokenizeChatRequest
2442
2443
2444 class TokenizeResponse(OpenAIBaseModel):
2445 count: int
2446 max_model_len: int
2447 tokens: list[int]
2448 - token_strs: Optional[list[str]] = None
2448 + token_strs: list[str] | None = None
2449
2450
2451 class DetokenizeRequest(OpenAIBaseModel):
2452 - model: Optional[str] = None
2452 + model: str | None = None
2453 tokens: list[int]
2454
2455
@@ -2474,7 +2474,7 @@ class LoadLoRAAdapterRequest(BaseModel):
2474
2475 class UnloadLoRAAdapterRequest(BaseModel):
2476 lora_name: str
2477 - lora_int_id: Optional[int] = Field(default=None)
2477 + lora_int_id: int | None = Field(default=None)
2478
2479
2480 ## Protocols for Audio
@@ -2491,11 +2491,11 @@ class TranscriptionRequest(OpenAIBaseModel):
2491 formats: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, or webm.
2492 """
2493
2494 - model: Optional[str] = None
2494 + model: str | None = None
2495 """ID of the model to use.
2496 """
2497
2498 - language: Optional[str] = None
2498 + language: str | None = None
2499 """The language of the input audio.
2500
2501 Supplying the input language in
@@ -2530,16 +2530,16 @@ class TranscriptionRequest(OpenAIBaseModel):
2530 timestamps incurs additional latency.
2531 """
2532
2533 - stream: Optional[bool] = False
2533 + stream: bool | None = False
2534 """When set, it will enable output to be streamed in a similar fashion
2535 as the Chat Completion endpoint.
2536 """
2537 # --8<-- [start:transcription-extra-params]
2538 # Flattened stream option to simplify form data.
2539 - stream_include_usage: Optional[bool] = False
2540 - stream_continuous_usage_stats: Optional[bool] = False
2539 + stream_include_usage: bool | None = False
2540 + stream_continuous_usage_stats: bool | None = False
2541
2542 - vllm_xargs: Optional[dict[str, Union[str, int, float]]] = Field(
2542 + vllm_xargs: dict[str, str | int | float] | None = Field(
2543 default=None,
2544 description=(
2545 "Additional request parameters with string or "
@@ -2548,7 +2548,7 @@ class TranscriptionRequest(OpenAIBaseModel):
2548 )
2549 # --8<-- [end:transcription-extra-params]
2550
2551 - to_language: Optional[str] = None
2551 + to_language: str | None = None
2552 """The language of the output audio we transcribe to.
2553
2554 Please note that this is not currently used by supported models at this
@@ -2565,29 +2565,29 @@ class TranscriptionRequest(OpenAIBaseModel):
2565 to automatically increase the temperature until certain thresholds are hit.
2566 """
2567
2568 - top_p: Optional[float] = None
2568 + top_p: float | None = None
2569 """Enables nucleus (top-p) sampling, where tokens are selected from the
2570 smallest possible set whose cumulative probability exceeds `p`.
2571 """
2572
2573 - top_k: Optional[int] = None
2573 + top_k: int | None = None
2574 """Limits sampling to the `k` most probable tokens at each step."""
2575
2576 - min_p: Optional[float] = None
2576 + min_p: float | None = None
2577 """Filters out tokens with a probability lower than `min_p`, ensuring a
2578 minimum likelihood threshold during sampling.
2579 """
2580
2581 - seed: Optional[int] = Field(None, ge=_LONG_INFO.min, le=_LONG_INFO.max)
2581 + seed: int | None = Field(None, ge=_LONG_INFO.min, le=_LONG_INFO.max)
2582 """The seed to use for sampling."""
2583
2584 - frequency_penalty: Optional[float] = 0.0
2584 + frequency_penalty: float | None = 0.0
2585 """The frequency penalty to use for sampling."""
2586
2587 - repetition_penalty: Optional[float] = None
2587 + repetition_penalty: float | None = None
2588 """The repetition penalty to use for sampling."""
2589
2590 - presence_penalty: Optional[float] = 0.0
2590 + presence_penalty: float | None = 0.0
2591 """The presence penalty to use for sampling."""
2592 # --8<-- [end:transcription-sampling-params]
2593
@@ -2601,7 +2601,7 @@ class TranscriptionRequest(OpenAIBaseModel):
2601 }
2602
2603 def to_sampling_params(
2604 - self, default_max_tokens: int, default_sampling_params: Optional[dict] = None
2604 + self, default_max_tokens: int, default_sampling_params: dict | None = None
2605 ) -> SamplingParams:
2606 max_tokens = default_max_tokens
2607
@@ -2740,17 +2740,17 @@ class TranscriptionResponseVerbose(OpenAIBaseModel):
2740 text: str
2741 """The transcribed text."""
2742
2743 - segments: Optional[list[TranscriptionSegment]] = None
2743 + segments: list[TranscriptionSegment] | None = None
2744 """Segments of the transcribed text and their corresponding details."""
2745
2746 - words: Optional[list[TranscriptionWord]] = None
2746 + words: list[TranscriptionWord] | None = None
2747 """Extracted words and their corresponding timestamps."""
2748
2749
2750 class TranslationResponseStreamChoice(OpenAIBaseModel):
2751 delta: DeltaMessage
2752 - finish_reason: Optional[str] = None
2753 - stop_reason: Optional[Union[int, str]] = None
2752 + finish_reason: str | None = None
2753 + stop_reason: int | str | None = None
2754
2755
2756 class TranslationStreamResponse(OpenAIBaseModel):
@@ -2759,7 +2759,7 @@ class TranslationStreamResponse(OpenAIBaseModel):
2759 created: int = Field(default_factory=lambda: int(time.time()))
2760 model: str
2761 choices: list[TranslationResponseStreamChoice]
2762 - usage: Optional[UsageInfo] = Field(default=None)
2762 + usage: UsageInfo | None = Field(default=None)
2763
2764
2765 class TranslationRequest(OpenAIBaseModel):
@@ -2772,7 +2772,7 @@ class TranslationRequest(OpenAIBaseModel):
2772 formats: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, or webm.
2773 """
2774
2775 - model: Optional[str] = None
2775 + model: str | None = None
2776 """ID of the model to use.
2777 """
2778
@@ -2792,7 +2792,7 @@ class TranslationRequest(OpenAIBaseModel):
2792
2793 # TODO support additional sampling parameters
2794 # --8<-- [start:translation-sampling-params]
2795 - seed: Optional[int] = Field(None, ge=_LONG_INFO.min, le=_LONG_INFO.max)
2795 + seed: int | None = Field(None, ge=_LONG_INFO.min, le=_LONG_INFO.max)
2796 """The seed to use for sampling."""
2797
2798 temperature: float = Field(default=0.0)
@@ -2806,7 +2806,7 @@ class TranslationRequest(OpenAIBaseModel):
2806 # --8<-- [end:translation-sampling-params]
2807
2808 # --8<-- [start:translation-extra-params]
2809 - language: Optional[str] = None
2809 + language: str | None = None
2810 """The language of the input audio we translate from.
2811
2812 Supplying the input language in
@@ -2814,7 +2814,7 @@ class TranslationRequest(OpenAIBaseModel):
2814 will improve accuracy.
2815 """
2816
2817 - to_language: Optional[str] = None
2817 + to_language: str | None = None
2818 """The language of the input audio we translate to.
2819
2820 Please note that this is not supported by all models, refer to the specific
@@ -2822,14 +2822,14 @@ class TranslationRequest(OpenAIBaseModel):
2822 For instance, Whisper only supports `to_language=en`.
2823 """
2824
2825 - stream: Optional[bool] = False
2825 + stream: bool | None = False
2826 """Custom field not present in the original OpenAI definition. When set,
2827 it will enable output to be streamed in a similar fashion as the Chat
2828 Completion endpoint.
2829 """
2830 # Flattened stream option to simplify form data.
2831 - stream_include_usage: Optional[bool] = False
2832 - stream_continuous_usage_stats: Optional[bool] = False
2831 + stream_include_usage: bool | None = False
2832 + stream_continuous_usage_stats: bool | None = False
2833 # --8<-- [end:translation-extra-params]
2834
2835 # Default sampling parameters for translation requests.
@@ -2838,7 +2838,7 @@ class TranslationRequest(OpenAIBaseModel):
2838 }
2839
2840 def to_sampling_params(
2841 - self, default_max_tokens: int, default_sampling_params: Optional[dict] = None
2841 + self, default_max_tokens: int, default_sampling_params: dict | None = None
2842 ) -> SamplingParams:
2843 max_tokens = default_max_tokens
2844
@@ -2939,8 +2939,8 @@ class TranslationResponseVerbose(OpenAIBaseModel):
2939 text: str
2940 """The translated text."""
2941
2942 - segments: Optional[list[TranslationSegment]] = None
2942 + segments: list[TranslationSegment] | None = None
2943 """Segments of the translated text and their corresponding details."""
2944
2945 - words: Optional[list[TranslationWord]] = None
2945 + words: list[TranslationWord] | None = None
2946 """Extracted words and their corresponding timestamps."""
vllm/entrypoints/openai/run_batch.py
+2 -3
@@ -4,10 +4,9 @@
4 import asyncio
5 import tempfile
6 from argparse import Namespace
7 -from collections.abc import Awaitable
7 +from collections.abc import Awaitable, Callable
8 from http import HTTPStatus
9 from io import StringIO
10 -from typing import Callable, Optional
10
11 import aiohttp
12 import torch
@@ -124,7 +123,7 @@ _BAR_FORMAT = "{desc}: {percentage:3.0f}% Completed | {n_fmt}/{total_fmt} [{elap
123 class BatchProgressTracker:
124 def __init__(self):
125 self._total = 0
127 - self._pbar: Optional[tqdm] = None
126 + self._pbar: tqdm | None = None
127
128 def submitted(self):
129 self._total += 1
vllm/entrypoints/openai/serving_chat.py
+22 -22
@@ -6,7 +6,7 @@ import json
6 import time
7 from collections.abc import AsyncGenerator, AsyncIterator
8 from collections.abc import Sequence as GenericSequence
9 -from typing import Final, Optional, Union
9 +from typing import Final
10
11 import jinja2
12 import partial_json_parser
@@ -82,15 +82,15 @@ class OpenAIServingChat(OpenAIServing):
82 models: OpenAIServingModels,
83 response_role: str,
84 *,
85 - request_logger: Optional[RequestLogger],
86 - chat_template: Optional[str],
85 + request_logger: RequestLogger | None,
86 + chat_template: str | None,
87 chat_template_content_format: ChatTemplateContentFormatOption,
88 trust_request_chat_template: bool = False,
89 return_tokens_as_token_ids: bool = False,
90 reasoning_parser: str = "",
91 enable_auto_tools: bool = False,
92 exclude_tools_when_tool_choice_none: bool = False,
93 - tool_parser: Optional[str] = None,
93 + tool_parser: str | None = None,
94 enable_prompt_tokens_details: bool = False,
95 enable_force_include_usage: bool = False,
96 enable_log_outputs: bool = False,
@@ -159,8 +159,8 @@ class OpenAIServingChat(OpenAIServing):
159 async def create_chat_completion(
160 self,
161 request: ChatCompletionRequest,
162 - raw_request: Optional[Request] = None,
163 - ) -> Union[AsyncGenerator[str, None], ChatCompletionResponse, ErrorResponse]:
162 + raw_request: Request | None = None,
163 + ) -> AsyncGenerator[str, None] | ChatCompletionResponse | ErrorResponse:
164 """
165 Chat Completion API similar to OpenAI's API.
166
@@ -281,7 +281,7 @@ class OpenAIServingChat(OpenAIServing):
281 default_sampling_params=self.default_sampling_params,
282 )
283
284 - sampling_params: Union[SamplingParams, BeamSearchParams]
284 + sampling_params: SamplingParams | BeamSearchParams
285 if request.use_beam_search:
286 sampling_params = request.to_beam_search_params(
287 max_tokens, self.default_sampling_params
@@ -416,11 +416,11 @@ class OpenAIServingChat(OpenAIServing):
416 def extract_tool_call_required_streaming(
417 self,
418 previous_text: str,
419 - current_text: Optional[str],
419 + current_text: str | None,
420 delta_text: str,
421 function_name_returned: bool,
422 - tool_call_idx: Optional[int] = None,
423 - ) -> tuple[Optional[DeltaMessage], bool]:
422 + tool_call_idx: int | None = None,
423 + ) -> tuple[DeltaMessage | None, bool]:
424 if current_text is None or current_text == "":
425 # if the current text is empty, we cannot parse it
426 return None, function_name_returned
@@ -548,7 +548,7 @@ class OpenAIServingChat(OpenAIServing):
548 and self._should_stream_with_auto_tool_parsing(request)
549 )
550
551 - all_previous_token_ids: Optional[list[list[int]]]
551 + all_previous_token_ids: list[list[int]] | None
552 function_name_returned = [False] * num_choices
553 if self.tool_call_id_type == "kimi_k2":
554 history_tool_call_cnt = get_history_tool_calls_cnt(conversation)
@@ -583,7 +583,7 @@ class OpenAIServingChat(OpenAIServing):
583 # Prepare the tool parser if it's needed
584 try:
585 if tool_choice_auto and self.tool_parser:
586 - tool_parsers: list[Optional[ToolParser]] = [
586 + tool_parsers: list[ToolParser | None] = [
587 self.tool_parser(tokenizer)
588 ] * num_choices
589 else:
@@ -661,7 +661,7 @@ class OpenAIServingChat(OpenAIServing):
661 # Send response to echo the input portion of the
662 # last message
663 if request.echo:
664 - last_msg_content: Union[str, list[dict[str, str]]] = ""
664 + last_msg_content: str | list[dict[str, str]] = ""
665 if (
666 conversation
667 and "content" in conversation[-1]
@@ -734,7 +734,7 @@ class OpenAIServingChat(OpenAIServing):
734 # Chunked prefill case, don't return empty chunks
735 continue
736
737 - delta_message: Optional[DeltaMessage]
737 + delta_message: DeltaMessage | None
738
739 # just update previous_texts and previous_token_ids
740 if tool_choice_auto or self.reasoning_parser:
@@ -1260,9 +1260,9 @@ class OpenAIServingChat(OpenAIServing):
1260 conversation: list[ConversationMessage],
1261 tokenizer: AnyTokenizer,
1262 request_metadata: RequestResponseMetadata,
1263 - ) -> Union[ErrorResponse, ChatCompletionResponse]:
1263 + ) -> ErrorResponse | ChatCompletionResponse:
1264 created_time = int(time.time())
1265 - final_res: Optional[RequestOutput] = None
1265 + final_res: RequestOutput | None = None
1266
1267 try:
1268 async for res in result_generator:
@@ -1512,7 +1512,7 @@ class OpenAIServingChat(OpenAIServing):
1512 choices.append(choice_data)
1513
1514 if request.echo:
1515 - last_msg_content: Union[str, list[dict[str, str]]] = ""
1515 + last_msg_content: str | list[dict[str, str]] = ""
1516 if (
1517 conversation
1518 and "content" in conversation[-1]
@@ -1597,7 +1597,7 @@ class OpenAIServingChat(OpenAIServing):
1597 def _get_top_logprobs(
1598 self,
1599 logprobs: dict[int, Logprob],
1600 - top_logprobs: Optional[int],
1600 + top_logprobs: int | None,
1601 tokenizer: AnyTokenizer,
1602 should_return_as_token_id: bool,
1603 ) -> list[ChatCompletionLogProb]:
@@ -1621,10 +1621,10 @@ class OpenAIServingChat(OpenAIServing):
1621 def _create_chat_logprobs(
1622 self,
1623 token_ids: GenericSequence[int],
1624 - top_logprobs: GenericSequence[Optional[dict[int, Logprob]]],
1624 + top_logprobs: GenericSequence[dict[int, Logprob] | None],
1625 tokenizer: AnyTokenizer,
1626 - num_output_top_logprobs: Optional[int] = None,
1627 - return_as_token_id: Optional[bool] = None,
1626 + num_output_top_logprobs: int | None = None,
1627 + return_as_token_id: bool | None = None,
1628 ) -> ChatCompletionLogProbs:
1629 """Create OpenAI-style logprobs."""
1630 logprobs_content: list[ChatCompletionLogProbsContent] = []
@@ -1693,7 +1693,7 @@ class OpenAIServingChat(OpenAIServing):
1693
1694 def _should_check_for_unstreamed_tool_arg_tokens(
1695 self,
1696 - delta_message: Optional[DeltaMessage],
1696 + delta_message: DeltaMessage | None,
1697 output: CompletionOutput,
1698 ) -> bool:
1699 """
vllm/entrypoints/openai/serving_classification.py
+6 -6
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from http import HTTPStatus
5 -from typing import Optional, Union, cast
5 +from typing import cast
6
7 import numpy as np
8 from fastapi import Request
@@ -36,7 +36,7 @@ class ClassificationMixin(OpenAIServing):
36 async def _preprocess(
37 self,
38 ctx: ServeContext,
39 - ) -> Optional[ErrorResponse]:
39 + ) -> ErrorResponse | None:
40 """
41 Process classification inputs: tokenize text, resolve adapters,
42 and prepare model-specific inputs.
@@ -70,7 +70,7 @@ class ClassificationMixin(OpenAIServing):
70 def _build_response(
71 self,
72 ctx: ServeContext,
73 - ) -> Union[ClassificationResponse, ErrorResponse]:
73 + ) -> ClassificationResponse | ErrorResponse:
74 """
75 Convert model outputs to a formatted classification response
76 with probabilities and labels.
@@ -129,7 +129,7 @@ class ServingClassification(ClassificationMixin):
129 engine_client: EngineClient,
130 models: OpenAIServingModels,
131 *,
132 - request_logger: Optional[RequestLogger],
132 + request_logger: RequestLogger | None,
133 log_error_stack: bool = False,
134 ) -> None:
135 super().__init__(
@@ -143,7 +143,7 @@ class ServingClassification(ClassificationMixin):
143 self,
144 request: ClassificationRequest,
145 raw_request: Request,
146 - ) -> Union[ClassificationResponse, ErrorResponse]:
146 + ) -> ClassificationResponse | ErrorResponse:
147 model_name = self.models.model_name()
148 request_id = f"{self.request_id_prefix}-{self._base_request_id(raw_request)}"
149
@@ -160,7 +160,7 @@ class ServingClassification(ClassificationMixin):
160 def _create_pooling_params(
161 self,
162 ctx: ClassificationServeContext,
163 - ) -> Union[PoolingParams, ErrorResponse]:
163 + ) -> PoolingParams | ErrorResponse:
164 pooling_params = super()._create_pooling_params(ctx)
165 if isinstance(pooling_params, ErrorResponse):
166 return pooling_params
vllm/entrypoints/openai/serving_completion.py
+16 -16
@@ -5,7 +5,7 @@ import asyncio
5 import time
6 from collections.abc import AsyncGenerator, AsyncIterator
7 from collections.abc import Sequence as GenericSequence
8 -from typing import Optional, Union, cast
8 +from typing import cast
9
10 import jinja2
11 from fastapi import Request
@@ -45,7 +45,7 @@ class OpenAIServingCompletion(OpenAIServing):
45 engine_client: EngineClient,
46 models: OpenAIServingModels,
47 *,
48 - request_logger: Optional[RequestLogger],
48 + request_logger: RequestLogger | None,
49 return_tokens_as_token_ids: bool = False,
50 enable_prompt_tokens_details: bool = False,
51 enable_force_include_usage: bool = False,
@@ -73,8 +73,8 @@ class OpenAIServingCompletion(OpenAIServing):
73 async def create_completion(
74 self,
75 request: CompletionRequest,
76 - raw_request: Optional[Request] = None,
77 - ) -> Union[AsyncGenerator[str, None], CompletionResponse, ErrorResponse]:
76 + raw_request: Request | None = None,
77 + ) -> AsyncGenerator[str, None] | CompletionResponse | ErrorResponse:
78 """Completion API similar to OpenAI's API.
79
80 See https://platform.openai.com/docs/api-reference/completions/create
@@ -166,7 +166,7 @@ class OpenAIServingCompletion(OpenAIServing):
166 default_sampling_params=self.default_sampling_params,
167 )
168
169 - sampling_params: Union[SamplingParams, BeamSearchParams]
169 + sampling_params: SamplingParams | BeamSearchParams
170 if request.use_beam_search:
171 sampling_params = request.to_beam_search_params(
172 max_tokens, self.default_sampling_params
@@ -196,7 +196,7 @@ class OpenAIServingCompletion(OpenAIServing):
196 # Mypy inconsistently requires this second cast in different
197 # environments. It shouldn't be necessary (redundant from above)
198 # but pre-commit in CI fails without it.
199 - engine_prompt = cast(Union[EmbedsPrompt, TokensPrompt], engine_prompt)
199 + engine_prompt = cast(EmbedsPrompt | TokensPrompt, engine_prompt)
200 if isinstance(sampling_params, BeamSearchParams):
201 generator = self.beam_search(
202 prompt=engine_prompt,
@@ -260,7 +260,7 @@ class OpenAIServingCompletion(OpenAIServing):
260 )
261
262 # Non-streaming response
263 - final_res_batch: list[Optional[RequestOutput]] = [None] * num_prompts
263 + final_res_batch: list[RequestOutput | None] = [None] * num_prompts
264 try:
265 async for i, res in result_generator:
266 final_res_batch[i] = res
@@ -312,7 +312,7 @@ class OpenAIServingCompletion(OpenAIServing):
312 async def completion_stream_generator(
313 self,
314 request: CompletionRequest,
315 - engine_prompts: list[Union[TokensPrompt, EmbedsPrompt]],
315 + engine_prompts: list[TokensPrompt | EmbedsPrompt],
316 result_generator: AsyncIterator[tuple[int, RequestOutput]],
317 request_id: str,
318 created_time: int,
@@ -362,7 +362,7 @@ class OpenAIServingCompletion(OpenAIServing):
362 num_prompt_tokens[prompt_idx] = len(prompt_token_ids)
363
364 delta_token_ids: GenericSequence[int]
365 - out_logprobs: Optional[GenericSequence[Optional[dict[int, Logprob]]]]
365 + out_logprobs: GenericSequence[dict[int, Logprob] | None] | None
366
367 for output in res.outputs:
368 i = output.index + prompt_idx * num_choices
@@ -370,7 +370,7 @@ class OpenAIServingCompletion(OpenAIServing):
370 # Useful when request.return_token_ids is True
371 # Returning prompt token IDs shares the same logic
372 # with the echo implementation.
373 - prompt_token_ids_to_return: Optional[list[int]] = None
373 + prompt_token_ids_to_return: list[int] | None = None
374
375 assert request.max_tokens is not None
376 if request.echo and not has_echoed[i]:
@@ -524,7 +524,7 @@ class OpenAIServingCompletion(OpenAIServing):
524 prompt_text = final_res.prompt
525
526 token_ids: GenericSequence[int]
527 - out_logprobs: Optional[GenericSequence[Optional[dict[int, Logprob]]]]
527 + out_logprobs: GenericSequence[dict[int, Logprob] | None] | None
528
529 for output in final_res.outputs:
530 assert request.max_tokens is not None
@@ -617,17 +617,17 @@ class OpenAIServingCompletion(OpenAIServing):
617 def _create_completion_logprobs(
618 self,
619 token_ids: GenericSequence[int],
620 - top_logprobs: GenericSequence[Optional[dict[int, Logprob]]],
620 + top_logprobs: GenericSequence[dict[int, Logprob] | None],
621 num_output_top_logprobs: int,
622 tokenizer: AnyTokenizer,
623 initial_text_offset: int = 0,
624 - return_as_token_id: Optional[bool] = None,
624 + return_as_token_id: bool | None = None,
625 ) -> CompletionLogProbs:
626 """Create logprobs for OpenAI Completion API."""
627 out_text_offset: list[int] = []
628 - out_token_logprobs: list[Optional[float]] = []
628 + out_token_logprobs: list[float | None] = []
629 out_tokens: list[str] = []
630 - out_top_logprobs: list[Optional[dict[str, float]]] = []
630 + out_top_logprobs: list[dict[str, float] | None] = []
631
632 last_token_len = 0
633
@@ -695,7 +695,7 @@ class OpenAIServingCompletion(OpenAIServing):
695 def _build_render_config(
696 self,
697 request: CompletionRequest,
698 - max_input_length: Optional[int] = None,
698 + max_input_length: int | None = None,
699 ) -> RenderConfig:
700 max_input_tokens_len = self.max_model_len - (request.max_tokens or 0)
701 return RenderConfig(
vllm/entrypoints/openai/serving_embedding.py
+17 -19
@@ -3,7 +3,7 @@
3
4 import base64
5 from collections.abc import AsyncGenerator, Mapping
6 -from typing import Any, Final, Literal, Optional, Union, cast
6 +from typing import Any, Final, Literal, cast
7
8 import numpy as np
9 import torch
@@ -48,7 +48,7 @@ logger = init_logger(__name__)
48 def _get_embedding(
49 output: EmbeddingOutput,
50 encoding_format: Literal["float", "base64"],
51 -) -> Union[list[float], str]:
51 +) -> list[float] | str:
52 if encoding_format == "float":
53 return output.embedding
54 elif encoding_format == "base64":
@@ -80,7 +80,7 @@ class EmbeddingMixin(OpenAIServing):
80 async def _preprocess(
81 self,
82 ctx: ServeContext,
83 - ) -> Optional[ErrorResponse]:
83 + ) -> ErrorResponse | None:
84 ctx = cast(EmbeddingServeContext, ctx)
85 try:
86 ctx.lora_request = self._maybe_get_adapters(ctx.request)
@@ -130,7 +130,7 @@ class EmbeddingMixin(OpenAIServing):
130 def _build_response(
131 self,
132 ctx: ServeContext,
133 - ) -> Union[EmbeddingResponse, ErrorResponse]:
133 + ) -> EmbeddingResponse | ErrorResponse:
134 items: list[EmbeddingResponseData] = []
135 num_prompt_tokens = 0
136
@@ -314,9 +314,9 @@ class EmbeddingMixin(OpenAIServing):
314 ctx: EmbeddingServeContext,
315 engine_prompt: EngineTokensPrompt,
316 pooling_params: PoolingParams,
317 - trace_headers: Optional[Mapping[str, str]],
317 + trace_headers: Mapping[str, str] | None,
318 prompt_index: int,
319 - ) -> AsyncGenerator[Union[RequestOutput, PoolingRequestOutput], None]:
319 + ) -> AsyncGenerator[RequestOutput | PoolingRequestOutput, None]:
320 """Create a generator for a single prompt using standard processing."""
321 request_id_item = f"{ctx.request_id}-{prompt_index}"
322
@@ -341,7 +341,7 @@ class EmbeddingMixin(OpenAIServing):
341 async def _prepare_generators(
342 self,
343 ctx: ServeContext,
344 - ) -> Optional[ErrorResponse]:
344 + ) -> ErrorResponse | None:
345 """Override to support chunked processing."""
346 ctx = cast(EmbeddingServeContext, ctx)
347
@@ -354,7 +354,7 @@ class EmbeddingMixin(OpenAIServing):
354
355 # Custom logic for chunked processing
356 generators: list[
357 - AsyncGenerator[Union[RequestOutput, PoolingRequestOutput], None]
357 + AsyncGenerator[RequestOutput | PoolingRequestOutput, None]
358 ] = []
359
360 try:
@@ -413,7 +413,7 @@ class EmbeddingMixin(OpenAIServing):
413 async def _collect_batch(
414 self,
415 ctx: ServeContext,
416 - ) -> Optional[ErrorResponse]:
416 + ) -> ErrorResponse | None:
417 """Collect and aggregate batch results
418 with support for chunked processing.
419
@@ -522,9 +522,7 @@ class EmbeddingMixin(OpenAIServing):
522 )
523
524 # Finalize aggregated results
525 - final_res_batch: list[
526 - Union[PoolingRequestOutput, EmbeddingRequestOutput]
527 - ] = []
525 + final_res_batch: list[PoolingRequestOutput | EmbeddingRequestOutput] = []
526 num_prompts = len(ctx.engine_prompts)
527
528 for prompt_idx in range(num_prompts):
@@ -581,7 +579,7 @@ class EmbeddingMixin(OpenAIServing):
579 )
580
581 ctx.final_res_batch = cast(
584 - list[Union[RequestOutput, PoolingRequestOutput]], final_res_batch
582 + list[RequestOutput | PoolingRequestOutput], final_res_batch
583 )
584
585 return None
@@ -598,8 +596,8 @@ class OpenAIServingEmbedding(EmbeddingMixin):
596 engine_client: EngineClient,
597 models: OpenAIServingModels,
598 *,
601 - request_logger: Optional[RequestLogger],
602 - chat_template: Optional[str],
599 + request_logger: RequestLogger | None,
600 + chat_template: str | None,
601 chat_template_content_format: ChatTemplateContentFormatOption,
602 trust_request_chat_template: bool = False,
603 log_error_stack: bool = False,
@@ -618,8 +616,8 @@ class OpenAIServingEmbedding(EmbeddingMixin):
616 async def create_embedding(
617 self,
618 request: EmbeddingRequest,
621 - raw_request: Optional[Request] = None,
622 - ) -> Union[EmbeddingResponse, ErrorResponse]:
619 + raw_request: Request | None = None,
620 + ) -> EmbeddingResponse | ErrorResponse:
621 """
622 Embedding API similar to OpenAI's API.
623
@@ -647,7 +645,7 @@ class OpenAIServingEmbedding(EmbeddingMixin):
645 def _create_pooling_params(
646 self,
647 ctx: ServeContext[EmbeddingRequest],
650 - ) -> Union[PoolingParams, ErrorResponse]:
648 + ) -> PoolingParams | ErrorResponse:
649 pooling_params = super()._create_pooling_params(ctx)
650 if isinstance(pooling_params, ErrorResponse):
651 return pooling_params
@@ -662,7 +660,7 @@ class OpenAIServingEmbedding(EmbeddingMixin):
660 async def _preprocess(
661 self,
662 ctx: ServeContext,
665 - ) -> Optional[ErrorResponse]:
663 + ) -> ErrorResponse | None:
664 if isinstance(ctx.request, EmbeddingChatRequest):
665 error_check_ret = self._validate_chat_template(
666 request_chat_template=ctx.request.chat_template,
vllm/entrypoints/openai/serving_engine.py
+94 -96
@@ -5,10 +5,10 @@ import json
5 import sys
6 import time
7 import traceback
8 -from collections.abc import AsyncGenerator, Iterable, Mapping, Sequence
8 +from collections.abc import AsyncGenerator, Callable, Iterable, Mapping, Sequence
9 from concurrent.futures import ThreadPoolExecutor
10 from http import HTTPStatus
11 -from typing import Any, Callable, ClassVar, Generic, Optional, TypeVar, Union
11 +from typing import Any, ClassVar, Generic, TypeAlias, TypeVar
12
13 import torch
14 from fastapi import Request
@@ -102,38 +102,38 @@ from vllm.v1.engine import EngineCoreRequest
102
103 logger = init_logger(__name__)
104
105 -CompletionLikeRequest = Union[
106 - CompletionRequest,
107 - DetokenizeRequest,
108 - EmbeddingCompletionRequest,
109 - RerankRequest,
110 - ClassificationRequest,
111 - ScoreRequest,
112 - TokenizeCompletionRequest,
113 -]
114 -
115 -ChatLikeRequest = Union[
116 - ChatCompletionRequest, EmbeddingChatRequest, TokenizeChatRequest
117 -]
118 -SpeechToTextRequest = Union[TranscriptionRequest, TranslationRequest]
119 -AnyRequest = Union[
120 - CompletionLikeRequest,
121 - ChatLikeRequest,
122 - SpeechToTextRequest,
123 - ResponsesRequest,
124 - IOProcessorRequest,
125 -]
105 +CompletionLikeRequest: TypeAlias = (
106 + CompletionRequest
107 + | DetokenizeRequest
108 + | EmbeddingCompletionRequest
109 + | RerankRequest
110 + | ClassificationRequest
111 + | ScoreRequest
112 + | TokenizeCompletionRequest
113 +)
114
127 -AnyResponse = Union[
128 - CompletionResponse,
129 - ChatCompletionResponse,
130 - EmbeddingResponse,
131 - TranscriptionResponse,
132 - TokenizeResponse,
133 - PoolingResponse,
134 - ClassificationResponse,
135 - ScoreResponse,
136 -]
115 +ChatLikeRequest: TypeAlias = (
116 + ChatCompletionRequest | EmbeddingChatRequest | TokenizeChatRequest
117 +)
118 +SpeechToTextRequest: TypeAlias = TranscriptionRequest | TranslationRequest
119 +AnyRequest: TypeAlias = (
120 + CompletionLikeRequest
121 + | ChatLikeRequest
122 + | SpeechToTextRequest
123 + | ResponsesRequest
124 + | IOProcessorRequest
125 +)
126 +
127 +AnyResponse: TypeAlias = (
128 + CompletionResponse
129 + | ChatCompletionResponse
130 + | EmbeddingResponse
131 + | TranscriptionResponse
132 + | TokenizeResponse
133 + | PoolingResponse
134 + | ClassificationResponse
135 + | ScoreResponse
136 +)
137
138
139 class TextTokensPrompt(TypedDict):
@@ -145,7 +145,7 @@ class EmbedsPrompt(TypedDict):
145 prompt_embeds: torch.Tensor
146
147
148 -RequestPrompt = Union[list[int], str, TextTokensPrompt, EmbedsPrompt]
148 +RequestPrompt: TypeAlias = list[int] | str | TextTokensPrompt | EmbedsPrompt
149
150
151 def is_text_tokens_prompt(prompt: RequestPrompt) -> TypeIs[TextTokensPrompt]:
@@ -173,8 +173,8 @@ class RequestProcessingMixin(BaseModel):
173 handling prompt preparation and engine input.
174 """
175
176 - request_prompts: Optional[Sequence[RequestPrompt]] = []
177 - engine_prompts: Optional[list[EngineTokensPrompt]] = []
176 + request_prompts: Sequence[RequestPrompt] | None = []
177 + engine_prompts: list[EngineTokensPrompt] | None = []
178
179 model_config = ConfigDict(arbitrary_types_allowed=True)
180
@@ -185,10 +185,10 @@ class ResponseGenerationMixin(BaseModel):
185 managing result generators and final batch results.
186 """
187
188 - result_generator: Optional[
189 - AsyncGenerator[tuple[int, Union[RequestOutput, PoolingRequestOutput]], None]
190 - ] = None
191 - final_res_batch: list[Union[RequestOutput, PoolingRequestOutput]] = Field(
188 + result_generator: (
189 + AsyncGenerator[tuple[int, RequestOutput | PoolingRequestOutput], None] | None
190 + ) = None
191 + final_res_batch: list[RequestOutput | PoolingRequestOutput] = Field(
192 default_factory=list
193 )
194
@@ -203,14 +203,14 @@ class ServeContext(
203 ):
204 # Shared across all requests
205 request: RequestT
206 - raw_request: Optional[Request] = None
206 + raw_request: Request | None = None
207 model_name: str
208 request_id: str
209 created_time: int = Field(default_factory=lambda: int(time.time()))
210 - lora_request: Optional[LoRARequest] = None
210 + lora_request: LoRARequest | None = None
211
212 # Shared across most requests
213 - tokenizer: Optional[AnyTokenizer] = None
213 + tokenizer: AnyTokenizer | None = None
214
215 # `protected_namespaces` resolves Pydantic v2's warning
216 # on conflict with protected namespace "model_"
@@ -224,7 +224,7 @@ ClassificationServeContext = ServeContext[ClassificationRequest]
224
225
226 class EmbeddingServeContext(ServeContext[EmbeddingRequest]):
227 - chat_template: Optional[str] = None
227 + chat_template: str | None = None
228 chat_template_content_format: ChatTemplateContentFormatOption
229
230
@@ -247,7 +247,7 @@ class OpenAIServing:
247 engine_client: EngineClient,
248 models: OpenAIServingModels,
249 *,
250 - request_logger: Optional[RequestLogger],
250 + request_logger: RequestLogger | None,
251 return_tokens_as_token_ids: bool = False,
252 enable_force_include_usage: bool = False,
253 log_error_stack: bool = False,
@@ -276,8 +276,8 @@ class OpenAIServing:
276 self.max_model_len = self.model_config.max_model_len
277
278 def _get_tool_parser(
279 - self, tool_parser_name: Optional[str] = None, enable_auto_tools: bool = False
280 - ) -> Optional[Callable[[AnyTokenizer], ToolParser]]:
279 + self, tool_parser_name: str | None = None, enable_auto_tools: bool = False
280 + ) -> Callable[[AnyTokenizer], ToolParser] | None:
281 """Get the tool parser based on the name."""
282 parser = None
283 if not enable_auto_tools or tool_parser_name is None:
@@ -307,7 +307,7 @@ class OpenAIServing:
307 def _get_reasoning_parser(
308 self,
309 reasoning_parser_name: str,
310 - ) -> Optional[Callable[[AnyTokenizer], ReasoningParser]]:
310 + ) -> Callable[[AnyTokenizer], ReasoningParser] | None:
311 """Get the reasoning parser based on the name."""
312 parser = None
313 if not reasoning_parser_name:
@@ -328,7 +328,7 @@ class OpenAIServing:
328 prompt: PromptType,
329 request_id: str,
330 params: BeamSearchParams,
331 - lora_request: Optional[LoRARequest] = None,
331 + lora_request: LoRARequest | None = None,
332 ) -> AsyncGenerator[RequestOutput, None]:
333 beam_width = params.beam_width
334 max_tokens = params.max_tokens
@@ -364,9 +364,9 @@ class OpenAIServing:
364 # this happens again in generation, so the double expansion causes
365 # a mismatch.
366 # TODO - would be ideal to handle this more gracefully.
367 - prompt_text: Optional[str]
367 + prompt_text: str | None
368 prompt_token_ids: list[int]
369 - multi_modal_data: Optional[MultiModalDataDict]
369 + multi_modal_data: MultiModalDataDict | None
370 if isinstance(prompt, str):
371 prompt_text = prompt
372 prompt_token_ids = []
@@ -376,7 +376,7 @@ class OpenAIServing:
376 prompt_token_ids = prompt.get("prompt_token_ids", []) # type: ignore
377 multi_modal_data = prompt.get("multi_modal_data") # type: ignore
378
379 - mm_processor_kwargs: Optional[dict[str, Any]] = processed_inputs.get(
379 + mm_processor_kwargs: dict[str, Any] | None = processed_inputs.get(
380 "mm_processor_kwargs"
381 ) # type: ignore
382
@@ -507,7 +507,7 @@ class OpenAIServing:
507 prompt_logprobs=None,
508 )
509
510 - def _get_renderer(self, tokenizer: Optional[AnyTokenizer]) -> BaseRenderer:
510 + def _get_renderer(self, tokenizer: AnyTokenizer | None) -> BaseRenderer:
511 """
512 Get a Renderer instance with the provided tokenizer.
513 Uses shared async tokenizer pool for efficiency.
@@ -545,7 +545,7 @@ class OpenAIServing:
545 async def _preprocess(
546 self,
547 ctx: ServeContext,
548 - ) -> Optional[ErrorResponse]:
548 + ) -> ErrorResponse | None:
549 """
550 Default preprocessing hook. Subclasses may override
551 to prepare `ctx` (classification, embedding, etc.).
@@ -555,7 +555,7 @@ class OpenAIServing:
555 def _build_response(
556 self,
557 ctx: ServeContext,
558 - ) -> Union[AnyResponse, ErrorResponse]:
558 + ) -> AnyResponse | ErrorResponse:
559 """
560 Default response builder. Subclass may override this method
561 to return the appropriate response object.
@@ -565,8 +565,8 @@ class OpenAIServing:
565 async def handle(
566 self,
567 ctx: ServeContext,
568 - ) -> Union[AnyResponse, ErrorResponse]:
569 - generation: AsyncGenerator[Union[AnyResponse, ErrorResponse], None]
568 + ) -> AnyResponse | ErrorResponse:
569 + generation: AsyncGenerator[AnyResponse | ErrorResponse, None]
570 generation = self._pipeline(ctx)
571
572 async for response in generation:
@@ -577,7 +577,7 @@ class OpenAIServing:
577 async def _pipeline(
578 self,
579 ctx: ServeContext,
580 - ) -> AsyncGenerator[Union[AnyResponse, ErrorResponse], None]:
580 + ) -> AsyncGenerator[AnyResponse | ErrorResponse, None]:
581 """Execute the request processing pipeline yielding responses."""
582 if error := await self._check_model(ctx.request):
583 yield error
@@ -598,7 +598,7 @@ class OpenAIServing:
598
599 yield self._build_response(ctx)
600
601 - def _validate_request(self, ctx: ServeContext) -> Optional[ErrorResponse]:
601 + def _validate_request(self, ctx: ServeContext) -> ErrorResponse | None:
602 truncate_prompt_tokens = getattr(ctx.request, "truncate_prompt_tokens", None)
603
604 if (
@@ -615,7 +615,7 @@ class OpenAIServing:
615 def _create_pooling_params(
616 self,
617 ctx: ServeContext,
618 - ) -> Union[PoolingParams, ErrorResponse]:
618 + ) -> PoolingParams | ErrorResponse:
619 if not hasattr(ctx.request, "to_pooling_params"):
620 return self.create_error_response(
621 "Request type does not support pooling parameters"
@@ -626,10 +626,10 @@ class OpenAIServing:
626 async def _prepare_generators(
627 self,
628 ctx: ServeContext,
629 - ) -> Optional[ErrorResponse]:
629 + ) -> ErrorResponse | None:
630 """Schedule the request and get the result generator."""
631 generators: list[
632 - AsyncGenerator[Union[RequestOutput, PoolingRequestOutput], None]
632 + AsyncGenerator[RequestOutput | PoolingRequestOutput, None]
633 ] = []
634
635 try:
@@ -678,14 +678,14 @@ class OpenAIServing:
678 async def _collect_batch(
679 self,
680 ctx: ServeContext,
681 - ) -> Optional[ErrorResponse]:
681 + ) -> ErrorResponse | None:
682 """Collect batch results from the result generator."""
683 try:
684 if ctx.engine_prompts is None:
685 return self.create_error_response("Engine prompts not available")
686
687 num_prompts = len(ctx.engine_prompts)
688 - final_res_batch: list[Optional[Union[RequestOutput, PoolingRequestOutput]]]
688 + final_res_batch: list[RequestOutput | PoolingRequestOutput | None]
689 final_res_batch = [None] * num_prompts
690
691 if ctx.result_generator is None:
@@ -738,7 +738,7 @@ class OpenAIServing:
738 async def _check_model(
739 self,
740 request: AnyRequest,
741 - ) -> Optional[ErrorResponse]:
741 + ) -> ErrorResponse | None:
742 error_response = None
743
744 if self._is_model_supported(request.model):
@@ -764,9 +764,7 @@ class OpenAIServing:
764 status_code=HTTPStatus.NOT_FOUND,
765 )
766
767 - def _get_active_default_mm_loras(
768 - self, request: AnyRequest
769 - ) -> Optional[LoRARequest]:
767 + def _get_active_default_mm_loras(self, request: AnyRequest) -> LoRARequest | None:
768 """Determine if there are any active default multimodal loras."""
769 # TODO: Currently this is only enabled for chat completions
770 # to be better aligned with only being enabled for .generate
@@ -793,7 +791,7 @@ class OpenAIServing:
791 self,
792 request: AnyRequest,
793 supports_default_mm_loras: bool = False,
796 - ) -> Optional[LoRARequest]:
794 + ) -> LoRARequest | None:
795 if request.model in self.models.lora_requests:
796 return self.models.lora_requests[request.model]
797
@@ -877,7 +875,7 @@ class OpenAIServing:
875 self,
876 request: AnyRequest,
877 prompt_ids: list[int],
880 - tokenizer: Optional[AnyTokenizer],
878 + tokenizer: AnyTokenizer | None,
879 ) -> TextTokensPrompt:
880 truncate_prompt_tokens = getattr(request, "truncate_prompt_tokens", None)
881
@@ -972,7 +970,7 @@ class OpenAIServing:
970 self,
971 request: AnyRequest,
972 tokenizer: AnyTokenizer,
975 - prompt_input: Union[str, list[int]],
973 + prompt_input: str | list[int],
974 add_special_tokens: bool = True,
975 ) -> TextTokensPrompt:
976 """
@@ -991,7 +989,7 @@ class OpenAIServing:
989 self,
990 request: AnyRequest,
991 tokenizer: AnyTokenizer,
994 - prompt_inputs: Iterable[Union[str, list[int]]],
992 + prompt_inputs: Iterable[str | list[int]],
993 add_special_tokens: bool = True,
994 ) -> AsyncGenerator[TextTokensPrompt, None]:
995 """
@@ -1014,10 +1012,10 @@ class OpenAIServing:
1012
1013 def _validate_chat_template(
1014 self,
1017 - request_chat_template: Optional[str],
1018 - chat_template_kwargs: Optional[dict[str, Any]],
1015 + request_chat_template: str | None,
1016 + chat_template_kwargs: dict[str, Any] | None,
1017 trust_request_chat_template: bool,
1020 - ) -> Optional[ErrorResponse]:
1018 + ) -> ErrorResponse | None:
1019 if not trust_request_chat_template and (
1020 request_chat_template is not None
1021 or (
@@ -1034,17 +1032,17 @@ class OpenAIServing:
1032
1033 async def _preprocess_chat(
1034 self,
1037 - request: Union[ChatLikeRequest, ResponsesRequest],
1035 + request: ChatLikeRequest | ResponsesRequest,
1036 tokenizer: AnyTokenizer,
1037 messages: list[ChatCompletionMessageParam],
1040 - chat_template: Optional[str],
1038 + chat_template: str | None,
1039 chat_template_content_format: ChatTemplateContentFormatOption,
1040 add_generation_prompt: bool = True,
1041 continue_final_message: bool = False,
1044 - tool_dicts: Optional[list[dict[str, Any]]] = None,
1045 - documents: Optional[list[dict[str, str]]] = None,
1046 - chat_template_kwargs: Optional[dict[str, Any]] = None,
1047 - tool_parser: Optional[Callable[[AnyTokenizer], ToolParser]] = None,
1042 + tool_dicts: list[dict[str, Any]] | None = None,
1043 + documents: list[dict[str, str]] | None = None,
1044 + chat_template_kwargs: dict[str, Any] | None = None,
1045 + tool_parser: Callable[[AnyTokenizer], ToolParser] | None = None,
1046 add_special_tokens: bool = False,
1047 ) -> tuple[
1048 list[ConversationMessage],
@@ -1076,7 +1074,7 @@ class OpenAIServing:
1074 )
1075 _chat_template_kwargs.update(chat_template_kwargs or {})
1076
1079 - request_prompt: Union[str, list[int]]
1077 + request_prompt: str | list[int]
1078
1079 if tokenizer is None:
1080 request_prompt = "placeholder"
@@ -1158,10 +1156,10 @@ class OpenAIServing:
1156 self,
1157 request_id: str,
1158 engine_prompt: PromptType,
1161 - params: Union[SamplingParams, PoolingParams],
1159 + params: SamplingParams | PoolingParams,
1160 *,
1163 - lora_request: Optional[LoRARequest],
1164 - trace_headers: Optional[Mapping[str, str]],
1161 + lora_request: LoRARequest | None,
1162 + trace_headers: Mapping[str, str] | None,
1163 priority: int,
1164 ) -> tuple[EngineCoreRequest, dict[str, Any]]:
1165 """Use the Processor to process inputs for AsyncLLM."""
@@ -1188,7 +1186,7 @@ class OpenAIServing:
1186 engine_prompt: EngineTokensPrompt,
1187 sampling_params: SamplingParams,
1188 context: ConversationContext,
1191 - lora_request: Optional[LoRARequest] = None,
1189 + lora_request: LoRARequest | None = None,
1190 priority: int = 0,
1191 **kwargs,
1192 ):
@@ -1250,7 +1248,7 @@ class OpenAIServing:
1248
1249 def _get_prompt_components(
1250 self,
1253 - prompt: Union[RequestPrompt, PromptType],
1251 + prompt: RequestPrompt | PromptType,
1252 ) -> PromptComponents:
1253 if isinstance(prompt, list):
1254 return PromptComponents(token_ids=prompt)
@@ -1260,9 +1258,9 @@ class OpenAIServing:
1258 def _log_inputs(
1259 self,
1260 request_id: str,
1263 - inputs: Union[RequestPrompt, PromptType],
1264 - params: Optional[Union[SamplingParams, PoolingParams, BeamSearchParams]],
1265 - lora_request: Optional[LoRARequest],
1261 + inputs: RequestPrompt | PromptType,
1262 + params: SamplingParams | PoolingParams | BeamSearchParams | None,
1263 + lora_request: LoRARequest | None,
1264 ) -> None:
1265 if self.request_logger is None:
1266 return
@@ -1281,7 +1279,7 @@ class OpenAIServing:
1279 async def _get_trace_headers(
1280 self,
1281 headers: Headers,
1284 - ) -> Optional[Mapping[str, str]]:
1282 + ) -> Mapping[str, str] | None:
1283 is_tracing_enabled = await self.engine_client.is_tracing_enabled()
1284
1285 if is_tracing_enabled:
@@ -1294,8 +1292,8 @@ class OpenAIServing:
1292
1293 @staticmethod
1294 def _base_request_id(
1297 - raw_request: Optional[Request], default: Optional[str] = None
1298 - ) -> Optional[str]:
1295 + raw_request: Request | None, default: str | None = None
1296 + ) -> str | None:
1297 """Pulls the request id to use from a header, if provided"""
1298 default = default or random_uuid()
1299 if raw_request is None:
@@ -1317,15 +1315,15 @@ class OpenAIServing:
1315 return logprob.decoded_token
1316 return tokenizer.decode(token_id)
1317
1320 - def _is_model_supported(self, model_name: Optional[str]) -> bool:
1318 + def _is_model_supported(self, model_name: str | None) -> bool:
1319 if not model_name:
1320 return True
1321 return self.models.is_base_model(model_name)
1322
1323
1324 def clamp_prompt_logprobs(
1327 - prompt_logprobs: Union[PromptLogprobs, None],
1328 -) -> Union[PromptLogprobs, None]:
1325 + prompt_logprobs: PromptLogprobs | None,
1326 +) -> PromptLogprobs | None:
1327 if prompt_logprobs is None:
1328 return prompt_logprobs
1329
vllm/entrypoints/openai/serving_models.py
+9 -10
@@ -5,7 +5,6 @@ from asyncio import Lock
5 from collections import defaultdict
6 from dataclasses import dataclass
7 from http import HTTPStatus
8 -from typing import Optional, Union
8
9 from vllm.engine.protocol import EngineClient
10 from vllm.entrypoints.openai.protocol import (
@@ -35,7 +34,7 @@ class BaseModelPath:
34 class LoRAModulePath:
35 name: str
36 path: str
38 - base_model_name: Optional[str] = None
37 + base_model_name: str | None = None
38
39
40 class OpenAIServingModels:
@@ -52,7 +51,7 @@ class OpenAIServingModels:
51 engine_client: EngineClient,
52 base_model_paths: list[BaseModelPath],
53 *,
55 - lora_modules: Optional[list[LoRAModulePath]] = None,
54 + lora_modules: list[LoRAModulePath] | None = None,
55 ):
56 super().__init__()
57
@@ -93,7 +92,7 @@ class OpenAIServingModels:
92 def is_base_model(self, model_name) -> bool:
93 return any(model.name == model_name for model in self.base_model_paths)
94
96 - def model_name(self, lora_request: Optional[LoRARequest] = None) -> str:
95 + def model_name(self, lora_request: LoRARequest | None = None) -> str:
96 """Returns the appropriate model name depending on the availability
97 and support of the LoRA or base model.
98 Parameters:
@@ -132,8 +131,8 @@ class OpenAIServingModels:
131 return ModelList(data=model_cards)
132
133 async def load_lora_adapter(
135 - self, request: LoadLoRAAdapterRequest, base_model_name: Optional[str] = None
136 - ) -> Union[ErrorResponse, str]:
134 + self, request: LoadLoRAAdapterRequest, base_model_name: str | None = None
135 + ) -> ErrorResponse | str:
136 lora_name = request.lora_name
137
138 # Ensure atomicity based on the lora name
@@ -173,7 +172,7 @@ class OpenAIServingModels:
172
173 async def unload_lora_adapter(
174 self, request: UnloadLoRAAdapterRequest
176 - ) -> Union[ErrorResponse, str]:
175 + ) -> ErrorResponse | str:
176 lora_name = request.lora_name
177
178 # Ensure atomicity based on the lora name
@@ -189,7 +188,7 @@ class OpenAIServingModels:
188
189 async def _check_load_lora_adapter_request(
190 self, request: LoadLoRAAdapterRequest
192 - ) -> Optional[ErrorResponse]:
191 + ) -> ErrorResponse | None:
192 # Check if both 'lora_name' and 'lora_path' are provided
193 if not request.lora_name or not request.lora_path:
194 return create_error_response(
@@ -211,7 +210,7 @@ class OpenAIServingModels:
210
211 async def _check_unload_lora_adapter_request(
212 self, request: UnloadLoRAAdapterRequest
214 - ) -> Optional[ErrorResponse]:
213 + ) -> ErrorResponse | None:
214 # Check if 'lora_name' is not provided return an error
215 if not request.lora_name:
216 return create_error_response(
@@ -230,7 +229,7 @@ class OpenAIServingModels:
229
230 return None
231
233 - async def resolve_lora(self, lora_name: str) -> Union[LoRARequest, ErrorResponse]:
232 + async def resolve_lora(self, lora_name: str) -> LoRARequest | ErrorResponse:
233 """Attempt to resolve a LoRA adapter using available resolvers.
234
235 Args:
vllm/entrypoints/openai/serving_pooling.py
+7 -7
@@ -5,7 +5,7 @@ import asyncio
5 import base64
6 import time
7 from collections.abc import AsyncGenerator
8 -from typing import Final, Literal, Optional, Union, cast
8 +from typing import Final, Literal, cast
9
10 import jinja2
11 import numpy as np
@@ -41,7 +41,7 @@ logger = init_logger(__name__)
41 def _get_data(
42 output: PoolingOutput,
43 encoding_format: Literal["float", "base64"],
44 -) -> Union[list[float], str]:
44 +) -> list[float] | str:
45 if encoding_format == "float":
46 return output.data.tolist()
47 elif encoding_format == "base64":
@@ -60,8 +60,8 @@ class OpenAIServingPooling(OpenAIServing):
60 engine_client: EngineClient,
61 models: OpenAIServingModels,
62 *,
63 - request_logger: Optional[RequestLogger],
64 - chat_template: Optional[str],
63 + request_logger: RequestLogger | None,
64 + chat_template: str | None,
65 chat_template_content_format: ChatTemplateContentFormatOption,
66 trust_request_chat_template: bool = False,
67 log_error_stack: bool = False,
@@ -80,8 +80,8 @@ class OpenAIServingPooling(OpenAIServing):
80 async def create_pooling(
81 self,
82 request: PoolingRequest,
83 - raw_request: Optional[Request] = None,
84 - ) -> Union[PoolingResponse, IOProcessorResponse, ErrorResponse]:
83 + raw_request: Request | None = None,
84 + ) -> PoolingResponse | IOProcessorResponse | ErrorResponse:
85 """
86 See https://platform.openai.com/docs/api-reference/embeddings/create
87 for the API specification. This API mimics the OpenAI Embedding API.
@@ -219,7 +219,7 @@ class OpenAIServingPooling(OpenAIServing):
219 num_prompts = len(engine_prompts)
220
221 # Non-streaming response
222 - final_res_batch: list[Optional[PoolingRequestOutput]]
222 + final_res_batch: list[PoolingRequestOutput | None]
223 final_res_batch = [None] * num_prompts
224 try:
225 async for i, res in result_generator:
vllm/entrypoints/openai/serving_responses.py
+36 -36
@@ -6,11 +6,11 @@ import json
6 import time
7 import uuid
8 from collections import deque
9 -from collections.abc import AsyncGenerator, AsyncIterator, Sequence
9 +from collections.abc import AsyncGenerator, AsyncIterator, Callable, Sequence
10 from contextlib import AsyncExitStack
11 from copy import copy
12 from http import HTTPStatus
13 -from typing import Callable, Final, Optional, Union
13 +from typing import Final
14
15 import jinja2
16 from fastapi import Request
@@ -109,14 +109,14 @@ class OpenAIServingResponses(OpenAIServing):
109 engine_client: EngineClient,
110 models: OpenAIServingModels,
111 *,
112 - request_logger: Optional[RequestLogger],
113 - chat_template: Optional[str],
112 + request_logger: RequestLogger | None,
113 + chat_template: str | None,
114 chat_template_content_format: ChatTemplateContentFormatOption,
115 return_tokens_as_token_ids: bool = False,
116 reasoning_parser: str = "",
117 enable_auto_tools: bool = False,
118 - tool_parser: Optional[str] = None,
119 - tool_server: Optional[ToolServer] = None,
118 + tool_parser: str | None = None,
119 + tool_server: ToolServer | None = None,
120 enable_prompt_tokens_details: bool = False,
121 enable_force_include_usage: bool = False,
122 enable_log_outputs: bool = False,
@@ -210,7 +210,7 @@ class OpenAIServingResponses(OpenAIServing):
210
211 def _validate_generator_input(
212 self, engine_prompt: EngineTokensPrompt
213 - ) -> Optional[ErrorResponse]:
213 + ) -> ErrorResponse | None:
214 """Add validations to the input to the generator here."""
215 if self.max_model_len <= len(engine_prompt["prompt_token_ids"]):
216 error_message = (
@@ -229,12 +229,12 @@ class OpenAIServingResponses(OpenAIServing):
229 async def create_responses(
230 self,
231 request: ResponsesRequest,
232 - raw_request: Optional[Request] = None,
233 - ) -> Union[
234 - AsyncGenerator[StreamingResponsesResponse, None],
235 - ResponsesResponse,
236 - ErrorResponse,
237 - ]:
232 + raw_request: Request | None = None,
233 + ) -> (
234 + AsyncGenerator[StreamingResponsesResponse, None]
235 + | ResponsesResponse
236 + | ErrorResponse
237 + ):
238 error_check_ret = await self._check_model(request)
239 if error_check_ret is not None:
240 logger.error("Error with model %s", error_check_ret)
@@ -460,7 +460,7 @@ class OpenAIServingResponses(OpenAIServing):
460 async def _make_request(
461 self,
462 request: ResponsesRequest,
463 - prev_response: Optional[ResponsesResponse],
463 + prev_response: ResponsesResponse | None,
464 tokenizer: AnyTokenizer,
465 ):
466 if len(request.tools) > 0:
@@ -481,7 +481,7 @@ class OpenAIServingResponses(OpenAIServing):
481 def _make_request_with_harmony(
482 self,
483 request: ResponsesRequest,
484 - prev_response: Optional[ResponsesResponse],
484 + prev_response: ResponsesResponse | None,
485 ):
486 if request.tool_choice != "auto":
487 raise NotImplementedError(
@@ -522,8 +522,8 @@ class OpenAIServingResponses(OpenAIServing):
522 model_name: str,
523 tokenizer: AnyTokenizer,
524 request_metadata: RequestResponseMetadata,
525 - created_time: Optional[int] = None,
526 - ) -> Union[ErrorResponse, ResponsesResponse]:
525 + created_time: int | None = None,
526 + ) -> ErrorResponse | ResponsesResponse:
527 if created_time is None:
528 created_time = int(time.time())
529
@@ -642,9 +642,9 @@ class OpenAIServingResponses(OpenAIServing):
642 def _create_response_logprobs(
643 self,
644 token_ids: Sequence[int],
645 - logprobs: Optional[SampleLogprobs],
645 + logprobs: SampleLogprobs | None,
646 tokenizer: AnyTokenizer,
647 - top_logprobs: Optional[int] = None,
647 + top_logprobs: int | None = None,
648 ) -> list[Logprob]:
649 assert logprobs is not None, "logprobs must be provided"
650 assert len(token_ids) == len(logprobs), (
@@ -676,9 +676,9 @@ class OpenAIServingResponses(OpenAIServing):
676 def _create_stream_response_logprobs(
677 self,
678 token_ids: Sequence[int],
679 - logprobs: Optional[SampleLogprobs],
679 + logprobs: SampleLogprobs | None,
680 tokenizer: AnyTokenizer,
681 - top_logprobs: Optional[int] = None,
681 + top_logprobs: int | None = None,
682 ) -> list[response_text_delta_event.Logprob]:
683 lgs = self._create_response_logprobs(
684 token_ids=token_ids,
@@ -793,7 +793,7 @@ class OpenAIServingResponses(OpenAIServing):
793 def _construct_input_messages(
794 self,
795 request: ResponsesRequest,
796 - prev_response: Optional[ResponsesResponse] = None,
796 + prev_response: ResponsesResponse | None = None,
797 ) -> list[ChatCompletionMessageParam]:
798 messages: list[ChatCompletionMessageParam] = []
799 if request.instructions:
@@ -833,7 +833,7 @@ class OpenAIServingResponses(OpenAIServing):
833 def _construct_input_messages_with_harmony(
834 self,
835 request: ResponsesRequest,
836 - prev_response: Optional[ResponsesResponse],
836 + prev_response: ResponsesResponse | None,
837 ) -> list[OpenAIHarmonyMessage]:
838 messages: list[OpenAIHarmonyMessage] = []
839 if prev_response is None:
@@ -986,7 +986,7 @@ class OpenAIServingResponses(OpenAIServing):
986 async def responses_background_stream_generator(
987 self,
988 response_id: str,
989 - starting_after: Optional[int] = None,
989 + starting_after: int | None = None,
990 ) -> AsyncGenerator[StreamingResponsesResponse, None]:
991 if response_id not in self.event_store:
992 raise ValueError(f"Unknown response_id: {response_id}")
@@ -1011,13 +1011,13 @@ class OpenAIServingResponses(OpenAIServing):
1011 async def retrieve_responses(
1012 self,
1013 response_id: str,
1014 - starting_after: Optional[int],
1015 - stream: Optional[bool],
1016 - ) -> Union[
1017 - ErrorResponse,
1018 - ResponsesResponse,
1019 - AsyncGenerator[StreamingResponsesResponse, None],
1020 - ]:
1014 + starting_after: int | None,
1015 + stream: bool | None,
1016 + ) -> (
1017 + ErrorResponse
1018 + | ResponsesResponse
1019 + | AsyncGenerator[StreamingResponsesResponse, None]
1020 + ):
1021 async with self.response_store_lock:
1022 response = self.response_store.get(response_id)
1023
@@ -1034,7 +1034,7 @@ class OpenAIServingResponses(OpenAIServing):
1034 async def cancel_responses(
1035 self,
1036 response_id: str,
1037 - ) -> Union[ErrorResponse, ResponsesResponse]:
1037 + ) -> ErrorResponse | ResponsesResponse:
1038 async with self.response_store_lock:
1039 response = self.response_store.get(response_id)
1040 if response is None:
@@ -1082,7 +1082,7 @@ class OpenAIServingResponses(OpenAIServing):
1082 self,
1083 request: ResponsesRequest,
1084 sampling_params: SamplingParams,
1085 - result_generator: AsyncIterator[Optional[ConversationContext]],
1085 + result_generator: AsyncIterator[ConversationContext | None],
1086 context: ConversationContext,
1087 model_name: str,
1088 tokenizer: AnyTokenizer,
@@ -1385,7 +1385,7 @@ class OpenAIServingResponses(OpenAIServing):
1385 self,
1386 request: ResponsesRequest,
1387 sampling_params: SamplingParams,
1388 - result_generator: AsyncIterator[Optional[ConversationContext]],
1388 + result_generator: AsyncIterator[ConversationContext | None],
1389 context: ConversationContext,
1390 model_name: str,
1391 tokenizer: AnyTokenizer,
@@ -1772,12 +1772,12 @@ class OpenAIServingResponses(OpenAIServing):
1772 self,
1773 request: ResponsesRequest,
1774 sampling_params: SamplingParams,
1775 - result_generator: AsyncIterator[Optional[ConversationContext]],
1775 + result_generator: AsyncIterator[ConversationContext | None],
1776 context: ConversationContext,
1777 model_name: str,
1778 tokenizer: AnyTokenizer,
1779 request_metadata: RequestResponseMetadata,
1780 - created_time: Optional[int] = None,
1780 + created_time: int | None = None,
1781 ) -> AsyncGenerator[StreamingResponsesResponse, None]:
1782 # TODO:
1783 # 1. Handle disconnect
vllm/entrypoints/openai/serving_score.py
+29 -29
@@ -3,7 +3,7 @@
3 import asyncio
4 import time
5 from collections.abc import AsyncGenerator, Mapping
6 -from typing import Any, Optional, Union
6 +from typing import Any
7
8 from fastapi import Request
9
@@ -48,7 +48,7 @@ class ServingScores(OpenAIServing):
48 engine_client: EngineClient,
49 models: OpenAIServingModels,
50 *,
51 - request_logger: Optional[RequestLogger],
51 + request_logger: RequestLogger | None,
52 log_error_stack: bool = False,
53 ) -> None:
54 super().__init__(
@@ -63,12 +63,12 @@ class ServingScores(OpenAIServing):
63 tokenizer: AnyTokenizer,
64 texts_1: list[str],
65 texts_2: list[str],
66 - request: Union[RerankRequest, ScoreRequest],
66 + request: RerankRequest | ScoreRequest,
67 request_id: str,
68 - tokenization_kwargs: Optional[dict[str, Any]] = None,
69 - lora_request: Optional[Union[LoRARequest, None]] = None,
70 - trace_headers: Optional[Mapping[str, str]] = None,
71 - ) -> Union[list[PoolingRequestOutput], ErrorResponse]:
68 + tokenization_kwargs: dict[str, Any] | None = None,
69 + lora_request: LoRARequest | None | None = None,
70 + trace_headers: Mapping[str, str] | None = None,
71 + ) -> list[PoolingRequestOutput] | ErrorResponse:
72 input_texts = texts_1 + texts_2
73
74 engine_prompts: list[TokensPrompt] = []
@@ -125,7 +125,7 @@ class ServingScores(OpenAIServing):
125 # Non-streaming response
126 final_res_batch: list[PoolingRequestOutput] = []
127
128 - embeddings: list[Optional[PoolingRequestOutput]] = [None] * len(engine_prompts)
128 + embeddings: list[PoolingRequestOutput | None] = [None] * len(engine_prompts)
129
130 async for i, res in result_generator:
131 embeddings[i] = res
@@ -152,11 +152,11 @@ class ServingScores(OpenAIServing):
152
153 def _preprocess_score(
154 self,
155 - request: Union[RerankRequest, ScoreRequest],
155 + request: RerankRequest | ScoreRequest,
156 tokenizer: AnyTokenizer,
157 tokenization_kwargs: dict[str, Any],
158 - data_1: Union[str, ScoreContentPartParam],
159 - data_2: Union[str, ScoreContentPartParam],
158 + data_1: str | ScoreContentPartParam,
159 + data_2: str | ScoreContentPartParam,
160 ) -> tuple[str, TokensPrompt]:
161 model_config = self.model_config
162
@@ -176,14 +176,14 @@ class ServingScores(OpenAIServing):
176 async def _cross_encoding_score(
177 self,
178 tokenizer: AnyTokenizer,
179 - data_1: Union[list[str], list[ScoreContentPartParam]],
180 - data_2: Union[list[str], list[ScoreContentPartParam]],
181 - request: Union[RerankRequest, ScoreRequest],
179 + data_1: list[str] | list[ScoreContentPartParam],
180 + data_2: list[str] | list[ScoreContentPartParam],
181 + request: RerankRequest | ScoreRequest,
182 request_id: str,
183 - tokenization_kwargs: Optional[dict[str, Any]] = None,
184 - lora_request: Optional[Union[LoRARequest, None]] = None,
185 - trace_headers: Optional[Mapping[str, str]] = None,
186 - ) -> Union[list[PoolingRequestOutput], ErrorResponse]:
183 + tokenization_kwargs: dict[str, Any] | None = None,
184 + lora_request: LoRARequest | None | None = None,
185 + trace_headers: Mapping[str, str] | None = None,
186 + ) -> list[PoolingRequestOutput] | ErrorResponse:
187 request_prompts: list[str] = []
188 engine_prompts: list[TokensPrompt] = []
189
@@ -259,7 +259,7 @@ class ServingScores(OpenAIServing):
259 result_generator = merge_async_iterators(*generators)
260
261 # Non-streaming response
262 - final_res_batch: list[Optional[PoolingRequestOutput]] = [None] * len(
262 + final_res_batch: list[PoolingRequestOutput | None] = [None] * len(
263 engine_prompts
264 )
265
@@ -270,12 +270,12 @@ class ServingScores(OpenAIServing):
270
271 async def _run_scoring(
272 self,
273 - data_1: Union[list[str], str, ScoreMultiModalParam],
274 - data_2: Union[list[str], str, ScoreMultiModalParam],
275 - request: Union[ScoreRequest, RerankRequest],
273 + data_1: list[str] | str | ScoreMultiModalParam,
274 + data_2: list[str] | str | ScoreMultiModalParam,
275 + request: ScoreRequest | RerankRequest,
276 request_id: str,
277 - raw_request: Optional[Request] = None,
278 - ) -> Union[list[PoolingRequestOutput], ErrorResponse]:
277 + raw_request: Request | None = None,
278 + ) -> list[PoolingRequestOutput] | ErrorResponse:
279 lora_request = self._maybe_get_adapters(request)
280
281 tokenizer = await self.engine_client.get_tokenizer()
@@ -339,8 +339,8 @@ class ServingScores(OpenAIServing):
339 async def create_score(
340 self,
341 request: ScoreRequest,
342 - raw_request: Optional[Request] = None,
343 - ) -> Union[ScoreResponse, ErrorResponse]:
342 + raw_request: Request | None = None,
343 + ) -> ScoreResponse | ErrorResponse:
344 """
345 Score API similar to Sentence Transformers cross encoder
346
@@ -377,8 +377,8 @@ class ServingScores(OpenAIServing):
377 return self.create_error_response(str(e))
378
379 async def do_rerank(
380 - self, request: RerankRequest, raw_request: Optional[Request] = None
381 - ) -> Union[RerankResponse, ErrorResponse]:
380 + self, request: RerankRequest, raw_request: Request | None = None
381 + ) -> RerankResponse | ErrorResponse:
382 """
383 Rerank API based on JinaAI's rerank API; implements the same
384 API interface. Designed for compatibility with off-the-shelf
@@ -468,7 +468,7 @@ class ServingScores(OpenAIServing):
468 final_res_batch: list[PoolingRequestOutput],
469 request_id: str,
470 model_name: str,
471 - documents: Union[list[str], ScoreMultiModalParam],
471 + documents: list[str] | ScoreMultiModalParam,
472 top_n: int,
473 ) -> RerankResponse:
474 """
vllm/entrypoints/openai/serving_tokenization.py
+7 -7
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import Any, Final, Optional, Union
4 +from typing import Any, Final
5
6 import jinja2
7 from fastapi import Request
@@ -33,8 +33,8 @@ class OpenAIServingTokenization(OpenAIServing):
33 engine_client: EngineClient,
34 models: OpenAIServingModels,
35 *,
36 - request_logger: Optional[RequestLogger],
37 - chat_template: Optional[str],
36 + request_logger: RequestLogger | None,
37 + chat_template: str | None,
38 chat_template_content_format: ChatTemplateContentFormatOption,
39 trust_request_chat_template: bool = False,
40 log_error_stack: bool = False,
@@ -54,7 +54,7 @@ class OpenAIServingTokenization(OpenAIServing):
54 self,
55 request: TokenizeRequest,
56 raw_request: Request,
57 - ) -> Union[TokenizeResponse, ErrorResponse]:
57 + ) -> TokenizeResponse | ErrorResponse:
58 error_check_ret = await self._check_model(request)
59 if error_check_ret is not None:
60 return error_check_ret
@@ -129,7 +129,7 @@ class OpenAIServingTokenization(OpenAIServing):
129 self,
130 request: DetokenizeRequest,
131 raw_request: Request,
132 - ) -> Union[DetokenizeResponse, ErrorResponse]:
132 + ) -> DetokenizeResponse | ErrorResponse:
133 error_check_ret = await self._check_model(request)
134 if error_check_ret is not None:
135 return error_check_ret
@@ -155,7 +155,7 @@ class OpenAIServingTokenization(OpenAIServing):
155
156 async def get_tokenizer_info(
157 self,
158 - ) -> Union[TokenizerInfoResponse, ErrorResponse]:
158 + ) -> TokenizerInfoResponse | ErrorResponse:
159 """Get comprehensive tokenizer information."""
160 try:
161 tokenizer = await self.engine_client.get_tokenizer()
@@ -171,7 +171,7 @@ class OpenAIServingTokenization(OpenAIServing):
171 @dataclass
172 class TokenizerInfo:
173 tokenizer: AnyTokenizer
174 - chat_template: Optional[str]
174 + chat_template: str | None
175
176 def to_dict(self) -> dict[str, Any]:
177 """Return the tokenizer configuration."""
vllm/entrypoints/openai/serving_transcription.py
+4 -5
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import AsyncGenerator
4 -from typing import Optional, Union
4
5 from fastapi import Request
6
@@ -35,7 +34,7 @@ class OpenAIServingTranscription(OpenAISpeechToText):
34 engine_client: EngineClient,
35 models: OpenAIServingModels,
36 *,
38 - request_logger: Optional[RequestLogger],
37 + request_logger: RequestLogger | None,
38 return_tokens_as_token_ids: bool = False,
39 log_error_stack: bool = False,
40 ):
@@ -50,7 +49,7 @@ class OpenAIServingTranscription(OpenAISpeechToText):
49
50 async def create_transcription(
51 self, audio_data: bytes, request: TranscriptionRequest, raw_request: Request
53 - ) -> Union[TranscriptionResponse, AsyncGenerator[str, None], ErrorResponse]:
52 + ) -> TranscriptionResponse | AsyncGenerator[str, None] | ErrorResponse:
53 """Transcription API similar to OpenAI's API.
54
55 See https://platform.openai.com/docs/api-reference/audio/createTranscription
@@ -94,7 +93,7 @@ class OpenAIServingTranslation(OpenAISpeechToText):
93 engine_client: EngineClient,
94 models: OpenAIServingModels,
95 *,
97 - request_logger: Optional[RequestLogger],
96 + request_logger: RequestLogger | None,
97 return_tokens_as_token_ids: bool = False,
98 log_error_stack: bool = False,
99 ):
@@ -109,7 +108,7 @@ class OpenAIServingTranslation(OpenAISpeechToText):
108
109 async def create_translation(
110 self, audio_data: bytes, request: TranslationRequest, raw_request: Request
112 - ) -> Union[TranslationResponse, AsyncGenerator[str, None], ErrorResponse]:
111 + ) -> TranslationResponse | AsyncGenerator[str, None] | ErrorResponse:
112 """Translation API similar to OpenAI's API.
113
114 See https://platform.openai.com/docs/api-reference/audio/createTranslation
vllm/entrypoints/openai/speech_to_text.py
+10 -15
@@ -4,9 +4,9 @@ import asyncio
4 import io
5 import math
6 import time
7 -from collections.abc import AsyncGenerator
7 +from collections.abc import AsyncGenerator, Callable
8 from functools import cached_property
9 -from typing import Callable, Literal, Optional, TypeVar, Union, cast
9 +from typing import Literal, TypeAlias, TypeVar, cast
10
11 import numpy as np
12 from fastapi import Request
@@ -39,7 +39,7 @@ try:
39 except ImportError:
40 librosa = PlaceholderModule("librosa") # type: ignore[assignment]
41
42 -SpeechToTextResponse = Union[TranscriptionResponse, TranslationResponse]
42 +SpeechToTextResponse: TypeAlias = TranscriptionResponse | TranslationResponse
43 T = TypeVar("T", bound=SpeechToTextResponse)
44
45 logger = init_logger(__name__)
@@ -54,7 +54,7 @@ class OpenAISpeechToText(OpenAIServing):
54 engine_client: EngineClient,
55 models: OpenAIServingModels,
56 *,
57 - request_logger: Optional[RequestLogger],
57 + request_logger: RequestLogger | None,
58 return_tokens_as_token_ids: bool = False,
59 task_type: Literal["transcribe", "translate"] = "transcribe",
60 log_error_stack: bool = False,
@@ -140,7 +140,7 @@ class OpenAISpeechToText(OpenAIServing):
140 raw_request: Request,
141 response_class: type[T],
142 stream_generator_method: Callable[..., AsyncGenerator[str, None]],
143 - ) -> Union[T, AsyncGenerator[str, None], ErrorResponse]:
143 + ) -> T | AsyncGenerator[str, None] | ErrorResponse:
144 """Base method for speech-to-text operations like transcription and
145 translation."""
146 error_check_ret = await self._check_model(request)
@@ -181,9 +181,7 @@ class OpenAISpeechToText(OpenAIServing):
181 logger.exception("Error in preprocessing prompt inputs")
182 return self.create_error_response(str(e))
183
184 - list_result_generator: Optional[list[AsyncGenerator[RequestOutput, None]]] = (
185 - None
186 - )
184 + list_result_generator: list[AsyncGenerator[RequestOutput, None]] | None = None
185 try:
186 # Unlike most decoder-only models, whisper generation length is not
187 # constrained by the size of the input audio, which is mapped to a
@@ -252,13 +250,10 @@ class OpenAISpeechToText(OpenAIServing):
250 request_metadata: RequestResponseMetadata,
251 audio_duration_s: float,
252 chunk_object_type: Literal["translation.chunk", "transcription.chunk"],
255 - response_stream_choice_class: Union[
256 - type[TranscriptionResponseStreamChoice],
257 - type[TranslationResponseStreamChoice],
258 - ],
259 - stream_response_class: Union[
260 - type[TranscriptionStreamResponse], type[TranslationStreamResponse]
261 - ],
253 + response_stream_choice_class: type[TranscriptionResponseStreamChoice]
254 + | type[TranslationResponseStreamChoice],
255 + stream_response_class: type[TranscriptionStreamResponse]
256 + | type[TranslationStreamResponse],
257 ) -> AsyncGenerator[str, None]:
258 created_time = int(time.time())
259 model_name = request.model
vllm/entrypoints/openai/tool_parsers/abstract_tool_parser.py
+6 -7
@@ -2,9 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import os
5 -from collections.abc import Sequence
5 +from collections.abc import Callable, Sequence
6 from functools import cached_property
7 -from typing import Callable, Optional, Union
7
8 from vllm.entrypoints.openai.protocol import (
9 ChatCompletionRequest,
@@ -69,7 +68,7 @@ class ToolParser:
68 current_token_ids: Sequence[int],
69 delta_token_ids: Sequence[int],
70 request: ChatCompletionRequest,
72 - ) -> Union[DeltaMessage, None]:
71 + ) -> DeltaMessage | None:
72 """
73 Instance method that should be implemented for extracting tool calls
74 from an incomplete response; for use when handling tool calls and
@@ -101,7 +100,7 @@ class ToolParserManager:
100 def _register_module(
101 cls,
102 module: type,
104 - module_name: Optional[Union[str, list[str]]] = None,
103 + module_name: str | list[str] | None = None,
104 force: bool = True,
105 ) -> None:
106 if not issubclass(module, ToolParser):
@@ -123,10 +122,10 @@ class ToolParserManager:
122 @classmethod
123 def register_module(
124 cls,
126 - name: Optional[Union[str, list[str]]] = None,
125 + name: str | list[str] | None = None,
126 force: bool = True,
128 - module: Union[type, None] = None,
129 - ) -> Union[type, Callable]:
127 + module: type | None = None,
128 + ) -> type | Callable:
129 """
130 Register module with the given name or name list. it can be used as a
131 decoder(with module as None) or normal function(with module as not
vllm/entrypoints/openai/tool_parsers/deepseekv31_tool_parser.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Union
5
6 import regex as re
7
@@ -129,7 +128,7 @@ class DeepSeekV31ToolParser(ToolParser):
128 current_token_ids: Sequence[int],
129 delta_token_ids: Sequence[int],
130 request: ChatCompletionRequest,
132 - ) -> Union[DeltaMessage, None]:
131 + ) -> DeltaMessage | None:
132 logger.debug("delta_text: %s", delta_text)
133 logger.debug("delta_token_ids: %s", delta_token_ids)
134 # check to see if we should be streaming a tool call - is there a
@@ -272,7 +271,7 @@ class DeepSeekV31ToolParser(ToolParser):
271 if not self.current_tool_name_sent:
272 if current_tool_call is None:
273 return None
275 - function_name: Union[str, None] = current_tool_call.get("name")
274 + function_name: str | None = current_tool_call.get("name")
275 if function_name:
276 self.current_tool_name_sent = True
277 return DeltaMessage(
vllm/entrypoints/openai/tool_parsers/deepseekv3_tool_parser.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Union
5
6 import regex as re
7
@@ -129,7 +128,7 @@ class DeepSeekV3ToolParser(ToolParser):
128 current_token_ids: Sequence[int],
129 delta_token_ids: Sequence[int],
130 request: ChatCompletionRequest,
132 - ) -> Union[DeltaMessage, None]:
131 + ) -> DeltaMessage | None:
132 logger.debug("delta_text: %s", delta_text)
133 logger.debug("delta_token_ids: %s", delta_token_ids)
134 # check to see if we should be streaming a tool call - is there a
@@ -272,7 +271,7 @@ class DeepSeekV3ToolParser(ToolParser):
271 if not self.current_tool_name_sent:
272 if current_tool_call is None:
273 return None
275 - function_name: Union[str, None] = current_tool_call.get("name")
274 + function_name: str | None = current_tool_call.get("name")
275 if function_name:
276 self.current_tool_name_sent = True
277 return DeltaMessage(
vllm/entrypoints/openai/tool_parsers/glm4_moe_tool_parser.py
+3 -3
@@ -4,7 +4,7 @@
4 import ast
5 import json
6 from collections.abc import Sequence
7 -from typing import Any, Optional, Union
7 +from typing import Any
8
9 import regex as re
10
@@ -66,7 +66,7 @@ class Glm4MoeModelToolParser(ToolParser):
66 def _is_string_type(
67 tool_name: str,
68 arg_name: str,
69 - tools: Optional[list[ChatCompletionToolsParam]],
69 + tools: list[ChatCompletionToolsParam] | None,
70 ) -> bool:
71 if tools is None:
72 return False
@@ -144,7 +144,7 @@ class Glm4MoeModelToolParser(ToolParser):
144 current_token_ids: Sequence[int],
145 delta_token_ids: Sequence[int],
146 request: ChatCompletionRequest,
147 - ) -> Union[DeltaMessage, None]:
147 + ) -> DeltaMessage | None:
148 self._buffer += delta_text
149 cur_text = self._buffer
150 start_idx = cur_text.find(self.tool_call_start_token)
vllm/entrypoints/openai/tool_parsers/granite_20b_fc_tool_parser.py
+1 -2
@@ -4,7 +4,6 @@
4 import json
5 from collections.abc import Sequence
6 from json import JSONDecoder
7 -from typing import Union
7
8 import partial_json_parser
9 import regex as re
@@ -121,7 +120,7 @@ class Granite20bFCToolParser(ToolParser):
120 current_token_ids: Sequence[int],
121 delta_token_ids: Sequence[int],
122 request: ChatCompletionRequest,
124 - ) -> Union[DeltaMessage, None]:
123 + ) -> DeltaMessage | None:
124 if len(current_text) < len(self.bot_token) and self.bot_token.startswith(
125 current_text
126 ):
vllm/entrypoints/openai/tool_parsers/granite_tool_parser.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import json
5 from collections.abc import Sequence
6 -from typing import Union
6
7 import partial_json_parser
8 from partial_json_parser.core.options import Allow
@@ -108,7 +107,7 @@ class GraniteToolParser(ToolParser):
107 current_token_ids: Sequence[int],
108 delta_token_ids: Sequence[int],
109 request: ChatCompletionRequest,
111 - ) -> Union[DeltaMessage, None]:
110 + ) -> DeltaMessage | None:
111 start_idx = consume_space(0, current_text)
112 if current_text[start_idx:].startswith(self.bot_token):
113 start_idx = consume_space(start_idx + len(self.bot_token), current_text)
vllm/entrypoints/openai/tool_parsers/hermes_tool_parser.py
+2 -3
@@ -3,7 +3,6 @@
3
4 import json
5 from collections.abc import Sequence
6 -from typing import Union
6
7 import partial_json_parser
8 import regex as re
@@ -181,7 +180,7 @@ class Hermes2ProToolParser(ToolParser):
180 current_token_ids: Sequence[int],
181 delta_token_ids: Sequence[int],
182 request: ChatCompletionRequest,
184 - ) -> Union[DeltaMessage, None]:
183 + ) -> DeltaMessage | None:
184 # 1. All tokens are parsed based on _text, not token_ids.
185 # 2. All incoming text data is processed by the tool_call_delta_buffer
186 # function for buffering before being used for parsing.
@@ -333,7 +332,7 @@ class Hermes2ProToolParser(ToolParser):
332 if not self.current_tool_name_sent:
333 if current_tool_call is None:
334 return None
336 - function_name: Union[str, None] = current_tool_call.get("name")
335 + function_name: str | None = current_tool_call.get("name")
336 if function_name:
337 self.current_tool_name_sent = True
338 return DeltaMessage(
vllm/entrypoints/openai/tool_parsers/hunyuan_a13b_tool_parser.py
+3 -3
@@ -4,7 +4,7 @@
4
5 import json
6 from collections.abc import Sequence
7 -from typing import Any, Optional, Union
7 +from typing import Any
8
9 import regex as re
10
@@ -73,7 +73,7 @@ class HunyuanA13BToolParser(ToolParser):
73
74 def preprocess_model_output(
75 self, model_output: str
76 - ) -> tuple[Optional[str], Optional[str]]:
76 + ) -> tuple[str | None, str | None]:
77 # find the location tool call
78 for match in self.answer_tool_calls_pattern.finditer(model_output):
79 start, end = match.span()
@@ -176,7 +176,7 @@ class HunyuanA13BToolParser(ToolParser):
176 current_token_ids: Sequence[int],
177 delta_token_ids: Sequence[int],
178 request: ChatCompletionRequest,
179 - ) -> Union[DeltaMessage, None]:
179 + ) -> DeltaMessage | None:
180 """
181 Extract tool calls for streaming mode.
182 """
vllm/entrypoints/openai/tool_parsers/internlm2_tool_parser.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import json
5 from collections.abc import Sequence
6 -from typing import Union
6
7 import partial_json_parser
8 from partial_json_parser.core.options import Allow
@@ -59,7 +58,7 @@ class Internlm2ToolParser(ToolParser):
58 current_token_ids: Sequence[int],
59 delta_token_ids: Sequence[int],
60 request: ChatCompletionRequest,
62 - ) -> Union[DeltaMessage, None]:
61 + ) -> DeltaMessage | None:
62 if "<|action_start|>" not in current_text:
63 self.position = len(current_text)
64 return DeltaMessage(content=delta_text)
vllm/entrypoints/openai/tool_parsers/jamba_tool_parser.py
+2 -3
@@ -3,7 +3,6 @@
3
4 import json
5 from collections.abc import Sequence
6 -from typing import Union
6
7 import partial_json_parser
8 import regex as re
@@ -129,7 +128,7 @@ class JambaToolParser(ToolParser):
128 current_token_ids: Sequence[int],
129 delta_token_ids: Sequence[int],
130 request: ChatCompletionRequest,
132 - ) -> Union[DeltaMessage, None]:
131 + ) -> DeltaMessage | None:
132 # if the tool call token is not in the tokens generated so far, append
133 # output to contents since it's not a tool
134 if self.tool_calls_start_token not in current_text:
@@ -190,7 +189,7 @@ class JambaToolParser(ToolParser):
189 # auto-generated due to JSON completions, but wasn't
190 # streamed to the client yet.
191 if self.current_tool_id >= 0:
193 - diff: Union[str, None] = current_tool_call.get("arguments")
192 + diff: str | None = current_tool_call.get("arguments")
193
194 if diff:
195 diff = json.dumps(diff, ensure_ascii=False).replace(
vllm/entrypoints/openai/tool_parsers/kimi_k2_tool_parser.py
+2 -3
@@ -3,7 +3,6 @@
3 # code modified from deepseekv3_tool_parser.py
4
5 from collections.abc import Sequence
6 -from typing import Union
6
7 import regex as re
8
@@ -131,7 +130,7 @@ class KimiK2ToolParser(ToolParser):
130 current_token_ids: Sequence[int],
131 delta_token_ids: Sequence[int],
132 request: ChatCompletionRequest,
134 - ) -> Union[DeltaMessage, None]:
133 + ) -> DeltaMessage | None:
134 logger.debug("delta_text: %s", delta_text)
135 logger.debug("delta_token_ids: %s", delta_token_ids)
136 # check to see if we should be streaming a tool call - is there a
@@ -278,7 +277,7 @@ class KimiK2ToolParser(ToolParser):
277 if not self.current_tool_name_sent:
278 if current_tool_call is None:
279 return None
281 - function_name: Union[str, None] = current_tool_call.get("name")
280 + function_name: str | None = current_tool_call.get("name")
281 tool_id = current_tool_call.get("id")
282 if function_name:
283 self.current_tool_name_sent = True
vllm/entrypoints/openai/tool_parsers/llama4_pythonic_tool_parser.py
+4 -4
@@ -3,7 +3,7 @@
3 import ast
4 import json
5 from collections.abc import Sequence
6 -from typing import Any, Union
6 +from typing import Any
7
8 import regex as re
9 from transformers import PreTrainedTokenizerBase
@@ -128,7 +128,7 @@ class Llama4PythonicToolParser(ToolParser):
128 current_token_ids: Sequence[int],
129 delta_token_ids: Sequence[int],
130 request: ChatCompletionRequest,
131 - ) -> Union[DeltaMessage, None]:
131 + ) -> DeltaMessage | None:
132 if not current_text.startswith("[") and not current_text.startswith(
133 "<|python_start|>"
134 ):
@@ -245,7 +245,7 @@ def _handle_single_tool(call: ast.Call) -> ToolCall:
245 )
246
247
248 -def _make_valid_python(text: str) -> Union[tuple[str, str], None]:
248 +def _make_valid_python(text: str) -> tuple[str, str] | None:
249 bracket_stack = []
250 for index, char in enumerate(text):
251 if char in {"[", "(", "{"}:
@@ -317,7 +317,7 @@ def _make_valid_python(text: str) -> Union[tuple[str, str], None]:
317
318 def _compute_tool_delta(
319 previously_sent_args: str, new_call: ToolCall, index: int, withheld_suffix: str
320 -) -> Union[DeltaToolCall, None]:
320 +) -> DeltaToolCall | None:
321 new_call_args = new_call.function.arguments
322 if withheld_suffix:
323 assert new_call_args.endswith(withheld_suffix)
vllm/entrypoints/openai/tool_parsers/llama_tool_parser.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import json
5 from collections.abc import Sequence
6 -from typing import Union
6
7 import partial_json_parser
8 import regex as re
@@ -134,7 +133,7 @@ class Llama3JsonToolParser(ToolParser):
133 current_token_ids: Sequence[int],
134 delta_token_ids: Sequence[int],
135 request: ChatCompletionRequest,
137 - ) -> Union[DeltaMessage, None]:
136 + ) -> DeltaMessage | None:
137 if not (
138 current_text.startswith(self.bot_token) or current_text.startswith("{")
139 ):
vllm/entrypoints/openai/tool_parsers/minimax_tool_parser.py
+7 -7
@@ -3,7 +3,7 @@
3
4 import json
5 from collections.abc import Sequence
6 -from typing import Any, Optional, Union
6 +from typing import Any
7
8 import regex as re
9
@@ -509,7 +509,7 @@ class MinimaxToolParser(ToolParser):
509
510 def _get_current_tool_content(
511 self, text: str, tool_index: int
512 - ) -> tuple[Optional[str], Optional[str]]:
512 + ) -> tuple[str | None, str | None]:
513 """
514 Get the content of a specific tool by index.
515
@@ -545,7 +545,7 @@ class MinimaxToolParser(ToolParser):
545
546 def _handle_tool_name_streaming(
547 self, tool_content: str, tool_count: int
548 - ) -> Union[DeltaMessage, None]:
548 + ) -> DeltaMessage | None:
549 """
550 Handle streaming of tool names.
551
@@ -595,7 +595,7 @@ class MinimaxToolParser(ToolParser):
595
596 def _handle_tool_args_streaming(
597 self, tool_content: str, tool_count: int
598 - ) -> Union[DeltaMessage, None]:
598 + ) -> DeltaMessage | None:
599 """
600 Handle streaming of tool arguments.
601
@@ -702,7 +702,7 @@ class MinimaxToolParser(ToolParser):
702 current_token_ids: Sequence[int],
703 delta_token_ids: Sequence[int],
704 request: ChatCompletionRequest,
705 - ) -> Union[DeltaMessage, None]:
705 + ) -> DeltaMessage | None:
706 self._update_thinking_state(current_text)
707
708 if self.in_thinking_tag:
@@ -776,7 +776,7 @@ class MinimaxToolParser(ToolParser):
776 )
777 return None
778
779 - def _find_tool_start_outside_thinking(self, current_text: str) -> Optional[int]:
779 + def _find_tool_start_outside_thinking(self, current_text: str) -> int | None:
780 """
781 Find the start position of tool calls outside of thinking tags.
782
@@ -809,7 +809,7 @@ class MinimaxToolParser(ToolParser):
809
810 def _extract_content_before_tools(
811 self, current_text: str, delta_text: str, tool_start: int
812 - ) -> Optional[str]:
812 + ) -> str | None:
813 """
814 Extract content that appears before tool calls.
815
vllm/entrypoints/openai/tool_parsers/mistral_tool_parser.py
+2 -3
@@ -5,7 +5,6 @@ import json
5 from collections.abc import Sequence
6 from random import choices
7 from string import ascii_letters, digits
8 -from typing import Union
8
9 import partial_json_parser
10 import regex as re
@@ -194,7 +193,7 @@ class MistralToolParser(ToolParser):
193 current_token_ids: Sequence[int],
194 delta_token_ids: Sequence[int],
195 request: ChatCompletionRequest,
197 - ) -> Union[DeltaMessage, None]:
196 + ) -> DeltaMessage | None:
197 # if the tool call token is not in the tokens generated so far, append
198 # output to contents since it's not a tool
199 if self.bot_token not in current_text:
@@ -252,7 +251,7 @@ class MistralToolParser(ToolParser):
251 # auto-generated due to JSON completions, but wasn't
252 # streamed to the client yet.
253 if self.current_tool_id >= 0:
255 - diff: Union[str, None] = current_tool_call.get("arguments")
254 + diff: str | None = current_tool_call.get("arguments")
255
256 if diff:
257 diff = json.dumps(diff, ensure_ascii=False).replace(
vllm/entrypoints/openai/tool_parsers/openai_tool_parser.py
+3 -3
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import json
4 from collections.abc import Sequence
5 from typing import TYPE_CHECKING
@@ -22,13 +20,15 @@ from vllm.logger import init_logger
20
21 if TYPE_CHECKING:
22 from vllm.transformers_utils.tokenizer import AnyTokenizer
23 +else:
24 + AnyTokenizer = object
25
26 logger = init_logger(__name__)
27
28
29 @ToolParserManager.register_module("openai")
30 class OpenAIToolParser(ToolParser):
31 - def __init__(self, tokenizer: AnyTokenizer):
31 + def __init__(self, tokenizer: "AnyTokenizer"):
32 super().__init__(tokenizer)
33
34 def extract_tool_calls(
vllm/entrypoints/openai/tool_parsers/phi4mini_tool_parser.py
+2 -2
@@ -3,7 +3,7 @@
3
4 import json
5 from collections.abc import Sequence
6 -from typing import Any, Optional
6 +from typing import Any
7
8 import regex as re
9 from transformers import PreTrainedTokenizerBase
@@ -118,5 +118,5 @@ class Phi4MiniJsonToolParser(ToolParser):
118 current_token_ids: Sequence[int],
119 delta_token_ids: Sequence[int],
120 request: ChatCompletionRequest,
121 - ) -> Optional[DeltaMessage]:
121 + ) -> DeltaMessage | None:
122 return None
vllm/entrypoints/openai/tool_parsers/pythonic_tool_parser.py
+4 -4
@@ -4,7 +4,7 @@
4 import ast
5 import json
6 from collections.abc import Sequence
7 -from typing import Any, Union
7 +from typing import Any
8
9 import regex as re
10 from transformers import PreTrainedTokenizerBase
@@ -124,7 +124,7 @@ class PythonicToolParser(ToolParser):
124 current_token_ids: Sequence[int],
125 delta_token_ids: Sequence[int],
126 request: ChatCompletionRequest,
127 - ) -> Union[DeltaMessage, None]:
127 + ) -> DeltaMessage | None:
128 if not current_text.startswith("["):
129 return DeltaMessage(content=delta_text)
130
@@ -236,7 +236,7 @@ def _handle_single_tool(call: ast.Call) -> ToolCall:
236 )
237
238
239 -def _make_valid_python(text: str) -> Union[tuple[str, str], None]:
239 +def _make_valid_python(text: str) -> tuple[str, str] | None:
240 bracket_stack = []
241 for index, char in enumerate(text):
242 if char in {"[", "(", "{"}:
@@ -308,7 +308,7 @@ def _make_valid_python(text: str) -> Union[tuple[str, str], None]:
308
309 def _compute_tool_delta(
310 previously_sent_args: str, new_call: ToolCall, index: int, withheld_suffix: str
311 -) -> Union[DeltaToolCall, None]:
311 +) -> DeltaToolCall | None:
312 new_call_args = new_call.function.arguments
313 if withheld_suffix:
314 assert new_call_args.endswith(withheld_suffix)
vllm/entrypoints/openai/tool_parsers/qwen3coder_tool_parser.py
+6 -6
@@ -4,7 +4,7 @@ import ast
4 import json
5 import uuid
6 from collections.abc import Sequence
7 -from typing import Any, Optional, Union
7 +from typing import Any
8
9 import regex as re
10
@@ -36,7 +36,7 @@ class Qwen3CoderToolParser(ToolParser):
36 self.current_tool_name_sent: bool = False
37 self.prev_tool_call_arr: list[dict] = []
38 # Override base class type - we use string IDs for tool calls
39 - self.current_tool_id: Optional[str] = None # type: ignore
39 + self.current_tool_id: str | None = None # type: ignore
40 self.streamed_args_for_tool: list[str] = []
41
42 # Sentinel tokens for streaming mode
@@ -110,7 +110,7 @@ class Qwen3CoderToolParser(ToolParser):
110 self.streaming_request = None
111
112 def _get_arguments_config(
113 - self, func_name: str, tools: Optional[list[ChatCompletionToolsParam]]
113 + self, func_name: str, tools: list[ChatCompletionToolsParam] | None
114 ) -> dict:
115 """Extract argument configuration for a function."""
116 if tools is None:
@@ -240,8 +240,8 @@ class Qwen3CoderToolParser(ToolParser):
240 return param_value
241
242 def _parse_xml_function_call(
243 - self, function_call_str: str, tools: Optional[list[ChatCompletionToolsParam]]
244 - ) -> Optional[ToolCall]:
243 + self, function_call_str: str, tools: list[ChatCompletionToolsParam] | None
244 + ) -> ToolCall | None:
245 # Extract function name
246 end_index = function_call_str.index(">")
247 function_name = function_call_str[:end_index]
@@ -349,7 +349,7 @@ class Qwen3CoderToolParser(ToolParser):
349 current_token_ids: Sequence[int],
350 delta_token_ids: Sequence[int],
351 request: ChatCompletionRequest,
352 - ) -> Union[DeltaMessage, None]:
352 + ) -> DeltaMessage | None:
353 # Store request for type conversion
354 if not previous_text:
355 self._reset_streaming_state()
vllm/entrypoints/openai/tool_parsers/qwen3xml_tool_parser.py
+8 -10
@@ -4,7 +4,7 @@ import ast
4 import json
5 import uuid
6 from collections.abc import Sequence
7 -from typing import Any, Optional, Union
7 +from typing import Any
8 from xml.parsers.expat import ParserCreate
9
10 import regex as re
@@ -39,7 +39,7 @@ class StreamingXMLToolCallParser:
39 self.reset_streaming_state()
40
41 # Tool configuration information
42 - self.tools: Union[list[ChatCompletionToolsParam], None] = None
42 + self.tools: list[ChatCompletionToolsParam] | None = None
43 self.tool_call_start_token: str = "<tool_call>"
44 self.tool_call_end_token: str = "</tool_call>"
45 self.function_start_token: str = "<function="
@@ -341,7 +341,7 @@ class StreamingXMLToolCallParser:
341 # Skip blank content
342 return not element
343
344 - def _find_next_complete_element(self, start_pos: int) -> tuple[Optional[str], int]:
344 + def _find_next_complete_element(self, start_pos: int) -> tuple[str | None, int]:
345 """
346 Find next complete XML element from specified position
347
@@ -584,7 +584,7 @@ class StreamingXMLToolCallParser:
584 """Emit Delta response (streaming output)"""
585 self.deltas.append(delta)
586
587 - def _auto_close_open_parameter_if_needed(self, incoming_tag: Optional[str] = None):
587 + def _auto_close_open_parameter_if_needed(self, incoming_tag: str | None = None):
588 """Before starting to process new elements,
589 if there are unclosed tags from before,
590 automatically complete their endings to the parser.
@@ -953,7 +953,7 @@ class StreamingXMLToolCallParser:
953 self.parser.EndElementHandler = self._end_element
954 self.parser.CharacterDataHandler = self._char_data
955
956 - def set_tools(self, tools: Union[list[ChatCompletionToolsParam], None]):
956 + def set_tools(self, tools: list[ChatCompletionToolsParam] | None):
957 """Set tool configuration information"""
958 self.tools = tools
959
@@ -961,7 +961,7 @@ class StreamingXMLToolCallParser:
961 """Generate unique call ID"""
962 return f"call_{uuid.uuid4().hex[:24]}"
963
964 - def _extract_function_name(self, name: str, attrs: dict[str, str]) -> Optional[str]:
964 + def _extract_function_name(self, name: str, attrs: dict[str, str]) -> str | None:
965 """Extract function name from various formats"""
966 if attrs and "name" in attrs:
967 return attrs["name"]
@@ -973,9 +973,7 @@ class StreamingXMLToolCallParser:
973
974 return None
975
976 - def _extract_parameter_name(
977 - self, name: str, attrs: dict[str, str]
978 - ) -> Optional[str]:
976 + def _extract_parameter_name(self, name: str, attrs: dict[str, str]) -> str | None:
977 """Extract parameter name from various formats"""
978 if attrs and "name" in attrs:
979 return attrs["name"]
@@ -1218,7 +1216,7 @@ class Qwen3XMLToolParser(ToolParser):
1216 current_token_ids: Sequence[int],
1217 delta_token_ids: Sequence[int],
1218 request: ChatCompletionRequest,
1221 - ) -> Union[DeltaMessage, None]:
1219 + ) -> DeltaMessage | None:
1220 if not previous_text:
1221 self.parser.reset_streaming_state()
1222 if request:
vllm/entrypoints/openai/tool_parsers/seed_oss_tool_parser.py
+4 -4
@@ -7,7 +7,7 @@ import ast
7 import json
8 import uuid
9 from collections.abc import Sequence
10 -from typing import Any, Optional, Union
10 +from typing import Any
11
12 import regex as re
13
@@ -109,8 +109,8 @@ class SeedOssToolParser(ToolParser):
109 self.json_closed = False
110
111 def _parse_xml_function_call(
112 - self, function_call_str: str, tools: Optional[list[ChatCompletionToolsParam]]
113 - ) -> Optional[ToolCall]:
112 + self, function_call_str: str, tools: list[ChatCompletionToolsParam] | None
113 + ) -> ToolCall | None:
114 def get_arguments_config(func_name: str) -> dict:
115 if tools is None:
116 return {}
@@ -357,7 +357,7 @@ class SeedOssToolParser(ToolParser):
357 current_token_ids: Sequence[int],
358 delta_token_ids: Sequence[int],
359 request: ChatCompletionRequest,
360 - ) -> Union[DeltaMessage, None]:
360 + ) -> DeltaMessage | None:
361 # If no delta text, return None unless
362 # it's an EOS token after tool calls
363 if not delta_text:
vllm/entrypoints/openai/tool_parsers/step3_tool_parser.py
+3 -3
@@ -4,7 +4,7 @@
4 import contextlib
5 import json
6 from collections.abc import Sequence
7 -from typing import Any, Optional, Union
7 +from typing import Any
8
9 import regex as re
10
@@ -58,7 +58,7 @@ class Step3ToolParser(ToolParser):
58 @staticmethod
59 def _parse_steptml_invoke(
60 action_text: str,
61 - ) -> tuple[Optional[str], Optional[dict[str, str]]]:
61 + ) -> tuple[str | None, dict[str, str] | None]:
62 func_name_match = re.search(r'<steptml:invoke name="([^"]+)">', action_text)
63 if not func_name_match:
64 return None, None
@@ -117,7 +117,7 @@ class Step3ToolParser(ToolParser):
117 current_token_ids: Sequence[int],
118 delta_token_ids: Sequence[int],
119 request: ChatCompletionRequest,
120 - ) -> Union[DeltaMessage, None]:
120 + ) -> DeltaMessage | None:
121 # The main loop processes the stream from the last known position.
122 while True:
123 if self.position >= len(current_text):
vllm/entrypoints/renderer.py
+38 -43
@@ -5,7 +5,7 @@ import asyncio
5 import io
6 from abc import ABC, abstractmethod
7 from dataclasses import dataclass
8 -from typing import Annotated, Optional, Union
8 +from typing import Annotated
9
10 import pybase64
11 import torch
@@ -24,25 +24,25 @@ from vllm.utils import AsyncMicrobatchTokenizer
24 class RenderConfig:
25 """Configuration to control how prompts are prepared."""
26
27 - max_length: Optional[int] = None
27 + max_length: int | None = None
28 """Maximum allowable total input token length. If provided,
29 token inputs longer than this raise ``ValueError``."""
30
31 - truncate_prompt_tokens: Optional[int] = None
31 + truncate_prompt_tokens: int | None = None
32 """Number of tokens to keep. ``None`` means no truncation.
33 ``0`` yields an empty list (and skips embeds).
34 ``-1`` maps to ``model_config.max_model_len``."""
35
36 - add_special_tokens: Optional[bool] = True
36 + add_special_tokens: bool | None = True
37 """Whether to add model-specific special tokens during tokenization."""
38
39 - cache_salt: Optional[str] = None
39 + cache_salt: str | None = None
40 """String to disambiguate prefix cache entries."""
41
42 - needs_detokenization: Optional[bool] = False
42 + needs_detokenization: bool | None = False
43 """If True, detokenize IDs back to text for inclusion in outputs."""
44
45 - def verify_truncate_prompt_tokens(self, model_config: ModelConfig) -> Optional[int]:
45 + def verify_truncate_prompt_tokens(self, model_config: ModelConfig) -> int | None:
46 """Validate and normalize `truncate_prompt_tokens` parameter."""
47 truncate_prompt_tokens = self.truncate_prompt_tokens
48 if truncate_prompt_tokens is None:
@@ -85,7 +85,7 @@ class BaseRenderer(ABC):
85 def __init__(
86 self,
87 model_config: ModelConfig,
88 - tokenizer: Optional[AnyTokenizer] = None,
88 + tokenizer: AnyTokenizer | None = None,
89 ):
90 super().__init__()
91 self.model_config = model_config
@@ -95,7 +95,7 @@ class BaseRenderer(ABC):
95 async def render_prompt(
96 self,
97 *,
98 - prompt_or_prompts: Union[str, list[str], list[int], list[list[int]]],
98 + prompt_or_prompts: str | list[str] | list[int] | list[list[int]],
99 config: RenderConfig,
100 ) -> list[EngineTokensPrompt]:
101 """
@@ -126,12 +126,10 @@ class BaseRenderer(ABC):
126 async def render_prompt_and_embeds(
127 self,
128 *,
129 - prompt_or_prompts: Optional[
130 - Union[str, list[str], list[int], list[list[int]]]
131 - ] = None,
132 - prompt_embeds: Optional[Union[bytes, list[bytes]]] = None,
129 + prompt_or_prompts: str | list[str] | list[int] | list[list[int]] | None = None,
130 + prompt_embeds: bytes | list[bytes] | None = None,
131 config: RenderConfig,
134 - ) -> list[Union[EngineTokensPrompt, EngineEmbedsPrompt]]:
132 + ) -> list[EngineTokensPrompt | EngineEmbedsPrompt]:
133 """
134 Convert text/token and/or base64-encoded embeddings inputs into
135 engine-ready prompt objects using a unified RenderConfig.
@@ -161,9 +159,9 @@ class BaseRenderer(ABC):
159 @classmethod
160 def load_prompt_embeds(
161 cls,
164 - prompt_embeds: Union[bytes, list[bytes]],
165 - truncate_prompt_tokens: Optional[Annotated[int, Field(ge=0)]] = None,
166 - cache_salt: Optional[str] = None,
162 + prompt_embeds: bytes | list[bytes],
163 + truncate_prompt_tokens: Annotated[int, Field(ge=0)] | None = None,
164 + cache_salt: str | None = None,
165 ) -> list[EngineEmbedsPrompt]:
166 """Load and validate base64-encoded embeddings into prompt objects."""
167
@@ -199,19 +197,18 @@ class CompletionRenderer(BaseRenderer):
197 def __init__(
198 self,
199 model_config: ModelConfig,
202 - tokenizer: Optional[AnyTokenizer] = None,
203 - async_tokenizer_pool: Optional[
204 - dict[AnyTokenizer, AsyncMicrobatchTokenizer]
205 - ] = None,
200 + tokenizer: AnyTokenizer | None = None,
201 + async_tokenizer_pool: dict[AnyTokenizer, AsyncMicrobatchTokenizer]
202 + | None = None,
203 ):
204 super().__init__(model_config, tokenizer)
205 self.async_tokenizer_pool = async_tokenizer_pool
209 - self.async_tokenizer: Optional[AsyncMicrobatchTokenizer] = None
206 + self.async_tokenizer: AsyncMicrobatchTokenizer | None = None
207
208 async def render_prompt(
209 self,
210 *,
214 - prompt_or_prompts: Union[str, list[str], list[int], list[list[int]]],
211 + prompt_or_prompts: str | list[str] | list[int] | list[list[int]],
212 config: RenderConfig,
213 ) -> list[EngineTokensPrompt]:
214 """Implementation of prompt rendering for completion-style requests.
@@ -237,12 +234,10 @@ class CompletionRenderer(BaseRenderer):
234 async def render_prompt_and_embeds(
235 self,
236 *,
240 - prompt_or_prompts: Optional[
241 - Union[str, list[str], list[int], list[list[int]]]
242 - ] = None,
243 - prompt_embeds: Optional[Union[bytes, list[bytes]]] = None,
237 + prompt_or_prompts: str | list[str] | list[int] | list[list[int]] | None = None,
238 + prompt_embeds: bytes | list[bytes] | None = None,
239 config: RenderConfig,
245 - ) -> list[Union[EngineTokensPrompt, EngineEmbedsPrompt]]:
240 + ) -> list[EngineTokensPrompt | EngineEmbedsPrompt]:
241 """
242 Render text/token prompts and/or precomputed embedding prompts. At
243 least one of `prompt_or_prompts` or `prompt_embeds` must be provided.
@@ -251,7 +246,7 @@ class CompletionRenderer(BaseRenderer):
246 if truncate_prompt_tokens == 0:
247 return []
248
254 - rendered: list[Union[EngineTokensPrompt, EngineEmbedsPrompt]] = []
249 + rendered: list[EngineTokensPrompt | EngineEmbedsPrompt] = []
250
251 if prompt_embeds is not None:
252 rendered.extend(
@@ -271,7 +266,7 @@ class CompletionRenderer(BaseRenderer):
266 return rendered
267
268 def _maybe_apply_truncation(
274 - self, token_ids: list[int], truncate_prompt_tokens: Optional[int]
269 + self, token_ids: list[int], truncate_prompt_tokens: int | None
270 ) -> list[int]:
271 """Apply truncation to token sequence."""
272 if truncate_prompt_tokens is None:
@@ -283,9 +278,9 @@ class CompletionRenderer(BaseRenderer):
278
279 async def _create_prompt(
280 self,
286 - prompt_input: Union[EngineTextPrompt, EngineTokensPrompt],
281 + prompt_input: EngineTextPrompt | EngineTokensPrompt,
282 config: RenderConfig,
288 - truncate_prompt_tokens: Optional[int],
283 + truncate_prompt_tokens: int | None,
284 ) -> EngineTokensPrompt:
285 prompt, prompt_token_ids, _ = get_prompt_components(prompt_input)
286
@@ -315,10 +310,10 @@ class CompletionRenderer(BaseRenderer):
310 async def _create_prompt_from_text(
311 self,
312 text: str,
318 - max_length: Optional[int],
319 - truncate_prompt_tokens: Optional[int],
320 - add_special_tokens: Optional[bool],
321 - cache_salt: Optional[str],
313 + max_length: int | None,
314 + truncate_prompt_tokens: int | None,
315 + add_special_tokens: bool | None,
316 + cache_salt: str | None,
317 ) -> EngineTokensPrompt:
318 """Tokenize text input asynchronously."""
319 async_tokenizer = self._get_async_tokenizer()
@@ -348,10 +343,10 @@ class CompletionRenderer(BaseRenderer):
343 async def _create_prompt_from_token_ids(
344 self,
345 token_ids: list[int],
351 - max_length: Optional[int],
352 - truncate_prompt_tokens: Optional[int],
353 - cache_salt: Optional[str],
354 - needs_detokenization: Optional[bool] = False,
346 + max_length: int | None,
347 + truncate_prompt_tokens: int | None,
348 + cache_salt: str | None,
349 + needs_detokenization: bool | None = False,
350 ) -> EngineTokensPrompt:
351 """Optionally detokenize token IDs and build a tokens prompt."""
352 token_ids = self._maybe_apply_truncation(token_ids, truncate_prompt_tokens)
@@ -391,9 +386,9 @@ class CompletionRenderer(BaseRenderer):
386 def _create_tokens_prompt(
387 self,
388 token_ids: list[int],
394 - max_length: Optional[int] = None,
395 - cache_salt: Optional[str] = None,
396 - prompt: Optional[str] = None,
389 + max_length: int | None = None,
390 + cache_salt: str | None = None,
391 + prompt: str | None = None,
392 ) -> EngineTokensPrompt:
393 """Create validated EngineTokensPrompt."""
394 if max_length is not None and len(token_ids) > max_length:
vllm/entrypoints/score_utils.py
+17 -17
@@ -1,9 +1,9 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, Optional, Union, cast
3 +from typing import Any, TypeAlias, cast
4
5 from torch.nn import CosineSimilarity
6 -from typing_extensions import Required, TypeAlias, TypedDict
6 +from typing_extensions import Required, TypedDict
7
8 from vllm.config import ModelConfig
9 from vllm.entrypoints.chat_utils import (
@@ -25,9 +25,9 @@ from vllm.transformers_utils.tokenizer import (
25 PreTrainedTokenizerFast,
26 )
27
28 -ScoreContentPartParam: TypeAlias = Union[
29 - ChatCompletionContentPartImageParam, ChatCompletionContentPartImageEmbedsParam
30 -]
28 +ScoreContentPartParam: TypeAlias = (
29 + ChatCompletionContentPartImageParam | ChatCompletionContentPartImageEmbedsParam
30 +)
31
32
33 class ScoreMultiModalParam(TypedDict, total=False):
@@ -45,12 +45,12 @@ class ScoreMultiModalParam(TypedDict, total=False):
45
46
47 def _cosine_similarity(
48 - tokenizer: Union[PreTrainedTokenizer, PreTrainedTokenizerFast],
48 + tokenizer: PreTrainedTokenizer | PreTrainedTokenizerFast,
49 embed_1: list[PoolingRequestOutput],
50 embed_2: list[PoolingRequestOutput],
51 ) -> list[PoolingRequestOutput]:
52 scorer = CosineSimilarity(0)
53 - scores: Union[list[PoolingRequestOutput]] = []
53 + scores: list[PoolingRequestOutput] = []
54
55 for emb_1, emb_2 in zip(embed_1, embed_2):
56 pair_score = scorer(emb_1.outputs.data, emb_2.outputs.data)
@@ -74,8 +74,8 @@ def _cosine_similarity(
74
75
76 def _validate_score_input_lens(
77 - data_1: Union[list[str], list[ScoreContentPartParam]],
78 - data_2: Union[list[str], list[ScoreContentPartParam]],
77 + data_1: list[str] | list[ScoreContentPartParam],
78 + data_2: list[str] | list[ScoreContentPartParam],
79 ):
80 len_1 = len(data_1)
81 len_2 = len(data_2)
@@ -89,18 +89,18 @@ def _validate_score_input_lens(
89
90
91 def parse_score_data(
92 - data_1: Union[str, ScoreContentPartParam],
93 - data_2: Union[str, ScoreContentPartParam],
92 + data_1: str | ScoreContentPartParam,
93 + data_2: str | ScoreContentPartParam,
94 model_config: ModelConfig,
95 tokenizer: AnyTokenizer,
96 -) -> tuple[str, str, Optional[MultiModalDataDict]]:
96 +) -> tuple[str, str, MultiModalDataDict | None]:
97 mm_tracker = MultiModalItemTracker(model_config, tokenizer)
98
99 content_1 = _parse_score_content(data_1, mm_tracker)
100
101 content_2 = _parse_score_content(data_2, mm_tracker)
102
103 - def ensure_str(content: Optional[_ContentPart]) -> str:
103 + def ensure_str(content: _ContentPart | None) -> str:
104 if content is not None and isinstance(content, str):
105 return cast(str, content)
106 else:
@@ -113,9 +113,9 @@ def parse_score_data(
113
114
115 def _parse_score_content(
116 - data: Union[str, ScoreContentPartParam],
116 + data: str | ScoreContentPartParam,
117 mm_tracker: BaseMultiModalItemTracker,
118 -) -> Optional[_ContentPart]:
118 +) -> _ContentPart | None:
119 if isinstance(data, str):
120 data = ChatCompletionContentPartTextParam(type="text", text=data)
121
@@ -182,8 +182,8 @@ def get_score_prompt(
182 model_config: ModelConfig,
183 tokenizer: AnyTokenizer,
184 tokenization_kwargs: dict[str, Any],
185 - data_1: Union[str, ScoreContentPartParam],
186 - data_2: Union[str, ScoreContentPartParam],
185 + data_1: str | ScoreContentPartParam,
186 + data_2: str | ScoreContentPartParam,
187 ) -> tuple[str, TokensPrompt]:
188 prompt_1, prompt_2, mm_data = parse_score_data(
189 data_1,
vllm/entrypoints/ssl.py
+4 -4
@@ -2,8 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import asyncio
5 +from collections.abc import Callable
6 from ssl import SSLContext
6 -from typing import Callable, Optional
7
8 from watchfiles import Change, awatch
9
@@ -20,9 +20,9 @@ class SSLCertRefresher:
20 def __init__(
21 self,
22 ssl_context: SSLContext,
23 - key_path: Optional[str] = None,
24 - cert_path: Optional[str] = None,
25 - ca_path: Optional[str] = None,
23 + key_path: str | None = None,
24 + cert_path: str | None = None,
25 + ca_path: str | None = None,
26 ) -> None:
27 self.ssl = ssl_context
28 self.key_path = key_path
vllm/entrypoints/tool_server.py
+6 -6
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from abc import ABC, abstractmethod
4 from contextlib import AbstractAsyncContextManager, asynccontextmanager
5 -from typing import TYPE_CHECKING, Any, Optional
5 +from typing import TYPE_CHECKING, Any
6
7 from openai_harmony import ToolDescription, ToolNamespaceConfig
8
@@ -80,7 +80,7 @@ class ToolServer(ABC):
80 pass
81
82 @abstractmethod
83 - def get_tool_description(self, tool_name: str) -> Optional[ToolNamespaceConfig]:
83 + def get_tool_description(self, tool_name: str) -> ToolNamespaceConfig | None:
84 """
85 Return the tool description for the given tool name.
86 If the tool is not supported, return None.
@@ -89,7 +89,7 @@ class ToolServer(ABC):
89
90 @abstractmethod
91 def new_session(
92 - self, tool_name: str, session_id: str, headers: Optional[dict[str, str]] = None
92 + self, tool_name: str, session_id: str, headers: dict[str, str] | None = None
93 ) -> AbstractAsyncContextManager[Any]:
94 """
95 Create a session for the tool.
@@ -152,7 +152,7 @@ class MCPToolServer(ToolServer):
152
153 @asynccontextmanager
154 async def new_session(
155 - self, tool_name: str, session_id: str, headers: Optional[dict[str, str]] = None
155 + self, tool_name: str, session_id: str, headers: dict[str, str] | None = None
156 ):
157 from mcp import ClientSession
158 from mcp.client.sse import sse_client
@@ -190,7 +190,7 @@ class DemoToolServer(ToolServer):
190 def has_tool(self, tool_name: str) -> bool:
191 return tool_name in self.tools
192
193 - def get_tool_description(self, tool_name: str) -> Optional[ToolNamespaceConfig]:
193 + def get_tool_description(self, tool_name: str) -> ToolNamespaceConfig | None:
194 if tool_name not in self.tools:
195 return None
196 if tool_name == "browser":
@@ -202,7 +202,7 @@ class DemoToolServer(ToolServer):
202
203 @asynccontextmanager
204 async def new_session(
205 - self, tool_name: str, session_id: str, headers: Optional[dict[str, str]] = None
205 + self, tool_name: str, session_id: str, headers: dict[str, str] | None = None
206 ):
207 if tool_name not in self.tools:
208 raise KeyError(f"Tool '{tool_name}' is not supported")
vllm/entrypoints/utils.py
+6 -6
@@ -6,7 +6,7 @@ import dataclasses
6 import functools
7 import os
8 from argparse import Namespace
9 -from typing import Any, Optional, Union
9 +from typing import Any
10
11 from fastapi import Request
12 from fastapi.responses import JSONResponse, StreamingResponse
@@ -164,9 +164,9 @@ def cli_env_setup():
164
165 def _validate_truncation_size(
166 max_model_len: int,
167 - truncate_prompt_tokens: Optional[int],
168 - tokenization_kwargs: Optional[dict[str, Any]] = None,
169 -) -> Optional[int]:
167 + truncate_prompt_tokens: int | None,
168 + tokenization_kwargs: dict[str, Any] | None = None,
169 +) -> int | None:
170 if truncate_prompt_tokens is not None:
171 if truncate_prompt_tokens <= -1:
172 truncate_prompt_tokens = max_model_len
@@ -191,7 +191,7 @@ def _validate_truncation_size(
191
192 def get_max_tokens(
193 max_model_len: int,
194 - request: Union[ChatCompletionRequest, CompletionRequest],
194 + request: ChatCompletionRequest | CompletionRequest,
195 input_length: int,
196 default_sampling_params: dict,
197 ) -> int:
@@ -211,7 +211,7 @@ def get_max_tokens(
211 )
212
213
214 -def log_non_default_args(args: Union[Namespace, EngineArgs]):
214 +def log_non_default_args(args: Namespace | EngineArgs):
215 non_default_args = {}
216
217 # Handle Namespace
vllm/envs.py
+43 -42
@@ -6,27 +6,28 @@ import json
6 import os
7 import sys
8 import tempfile
9 -from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Union
9 +from collections.abc import Callable
10 +from typing import TYPE_CHECKING, Any, Literal
11
12 if TYPE_CHECKING:
13 VLLM_HOST_IP: str = ""
13 - VLLM_PORT: Optional[int] = None
14 + VLLM_PORT: int | None = None
15 VLLM_RPC_BASE_PATH: str = tempfile.gettempdir()
16 VLLM_USE_MODELSCOPE: bool = False
17 VLLM_RINGBUFFER_WARNING_INTERVAL: int = 60
17 - VLLM_NCCL_SO_PATH: Optional[str] = None
18 - LD_LIBRARY_PATH: Optional[str] = None
18 + VLLM_NCCL_SO_PATH: str | None = None
19 + LD_LIBRARY_PATH: str | None = None
20 VLLM_USE_TRITON_FLASH_ATTN: bool = True
21 VLLM_V1_USE_PREFILL_DECODE_ATTENTION: bool = False
21 - VLLM_FLASH_ATTN_VERSION: Optional[int] = None
22 + VLLM_FLASH_ATTN_VERSION: int | None = None
23 LOCAL_RANK: int = 0
23 - CUDA_VISIBLE_DEVICES: Optional[str] = None
24 + CUDA_VISIBLE_DEVICES: str | None = None
25 VLLM_ENGINE_ITERATION_TIMEOUT_S: int = 60
25 - VLLM_API_KEY: Optional[str] = None
26 - S3_ACCESS_KEY_ID: Optional[str] = None
27 - S3_SECRET_ACCESS_KEY: Optional[str] = None
28 - S3_ENDPOINT_URL: Optional[str] = None
29 - VLLM_MODEL_REDIRECT_PATH: Optional[str] = None
26 + VLLM_API_KEY: str | None = None
27 + S3_ACCESS_KEY_ID: str | None = None
28 + S3_SECRET_ACCESS_KEY: str | None = None
29 + S3_ENDPOINT_URL: str | None = None
30 + VLLM_MODEL_REDIRECT_PATH: str | None = None
31 VLLM_CACHE_ROOT: str = os.path.expanduser("~/.cache/vllm")
32 VLLM_CONFIG_ROOT: str = os.path.expanduser("~/.config/vllm")
33 VLLM_USAGE_STATS_SERVER: str = "https://stats.vllm.ai"
@@ -38,16 +39,16 @@ if TYPE_CHECKING:
39 VLLM_LOGGING_LEVEL: str = "INFO"
40 VLLM_LOGGING_PREFIX: str = ""
41 VLLM_LOGGING_STREAM: str = "ext://sys.stdout"
41 - VLLM_LOGGING_CONFIG_PATH: Optional[str] = None
42 - VLLM_LOGITS_PROCESSOR_THREADS: Optional[int] = None
42 + VLLM_LOGGING_CONFIG_PATH: str | None = None
43 + VLLM_LOGITS_PROCESSOR_THREADS: int | None = None
44 VLLM_LOG_STATS_INTERVAL: float = 10.0
45 VLLM_TRACE_FUNCTION: int = 0
45 - VLLM_ATTENTION_BACKEND: Optional[str] = None
46 - VLLM_USE_FLASHINFER_SAMPLER: Optional[bool] = None
47 - VLLM_PP_LAYER_PARTITION: Optional[str] = None
48 - VLLM_CPU_KVCACHE_SPACE: Optional[int] = 0
46 + VLLM_ATTENTION_BACKEND: str | None = None
47 + VLLM_USE_FLASHINFER_SAMPLER: bool | None = None
48 + VLLM_PP_LAYER_PARTITION: str | None = None
49 + VLLM_CPU_KVCACHE_SPACE: int | None = 0
50 VLLM_CPU_OMP_THREADS_BIND: str = ""
50 - VLLM_CPU_NUM_OF_RESERVED_CPU: Optional[int] = None
51 + VLLM_CPU_NUM_OF_RESERVED_CPU: int | None = None
52 VLLM_CPU_MOE_PREPACK: bool = True
53 VLLM_CPU_SGL_KERNEL: bool = False
54 VLLM_XLA_CACHE_PATH: str = os.path.join(VLLM_CACHE_ROOT, "xla_cache")
@@ -73,20 +74,20 @@ if TYPE_CHECKING:
74 VLLM_MM_INPUT_CACHE_GIB: int = 4
75 VLLM_TARGET_DEVICE: str = "cuda"
76 VLLM_MAIN_CUDA_VERSION: str = "12.8"
76 - MAX_JOBS: Optional[str] = None
77 - NVCC_THREADS: Optional[str] = None
77 + MAX_JOBS: str | None = None
78 + NVCC_THREADS: str | None = None
79 VLLM_USE_PRECOMPILED: bool = False
80 VLLM_DOCKER_BUILD_CONTEXT: bool = False
81 VLLM_TEST_USE_PRECOMPILED_NIGHTLY_WHEEL: bool = False
82 VLLM_KEEP_ALIVE_ON_ENGINE_DEATH: bool = False
82 - CMAKE_BUILD_TYPE: Optional[Literal["Debug", "Release", "RelWithDebInfo"]] = None
83 + CMAKE_BUILD_TYPE: Literal["Debug", "Release", "RelWithDebInfo"] | None = None
84 VERBOSE: bool = False
85 VLLM_ALLOW_LONG_MAX_MODEL_LEN: bool = False
86 VLLM_RPC_TIMEOUT: int = 10000 # ms
87 VLLM_HTTP_TIMEOUT_KEEP_ALIVE: int = 5 # seconds
87 - VLLM_PLUGINS: Optional[list[str]] = None
88 - VLLM_LORA_RESOLVER_CACHE_DIR: Optional[str] = None
89 - VLLM_TORCH_PROFILER_DIR: Optional[str] = None
88 + VLLM_PLUGINS: list[str] | None = None
89 + VLLM_LORA_RESOLVER_CACHE_DIR: str | None = None
90 + VLLM_TORCH_PROFILER_DIR: str | None = None
91 VLLM_TORCH_PROFILER_RECORD_SHAPES: bool = False
92 VLLM_TORCH_PROFILER_WITH_PROFILE_MEMORY: bool = False
93 VLLM_USE_AOT_COMPILE: bool = False
@@ -126,7 +127,7 @@ if TYPE_CHECKING:
127 VLLM_FLASH_ATTN_MAX_NUM_SPLITS_FOR_CUDA_GRAPH: int = 32
128 VLLM_RAY_PER_WORKER_GPUS: float = 1.0
129 VLLM_RAY_BUNDLE_INDICES: str = ""
129 - VLLM_CUDART_SO_PATH: Optional[str] = None
130 + VLLM_CUDART_SO_PATH: str | None = None
131 VLLM_DP_RANK: int = 0
132 VLLM_DP_RANK_LOCAL: int = -1
133 VLLM_DP_SIZE: int = 1
@@ -137,11 +138,11 @@ if TYPE_CHECKING:
138 VLLM_RANDOMIZE_DP_DUMMY_INPUTS: bool = False
139 VLLM_RAY_DP_PACK_STRATEGY: str = "strict"
140 VLLM_MARLIN_USE_ATOMIC_ADD: bool = False
140 - VLLM_MXFP4_USE_MARLIN: Optional[bool] = None
141 + VLLM_MXFP4_USE_MARLIN: bool | None = None
142 VLLM_V0_USE_OUTLINES_CACHE: bool = False
143 VLLM_V1_USE_OUTLINES_CACHE: bool = False
144 VLLM_TPU_BUCKET_PADDING_GAP: int = 0
144 - VLLM_TPU_MOST_MODEL_LEN: Optional[int] = None
145 + VLLM_TPU_MOST_MODEL_LEN: int | None = None
146 VLLM_TPU_USING_PATHWAYS: bool = False
147 VLLM_USE_DEEP_GEMM: bool = True
148 VLLM_USE_DEEP_GEMM_E8M0: bool = True
@@ -169,21 +170,21 @@ if TYPE_CHECKING:
170 VLLM_SLEEP_WHEN_IDLE: bool = False
171 VLLM_MQ_MAX_CHUNK_BYTES_MB: int = 16
172 VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS: int = 300
172 - VLLM_KV_CACHE_LAYOUT: Optional[Literal["NHD", "HND"]] = None
173 + VLLM_KV_CACHE_LAYOUT: Literal["NHD", "HND"] | None = None
174 VLLM_COMPUTE_NANS_IN_LOGITS: bool = False
175 VLLM_USE_NVFP4_CT_EMULATIONS: bool = False
176 VLLM_ROCM_QUICK_REDUCE_QUANTIZATION: Literal[
177 "FP", "INT8", "INT6", "INT4", "NONE"
178 ] = "NONE"
179 VLLM_ROCM_QUICK_REDUCE_CAST_BF16_TO_FP16: bool = True
179 - VLLM_ROCM_QUICK_REDUCE_MAX_SIZE_BYTES_MB: Optional[int] = None
180 + VLLM_ROCM_QUICK_REDUCE_MAX_SIZE_BYTES_MB: int | None = None
181 VLLM_NIXL_ABORT_REQUEST_TIMEOUT: int = 480
182 VLLM_USE_CUDNN_PREFILL: bool = False
183 VLLM_ENABLE_CUDAGRAPH_GC: bool = False
184 VLLM_LOOPBACK_IP: str = ""
185 VLLM_ALLOW_CHUNKED_LOCAL_ATTN_WITH_HYBRID_KV_CACHE: bool = False
186 VLLM_ENABLE_RESPONSES_API_STORE: bool = False
186 - VLLM_USE_TRTLLM_ATTENTION: Optional[str] = None
187 + VLLM_USE_TRTLLM_ATTENTION: str | None = None
188 VLLM_FLASHINFER_DISABLE_Q_QUANTIZATION: bool = False
189 VLLM_HAS_FLASHINFER_CUBIN: bool = False
190 VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8: bool = False
@@ -191,7 +192,7 @@ if TYPE_CHECKING:
192 VLLM_ROCM_FP8_MFMA_PAGE_ATTN: bool = False
193 VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8_CUTLASS: bool = False
194 VLLM_ALLREDUCE_USE_SYMM_MEM: bool = True
194 - VLLM_TUNED_CONFIG_FOLDER: Optional[str] = None
195 + VLLM_TUNED_CONFIG_FOLDER: str | None = None
196 VLLM_DISABLE_PAD_FOR_CUDAGRAPH: bool = False
197 VLLM_GPT_OSS_HARMONY_SYSTEM_INSTRUCTIONS: bool = False
198 VLLM_CUSTOM_SCOPES_FOR_PROFILING: bool = False
@@ -201,12 +202,12 @@ if TYPE_CHECKING:
202 VLLM_DEEPEP_BUFFER_SIZE_MB: int = 1024
203 VLLM_DBO_COMM_SMS: int = 20
204 GPT_OSS_SYSTEM_TOOL_MCP_LABELS: list[str] = []
204 - VLLM_PATTERN_MATCH_DEBUG: Optional[str] = None
205 - VLLM_DEBUG_DUMP_PATH: Optional[str] = None
205 + VLLM_PATTERN_MATCH_DEBUG: str | None = None
206 + VLLM_DEBUG_DUMP_PATH: str | None = None
207 VLLM_ENABLE_INDUCTOR_MAX_AUTOTUNE: bool = True
208 VLLM_ENABLE_INDUCTOR_COORDINATE_DESCENT_TUNING: bool = True
209 VLLM_USE_NCCL_SYMM_MEM: bool = False
209 - VLLM_NCCL_INCLUDE_PATH: Optional[str] = None
210 + VLLM_NCCL_INCLUDE_PATH: str | None = None
211 VLLM_USE_FBGEMM: bool = False
212 VLLM_GC_DEBUG: str = ""
213
@@ -225,13 +226,13 @@ def get_default_config_root():
226 )
227
228
228 -def maybe_convert_int(value: Optional[str]) -> Optional[int]:
229 +def maybe_convert_int(value: str | None) -> int | None:
230 if value is None:
231 return None
232 return int(value)
233
234
234 -def maybe_convert_bool(value: Optional[str]) -> Optional[bool]:
235 +def maybe_convert_bool(value: str | None) -> bool | None:
236 if value is None:
237 return None
238 return bool(int(value))
@@ -246,10 +247,10 @@ def use_aot_compile() -> bool:
247
248 def env_with_choices(
249 env_name: str,
249 - default: Optional[str],
250 - choices: Union[list[str], Callable[[], list[str]]],
250 + default: str | None,
251 + choices: list[str] | Callable[[], list[str]],
252 case_sensitive: bool = True,
252 -) -> Callable[[], Optional[str]]:
253 +) -> Callable[[], str | None]:
254 """
255 Create a lambda that validates environment variable against allowed choices
256
@@ -263,7 +264,7 @@ def env_with_choices(
264 Lambda function for environment_variables dict
265 """
266
266 - def _get_validated_env() -> Optional[str]:
267 + def _get_validated_env() -> str | None:
268 value = os.getenv(env_name)
269 if value is None:
270 return default
@@ -292,7 +293,7 @@ def env_with_choices(
293 def env_list_with_choices(
294 env_name: str,
295 default: list[str],
295 - choices: Union[list[str], Callable[[], list[str]]],
296 + choices: list[str] | Callable[[], list[str]],
297 case_sensitive: bool = True,
298 ) -> Callable[[], list[str]]:
299 """
@@ -344,7 +345,7 @@ def env_list_with_choices(
345 return _get_validated_env_list
346
347
347 -def get_vllm_port() -> Optional[int]:
348 +def get_vllm_port() -> int | None:
349 """Get the port from VLLM_PORT environment variable.
350
351 Returns:
vllm/executor/executor_base.py
+19 -19
@@ -4,9 +4,9 @@
4 import asyncio
5 import time
6 from abc import ABC, abstractmethod
7 -from collections.abc import Awaitable
7 +from collections.abc import Awaitable, Callable
8 from functools import cached_property
9 -from typing import Any, Callable, Optional, Union
9 +from typing import Any
10
11 from typing_extensions import TypeVar
12
@@ -63,10 +63,10 @@ class ExecutorBase(ABC):
63 @abstractmethod
64 def collective_rpc(
65 self,
66 - method: Union[str, Callable[[WorkerBase], _R]],
67 - timeout: Optional[float] = None,
66 + method: str | Callable[[WorkerBase], _R],
67 + timeout: float | None = None,
68 args: tuple = (),
69 - kwargs: Optional[dict[str, Any]] = None,
69 + kwargs: dict[str, Any] | None = None,
70 ) -> list[_R]:
71 """
72 Execute an RPC call on all workers.
@@ -143,7 +143,7 @@ class ExecutorBase(ABC):
143
144 def execute_model(
145 self, execute_model_req: ExecuteModelRequest
146 - ) -> Optional[list[Union[SamplerOutput, PoolerOutput]]]:
146 + ) -> list[SamplerOutput | PoolerOutput] | None:
147 output = self.collective_rpc("execute_model", args=(execute_model_req,))
148 return output[0]
149
@@ -192,7 +192,7 @@ class ExecutorBase(ABC):
192 "It took %.6f seconds to fall asleep.", time_after_sleep - time_before_sleep
193 )
194
195 - def wake_up(self, tags: Optional[list[str]] = None):
195 + def wake_up(self, tags: list[str] | None = None):
196 if not self.is_sleeping:
197 logger.warning("Executor is not sleeping.")
198 return
@@ -222,8 +222,8 @@ class ExecutorBase(ABC):
222 def save_sharded_state(
223 self,
224 path: str,
225 - pattern: Optional[str] = None,
226 - max_size: Optional[int] = None,
225 + pattern: str | None = None,
226 + max_size: int | None = None,
227 ) -> None:
228 self.collective_rpc(
229 "save_sharded_state",
@@ -256,7 +256,7 @@ class ExecutorBase(ABC):
256 exception."""
257 self.check_health()
258
259 - def init_kv_output_aggregator(self, finished_count: Optional[int]) -> None:
259 + def init_kv_output_aggregator(self, finished_count: int | None) -> None:
260 """Init KVOutputAggregator"""
261 self.kv_output_aggregator = KVOutputAggregator(
262 finished_count or self.parallel_config.world_size
@@ -269,7 +269,7 @@ class DistributedExecutorBase(ExecutorBase):
269 def __init__(self, *args, **kwargs):
270 # This is non-None when the execute model loop is running
271 # in the parallel workers. It's a coroutine in the AsyncLLMEngine case.
272 - self.parallel_worker_tasks: Optional[Union[Any, Awaitable[Any]]] = None
272 + self.parallel_worker_tasks: Any | Awaitable[Any] | None = None
273
274 super().__init__(*args, **kwargs)
275
@@ -302,8 +302,8 @@ class DistributedExecutorBase(ExecutorBase):
302
303 @abstractmethod
304 def _driver_execute_model(
305 - self, execute_model_req: Optional[ExecuteModelRequest]
306 - ) -> Optional[list[SamplerOutput]]:
305 + self, execute_model_req: ExecuteModelRequest | None
306 + ) -> list[SamplerOutput] | None:
307 """Run execute_model in the driver worker.
308
309 Passing None will cause the driver to stop the model execution loop
@@ -314,20 +314,20 @@ class DistributedExecutorBase(ExecutorBase):
314
315 def collective_rpc(
316 self,
317 - method: Union[str, Callable],
318 - timeout: Optional[float] = None,
317 + method: str | Callable,
318 + timeout: float | None = None,
319 args: tuple = (),
320 - kwargs: Optional[dict[str, Any]] = None,
320 + kwargs: dict[str, Any] | None = None,
321 ) -> list[Any]:
322 return self._run_workers(method, *args, **(kwargs or {}))
323
324 @abstractmethod
325 def _run_workers(
326 self,
327 - method: Union[str, Callable],
327 + method: str | Callable,
328 *args,
329 async_run_tensor_parallel_workers_only: bool = False,
330 - max_concurrent_workers: Optional[int] = None,
330 + max_concurrent_workers: int | None = None,
331 **kwargs,
332 ) -> Any:
333 """Runs the given method on all workers.
@@ -374,7 +374,7 @@ class DistributedExecutorBase(ExecutorBase):
374 @abstractmethod
375 async def _driver_execute_model_async(
376 self,
377 - execute_model_req: Optional[ExecuteModelRequest] = None,
377 + execute_model_req: ExecuteModelRequest | None = None,
378 ) -> list[SamplerOutput]:
379 """Execute the model asynchronously in the driver worker.
380
vllm/executor/ray_distributed_executor.py
+11 -10
@@ -4,8 +4,9 @@
4 import asyncio
5 import os
6 from collections import defaultdict
7 +from collections.abc import Callable
8 from dataclasses import dataclass
8 -from typing import TYPE_CHECKING, Any, Callable, Optional, Union
9 +from typing import TYPE_CHECKING, Any
10
11 import cloudpickle
12 import msgspec
@@ -71,7 +72,7 @@ class RayDistributedExecutor(DistributedExecutorBase):
72 uses_ray: bool = True
73
74 def _init_executor(self) -> None:
74 - self.forward_dag: Optional[ray.dag.CompiledDAG] = None
75 + self.forward_dag: ray.dag.CompiledDAG | None = None
76 if envs.VLLM_USE_V1:
77 # V1 uses SPMD worker and compiled DAG
78 os.environ["VLLM_USE_RAY_SPMD_WORKER"] = "1"
@@ -114,10 +115,10 @@ class RayDistributedExecutor(DistributedExecutorBase):
115 self._init_workers_ray(placement_group)
116
117 self.input_encoder = msgspec.msgpack.Encoder(enc_hook=encode_hook)
117 - self.output_decoder = msgspec.msgpack.Decoder(Optional[list[SamplerOutput]])
118 + self.output_decoder = msgspec.msgpack.Decoder(list[SamplerOutput] | None)
119 self.use_v1 = envs.VLLM_USE_V1
120
120 - self.pp_locks: Optional[list[asyncio.Lock]] = None
121 + self.pp_locks: list[asyncio.Lock] | None = None
122 if not self.use_ray_compiled_dag:
123 self.driver_exec_method = make_async(self.driver_worker.execute_method)
124
@@ -162,7 +163,7 @@ class RayDistributedExecutor(DistributedExecutorBase):
163
164 # The driver dummy worker does not actually use any resources.
165 # It holds the resource for the driver worker.
165 - self.driver_dummy_worker: Optional[RayWorkerWrapper] = None
166 + self.driver_dummy_worker: RayWorkerWrapper | None = None
167 # The remaining workers are the actual ray actors.
168 self.workers: list[RayWorkerWrapper] = []
169
@@ -432,8 +433,8 @@ class RayDistributedExecutor(DistributedExecutorBase):
433 self.non_driver_workers.append(worker)
434
435 def _driver_execute_model(
435 - self, execute_model_req: Optional[ExecuteModelRequest]
436 - ) -> Optional[list[SamplerOutput]]:
436 + self, execute_model_req: ExecuteModelRequest | None
437 + ) -> list[SamplerOutput] | None:
438 """Run execute_model in the driver worker.
439
440 Passing None will cause the driver to stop the model execution
@@ -463,10 +464,10 @@ class RayDistributedExecutor(DistributedExecutorBase):
464
465 def _run_workers(
466 self,
466 - method: Union[str, Callable],
467 + method: str | Callable,
468 *args,
469 async_run_tensor_parallel_workers_only: bool = False,
469 - max_concurrent_workers: Optional[int] = None,
470 + max_concurrent_workers: int | None = None,
471 **kwargs,
472 ) -> Any:
473 """Runs the given method on all workers. Can be used in the following
@@ -683,7 +684,7 @@ class RayDistributedExecutor(DistributedExecutorBase):
684 return self.output_decoder.decode(output)
685
686 async def _driver_execute_model_async(
686 - self, execute_model_req: Optional[ExecuteModelRequest] = None
687 + self, execute_model_req: ExecuteModelRequest | None = None
688 ) -> list[SamplerOutput]:
689 assert not self.use_ray_spmd_worker, (
690 "driver_worker does not exist for VLLM_USE_RAY_SPMD_WORKER=1"
vllm/executor/ray_utils.py
+3 -3
@@ -4,7 +4,7 @@
4 import os
5 import time
6 from collections import defaultdict
7 -from typing import TYPE_CHECKING, Optional, Union
7 +from typing import TYPE_CHECKING, Union
8
9 import msgspec
10
@@ -72,7 +72,7 @@ try:
72
73 def execute_model_spmd(
74 self,
75 - req_or_tuple: Union[bytes, tuple[bytes, Optional[IntermediateTensors]]],
75 + req_or_tuple: bytes | tuple[bytes, IntermediateTensors | None],
76 ) -> bytes:
77 """Execute model in SPMD fashion: used only when SPMD worker and
78 compiled DAG are both enabled.
@@ -300,7 +300,7 @@ def _wait_until_pg_removed(current_placement_group: "PlacementGroup"):
300
301 def initialize_ray_cluster(
302 parallel_config: ParallelConfig,
303 - ray_address: Optional[str] = None,
303 + ray_address: str | None = None,
304 ):
305 """Initialize the distributed cluster with Ray.
306
vllm/executor/uniproc_executor.py
+6 -5
@@ -1,10 +1,11 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import os
4 +from collections.abc import Callable
5 from concurrent.futures import Future, ThreadPoolExecutor
6 from functools import cached_property
7 from multiprocessing import Lock
7 -from typing import Any, Callable, Optional, Union
8 +from typing import Any
9
10 import torch
11 import torch.distributed as dist
@@ -36,7 +37,7 @@ class UniProcExecutor(ExecutorBase):
37 shared_worker_lock=Lock(),
38 )
39
39 - self.async_output_thread: Optional[ThreadPoolExecutor] = None
40 + self.async_output_thread: ThreadPoolExecutor | None = None
41 if self.max_concurrent_batches > 1:
42 self.async_output_thread = ThreadPoolExecutor(
43 max_workers=1, thread_name_prefix="WorkerAsyncOutput"
@@ -60,10 +61,10 @@ class UniProcExecutor(ExecutorBase):
61
62 def collective_rpc(
63 self,
63 - method: Union[str, Callable],
64 - timeout: Optional[float] = None,
64 + method: str | Callable,
65 + timeout: float | None = None,
66 args: tuple = (),
66 - kwargs: Optional[dict] = None,
67 + kwargs: dict | None = None,
68 non_block: bool = False,
69 ) -> list[Any]:
70 if kwargs is None:
vllm/forward_context.py
+16 -16
@@ -5,7 +5,7 @@ import time
5 from collections import defaultdict
6 from contextlib import contextmanager
7 from dataclasses import dataclass
8 -from typing import TYPE_CHECKING, Any, NamedTuple, Optional, Union
8 +from typing import TYPE_CHECKING, Any, NamedTuple, Union
9
10 import torch
11
@@ -84,7 +84,7 @@ class DPMetadata:
84 num_tokens_across_dp_cpu: torch.Tensor
85
86 # NOTE: local_sizes should only be set by the chunked_sizes context manager
87 - local_sizes: Optional[list[int]] = None
87 + local_sizes: list[int] | None = None
88
89 @staticmethod
90 def make(
@@ -158,7 +158,7 @@ class DPMetadata:
158 finally:
159 self.local_sizes = None
160
161 - def get_chunk_sizes_across_dp_rank(self) -> Optional[list[int]]:
161 + def get_chunk_sizes_across_dp_rank(self) -> list[int] | None:
162 assert self.local_sizes is not None
163 return self.local_sizes
164
@@ -194,13 +194,13 @@ class ForwardContext:
194 # TODO: remove after making all virtual_engines share the same kv cache
195 virtual_engine: int # set dynamically for each forward pass
196 # set dynamically for each forward pass
197 - dp_metadata: Optional[DPMetadata] = None
197 + dp_metadata: DPMetadata | None = None
198 # determine the cudagraph style at runtime to be FULL, PIECEWISE, or NONE.
199 # by default NONE, no cudagraph is used.
200 cudagraph_runtime_mode: CUDAGraphMode = CUDAGraphMode.NONE
201 - batch_descriptor: Optional[BatchDescriptor] = None
201 + batch_descriptor: BatchDescriptor | None = None
202
203 - ubatch_slices: Optional[UBatchSlices] = None
203 + ubatch_slices: UBatchSlices | None = None
204
205 def __post_init__(self):
206 assert self.cudagraph_runtime_mode.valid_runtime_modes(), (
@@ -208,7 +208,7 @@ class ForwardContext:
208 )
209
210
211 -_forward_context: Optional[ForwardContext] = None
211 +_forward_context: ForwardContext | None = None
212
213
214 def get_forward_context() -> ForwardContext:
@@ -224,10 +224,10 @@ def create_forward_context(
224 attn_metadata: Any,
225 vllm_config: VllmConfig,
226 virtual_engine: int = 0,
227 - dp_metadata: Optional[DPMetadata] = None,
227 + dp_metadata: DPMetadata | None = None,
228 cudagraph_runtime_mode: CUDAGraphMode = CUDAGraphMode.NONE,
229 - batch_descriptor: Optional[BatchDescriptor] = None,
230 - ubatch_slices: Optional[UBatchSlices] = None,
229 + batch_descriptor: BatchDescriptor | None = None,
230 + ubatch_slices: UBatchSlices | None = None,
231 ):
232 return ForwardContext(
233 no_compile_layers=vllm_config.compilation_config.static_forward_context,
@@ -241,7 +241,7 @@ def create_forward_context(
241
242
243 @contextmanager
244 -def override_forward_context(forward_context: Optional[ForwardContext]):
244 +def override_forward_context(forward_context: ForwardContext | None):
245 """A context manager that overrides the current forward context.
246 This is used to override the forward context for a specific
247 forward pass.
@@ -260,11 +260,11 @@ def set_forward_context(
260 attn_metadata: Any,
261 vllm_config: VllmConfig,
262 virtual_engine: int = 0,
263 - num_tokens: Optional[int] = None,
264 - num_tokens_across_dp: Optional[torch.Tensor] = None,
263 + num_tokens: int | None = None,
264 + num_tokens_across_dp: torch.Tensor | None = None,
265 cudagraph_runtime_mode: CUDAGraphMode = CUDAGraphMode.NONE,
266 - batch_descriptor: Optional[BatchDescriptor] = None,
267 - ubatch_slices: Optional[UBatchSlices] = None,
266 + batch_descriptor: BatchDescriptor | None = None,
267 + ubatch_slices: UBatchSlices | None = None,
268 ):
269 """A context manager that stores the current forward context,
270 can be attention metadata, etc.
@@ -275,7 +275,7 @@ def set_forward_context(
275 if need_to_track_batchsize:
276 forward_start_time = time.perf_counter()
277
278 - dp_metadata: Optional[DPMetadata] = None
278 + dp_metadata: DPMetadata | None = None
279 if vllm_config.parallel_config.data_parallel_size > 1 and (
280 attn_metadata is not None or num_tokens is not None
281 ):
vllm/inputs/data.py
+26 -24
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable
4 -from typing import TYPE_CHECKING, Any, Generic, Literal, Optional, Union, cast
4 +from typing import TYPE_CHECKING, Any, Generic, Literal, TypeAlias, cast
5
6 import torch
7 from typing_extensions import NotRequired, TypedDict, TypeIs, TypeVar
@@ -12,6 +12,10 @@ if TYPE_CHECKING:
12 MultiModalInputs,
13 MultiModalUUIDDict,
14 )
15 +else:
16 + MultiModalDataDict = object
17 + MultiModalInputs = object
18 + MultiModalUUIDDict = object
19
20
21 class TextPrompt(TypedDict):
@@ -20,13 +24,13 @@ class TextPrompt(TypedDict):
24 prompt: str
25 """The input text to be tokenized before passing to the model."""
26
23 - multi_modal_data: NotRequired[Optional["MultiModalDataDict"]]
27 + multi_modal_data: NotRequired[MultiModalDataDict | None]
28 """
29 Optional multi-modal data to pass to the model,
30 if the model supports it.
31 """
32
29 - mm_processor_kwargs: NotRequired[Optional[dict[str, Any]]]
33 + mm_processor_kwargs: NotRequired[dict[str, Any] | None]
34 """
35 Optional multi-modal processor kwargs to be forwarded to the
36 multimodal input mapper & processor. Note that if multiple modalities
@@ -34,7 +38,7 @@ class TextPrompt(TypedDict):
38 to pass the mm_processor_kwargs to each of them.
39 """
40
37 - multi_modal_uuids: NotRequired["MultiModalUUIDDict"]
41 + multi_modal_uuids: NotRequired[MultiModalUUIDDict]
42 """
43 Optional user-specified UUIDs for multimodal items, mapped by modality.
44 Lists must match the number of items per modality and may contain `None`.
@@ -61,13 +65,13 @@ class TokensPrompt(TypedDict):
65 token_type_ids: NotRequired[list[int]]
66 """A list of token type IDs to pass to the cross encoder model."""
67
64 - multi_modal_data: NotRequired[Optional["MultiModalDataDict"]]
68 + multi_modal_data: NotRequired[MultiModalDataDict | None]
69 """
70 Optional multi-modal data to pass to the model,
71 if the model supports it.
72 """
73
70 - mm_processor_kwargs: NotRequired[Optional[dict[str, Any]]]
74 + mm_processor_kwargs: NotRequired[dict[str, Any] | None]
75 """
76 Optional multi-modal processor kwargs to be forwarded to the
77 multimodal input mapper & processor. Note that if multiple modalities
@@ -75,7 +79,7 @@ class TokensPrompt(TypedDict):
79 to pass the mm_processor_kwargs to each of them.
80 """
81
78 - multi_modal_uuids: NotRequired["MultiModalUUIDDict"]
82 + multi_modal_uuids: NotRequired[MultiModalUUIDDict]
83 """
84 Optional user-specified UUIDs for multimodal items, mapped by modality.
85 Lists must match the number of items per modality and may contain `None`.
@@ -111,7 +115,7 @@ class DataPrompt(TypedDict):
115 """The input data format"""
116
117
114 -SingletonPrompt = Union[str, TextPrompt, TokensPrompt, EmbedsPrompt]
118 +SingletonPrompt: TypeAlias = str | TextPrompt | TokensPrompt | EmbedsPrompt
119 """
120 Set of possible schemas for a single prompt:
121
@@ -185,12 +189,12 @@ class ExplicitEncoderDecoderPrompt(TypedDict, Generic[_T1_co, _T2_co]):
189
190 encoder_prompt: _T1_co
191
188 - decoder_prompt: Optional[_T2_co]
192 + decoder_prompt: _T2_co | None
193
194 mm_processor_kwargs: NotRequired[dict[str, Any]]
195
196
193 -PromptType = Union[SingletonPrompt, ExplicitEncoderDecoderPrompt]
197 +PromptType: TypeAlias = SingletonPrompt | ExplicitEncoderDecoderPrompt
198 """
199 Set of possible schemas for an LLM input, including
200 both decoder-only and encoder/decoder input types:
@@ -220,7 +224,7 @@ class TokenInputs(TypedDict):
224
225 def token_inputs(
226 prompt_token_ids: list[int],
223 - cache_salt: Optional[str] = None,
227 + cache_salt: str | None = None,
228 ) -> TokenInputs:
229 """Construct [`TokenInputs`][vllm.inputs.data.TokenInputs] from optional
230 values."""
@@ -249,7 +253,7 @@ class EmbedsInputs(TypedDict):
253
254 def embeds_inputs(
255 prompt_embeds: torch.Tensor,
252 - cache_salt: Optional[str] = None,
256 + cache_salt: str | None = None,
257 ) -> EmbedsInputs:
258 """Construct [`EmbedsInputs`][vllm.inputs.data.EmbedsInputs] from optional
259 values."""
@@ -261,7 +265,7 @@ def embeds_inputs(
265 return inputs
266
267
264 -DecoderOnlyInputs = Union[TokenInputs, EmbedsInputs, "MultiModalInputs"]
268 +DecoderOnlyInputs: TypeAlias = TokenInputs | EmbedsInputs | MultiModalInputs
269 """
270 The inputs in [`LLMEngine`][vllm.engine.llm_engine.LLMEngine] before they are
271 passed to the model executor.
@@ -277,20 +281,20 @@ class EncoderDecoderInputs(TypedDict):
281 This specifies the required data for encoder-decoder models.
282 """
283
280 - encoder: Union[TokenInputs, "MultiModalInputs"]
284 + encoder: TokenInputs | MultiModalInputs
285 """The inputs for the encoder portion."""
286
283 - decoder: Union[TokenInputs, "MultiModalInputs"]
287 + decoder: TokenInputs | MultiModalInputs
288 """The inputs for the decoder portion."""
289
290
287 -SingletonInputs = Union[TokenInputs, EmbedsInputs, "MultiModalInputs"]
291 +SingletonInputs: TypeAlias = TokenInputs | EmbedsInputs | MultiModalInputs
292 """
293 A processed [`SingletonPrompt`][vllm.inputs.data.SingletonPrompt] which can be
294 passed to [`Sequence`][collections.abc.Sequence].
295 """
296
293 -ProcessorInputs = Union[DecoderOnlyInputs, EncoderDecoderInputs]
297 +ProcessorInputs: TypeAlias = DecoderOnlyInputs | EncoderDecoderInputs
298 """
299 The outputs from [`vllm.inputs.preprocess.InputPreprocessor`][].
300 """
@@ -301,8 +305,8 @@ _T2 = TypeVar("_T2", bound=SingletonPrompt, default=SingletonPrompt)
305
306 def build_explicit_enc_dec_prompt(
307 encoder_prompt: _T1,
304 - decoder_prompt: Optional[_T2],
305 - mm_processor_kwargs: Optional[dict[str, Any]] = None,
308 + decoder_prompt: _T2 | None,
309 + mm_processor_kwargs: dict[str, Any] | None = None,
310 ) -> ExplicitEncoderDecoderPrompt[_T1, _T2]:
311 if mm_processor_kwargs is None:
312 mm_processor_kwargs = {}
@@ -315,10 +319,8 @@ def build_explicit_enc_dec_prompt(
319
320 def zip_enc_dec_prompts(
321 enc_prompts: Iterable[_T1],
318 - dec_prompts: Iterable[Optional[_T2]],
319 - mm_processor_kwargs: Optional[
320 - Union[Iterable[dict[str, Any]], dict[str, Any]]
321 - ] = None,
322 + dec_prompts: Iterable[_T2 | None],
323 + mm_processor_kwargs: Iterable[dict[str, Any]] | dict[str, Any] | None = None,
324 ) -> list[ExplicitEncoderDecoderPrompt[_T1, _T2]]:
325 """
326 Zip encoder and decoder prompts together into a list of
@@ -350,7 +352,7 @@ def zip_enc_dec_prompts(
352
353 def to_enc_dec_tuple_list(
354 enc_dec_prompts: Iterable[ExplicitEncoderDecoderPrompt[_T1, _T2]],
353 -) -> list[tuple[_T1, Optional[_T2]]]:
355 +) -> list[tuple[_T1, _T2 | None]]:
356 return [
357 (enc_dec_prompt["encoder_prompt"], enc_dec_prompt["decoder_prompt"])
358 for enc_dec_prompt in enc_dec_prompts
vllm/inputs/parse.py
+10 -10
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Sequence
4 -from typing import TYPE_CHECKING, Literal, NamedTuple, Optional, TypedDict, Union, cast
4 +from typing import TYPE_CHECKING, Literal, NamedTuple, TypeAlias, TypedDict, cast
5
6 from typing_extensions import TypeIs
7
@@ -23,8 +23,8 @@ if TYPE_CHECKING:
23
24
25 def parse_raw_prompts(
26 - prompt: Union[str, list[str], list[int], list[list[int]]],
27 -) -> Union[Sequence[TextPrompt], Sequence[TokensPrompt]]:
26 + prompt: str | list[str] | list[int] | list[list[int]],
27 +) -> Sequence[TextPrompt] | Sequence[TokensPrompt]:
28 if isinstance(prompt, str):
29 # case 1: a string
30 return [TextPrompt(prompt=prompt)]
@@ -76,9 +76,9 @@ class ParsedEmbedsPrompt(TypedDict):
76 content: EmbedsPrompt
77
78
79 -ParsedSingletonPrompt = Union[
80 - ParsedStrPrompt, ParsedTextPrompt, ParsedTokensPrompt, ParsedEmbedsPrompt
81 -]
79 +ParsedSingletonPrompt: TypeAlias = (
80 + ParsedStrPrompt | ParsedTextPrompt | ParsedTokensPrompt | ParsedEmbedsPrompt
81 +)
82
83
84 def parse_singleton_prompt(prompt: SingletonPrompt) -> ParsedSingletonPrompt:
@@ -106,7 +106,7 @@ def is_explicit_encoder_decoder_prompt(
106
107 def split_enc_dec_inputs(
108 inputs: ProcessorInputs,
109 -) -> tuple[Optional[SingletonInputs], SingletonInputs]:
109 +) -> tuple[SingletonInputs | None, SingletonInputs]:
110 if "encoder" in inputs and "decoder" in inputs:
111 # NOTE: This passes pyright but not mypy
112 return (
@@ -118,9 +118,9 @@ def split_enc_dec_inputs(
118
119
120 class PromptComponents(NamedTuple):
121 - text: Optional[str] = None
122 - token_ids: Optional[list[int]] = None
123 - embeds: Optional["torch.Tensor"] = None
121 + text: str | None = None
122 + token_ids: list[int] | None = None
123 + embeds: "torch.Tensor | None" = None
124
125
126 def get_prompt_components(prompt: PromptType) -> PromptComponents:
vllm/inputs/preprocess.py
+42 -44
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Mapping
5 -from typing import Any, Optional, Union, cast
5 +from typing import Any, cast
6
7 from typing_extensions import assert_never
8
@@ -46,9 +46,9 @@ class InputPreprocessor:
46 def __init__(
47 self,
48 model_config: ModelConfig,
49 - tokenizer: Optional[AnyTokenizer],
49 + tokenizer: AnyTokenizer | None,
50 mm_registry: MultiModalRegistry = MULTIMODAL_REGISTRY,
51 - mm_processor_cache: Optional[BaseMultiModalProcessorCache] = None,
51 + mm_processor_cache: BaseMultiModalProcessorCache | None = None,
52 ) -> None:
53 super().__init__()
54
@@ -67,7 +67,7 @@ class InputPreprocessor:
67
68 return self.tokenizer
69
70 - def get_bos_token_id(self) -> Optional[int]:
70 + def get_bos_token_id(self) -> int | None:
71 if self.tokenizer is None:
72 logger.warning_once(
73 "Using None for BOS token id because tokenizer is not initialized"
@@ -76,7 +76,7 @@ class InputPreprocessor:
76
77 return self.tokenizer.bos_token_id
78
79 - def get_eos_token_id(self) -> Optional[int]:
79 + def get_eos_token_id(self) -> int | None:
80 if self.tokenizer is None:
81 logger.warning_once(
82 "Using None for EOS token id because tokenizer is not initialized"
@@ -85,7 +85,7 @@ class InputPreprocessor:
85
86 return self.tokenizer.eos_token_id
87
88 - def get_decoder_start_token_id(self) -> Optional[int]:
88 + def get_decoder_start_token_id(self) -> int | None:
89 """
90 Obtain the decoder start token id employed by an encoder/decoder
91 model. Returns None for non-encoder/decoder models or if the
@@ -157,7 +157,7 @@ class InputPreprocessor:
157
158 def _prepare_decoder_input_ids_for_generation(
159 self,
160 - decoder_input_ids: Optional[list[int]],
160 + decoder_input_ids: list[int] | None,
161 ) -> list[int]:
162 """
163 Prepares `decoder_input_ids` for generation with encoder-decoder models.
@@ -194,7 +194,7 @@ class InputPreprocessor:
194
195 def _get_tokenization_kw(
196 self,
197 - overrides: Optional[dict[str, Any]] = None,
197 + overrides: dict[str, Any] | None = None,
198 ) -> dict[str, Any]:
199 kwargs = dict[str, Any]()
200
@@ -212,7 +212,7 @@ class InputPreprocessor:
212 def _tokenize_prompt(
213 self,
214 prompt: str,
215 - tokenization_kwargs: Optional[dict[str, Any]] = None,
215 + tokenization_kwargs: dict[str, Any] | None = None,
216 ) -> list[int]:
217 """
218 Apply the model's tokenizer to a text prompt, returning the
@@ -251,12 +251,12 @@ class InputPreprocessor:
251
252 def _process_multimodal(
253 self,
254 - prompt: Union[str, list[int]],
254 + prompt: str | list[int],
255 mm_data: MultiModalDataDict,
256 - mm_processor_kwargs: Optional[Mapping[str, object]],
257 - tokenization_kwargs: Optional[dict[str, Any]] = None,
256 + mm_processor_kwargs: Mapping[str, object] | None,
257 + tokenization_kwargs: dict[str, Any] | None = None,
258 *,
259 - mm_uuids: Optional[MultiModalUUIDDict] = None,
259 + mm_uuids: MultiModalUUIDDict | None = None,
260 ) -> MultiModalInputs:
261 """
262 Apply the model's multi-modal processor to a multi-modal prompt,
@@ -320,7 +320,7 @@ class InputPreprocessor:
320 )
321
322 def _truncate_inputs(
323 - self, inputs: list[int], tokenization_kwargs: Optional[dict[str, Any]] = None
323 + self, inputs: list[int], tokenization_kwargs: dict[str, Any] | None = None
324 ) -> list[int]:
325 if (
326 not tokenization_kwargs
@@ -339,15 +339,15 @@ class InputPreprocessor:
339 def _process_tokens(
340 self,
341 parsed_content: TokensPrompt,
342 - tokenization_kwargs: Optional[dict[str, Any]] = None,
342 + tokenization_kwargs: dict[str, Any] | None = None,
343 *,
344 - mm_uuids: Optional[MultiModalUUIDDict] = None,
345 - ) -> Union[TokenInputs, MultiModalInputs]:
344 + mm_uuids: MultiModalUUIDDict | None = None,
345 + ) -> TokenInputs | MultiModalInputs:
346 prompt_token_ids = self._truncate_inputs(
347 parsed_content["prompt_token_ids"], tokenization_kwargs
348 )
349
350 - inputs: Union[TokenInputs, MultiModalInputs]
350 + inputs: TokenInputs | MultiModalInputs
351 if self.model_config.is_multimodal_model:
352 inputs = self._process_multimodal(
353 prompt_token_ids,
@@ -370,13 +370,13 @@ class InputPreprocessor:
370 def _process_text(
371 self,
372 parsed_content: TextPrompt,
373 - tokenization_kwargs: Optional[dict[str, Any]] = None,
373 + tokenization_kwargs: dict[str, Any] | None = None,
374 *,
375 - mm_uuids: Optional[MultiModalUUIDDict] = None,
376 - ) -> Union[TokenInputs, MultiModalInputs]:
375 + mm_uuids: MultiModalUUIDDict | None = None,
376 + ) -> TokenInputs | MultiModalInputs:
377 prompt_text = parsed_content["prompt"]
378
379 - inputs: Union[TokenInputs, MultiModalInputs]
379 + inputs: TokenInputs | MultiModalInputs
380 if self.model_config.is_multimodal_model:
381 inputs = self._process_multimodal(
382 prompt_text,
@@ -403,9 +403,9 @@ class InputPreprocessor:
403 def _prompt_to_llm_inputs(
404 self,
405 prompt: SingletonPrompt,
406 - tokenization_kwargs: Optional[dict[str, Any]] = None,
406 + tokenization_kwargs: dict[str, Any] | None = None,
407 *,
408 - mm_uuids: Optional[MultiModalUUIDDict] = None,
408 + mm_uuids: MultiModalUUIDDict | None = None,
409 ) -> SingletonInputs:
410 """
411 Extract the singleton inputs from a prompt.
@@ -445,7 +445,7 @@ class InputPreprocessor:
445 def _build_enc_dec_llm_inputs(
446 self,
447 encoder_inputs: SingletonInputs,
448 - decoder_inputs: Optional[SingletonInputs],
448 + decoder_inputs: SingletonInputs | None,
449 ) -> EncoderDecoderInputs:
450 if (
451 encoder_inputs["type"] == "embeds"
@@ -457,10 +457,8 @@ class InputPreprocessor:
457 )
458
459 # Needed for mypy
460 - encoder_inputs = cast(Union[TokenInputs, MultiModalInputs], encoder_inputs)
461 - decoder_inputs = cast(
462 - Optional[Union[TokenInputs, MultiModalInputs]], decoder_inputs
463 - )
460 + encoder_inputs = cast(TokenInputs | MultiModalInputs, encoder_inputs)
461 + decoder_inputs = cast(TokenInputs | MultiModalInputs | None, decoder_inputs)
462
463 if decoder_inputs is None:
464 if self.model_config.hf_config.model_type == "whisper":
@@ -491,8 +489,8 @@ class InputPreprocessor:
489
490 def _split_enc_dec_mm_inputs(
491 self,
494 - inputs: Union[SingletonInputs, MultiModalEncDecInputs],
495 - decoder_inputs_to_override: Optional[SingletonInputs] = None,
492 + inputs: SingletonInputs | MultiModalEncDecInputs,
493 + decoder_inputs_to_override: SingletonInputs | None = None,
494 ) -> tuple[SingletonInputs, SingletonInputs]:
495 """
496 For encoder/decoder models only:
@@ -509,11 +507,11 @@ class InputPreprocessor:
507
508 # Needed for mypy
509 inputs = cast(
512 - Union[TokenInputs, MultiModalInputs, MultiModalEncDecInputs],
510 + TokenInputs | MultiModalInputs | MultiModalEncDecInputs,
511 inputs,
512 )
513 decoder_inputs_to_override = cast(
516 - Optional[Union[TokenInputs, MultiModalInputs]],
514 + TokenInputs | MultiModalInputs | None,
515 decoder_inputs_to_override,
516 )
517
@@ -553,9 +551,9 @@ class InputPreprocessor:
551 def _process_encoder_decoder_prompt(
552 self,
553 prompt: PromptType,
556 - tokenization_kwargs: Optional[dict[str, Any]] = None,
554 + tokenization_kwargs: dict[str, Any] | None = None,
555 *,
558 - mm_uuids: Optional[MultiModalUUIDDict] = None,
556 + mm_uuids: MultiModalUUIDDict | None = None,
557 ) -> EncoderDecoderInputs:
558 """
559 For encoder/decoder models only:
@@ -591,7 +589,7 @@ class InputPreprocessor:
589 instance
590 """
591 encoder_inputs: SingletonInputs
594 - decoder_inputs: Optional[SingletonInputs]
592 + decoder_inputs: SingletonInputs | None
593
594 if is_explicit_encoder_decoder_prompt(prompt):
595 # `cast` is needed for mypy, but not pyright
@@ -633,7 +631,7 @@ class InputPreprocessor:
631 ) -> DecoderOnlyInputs:
632 if "prompt_token_ids" in prompt_inputs:
633 prompt_inputs = cast(
636 - Union[TokenInputs, MultiModalInputs], prompt_inputs
634 + TokenInputs | MultiModalInputs, prompt_inputs
635 ) # Needed for mypy
636
637 return prompt_inputs
@@ -641,9 +639,9 @@ class InputPreprocessor:
639 def _process_decoder_only_prompt(
640 self,
641 prompt: SingletonPrompt,
644 - tokenization_kwargs: Optional[dict[str, Any]] = None,
642 + tokenization_kwargs: dict[str, Any] | None = None,
643 *,
646 - mm_uuids: Optional[MultiModalUUIDDict] = None,
644 + mm_uuids: MultiModalUUIDDict | None = None,
645 ) -> DecoderOnlyInputs:
646 """
647 For decoder-only models:
@@ -670,9 +668,9 @@ class InputPreprocessor:
668 def _preprocess(
669 self,
670 prompt: PromptType,
673 - tokenization_kwargs: Optional[dict[str, Any]] = None,
671 + tokenization_kwargs: dict[str, Any] | None = None,
672 *,
675 - mm_uuids: Optional[MultiModalUUIDDict] = None,
673 + mm_uuids: MultiModalUUIDDict | None = None,
674 ) -> ProcessorInputs:
675 if self.model_config.is_encoder_decoder:
676 # Encoder-decoder model requires special mapping of
@@ -699,9 +697,9 @@ class InputPreprocessor:
697 def preprocess(
698 self,
699 prompt: PromptType,
702 - tokenization_kwargs: Optional[dict[str, Any]] = None,
700 + tokenization_kwargs: dict[str, Any] | None = None,
701 *,
704 - mm_uuids: Optional[MultiModalUUIDDict] = None,
702 + mm_uuids: MultiModalUUIDDict | None = None,
703 ) -> ProcessorInputs:
704 """Preprocess the input prompt."""
705 res = self._preprocess(
@@ -718,7 +716,7 @@ class InputPreprocessor:
716
717 return res
718
721 - def stat_mm_cache(self) -> Optional[MultiModalCacheStats]:
719 + def stat_mm_cache(self) -> MultiModalCacheStats | None:
720 mm_cache_stats = self.mm_cache_stats
721 if mm_cache_stats is None:
722 return None
vllm/logger.py
+2 -2
@@ -13,7 +13,7 @@ from logging import Logger
13 from logging.config import dictConfig
14 from os import path
15 from types import MethodType
16 -from typing import Any, Optional, cast
16 +from typing import Any, cast
17
18 import vllm.envs as envs
19
@@ -217,7 +217,7 @@ def _trace_calls(log_path, root_dir, frame, event, arg=None):
217 return partial(_trace_calls, log_path, root_dir)
218
219
220 -def enable_trace_function_call(log_file_path: str, root_dir: Optional[str] = None):
220 +def enable_trace_function_call(log_file_path: str, root_dir: str | None = None):
221 """
222 Enable tracing of every function call in code under `root_dir`.
223 This is useful for debugging hangs or crashes.
vllm/logging_utils/dump_input.py
+2 -3
@@ -4,7 +4,6 @@
4 import contextlib
5 import enum
6 import json
7 -from typing import Optional
7
8 import torch
9
@@ -57,7 +56,7 @@ def prepare_object_to_dump(obj) -> str:
56 def dump_engine_exception(
57 config: VllmConfig,
58 scheduler_output: SchedulerOutput,
60 - scheduler_stats: Optional[SchedulerStats],
59 + scheduler_stats: SchedulerStats | None,
60 ):
61 # NOTE: ensure we can log extra info without risking raises
62 # unexpected errors during logging
@@ -68,7 +67,7 @@ def dump_engine_exception(
67 def _dump_engine_exception(
68 config: VllmConfig,
69 scheduler_output: SchedulerOutput,
71 - scheduler_stats: Optional[SchedulerStats],
70 + scheduler_stats: SchedulerStats | None,
71 ):
72 logger.error(
73 "Dumping input data for V1 LLM engine (v%s) with config: %s, ",
vllm/logits_process.py
+6 -6
@@ -1,16 +1,16 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from collections.abc import Sequence
4 -from typing import Callable, Union
3 +from collections.abc import Callable, Sequence
4 +from typing import TypeAlias
5
6 import torch
7
8 from vllm.transformers_utils.tokenizer import AnyTokenizer
9
10 -LogitsProcessor = Union[
11 - Callable[[list[int], torch.Tensor], torch.Tensor],
12 - Callable[[list[int], list[int], torch.Tensor], torch.Tensor],
13 -]
10 +LogitsProcessor: TypeAlias = (
11 + Callable[[list[int], torch.Tensor], torch.Tensor]
12 + | Callable[[list[int], list[int], torch.Tensor], torch.Tensor]
13 +)
14 """LogitsProcessor is a function that takes a list
15 of previously generated tokens, the logits tensor
16 for the next token and, optionally, prompt tokens as a
vllm/logprobs.py
+3 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import Optional
4
5
6 # We use dataclass for now because it is used for
@@ -18,12 +17,12 @@ class Logprob:
17 """
18
19 logprob: float
21 - rank: Optional[int] = None
22 - decoded_token: Optional[str] = None
20 + rank: int | None = None
21 + decoded_token: str | None = None
22
23
24 # {token_id -> logprob} per each sequence group. None if the corresponding
25 # sequence group doesn't require prompt logprob.
27 -PromptLogprobs = list[Optional[dict[int, Logprob]]]
26 +PromptLogprobs = list[dict[int, Logprob] | None]
27 # {token_id -> logprob} for each sequence group.
28 SampleLogprobs = list[dict[int, Logprob]]
vllm/lora/layers/base.py
+8 -8
@@ -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, Optional, Union
4 +from typing import TYPE_CHECKING
5
6 import torch
7 import torch.nn as nn
@@ -15,14 +15,14 @@ if TYPE_CHECKING:
15
16 class BaseLayerWithLoRA(nn.Module):
17 def slice_lora_a(
18 - self, lora_a: Union[torch.Tensor, list[Union[torch.Tensor, None]]]
19 - ) -> Union[torch.Tensor, list[Union[torch.Tensor, None]]]:
18 + self, lora_a: torch.Tensor | list[torch.Tensor | None]
19 + ) -> torch.Tensor | list[torch.Tensor | None]:
20 """Slice lora a if splitting for tensor parallelism."""
21 ...
22
23 def slice_lora_b(
24 - self, lora_b: Union[torch.Tensor, list[Union[torch.Tensor, None]]]
25 - ) -> Union[torch.Tensor, list[Union[torch.Tensor, None]]]:
24 + self, lora_b: torch.Tensor | list[torch.Tensor | None]
25 + ) -> torch.Tensor | list[torch.Tensor | None]:
26 """Slice lora b if splitting with tensor parallelism."""
27 ...
28
@@ -30,7 +30,7 @@ class BaseLayerWithLoRA(nn.Module):
30 self,
31 max_loras: int,
32 lora_config: LoRAConfig,
33 - model_config: Optional[PretrainedConfig] = None,
33 + model_config: PretrainedConfig | None = None,
34 ) -> None:
35 """Initializes lora matrices."""
36 ...
@@ -44,7 +44,7 @@ class BaseLayerWithLoRA(nn.Module):
44 index: int,
45 lora_a: torch.Tensor,
46 lora_b: torch.Tensor,
47 - embeddings_tensor: Optional[torch.Tensor],
47 + embeddings_tensor: torch.Tensor | None,
48 ):
49 """Overwrites lora tensors at index."""
50 ...
@@ -61,7 +61,7 @@ class BaseLayerWithLoRA(nn.Module):
61 source_layer: nn.Module,
62 lora_config: LoRAConfig,
63 packed_modules_list: list,
64 - model_config: Optional[PretrainedConfig],
64 + model_config: PretrainedConfig | None,
65 ) -> bool:
66 """Returns True if the layer can be replaced by this LoRA layer."""
67 raise NotImplementedError
vllm/lora/layers/base_linear.py
+5 -8
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6 from transformers import PretrainedConfig
@@ -37,7 +36,7 @@ class BaseLinearLayerWithLoRA(BaseLayerWithLoRA):
36 self,
37 max_loras: int,
38 lora_config: LoRAConfig,
40 - model_config: Optional[PretrainedConfig] = None,
39 + model_config: PretrainedConfig | None = None,
40 ) -> None:
41 self.lora_config = lora_config
42 #
@@ -97,7 +96,7 @@ class BaseLinearLayerWithLoRA(BaseLayerWithLoRA):
96 index: int,
97 lora_a: torch.Tensor,
98 lora_b: torch.Tensor,
100 - embeddings_tensor: Optional[torch.Tensor],
99 + embeddings_tensor: torch.Tensor | None,
100 ):
101 # Except for QKVParallelLinearWithLoRA and
102 # MergedColumnParallelLinearWithLoRA, all other linear LoRA layers
@@ -119,9 +118,7 @@ class BaseLinearLayerWithLoRA(BaseLayerWithLoRA):
118 lora_b, non_blocking=True
119 )
120
122 - def apply(
123 - self, x: torch.Tensor, bias: Optional[torch.Tensor] = None
124 - ) -> torch.Tensor:
121 + def apply(self, x: torch.Tensor, bias: torch.Tensor | None = None) -> torch.Tensor:
122 output = self.base_layer.quant_method.apply(self.base_layer, x, bias)
123
124 # In transformers backend, x and output have extra batch dimension like
@@ -131,7 +128,7 @@ class BaseLinearLayerWithLoRA(BaseLayerWithLoRA):
128 output = output.flatten(0, 1)
129 x = x.flatten(0, 1)
130
134 - lora_output: Optional[torch.Tensor] = self.punica_wrapper.add_lora_linear(
131 + lora_output: torch.Tensor | None = self.punica_wrapper.add_lora_linear(
132 output, x, self.lora_a_stacked, self.lora_b_stacked, 1.0, self.output_slices
133 )
134 if not current_platform.can_update_inplace():
@@ -160,7 +157,7 @@ class BaseLinearLayerWithLoRA(BaseLayerWithLoRA):
157 raise ValueError(f"Unsupported base layer: {self.base_layer}")
158
159 @property
163 - def bias(self) -> Optional[torch.Tensor]:
160 + def bias(self) -> torch.Tensor | None:
161 if hasattr(self.base_layer, "bias"):
162 return self.base_layer.bias
163 else:
vllm/lora/layers/column_parallel_linear.py
+27 -36
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import torch
6 import torch.nn as nn
@@ -46,7 +45,7 @@ def _mcp_apply(x, bias, layer: "ColumnParallelLinearWithLoRA"):
45 device=x.device,
46 )
47
49 - shrunk_buffers: Optional[torch.Tensor] = layer.punica_wrapper.add_shrink(
48 + shrunk_buffers: torch.Tensor | None = layer.punica_wrapper.add_shrink(
49 buffers, x, layer.lora_a_stacked, 1.0
50 )
51
@@ -55,7 +54,7 @@ def _mcp_apply(x, bias, layer: "ColumnParallelLinearWithLoRA"):
54
55 buffers = tensor_model_parallel_all_gather(buffers)
56
58 - lora_output: Optional[torch.Tensor] = layer.punica_wrapper.add_expand(
57 + lora_output: torch.Tensor | None = layer.punica_wrapper.add_expand(
58 output,
59 buffers,
60 layer.lora_b_stacked,
@@ -121,7 +120,7 @@ class ColumnParallelLinearWithLoRA(BaseLinearLayerWithLoRA):
120
121 def forward(
122 self, input_: torch.Tensor
124 - ) -> Union[torch.Tensor, tuple[torch.Tensor, Optional[torch.Tensor]]]:
123 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor | None]:
124 """Forward of ColumnParallelLinear
125
126 Args:
@@ -154,7 +153,7 @@ class ColumnParallelLinearWithLoRA(BaseLinearLayerWithLoRA):
153 source_layer: nn.Module,
154 lora_config: LoRAConfig,
155 packed_modules_list: list,
157 - model_config: Optional[PretrainedConfig],
156 + model_config: PretrainedConfig | None,
157 ) -> bool:
158 return type(source_layer) is ColumnParallelLinear or (
159 type(source_layer) is MergedColumnParallelLinear
@@ -172,7 +171,7 @@ class MergedColumnParallelLinearWithLoRA(ColumnParallelLinearWithLoRA):
171 """
172
173 def __init__(
175 - self, base_layer: Union[MergedColumnParallelLinear, QKVParallelLinear]
174 + self, base_layer: MergedColumnParallelLinear | QKVParallelLinear
175 ) -> None:
176 super().__init__(base_layer)
177 # There are two LoRA layers
@@ -189,7 +188,7 @@ class MergedColumnParallelLinearWithLoRA(ColumnParallelLinearWithLoRA):
188 self,
189 max_loras: int,
190 lora_config: LoRAConfig,
192 - model_config: Optional[PretrainedConfig] = None,
191 + model_config: PretrainedConfig | None = None,
192 ) -> None:
193 """
194 The main reason for overriding this function is to enhance code
@@ -227,13 +226,13 @@ class MergedColumnParallelLinearWithLoRA(ColumnParallelLinearWithLoRA):
226 )
227
228 def slice_lora_a(
230 - self, lora_a: list[Union[torch.Tensor, None]]
231 - ) -> list[Union[torch.Tensor, None]]:
229 + self, lora_a: list[torch.Tensor | None]
230 + ) -> list[torch.Tensor | None]:
231 return lora_a
232
233 def slice_lora_b(
235 - self, lora_b: list[Union[torch.Tensor, None]]
236 - ) -> list[Union[torch.Tensor, None]]:
234 + self, lora_b: list[torch.Tensor | None]
235 + ) -> list[torch.Tensor | None]:
236 sliced_lora_b = [None] * self.n_slices
237 for i, (shard_id, shard_size) in enumerate(
238 zip(self.output_ids, self.output_slices)
@@ -249,7 +248,7 @@ class MergedColumnParallelLinearWithLoRA(ColumnParallelLinearWithLoRA):
248 index: int,
249 lora_a: torch.Tensor,
250 lora_b: torch.Tensor,
252 - embeddings_tensor: Optional[torch.Tensor],
251 + embeddings_tensor: torch.Tensor | None,
252 ):
253 self.reset_lora(index)
254
@@ -274,7 +273,7 @@ class MergedColumnParallelLinearWithLoRA(ColumnParallelLinearWithLoRA):
273 source_layer: nn.Module,
274 lora_config: LoRAConfig,
275 packed_modules_list: list,
277 - model_config: Optional[PretrainedConfig],
276 + model_config: PretrainedConfig | None,
277 ) -> bool:
278 return (
279 type(source_layer) is MergedColumnParallelLinear
@@ -340,7 +339,7 @@ class QKVParallelLinearWithLoRA(ColumnParallelLinearWithLoRA):
339 source_layer: nn.Module,
340 lora_config: LoRAConfig,
341 packed_modules_list: list,
343 - model_config: Optional[PretrainedConfig],
342 + model_config: PretrainedConfig | None,
343 ) -> bool:
344 return type(source_layer) is QKVParallelLinear and len(packed_modules_list) == 1
345
@@ -383,7 +382,7 @@ class MergedQKVParallelLinearWithLoRA(MergedColumnParallelLinearWithLoRA):
382 self,
383 max_loras: int,
384 lora_config: LoRAConfig,
386 - model_config: Optional[PretrainedConfig] = None,
385 + model_config: PretrainedConfig | None = None,
386 ) -> None:
387 """
388 The main reason for overloading this function is to handle inconsistent
@@ -398,7 +397,7 @@ class MergedQKVParallelLinearWithLoRA(MergedColumnParallelLinearWithLoRA):
397 source_layer: nn.Module,
398 lora_config: LoRAConfig,
399 packed_modules_list: list,
401 - model_config: Optional[PretrainedConfig],
400 + model_config: PretrainedConfig | None,
401 ) -> bool:
402 return type(source_layer) is QKVParallelLinear and len(packed_modules_list) == 3
403
@@ -426,9 +425,7 @@ class ColumnParallelLinearWithShardedLoRA(ColumnParallelLinearWithLoRA):
425 lora_a = lora_a[start_idx : start_idx + shard_size, :]
426 return lora_a
427
429 - def apply(
430 - self, x: torch.Tensor, bias: Optional[torch.Tensor] = None
431 - ) -> torch.Tensor:
428 + def apply(self, x: torch.Tensor, bias: torch.Tensor | None = None) -> torch.Tensor:
429 return _mcp_apply(x, bias, self)
430
431 @classmethod
@@ -438,7 +435,7 @@ class ColumnParallelLinearWithShardedLoRA(ColumnParallelLinearWithLoRA):
435 source_layer: nn.Module,
436 lora_config: LoRAConfig,
437 packed_modules_list: list,
441 - model_config: Optional[PretrainedConfig],
438 + model_config: PretrainedConfig | None,
439 ) -> bool:
440 # specifying kwargs so they can be easily accessed in decorator
441 return super().can_replace_layer(
@@ -459,8 +456,8 @@ class MergedColumnParallelLinearWithShardedLoRA(MergedColumnParallelLinearWithLo
456 """
457
458 def slice_lora_a(
462 - self, lora_a: list[Union[torch.Tensor, None]]
463 - ) -> list[Union[torch.Tensor, None]]:
459 + self, lora_a: list[torch.Tensor | None]
460 + ) -> list[torch.Tensor | None]:
461 # NOTE: lora_a contains 2 subloras, and each sublora could be None.
462 output_shard_size = self.lora_a_stacked[0].shape[2]
463 output_start_idx = self.tp_rank * output_shard_size
@@ -474,9 +471,7 @@ class MergedColumnParallelLinearWithShardedLoRA(MergedColumnParallelLinearWithLo
471 ]
472 return lora_a
473
477 - def apply(
478 - self, x: torch.Tensor, bias: Optional[torch.Tensor] = None
479 - ) -> torch.Tensor:
474 + def apply(self, x: torch.Tensor, bias: torch.Tensor | None = None) -> torch.Tensor:
475 return _mcp_apply(x, bias, self)
476
477 @classmethod
@@ -486,7 +481,7 @@ class MergedColumnParallelLinearWithShardedLoRA(MergedColumnParallelLinearWithLo
481 source_layer: nn.Module,
482 lora_config: LoRAConfig,
483 packed_modules_list: list,
489 - model_config: Optional[PretrainedConfig],
484 + model_config: PretrainedConfig | None,
485 ) -> bool:
486 # specifying kwargs so they can be easily accessed in decorator
487 return super().can_replace_layer(
@@ -512,9 +507,7 @@ class QKVParallelLinearWithShardedLoRA(QKVParallelLinearWithLoRA):
507 lora_a = lora_a[start_idx : start_idx + shard_size, :]
508 return lora_a
509
515 - def apply(
516 - self, x: torch.Tensor, bias: Optional[torch.Tensor] = None
517 - ) -> torch.Tensor:
510 + def apply(self, x: torch.Tensor, bias: torch.Tensor | None = None) -> torch.Tensor:
511 return _mcp_apply(x, bias, self)
512
513 @classmethod
@@ -524,7 +517,7 @@ class QKVParallelLinearWithShardedLoRA(QKVParallelLinearWithLoRA):
517 source_layer: nn.Module,
518 lora_config: LoRAConfig,
519 packed_modules_list: list,
527 - model_config: Optional[PretrainedConfig],
520 + model_config: PretrainedConfig | None,
521 ) -> bool:
522 # specifying kwargs so they can be easily accessed in decorator
523 return super().can_replace_layer(
@@ -545,8 +538,8 @@ class MergedQKVParallelLinearWithShardedLoRA(MergedQKVParallelLinearWithLoRA):
538 """
539
540 def slice_lora_a(
548 - self, lora_a: list[Union[torch.Tensor, None]]
549 - ) -> list[Union[torch.Tensor, None]]:
541 + self, lora_a: list[torch.Tensor | None]
542 + ) -> list[torch.Tensor | None]:
543 # NOTE: lora_a contains 3 subloras, and each sublora could be None.
544 shard_size = [self.lora_a_stacked[i].shape[2] for i in range(3)]
545 start_idx = [self.tp_rank * shard_size[i] for i in range(3)]
@@ -563,9 +556,7 @@ class MergedQKVParallelLinearWithShardedLoRA(MergedQKVParallelLinearWithLoRA):
556 ]
557 return lora_a
558
566 - def apply(
567 - self, x: torch.Tensor, bias: Optional[torch.Tensor] = None
568 - ) -> torch.Tensor:
559 + def apply(self, x: torch.Tensor, bias: torch.Tensor | None = None) -> torch.Tensor:
560 return _mcp_apply(x, bias, self)
561
562 @classmethod
@@ -575,7 +566,7 @@ class MergedQKVParallelLinearWithShardedLoRA(MergedQKVParallelLinearWithLoRA):
566 source_layer: nn.Module,
567 lora_config: LoRAConfig,
568 packed_modules_list: list,
578 - model_config: Optional[PretrainedConfig],
569 + model_config: PretrainedConfig | None,
570 ) -> bool:
571 # specifying kwargs so they can be easily accessed in decorator
572 return super().can_replace_layer(
vllm/lora/layers/logits_processor.py
+7 -8
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import math
5 -from typing import Optional
5
6 import torch
7 import torch.nn as nn
@@ -41,7 +40,7 @@ class LogitsProcessorWithLoRA(BaseLayerWithLoRA):
40 hidden_size: int,
41 dtype: torch.dtype,
42 device: torch.device,
44 - sharded_to_full_mapping: Optional[list[int]],
43 + sharded_to_full_mapping: list[int] | None,
44 ) -> None:
45 super().__init__()
46 self.base_layer = base_layer
@@ -88,7 +87,7 @@ class LogitsProcessorWithLoRA(BaseLayerWithLoRA):
87 self,
88 max_loras: int,
89 lora_config: LoRAConfig,
91 - model_config: Optional[PretrainedConfig] = None,
90 + model_config: PretrainedConfig | None = None,
91 ) -> None:
92 # TODO: Verify if this condition can be further relaxed
93 if 32000 < self.base_layer.vocab_size > 257024:
@@ -142,7 +141,7 @@ class LogitsProcessorWithLoRA(BaseLayerWithLoRA):
141 index: int,
142 lora_a: torch.Tensor,
143 lora_b: torch.Tensor,
145 - embeddings_tensor: Optional[torch.Tensor],
144 + embeddings_tensor: torch.Tensor | None,
145 ):
146 self.reset_lora(index)
147 self.lora_a_stacked[index, 0, : lora_a.shape[0], : lora_a.shape[1]].copy_(
@@ -162,8 +161,8 @@ class LogitsProcessorWithLoRA(BaseLayerWithLoRA):
161 self,
162 hidden_states: torch.Tensor,
163 lm_head: VocabParallelEmbedding,
165 - embedding_bias: Optional[torch.Tensor] = None,
166 - ) -> Optional[torch.Tensor]:
164 + embedding_bias: torch.Tensor | None = None,
165 + ) -> torch.Tensor | None:
166 # Get the logits for the next tokens.
167 logits = lm_head.quant_method.apply(lm_head, hidden_states)
168 if embedding_bias is not None:
@@ -227,7 +226,7 @@ class LogitsProcessorWithLoRA(BaseLayerWithLoRA):
226 + lora_logits.shape[1],
227 ] = lora_logits
228
230 - lora_output: Optional[torch.Tensor] = self.punica_wrapper.add_lora_logits(
229 + lora_output: torch.Tensor | None = self.punica_wrapper.add_lora_logits(
230 logits, hidden_states, self.lora_a_stacked, self.lora_b_stacked, 1.0
231 )
232
@@ -247,7 +246,7 @@ class LogitsProcessorWithLoRA(BaseLayerWithLoRA):
246 source_layer: nn.Module,
247 lora_config: LoRAConfig,
248 packed_modules_list: list,
250 - model_config: Optional[PretrainedConfig],
249 + model_config: PretrainedConfig | None,
250 ) -> bool:
251 # Special handling for the LogitsProcessor.
252 return False
vllm/lora/layers/replicated_linear.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import torch
6 import torch.nn as nn
@@ -24,7 +23,7 @@ class ReplicatedLinearWithLoRA(BaseLinearLayerWithLoRA):
23
24 def forward(
25 self, input_: torch.Tensor
27 - ) -> Union[torch.Tensor, tuple[torch.Tensor, Optional[torch.Tensor]]]:
26 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor | None]:
27 """Forward of ReplicatedLinearWithLoRA
28
29 Args:
@@ -54,6 +53,6 @@ class ReplicatedLinearWithLoRA(BaseLinearLayerWithLoRA):
53 source_layer: nn.Module,
54 lora_config: LoRAConfig,
55 packed_modules_list: list,
57 - model_config: Optional[PretrainedConfig],
56 + model_config: PretrainedConfig | None,
57 ) -> bool:
58 return type(source_layer) is ReplicatedLinear
vllm/lora/layers/row_parallel_linear.py
+6 -9
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import torch
6 import torch.nn as nn
@@ -41,7 +40,7 @@ class RowParallelLinearWithLoRA(BaseLinearLayerWithLoRA):
40
41 def forward(
42 self, input_: torch.Tensor
44 - ) -> Union[torch.Tensor, tuple[torch.Tensor, Optional[torch.Tensor]]]:
43 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor | None]:
44 """Forward of RowParallelLinear
45
46 Args:
@@ -93,7 +92,7 @@ class RowParallelLinearWithLoRA(BaseLinearLayerWithLoRA):
92 source_layer: nn.Module,
93 lora_config: LoRAConfig,
94 packed_modules_list: list,
96 - model_config: Optional[PretrainedConfig],
95 + model_config: PretrainedConfig | None,
96 ) -> bool:
97 return type(source_layer) is RowParallelLinear
98
@@ -120,9 +119,7 @@ class RowParallelLinearWithShardedLoRA(RowParallelLinearWithLoRA):
119 lora_b = lora_b[start_idx:end_idx, :]
120 return lora_b
121
123 - def apply(
124 - self, x: torch.Tensor, bias: Optional[torch.Tensor] = None
125 - ) -> torch.Tensor:
122 + def apply(self, x: torch.Tensor, bias: torch.Tensor | None = None) -> torch.Tensor:
123 output = self.base_layer.quant_method.apply(self.base_layer, x)
124
125 x = x.view(-1, x.shape[-1])
@@ -133,7 +130,7 @@ class RowParallelLinearWithShardedLoRA(RowParallelLinearWithLoRA):
130 device=x.device,
131 )
132
136 - shrunk_buffer: Optional[torch.Tensor] = self.punica_wrapper.add_shrink(
133 + shrunk_buffer: torch.Tensor | None = self.punica_wrapper.add_shrink(
134 buffer, x, self.lora_a_stacked, 1.0
135 )
136 if not current_platform.can_update_inplace():
@@ -150,7 +147,7 @@ class RowParallelLinearWithShardedLoRA(RowParallelLinearWithLoRA):
147 # NOTE offset are based on the rank.
148 shard_size = self.lora_b_stacked[0].shape[2]
149 offset_start = self.tp_rank * shard_size
153 - lora_output: Optional[torch.Tensor] = self.punica_wrapper.add_expand(
150 + lora_output: torch.Tensor | None = self.punica_wrapper.add_expand(
151 output,
152 buffer,
153 self.lora_b_stacked,
@@ -172,7 +169,7 @@ class RowParallelLinearWithShardedLoRA(RowParallelLinearWithLoRA):
169 source_layer: nn.Module,
170 lora_config: LoRAConfig,
171 packed_modules_list: list,
175 - model_config: Optional[PretrainedConfig],
172 + model_config: PretrainedConfig | None,
173 ) -> bool:
174 # specifying kwargs so they can be easily accessed in decorator
175 return super().can_replace_layer(
vllm/lora/layers/vocal_parallel_embedding.py
+6 -7
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6 import torch.nn as nn
@@ -19,14 +18,14 @@ class VocabParallelEmbeddingWithLoRA(BaseLayerWithLoRA):
18 def __init__(self, base_layer: VocabParallelEmbedding) -> None:
19 super().__init__()
20 self.base_layer = base_layer
22 - self.embeddings_slice: Optional[tuple[int, int]]
23 - self.embeddings_weights: Optional[torch.Tensor]
21 + self.embeddings_slice: tuple[int, int] | None
22 + self.embeddings_weights: torch.Tensor | None
23
24 def create_lora_weights(
25 self,
26 max_loras: int,
27 lora_config: LoRAConfig,
29 - model_config: Optional[PretrainedConfig] = None,
28 + model_config: PretrainedConfig | None = None,
29 ) -> None:
30 if self.base_layer.num_added_embeddings_per_partition > 0:
31 # We can start adding lora weights
@@ -90,7 +89,7 @@ class VocabParallelEmbeddingWithLoRA(BaseLayerWithLoRA):
89 index: int,
90 lora_a: torch.Tensor,
91 lora_b: torch.Tensor,
93 - embeddings_tensor: Optional[torch.Tensor],
92 + embeddings_tensor: torch.Tensor | None,
93 ):
94 self.reset_lora(index)
95 # NOTE self.lora_a_stacked is row-major, and lora_a is col-major,
@@ -143,7 +142,7 @@ class VocabParallelEmbeddingWithLoRA(BaseLayerWithLoRA):
142 -1,
143 )
144
146 - lora_output: Optional[torch.Tensor] = self.punica_wrapper.add_lora_embedding(
145 + lora_output: torch.Tensor | None = self.punica_wrapper.add_lora_embedding(
146 full_output, full_lora_a_embeddings, self.lora_b_stacked, add_input=True
147 )
148
@@ -158,7 +157,7 @@ class VocabParallelEmbeddingWithLoRA(BaseLayerWithLoRA):
157 source_layer: nn.Module,
158 lora_config: LoRAConfig,
159 packed_modules_list: list,
161 - model_config: Optional[PretrainedConfig],
160 + model_config: PretrainedConfig | None,
161 ) -> bool:
162 return type(source_layer) is VocabParallelEmbedding
163
vllm/lora/lora_weights.py
+8 -8
@@ -21,8 +21,8 @@ class LoRALayerWeights:
21 lora_alpha: int,
22 lora_a: torch.Tensor,
23 lora_b: torch.Tensor,
24 - embeddings_tensor: Optional[torch.Tensor] = None,
25 - scaling: Optional[float] = None,
24 + embeddings_tensor: torch.Tensor | None = None,
25 + scaling: float | None = None,
26 ) -> None:
27 self.module_name = module_name
28 self.rank = rank
@@ -67,7 +67,7 @@ class LoRALayerWeights:
67 cls,
68 module_name: str,
69 peft_helper: PEFTHelper,
70 - embeddings_tensor: Optional[torch.Tensor] = None,
70 + embeddings_tensor: torch.Tensor | None = None,
71 ) -> "LoRALayerWeights":
72 # lora_a and lora_b are set to None for config-based construction
73 return cls(
@@ -89,7 +89,7 @@ class LoRALayerWeights:
89 rank: int,
90 dtype: torch.dtype,
91 device: torch.types.Device,
92 - embeddings_tensor_dim: Optional[int] = None,
92 + embeddings_tensor_dim: int | None = None,
93 ) -> "LoRALayerWeights":
94 pin_memory = str(device) == "cpu" and is_pin_memory_available()
95 lora_a = torch.zeros(
@@ -127,10 +127,10 @@ class PackedLoRALayerWeights(LoRALayerWeights):
127 self,
128 module_name: str,
129 rank: int,
130 - lora_alphas: list[Optional[int]],
131 - lora_a: list[Optional[torch.Tensor]],
132 - lora_b: list[Optional[torch.Tensor]],
133 - scaling: Optional[list[float]] = None,
130 + lora_alphas: list[int | None],
131 + lora_a: list[torch.Tensor | None],
132 + lora_b: list[torch.Tensor | None],
133 + scaling: list[float] | None = None,
134 ) -> None:
135 super().__init__(
136 module_name=module_name,
vllm/lora/models.py
+25 -24
@@ -3,7 +3,8 @@
3
4 import math
5 import os
6 -from typing import Callable, Optional, TypeVar, Union
6 +from collections.abc import Callable
7 +from typing import TypeVar
8
9 import regex as re
10 import safetensors.torch
@@ -44,7 +45,7 @@ class AdapterLRUCache(LRUCache[int, T]):
45 super().__init__(capacity)
46 self.deactivate_fn = deactivate_fn
47
47 - def _on_remove(self, key: int, value: Optional[T]):
48 + def _on_remove(self, key: int, value: T | None):
49 logger.debug("Removing adapter int id: %d", key)
50 self.deactivate_fn(key)
51 return super()._on_remove(key, value)
@@ -113,7 +114,7 @@ class LoRAModel:
114 else 0
115 )
116
116 - def get_lora(self, module_name: str) -> Optional[LoRALayerWeights]:
117 + def get_lora(self, module_name: str) -> LoRALayerWeights | None:
118 """Get LoRA for a given module by name"""
119 return self.loras.get(module_name, None)
120
@@ -128,12 +129,12 @@ class LoRAModel:
129 tensors: dict[str, torch.Tensor],
130 peft_helper: PEFTHelper,
131 device: str = "cuda",
131 - dtype: Optional[torch.dtype] = None,
132 - embeddings: Optional[dict[str, torch.Tensor]] = None,
133 - target_embedding_padding: Optional[int] = None,
134 - embedding_modules: Optional[dict[str, str]] = None,
135 - embedding_padding_modules: Optional[list[str]] = None,
136 - weights_mapper: Optional[WeightsMapper] = None,
132 + dtype: torch.dtype | None = None,
133 + embeddings: dict[str, torch.Tensor] | None = None,
134 + target_embedding_padding: int | None = None,
135 + embedding_modules: dict[str, str] | None = None,
136 + embedding_padding_modules: list[str] | None = None,
137 + weights_mapper: WeightsMapper | None = None,
138 ) -> "LoRAModel":
139 """Create a LoRAModel from a dictionary of tensors."""
140 pin_memory = str(device) == "cpu" and is_pin_memory_available()
@@ -191,14 +192,14 @@ class LoRAModel:
192 expected_lora_modules: list[str],
193 peft_helper: PEFTHelper,
194 *,
194 - lora_model_id: Optional[int] = None,
195 + lora_model_id: int | None = None,
196 device: str = "cuda",
196 - dtype: Optional[torch.dtype] = None,
197 - target_embedding_padding: Optional[int] = None,
198 - embedding_modules: Optional[dict[str, str]] = None,
199 - embedding_padding_modules: Optional[list[str]] = None,
200 - weights_mapper: Optional[WeightsMapper] = None,
201 - tensorizer_config_dict: Optional[dict] = None,
197 + dtype: torch.dtype | None = None,
198 + target_embedding_padding: int | None = None,
199 + embedding_modules: dict[str, str] | None = None,
200 + embedding_padding_modules: list[str] | None = None,
201 + weights_mapper: WeightsMapper | None = None,
202 + tensorizer_config_dict: dict | None = None,
203 ) -> "LoRAModel":
204 """Create a LoRAModel from a local checkpoint.
205
@@ -223,7 +224,7 @@ class LoRAModel:
224 )
225 new_embeddings_bin_file_path = os.path.join(lora_dir, "new_embeddings.bin")
226 tensors: dict[str, torch.Tensor] = {}
226 - unexpected_modules: list[Union[list[str], str]] = []
227 + unexpected_modules: list[list[str] | str] = []
228
229 def check_unexpected_modules(modules: dict):
230 for lora_module in modules.keys(): # noqa
@@ -357,7 +358,7 @@ class LoRAModelManager:
358 self.max_num_seqs = max_num_seqs
359 assert self.capacity >= self.lora_slots
360 self.max_num_batched_tokens = math.ceil(max_num_batched_tokens / 8) * 8
360 - self.lora_index_to_id: list[Optional[int]] = [None] * self.lora_slots
361 + self.lora_index_to_id: list[int | None] = [None] * self.lora_slots
362 self.vocab_size = vocab_size
363 self.punica_wrapper = get_punica_wrapper(
364 max_num_batched_tokens,
@@ -383,7 +384,7 @@ class LoRAModelManager:
384 self.packed_modules: dict[str, list[str]] = {}
385 self.modules: dict[str, BaseLayerWithLoRA] = {}
386 # Dict instead of a set for compatibility with LRUCache.
386 - self._last_mapping: Optional[LoRAMapping] = None
387 + self._last_mapping: LoRAMapping | None = None
388 self._create_lora_modules()
389 self.model.lora_manager = self
390
@@ -555,7 +556,7 @@ class LoRAModelManager:
556 self,
557 lora_id: int,
558 rank: int,
558 - embedding_modules: Optional[dict[str, str]] = None,
559 + embedding_modules: dict[str, str] | None = None,
560 ) -> LoRAModel:
561 """Create zero-initialized LoRAModel for warmup."""
562 model = LoRAModel(lora_id, rank, {})
@@ -607,7 +608,7 @@ class LoRAModelManager:
608 else:
609 parts = module_name.split(".")
610 replacements = self.packed_modules_mapping[parts[-1]]
610 - subloras: list[Optional[LoRALayerWeights]] = []
611 + subloras: list[LoRALayerWeights | None] = []
612 for i, r in enumerate(replacements):
613 lora = LoRALayerWeights.create_dummy_lora_weights(
614 module_name + "." + r,
@@ -658,7 +659,7 @@ class LoRAModelManager:
659
660 def _create_merged_loras_inplace(self, lora_model: LoRAModel) -> None:
661 for module_name, new_module_names in self.packed_modules.items():
661 - replacement_loras: list[Optional[LoRALayerWeights]] = []
662 + replacement_loras: list[LoRALayerWeights | None] = []
663 replaced_module: set[str] = set()
664 has_replacement = False
665 for r in new_module_names:
@@ -687,7 +688,7 @@ class LoRAModelManager:
688
689 def _get_lora_layer_weights(
690 self, lora_model: LoRAModel, module_name: str
690 - ) -> Optional[LoRALayerWeights]:
691 + ) -> LoRALayerWeights | None:
692 org_module_name = module_name
693 if self.is_pooling_model and not lora_model.check_lora_name(module_name):
694 # If it's a pool model, and the layer name is not found,
@@ -732,7 +733,7 @@ class LoRAModelManager:
733 def list_adapters(self) -> dict[int, LoRAModel]:
734 return dict(self._registered_adapters)
735
735 - def get_adapter(self, adapter_id: int) -> Optional[LoRAModel]:
736 + def get_adapter(self, adapter_id: int) -> LoRAModel | None:
737 return self._registered_adapters.get(adapter_id)
738
739
vllm/lora/ops/triton_ops/lora_kernel_metadata.py
+1 -2
@@ -5,7 +5,6 @@ LoRA kernels metadata preparation utilities.
5 """
6
7 from dataclasses import dataclass
8 -from typing import Union
8
9 import torch
10
@@ -31,7 +30,7 @@ class LoRAKernelMeta:
30
31 @staticmethod
32 def make(
34 - max_loras: int, max_num_tokens: int, device: Union[torch.device, str]
33 + max_loras: int, max_num_tokens: int, device: torch.device | str
34 ) -> "LoRAKernelMeta":
35 token_lora_mapping = torch.empty(
36 max_num_tokens, dtype=torch.int32, device=device
vllm/lora/peft_helper.py
+6 -6
@@ -7,7 +7,7 @@ import json
7 import math
8 import os
9 from dataclasses import MISSING, dataclass, field, fields
10 -from typing import Literal, Optional, Union
10 +from typing import Literal
11
12 from vllm.config.lora import LoRAConfig
13 from vllm.logger import init_logger
@@ -27,17 +27,17 @@ class PEFTHelper:
27 # Required fields
28 r: int
29 lora_alpha: int
30 - target_modules: Union[list[str], str]
30 + target_modules: list[str] | str
31
32 bias: Literal["none"] = field(default="none")
33 - modules_to_save: Optional[list[str]] = field(default=None)
33 + modules_to_save: list[str] | None = field(default=None)
34 # True to use Rank-Stabilized LoRA (rsLoRA, see: https://arxiv.org/abs/2312.03732)
35 use_rslora: bool = field(default=False)
36 # True to use Weight-Decomposed Low-Rank Adaptation (DoRA, see: https://arxiv.org/abs/2402.09353)
37 use_dora: bool = field(default=False)
38 # Extra vllm field, start with 'vllm_' to avoid conflict
39 vllm_lora_scaling_factor: float = field(default=1.0)
40 - vllm_max_position_embeddings: Optional[int] = field(default=False)
40 + vllm_max_position_embeddings: int | None = field(default=False)
41
42 def _validate_features(self) -> list[str]:
43 """
@@ -81,8 +81,8 @@ class PEFTHelper:
81 def from_local_dir(
82 cls,
83 lora_path: str,
84 - max_position_embeddings: Optional[int],
85 - tensorizer_config_dict: Optional[dict] = None,
84 + max_position_embeddings: int | None,
85 + tensorizer_config_dict: dict | None = None,
86 ) -> "PEFTHelper":
87 lora_config_path = os.path.join(lora_path, "adapter_config.json")
88
vllm/lora/punica_wrapper/punica_base.py
+24 -24
@@ -8,7 +8,7 @@ https://arxiv.org/abs/2310.18547
8 """
9
10 from abc import ABC, abstractmethod
11 -from typing import TYPE_CHECKING, Optional, Union
11 +from typing import TYPE_CHECKING
12
13 import torch
14
@@ -28,7 +28,7 @@ class PunicaWrapperABC(ABC):
28 def update_metadata(
29 self,
30 mapping: "LoRAMapping",
31 - lora_index_to_id: list[Optional[int]],
31 + lora_index_to_id: list[int | None],
32 max_loras: int,
33 vocab_size: int,
34 extra_vocab_size: int,
@@ -42,12 +42,12 @@ class PunicaWrapperABC(ABC):
42 @abstractmethod
43 def add_shrink(
44 self,
45 - y: Union[tuple[torch.Tensor, ...], torch.Tensor],
45 + y: tuple[torch.Tensor, ...] | torch.Tensor,
46 x: torch.Tensor,
47 lora_a_stacked: tuple[torch.Tensor, ...],
48 scale: float,
49 **kwargs,
50 - ) -> Optional[torch.Tensor]:
50 + ) -> torch.Tensor | None:
51 """
52 Performs GEMM for multiple slices of lora_a.
53 """
@@ -58,13 +58,13 @@ class PunicaWrapperABC(ABC):
58 def add_expand(
59 self,
60 y: torch.Tensor,
61 - x: Union[tuple[torch.Tensor, ...], torch.Tensor],
61 + x: tuple[torch.Tensor, ...] | torch.Tensor,
62 lora_b_stacked: tuple[torch.Tensor, ...],
63 output_slices: tuple[int, ...],
64 offset_start: int = 0,
65 add_inputs=True,
66 **kwargs,
67 - ) -> Optional[torch.Tensor]:
67 + ) -> torch.Tensor | None:
68 """
69 Performs GEMM for multiple slices of lora_b.
70 """
@@ -78,7 +78,7 @@ class PunicaWrapperABC(ABC):
78 lora_b_stacked: torch.Tensor,
79 add_inputs: bool = True,
80 **kwargs,
81 - ) -> Optional[torch.Tensor]:
81 + ) -> torch.Tensor | None:
82 """
83 Applies lora specifically for VocabParallelEmbeddingWithLoRA,
84 and this layer only requires the expand operation.
@@ -95,9 +95,9 @@ class PunicaWrapperABC(ABC):
95 scale: float,
96 output_slices: tuple[int, ...],
97 *,
98 - buffer: Optional[tuple[torch.Tensor, ...]] = None,
98 + buffer: tuple[torch.Tensor, ...] | None = None,
99 **kwargs,
100 - ) -> Optional[torch.Tensor]:
100 + ) -> torch.Tensor | None:
101 """
102 Applicable to linear-related lora.
103 """
@@ -113,9 +113,9 @@ class PunicaWrapperABC(ABC):
113 lora_b_stacked: torch.Tensor,
114 scale,
115 *,
116 - buffer: Optional[torch.Tensor] = None,
116 + buffer: torch.Tensor | None = None,
117 **kwargs,
118 - ) -> Optional[torch.Tensor]:
118 + ) -> torch.Tensor | None:
119 """
120 Applies lora specifically for LogitsProcessorWithLoRA.
121 """
@@ -133,7 +133,7 @@ class PunicaWrapperBase(PunicaWrapperABC):
133 self,
134 max_num_batched_tokens: int,
135 max_batches: int,
136 - device: Union[torch.device, str],
136 + device: torch.device | str,
137 **kwargs,
138 ):
139 self._token_lora_indices = torch.empty(
@@ -152,7 +152,7 @@ class PunicaWrapperBase(PunicaWrapperABC):
152 # 4 is the number of indices tensors.
153 # base_indices, sampler_indices, sampler_indices_padded,
154 # embeddings_indices
155 - self.indices_len: list[Optional[int]] = [None] * 4
155 + self.indices_len: list[int | None] = [None] * 4
156 # these attributes are the information required for sgmv kernel
157 self._seq_start_locs = torch.empty(max_batches, dtype=torch.long, device=device)
158 self._seq_lengths = torch.empty(max_batches, dtype=torch.long, device=device)
@@ -169,7 +169,7 @@ class PunicaWrapperBase(PunicaWrapperABC):
169 def _update_base_metadata(
170 self,
171 mapping: "LoRAMapping",
172 - lora_index_to_id: list[Optional[int]],
172 + lora_index_to_id: list[int | None],
173 max_loras: int,
174 vocab_size: int,
175 extra_vocab_size: int,
@@ -282,7 +282,7 @@ class PunicaWrapperBase(PunicaWrapperABC):
282 def update_metadata(
283 self,
284 mapping: "LoRAMapping",
285 - lora_index_to_id: list[Optional[int]],
285 + lora_index_to_id: list[int | None],
286 max_loras: int,
287 vocab_size: int,
288 extra_vocab_size: int,
@@ -302,12 +302,12 @@ class PunicaWrapperBase(PunicaWrapperABC):
302 @abstractmethod
303 def add_shrink(
304 self,
305 - y: Union[tuple[torch.Tensor, ...], torch.Tensor],
305 + y: tuple[torch.Tensor, ...] | torch.Tensor,
306 x: torch.Tensor,
307 lora_a_stacked: tuple[torch.Tensor, ...],
308 scale: float,
309 **kwargs,
310 - ) -> Optional[torch.Tensor]:
310 + ) -> torch.Tensor | None:
311 """
312 Performs GEMM for multiple slices of lora_a.
313
@@ -329,13 +329,13 @@ class PunicaWrapperBase(PunicaWrapperABC):
329 def add_expand(
330 self,
331 y: torch.Tensor,
332 - x: Union[tuple[torch.Tensor, ...], torch.Tensor],
332 + x: tuple[torch.Tensor, ...] | torch.Tensor,
333 lora_b_stacked: tuple[torch.Tensor, ...],
334 output_slices: tuple[int, ...],
335 offset_start: int = 0,
336 add_inputs=True,
337 **kwargs,
338 - ) -> Optional[torch.Tensor]:
338 + ) -> torch.Tensor | None:
339 """
340 Performs GEMM for multiple slices of lora_b.
341
@@ -366,7 +366,7 @@ class PunicaWrapperBase(PunicaWrapperABC):
366 lora_b_stacked: torch.Tensor,
367 add_inputs: bool = True,
368 **kwargs,
369 - ) -> Optional[torch.Tensor]:
369 + ) -> torch.Tensor | None:
370 """
371 Applies lora specifically for VocabParallelEmbeddingWithLoRA.
372 and this layer only requires the expand operation.
@@ -392,9 +392,9 @@ class PunicaWrapperBase(PunicaWrapperABC):
392 scale: float,
393 output_slices: tuple[int, ...],
394 *,
395 - buffer: Optional[tuple[torch.Tensor, ...]] = None,
395 + buffer: tuple[torch.Tensor, ...] | None = None,
396 **kwargs,
397 - ) -> Optional[torch.Tensor]:
397 + ) -> torch.Tensor | None:
398 """
399 Applicable to linear-related lora.
400
@@ -428,9 +428,9 @@ class PunicaWrapperBase(PunicaWrapperABC):
428 lora_b_stacked: torch.Tensor,
429 scale,
430 *,
431 - buffer: Optional[torch.Tensor] = None,
431 + buffer: torch.Tensor | None = None,
432 **kwargs,
433 - ) -> Optional[torch.Tensor]:
433 + ) -> torch.Tensor | None:
434 """
435 Applies lora specifically for LogitsProcessorWithLoRA.
436
vllm/lora/punica_wrapper/punica_cpu.py
+6 -6
@@ -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 Callable, Optional, Union
4 +from collections.abc import Callable
5
6 import torch
7
@@ -30,7 +30,7 @@ class PunicaWrapperCPU(PunicaWrapperBase):
30 self,
31 max_num_batched_tokens: int,
32 max_batches: int,
33 - device: Union[torch.device, str],
33 + device: torch.device | str,
34 **kwargs,
35 ):
36 PunicaWrapperBase.__init__(self, max_num_batched_tokens, max_batches, device)
@@ -165,7 +165,7 @@ class PunicaWrapperCPU(PunicaWrapperBase):
165
166 def add_shrink(
167 self,
168 - y: Union[tuple[torch.Tensor, ...], torch.Tensor],
168 + y: tuple[torch.Tensor, ...] | torch.Tensor,
169 x: torch.Tensor,
170 lora_a_stacked: tuple[torch.Tensor, ...],
171 scale: float,
@@ -197,7 +197,7 @@ class PunicaWrapperCPU(PunicaWrapperBase):
197 def add_expand(
198 self,
199 y: torch.Tensor,
200 - x: Union[tuple[torch.Tensor, ...], torch.Tensor],
200 + x: tuple[torch.Tensor, ...] | torch.Tensor,
201 lora_b_stacked: tuple[torch.Tensor, ...],
202 output_slices: tuple[int, ...],
203 offset_start: int = 0,
@@ -271,7 +271,7 @@ class PunicaWrapperCPU(PunicaWrapperBase):
271 scale: float,
272 output_slices: tuple[int, ...],
273 *,
274 - buffer: Optional[tuple[torch.Tensor, ...]] = None,
274 + buffer: tuple[torch.Tensor, ...] | None = None,
275 **kwargs,
276 ) -> None:
277 """
@@ -319,7 +319,7 @@ class PunicaWrapperCPU(PunicaWrapperBase):
319 lora_b_stacked: torch.Tensor,
320 scale,
321 *,
322 - buffer: Optional[torch.Tensor] = None,
322 + buffer: torch.Tensor | None = None,
323 **kwargs,
324 ) -> None:
325 """
vllm/lora/punica_wrapper/punica_gpu.py
+5 -5
@@ -7,7 +7,7 @@ Punica: Multi-Tenant LoRA Serving.
7 https://arxiv.org/abs/2310.18547
8 """
9
10 -from typing import Optional, Union, final
10 +from typing import final
11
12 import torch
13
@@ -32,7 +32,7 @@ class PunicaWrapperGPU(PunicaWrapperBase):
32 self,
33 max_num_batched_tokens: int,
34 max_batches: int,
35 - device: Union[torch.device, str],
35 + device: torch.device | str,
36 **kwargs,
37 ):
38 PunicaWrapperBase.__init__(self, max_num_batched_tokens, max_batches, device)
@@ -50,7 +50,7 @@ class PunicaWrapperGPU(PunicaWrapperBase):
50 def update_metadata(
51 self,
52 mapping: LoRAMapping,
53 - lora_index_to_id: list[Optional[int]],
53 + lora_index_to_id: list[int | None],
54 max_loras: int,
55 vocab_size: int,
56 extra_vocab_size: int,
@@ -179,7 +179,7 @@ class PunicaWrapperGPU(PunicaWrapperBase):
179 scale: float,
180 output_slices: tuple[int, ...],
181 *,
182 - buffer: Optional[torch.Tensor] = None,
182 + buffer: torch.Tensor | None = None,
183 **kwargs,
184 ) -> None:
185 """
@@ -238,7 +238,7 @@ class PunicaWrapperGPU(PunicaWrapperBase):
238 lora_b_stacked: torch.Tensor,
239 scale,
240 *,
241 - buffer: Optional[torch.Tensor] = None,
241 + buffer: torch.Tensor | None = None,
242 **kwargs,
243 ) -> None:
244 """
vllm/lora/punica_wrapper/punica_tpu.py
+8 -8
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import math
5 -from typing import TYPE_CHECKING, Optional, Union
5 +from typing import TYPE_CHECKING
6
7 import torch
8 import torch.nn.functional as F
@@ -29,7 +29,7 @@ class PunicaWrapperTPU(PunicaWrapperBase):
29 self,
30 max_num_batched_tokens: int,
31 max_batches: int,
32 - device: Union[torch.device, str],
32 + device: torch.device | str,
33 **kwargs,
34 ):
35 PunicaWrapperBase.__init__(self, max_num_batched_tokens, max_batches, device)
@@ -105,12 +105,12 @@ class PunicaWrapperTPU(PunicaWrapperBase):
105
106 def add_shrink(
107 self,
108 - y: Union[tuple[torch.Tensor, ...], torch.Tensor],
108 + y: tuple[torch.Tensor, ...] | torch.Tensor,
109 x: torch.Tensor,
110 lora_a_stacked: tuple[torch.Tensor, ...],
111 scale: float,
112 **kwargs,
113 - ) -> Optional[torch.Tensor]:
113 + ) -> torch.Tensor | None:
114 """
115 Performs GEMM for multiple slices of lora_a.
116
@@ -137,7 +137,7 @@ class PunicaWrapperTPU(PunicaWrapperBase):
137 def add_expand(
138 self,
139 y: torch.Tensor,
140 - x: Union[tuple[torch.Tensor, ...], torch.Tensor],
140 + x: tuple[torch.Tensor, ...] | torch.Tensor,
141 lora_b_stacked: tuple[torch.Tensor, ...],
142 output_slices: tuple[int, ...],
143 offset_start: int = 0,
@@ -209,7 +209,7 @@ class PunicaWrapperTPU(PunicaWrapperBase):
209 scale: float,
210 output_slices: tuple[int, ...],
211 *,
212 - buffer: Optional[tuple[torch.Tensor, ...]] = None,
212 + buffer: tuple[torch.Tensor, ...] | None = None,
213 **kwargs,
214 ) -> torch.Tensor:
215 """
@@ -257,7 +257,7 @@ class PunicaWrapperTPU(PunicaWrapperBase):
257 lora_b_stacked: torch.Tensor,
258 scale,
259 *,
260 - buffer: Optional[torch.Tensor] = None,
260 + buffer: torch.Tensor | None = None,
261 **kwargs,
262 ) -> torch.Tensor:
263 """
@@ -289,7 +289,7 @@ class PunicaWrapperTPU(PunicaWrapperBase):
289 def _update_base_metadata(
290 self,
291 mapping: "LoRAMapping",
292 - lora_index_to_id: list[Optional[int]],
292 + lora_index_to_id: list[int | None],
293 max_loras: int,
294 vocab_size: int,
295 extra_vocab_size: int,
vllm/lora/punica_wrapper/punica_xpu.py
+5 -5
@@ -7,7 +7,7 @@ Punica: Multi-Tenant LoRA Serving.
7 https://arxiv.org/abs/2310.18547
8 """
9
10 -from typing import Optional, Union, final
10 +from typing import final
11
12 import torch
13
@@ -29,7 +29,7 @@ class PunicaWrapperXPU(PunicaWrapperBase):
29 self,
30 max_num_batched_tokens: int,
31 max_batches: int,
32 - device: Union[torch.device, str],
32 + device: torch.device | str,
33 **kwargs,
34 ):
35 PunicaWrapperBase.__init__(self, max_num_batched_tokens, max_batches, device)
@@ -40,7 +40,7 @@ class PunicaWrapperXPU(PunicaWrapperBase):
40 def update_metadata(
41 self,
42 mapping: LoRAMapping,
43 - lora_index_to_id: list[Optional[int]],
43 + lora_index_to_id: list[int | None],
44 max_loras: int,
45 vocab_size: int,
46 extra_vocab_size: int,
@@ -180,7 +180,7 @@ class PunicaWrapperXPU(PunicaWrapperBase):
180 scale: float,
181 output_slices: tuple[int, ...],
182 *,
183 - buffer: Optional[torch.Tensor] = None,
183 + buffer: torch.Tensor | None = None,
184 **kwargs,
185 ) -> None:
186 """
@@ -247,7 +247,7 @@ class PunicaWrapperXPU(PunicaWrapperBase):
247 lora_b_stacked: torch.Tensor,
248 scale,
249 *,
250 - buffer: Optional[torch.Tensor] = None,
250 + buffer: torch.Tensor | None = None,
251 **kwargs,
252 ) -> None:
253 """
vllm/lora/punica_wrapper/utils.py
+3 -3
@@ -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, Optional, Union
4 +from typing import TYPE_CHECKING
5
6 import torch
7
@@ -51,7 +51,7 @@ def compute_meta(
51 # TODO see if this can be vectorized
52 def convert_mapping(
53 mapping: "LoRAMapping",
54 - lora_index_to_id: list[Optional[int]],
54 + lora_index_to_id: list[int | None],
55 max_loras: int,
56 vocab_size: int,
57 extra_vocab_size: int,
@@ -104,7 +104,7 @@ def convert_mapping(
104 embedding_indices[i] = lora_idx if index_mapping_indices[i] > 0 else 0
105 lora_indices[i] = lora_idx
106
107 - indices_list: list[Union[list[int], torch.Tensor]] = [
107 + indices_list: list[list[int] | torch.Tensor] = [
108 index_mapping_indices,
109 lora_indices,
110 embedding_indices,
vllm/lora/request.py
+4 -5
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import warnings
5 -from typing import Optional
5
6 import msgspec
7
@@ -27,10 +26,10 @@ class LoRARequest(
26 lora_name: str
27 lora_int_id: int
28 lora_path: str = ""
30 - lora_local_path: Optional[str] = msgspec.field(default=None)
31 - long_lora_max_len: Optional[int] = None
32 - base_model_name: Optional[str] = msgspec.field(default=None)
33 - tensorizer_config_dict: Optional[dict] = None
29 + lora_local_path: str | None = msgspec.field(default=None)
30 + long_lora_max_len: int | None = None
31 + base_model_name: str | None = msgspec.field(default=None)
32 + tensorizer_config_dict: dict | None = None
33
34 def __post_init__(self):
35 if self.lora_int_id < 1:
vllm/lora/resolver.py
+1 -2
@@ -4,7 +4,6 @@
4 from abc import ABC, abstractmethod
5 from collections.abc import Set
6 from dataclasses import dataclass, field
7 -from typing import Optional
7
8 from vllm.logger import init_logger
9 from vllm.lora.request import LoRARequest
@@ -24,7 +23,7 @@ class LoRAResolver(ABC):
23 @abstractmethod
24 async def resolve_lora(
25 self, base_model_name: str, lora_name: str
27 - ) -> Optional[LoRARequest]:
26 + ) -> LoRARequest | None:
27 """Abstract method to resolve and fetch a LoRA model adapter.
28
29 Implements logic to locate and download LoRA adapter based on the name.
vllm/lora/utils.py
+4 -4
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import os
5 -from typing import TYPE_CHECKING, Optional, Union
5 +from typing import TYPE_CHECKING, Optional
6
7 import huggingface_hub
8 import regex as re
@@ -66,7 +66,7 @@ def from_layer(
66 max_loras: int,
67 lora_config: LoRAConfig,
68 packed_modules_list: list,
69 - model_config: Optional[PretrainedConfig] = None,
69 + model_config: PretrainedConfig | None = None,
70 ) -> nn.Module:
71 for lora_cls in _all_lora_classes:
72 # specifying kwargs so they can be easily accessed in decorator
@@ -87,7 +87,7 @@ def from_layer_logits_processor(
87 lm_head: "ParallelLMHead",
88 max_loras: int,
89 lora_config: LoRAConfig,
90 - model_config: Optional[PretrainedConfig] = None,
90 + model_config: PretrainedConfig | None = None,
91 ) -> LogitsProcessorWithLoRA:
92 ret = LogitsProcessorWithLoRA(
93 layer,
@@ -155,7 +155,7 @@ def parse_fine_tuned_lora_name(
155
156
157 def is_regex_target_modules(
158 - load_modules: Union[str, list[str]], expected_lora_modules: list[str]
158 + load_modules: str | list[str], expected_lora_modules: list[str]
159 ) -> bool:
160 """
161 PEFT supports passing `target_modules` in the form of regular expressions,
vllm/lora/worker_manager.py
+3 -3
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from contextlib import contextmanager
5 -from typing import Any, Literal, Optional, Union
5 +from typing import Any, Literal
6
7 import torch
8
@@ -40,7 +40,7 @@ class WorkerLoRAManager:
40 self._lora_model_cls = lora_model_cls
41 self.embedding_modules = embedding_modules
42 self.embedding_padding_modules = embedding_padding_modules
43 - self._cached_dummy_lora: Union[None, Literal[False], LoRAModel] = False
43 + self._cached_dummy_lora: None | Literal[False] | LoRAModel = False
44 self.max_num_seqs = vllm_config.scheduler_config.max_num_seqs
45 self.max_num_batched_tokens = (
46 vllm_config.scheduler_config.max_num_batched_tokens
@@ -166,7 +166,7 @@ class WorkerLoRAManager:
166 def pin_adapter(self, adapter_id: int) -> bool:
167 return self._adapter_manager.pin_adapter(adapter_id)
168
169 - def set_active_adapters(self, requests: set[Any], mapping: Optional[Any]) -> None:
169 + def set_active_adapters(self, requests: set[Any], mapping: Any | None) -> None:
170 self._apply_adapters(requests)
171 if mapping is not None:
172 self._adapter_manager.set_adapter_mapping(mapping)
vllm/model_executor/custom_op.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch.nn as nn
6
@@ -171,7 +170,7 @@ class CustomOp(nn.Module):
170 # or
171 # - @CustomOP.register_oot(name="UnquantizedFusedMoEMethod")
172 @classmethod
174 - def register_oot(cls, _decorated_op_cls=None, name: Optional[str] = None):
173 + def register_oot(cls, _decorated_op_cls=None, name: str | None = None):
174 def decorator(op_cls):
175 reg_name = name if name is not None else cls.__name__
176 assert reg_name not in cls.op_registry_oot, f"Duplicate op name: {reg_name}"
vllm/model_executor/layers/activation.py
+1 -2
@@ -3,7 +3,6 @@
3 """Custom activation functions."""
4
5 import math
6 -from typing import Optional
6
7 import torch
8 import torch.nn as nn
@@ -486,7 +485,7 @@ class ScaledActivation(nn.Module):
485 act_module: nn.Module,
486 intermediate_size: int,
487 input_is_parallel: bool = True,
489 - params_dtype: Optional[torch.dtype] = None,
488 + params_dtype: torch.dtype | None = None,
489 ):
490 super().__init__()
491 self.act = act_module
vllm/model_executor/layers/batch_invariant.py
+4 -6
@@ -4,7 +4,7 @@ import contextlib
4 import os
5 from collections import namedtuple
6 from collections.abc import Callable
7 -from typing import Any, Union
7 +from typing import Any
8
9 import torch
10
@@ -138,7 +138,7 @@ def matmul_kernel_persistent(
138
139
140 def matmul_persistent(
141 - a: torch.Tensor, b: torch.Tensor, bias: Union[torch.Tensor, None] = None
141 + a: torch.Tensor, b: torch.Tensor, bias: torch.Tensor | None = None
142 ):
143 # Check constraints.
144 assert a.shape[1] == b.shape[0], "Incompatible dimensions"
@@ -375,7 +375,7 @@ def mean_dim(
375 input: torch.Tensor,
376 dim: int,
377 keepdim: bool = False,
378 - dtype: Union[torch.dtype, None] = None,
378 + dtype: torch.dtype | None = None,
379 ) -> torch.Tensor:
380 """
381 Triton implementation of torch.mean with single dimension reduction.
@@ -475,9 +475,7 @@ def _log_softmax_batch_invariant(input, dim, _half_to_float):
475 return log_softmax(input, dim=dim)
476
477
478 -def mean_batch_invariant(
479 - input, dim, keepdim=False, dtype: Union[torch.dtype, None] = None
480 -):
478 +def mean_batch_invariant(input, dim, keepdim=False, dtype: torch.dtype | None = None):
479 assert dtype is None or dtype == torch.float32, f"unsupported dtype: {dtype}"
480
481 result = input.to(torch.float32)
vllm/model_executor/layers/fla/ops/chunk.py
+3 -4
@@ -8,7 +8,6 @@
8 # Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
9 # ruff: noqa: E501
10 import warnings
11 -from typing import Optional
11
12 import torch
13 from einops import rearrange
@@ -32,7 +31,7 @@ def chunk_gated_delta_rule_fwd(
31 scale: float,
32 initial_state: torch.Tensor,
33 output_final_state: bool,
35 - cu_seqlens: Optional[torch.LongTensor] = None,
34 + cu_seqlens: torch.LongTensor | None = None,
35 ):
36 g = chunk_local_cumsum(g, chunk_size=64, cu_seqlens=cu_seqlens)
37 # obtain WY representation. u is actually the new v.
@@ -86,7 +85,7 @@ class ChunkGatedDeltaRuleFunction(torch.autograd.Function):
85 scale: float,
86 initial_state: torch.Tensor,
87 output_final_state: bool,
89 - cu_seqlens: Optional[torch.LongTensor] = None,
88 + cu_seqlens: torch.LongTensor | None = None,
89 use_qk_l2norm_in_kernel: bool = False,
90 ):
91 if use_qk_l2norm_in_kernel:
@@ -119,7 +118,7 @@ def chunk_gated_delta_rule(
118 scale: float = None,
119 initial_state: torch.Tensor = None,
120 output_final_state: bool = False,
122 - cu_seqlens: Optional[torch.LongTensor] = None,
121 + cu_seqlens: torch.LongTensor | None = None,
122 head_first: bool = False,
123 use_qk_l2norm_in_kernel: bool = False,
124 ):
vllm/model_executor/layers/fla/ops/chunk_delta_h.py
+3 -4
@@ -7,7 +7,6 @@
7 # the following copyright notice:
8 # Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
9 # ruff: noqa: E501
10 -from typing import Optional
10
11 import torch
12
@@ -257,12 +256,12 @@ def chunk_gated_delta_rule_fwd_h(
256 k: torch.Tensor,
257 w: torch.Tensor,
258 u: torch.Tensor,
260 - g: Optional[torch.Tensor] = None,
261 - initial_state: Optional[torch.Tensor] = None,
259 + g: torch.Tensor | None = None,
260 + initial_state: torch.Tensor | None = None,
261 output_final_state: bool = False,
262 chunk_size: int = 64, # SY: remove this argument and force chunk size 64?
263 save_new_value: bool = True,
265 - cu_seqlens: Optional[torch.LongTensor] = None,
264 + cu_seqlens: torch.LongTensor | None = None,
265 ) -> tuple[torch.Tensor, torch.Tensor]:
266 B, T, Hg, K, V = *k.shape, u.shape[-1]
267 H = u.shape[-2]
vllm/model_executor/layers/fla/ops/chunk_o.py
+3 -4
@@ -9,7 +9,6 @@
9
10 # ruff: noqa: E501
11
12 -from typing import Optional
12
13 import torch
14
@@ -144,9 +143,9 @@ def chunk_fwd_o(
143 k: torch.Tensor,
144 v: torch.Tensor,
145 h: torch.Tensor,
147 - g: Optional[torch.Tensor] = None, # cumsum of log decay
148 - scale: Optional[float] = None,
149 - cu_seqlens: Optional[torch.LongTensor] = None,
146 + g: torch.Tensor | None = None, # cumsum of log decay
147 + scale: float | None = None,
148 + cu_seqlens: torch.LongTensor | None = None,
149 chunk_size: int = 64,
150 ) -> torch.Tensor:
151 B, T, Hg, K, V = *q.shape, v.shape[-1]
vllm/model_executor/layers/fla/ops/chunk_scaled_dot_kkt.py
+2 -3
@@ -7,7 +7,6 @@
7 # the following copyright notice:
8 # Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
9 # ruff: noqa: E501
10 -from typing import Optional
10
11 import torch
12
@@ -104,8 +103,8 @@ def chunk_scaled_dot_kkt_fwd_kernel(
103 def chunk_scaled_dot_kkt_fwd(
104 k: torch.Tensor,
105 beta: torch.Tensor,
107 - g_cumsum: Optional[torch.Tensor] = None,
108 - cu_seqlens: Optional[torch.LongTensor] = None,
106 + g_cumsum: torch.Tensor | None = None,
107 + cu_seqlens: torch.LongTensor | None = None,
108 chunk_size: int = 64,
109 output_dtype: torch.dtype = torch.float32,
110 ) -> torch.Tensor:
vllm/model_executor/layers/fla/ops/cumsum.py
+6 -7
@@ -8,7 +8,6 @@
8 # Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
9 # ruff: noqa: E501
10 import warnings
11 -from typing import Optional
11
12 import torch
13
@@ -163,9 +162,9 @@ def chunk_local_cumsum_scalar(
162 g: torch.Tensor,
163 chunk_size: int,
164 reverse: bool = False,
166 - cu_seqlens: Optional[torch.Tensor] = None,
165 + cu_seqlens: torch.Tensor | None = None,
166 head_first: bool = False,
168 - output_dtype: Optional[torch.dtype] = torch.float,
167 + output_dtype: torch.dtype | None = torch.float,
168 ) -> torch.Tensor:
169 if head_first:
170 B, H, T = g.shape
@@ -200,9 +199,9 @@ def chunk_local_cumsum_vector(
199 g: torch.Tensor,
200 chunk_size: int,
201 reverse: bool = False,
203 - cu_seqlens: Optional[torch.Tensor] = None,
202 + cu_seqlens: torch.Tensor | None = None,
203 head_first: bool = False,
205 - output_dtype: Optional[torch.dtype] = torch.float,
204 + output_dtype: torch.dtype | None = torch.float,
205 ) -> torch.Tensor:
206 if head_first:
207 B, H, T, S = g.shape
@@ -248,9 +247,9 @@ def chunk_local_cumsum(
247 g: torch.Tensor,
248 chunk_size: int,
249 reverse: bool = False,
251 - cu_seqlens: Optional[torch.Tensor] = None,
250 + cu_seqlens: torch.Tensor | None = None,
251 head_first: bool = False,
253 - output_dtype: Optional[torch.dtype] = torch.float,
252 + output_dtype: torch.dtype | None = torch.float,
253 **kwargs,
254 ) -> torch.Tensor:
255 if not head_first and g.shape[1] < g.shape[2]:
vllm/model_executor/layers/fla/ops/fused_recurrent.py
+9 -10
@@ -7,7 +7,6 @@
7 # the following copyright notice:
8 # Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
9 # ruff: noqa: E501
10 -from typing import Optional
10
11 import torch
12
@@ -169,9 +168,9 @@ def fused_recurrent_gated_delta_rule_fwd(
168 scale: float,
169 initial_state: torch.Tensor,
170 inplace_final_state: bool = True,
172 - cu_seqlens: Optional[torch.LongTensor] = None,
173 - ssm_state_indices: Optional[torch.Tensor] = None,
174 - num_accepted_tokens: Optional[torch.Tensor] = None,
171 + cu_seqlens: torch.LongTensor | None = None,
172 + ssm_state_indices: torch.Tensor | None = None,
173 + num_accepted_tokens: torch.Tensor | None = None,
174 use_qk_l2norm_in_kernel: bool = False,
175 ) -> tuple[torch.Tensor, torch.Tensor]:
176 B, T, H, K, V = *k.shape, v.shape[-1]
@@ -248,9 +247,9 @@ class FusedRecurrentFunction(torch.autograd.Function):
247 scale: float,
248 initial_state: torch.Tensor,
249 inplace_final_state: bool = True,
251 - cu_seqlens: Optional[torch.LongTensor] = None,
252 - ssm_state_indices: Optional[torch.Tensor] = None,
253 - num_accepted_tokens: Optional[torch.Tensor] = None,
250 + cu_seqlens: torch.LongTensor | None = None,
251 + ssm_state_indices: torch.Tensor | None = None,
252 + num_accepted_tokens: torch.Tensor | None = None,
253 use_qk_l2norm_in_kernel: bool = False,
254 ):
255 o, final_state = fused_recurrent_gated_delta_rule_fwd(
@@ -280,9 +279,9 @@ def fused_recurrent_gated_delta_rule(
279 scale: float = None,
280 initial_state: torch.Tensor = None,
281 inplace_final_state: bool = True,
283 - cu_seqlens: Optional[torch.LongTensor] = None,
284 - ssm_state_indices: Optional[torch.Tensor] = None,
285 - num_accepted_tokens: Optional[torch.Tensor] = None,
282 + cu_seqlens: torch.LongTensor | None = None,
283 + ssm_state_indices: torch.Tensor | None = None,
284 + num_accepted_tokens: torch.Tensor | None = None,
285 use_qk_l2norm_in_kernel: bool = False,
286 ) -> tuple[torch.Tensor, torch.Tensor]:
287 r"""
vllm/model_executor/layers/fla/ops/l2norm.py
+1 -2
@@ -8,7 +8,6 @@
8 # Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
9
10 import os
11 -from typing import Optional
11
12 import torch
13
@@ -90,7 +89,7 @@ def l2norm_fwd_kernel2(X, Y, eps, M, N: tl.constexpr, MBLOCK: tl.constexpr):
89
90
91 def l2norm_fwd(
93 - x: torch.Tensor, eps: float = 1e-6, output_dtype: Optional[torch.dtype] = None
92 + x: torch.Tensor, eps: float = 1e-6, output_dtype: torch.dtype | None = None
93 ):
94 x_shape_og = x.shape
95 x = x.view(-1, x.shape[-1])
vllm/model_executor/layers/fla/ops/layernorm_guard.py
+6 -7
@@ -14,7 +14,6 @@
14 # The models we train have hidden dim up to 8k anyway (e.g. Llama 70B), so this is fine.
15
16 from functools import lru_cache
17 -from typing import Optional
17
18 import torch
19 import torch.nn as nn
@@ -324,10 +323,10 @@ class LayerNormGated(nn.Module):
323 self,
324 hidden_size,
325 eps: float = 1e-5,
327 - group_size: Optional[int] = None,
326 + group_size: int | None = None,
327 norm_before_gate: bool = True,
329 - device: Optional[torch.device] = None,
330 - dtype: Optional[torch.dtype] = None,
328 + device: torch.device | None = None,
329 + dtype: torch.dtype | None = None,
330 ):
331 """If group_size is not None, we do GroupNorm with each group having group_size elements.
332 group_size=None is equivalent to group_size=hidden_size (i.e. there's only 1 group).
@@ -364,10 +363,10 @@ class RMSNormGated(nn.Module):
363 self,
364 hidden_size,
365 eps: float = 1e-5,
367 - group_size: Optional[int] = None,
366 + group_size: int | None = None,
367 norm_before_gate: bool = False,
369 - device: Optional[torch.device] = None,
370 - dtype: Optional[torch.dtype] = None,
368 + device: torch.device | None = None,
369 + dtype: torch.dtype | None = None,
370 ):
371 """If group_size is not None, we do GroupNorm with each group having group_size elements.
372 group_size=None is equivalent to group_size=hidden_size (i.e. there's only 1 group).
vllm/model_executor/layers/fla/ops/solve_tril.py
+1 -2
@@ -7,7 +7,6 @@
7 # the following copyright notice:
8 # Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
9 # ruff: noqa: E501
10 -from typing import Optional
10
11 import torch
12
@@ -407,7 +406,7 @@ def merge_16x16_to_64x64_inverse_kernel(
406 @input_guard
407 def solve_tril(
408 A: torch.Tensor,
410 - cu_seqlens: Optional[torch.Tensor] = None,
409 + cu_seqlens: torch.Tensor | None = None,
410 output_dtype: torch.dtype = torch.float,
411 ) -> torch.Tensor:
412 """
vllm/model_executor/layers/fla/ops/utils.py
+3 -2
@@ -11,8 +11,9 @@ import contextlib
11 import functools
12 import logging
13 import os
14 +from collections.abc import Callable
15 from enum import Enum
15 -from typing import Any, Callable, Literal, Optional
16 +from typing import Any, Literal
17
18 import torch
19
@@ -43,7 +44,7 @@ def tensor_cache(fn: Callable[..., torch.Tensor]) -> Callable[..., torch.Tensor]
44 A wrapped version of the input function with single-entry caching.
45 """
46
46 - cache_entries: tuple[Optional[tuple], Optional[dict], Any] = []
47 + cache_entries: tuple[tuple | None, dict | None, Any] = []
48 cache_size = 4
49
50 @functools.wraps(fn)
vllm/model_executor/layers/fla/ops/wy_fast.py
+1 -2
@@ -8,7 +8,6 @@
8 # Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
9
10 # ruff: noqa: E501
11 -from typing import Optional
11
12 import torch
13
@@ -123,7 +122,7 @@ def recompute_w_u_fwd(
122 beta: torch.Tensor,
123 g_cumsum: torch.Tensor,
124 A: torch.Tensor,
126 - cu_seqlens: Optional[torch.LongTensor],
125 + cu_seqlens: torch.LongTensor | None,
126 ) -> tuple[torch.Tensor, torch.Tensor]:
127 B, T, Hg, K, V = *k.shape, v.shape[-1]
128 H = v.shape[-2]
vllm/model_executor/layers/fused_moe/__init__.py
+3 -3
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from contextlib import contextmanager
5 -from typing import Any, Optional
5 +from typing import Any
6
7 from vllm.model_executor.layers.fused_moe.config import FusedMoEConfig
8 from vllm.model_executor.layers.fused_moe.layer import (
@@ -19,7 +19,7 @@ from vllm.model_executor.layers.fused_moe.shared_fused_moe import SharedFusedMoE
19 from vllm.model_executor.layers.fused_moe.utils import activation_without_mul
20 from vllm.triton_utils import HAS_TRITON
21
22 -_config: Optional[dict[str, Any]] = None
22 +_config: dict[str, Any] | None = None
23
24
25 @contextmanager
@@ -31,7 +31,7 @@ def override_config(config):
31 _config = old_config
32
33
34 -def get_config() -> Optional[dict[str, Any]]:
34 +def get_config() -> dict[str, Any] | None:
35 return _config
36
37
vllm/model_executor/layers/fused_moe/batched_deep_gemm_moe.py
+5 -6
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -259,7 +258,7 @@ class BatchedDeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
258 topk: int,
259 global_num_experts: int,
260 local_num_experts: int,
262 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
261 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
262 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
263 # FIXME (varun): We should be able to dispatch only from the leader
264 # DP ranks in the case of TP > 1. At the moment, all the Ranks
@@ -282,12 +281,12 @@ class BatchedDeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
281 topk_ids: torch.Tensor,
282 activation: str,
283 global_num_experts: int,
285 - expert_map: Optional[torch.Tensor],
286 - a1q_scale: Optional[torch.Tensor],
287 - a2_scale: Optional[torch.Tensor],
284 + expert_map: torch.Tensor | None,
285 + a1q_scale: torch.Tensor | None,
286 + a2_scale: torch.Tensor | None,
287 workspace13: torch.Tensor,
288 workspace2: torch.Tensor,
290 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
289 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
290 apply_router_weight_on_input: bool,
291 ):
292 assert expert_tokens_meta is not None
vllm/model_executor/layers/fused_moe/batched_triton_or_deep_gemm_moe.py
+5 -6
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -110,7 +109,7 @@ class BatchedTritonOrDeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
109 topk: int,
110 global_num_experts: int,
111 local_num_experts: int,
113 - expert_tokens_metadata: Optional[mk.ExpertTokensMetadata],
112 + expert_tokens_metadata: mk.ExpertTokensMetadata | None,
113 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
114 # Note: the deep gemm workspaces are strictly larger than the triton
115 # workspaces so we can be pessimistic here and allocate for DeepGemm
@@ -148,12 +147,12 @@ class BatchedTritonOrDeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
147 topk_ids: torch.Tensor,
148 activation: str,
149 global_num_experts: int,
151 - expert_map: Optional[torch.Tensor],
152 - a1q_scale: Optional[torch.Tensor],
153 - a2_scale: Optional[torch.Tensor],
150 + expert_map: torch.Tensor | None,
151 + a1q_scale: torch.Tensor | None,
152 + a2_scale: torch.Tensor | None,
153 workspace13: torch.Tensor,
154 workspace2: torch.Tensor,
156 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
155 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
156 apply_router_weight_on_input: bool,
157 ):
158 experts = (
vllm/model_executor/layers/fused_moe/config.py
+64 -64
@@ -34,8 +34,8 @@ def _get_config_dtype_str(
34 use_fp8_w8a8: bool = False,
35 use_int8_w8a16: bool = False,
36 use_int4_w4a16: bool = False,
37 - ocp_mx_scheme: Optional[str] = None,
38 -) -> Optional[str]:
37 + ocp_mx_scheme: str | None = None,
38 +) -> str | None:
39 """
40 Return a string used to construct the filename that contains the
41 tuning info for a particular quantization scheme. See
@@ -60,16 +60,16 @@ def _get_config_dtype_str(
60
61
62 def _quant_flags_to_group_shape(
63 - quant_dtype: Union[torch.dtype, str, None],
63 + quant_dtype: torch.dtype | str | None,
64 per_act_token_quant: bool,
65 per_out_ch_quant: bool,
66 - block_shape: Optional[list[int]],
67 -) -> tuple[Optional[GroupShape], Optional[GroupShape]]:
66 + block_shape: list[int] | None,
67 +) -> tuple[GroupShape | None, GroupShape | None]:
68 """
69 Convert MoE quantization flags into more generic GroupShapes.
70 """
71 - a_shape: Optional[GroupShape]
72 - w_shape: Optional[GroupShape]
71 + a_shape: GroupShape | None
72 + w_shape: GroupShape | None
73 if block_shape is not None:
74 assert not per_act_token_quant
75 assert not per_out_ch_quant
@@ -100,7 +100,7 @@ class FusedMoEQuantDesc:
100 # The quantized type of this parameters. None means unquantized or
101 # already quantized.
102 # TODO (bnell): use scalar_type instead of Union.
103 - dtype: Union[torch.dtype, str, None] = None
103 + dtype: torch.dtype | str | None = None
104
105 # A field that describes the quantization group shape, from quant_utils.py.
106 # * (-1, -1) for per-tensor quantization
@@ -109,7 +109,7 @@ class FusedMoEQuantDesc:
109 # * (128, 128) for 128x128 deepseek style block quantization
110 # * (1, 128) for deepseek style activation quantization
111 # (i.e. per-token-per-group)
112 - shape: Optional[GroupShape] = None
112 + shape: GroupShape | None = None
113
114 # Quantization scales.
115 # TODO(bnell): maybe put PrecisionConfigs in subclass of QuantDesc?
@@ -117,13 +117,13 @@ class FusedMoEQuantDesc:
117
118 # Quantization alphas or gscales, used for nvfp4 types.
119 # TODO(bnell): put some of these in subclasses
120 - alpha_or_gscale: Optional[torch.Tensor] = None
120 + alpha_or_gscale: torch.Tensor | None = None
121
122 # Zero points for int4/int8 types
123 - zp: Optional[torch.Tensor] = None
123 + zp: torch.Tensor | None = None
124
125 # Biases for GPT triton MoE
126 - bias: Optional[torch.Tensor] = None
126 + bias: torch.Tensor | None = None
127
128
129 # TODO(bnell): have subclasses for specific moe methods?
@@ -179,7 +179,7 @@ class FusedMoEQuantConfig:
179 #
180
181 @property
182 - def quant_dtype(self) -> Union[torch.dtype, str, None]:
182 + def quant_dtype(self) -> torch.dtype | str | None:
183 return self._a1.dtype
184
185 @property
@@ -203,7 +203,7 @@ class FusedMoEQuantConfig:
203 return self._a1.shape == GroupShape.PER_TENSOR
204
205 @property
206 - def block_shape(self) -> Optional[list[int]]:
206 + def block_shape(self) -> list[int] | None:
207 if (
208 self._a1.shape is not None
209 and self._a1.shape != GroupShape.PER_TENSOR
@@ -218,34 +218,34 @@ class FusedMoEQuantConfig:
218 return self.block_shape is not None
219
220 @property
221 - def a1_scale(self) -> Optional[torch.Tensor]:
221 + def a1_scale(self) -> torch.Tensor | None:
222 assert self._a1.scale is None or isinstance(self._a1.scale, torch.Tensor)
223 return self._a1.scale
224
225 @property
226 - def a1_gscale(self) -> Optional[torch.Tensor]:
226 + def a1_gscale(self) -> torch.Tensor | None:
227 return self._a1.alpha_or_gscale
228
229 @property
230 - def a2_scale(self) -> Optional[torch.Tensor]:
230 + def a2_scale(self) -> torch.Tensor | None:
231 assert self._a2.scale is None or isinstance(self._a2.scale, torch.Tensor)
232 return self._a2.scale
233
234 @property
235 - def a2_gscale(self) -> Optional[torch.Tensor]:
235 + def a2_gscale(self) -> torch.Tensor | None:
236 return self._a2.alpha_or_gscale
237
238 @property
239 - def w1_scale(self) -> Optional[torch.Tensor]:
239 + def w1_scale(self) -> torch.Tensor | None:
240 assert self._w1.scale is None or isinstance(self._w1.scale, torch.Tensor)
241 return self._w1.scale
242
243 @property
244 - def w1_zp(self) -> Optional[torch.Tensor]:
244 + def w1_zp(self) -> torch.Tensor | None:
245 return self._w1.zp
246
247 @property
248 - def w1_bias(self) -> Optional[torch.Tensor]:
248 + def w1_bias(self) -> torch.Tensor | None:
249 return self._w1.bias
250
251 @property
@@ -254,20 +254,20 @@ class FusedMoEQuantConfig:
254 return self._w1.scale
255
256 @property
257 - def g1_alphas(self) -> Optional[torch.Tensor]:
257 + def g1_alphas(self) -> torch.Tensor | None:
258 return self._w1.alpha_or_gscale
259
260 @property
261 - def w2_scale(self) -> Optional[torch.Tensor]:
261 + def w2_scale(self) -> torch.Tensor | None:
262 assert self._w2.scale is None or isinstance(self._w2.scale, torch.Tensor)
263 return self._w2.scale
264
265 @property
266 - def w2_zp(self) -> Optional[torch.Tensor]:
266 + def w2_zp(self) -> torch.Tensor | None:
267 return self._w2.zp
268
269 @property
270 - def w2_bias(self) -> Optional[torch.Tensor]:
270 + def w2_bias(self) -> torch.Tensor | None:
271 return self._w2.bias
272
273 @property
@@ -276,7 +276,7 @@ class FusedMoEQuantConfig:
276 return self._w2.scale
277
278 @property
279 - def g2_alphas(self) -> Optional[torch.Tensor]:
279 + def g2_alphas(self) -> torch.Tensor | None:
280 return self._w2.alpha_or_gscale
281
282 @property
@@ -296,7 +296,7 @@ class FusedMoEQuantConfig:
296 return self._a1.dtype is None and self._w1.dtype == "int4"
297
298 @property
299 - def ocp_mx_scheme(self) -> Union[str, None]:
299 + def ocp_mx_scheme(self) -> str | None:
300 if not hasattr(self, "_ocp_mx_scheme"):
301 if (self._a1.dtype is not None and not isinstance(self._a1.dtype, str)) or (
302 self._w1.dtype is not None and not isinstance(self._w1.dtype, str)
@@ -322,7 +322,7 @@ class FusedMoEQuantConfig:
322 def use_nvfp4_w4a4(self) -> bool:
323 return self.quant_dtype == "nvfp4"
324
325 - def config_name(self, dtype: torch.dtype) -> Optional[str]:
325 + def config_name(self, dtype: torch.dtype) -> str | None:
326 """
327 Return a string used to construct the filename that contains the
328 tuning info for a particular quantization scheme. See
@@ -340,7 +340,7 @@ class FusedMoEQuantConfig:
340 self,
341 max_tokens: int,
342 hidden_dim: int,
343 - ) -> Optional[tuple[int, int]]:
343 + ) -> tuple[int, int] | None:
344 """
345 Construct the proper activation scale shape for this
346 config.
@@ -363,7 +363,7 @@ class FusedMoEQuantConfig:
363 num_experts: int,
364 max_tokens: int,
365 hidden_dim: int,
366 - ) -> Optional[tuple[int, int, int]]:
366 + ) -> tuple[int, int, int] | None:
367 """
368 Construct the proper activation batched scale shape for this
369 config, e.g. (num experts, *scale_shape).
@@ -377,23 +377,23 @@ class FusedMoEQuantConfig:
377
378 @staticmethod
379 def make(
380 - quant_dtype: Union[torch.dtype, str, None] = None,
380 + quant_dtype: torch.dtype | str | None = None,
381 per_act_token_quant: bool = False,
382 per_out_ch_quant: bool = False,
383 - block_shape: Optional[list[int]] = None,
383 + block_shape: list[int] | None = None,
384 w1_scale: Union[torch.Tensor, "PrecisionConfig", None] = None,
385 w2_scale: Union[torch.Tensor, "PrecisionConfig", None] = None,
386 - a1_scale: Optional[torch.Tensor] = None,
387 - a2_scale: Optional[torch.Tensor] = None,
388 - g1_alphas: Optional[torch.Tensor] = None,
389 - g2_alphas: Optional[torch.Tensor] = None,
390 - a1_gscale: Optional[torch.Tensor] = None,
391 - a2_gscale: Optional[torch.Tensor] = None,
392 - w1_bias: Optional[torch.Tensor] = None,
393 - w2_bias: Optional[torch.Tensor] = None,
394 - w1_zp: Optional[torch.Tensor] = None,
395 - w2_zp: Optional[torch.Tensor] = None,
396 - weight_dtype: Union[torch.dtype, str, None] = None,
386 + a1_scale: torch.Tensor | None = None,
387 + a2_scale: torch.Tensor | None = None,
388 + g1_alphas: torch.Tensor | None = None,
389 + g2_alphas: torch.Tensor | None = None,
390 + a1_gscale: torch.Tensor | None = None,
391 + a2_gscale: torch.Tensor | None = None,
392 + w1_bias: torch.Tensor | None = None,
393 + w2_bias: torch.Tensor | None = None,
394 + w1_zp: torch.Tensor | None = None,
395 + w2_zp: torch.Tensor | None = None,
396 + weight_dtype: torch.dtype | str | None = None,
397 ) -> "FusedMoEQuantConfig":
398 """
399 General builder function for a FusedMoEQuantConfig.
@@ -457,11 +457,11 @@ class FusedMoEQuantConfig:
457 def fp8_w8a8_moe_quant_config(
458 w1_scale: torch.Tensor,
459 w2_scale: torch.Tensor,
460 - a1_scale: Optional[torch.Tensor] = None,
461 - a2_scale: Optional[torch.Tensor] = None,
460 + a1_scale: torch.Tensor | None = None,
461 + a2_scale: torch.Tensor | None = None,
462 per_act_token_quant: bool = False,
463 per_out_ch_quant: bool = False,
464 - block_shape: Optional[list[int]] = None,
464 + block_shape: list[int] | None = None,
465 ) -> FusedMoEQuantConfig:
466 """
467 Construct a quant config for fp8 activations and fp8 weights.
@@ -481,8 +481,8 @@ def fp8_w8a8_moe_quant_config(
481 def int8_w8a8_moe_quant_config(
482 w1_scale: torch.Tensor,
483 w2_scale: torch.Tensor,
484 - a1_scale: Optional[torch.Tensor],
485 - a2_scale: Optional[torch.Tensor],
484 + a1_scale: torch.Tensor | None,
485 + a2_scale: torch.Tensor | None,
486 per_act_token_quant: bool = False,
487 ) -> FusedMoEQuantConfig:
488 """
@@ -503,8 +503,8 @@ def int8_w8a8_moe_quant_config(
503 def mxfp4_w4a16_moe_quant_config(
504 w1_scale: Union[torch.Tensor, "PrecisionConfig"],
505 w2_scale: Union[torch.Tensor, "PrecisionConfig"],
506 - w1_bias: Optional[torch.Tensor] = None,
507 - w2_bias: Optional[torch.Tensor] = None,
506 + w1_bias: torch.Tensor | None = None,
507 + w2_bias: torch.Tensor | None = None,
508 ) -> FusedMoEQuantConfig:
509 """
510 Construct a quant config for unquantized activations and mxfp4 weights.
@@ -521,12 +521,12 @@ def ocp_mx_moe_quant_config(
521 quant_dtype: str,
522 w1_scale: Union[torch.Tensor, "PrecisionConfig"],
523 w2_scale: Union[torch.Tensor, "PrecisionConfig"],
524 - weight_dtype: Optional[str] = None,
525 - a1_scale: Optional[torch.Tensor] = None,
526 - a2_scale: Optional[torch.Tensor] = None,
527 - w1_bias: Optional[torch.Tensor] = None,
528 - w2_bias: Optional[torch.Tensor] = None,
529 - block_shape: Optional[list[int]] = None,
524 + weight_dtype: str | None = None,
525 + a1_scale: torch.Tensor | None = None,
526 + a2_scale: torch.Tensor | None = None,
527 + w1_bias: torch.Tensor | None = None,
528 + w2_bias: torch.Tensor | None = None,
529 + block_shape: list[int] | None = None,
530 ) -> FusedMoEQuantConfig:
531 """
532 Construct a quant config for mxfp4 activations and mxfp4 weights.
@@ -575,9 +575,9 @@ def nvfp4_moe_quant_config(
575 def int4_w4a16_moe_quant_config(
576 w1_scale: torch.Tensor,
577 w2_scale: torch.Tensor,
578 - w1_zp: Optional[torch.Tensor],
579 - w2_zp: Optional[torch.Tensor],
580 - block_shape: Optional[list[int]] = None,
578 + w1_zp: torch.Tensor | None,
579 + w2_zp: torch.Tensor | None,
580 + block_shape: list[int] | None = None,
581 ) -> FusedMoEQuantConfig:
582 """
583 Construct a quant config for 16-bit float activations and int4 weights.
@@ -595,9 +595,9 @@ def int4_w4a16_moe_quant_config(
595 def int8_w8a16_moe_quant_config(
596 w1_scale: torch.Tensor,
597 w2_scale: torch.Tensor,
598 - w1_zp: Optional[torch.Tensor],
599 - w2_zp: Optional[torch.Tensor],
600 - block_shape: Optional[list[int]] = None,
598 + w1_zp: torch.Tensor | None,
599 + w2_zp: torch.Tensor | None,
600 + block_shape: list[int] | None = None,
601 ) -> FusedMoEQuantConfig:
602 """
603 Construct a quant config for 16-bit float activations and int8 weights.
@@ -613,8 +613,8 @@ def int8_w8a16_moe_quant_config(
613
614
615 def biased_moe_quant_config(
616 - w1_bias: Optional[torch.Tensor],
617 - w2_bias: Optional[torch.Tensor],
616 + w1_bias: torch.Tensor | None,
617 + w2_bias: torch.Tensor | None,
618 ) -> FusedMoEQuantConfig:
619 """
620 Construct a quant config for unquantized activations with biases.
vllm/model_executor/layers/fused_moe/cpu_fused_moe.py
+21 -21
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Callable, Optional
3 +from collections.abc import Callable
4
5 import torch
6 from torch.nn import functional as F
@@ -33,7 +33,7 @@ def grouped_topk(
33 topk_group: int = 0,
34 scoring_func: str = "softmax",
35 routed_scaling_factor: float = 1.0,
36 - e_score_correction_bias: Optional[torch.Tensor] = None,
36 + e_score_correction_bias: torch.Tensor | None = None,
37 ) -> tuple[torch.Tensor, torch.Tensor]:
38 assert hidden_states.shape[0] == gating_output.shape[0], "Number of tokens mismatch"
39
@@ -88,12 +88,12 @@ def select_experts(
88 top_k: int,
89 use_grouped_topk: bool,
90 renormalize: bool,
91 - topk_group: Optional[int] = None,
92 - num_expert_group: Optional[int] = None,
93 - custom_routing_function: Optional[Callable] = None,
91 + topk_group: int | None = None,
92 + num_expert_group: int | None = None,
93 + custom_routing_function: Callable | None = None,
94 scoring_func: str = "softmax",
95 routed_scaling_factor: float = 1.0,
96 - e_score_correction_bias: Optional[torch.Tensor] = None,
96 + e_score_correction_bias: torch.Tensor | None = None,
97 ) -> tuple[torch.Tensor, torch.Tensor]:
98 if use_grouped_topk:
99 assert topk_group is not None
@@ -147,14 +147,14 @@ class IPEXFusedMOE:
147 top_k: int,
148 router_logits: torch.Tensor,
149 renormalize: bool,
150 - topk_group: Optional[int] = None,
151 - num_expert_group: Optional[int] = None,
150 + topk_group: int | None = None,
151 + num_expert_group: int | None = None,
152 global_num_experts: int = -1,
153 - expert_map: Optional[torch.Tensor] = None,
154 - custom_routing_function: Optional[Callable] = None,
153 + expert_map: torch.Tensor | None = None,
154 + custom_routing_function: Callable | None = None,
155 scoring_func: str = "softmax",
156 routed_scaling_factor: float = 1.0,
157 - e_score_correction_bias: Optional[torch.Tensor] = None,
157 + e_score_correction_bias: torch.Tensor | None = None,
158 apply_router_weight_on_input: bool = False,
159 activation: str = "silu",
160 ) -> torch.Tensor:
@@ -189,14 +189,14 @@ class SGLFusedMOE:
189 top_k: int,
190 router_logits: torch.Tensor,
191 renormalize: bool,
192 - topk_group: Optional[int] = None,
193 - num_expert_group: Optional[int] = None,
192 + topk_group: int | None = None,
193 + num_expert_group: int | None = None,
194 global_num_experts: int = -1,
195 - expert_map: Optional[torch.Tensor] = None,
196 - custom_routing_function: Optional[Callable] = None,
195 + expert_map: torch.Tensor | None = None,
196 + custom_routing_function: Callable | None = None,
197 scoring_func: str = "softmax",
198 routed_scaling_factor: float = 1.0,
199 - e_score_correction_bias: Optional[torch.Tensor] = None,
199 + e_score_correction_bias: torch.Tensor | None = None,
200 apply_router_weight_on_input: bool = False,
201 activation: str = "silu",
202 ) -> torch.Tensor:
@@ -247,14 +247,14 @@ class CPUFusedMOE:
247 top_k: int,
248 router_logits: torch.Tensor,
249 renormalize: bool,
250 - topk_group: Optional[int] = None,
251 - num_expert_group: Optional[int] = None,
250 + topk_group: int | None = None,
251 + num_expert_group: int | None = None,
252 global_num_experts: int = -1,
253 - expert_map: Optional[torch.Tensor] = None,
254 - custom_routing_function: Optional[Callable] = None,
253 + expert_map: torch.Tensor | None = None,
254 + custom_routing_function: Callable | None = None,
255 scoring_func: str = "softmax",
256 routed_scaling_factor: float = 1.0,
257 - e_score_correction_bias: Optional[torch.Tensor] = None,
257 + e_score_correction_bias: torch.Tensor | None = None,
258 apply_router_weight_on_input: bool = False,
259 activation: str = "silu",
260 ) -> torch.Tensor:
vllm/model_executor/layers/fused_moe/cutlass_moe.py
+27 -27
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """CUTLASS based Fused MoE kernels."""
4
5 -from typing import Callable, Optional
5 +from collections.abc import Callable
6
7 import torch
8
@@ -35,23 +35,23 @@ def run_cutlass_moe_fp8(
35 topk_ids: torch.Tensor,
36 activation_callable: Callable,
37 global_num_experts: int,
38 - expert_map: Optional[torch.Tensor],
39 - w1_scale: Optional[torch.Tensor],
40 - w2_scale: Optional[torch.Tensor],
41 - a1q_scale: Optional[torch.Tensor],
42 - a2_scale: Optional[torch.Tensor],
38 + expert_map: torch.Tensor | None,
39 + w1_scale: torch.Tensor | None,
40 + w2_scale: torch.Tensor | None,
41 + a1q_scale: torch.Tensor | None,
42 + a2_scale: torch.Tensor | None,
43 ab_strides1: torch.Tensor,
44 ab_strides2: torch.Tensor,
45 c_strides1: torch.Tensor,
46 c_strides2: torch.Tensor,
47 workspace13: torch.Tensor,
48 workspace2: torch.Tensor,
49 - expert_num_tokens: Optional[torch.Tensor],
49 + expert_num_tokens: torch.Tensor | None,
50 out_dtype: torch.dtype,
51 per_act_token: bool,
52 per_out_ch: bool,
53 use_batched_format: bool,
54 - topk_weights: Optional[torch.Tensor],
54 + topk_weights: torch.Tensor | None,
55 ):
56 a1q = hidden_states
57
@@ -249,7 +249,7 @@ def run_cutlass_moe_fp8(
249 class CutlassExpertsFp8Base(mk.FusedMoEPermuteExpertsUnpermute):
250 def __init__(
251 self,
252 - out_dtype: Optional[torch.dtype],
252 + out_dtype: torch.dtype | None,
253 ab_strides1: torch.Tensor,
254 ab_strides2: torch.Tensor,
255 c_strides1: torch.Tensor,
@@ -278,12 +278,12 @@ class CutlassExpertsFp8Base(mk.FusedMoEPermuteExpertsUnpermute):
278 topk_ids: torch.Tensor,
279 activation: str,
280 global_num_experts: int,
281 - expert_map: Optional[torch.Tensor],
282 - a1q_scale: Optional[torch.Tensor],
283 - a2_scale: Optional[torch.Tensor],
281 + expert_map: torch.Tensor | None,
282 + a1q_scale: torch.Tensor | None,
283 + a2_scale: torch.Tensor | None,
284 workspace13: torch.Tensor,
285 workspace2: torch.Tensor,
286 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
286 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
287 apply_router_weight_on_input: bool,
288 ):
289 assert self.w1_zp is None, "w1_zp is not supported in CUTLASS MoE"
@@ -331,7 +331,7 @@ class CutlassExpertsFp8Base(mk.FusedMoEPermuteExpertsUnpermute):
331 class CutlassExpertsFp8(CutlassExpertsFp8Base):
332 def __init__(
333 self,
334 - out_dtype: Optional[torch.dtype],
334 + out_dtype: torch.dtype | None,
335 ab_strides1: torch.Tensor,
336 ab_strides2: torch.Tensor,
337 c_strides1: torch.Tensor,
@@ -377,7 +377,7 @@ class CutlassExpertsFp8(CutlassExpertsFp8Base):
377 topk: int,
378 global_num_experts: int,
379 local_num_experts: int,
380 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
380 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
381 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
382 workspace1 = (M * topk, max(N, K))
383 workspace2 = (M * topk, max(N // 2, K))
@@ -390,7 +390,7 @@ class CutlassBatchedExpertsFp8(CutlassExpertsFp8Base):
390 self,
391 max_experts_per_worker: int,
392 num_dispatchers: int,
393 - out_dtype: Optional[torch.dtype],
393 + out_dtype: torch.dtype | None,
394 ab_strides1: torch.Tensor,
395 ab_strides2: torch.Tensor,
396 c_strides1: torch.Tensor,
@@ -435,7 +435,7 @@ class CutlassBatchedExpertsFp8(CutlassExpertsFp8Base):
435 topk: int,
436 global_num_experts: int,
437 local_num_experts: int,
438 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
438 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
439 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
440 num_dp = self.num_dispatchers
441 assert num_dp is not None
@@ -457,7 +457,7 @@ def cutlass_moe_fp8(
457 c_strides2: torch.Tensor,
458 quant_config: FusedMoEQuantConfig,
459 activation: str = "silu",
460 - expert_map: Optional[torch.Tensor] = None,
460 + expert_map: torch.Tensor | None = None,
461 apply_router_weight_on_input: bool = False,
462 global_num_experts: int = -1,
463 ) -> torch.Tensor:
@@ -768,7 +768,7 @@ class CutlassExpertsFp4(mk.FusedMoEPermuteExpertsUnpermute):
768 topk: int,
769 global_num_experts: int,
770 local_num_experts: int,
771 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
771 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
772 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
773 workspace1: tuple[int, ...] = ()
774 workspace2: tuple[int, ...] = ()
@@ -793,12 +793,12 @@ class CutlassExpertsFp4(mk.FusedMoEPermuteExpertsUnpermute):
793 topk_ids: torch.Tensor,
794 activation: str,
795 global_num_experts: int,
796 - expert_map: Optional[torch.Tensor],
797 - a1q_scale: Optional[torch.Tensor], # unused
798 - a2_scale: Optional[torch.Tensor], # unused
799 - workspace13: Optional[torch.Tensor],
800 - workspace2: Optional[torch.Tensor],
801 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
796 + expert_map: torch.Tensor | None,
797 + a1q_scale: torch.Tensor | None, # unused
798 + a2_scale: torch.Tensor | None, # unused
799 + workspace13: torch.Tensor | None,
800 + workspace2: torch.Tensor | None,
801 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
802 apply_router_weight_on_input: bool,
803 ):
804 e, m, n, k, _ = self.moe_problem_size(hidden_states, w1, w2, topk_ids)
@@ -839,7 +839,7 @@ def cutlass_moe_fp4(
839 n: int,
840 k: int,
841 e: int,
842 - expert_map: Optional[torch.Tensor] = None,
842 + expert_map: torch.Tensor | None = None,
843 apply_router_weight_on_input: bool = False,
844 ) -> torch.Tensor:
845 assert expert_map is None, (
@@ -896,7 +896,7 @@ def _valid_cutlass_block_scaled_grouped_gemm(
896 inplace: bool,
897 activation: str,
898 apply_router_weight_on_input: bool,
899 - expert_map: Optional[torch.Tensor],
899 + expert_map: torch.Tensor | None,
900 ) -> bool:
901 def _valid_cutlass_block_scaled_grouped_gemm_shape(N: int, K: int):
902 return N % 128 == 0 and K % 128 == 0
vllm/model_executor/layers/fused_moe/deep_gemm_moe.py
+9 -10
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5 from tqdm import tqdm
@@ -204,7 +203,7 @@ class DeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
203 topk: int,
204 global_num_experts: int,
205 local_num_experts: int,
207 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
206 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
207 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
208 assert self.block_shape is not None
209 block_m = self.block_shape[0]
@@ -228,12 +227,12 @@ class DeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
227 topk_ids: torch.Tensor,
228 activation: str,
229 global_num_experts: int,
231 - expert_map: Optional[torch.Tensor],
232 - a1q_scale: Optional[torch.Tensor],
233 - a2_scale: Optional[torch.Tensor],
230 + expert_map: torch.Tensor | None,
231 + a1q_scale: torch.Tensor | None,
232 + a2_scale: torch.Tensor | None,
233 workspace13: torch.Tensor,
234 workspace2: torch.Tensor,
236 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
235 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
236 apply_router_weight_on_input: bool,
237 ):
238 assert a1q_scale is not None
@@ -284,7 +283,7 @@ class DeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
283
284 self.activation(activation, act_out, mm1_out.view(-1, N))
285
287 - a2q_scale: Optional[torch.Tensor] = None
286 + a2q_scale: torch.Tensor | None = None
287 a2q, a2q_scale = per_token_group_quant_fp8(
288 act_out, self.block_shape[1], column_major_scales=True, out_q=quant_out
289 )
@@ -317,9 +316,9 @@ def deep_gemm_moe_fp8(
316 inplace: bool = False,
317 activation: str = "silu",
318 global_num_experts: int = -1,
320 - expert_map: Optional[torch.Tensor] = None,
321 - a1_scale: Optional[torch.Tensor] = None,
322 - a2_scale: Optional[torch.Tensor] = None,
319 + expert_map: torch.Tensor | None = None,
320 + a1_scale: torch.Tensor | None = None,
321 + a2_scale: torch.Tensor | None = None,
322 apply_router_weight_on_input=False,
323 ) -> torch.Tensor:
324 """
vllm/model_executor/layers/fused_moe/deep_gemm_utils.py
+7 -8
@@ -6,7 +6,6 @@ and updated to fit vllm needs and terminology.
6 """
7
8 import functools
9 -from typing import Optional
9
10 import torch
11
@@ -39,7 +38,7 @@ def compute_aligned_M(
38 num_topk: int,
39 local_num_experts: int,
40 alignment: int,
42 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
41 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
42 ):
43 if (expert_tokens_meta is not None) and (
44 expert_tokens_meta.expert_num_tokens_cpu is not None
@@ -175,7 +174,7 @@ def ep_scatter(
174 recv_x_scale: torch.Tensor,
175 recv_topk: torch.Tensor,
176 num_recv_tokens_per_expert: torch.Tensor,
178 - expert_map: Optional[torch.Tensor],
177 + expert_map: torch.Tensor | None,
178 expert_start_loc: torch.Tensor,
179 output_tensor: torch.Tensor,
180 output_tensor_scale: torch.Tensor,
@@ -305,7 +304,7 @@ def ep_gather(
304 recv_topk_ids: torch.Tensor,
305 recv_topk_weight: torch.Tensor,
306 input_index: torch.Tensor,
308 - expert_map: Optional[torch.Tensor],
307 + expert_map: torch.Tensor | None,
308 output_tensor: torch.Tensor,
309 ):
310 num_warps = 2
@@ -346,9 +345,9 @@ def deepgemm_moe_permute(
345 aq_scale: torch.Tensor,
346 topk_ids: torch.Tensor,
347 local_num_experts: int,
349 - expert_map: Optional[torch.Tensor],
350 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
351 - aq_out: Optional[torch.Tensor] = None,
348 + expert_map: torch.Tensor | None,
349 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
350 + aq_out: torch.Tensor | None = None,
351 ):
352 assert aq.ndim == 2
353 assert topk_ids.dtype.is_signed, "The kernel uses -1 to represent invalid topk_ids"
@@ -415,7 +414,7 @@ def deepgemm_unpermute_and_reduce(
414 topk_ids: torch.Tensor,
415 topk_weights: torch.Tensor,
416 inv_perm: torch.Tensor,
418 - expert_map: Optional[torch.Tensor],
417 + expert_map: torch.Tensor | None,
418 output: torch.Tensor,
419 ):
420 return ep_gather(
vllm/model_executor/layers/fused_moe/deepep_ht_prepare_finalize.py
+14 -14
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Callable, Optional, Union
3 +from collections.abc import Callable
4
5 import deep_ep
6 import torch
@@ -77,18 +77,18 @@ class DeepEPHTPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
77 def activation_format(self) -> mk.FusedMoEActivationFormat:
78 return mk.FusedMoEActivationFormat.Standard
79
80 - def max_num_tokens_per_rank(self) -> Optional[int]:
80 + def max_num_tokens_per_rank(self) -> int | None:
81 return None
82
83 - def topk_indices_dtype(self) -> Optional[torch.dtype]:
83 + def topk_indices_dtype(self) -> torch.dtype | None:
84 return torch.int64
85
86 - def _get_dispatch_config(self) -> Optional[deep_ep.Config]:
86 + def _get_dispatch_config(self) -> deep_ep.Config | None:
87 if self.num_dispatchers_ not in self.available_rank_configs:
88 return None
89 return deep_ep.Buffer.get_dispatch_config(self.num_dispatchers_)
90
91 - def _get_combine_config(self) -> Optional[deep_ep.Config]:
91 + def _get_combine_config(self) -> deep_ep.Config | None:
92 if self.num_dispatchers_ not in self.available_rank_configs:
93 return None
94 return deep_ep.Buffer.get_combine_config(self.num_dispatchers_)
@@ -96,11 +96,11 @@ class DeepEPHTPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
96 def _do_dispatch(
97 self,
98 tokens: torch.Tensor,
99 - token_scales: Optional[torch.Tensor],
99 + token_scales: torch.Tensor | None,
100 rank_topk_ids: torch.Tensor,
101 rank_topk_weights: torch.Tensor,
102 num_experts: int,
103 - a1_scale: Optional[torch.Tensor],
103 + a1_scale: torch.Tensor | None,
104 quant_config: FusedMoEQuantConfig,
105 ) -> Callable:
106 has_scales = token_scales is not None
@@ -175,12 +175,12 @@ class DeepEPHTPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
175 self,
176 event: deep_ep.EventOverlap,
177 has_scales: bool,
178 - token_data: Union[tuple[torch.Tensor, torch.Tensor], torch.Tensor],
179 - expert_topk_ids: Optional[torch.Tensor],
178 + token_data: tuple[torch.Tensor, torch.Tensor] | torch.Tensor,
179 + expert_topk_ids: torch.Tensor | None,
180 num_experts: int,
181 expert_num_tokens_per_expert_list: list[int],
182 - expert_topk_weights: Optional[torch.Tensor],
183 - a1_scale: Optional[torch.Tensor],
182 + expert_topk_weights: torch.Tensor | None,
183 + a1_scale: torch.Tensor | None,
184 quant_config: FusedMoEQuantConfig,
185 ) -> mk.PrepareResultType:
186 if event.event is not None:
@@ -249,7 +249,7 @@ class DeepEPHTPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
249 topk_weights: torch.Tensor,
250 topk_ids: torch.Tensor,
251 num_experts: int,
252 - expert_map: Optional[torch.Tensor],
252 + expert_map: torch.Tensor | None,
253 apply_router_weight_on_input: bool,
254 quant_config: FusedMoEQuantConfig,
255 ) -> mk.ReceiverType:
@@ -294,7 +294,7 @@ class DeepEPHTPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
294 topk_weights: torch.Tensor,
295 topk_ids: torch.Tensor,
296 num_experts: int,
297 - expert_map: Optional[torch.Tensor],
297 + expert_map: torch.Tensor | None,
298 apply_router_weight_on_input: bool,
299 quant_config: FusedMoEQuantConfig,
300 ) -> mk.PrepareResultType:
@@ -318,7 +318,7 @@ class DeepEPHTPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
318 apply_router_weight_on_input: bool,
319 weight_and_reduce_impl: mk.TopKWeightAndReduce,
320 do_async: bool,
321 - ) -> Optional[Callable]:
321 + ) -> Callable | None:
322 a2a_idx = dbo_current_ubatch_id()
323 handle = self.handles[a2a_idx]
324 assert handle is not None
vllm/model_executor/layers/fused_moe/deepep_ll_prepare_finalize.py
+10 -10
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Callable, Optional, Union
3 +from collections.abc import Callable
4
5 import deep_ep
6 import torch
@@ -67,7 +67,7 @@ class DeepEPLLPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
67 # The dispatch function returns a handle that the combine function
68 # requires. We store the handle here so it is available to the
69 # combine function.
70 - self.handles: list[Optional[tuple]] = [None, None]
70 + self.handles: list[tuple | None] = [None, None]
71 self.num_dispatchers_ = num_dispatchers
72
73 def num_dispatchers(self) -> int:
@@ -80,18 +80,18 @@ class DeepEPLLPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
80 def activation_format(self) -> mk.FusedMoEActivationFormat:
81 return mk.FusedMoEActivationFormat.BatchedExperts
82
83 - def max_num_tokens_per_rank(self) -> Optional[int]:
83 + def max_num_tokens_per_rank(self) -> int | None:
84 return self.max_tokens_per_rank
85
86 - def topk_indices_dtype(self) -> Optional[torch.dtype]:
86 + def topk_indices_dtype(self) -> torch.dtype | None:
87 return torch.int64
88
89 def _do_quant(
90 self,
91 - x: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
91 + x: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
92 a1_dtype: torch.dtype,
93 quant_config: FusedMoEQuantConfig,
94 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
94 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
95 if self.use_fp8_dispatch:
96 block_k = (
97 quant_config.block_shape[1]
@@ -137,7 +137,7 @@ class DeepEPLLPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
137 topk_weights: torch.Tensor,
138 topk_ids: torch.Tensor,
139 num_experts: int,
140 - expert_map: Optional[torch.Tensor],
140 + expert_map: torch.Tensor | None,
141 apply_router_weight_on_input: bool,
142 quant_config: FusedMoEQuantConfig,
143 ) -> tuple[Callable, mk.ReceiverType]:
@@ -200,9 +200,9 @@ class DeepEPLLPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
200
201 def _receiver(
202 self,
203 - expert_x: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
203 + expert_x: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
204 expert_num_tokens: torch.Tensor,
205 - a1_scale: Optional[torch.Tensor],
205 + a1_scale: torch.Tensor | None,
206 a1_dtype: torch.dtype,
207 quant_config: FusedMoEQuantConfig,
208 ) -> mk.PrepareResultType:
@@ -220,7 +220,7 @@ class DeepEPLLPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
220 topk_weights: torch.Tensor,
221 topk_ids: torch.Tensor,
222 num_experts: int,
223 - expert_map: Optional[torch.Tensor],
223 + expert_map: torch.Tensor | None,
224 apply_router_weight_on_input: bool,
225 quant_config: FusedMoEQuantConfig,
226 ) -> mk.PrepareResultType:
vllm/model_executor/layers/fused_moe/flashinfer_cutlass_moe.py
+10 -11
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -96,7 +95,7 @@ class FlashInferExperts(mk.FusedMoEPermuteExpertsUnpermute):
95 topk: int,
96 global_num_experts: int,
97 local_num_experts: int,
99 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
98 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
99 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
100 # We use global_num_experts due to how moe_align_block_size handles
101 # expert_maps.
@@ -133,13 +132,13 @@ class FlashInferExperts(mk.FusedMoEPermuteExpertsUnpermute):
132 topk_ids: torch.Tensor,
133 activation: str,
134 global_num_experts: int,
136 - expert_map: Optional[torch.Tensor],
137 - a1q_scale: Optional[torch.Tensor],
138 - a2_scale: Optional[torch.Tensor],
139 - workspace13: Optional[torch.Tensor],
140 - workspace2: Optional[torch.Tensor],
141 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
142 - apply_router_weight_on_input: Optional[bool],
135 + expert_map: torch.Tensor | None,
136 + a1q_scale: torch.Tensor | None,
137 + a2_scale: torch.Tensor | None,
138 + workspace13: torch.Tensor | None,
139 + workspace2: torch.Tensor | None,
140 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
141 + apply_router_weight_on_input: bool | None,
142 ):
143 assert activation == "silu", (
144 "Only activation silu is supported in FlashInferExperts"
@@ -207,7 +206,7 @@ def flashinfer_cutlass_moe_fp4(
206 inplace: bool = False,
207 activation: str = "silu",
208 global_num_experts: int = -1,
210 - expert_map: Optional[torch.Tensor] = None,
209 + expert_map: torch.Tensor | None = None,
210 apply_router_weight_on_input: bool = False,
211 ) -> torch.Tensor:
212 fused_experts = mk.FusedMoEModularKernel(
@@ -242,7 +241,7 @@ def flashinfer_cutlass_moe(
241 inplace: bool = False,
242 activation: str = "silu",
243 global_num_experts: int = -1,
245 - expert_map: Optional[torch.Tensor] = None,
244 + expert_map: torch.Tensor | None = None,
245 apply_router_weight_on_input: bool = False,
246 tp_rank: int = 0,
247 tp_size: int = 1,
vllm/model_executor/layers/fused_moe/flashinfer_cutlass_prepare_finalize.py
+4 -5
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -39,10 +38,10 @@ class FlashInferCutlassMoEPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
38 def activation_format(self) -> mk.FusedMoEActivationFormat:
39 return mk.FusedMoEActivationFormat.Standard
40
42 - def max_num_tokens_per_rank(self) -> Optional[int]:
41 + def max_num_tokens_per_rank(self) -> int | None:
42 return None
43
45 - def topk_indices_dtype(self) -> Optional[torch.dtype]:
44 + def topk_indices_dtype(self) -> torch.dtype | None:
45 return None
46
47 def num_dispatchers(self) -> int:
@@ -89,7 +88,7 @@ class FlashInferAllToAllMoEPrepareAndFinalize(FlashInferCutlassMoEPrepareAndFina
88 topk_weights: torch.Tensor,
89 topk_ids: torch.Tensor,
90 num_experts: int,
92 - expert_map: Optional[torch.Tensor],
91 + expert_map: torch.Tensor | None,
92 apply_router_weight_on_input: bool,
93 quant_config: FusedMoEQuantConfig,
94 ) -> mk.PrepareResultType:
@@ -164,7 +163,7 @@ class FlashInferAllGatherMoEPrepareAndFinalize(FlashInferCutlassMoEPrepareAndFin
163 topk_weights: torch.Tensor,
164 topk_ids: torch.Tensor,
165 num_experts: int,
167 - expert_map: Optional[torch.Tensor],
166 + expert_map: torch.Tensor | None,
167 apply_router_weight_on_input: bool,
168 quant_config: FusedMoEQuantConfig,
169 ) -> mk.PrepareResultType:
vllm/model_executor/layers/fused_moe/flashinfer_trtllm_moe.py
+6 -7
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -105,7 +104,7 @@ direct_register_custom_op(
104
105 def flashinfer_fused_moe_per_tensor_scale_fp8(
106 routing_logits: torch.Tensor,
108 - routing_bias: Optional[torch.Tensor],
107 + routing_bias: torch.Tensor | None,
108 hidden_states: torch.Tensor,
109 input_scale: torch.Tensor,
110 gemm1_weights: torch.Tensor,
@@ -115,8 +114,8 @@ def flashinfer_fused_moe_per_tensor_scale_fp8(
114 output2_scales_scalar: torch.Tensor,
115 num_experts: int,
116 top_k: int,
118 - num_expert_group: Optional[int],
119 - topk_group: Optional[int],
117 + num_expert_group: int | None,
118 + topk_group: int | None,
119 intermediate_size: int,
120 local_expert_offset: int,
121 local_num_experts: int,
@@ -163,7 +162,7 @@ def flashinfer_fused_moe_per_tensor_scale_fp8(
162
163 def flashinfer_fused_moe_per_tensor_scale_fp8_fake(
164 routing_logits: torch.Tensor,
166 - routing_bias: Optional[torch.Tensor],
165 + routing_bias: torch.Tensor | None,
166 hidden_states: torch.Tensor,
167 input_scale: torch.Tensor,
168 gemm1_weights: torch.Tensor,
@@ -173,8 +172,8 @@ def flashinfer_fused_moe_per_tensor_scale_fp8_fake(
172 output2_scales_scalar: torch.Tensor,
173 num_experts: int,
174 top_k: int,
176 - num_expert_group: Optional[int],
177 - topk_group: Optional[int],
175 + num_expert_group: int | None,
176 + topk_group: int | None,
177 intermediate_size: int,
178 local_expert_offset: int,
179 local_num_experts: int,
vllm/model_executor/layers/fused_moe/fused_batched_moe.py
+20 -22
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Fused batched MoE kernel."""
4
5 -from typing import Optional
6 -
5 import torch
6
7 import vllm.model_executor.layers.fused_moe.modular_kernel as mk
@@ -370,8 +368,8 @@ def invoke_moe_batched_triton_kernel(
368 expert_num_tokens: torch.Tensor, # [E]
369 compute_type: tl.dtype,
370 # Quantization data
373 - A_scale: Optional[torch.Tensor],
374 - B_scale: Optional[torch.Tensor],
371 + A_scale: torch.Tensor | None,
372 + B_scale: torch.Tensor | None,
373 B_zp: torch.Tensor,
374 # Quantization schemes
375 use_fp8_w8a8: bool,
@@ -379,7 +377,7 @@ def invoke_moe_batched_triton_kernel(
377 use_int4_w4a16: bool,
378 config: dict[str, int],
379 per_act_token_quant: bool,
382 - block_shape: Optional[list[int]] = None,
380 + block_shape: list[int] | None = None,
381 ):
382 assert not use_int4_w4a16
383 max_num_tokens = A.size(1)
@@ -500,10 +498,10 @@ class BatchedPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
498 def activation_format(self) -> mk.FusedMoEActivationFormat:
499 return mk.FusedMoEActivationFormat.BatchedExperts
500
503 - def max_num_tokens_per_rank(self) -> Optional[int]:
501 + def max_num_tokens_per_rank(self) -> int | None:
502 return self.max_num_tokens
503
506 - def topk_indices_dtype(self) -> Optional[torch.dtype]:
504 + def topk_indices_dtype(self) -> torch.dtype | None:
505 return None
506
507 def num_dispatchers(self) -> int:
@@ -518,7 +516,7 @@ class BatchedPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
516 topk_weights: torch.Tensor,
517 topk_ids: torch.Tensor,
518 num_experts: int,
521 - expert_map: Optional[torch.Tensor],
519 + expert_map: torch.Tensor | None,
520 apply_router_weight_on_input: bool,
521 quant_config: FusedMoEQuantConfig,
522 ) -> mk.PrepareResultType:
@@ -674,7 +672,7 @@ class NaiveBatchedExperts(mk.FusedMoEPermuteExpertsUnpermute):
672 topk: int,
673 global_num_experts: int,
674 local_num_experts: int,
677 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
675 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
676 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
677 num_dp = self.num_dispatchers
678 num_experts = local_num_experts
@@ -701,12 +699,12 @@ class NaiveBatchedExperts(mk.FusedMoEPermuteExpertsUnpermute):
699 topk_ids: torch.Tensor,
700 activation: str,
701 global_num_experts: int,
704 - expert_map: Optional[torch.Tensor],
705 - a1q_scale: Optional[torch.Tensor],
706 - a2_scale: Optional[torch.Tensor],
702 + expert_map: torch.Tensor | None,
703 + a1q_scale: torch.Tensor | None,
704 + a2_scale: torch.Tensor | None,
705 workspace13: torch.Tensor,
706 workspace2: torch.Tensor,
709 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
707 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
708 apply_router_weight_on_input: bool,
709 ):
710 assert hidden_states.dim() == 3
@@ -754,15 +752,15 @@ class NaiveBatchedExperts(mk.FusedMoEPermuteExpertsUnpermute):
752
753 def batched_moe_kernel_quantize_input(
754 A: torch.Tensor,
757 - A_scale: Optional[torch.Tensor],
755 + A_scale: torch.Tensor | None,
756 num_tokens: int,
757 E: int,
758 N: int,
759 expert_num_tokens: torch.Tensor,
762 - qtype: Optional[torch.dtype],
760 + qtype: torch.dtype | None,
761 per_act_token_quant: bool,
764 - block_shape: Optional[list[int]] = None,
765 -) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
762 + block_shape: list[int] | None = None,
763 +) -> tuple[torch.Tensor, torch.Tensor | None]:
764 if torch.compiler.is_compiling() or torch.cuda.is_current_stream_capturing():
765 # Note: this does a bunch of extra work because expert_num_tokens is
766 # ignored but it does support torch.compile + cudagraphs.
@@ -868,7 +866,7 @@ class BatchedTritonExperts(mk.FusedMoEPermuteExpertsUnpermute):
866 topk: int,
867 global_num_experts: int,
868 local_num_experts: int,
871 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
869 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
870 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
871 num_dp = self.num_dispatchers
872 num_experts = local_num_experts
@@ -888,12 +886,12 @@ class BatchedTritonExperts(mk.FusedMoEPermuteExpertsUnpermute):
886 topk_ids: torch.Tensor,
887 activation: str,
888 global_num_experts: int,
891 - expert_map: Optional[torch.Tensor],
892 - a1q_scale: Optional[torch.Tensor],
893 - a2_scale: Optional[torch.Tensor],
889 + expert_map: torch.Tensor | None,
890 + a1q_scale: torch.Tensor | None,
891 + a2_scale: torch.Tensor | None,
892 workspace13: torch.Tensor,
893 workspace2: torch.Tensor,
896 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
894 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
895 apply_router_weight_on_input: bool,
896 ):
897 # Check constraints.
vllm/model_executor/layers/fused_moe/fused_marlin_moe.py
+36 -38
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Fused MoE utilities for GPTQ."""
4
5 -from typing import Optional
6 -
5 import torch
6 from typing_extensions import override
7
@@ -28,31 +26,31 @@ def fused_marlin_moe(
26 hidden_states: torch.Tensor,
27 w1: torch.Tensor,
28 w2: torch.Tensor,
31 - bias1: Optional[torch.Tensor],
32 - bias2: Optional[torch.Tensor],
29 + bias1: torch.Tensor | None,
30 + bias2: torch.Tensor | None,
31 w1_scale: torch.Tensor,
32 w2_scale: torch.Tensor,
35 - gating_output: Optional[torch.Tensor],
33 + gating_output: torch.Tensor | None,
34 topk_weights: torch.Tensor,
35 topk_ids: torch.Tensor,
36 quant_type_id: int,
37 apply_router_weight_on_input: bool = False,
38 global_num_experts: int = -1,
41 - activation: Optional[str] = "silu",
42 - expert_map: Optional[torch.Tensor] = None,
43 - global_scale1: Optional[torch.Tensor] = None,
44 - global_scale2: Optional[torch.Tensor] = None,
45 - g_idx1: Optional[torch.Tensor] = None,
46 - g_idx2: Optional[torch.Tensor] = None,
47 - sort_indices1: Optional[torch.Tensor] = None,
48 - sort_indices2: Optional[torch.Tensor] = None,
49 - w1_zeros: Optional[torch.Tensor] = None,
50 - w2_zeros: Optional[torch.Tensor] = None,
51 - workspace: Optional[torch.Tensor] = None,
52 - intermediate_cache13: Optional[torch.Tensor] = None,
53 - intermediate_cache2: Optional[torch.Tensor] = None,
39 + activation: str | None = "silu",
40 + expert_map: torch.Tensor | None = None,
41 + global_scale1: torch.Tensor | None = None,
42 + global_scale2: torch.Tensor | None = None,
43 + g_idx1: torch.Tensor | None = None,
44 + g_idx2: torch.Tensor | None = None,
45 + sort_indices1: torch.Tensor | None = None,
46 + sort_indices2: torch.Tensor | None = None,
47 + w1_zeros: torch.Tensor | None = None,
48 + w2_zeros: torch.Tensor | None = None,
49 + workspace: torch.Tensor | None = None,
50 + intermediate_cache13: torch.Tensor | None = None,
51 + intermediate_cache2: torch.Tensor | None = None,
52 is_k_full: bool = True,
55 - output: Optional[torch.Tensor] = None,
53 + output: torch.Tensor | None = None,
54 inplace: bool = False,
55 ) -> torch.Tensor:
56 """
@@ -249,26 +247,26 @@ def fused_marlin_moe_fake(
247 w2: torch.Tensor,
248 w1_scale: torch.Tensor,
249 w2_scale: torch.Tensor,
252 - gating_output: Optional[torch.Tensor],
250 + gating_output: torch.Tensor | None,
251 topk_weights: torch.Tensor,
252 topk_ids: torch.Tensor,
253 quant_type_id: int,
254 apply_router_weight_on_input: bool = False,
255 global_num_experts: int = -1,
258 - global_scale1: Optional[torch.Tensor] = None,
259 - global_scale2: Optional[torch.Tensor] = None,
260 - expert_map: Optional[torch.Tensor] = None,
261 - g_idx1: Optional[torch.Tensor] = None,
262 - g_idx2: Optional[torch.Tensor] = None,
263 - sort_indices1: Optional[torch.Tensor] = None,
264 - sort_indices2: Optional[torch.Tensor] = None,
265 - w1_zeros: Optional[torch.Tensor] = None,
266 - w2_zeros: Optional[torch.Tensor] = None,
267 - workspace: Optional[torch.Tensor] = None,
268 - intermediate_cache13: Optional[torch.Tensor] = None,
269 - intermediate_cache2: Optional[torch.Tensor] = None,
256 + global_scale1: torch.Tensor | None = None,
257 + global_scale2: torch.Tensor | None = None,
258 + expert_map: torch.Tensor | None = None,
259 + g_idx1: torch.Tensor | None = None,
260 + g_idx2: torch.Tensor | None = None,
261 + sort_indices1: torch.Tensor | None = None,
262 + sort_indices2: torch.Tensor | None = None,
263 + w1_zeros: torch.Tensor | None = None,
264 + w2_zeros: torch.Tensor | None = None,
265 + workspace: torch.Tensor | None = None,
266 + intermediate_cache13: torch.Tensor | None = None,
267 + intermediate_cache2: torch.Tensor | None = None,
268 is_k_full: bool = True,
271 - output: Optional[torch.Tensor] = None,
269 + output: torch.Tensor | None = None,
270 inplace: bool = False,
271 ) -> torch.Tensor:
272 return torch.empty_like(hidden_states)
@@ -341,7 +339,7 @@ class MarlinExperts(mk.FusedMoEPermuteExpertsUnpermute):
339 topk: int,
340 global_num_experts: int,
341 local_num_experts: int,
344 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
342 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
343 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
344 # Modular Kernel provisions output buffer from workspace1. However in
345 # the fused_marlin_moe() function, the final torch.sum(), is defined
@@ -374,12 +372,12 @@ class MarlinExperts(mk.FusedMoEPermuteExpertsUnpermute):
372 topk_ids: torch.Tensor,
373 activation: str,
374 global_num_experts: int,
377 - expert_map: Optional[torch.Tensor],
378 - a1q_scale: Optional[torch.Tensor],
379 - a2_scale: Optional[torch.Tensor],
375 + expert_map: torch.Tensor | None,
376 + a1q_scale: torch.Tensor | None,
377 + a2_scale: torch.Tensor | None,
378 workspace13: torch.Tensor,
379 workspace2: torch.Tensor,
382 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
380 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
381 apply_router_weight_on_input: bool,
382 ):
383 assert self.w1_scale is not None
vllm/model_executor/layers/fused_moe/fused_moe.py
+85 -84
@@ -5,7 +5,8 @@
5 import functools
6 import json
7 import os
8 -from typing import Any, Callable, Optional, Union
8 +from collections.abc import Callable
9 +from typing import Any
10
11 import torch
12 import torch.nn.functional as F
@@ -539,10 +540,10 @@ def invoke_fused_moe_kernel(
540 A: torch.Tensor,
541 B: torch.Tensor,
542 C: torch.Tensor,
542 - A_scale: Optional[torch.Tensor],
543 - B_scale: Optional[torch.Tensor],
544 - B_zp: Optional[torch.Tensor],
545 - topk_weights: Optional[torch.Tensor],
543 + A_scale: torch.Tensor | None,
544 + B_scale: torch.Tensor | None,
545 + B_zp: torch.Tensor | None,
546 + topk_weights: torch.Tensor | None,
547 sorted_token_ids: torch.Tensor,
548 expert_ids: torch.Tensor,
549 num_tokens_post_padded: torch.Tensor,
@@ -555,8 +556,8 @@ def invoke_fused_moe_kernel(
556 use_int8_w8a16: bool,
557 use_int4_w4a16: bool,
558 per_channel_quant: bool,
558 - block_shape: Optional[list[int]] = None,
559 - B_bias: Optional[torch.Tensor] = None,
559 + block_shape: list[int] | None = None,
560 + B_bias: torch.Tensor | None = None,
561 ) -> None:
562 assert topk_weights is not None or not mul_routed_weight
563 assert topk_weights is None or topk_weights.stride(1) == 1
@@ -808,7 +809,7 @@ def zero_experts_compute_triton(
809
810 # Adapted from: https://github.com/sgl-project/sglang/pull/2628
811 def get_config_file_name(
811 - E: int, N: int, dtype: Optional[str], block_shape: Optional[list[int]] = None
812 + E: int, N: int, dtype: str | None, block_shape: list[int] | None = None
813 ) -> str:
814 device_name = current_platform.get_device_name().replace(" ", "_")
815 dtype_selector = "" if not dtype else f",dtype={dtype}"
@@ -823,10 +824,10 @@ def get_config_file_name(
824 def get_moe_configs(
825 E: int,
826 N: int,
826 - dtype: Optional[str],
827 - block_n: Optional[int] = None,
828 - block_k: Optional[int] = None,
829 -) -> Optional[dict[int, Any]]:
827 + dtype: str | None,
828 + block_n: int | None = None,
829 + block_k: int | None = None,
830 +) -> dict[int, Any] | None:
831 """
832 Return optimized configurations for the fused MoE kernel.
833
@@ -965,8 +966,8 @@ def get_default_config(
966 N: int,
967 K: int,
968 topk: int,
968 - dtype: Optional[str],
969 - block_shape: Optional[list[int]] = None,
969 + dtype: str | None,
970 + block_shape: list[int] | None = None,
971 ) -> dict[str, int]:
972 if dtype == "fp8_w8a8" and block_shape is not None:
973 # Block-wise quant: BLOCK_SIZE_N must be divisible by block_shape[0]
@@ -1016,9 +1017,9 @@ def try_get_optimal_moe_config(
1017 w1_shape: tuple[int, ...],
1018 w2_shape: tuple[int, ...],
1019 top_k: int,
1019 - dtype: Optional[str],
1020 + dtype: str | None,
1021 M: int,
1021 - block_shape: Optional[list[int]] = None,
1022 + block_shape: list[int] | None = None,
1023 ) -> dict[str, int]:
1024 from vllm.model_executor.layers.fused_moe import get_config
1025
@@ -1076,7 +1077,7 @@ def fused_topk(
1077 gating_output: torch.Tensor,
1078 topk: int,
1079 renormalize: bool,
1079 - indices_type: Optional[torch.dtype] = None,
1080 + indices_type: torch.dtype | None = None,
1081 ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
1082 assert hidden_states.size(0) == gating_output.size(0), "Number of tokens mismatch"
1083
@@ -1135,7 +1136,7 @@ def grouped_topk(
1136 topk_group: int = 0,
1137 scoring_func: str = "softmax",
1138 routed_scaling_factor: float = 1.0,
1138 - e_score_correction_bias: Optional[torch.Tensor] = None,
1139 + e_score_correction_bias: torch.Tensor | None = None,
1140 ) -> tuple[torch.Tensor, torch.Tensor]:
1141 if (
1142 envs.VLLM_USE_FUSED_MOE_GROUPED_TOPK
@@ -1211,7 +1212,7 @@ def eplb_map_to_physical_and_record(
1212 expert_load_view: torch.Tensor,
1213 logical_to_physical_map: torch.Tensor,
1214 logical_replica_count: torch.Tensor,
1214 - indices_type: Optional[torch.dtype] = None,
1215 + indices_type: torch.dtype | None = None,
1216 ) -> torch.Tensor:
1217 """
1218 Map the logical expert ids to physical expert ids
@@ -1326,19 +1327,19 @@ def inplace_fused_experts(
1327 use_int8_w8a8: bool = False,
1328 use_int8_w8a16: bool = False,
1329 use_int4_w4a16: bool = False,
1329 - ocp_mx_scheme: Optional[str] = None,
1330 + ocp_mx_scheme: str | None = None,
1331 per_channel_quant: bool = False,
1332 global_num_experts: int = -1,
1332 - expert_map: Optional[torch.Tensor] = None,
1333 - w1_scale: Optional[torch.Tensor] = None,
1334 - w2_scale: Optional[torch.Tensor] = None,
1335 - w1_zp: Optional[torch.Tensor] = None,
1336 - w2_zp: Optional[torch.Tensor] = None,
1337 - a1_scale: Optional[torch.Tensor] = None,
1338 - a2_scale: Optional[torch.Tensor] = None,
1339 - block_shape: Optional[list[int]] = None,
1340 - w1_bias: Optional[torch.Tensor] = None,
1341 - w2_bias: Optional[torch.Tensor] = None,
1333 + expert_map: torch.Tensor | None = None,
1334 + w1_scale: torch.Tensor | None = None,
1335 + w2_scale: torch.Tensor | None = None,
1336 + w1_zp: torch.Tensor | None = None,
1337 + w2_zp: torch.Tensor | None = None,
1338 + a1_scale: torch.Tensor | None = None,
1339 + a2_scale: torch.Tensor | None = None,
1340 + block_shape: list[int] | None = None,
1341 + w1_bias: torch.Tensor | None = None,
1342 + w2_bias: torch.Tensor | None = None,
1343 ) -> None:
1344 fused_experts_impl(
1345 hidden_states,
@@ -1381,19 +1382,19 @@ def inplace_fused_experts_fake(
1382 use_int8_w8a8: bool = False,
1383 use_int8_w8a16: bool = False,
1384 use_int4_w4a16: bool = False,
1384 - ocp_mx_scheme: Optional[str] = None,
1385 + ocp_mx_scheme: str | None = None,
1386 per_channel_quant: bool = False,
1387 global_num_experts: int = -1,
1387 - expert_map: Optional[torch.Tensor] = None,
1388 - w1_scale: Optional[torch.Tensor] = None,
1389 - w2_scale: Optional[torch.Tensor] = None,
1390 - w1_zp: Optional[torch.Tensor] = None,
1391 - w2_zp: Optional[torch.Tensor] = None,
1392 - a1_scale: Optional[torch.Tensor] = None,
1393 - a2_scale: Optional[torch.Tensor] = None,
1394 - block_shape: Optional[list[int]] = None,
1395 - w1_bias: Optional[torch.Tensor] = None,
1396 - w2_bias: Optional[torch.Tensor] = None,
1388 + expert_map: torch.Tensor | None = None,
1389 + w1_scale: torch.Tensor | None = None,
1390 + w2_scale: torch.Tensor | None = None,
1391 + w1_zp: torch.Tensor | None = None,
1392 + w2_zp: torch.Tensor | None = None,
1393 + a1_scale: torch.Tensor | None = None,
1394 + a2_scale: torch.Tensor | None = None,
1395 + block_shape: list[int] | None = None,
1396 + w1_bias: torch.Tensor | None = None,
1397 + w2_bias: torch.Tensor | None = None,
1398 ) -> None:
1399 pass
1400
@@ -1423,19 +1424,19 @@ def outplace_fused_experts(
1424 use_int8_w8a8: bool = False,
1425 use_int8_w8a16: bool = False,
1426 use_int4_w4a16: bool = False,
1426 - ocp_mx_scheme: Optional[str] = None,
1427 + ocp_mx_scheme: str | None = None,
1428 per_channel_quant: bool = False,
1429 global_num_experts: int = -1,
1429 - expert_map: Optional[torch.Tensor] = None,
1430 - w1_scale: Optional[torch.Tensor] = None,
1431 - w2_scale: Optional[torch.Tensor] = None,
1432 - w1_zp: Optional[torch.Tensor] = None,
1433 - w2_zp: Optional[torch.Tensor] = None,
1434 - a1_scale: Optional[torch.Tensor] = None,
1435 - a2_scale: Optional[torch.Tensor] = None,
1436 - block_shape: Optional[list[int]] = None,
1437 - w1_bias: Optional[torch.Tensor] = None,
1438 - w2_bias: Optional[torch.Tensor] = None,
1430 + expert_map: torch.Tensor | None = None,
1431 + w1_scale: torch.Tensor | None = None,
1432 + w2_scale: torch.Tensor | None = None,
1433 + w1_zp: torch.Tensor | None = None,
1434 + w2_zp: torch.Tensor | None = None,
1435 + a1_scale: torch.Tensor | None = None,
1436 + a2_scale: torch.Tensor | None = None,
1437 + block_shape: list[int] | None = None,
1438 + w1_bias: torch.Tensor | None = None,
1439 + w2_bias: torch.Tensor | None = None,
1440 ) -> torch.Tensor:
1441 return fused_experts_impl(
1442 hidden_states,
@@ -1477,19 +1478,19 @@ def outplace_fused_experts_fake(
1478 use_int8_w8a8: bool = False,
1479 use_int8_w8a16: bool = False,
1480 use_int4_w4a16: bool = False,
1480 - ocp_mx_scheme: Optional[str] = None,
1481 + ocp_mx_scheme: str | None = None,
1482 per_channel_quant: bool = False,
1483 global_num_experts: int = -1,
1483 - expert_map: Optional[torch.Tensor] = None,
1484 - w1_scale: Optional[torch.Tensor] = None,
1485 - w2_scale: Optional[torch.Tensor] = None,
1486 - w1_zp: Optional[torch.Tensor] = None,
1487 - w2_zp: Optional[torch.Tensor] = None,
1488 - a1_scale: Optional[torch.Tensor] = None,
1489 - a2_scale: Optional[torch.Tensor] = None,
1490 - block_shape: Optional[list[int]] = None,
1491 - w1_bias: Optional[torch.Tensor] = None,
1492 - w2_bias: Optional[torch.Tensor] = None,
1484 + expert_map: torch.Tensor | None = None,
1485 + w1_scale: torch.Tensor | None = None,
1486 + w2_scale: torch.Tensor | None = None,
1487 + w1_zp: torch.Tensor | None = None,
1488 + w2_zp: torch.Tensor | None = None,
1489 + a1_scale: torch.Tensor | None = None,
1490 + a2_scale: torch.Tensor | None = None,
1491 + block_shape: list[int] | None = None,
1492 + w1_bias: torch.Tensor | None = None,
1493 + w2_bias: torch.Tensor | None = None,
1494 ) -> torch.Tensor:
1495 return torch.empty_like(hidden_states)
1496
@@ -1534,8 +1535,8 @@ def fused_experts(
1535 activation: str = "silu",
1536 apply_router_weight_on_input: bool = False,
1537 global_num_experts: int = -1,
1537 - expert_map: Optional[torch.Tensor] = None,
1538 - quant_config: Optional[FusedMoEQuantConfig] = None,
1538 + expert_map: torch.Tensor | None = None,
1539 + quant_config: FusedMoEQuantConfig | None = None,
1540 allow_deep_gemm: bool = False,
1541 allow_cutlass_block_scaled_grouped_gemm: bool = False,
1542 ) -> torch.Tensor:
@@ -1625,8 +1626,8 @@ GELU_NO_MUL: str = activation_without_mul("gelu")
1626 def _get_config_quant_dtype(
1627 use_fp8_w8a8: bool,
1628 use_int8_w8a8: bool,
1628 - ocp_mx_scheme: Optional[str],
1629 -) -> Union[None, torch.dtype, str]:
1629 + ocp_mx_scheme: str | None,
1630 +) -> None | torch.dtype | str:
1631 """
1632 Get the quantization type based on the quantization strategy flags.
1633 We don't have a quant_config at this point so we need to work backwards.
@@ -1660,19 +1661,19 @@ def fused_experts_impl(
1661 use_int8_w8a8: bool = False,
1662 use_int8_w8a16: bool = False,
1663 use_int4_w4a16: bool = False,
1663 - ocp_mx_scheme: Optional[str] = None,
1664 + ocp_mx_scheme: str | None = None,
1665 per_channel_quant: bool = False,
1666 global_num_experts: int = -1,
1666 - expert_map: Optional[torch.Tensor] = None,
1667 - w1_scale: Optional[torch.Tensor] = None,
1668 - w2_scale: Optional[torch.Tensor] = None,
1669 - w1_zp: Optional[torch.Tensor] = None,
1670 - w2_zp: Optional[torch.Tensor] = None,
1671 - a1_scale: Optional[torch.Tensor] = None,
1672 - a2_scale: Optional[torch.Tensor] = None,
1673 - block_shape: Optional[list[int]] = None,
1674 - w1_bias: Optional[torch.Tensor] = None,
1675 - w2_bias: Optional[torch.Tensor] = None,
1667 + expert_map: torch.Tensor | None = None,
1668 + w1_scale: torch.Tensor | None = None,
1669 + w2_scale: torch.Tensor | None = None,
1670 + w1_zp: torch.Tensor | None = None,
1671 + w2_zp: torch.Tensor | None = None,
1672 + a1_scale: torch.Tensor | None = None,
1673 + a2_scale: torch.Tensor | None = None,
1674 + block_shape: list[int] | None = None,
1675 + w1_bias: torch.Tensor | None = None,
1676 + w2_bias: torch.Tensor | None = None,
1677 ) -> torch.Tensor:
1678 # Check constraints.
1679 if use_int4_w4a16:
@@ -1964,7 +1965,7 @@ class TritonExperts(mk.FusedMoEPermuteExpertsUnpermute):
1965 topk: int,
1966 global_num_experts: int,
1967 local_num_experts: int,
1967 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
1968 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
1969 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
1970 workspace1 = (M, topk, max(N // 2, K))
1971 workspace2 = (M, topk, max(N, K))
@@ -1981,12 +1982,12 @@ class TritonExperts(mk.FusedMoEPermuteExpertsUnpermute):
1982 topk_ids: torch.Tensor,
1983 activation: str,
1984 global_num_experts: int,
1984 - expert_map: Optional[torch.Tensor],
1985 - a1q_scale: Optional[torch.Tensor],
1986 - a2_scale: Optional[torch.Tensor],
1985 + expert_map: torch.Tensor | None,
1986 + a1q_scale: torch.Tensor | None,
1987 + a2_scale: torch.Tensor | None,
1988 workspace13: torch.Tensor,
1989 workspace2: torch.Tensor,
1989 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
1990 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
1991 apply_router_weight_on_input: bool,
1992 ):
1993 # Check constraints.
@@ -2074,7 +2075,7 @@ class TritonExperts(mk.FusedMoEPermuteExpertsUnpermute):
2075 activation, intermediate_cache2, intermediate_cache1.view(-1, N)
2076 )
2077
2077 - a2q_scale: Optional[torch.Tensor] = None
2078 + a2q_scale: torch.Tensor | None = None
2079
2080 qintermediate_cache2, a2q_scale = moe_kernel_quantize_input(
2081 intermediate_cache2,
vllm/model_executor/layers/fused_moe/gpt_oss_triton_kernels_moe.py
+10 -11
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -80,10 +79,10 @@ def triton_kernel_moe_forward(
79 topk: int,
80 renormalize: bool,
81 activation: str = "silu",
83 - quant_config: Optional[FusedMoEQuantConfig] = None,
82 + quant_config: FusedMoEQuantConfig | None = None,
83 apply_router_weight_on_input: bool = False,
84 global_num_experts: int = -1,
86 - expert_map: Optional[torch.Tensor] = None,
85 + expert_map: torch.Tensor | None = None,
86 ) -> torch.Tensor:
87 routing_data, gather_idx, scatter_idx = routing(
88 gating_output, topk, sm_first=not renormalize
@@ -115,13 +114,13 @@ def triton_kernel_fused_experts(
114 gather_indx, # GatherIndx
115 scatter_indx, # ScatterIndx
116 activation: str = "silu",
118 - quant_config: Optional[FusedMoEQuantConfig] = None,
117 + quant_config: FusedMoEQuantConfig | None = None,
118 swiglu_alpha: float = 1.702,
119 swiglu_limit: float = 7.0,
120 apply_router_weight_on_input: bool = False,
121 global_num_experts: int = -1,
123 - expert_map: Optional[torch.Tensor] = None,
124 - a1q_scale: Optional[torch.Tensor] = None,
122 + expert_map: torch.Tensor | None = None,
123 + a1q_scale: torch.Tensor | None = None,
124 ) -> torch.Tensor:
125 if quant_config is None:
126 quant_config = FUSED_MOE_UNQUANTIZED_CONFIG
@@ -261,7 +260,7 @@ class OAITritonExperts(BaseOAITritonExperts):
260 topk: int,
261 global_num_experts: int,
262 local_num_experts: int,
264 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
263 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
264 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
265 # workspace are allocated inside the kernel
266 workspace1 = (M, K)
@@ -279,12 +278,12 @@ class OAITritonExperts(BaseOAITritonExperts):
278 topk_ids: torch.Tensor,
279 activation: str,
280 global_num_experts: int,
282 - expert_map: Optional[torch.Tensor],
283 - a1q_scale: Optional[torch.Tensor],
284 - a2_scale: Optional[torch.Tensor],
281 + expert_map: torch.Tensor | None,
282 + a1q_scale: torch.Tensor | None,
283 + a2_scale: torch.Tensor | None,
284 workspace13: torch.Tensor,
285 workspace2: torch.Tensor,
287 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
286 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
287 apply_router_weight_on_input: bool,
288 ):
289 if expert_map is not None:
vllm/model_executor/layers/fused_moe/layer.py
+108 -108
@@ -2,10 +2,10 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from abc import abstractmethod
5 -from collections.abc import Iterable
5 +from collections.abc import Callable, Iterable
6 from contextlib import nullcontext
7 from enum import Enum
8 -from typing import Callable, Literal, Optional, Union, get_args, overload
8 +from typing import Literal, get_args, overload
9
10 import torch
11 import torch.nn.functional as F
@@ -70,15 +70,15 @@ if current_platform.is_cuda_alike():
70 )
71 else:
72 fused_experts = None # type: ignore
73 - FusedMoEPermuteExpertsUnpermute = None # type: ignore
74 - FusedMoEPrepareAndFinalize = None # type: ignore
73 + FusedMoEPermuteExpertsUnpermute = object # type: ignore
74 + FusedMoEPrepareAndFinalize = object # type: ignore
75
76 def _eplb_map_to_physical_and_record(
77 topk_ids: torch.Tensor,
78 expert_load_view: torch.Tensor,
79 logical_to_physical_map: torch.Tensor,
80 logical_replica_count: torch.Tensor,
81 - indices_type: Optional[torch.dtype],
81 + indices_type: torch.dtype | None,
82 ) -> torch.Tensor:
83 # CPU fallback: no EPLB so just return as is
84 return topk_ids
@@ -110,8 +110,8 @@ class FusedMoEMethodBase(QuantizeMethodBase):
110 def __init__(self, moe: FusedMoEConfig):
111 super().__init__()
112 self.moe = moe
113 - self.moe_quant_config: Optional[FusedMoEQuantConfig] = None
114 - self.fused_experts: Optional[FusedMoEModularKernel] = None
113 + self.moe_quant_config: FusedMoEQuantConfig | None = None
114 + self.fused_experts: FusedMoEModularKernel | None = None
115 self.topk_indices_dtype = None
116
117 @abstractmethod
@@ -139,12 +139,12 @@ class FusedMoEMethodBase(QuantizeMethodBase):
139 @staticmethod
140 def _maybe_make_prepare_finalize(
141 moe: FusedMoEConfig,
142 - quant_config: Optional[FusedMoEQuantConfig],
143 - ) -> Optional[FusedMoEPrepareAndFinalize]:
142 + quant_config: FusedMoEQuantConfig | None,
143 + ) -> FusedMoEPrepareAndFinalize | None:
144 all2all_manager = get_ep_group().device_communicator.all2all_manager
145 assert all2all_manager is not None
146
147 - prepare_finalize: Optional[FusedMoEPrepareAndFinalize] = None
147 + prepare_finalize: FusedMoEPrepareAndFinalize | None = None
148
149 # TODO: could allow this now
150 assert not moe.use_flashinfer_cutlass_kernels, "Must be created in modelopt.py"
@@ -229,7 +229,7 @@ class FusedMoEMethodBase(QuantizeMethodBase):
229
230 return prepare_finalize
231
232 - def maybe_make_prepare_finalize(self) -> Optional[FusedMoEPrepareAndFinalize]:
232 + def maybe_make_prepare_finalize(self) -> FusedMoEPrepareAndFinalize | None:
233 if self.moe.moe_parallel_config.use_all2all_kernels:
234 return FusedMoEMethodBase._maybe_make_prepare_finalize(
235 self.moe, self.moe_quant_config
@@ -280,7 +280,7 @@ class FusedMoEMethodBase(QuantizeMethodBase):
280 @abstractmethod
281 def get_fused_moe_quant_config(
282 self, layer: torch.nn.Module
283 - ) -> Optional[FusedMoEQuantConfig]:
283 + ) -> FusedMoEQuantConfig | None:
284 raise NotImplementedError
285
286 @property
@@ -296,21 +296,21 @@ class FusedMoEMethodBase(QuantizeMethodBase):
296 top_k: int,
297 renormalize: bool,
298 use_grouped_topk: bool = False,
299 - topk_group: Optional[int] = None,
300 - num_expert_group: Optional[int] = None,
299 + topk_group: int | None = None,
300 + num_expert_group: int | None = None,
301 global_num_experts: int = -1,
302 - expert_map: Optional[torch.Tensor] = None,
303 - custom_routing_function: Optional[Callable] = None,
302 + expert_map: torch.Tensor | None = None,
303 + custom_routing_function: Callable | None = None,
304 scoring_func: str = "softmax",
305 routed_scaling_factor: float = 1.0,
306 - e_score_correction_bias: Optional[torch.Tensor] = None,
306 + e_score_correction_bias: torch.Tensor | None = None,
307 apply_router_weight_on_input: bool = False,
308 activation: str = "silu",
309 enable_eplb: bool = False,
310 - expert_load_view: Optional[torch.Tensor] = None,
311 - logical_to_physical_map: Optional[torch.Tensor] = None,
312 - logical_replica_count: Optional[torch.Tensor] = None,
313 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
310 + expert_load_view: torch.Tensor | None = None,
311 + logical_to_physical_map: torch.Tensor | None = None,
312 + logical_replica_count: torch.Tensor | None = None,
313 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
314 raise NotImplementedError
315
316
@@ -368,7 +368,7 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
368 )
369 self.flashinfer_cutlass_moe = None # type: ignore
370
371 - def maybe_make_prepare_finalize(self) -> Optional[FusedMoEPrepareAndFinalize]:
371 + def maybe_make_prepare_finalize(self) -> FusedMoEPrepareAndFinalize | None:
372 if self.rocm_aiter_moe_enabled:
373 return None
374 else:
@@ -532,21 +532,21 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
532 top_k: int,
533 renormalize: bool,
534 use_grouped_topk: bool = False,
535 - topk_group: Optional[int] = None,
536 - num_expert_group: Optional[int] = None,
535 + topk_group: int | None = None,
536 + num_expert_group: int | None = None,
537 global_num_experts: int = -1,
538 - expert_map: Optional[torch.Tensor] = None,
539 - custom_routing_function: Optional[Callable] = None,
538 + expert_map: torch.Tensor | None = None,
539 + custom_routing_function: Callable | None = None,
540 scoring_func: str = "softmax",
541 routed_scaling_factor: float = 1.0,
542 - e_score_correction_bias: Optional[torch.Tensor] = None,
542 + e_score_correction_bias: torch.Tensor | None = None,
543 apply_router_weight_on_input: bool = False,
544 activation: str = "silu",
545 enable_eplb: bool = False,
546 - expert_load_view: Optional[torch.Tensor] = None,
547 - logical_to_physical_map: Optional[torch.Tensor] = None,
548 - logical_replica_count: Optional[torch.Tensor] = None,
549 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
546 + expert_load_view: torch.Tensor | None = None,
547 + logical_to_physical_map: torch.Tensor | None = None,
548 + logical_replica_count: torch.Tensor | None = None,
549 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
550 if enable_eplb:
551 assert expert_load_view is not None
552 assert logical_to_physical_map is not None
@@ -578,7 +578,7 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
578
579 def get_fused_moe_quant_config(
580 self, layer: torch.nn.Module
581 - ) -> Optional[FusedMoEQuantConfig]:
581 + ) -> FusedMoEQuantConfig | None:
582 if self.moe.has_bias:
583 return biased_moe_quant_config(
584 layer.w13_bias,
@@ -595,21 +595,21 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
595 top_k: int,
596 router_logits: torch.Tensor,
597 renormalize: bool,
598 - topk_group: Optional[int] = None,
599 - num_expert_group: Optional[int] = None,
598 + topk_group: int | None = None,
599 + num_expert_group: int | None = None,
600 global_num_experts: int = -1,
601 - expert_map: Optional[torch.Tensor] = None,
602 - custom_routing_function: Optional[Callable] = None,
601 + expert_map: torch.Tensor | None = None,
602 + custom_routing_function: Callable | None = None,
603 scoring_func: str = "softmax",
604 routed_scaling_factor: float = 1.0,
605 - e_score_correction_bias: Optional[torch.Tensor] = None,
605 + e_score_correction_bias: torch.Tensor | None = None,
606 apply_router_weight_on_input: bool = False,
607 activation: str = "silu",
608 enable_eplb: bool = False,
609 - expert_load_view: Optional[torch.Tensor] = None,
610 - logical_to_physical_map: Optional[torch.Tensor] = None,
611 - logical_replica_count: Optional[torch.Tensor] = None,
612 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
609 + expert_load_view: torch.Tensor | None = None,
610 + logical_to_physical_map: torch.Tensor | None = None,
611 + logical_replica_count: torch.Tensor | None = None,
612 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
613 zero_expert_num = getattr(layer, "zero_expert_num", 0)
614 zero_expert_type = getattr(layer, "zero_expert_type", None)
615
@@ -705,21 +705,21 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
705 top_k: int,
706 router_logits: torch.Tensor,
707 renormalize: bool,
708 - topk_group: Optional[int] = None,
709 - num_expert_group: Optional[int] = None,
708 + topk_group: int | None = None,
709 + num_expert_group: int | None = None,
710 global_num_experts: int = -1,
711 - expert_map: Optional[torch.Tensor] = None,
712 - custom_routing_function: Optional[Callable] = None,
711 + expert_map: torch.Tensor | None = None,
712 + custom_routing_function: Callable | None = None,
713 scoring_func: str = "softmax",
714 routed_scaling_factor: float = 1.0,
715 - e_score_correction_bias: Optional[torch.Tensor] = None,
715 + e_score_correction_bias: torch.Tensor | None = None,
716 apply_router_weight_on_input: bool = False,
717 activation: str = "silu",
718 enable_eplb: bool = False,
719 - expert_load_view: Optional[torch.Tensor] = None,
720 - logical_to_physical_map: Optional[torch.Tensor] = None,
721 - logical_replica_count: Optional[torch.Tensor] = None,
722 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
719 + expert_load_view: torch.Tensor | None = None,
720 + logical_to_physical_map: torch.Tensor | None = None,
721 + logical_replica_count: torch.Tensor | None = None,
722 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
723 if (
724 enable_eplb is not False
725 or expert_load_view is not None
@@ -754,21 +754,21 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
754 top_k: int,
755 router_logits: torch.Tensor,
756 renormalize: bool,
757 - topk_group: Optional[int] = None,
758 - num_expert_group: Optional[int] = None,
757 + topk_group: int | None = None,
758 + num_expert_group: int | None = None,
759 global_num_experts: int = -1,
760 - expert_map: Optional[torch.Tensor] = None,
761 - custom_routing_function: Optional[Callable] = None,
760 + expert_map: torch.Tensor | None = None,
761 + custom_routing_function: Callable | None = None,
762 scoring_func: str = "softmax",
763 routed_scaling_factor: float = 1.0,
764 - e_score_correction_bias: Optional[torch.Tensor] = None,
764 + e_score_correction_bias: torch.Tensor | None = None,
765 apply_router_weight_on_input: bool = False,
766 activation: str = "silu",
767 enable_eplb: bool = False,
768 - expert_load_view: Optional[torch.Tensor] = None,
769 - logical_to_physical_map: Optional[torch.Tensor] = None,
770 - logical_replica_count: Optional[torch.Tensor] = None,
771 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
768 + expert_load_view: torch.Tensor | None = None,
769 + logical_to_physical_map: torch.Tensor | None = None,
770 + logical_replica_count: torch.Tensor | None = None,
771 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
772 if (
773 enable_eplb is not False
774 or expert_load_view is not None
@@ -795,21 +795,21 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
795 top_k: int,
796 router_logits: torch.Tensor,
797 renormalize: bool,
798 - topk_group: Optional[int] = None,
799 - num_expert_group: Optional[int] = None,
798 + topk_group: int | None = None,
799 + num_expert_group: int | None = None,
800 global_num_experts: int = -1,
801 - expert_map: Optional[torch.Tensor] = None,
802 - custom_routing_function: Optional[Callable] = None,
801 + expert_map: torch.Tensor | None = None,
802 + custom_routing_function: Callable | None = None,
803 scoring_func: str = "softmax",
804 routed_scaling_factor: float = 1.0,
805 - e_score_correction_bias: Optional[torch.Tensor] = None,
805 + e_score_correction_bias: torch.Tensor | None = None,
806 apply_router_weight_on_input: bool = False,
807 activation: str = "silu",
808 enable_eplb: bool = False,
809 - expert_load_view: Optional[torch.Tensor] = None,
810 - logical_to_physical_map: Optional[torch.Tensor] = None,
811 - logical_replica_count: Optional[torch.Tensor] = None,
812 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
809 + expert_load_view: torch.Tensor | None = None,
810 + logical_to_physical_map: torch.Tensor | None = None,
811 + logical_replica_count: torch.Tensor | None = None,
812 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
813 assert not use_grouped_topk
814 assert num_expert_group is None
815 assert topk_group is None
@@ -860,7 +860,7 @@ def determine_expert_map(
860 ep_rank: int,
861 global_num_experts: int,
862 expert_placement_strategy: ExpertPlacementStrategy = "linear",
863 -) -> tuple[int, Optional[torch.Tensor]]:
863 +) -> tuple[int, torch.Tensor | None]:
864 """
865 Calculates how many experts should be assigned to each rank for EP and
866 creates a mapping from global to local expert index. Experts are
@@ -941,7 +941,7 @@ def get_compressed_expert_map(expert_map: torch.Tensor) -> str:
941 def maybe_roundup_hidden_size(
942 hidden_size: int,
943 act_dtype: torch.dtype,
944 - quant_config: Optional[QuantizationConfig],
944 + quant_config: QuantizationConfig | None,
945 moe_parallel_config: FusedMoEParallelConfig,
946 ) -> int:
947 """
@@ -1016,30 +1016,30 @@ class FusedMoE(CustomOp):
1016 top_k: int,
1017 hidden_size: int,
1018 intermediate_size: int,
1019 - params_dtype: Optional[torch.dtype] = None,
1019 + params_dtype: torch.dtype | None = None,
1020 reduce_results: bool = False,
1021 renormalize: bool = True,
1022 use_grouped_topk: bool = False,
1023 - num_expert_group: Optional[int] = None,
1024 - topk_group: Optional[int] = None,
1025 - quant_config: Optional[QuantizationConfig] = None,
1026 - tp_size: Optional[int] = None,
1027 - ep_size: Optional[int] = None,
1028 - dp_size: Optional[int] = None,
1023 + num_expert_group: int | None = None,
1024 + topk_group: int | None = None,
1025 + quant_config: QuantizationConfig | None = None,
1026 + tp_size: int | None = None,
1027 + ep_size: int | None = None,
1028 + dp_size: int | None = None,
1029 prefix: str = "",
1030 - custom_routing_function: Optional[Callable] = None,
1030 + custom_routing_function: Callable | None = None,
1031 scoring_func: str = "softmax",
1032 routed_scaling_factor: float = 1.0,
1033 - e_score_correction_bias: Optional[torch.Tensor] = None,
1033 + e_score_correction_bias: torch.Tensor | None = None,
1034 apply_router_weight_on_input: bool = False,
1035 activation: str = "silu",
1036 enable_eplb: bool = False,
1037 num_redundant_experts: int = 0,
1038 has_bias: bool = False,
1039 is_sequence_parallel=False,
1040 - zero_expert_num: Optional[int] = 0,
1041 - zero_expert_type: Optional[str] = None,
1042 - expert_mapping: Optional[list[tuple[str, str, int, str]]] = None,
1040 + zero_expert_num: int | None = 0,
1041 + zero_expert_type: str | None = None,
1042 + expert_mapping: list[tuple[str, str, int, str]] | None = None,
1043 ):
1044 super().__init__()
1045 if params_dtype is None:
@@ -1092,9 +1092,9 @@ class FusedMoE(CustomOp):
1092 self.layer_name = prefix
1093
1094 self.enable_eplb = enable_eplb
1095 - self.expert_load_view: Optional[torch.Tensor] = None
1096 - self.logical_to_physical_map: Optional[torch.Tensor] = None
1097 - self.logical_replica_count: Optional[torch.Tensor] = None
1095 + self.expert_load_view: torch.Tensor | None = None
1096 + self.logical_to_physical_map: torch.Tensor | None = None
1097 + self.logical_replica_count: torch.Tensor | None = None
1098
1099 # Determine expert maps
1100 if self.use_ep:
@@ -1128,7 +1128,7 @@ class FusedMoE(CustomOp):
1128 )
1129 expert_placement_strategy = "linear"
1130
1131 - self.expert_map: Optional[torch.Tensor]
1131 + self.expert_map: torch.Tensor | None
1132 local_num_experts, expert_map = determine_expert_map(
1133 ep_size=self.ep_size,
1134 ep_rank=self.ep_rank,
@@ -1187,12 +1187,12 @@ class FusedMoE(CustomOp):
1187 has_bias=has_bias,
1188 )
1189 self.moe_config = moe
1190 - self.moe_quant_config: Optional[FusedMoEQuantConfig] = None
1190 + self.moe_quant_config: FusedMoEQuantConfig | None = None
1191 self.quant_config = quant_config
1192
1193 # Note: get_quant_method will look at the layer's local_num_experts
1194 # for heuristic purposes, so it must be initialized first.
1195 - quant_method: Optional[QuantizeMethodBase] = None
1195 + quant_method: QuantizeMethodBase | None = None
1196 quant_method = (
1197 UnquantizedFusedMoEMethod(moe)
1198 if quant_config is None
@@ -1238,8 +1238,8 @@ class FusedMoE(CustomOp):
1238 self.quant_method.create_weights(layer=self, **moe_quant_params)
1239
1240 # Chunked all2all staging tensor
1241 - self.batched_hidden_states: Optional[torch.Tensor] = None
1242 - self.batched_router_logits: Optional[torch.Tensor] = None
1241 + self.batched_hidden_states: torch.Tensor | None = None
1242 + self.batched_router_logits: torch.Tensor | None = None
1243
1244 if self.use_dp_chunking:
1245 states_shape: tuple[int, ...]
@@ -1262,7 +1262,7 @@ class FusedMoE(CustomOp):
1262 )
1263
1264 @property
1265 - def shared_experts(self) -> Optional[torch.nn.Module]:
1265 + def shared_experts(self) -> torch.nn.Module | None:
1266 return None
1267
1268 @property
@@ -1534,7 +1534,7 @@ class FusedMoE(CustomOp):
1534 shard_id: str,
1535 expert_id: int,
1536 return_success: bool = False,
1537 - ) -> Optional[bool]:
1537 + ) -> bool | None:
1538 if self.quant_config and self.quant_config.get_name() == "mxfp4":
1539 # (FIXME) for gpt-oss all experts are combined
1540 if "bias" in weight_name:
@@ -1851,21 +1851,21 @@ class FusedMoE(CustomOp):
1851 top_k: int,
1852 use_grouped_topk: bool,
1853 renormalize: bool,
1854 - topk_group: Optional[int] = None,
1855 - num_expert_group: Optional[int] = None,
1856 - custom_routing_function: Optional[Callable] = None,
1854 + topk_group: int | None = None,
1855 + num_expert_group: int | None = None,
1856 + custom_routing_function: Callable | None = None,
1857 scoring_func: str = "softmax",
1858 routed_scaling_factor: float = 1.0,
1859 - e_score_correction_bias: Optional[torch.Tensor] = None,
1860 - indices_type: Optional[torch.dtype] = None,
1859 + e_score_correction_bias: torch.Tensor | None = None,
1860 + indices_type: torch.dtype | None = None,
1861 enable_eplb: bool = False,
1862 - expert_map: Optional[torch.Tensor] = None,
1863 - expert_load_view: Optional[torch.Tensor] = None,
1864 - logical_to_physical_map: Optional[torch.Tensor] = None,
1865 - logical_replica_count: Optional[torch.Tensor] = None,
1866 - global_num_experts: Optional[int] = None,
1867 - zero_expert_num: Optional[int] = None,
1868 - zero_expert_type: Optional[str] = None,
1862 + expert_map: torch.Tensor | None = None,
1863 + expert_load_view: torch.Tensor | None = None,
1864 + logical_to_physical_map: torch.Tensor | None = None,
1865 + logical_replica_count: torch.Tensor | None = None,
1866 + global_num_experts: int | None = None,
1867 + zero_expert_num: int | None = None,
1868 + zero_expert_type: str | None = None,
1869 ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
1870 """
1871 Route the input hidden states to the top-k experts based on the
@@ -2006,7 +2006,7 @@ class FusedMoE(CustomOp):
2006 self,
2007 hidden_states: torch.Tensor,
2008 router_logits: torch.Tensor,
2009 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
2009 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
2010 og_hidden_states = hidden_states.shape[-1]
2011 if self.hidden_size != og_hidden_states:
2012 hidden_states = F.pad(
@@ -2047,14 +2047,14 @@ class FusedMoE(CustomOp):
2047 self,
2048 hidden_states: torch.Tensor,
2049 router_logits: torch.Tensor,
2050 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
2050 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
2051 return self.forward_native(hidden_states, router_logits)
2052
2053 def forward_impl_chunked(
2054 self,
2055 full_hidden_states: torch.Tensor,
2056 full_router_logits: torch.Tensor,
2057 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
2057 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
2058 assert self.batched_hidden_states is not None
2059 assert self.batched_router_logits is not None
2060 assert self.batched_hidden_states.dtype == full_hidden_states.dtype
@@ -2200,7 +2200,7 @@ class FusedMoE(CustomOp):
2200 self,
2201 hidden_states: torch.Tensor,
2202 router_logits: torch.Tensor,
2203 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
2203 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
2204 assert self.quant_method is not None
2205
2206 self.ensure_moe_quant_config()
vllm/model_executor/layers/fused_moe/modular_kernel.py
+50 -49
@@ -1,10 +1,11 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from abc import ABC, abstractmethod
4 +from collections.abc import Callable
5 from dataclasses import dataclass
6 from enum import Enum
7 from math import prod
7 -from typing import Callable, Optional, Union, final
8 +from typing import final
9
10 import torch
11
@@ -81,7 +82,7 @@ class ExpertTokensMetadata:
82 """
83
84 expert_num_tokens: torch.Tensor
84 - expert_num_tokens_cpu: Optional[torch.Tensor]
85 + expert_num_tokens_cpu: torch.Tensor | None
86
87 @staticmethod
88 def make_from_list(
@@ -104,7 +105,7 @@ class TopKWeightAndReduce(ABC):
105 @abstractmethod
106 def apply(
107 self,
107 - output: Optional[torch.Tensor],
108 + output: torch.Tensor | None,
109 fused_expert_output: torch.Tensor,
110 topk_weights: torch.Tensor,
111 topk_ids: torch.Tensor,
@@ -132,10 +133,10 @@ class TopKWeightAndReduce(ABC):
133 #
134 PrepareResultType = tuple[
135 torch.Tensor,
135 - Optional[torch.Tensor],
136 - Optional[ExpertTokensMetadata],
137 - Optional[torch.Tensor],
138 - Optional[torch.Tensor],
136 + torch.Tensor | None,
137 + ExpertTokensMetadata | None,
138 + torch.Tensor | None,
139 + torch.Tensor | None,
140 ]
141
142 ReceiverType = Callable[[], PrepareResultType]
@@ -155,7 +156,7 @@ class FusedMoEPrepareAndFinalize(ABC):
156 topk_weights: torch.Tensor,
157 topk_ids: torch.Tensor,
158 num_experts: int,
158 - expert_map: Optional[torch.Tensor],
159 + expert_map: torch.Tensor | None,
160 apply_router_weight_on_input: bool,
161 quant_config: FusedMoEQuantConfig,
162 ) -> PrepareResultType:
@@ -195,10 +196,10 @@ class FusedMoEPrepareAndFinalize(ABC):
196 topk_weights: torch.Tensor,
197 topk_ids: torch.Tensor,
198 num_experts: int,
198 - expert_map: Optional[torch.Tensor],
199 + expert_map: torch.Tensor | None,
200 apply_router_weight_on_input: bool,
201 quant_config: FusedMoEQuantConfig,
201 - ) -> Union[tuple[Callable, ReceiverType], ReceiverType]:
202 + ) -> tuple[Callable, ReceiverType] | ReceiverType:
203 """
204 Perform any quantization (and/or) dispatching needed for this kernel
205 but do not wait for results from other workers.
@@ -270,7 +271,7 @@ class FusedMoEPrepareAndFinalize(ABC):
271 topk_ids: torch.Tensor,
272 apply_router_weight_on_input: bool,
273 weight_and_reduce_impl: TopKWeightAndReduce,
273 - ) -> Union[tuple[Callable, Callable], Callable]:
274 + ) -> tuple[Callable, Callable] | Callable:
275 """
276 Perform any combine plus apply weights and perform a reduction on the
277 fused experts output but do not wait for results from other workers.
@@ -314,7 +315,7 @@ class FusedMoEPrepareAndFinalize(ABC):
315 raise NotImplementedError
316
317 @abstractmethod
317 - def topk_indices_dtype(self) -> Optional[torch.dtype]:
318 + def topk_indices_dtype(self) -> torch.dtype | None:
319 """
320 The PrepareFinalize All2All implementations generally constrain the
321 dtype of the topk_ids they support. This function returns the
@@ -324,7 +325,7 @@ class FusedMoEPrepareAndFinalize(ABC):
325 raise NotImplementedError
326
327 @abstractmethod
327 - def max_num_tokens_per_rank(self) -> Optional[int]:
328 + def max_num_tokens_per_rank(self) -> int | None:
329 """
330 Some PrepareFinalize All2All implementations are batched. Meaning,
331 they can process only as set of tokens at a time. This
@@ -423,11 +424,11 @@ class FusedMoEPermuteExpertsUnpermute(ABC):
424 #
425
426 @property
426 - def quant_dtype(self) -> Optional[torch.dtype]:
427 + def quant_dtype(self) -> torch.dtype | None:
428 return self.quant_config.quant_dtype
429
430 @property
430 - def block_shape(self) -> Optional[list[int]]:
431 + def block_shape(self) -> list[int] | None:
432 return self.quant_config.block_shape
433
434 @property
@@ -439,51 +440,51 @@ class FusedMoEPermuteExpertsUnpermute(ABC):
440 return self.quant_config.per_out_ch_quant
441
442 @property
442 - def a1_scale(self) -> Optional[torch.Tensor]:
443 + def a1_scale(self) -> torch.Tensor | None:
444 return self.quant_config.a1_scale
445
446 @property
446 - def a2_scale(self) -> Optional[torch.Tensor]:
447 + def a2_scale(self) -> torch.Tensor | None:
448 return self.quant_config.a2_scale
449
450 @property
450 - def a1_gscale(self) -> Optional[torch.Tensor]:
451 + def a1_gscale(self) -> torch.Tensor | None:
452 return self.quant_config.a1_gscale
453
454 @property
454 - def a2_gscale(self) -> Optional[torch.Tensor]:
455 + def a2_gscale(self) -> torch.Tensor | None:
456 return self.quant_config.a2_gscale
457
458 @property
458 - def w1_scale(self) -> Optional[torch.Tensor]:
459 + def w1_scale(self) -> torch.Tensor | None:
460 return self.quant_config.w1_scale
461
462 @property
462 - def w2_scale(self) -> Optional[torch.Tensor]:
463 + def w2_scale(self) -> torch.Tensor | None:
464 return self.quant_config.w2_scale
465
466 @property
466 - def w1_zp(self) -> Optional[torch.Tensor]:
467 + def w1_zp(self) -> torch.Tensor | None:
468 return self.quant_config.w1_zp
469
470 @property
470 - def w2_zp(self) -> Optional[torch.Tensor]:
471 + def w2_zp(self) -> torch.Tensor | None:
472 return self.quant_config.w2_zp
473
474 @property
474 - def w1_bias(self) -> Optional[torch.Tensor]:
475 + def w1_bias(self) -> torch.Tensor | None:
476 return self.quant_config.w1_bias
477
478 @property
478 - def w2_bias(self) -> Optional[torch.Tensor]:
479 + def w2_bias(self) -> torch.Tensor | None:
480 return self.quant_config.w2_bias
481
482 @property
482 - def g1_alphas(self) -> Optional[torch.Tensor]:
483 + def g1_alphas(self) -> torch.Tensor | None:
484 return self.quant_config.g1_alphas
485
486 @property
486 - def g2_alphas(self) -> Optional[torch.Tensor]:
487 + def g2_alphas(self) -> torch.Tensor | None:
488 return self.quant_config.g2_alphas
489
490 # TODO (bnell): make this return a CHUNK_SIZE or None instead?
@@ -517,7 +518,7 @@ class FusedMoEPermuteExpertsUnpermute(ABC):
518 topk: int,
519 global_num_experts: int,
520 local_num_experts: int,
520 - expert_tokens_meta: Optional[ExpertTokensMetadata],
521 + expert_tokens_meta: ExpertTokensMetadata | None,
522 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
523 """
524 Compute the shapes for the temporary and final outputs of the two gemms
@@ -578,12 +579,12 @@ class FusedMoEPermuteExpertsUnpermute(ABC):
579 topk_ids: torch.Tensor,
580 activation: str,
581 global_num_experts: int,
581 - expert_map: Optional[torch.Tensor],
582 - a1q_scale: Optional[torch.Tensor],
583 - a2_scale: Optional[torch.Tensor],
582 + expert_map: torch.Tensor | None,
583 + a1q_scale: torch.Tensor | None,
584 + a2_scale: torch.Tensor | None,
585 workspace13: torch.Tensor,
586 workspace2: torch.Tensor,
586 - expert_tokens_meta: Optional[ExpertTokensMetadata],
587 + expert_tokens_meta: ExpertTokensMetadata | None,
588 apply_router_weight_on_input: bool,
589 ) -> None:
590 """
@@ -625,8 +626,8 @@ class FusedMoEPermuteExpertsUnpermute(ABC):
626
627
628 def _slice_scales(
628 - scales: Optional[torch.Tensor], start: int, end: int
629 -) -> Optional[torch.Tensor]:
629 + scales: torch.Tensor | None, start: int, end: int
630 +) -> torch.Tensor | None:
631 if scales is not None:
632 if scales.numel() == 1:
633 return scales
@@ -688,7 +689,7 @@ class FusedMoEModularKernel(torch.nn.Module):
689 self,
690 prepare_finalize: FusedMoEPrepareAndFinalize,
691 fused_experts: FusedMoEPermuteExpertsUnpermute,
691 - shared_experts: Optional[torch.nn.Module] = None,
692 + shared_experts: torch.nn.Module | None = None,
693 ):
694 super().__init__()
695 self.prepare_finalize = prepare_finalize
@@ -741,7 +742,7 @@ class FusedMoEModularKernel(torch.nn.Module):
742 top_k: int,
743 global_num_experts: int,
744 local_num_experts: int,
744 - expert_tokens_meta: Optional[ExpertTokensMetadata],
745 + expert_tokens_meta: ExpertTokensMetadata | None,
746 ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
747 """
748 Allocate temporary and output buffers for the fused experts op.
@@ -825,11 +826,11 @@ class FusedMoEModularKernel(torch.nn.Module):
826 @staticmethod
827 def _slice_expert_tokens_metadata(
828 num_chunks: int,
828 - full_expert_tokens_meta: Optional[ExpertTokensMetadata],
829 + full_expert_tokens_meta: ExpertTokensMetadata | None,
830 chunk_topk_ids: torch.Tensor,
831 local_num_experts: int,
831 - expert_map: Optional[torch.Tensor],
832 - ) -> Optional[ExpertTokensMetadata]:
832 + expert_map: torch.Tensor | None,
833 + ) -> ExpertTokensMetadata | None:
834 if num_chunks == 1 or full_expert_tokens_meta is None:
835 return full_expert_tokens_meta
836
@@ -861,12 +862,12 @@ class FusedMoEModularKernel(torch.nn.Module):
862 topk_weights: torch.Tensor,
863 topk_ids: torch.Tensor,
864 global_num_experts: int,
864 - expert_map: Optional[torch.Tensor],
865 + expert_map: torch.Tensor | None,
866 apply_router_weight_on_input: bool,
867 ) -> tuple[
868 torch.Tensor,
868 - Optional[torch.Tensor],
869 - Optional[ExpertTokensMetadata],
869 + torch.Tensor | None,
870 + ExpertTokensMetadata | None,
871 torch.Tensor,
872 torch.Tensor,
873 ]:
@@ -945,7 +946,7 @@ class FusedMoEModularKernel(torch.nn.Module):
946 self,
947 in_dtype: torch.dtype,
948 a1q: torch.Tensor,
948 - a1q_scale: Optional[torch.Tensor],
949 + a1q_scale: torch.Tensor | None,
950 w1: torch.Tensor,
951 w2: torch.Tensor,
952 topk_weights: torch.Tensor,
@@ -953,9 +954,9 @@ class FusedMoEModularKernel(torch.nn.Module):
954 activation: str,
955 global_num_experts: int,
956 local_num_experts: int,
956 - expert_map: Optional[torch.Tensor],
957 + expert_map: torch.Tensor | None,
958 apply_router_weight_on_input: bool,
958 - expert_tokens_meta: Optional[ExpertTokensMetadata],
959 + expert_tokens_meta: ExpertTokensMetadata | None,
960 ) -> torch.Tensor:
961 _, M_full, N, K, top_k = self.fused_experts.moe_problem_size(
962 a1q, w1, w2, topk_ids
@@ -1042,12 +1043,12 @@ class FusedMoEModularKernel(torch.nn.Module):
1043 topk_weights: torch.Tensor,
1044 topk_ids: torch.Tensor,
1045 apply_router_weight_on_input: bool,
1045 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
1046 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
1047 """
1048 The _finalize method is a wrapper around self.prepare_finalize.finalize
1049 that handles DBO, async and shared expert overlap.
1050 """
1050 - shared_output: Optional[torch.Tensor] = None
1051 + shared_output: torch.Tensor | None = None
1052
1053 if not self.prepare_finalize.supports_async():
1054 assert not dbo_enabled()
@@ -1112,9 +1113,9 @@ class FusedMoEModularKernel(torch.nn.Module):
1113 inplace: bool = False,
1114 activation: str = "silu",
1115 global_num_experts: int = -1,
1115 - expert_map: Optional[torch.Tensor] = None,
1116 + expert_map: torch.Tensor | None = None,
1117 apply_router_weight_on_input: bool = False,
1117 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
1118 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
1119 """
1120 This function computes a Mixture of Experts (MoE) layer using two sets
1121 of weights, w1 and w2, and top-k gating mechanism.
vllm/model_executor/layers/fused_moe/moe_align_block_size.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -13,7 +12,7 @@ def moe_align_block_size(
12 topk_ids: torch.Tensor,
13 block_size: int,
14 num_experts: int,
16 - expert_map: Optional[torch.Tensor] = None,
15 + expert_map: torch.Tensor | None = None,
16 pad_sorted_ids: bool = False,
17 ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
18 """
vllm/model_executor/layers/fused_moe/moe_permute_unpermute.py
+11 -16
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -13,14 +12,12 @@ from vllm.model_executor.layers.fused_moe.utils import _fp8_perm
12
13 def _moe_permute(
14 curr_hidden_states: torch.Tensor,
16 - a1q_scale: Optional[torch.Tensor],
15 + a1q_scale: torch.Tensor | None,
16 curr_topk_ids: torch.Tensor,
17 global_num_experts: int,
19 - expert_map: Optional[torch.Tensor],
18 + expert_map: torch.Tensor | None,
19 block_m: int,
21 -) -> tuple[
22 - torch.Tensor, Optional[torch.Tensor], torch.Tensor, torch.Tensor, torch.Tensor
23 -]:
20 +) -> tuple[torch.Tensor, torch.Tensor | None, torch.Tensor, torch.Tensor, torch.Tensor]:
21 """
22 Determine the sorted_token_ids, expert_ids for the given problem size.
23 Permute the hidden states and scales according to `sorted_token_ids`.
@@ -33,7 +30,7 @@ def _moe_permute(
30 curr_topk_ids, block_m, global_num_experts, expert_map, pad_sorted_ids=True
31 )
32
36 - inv_perm: Optional[torch.Tensor] = None
33 + inv_perm: torch.Tensor | None = None
34
35 num_tokens = top_k_num * tokens_in_chunk
36 expert_ids = torch.repeat_interleave(expert_ids, block_m, dim=0)
@@ -53,7 +50,7 @@ def _moe_permute(
50 def _moe_unpermute_and_reduce(
51 out: torch.Tensor,
52 curr_hidden: torch.Tensor,
56 - inv_perm: Optional[torch.Tensor],
53 + inv_perm: torch.Tensor | None,
54 topk_weight: torch.Tensor,
55 apply_router_weight_on_input: bool,
56 ) -> None:
@@ -73,17 +70,15 @@ def _moe_unpermute_and_reduce(
70
71 def moe_permute(
72 hidden_states: torch.Tensor,
76 - a1q_scale: Optional[torch.Tensor],
73 + a1q_scale: torch.Tensor | None,
74 topk_ids: torch.Tensor,
75 n_expert: int,
76 n_local_expert: int = -1,
80 - expert_map: Optional[torch.Tensor] = None,
81 - align_block_size: Optional[int] = None,
77 + expert_map: torch.Tensor | None = None,
78 + align_block_size: int | None = None,
79 fill_invalid_expert: int = -1,
83 - permuted_hidden_states: Optional[torch.Tensor] = None,
84 -) -> tuple[
85 - torch.Tensor, Optional[torch.Tensor], torch.Tensor, torch.Tensor, torch.Tensor
86 -]:
80 + permuted_hidden_states: torch.Tensor | None = None,
81 +) -> tuple[torch.Tensor, torch.Tensor | None, torch.Tensor, torch.Tensor, torch.Tensor]:
82 """
83 This function expands and permutes activation to gather uncontinuous tokens
84 for each expert.
@@ -198,7 +193,7 @@ def moe_unpermute(
193 permuted_hidden_states: torch.Tensor,
194 topk_weights: torch.Tensor,
195 inv_permuted_idx: torch.Tensor,
201 - expert_first_token_offset: Optional[torch.Tensor] = None,
196 + expert_first_token_offset: torch.Tensor | None = None,
197 ) -> None:
198 """
199 This function expands and permutes activation to gathering uncontinuous
vllm/model_executor/layers/fused_moe/pplx_prepare_finalize.py
+13 -13
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Callable, Optional, Union
3 +from collections.abc import Callable
4
5 import pplx_kernels as pplx
6 import torch
@@ -24,9 +24,9 @@ def pplx_hidden_dim_scale_bytes(
24 max_num_tokens: int,
25 hidden_dim: int,
26 in_dtype: torch.dtype,
27 - quant_dtype: Union[torch.dtype, str, None],
27 + quant_dtype: torch.dtype | str | None,
28 per_act_token_quant: bool,
29 - block_shape: Optional[list[int]],
29 + block_shape: list[int] | None,
30 ):
31 # All pplx byte sizes must be 16-byte aligned.
32 align = 16
@@ -82,10 +82,10 @@ class PplxPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
82 def activation_format(self) -> mk.FusedMoEActivationFormat:
83 return mk.FusedMoEActivationFormat.BatchedExperts
84
85 - def max_num_tokens_per_rank(self) -> Optional[int]:
85 + def max_num_tokens_per_rank(self) -> int | None:
86 return self.max_num_tokens
87
88 - def topk_indices_dtype(self) -> Optional[torch.dtype]:
88 + def topk_indices_dtype(self) -> torch.dtype | None:
89 return torch.uint32
90
91 def num_dispatchers(self) -> int:
@@ -103,7 +103,7 @@ class PplxPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
103 topk_weights: torch.Tensor,
104 topk_ids: torch.Tensor,
105 num_experts: int,
106 - expert_map: Optional[torch.Tensor],
106 + expert_map: torch.Tensor | None,
107 apply_router_weight_on_input: bool,
108 quant_config: FusedMoEQuantConfig,
109 ) -> tuple[Callable, mk.ReceiverType]:
@@ -148,7 +148,7 @@ class PplxPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
148 a1q, a1q_scale, quant_config.per_act_token_quant, quant_config.block_shape
149 )
150
151 - orig_a_scale_block_shape: Optional[int] = None
151 + orig_a_scale_block_shape: int | None = None
152
153 if a1q_scale is not None:
154 scalar_scales = a1q_scale.numel() == 1
@@ -184,7 +184,7 @@ class PplxPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
184 device=device,
185 )
186
187 - expert_x_scale: Optional[torch.Tensor] = None
187 + expert_x_scale: torch.Tensor | None = None
188 if a1q.dtype.itemsize == 1:
189 if quant_config.is_per_act_token:
190 # (M x 1) -> (E x M x K)
@@ -212,7 +212,7 @@ class PplxPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
212
213 # This argument is optional, defaults to indices.size(0)
214 # There's not much point setting this unless it is != indices.size(0)
215 - bound_m: Optional[torch.Tensor] = None
215 + bound_m: torch.Tensor | None = None
216
217 self.a2a.dispatch(
218 out_expert_num_tokens=expert_num_tokens,
@@ -252,8 +252,8 @@ class PplxPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
252 self,
253 expert_num_tokens: torch.Tensor,
254 expert_x: torch.Tensor,
255 - expert_x_scale: Optional[torch.Tensor],
256 - orig_a_scale_block_shape: Optional[int],
255 + expert_x_scale: torch.Tensor | None,
256 + orig_a_scale_block_shape: int | None,
257 ) -> mk.PrepareResultType:
258 if expert_x_scale is not None:
259 expert_x_scale = expert_x_scale[:, :, :orig_a_scale_block_shape]
@@ -271,7 +271,7 @@ class PplxPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
271 topk_weights: torch.Tensor,
272 topk_ids: torch.Tensor,
273 num_experts: int,
274 - expert_map: Optional[torch.Tensor],
274 + expert_map: torch.Tensor | None,
275 apply_router_weight_on_input: bool,
276 quant_config: FusedMoEQuantConfig,
277 ) -> mk.PrepareResultType:
@@ -302,7 +302,7 @@ class PplxPrepareAndFinalize(mk.FusedMoEPrepareAndFinalize):
302
303 # This argument is optional
304 # There's not much point setting this unless it is != topk_ids.size(0)
305 - bound_m: Optional[torch.Tensor] = None
305 + bound_m: torch.Tensor | None = None
306
307 # TODO (bnell): fails in test_pplx_moe.py, figure out what's going on
308 # num_tokens = output.size(0) # M
vllm/model_executor/layers/fused_moe/prepare_finalize.py
+3 -4
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -18,10 +17,10 @@ class MoEPrepareAndFinalizeNoEP(mk.FusedMoEPrepareAndFinalize):
17 def activation_format(self) -> mk.FusedMoEActivationFormat:
18 return mk.FusedMoEActivationFormat.Standard
19
21 - def max_num_tokens_per_rank(self) -> Optional[int]:
20 + def max_num_tokens_per_rank(self) -> int | None:
21 return None
22
24 - def topk_indices_dtype(self) -> Optional[torch.dtype]:
23 + def topk_indices_dtype(self) -> torch.dtype | None:
24 return None
25
26 def num_dispatchers(self) -> int:
@@ -36,7 +35,7 @@ class MoEPrepareAndFinalizeNoEP(mk.FusedMoEPrepareAndFinalize):
35 topk_weights: torch.Tensor,
36 topk_ids: torch.Tensor,
37 num_experts: int,
39 - expert_map: Optional[torch.Tensor],
38 + expert_map: torch.Tensor | None,
39 apply_router_weight_on_input: bool,
40 quant_config: FusedMoEQuantConfig,
41 ) -> mk.PrepareResultType:
vllm/model_executor/layers/fused_moe/rocm_aiter_fused_moe.py
+25 -26
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from enum import IntEnum
4 from functools import cache
5 -from typing import Optional
5
6 import torch
7
@@ -53,13 +52,13 @@ def rocm_aiter_asm_moe_tkw1_impl(
52 w2: torch.Tensor,
53 topk_weights: torch.Tensor,
54 topk_ids: torch.Tensor,
56 - fc1_scale: Optional[torch.Tensor] = None,
57 - fc2_scale: Optional[torch.Tensor] = None,
58 - fc1_smooth_scale: Optional[torch.Tensor] = None,
59 - fc2_smooth_scale: Optional[torch.Tensor] = None,
55 + fc1_scale: torch.Tensor | None = None,
56 + fc2_scale: torch.Tensor | None = None,
57 + fc1_smooth_scale: torch.Tensor | None = None,
58 + fc2_smooth_scale: torch.Tensor | None = None,
59 a16: bool = False,
61 - per_tensor_quant_scale: Optional[torch.Tensor] = None,
62 - expert_mask: Optional[torch.Tensor] = None,
60 + per_tensor_quant_scale: torch.Tensor | None = None,
61 + expert_mask: torch.Tensor | None = None,
62 activation_method: int = ActivationMethod.SILU.value,
63 ) -> torch.Tensor:
64 from aiter import ActivationType
@@ -90,13 +89,13 @@ def rocm_aiter_asm_moe_tkw1_fake(
89 w2: torch.Tensor,
90 topk_weights: torch.Tensor,
91 topk_ids: torch.Tensor,
93 - fc1_scale: Optional[torch.Tensor] = None,
94 - fc2_scale: Optional[torch.Tensor] = None,
95 - fc1_smooth_scale: Optional[torch.Tensor] = None,
96 - fc2_smooth_scale: Optional[torch.Tensor] = None,
92 + fc1_scale: torch.Tensor | None = None,
93 + fc2_scale: torch.Tensor | None = None,
94 + fc1_smooth_scale: torch.Tensor | None = None,
95 + fc2_smooth_scale: torch.Tensor | None = None,
96 a16: bool = False,
98 - per_tensor_quant_scale: Optional[torch.Tensor] = None,
99 - expert_mask: Optional[torch.Tensor] = None,
97 + per_tensor_quant_scale: torch.Tensor | None = None,
98 + expert_mask: torch.Tensor | None = None,
99 activation_method: int = ActivationMethod.SILU.value,
100 ) -> torch.Tensor:
101 return torch.empty_like(hidden_states)
@@ -206,14 +205,14 @@ def rocm_aiter_fused_moe_impl(
205 w2: torch.Tensor,
206 topk_weight: torch.Tensor,
207 topk_ids: torch.Tensor,
209 - expert_mask: Optional[torch.Tensor] = None,
208 + expert_mask: torch.Tensor | None = None,
209 activation_method: int = ActivationMethod.SILU.value,
210 quant_method: int = QuantMethod.NO.value,
211 doweight_stage1: bool = False,
213 - w1_scale: Optional[torch.Tensor] = None,
214 - w2_scale: Optional[torch.Tensor] = None,
215 - a1_scale: Optional[torch.Tensor] = None,
216 - a2_scale: Optional[torch.Tensor] = None,
212 + w1_scale: torch.Tensor | None = None,
213 + w2_scale: torch.Tensor | None = None,
214 + a1_scale: torch.Tensor | None = None,
215 + a2_scale: torch.Tensor | None = None,
216 ) -> torch.Tensor:
217 from aiter import ActivationType, QuantType
218 from aiter.fused_moe import fused_moe
@@ -244,14 +243,14 @@ def rocm_aiter_fused_moe_fake(
243 w2: torch.Tensor,
244 topk_weight: torch.Tensor,
245 topk_ids: torch.Tensor,
247 - expert_mask: Optional[torch.Tensor] = None,
246 + expert_mask: torch.Tensor | None = None,
247 activation_method: int = ActivationMethod.SILU.value,
248 quant_method: int = QuantMethod.NO.value,
249 doweight_stage1: bool = False,
251 - w1_scale: Optional[torch.Tensor] = None,
252 - w2_scale: Optional[torch.Tensor] = None,
253 - a1_scale: Optional[torch.Tensor] = None,
254 - a2_scale: Optional[torch.Tensor] = None,
250 + w1_scale: torch.Tensor | None = None,
251 + w2_scale: torch.Tensor | None = None,
252 + a1_scale: torch.Tensor | None = None,
253 + a2_scale: torch.Tensor | None = None,
254 ) -> torch.Tensor:
255 return torch.empty_like(hidden_states)
256
@@ -300,7 +299,7 @@ def rocm_aiter_grouped_topk(
299 topk_group: int = 0,
300 scoring_func: str = "softmax",
301 routed_scaling_factor: float = 1.0,
303 - e_score_correction_bias: Optional[torch.Tensor] = None,
302 + e_score_correction_bias: torch.Tensor | None = None,
303 ) -> tuple[torch.Tensor, torch.Tensor]:
304 token = hidden_states.shape[0]
305 device = hidden_states.device
@@ -342,8 +341,8 @@ def rocm_aiter_fused_experts(
341 topk_ids: torch.Tensor,
342 activation: str = "silu",
343 apply_router_weight_on_input: bool = False,
345 - expert_map: Optional[torch.Tensor] = None,
346 - quant_config: Optional[FusedMoEQuantConfig] = None,
344 + expert_map: torch.Tensor | None = None,
345 + quant_config: FusedMoEQuantConfig | None = None,
346 ) -> torch.Tensor:
347 if quant_config is None:
348 quant_config = FUSED_MOE_UNQUANTIZED_CONFIG
vllm/model_executor/layers/fused_moe/routing_simulator.py
+4 -4
@@ -10,7 +10,7 @@ like uniform random routing.
10 """
11
12 from abc import ABC, abstractmethod
13 -from typing import Any, Optional
13 +from typing import Any
14
15 import torch
16
@@ -24,7 +24,7 @@ class RoutingStrategy(ABC):
24 hidden_states: torch.Tensor,
25 router_logits: torch.Tensor,
26 top_k: int,
27 - indices_type: Optional[torch.dtype] = None,
27 + indices_type: torch.dtype | None = None,
28 ) -> tuple[torch.Tensor, torch.Tensor]:
29 """
30 Route tokens to experts.
@@ -89,7 +89,7 @@ class DistributionBasedRouting(RoutingStrategy):
89 hidden_states: torch.Tensor,
90 router_logits: torch.Tensor,
91 top_k: int,
92 - indices_type: Optional[torch.dtype] = None,
92 + indices_type: torch.dtype | None = None,
93 ) -> tuple[torch.Tensor, torch.Tensor]:
94 """
95 Randomly select experts for each token using the specified distribution.
@@ -269,7 +269,7 @@ class RoutingSimulator:
269 router_logits: torch.Tensor,
270 strategy_name: str,
271 top_k: int,
272 - indices_type: Optional[torch.dtype] = None,
272 + indices_type: torch.dtype | None = None,
273 ) -> tuple[torch.Tensor, torch.Tensor]:
274 """
275 Simulate token-to-expert routing using the specified strategy.
vllm/model_executor/layers/fused_moe/shared_fused_moe.py
+2 -3
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -18,7 +17,7 @@ class SharedFusedMoE(FusedMoE):
17
18 def __init__(
19 self,
21 - shared_experts: Optional[torch.nn.Module],
20 + shared_experts: torch.nn.Module | None,
21 use_overlapped: bool = True,
22 **kwargs,
23 ):
@@ -35,7 +34,7 @@ class SharedFusedMoE(FusedMoE):
34 )
35
36 @property
38 - def shared_experts(self) -> Optional[torch.nn.Module]:
37 + def shared_experts(self) -> torch.nn.Module | None:
38 return self._shared_experts if self.use_overlapped else None
39
40 def forward(
vllm/model_executor/layers/fused_moe/topk_weight_and_reduce.py
+4 -5
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -29,7 +28,7 @@ class TopKWeightAndReduceDelegate(mk.TopKWeightAndReduce):
28
29 def apply(
30 self,
32 - output: Optional[torch.Tensor],
31 + output: torch.Tensor | None,
32 fused_expert_output: torch.Tensor,
33 topk_weights: torch.Tensor,
34 topk_ids: torch.Tensor,
@@ -52,7 +51,7 @@ class TopKWeightAndReduceNoOP(mk.TopKWeightAndReduce):
51
52 def apply(
53 self,
55 - output: Optional[torch.Tensor],
54 + output: torch.Tensor | None,
55 fused_expert_output: torch.Tensor,
56 topk_weights: torch.Tensor,
57 topk_ids: torch.Tensor,
@@ -84,7 +83,7 @@ class TopKWeightAndReduceContiguous(mk.TopKWeightAndReduce):
83
84 def apply(
85 self,
87 - output: Optional[torch.Tensor],
86 + output: torch.Tensor | None,
87 fused_expert_output: torch.Tensor,
88 topk_weights: torch.Tensor,
89 topk_ids: torch.Tensor,
@@ -133,7 +132,7 @@ class TopKWeightAndReduceNaiveBatched(mk.TopKWeightAndReduce):
132
133 def apply(
134 self,
136 - output: Optional[torch.Tensor],
135 + output: torch.Tensor | None,
136 fused_expert_output: torch.Tensor,
137 topk_weights: torch.Tensor,
138 topk_ids: torch.Tensor,
vllm/model_executor/layers/fused_moe/triton_deep_gemm_moe.py
+5 -6
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -89,7 +88,7 @@ class TritonOrDeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
88 topk: int,
89 global_num_experts: int,
90 local_num_experts: int,
92 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
91 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
92 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
93 # Note: the deep gemm workspaces are strictly larger than the triton
94 # workspaces so we can be pessimistic here and allocate for DeepGemm
@@ -128,12 +127,12 @@ class TritonOrDeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
127 topk_ids: torch.Tensor,
128 activation: str,
129 global_num_experts: int,
131 - expert_map: Optional[torch.Tensor],
132 - a1q_scale: Optional[torch.Tensor],
133 - a2_scale: Optional[torch.Tensor],
130 + expert_map: torch.Tensor | None,
131 + a1q_scale: torch.Tensor | None,
132 + a2_scale: torch.Tensor | None,
133 workspace13: torch.Tensor,
134 workspace2: torch.Tensor,
136 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
135 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
136 apply_router_weight_on_input: bool,
137 ):
138 use_deep_gemm = self.allow_deep_gemm and (
vllm/model_executor/layers/fused_moe/trtllm_moe.py
+5 -6
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -58,7 +57,7 @@ class TrtLlmGenExperts(mk.FusedMoEPermuteExpertsUnpermute):
57 topk: int,
58 global_num_experts: int,
59 local_num_experts: int,
61 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
60 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
61 ) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
62 # The workspaces for this implementation are managed by flashinfer.
63 workspace1 = (0,)
@@ -100,12 +99,12 @@ class TrtLlmGenExperts(mk.FusedMoEPermuteExpertsUnpermute):
99 topk_ids: torch.Tensor,
100 activation: str,
101 global_num_experts: int,
103 - expert_map: Optional[torch.Tensor],
104 - a1q_scale: Optional[torch.Tensor],
105 - a2_scale: Optional[torch.Tensor],
102 + expert_map: torch.Tensor | None,
103 + a1q_scale: torch.Tensor | None,
104 + a2_scale: torch.Tensor | None,
105 workspace13: torch.Tensor,
106 workspace2: torch.Tensor,
108 - expert_tokens_meta: Optional[mk.ExpertTokensMetadata],
107 + expert_tokens_meta: mk.ExpertTokensMetadata | None,
108 apply_router_weight_on_input: bool,
109 ):
110 topk = topk_ids.size(-1)
vllm/model_executor/layers/fused_moe/utils.py
+23 -24
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from math import prod
4 -from typing import Optional, Union
4
5 import torch
6
@@ -60,7 +59,7 @@ def _count_expert_num_tokens(
59
60
61 def count_expert_num_tokens(
63 - topk_ids: torch.Tensor, num_local_experts: int, expert_map: Optional[torch.Tensor]
62 + topk_ids: torch.Tensor, num_local_experts: int, expert_map: torch.Tensor | None
63 ) -> torch.Tensor:
64 """
65 Count the number to tokens assigned to each expert.
@@ -112,7 +111,7 @@ def _resize_cache(x: torch.Tensor, v: tuple[int, ...]) -> torch.Tensor:
111
112 def _nvfp4_quantize(
113 A: torch.Tensor,
115 - A_scale: Optional[torch.Tensor],
114 + A_scale: torch.Tensor | None,
115 is_sf_swizzled_layout: bool,
116 ) -> tuple[torch.Tensor, torch.Tensor]:
117 return flashinfer_fp4_quantize(
@@ -122,9 +121,9 @@ def _nvfp4_quantize(
121
122 def _fp8_quantize(
123 A: torch.Tensor,
125 - A_scale: Optional[torch.Tensor],
124 + A_scale: torch.Tensor | None,
125 per_act_token: bool,
127 - block_shape: Optional[list[int]] = None,
126 + block_shape: list[int] | None = None,
127 ) -> tuple[torch.Tensor, torch.Tensor]:
128 """
129 Perform fp8 quantization on the inputs. If a block_shape
@@ -148,9 +147,9 @@ def _fp8_quantize(
147
148 def _int8_quantize(
149 A: torch.Tensor,
151 - A_scale: Optional[torch.Tensor],
150 + A_scale: torch.Tensor | None,
151 per_act_token: bool,
153 - block_shape: Optional[list[int]] = None,
152 + block_shape: list[int] | None = None,
153 ) -> tuple[torch.Tensor, torch.Tensor]:
154 """
155 Perform int8 quantization on the inputs. If a block_shape
@@ -175,9 +174,9 @@ def _int8_quantize(
174
175 def _mxfp4_quantize(
176 A: torch.Tensor,
178 - A_scale: Optional[torch.Tensor],
177 + A_scale: torch.Tensor | None,
178 per_act_token_quant: bool,
180 - block_shape: Optional[list[int]] = None,
179 + block_shape: list[int] | None = None,
180 ) -> tuple[torch.Tensor, None]:
181 assert block_shape is None
182 # TODO: native mxfp4 is currently not integrated in vllm,
@@ -191,9 +190,9 @@ def _mxfp4_quantize(
190
191 def _mxfp8_e4m3_quantize(
192 A: torch.Tensor,
194 - A_scale: Optional[torch.Tensor],
193 + A_scale: torch.Tensor | None,
194 per_act_token_quant: bool,
196 - block_shape: Optional[list[int]] = None,
195 + block_shape: list[int] | None = None,
196 ) -> tuple[torch.Tensor, torch.Tensor]:
197 assert A_scale is None
198 assert not per_act_token_quant
@@ -203,9 +202,9 @@ def _mxfp8_e4m3_quantize(
202
203 def _mxfp6_e3m2_quantize(
204 A: torch.Tensor,
206 - A_scale: Optional[torch.Tensor],
205 + A_scale: torch.Tensor | None,
206 per_act_token_quant: bool,
208 - block_shape: Optional[list[int]] = None,
207 + block_shape: list[int] | None = None,
208 ) -> tuple[torch.Tensor, None]:
209 assert block_shape is None
210
@@ -220,9 +219,9 @@ def _mxfp6_e3m2_quantize(
219
220 def _mxfp6_e2m3_quantize(
221 A: torch.Tensor,
223 - A_scale: Optional[torch.Tensor],
222 + A_scale: torch.Tensor | None,
223 per_act_token_quant: bool,
225 - block_shape: Optional[list[int]] = None,
224 + block_shape: list[int] | None = None,
225 ) -> tuple[torch.Tensor, None]:
226 assert block_shape is None
227
@@ -237,12 +236,12 @@ def _mxfp6_e2m3_quantize(
236
237 def moe_kernel_quantize_input(
238 A: torch.Tensor,
240 - A_scale: Optional[torch.Tensor],
241 - quant_dtype: Union[None, torch.dtype, str],
239 + A_scale: torch.Tensor | None,
240 + quant_dtype: None | torch.dtype | str,
241 per_act_token_quant: bool,
243 - block_shape: Optional[list[int]] = None,
242 + block_shape: list[int] | None = None,
243 is_fp4_scale_swizzled: bool = True,
245 -) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
244 +) -> tuple[torch.Tensor, torch.Tensor | None]:
245 if quant_dtype == torch.float8_e4m3fn:
246 return _fp8_quantize(A, A_scale, per_act_token_quant, block_shape)
247 elif quant_dtype == torch.int8:
@@ -273,7 +272,7 @@ def _fp8_perm(m: torch.Tensor, idx: torch.Tensor) -> torch.Tensor:
272 return m[idx, ...]
273
274
276 -def normalize_scales_shape(scales: Optional[torch.Tensor]) -> Optional[torch.Tensor]:
275 +def normalize_scales_shape(scales: torch.Tensor | None) -> torch.Tensor | None:
276 if scales is not None:
277 if scales.numel() == 1:
278 scales = scales.view(1, 1)
@@ -283,9 +282,9 @@ def normalize_scales_shape(scales: Optional[torch.Tensor]) -> Optional[torch.Ten
282
283
284 def normalize_batched_scales_shape(
286 - scales: Optional[torch.Tensor],
285 + scales: torch.Tensor | None,
286 num_experts: int,
288 -) -> Optional[torch.Tensor]:
287 +) -> torch.Tensor | None:
288 if scales is not None and scales.ndim < 3:
289 if scales.numel() == 1:
290 scales = scales.view(1)
@@ -300,9 +299,9 @@ def normalize_batched_scales_shape(
299
300 def _validate_scale_shape(
301 a: torch.Tensor,
303 - a_scale: Optional[torch.Tensor],
302 + a_scale: torch.Tensor | None,
303 per_act_token_quant: bool,
305 - block_shape: Optional[list[int]],
304 + block_shape: list[int] | None,
305 ) -> None:
306 if a_scale is None:
307 return
vllm/model_executor/layers/layernorm.py
+16 -18
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Custom normalization layers."""
4
5 -from typing import Optional, Union
6 -
5 import torch
6 import torch.nn as nn
7 import torch.nn.functional as F
@@ -159,9 +157,9 @@ class RMSNorm(CustomOp):
157 self,
158 hidden_size: int,
159 eps: float = 1e-6,
162 - var_hidden_size: Optional[int] = None,
160 + var_hidden_size: int | None = None,
161 has_weight: bool = True,
164 - dtype: Optional[torch.dtype] = None,
162 + dtype: torch.dtype | None = None,
163 ) -> None:
164 super().__init__()
165
@@ -190,8 +188,8 @@ class RMSNorm(CustomOp):
188 def forward_native(
189 self,
190 x: torch.Tensor,
193 - residual: Optional[torch.Tensor] = None,
194 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
191 + residual: torch.Tensor | None = None,
192 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
193 """PyTorch-native implementation equivalent to forward()."""
194 orig_dtype = x.dtype
195 x = x.to(torch.float32)
@@ -231,8 +229,8 @@ class RMSNorm(CustomOp):
229 def forward_cuda(
230 self,
231 x: torch.Tensor,
234 - residual: Optional[torch.Tensor] = None,
235 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
232 + residual: torch.Tensor | None = None,
233 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
234 if self.variance_size_override is not None:
235 return self.forward_native(x, residual)
236
@@ -247,8 +245,8 @@ class RMSNorm(CustomOp):
245 def forward_hip(
246 self,
247 x: torch.Tensor,
250 - residual: Optional[torch.Tensor] = None,
251 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
248 + residual: torch.Tensor | None = None,
249 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
250 if self.variance_size_override is not None:
251 return self.forward_native(x, residual)
252
@@ -263,8 +261,8 @@ class RMSNorm(CustomOp):
261 def forward_xpu(
262 self,
263 x: torch.Tensor,
266 - residual: Optional[torch.Tensor] = None,
267 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
264 + residual: torch.Tensor | None = None,
265 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
266 if self.variance_size_override is not None:
267 return self.forward_native(x, residual)
268
@@ -313,8 +311,8 @@ class GemmaRMSNorm(CustomOp):
311 weight: torch.Tensor,
312 variance_epsilon: float,
313 x: torch.Tensor,
316 - residual: Optional[torch.Tensor],
317 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
314 + residual: torch.Tensor | None,
315 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
316 """PyTorch-native implementation equivalent to forward()."""
317 orig_dtype = x.dtype
318 if residual is not None:
@@ -337,16 +335,16 @@ class GemmaRMSNorm(CustomOp):
335 def forward_native(
336 self,
337 x: torch.Tensor,
340 - residual: Optional[torch.Tensor] = None,
341 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
338 + residual: torch.Tensor | None = None,
339 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
340 """PyTorch-native implementation equivalent to forward()."""
341 return self.forward_static(self.weight.data, self.variance_epsilon, x, residual)
342
343 def forward_cuda(
344 self,
345 x: torch.Tensor,
348 - residual: Optional[torch.Tensor] = None,
349 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
346 + residual: torch.Tensor | None = None,
347 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
348 if torch.compiler.is_compiling():
349 return self.forward_native(x, residual)
350
vllm/model_executor/layers/lightning_attn.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5 from einops import rearrange
@@ -529,7 +528,7 @@ def lightning_attention(
528 v: torch.Tensor,
529 ed: torch.Tensor,
530 block_size: int = 256,
532 - kv_history: Optional[torch.Tensor] = None,
531 + kv_history: torch.Tensor | None = None,
532 ) -> tuple[torch.Tensor, torch.Tensor]:
533 """
534 Apply lightning attention algorithm
vllm/model_executor/layers/linear.py
+25 -25
@@ -3,7 +3,7 @@
3
4 import itertools
5 from abc import abstractmethod
6 -from typing import Any, Optional, Union
6 +from typing import Any
7
8 import torch
9 from torch.nn.parameter import Parameter, UninitializedParameter
@@ -187,7 +187,7 @@ class LinearMethodBase(QuantizeMethodBase):
187 self,
188 layer: torch.nn.Module,
189 x: torch.Tensor,
190 - bias: Optional[torch.Tensor] = None,
190 + bias: torch.Tensor | None = None,
191 ) -> torch.Tensor:
192 """Apply the weights in layer to the input tensor.
193 Expects create_weights to have been called before on the layer."""
@@ -252,7 +252,7 @@ class UnquantizedLinearMethod(LinearMethodBase):
252 self,
253 layer: torch.nn.Module,
254 x: torch.Tensor,
255 - bias: Optional[torch.Tensor] = None,
255 + bias: torch.Tensor | None = None,
256 ) -> torch.Tensor:
257 return dispatch_unquantized_gemm()(layer, x, layer.weight, bias)
258
@@ -276,8 +276,8 @@ class LinearBase(CustomOp):
276 input_size: int,
277 output_size: int,
278 skip_bias_add: bool = False,
279 - params_dtype: Optional[torch.dtype] = None,
280 - quant_config: Optional[QuantizationConfig] = None,
279 + params_dtype: torch.dtype | None = None,
280 + quant_config: QuantizationConfig | None = None,
281 prefix: str = "",
282 *,
283 return_bias: bool = True,
@@ -295,7 +295,7 @@ class LinearBase(CustomOp):
295 self.quant_config = quant_config
296 self.prefix = prefix
297 if quant_config is None:
298 - self.quant_method: Optional[QuantizeMethodBase] = UnquantizedLinearMethod()
298 + self.quant_method: QuantizeMethodBase | None = UnquantizedLinearMethod()
299 else:
300 self.quant_method = quant_config.get_quant_method(self, prefix=prefix)
301 self.return_bias = return_bias
@@ -333,8 +333,8 @@ class ReplicatedLinear(LinearBase):
333 output_size: int,
334 bias: bool = True,
335 skip_bias_add: bool = False,
336 - params_dtype: Optional[torch.dtype] = None,
337 - quant_config: Optional[QuantizationConfig] = None,
336 + params_dtype: torch.dtype | None = None,
337 + quant_config: QuantizationConfig | None = None,
338 prefix: str = "",
339 *,
340 return_bias: bool = True,
@@ -409,7 +409,7 @@ class ReplicatedLinear(LinearBase):
409 def forward(
410 self,
411 x: torch.Tensor,
412 - ) -> Union[torch.Tensor, tuple[torch.Tensor, Optional[Parameter]]]:
412 + ) -> torch.Tensor | tuple[torch.Tensor, Parameter | None]:
413 bias = self.bias if not self.skip_bias_add else None
414 assert self.quant_method is not None
415
@@ -461,9 +461,9 @@ class ColumnParallelLinear(LinearBase):
461 bias: bool = True,
462 gather_output: bool = False,
463 skip_bias_add: bool = False,
464 - params_dtype: Optional[torch.dtype] = None,
465 - quant_config: Optional[QuantizationConfig] = None,
466 - output_sizes: Optional[list[int]] = None,
464 + params_dtype: torch.dtype | None = None,
465 + quant_config: QuantizationConfig | None = None,
466 + output_sizes: list[int] | None = None,
467 prefix: str = "",
468 *,
469 return_bias: bool = True,
@@ -574,7 +574,7 @@ class ColumnParallelLinear(LinearBase):
574 def forward(
575 self,
576 input_,
577 - ) -> Union[torch.Tensor, tuple[torch.Tensor, Optional[Parameter]]]:
577 + ) -> torch.Tensor | tuple[torch.Tensor, Parameter | None]:
578 bias = self.bias if not self.skip_bias_add else None
579
580 # Matrix multiply.
@@ -633,8 +633,8 @@ class MergedColumnParallelLinear(ColumnParallelLinear):
633 bias: bool = True,
634 gather_output: bool = False,
635 skip_bias_add: bool = False,
636 - params_dtype: Optional[torch.dtype] = None,
637 - quant_config: Optional[QuantizationConfig] = None,
636 + params_dtype: torch.dtype | None = None,
637 + quant_config: QuantizationConfig | None = None,
638 prefix: str = "",
639 *,
640 return_bias: bool = True,
@@ -662,7 +662,7 @@ class MergedColumnParallelLinear(ColumnParallelLinear):
662 self,
663 param: Parameter,
664 loaded_weight: torch.Tensor,
665 - loaded_shard_id: Optional[int] = None,
665 + loaded_shard_id: int | None = None,
666 ):
667 # Special case for GGUF
668 # initialize GGUF param after we know the quantize type
@@ -838,7 +838,7 @@ class MergedColumnParallelLinear(ColumnParallelLinear):
838 self,
839 param: BasevLLMParameter,
840 loaded_weight: torch.Tensor,
841 - loaded_shard_id: Optional[int] = None,
841 + loaded_shard_id: int | None = None,
842 ):
843 if loaded_shard_id is None:
844 if isinstance(param, PerTensorScaleParameter):
@@ -914,11 +914,11 @@ class QKVParallelLinear(ColumnParallelLinear):
914 hidden_size: int,
915 head_size: int,
916 total_num_heads: int,
917 - total_num_kv_heads: Optional[int] = None,
917 + total_num_kv_heads: int | None = None,
918 bias: bool = True,
919 skip_bias_add: bool = False,
920 - params_dtype: Optional[torch.dtype] = None,
921 - quant_config: Optional[QuantizationConfig] = None,
920 + params_dtype: torch.dtype | None = None,
921 + quant_config: QuantizationConfig | None = None,
922 prefix: str = "",
923 *,
924 return_bias: bool = True,
@@ -1027,7 +1027,7 @@ class QKVParallelLinear(ColumnParallelLinear):
1027 self,
1028 param: BasevLLMParameter,
1029 loaded_weight: torch.Tensor,
1030 - loaded_shard_id: Optional[str] = None,
1030 + loaded_shard_id: str | None = None,
1031 ):
1032 if loaded_shard_id is None: # special case for certain models
1033 if isinstance(param, PerTensorScaleParameter):
@@ -1071,7 +1071,7 @@ class QKVParallelLinear(ColumnParallelLinear):
1071 self,
1072 param: Parameter,
1073 loaded_weight: torch.Tensor,
1074 - loaded_shard_id: Optional[str] = None,
1074 + loaded_shard_id: str | None = None,
1075 ):
1076 # Special case for GGUF
1077 # initialize GGUF param after we know the quantize type
@@ -1296,9 +1296,9 @@ class RowParallelLinear(LinearBase):
1296 bias: bool = True,
1297 input_is_parallel: bool = True,
1298 skip_bias_add: bool = False,
1299 - params_dtype: Optional[torch.dtype] = None,
1299 + params_dtype: torch.dtype | None = None,
1300 reduce_results: bool = True,
1301 - quant_config: Optional[QuantizationConfig] = None,
1301 + quant_config: QuantizationConfig | None = None,
1302 prefix: str = "",
1303 *,
1304 return_bias: bool = True,
@@ -1405,7 +1405,7 @@ class RowParallelLinear(LinearBase):
1405 def forward(
1406 self,
1407 input_,
1408 - ) -> Union[torch.Tensor, tuple[torch.Tensor, Optional[Parameter]]]:
1408 + ) -> torch.Tensor | tuple[torch.Tensor, Parameter | None]:
1409 if self.input_is_parallel:
1410 input_parallel = input_
1411 else:
vllm/model_executor/layers/logits_processor.py
+6 -8
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """A layer that compute logits from hidden_stats."""
4
5 -from typing import Optional
6 -
5 import torch
6
7 from vllm.distributed import (
@@ -28,10 +26,10 @@ class LogitsProcessor(CustomOp):
26 def __init__(
27 self,
28 vocab_size: int,
31 - org_vocab_size: Optional[int] = None,
29 + org_vocab_size: int | None = None,
30 scale: float = 1.0,
31 logits_as_input: bool = False,
34 - soft_cap: Optional[float] = None,
32 + soft_cap: float | None = None,
33 ) -> None:
34 """
35 Args:
@@ -53,8 +51,8 @@ class LogitsProcessor(CustomOp):
51 self,
52 lm_head: VocabParallelEmbedding,
53 hidden_states: torch.Tensor,
56 - embedding_bias: Optional[torch.Tensor] = None,
57 - ) -> Optional[torch.Tensor]:
54 + embedding_bias: torch.Tensor | None = None,
55 + ) -> torch.Tensor | None:
56 if self.logits_as_input:
57 logits = hidden_states
58 else:
@@ -88,8 +86,8 @@ class LogitsProcessor(CustomOp):
86 self,
87 hidden_states: torch.Tensor,
88 lm_head: VocabParallelEmbedding,
91 - embedding_bias: Optional[torch.Tensor],
92 - ) -> Optional[torch.Tensor]:
89 + embedding_bias: torch.Tensor | None,
90 + ) -> torch.Tensor | None:
91 # Get the logits for the next tokens.
92 logits = lm_head.quant_method.apply(lm_head, hidden_states, bias=embedding_bias)
93
vllm/model_executor/layers/mamba/linear_attn.py
+7 -7
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import math
5 -from typing import TYPE_CHECKING, Optional, Union
5 +from typing import TYPE_CHECKING
6
7 if TYPE_CHECKING:
8 from vllm.attention.backends.abstract import AttentionBackend
@@ -87,8 +87,8 @@ class MiniMaxText01RMSNormTP(CustomOp):
87 def forward(
88 self,
89 x: torch.Tensor,
90 - residual: Optional[torch.Tensor] = None,
91 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
90 + residual: torch.Tensor | None = None,
91 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
92 assert residual is None, "RMSNorm does not support residual connection."
93 return self._forward(x)
94
@@ -102,7 +102,7 @@ class MiniMaxText01LinearKernel:
102 kv_caches: torch.Tensor,
103 slope_rate: torch.Tensor,
104 block_size: int,
105 - layer_idx: Optional[int] = None,
105 + layer_idx: int | None = None,
106 **kwargs,
107 ) -> torch.Tensor:
108 slope_rate = slope_rate.to(torch.float32)
@@ -154,9 +154,9 @@ class MiniMaxText01LinearAttention(nn.Module, MambaBase):
154 max_position: int,
155 block_size: int,
156 num_hidden_layer: int,
157 - model_config: Optional[ModelConfig] = None,
158 - cache_config: Optional[CacheConfig] = None,
159 - quant_config: Optional[QuantizationConfig] = None,
157 + model_config: ModelConfig | None = None,
158 + cache_config: CacheConfig | None = None,
159 + quant_config: QuantizationConfig | None = None,
160 layer_idx: int = 0,
161 linear_layer_idx: int = 0,
162 prefix: str = "linear_attn",
vllm/model_executor/layers/mamba/mamba_mixer.py
+7 -7
@@ -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, NamedTuple, Optional
4 +from typing import TYPE_CHECKING, NamedTuple
5
6 if TYPE_CHECKING:
7 from vllm.attention.backends.abstract import AttentionBackend
@@ -68,8 +68,8 @@ class MambaMixer(MambaBase, CustomOp):
68 rms_norm_eps: float = 1e-5,
69 activation="silu",
70 is_lora_enabled: bool = False,
71 - model_config: Optional[ModelConfig] = None,
72 - cache_config: Optional[CacheConfig] = None,
71 + model_config: ModelConfig | None = None,
72 + cache_config: CacheConfig | None = None,
73 prefix: str = "",
74 ):
75 super().__init__()
@@ -410,7 +410,7 @@ class MambaMixer(MambaBase, CustomOp):
410
411 return Mamba1AttentionBackend
412
413 - def _time_proj_bias(self) -> Optional[torch.Tensor]:
413 + def _time_proj_bias(self) -> torch.Tensor | None:
414 if hasattr(self.dt_proj, "bias") and self.dt_proj.bias is not None:
415 return self.dt_proj.bias.float()
416 return None
@@ -423,8 +423,8 @@ class PrefillDecodeSplit(NamedTuple):
423 gate_d: torch.Tensor
424 state_indices_tensor_p: torch.Tensor
425 state_indices_tensor_d: torch.Tensor
426 - query_start_loc_p: Optional[torch.Tensor]
427 - has_initial_states_p: Optional[torch.Tensor]
426 + query_start_loc_p: torch.Tensor | None
427 + has_initial_states_p: torch.Tensor | None
428
429
430 def split_batch_to_prefill_and_decode(
@@ -432,7 +432,7 @@ def split_batch_to_prefill_and_decode(
432 gate: torch.Tensor,
433 state_indices_tensor: torch.Tensor,
434 query_start_loc: torch.Tensor,
435 - has_initial_states: Optional[torch.Tensor],
435 + has_initial_states: torch.Tensor | None,
436 num_prefill_tokens: int,
437 num_decode_tokens: int,
438 num_prefills: int,
vllm/model_executor/layers/mamba/mamba_mixer2.py
+10 -10
@@ -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, Optional, Union
4 +from typing import TYPE_CHECKING
5
6 if TYPE_CHECKING:
7 from vllm.attention.backends.abstract import AttentionBackend
@@ -138,7 +138,7 @@ class Mixer2RMSNormGated(CustomOp):
138 self,
139 x: torch.Tensor,
140 gate: torch.Tensor,
141 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
141 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
142 input_dtype = x.dtype
143 if not self.use_rms_norm:
144 # Keep gate in float32 for numerical stability during silu
@@ -244,9 +244,9 @@ class MambaMixer2(MambaBase, CustomOp):
244 rms_norm_eps: float = 1e-5,
245 activation: str = "silu",
246 use_rms_norm: bool = True,
247 - model_config: Optional[ModelConfig] = None,
248 - cache_config: Optional[CacheConfig] = None,
249 - quant_config: Optional[QuantizationConfig] = None,
247 + model_config: ModelConfig | None = None,
248 + cache_config: CacheConfig | None = None,
249 + quant_config: QuantizationConfig | None = None,
250 prefix: str = "",
251 ):
252 super().__init__()
@@ -474,7 +474,7 @@ class MambaMixer2(MambaBase, CustomOp):
474 self,
475 hidden_states: torch.Tensor,
476 output: torch.Tensor,
477 - mup_vector: Optional[torch.Tensor] = None,
477 + mup_vector: torch.Tensor | None = None,
478 ):
479 pass
480
@@ -482,7 +482,7 @@ class MambaMixer2(MambaBase, CustomOp):
482 self,
483 hidden_states: torch.Tensor,
484 output: torch.Tensor,
485 - mup_vector: Optional[torch.Tensor] = None,
485 + mup_vector: torch.Tensor | None = None,
486 ):
487 torch.ops.vllm.mamba_mixer2(
488 hidden_states,
@@ -495,7 +495,7 @@ class MambaMixer2(MambaBase, CustomOp):
495 self,
496 hidden_states: torch.Tensor,
497 output: torch.Tensor,
498 - mup_vector: Optional[torch.Tensor] = None,
498 + mup_vector: torch.Tensor | None = None,
499 ):
500 forward_context = get_forward_context()
501 # attn_metadata contains metadata necessary for the mamba2 triton
@@ -904,7 +904,7 @@ def mamba_mixer2(
904 hidden_states: torch.Tensor,
905 output: torch.Tensor,
906 layer_name: str,
907 - mup_vector: Optional[torch.Tensor] = None,
907 + mup_vector: torch.Tensor | None = None,
908 ) -> None:
909 forward_context: ForwardContext = get_forward_context()
910 self = forward_context.no_compile_layers[layer_name]
@@ -915,7 +915,7 @@ def mamba_mixer2_fake(
915 hidden_states: torch.Tensor,
916 output: torch.Tensor,
917 layer_name: str,
918 - mup_vector: Optional[torch.Tensor] = None,
918 + mup_vector: torch.Tensor | None = None,
919 ) -> None:
920 return
921
vllm/model_executor/layers/mamba/mamba_utils.py
+6 -7
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Union
3
4 import torch
5
@@ -14,7 +13,7 @@ class MambaStateDtypeCalculator:
13 @classmethod
14 def linear_attention_state_dtype(
15 cls,
17 - model_dtype: Union[ModelDType, torch.dtype],
16 + model_dtype: ModelDType | torch.dtype,
17 mamba_cache_dtype: MambaDType,
18 ) -> tuple[torch.dtype, ...]:
19 # TODO (tdoublep) requires testing
@@ -26,7 +25,7 @@ class MambaStateDtypeCalculator:
25 @classmethod
26 def mamba1_state_dtype(
27 cls,
29 - model_dtype: Union[ModelDType, torch.dtype],
28 + model_dtype: ModelDType | torch.dtype,
29 mamba_cache_dtype: MambaDType,
30 mamba_ssm_cache_dtype: MambaDType,
31 ) -> tuple[torch.dtype, ...]:
@@ -37,7 +36,7 @@ class MambaStateDtypeCalculator:
36 @classmethod
37 def mamba2_state_dtype(
38 cls,
40 - model_dtype: Union[ModelDType, torch.dtype],
39 + model_dtype: ModelDType | torch.dtype,
40 mamba_cache_dtype: MambaDType,
41 mamba_ssm_cache_dtype: MambaDType,
42 ) -> tuple[torch.dtype, ...]:
@@ -48,7 +47,7 @@ class MambaStateDtypeCalculator:
47 @classmethod
48 def _mamba_state_dtype(
49 cls,
51 - model_dtype: Union[ModelDType, torch.dtype],
50 + model_dtype: ModelDType | torch.dtype,
51 mamba_cache_dtype: MambaDType,
52 mamba_ssm_cache_dtype: MambaDType,
53 ) -> tuple[torch.dtype, ...]:
@@ -63,7 +62,7 @@ class MambaStateDtypeCalculator:
62 @classmethod
63 def short_conv_state_dtype(
64 cls,
66 - model_dtype: Union[ModelDType, torch.dtype],
65 + model_dtype: ModelDType | torch.dtype,
66 mamba_cache_dtype: MambaDType,
67 ) -> tuple[torch.dtype, ...]:
68 conv_state_dtype = get_kv_cache_torch_dtype(mamba_cache_dtype, model_dtype)
@@ -72,7 +71,7 @@ class MambaStateDtypeCalculator:
71 @classmethod
72 def gated_delta_net_state_dtype(
73 cls,
75 - model_dtype: Union[ModelDType, torch.dtype],
74 + model_dtype: ModelDType | torch.dtype,
75 mamba_cache_dtype: MambaDType,
76 ) -> tuple[torch.dtype, torch.dtype]:
77 state_dtype = get_kv_cache_torch_dtype(mamba_cache_dtype, model_dtype)
vllm/model_executor/layers/mamba/ops/causal_conv1d.py
+15 -16
@@ -4,7 +4,6 @@
4 # Copyright (c) 2024, Tri Dao.
5 # Adapted from https://github.com/Dao-AILab/causal-conv1d/blob/main/causal_conv1d/causal_conv1d_interface.py
6
7 -from typing import Optional, Union
7
8 import numpy as np
9 import torch
@@ -469,17 +468,17 @@ def _causal_conv1d_fwd_kernel( # continuous batching
468 def causal_conv1d_fn(
469 x: torch.Tensor,
470 weight: torch.Tensor,
472 - bias: Union[torch.Tensor, None],
471 + bias: torch.Tensor | None,
472 conv_states: torch.Tensor,
473 query_start_loc: torch.Tensor,
475 - cache_indices: Optional[torch.Tensor] = None,
476 - has_initial_state: Optional[torch.Tensor] = None,
477 - activation: Optional[str] = "silu",
474 + cache_indices: torch.Tensor | None = None,
475 + has_initial_state: torch.Tensor | None = None,
476 + activation: str | None = "silu",
477 pad_slot_id: int = PAD_SLOT_ID,
479 - block_idx_first_scheduled_token: Optional[torch.Tensor] = None,
480 - block_idx_last_scheduled_token: Optional[torch.Tensor] = None,
481 - initial_state_idx: Optional[torch.Tensor] = None,
482 - num_computed_tokens: Optional[torch.Tensor] = None,
478 + block_idx_first_scheduled_token: torch.Tensor | None = None,
479 + block_idx_last_scheduled_token: torch.Tensor | None = None,
480 + initial_state_idx: torch.Tensor | None = None,
481 + num_computed_tokens: torch.Tensor | None = None,
482 block_size_to_align=0,
483 metadata=None,
484 validate_data=False,
@@ -1071,15 +1070,15 @@ def causal_conv1d_update(
1070 x: torch.Tensor,
1071 conv_state: torch.Tensor,
1072 weight: torch.Tensor,
1074 - bias: Optional[torch.Tensor] = None,
1075 - activation: Union[bool, str, None] = None,
1076 - conv_state_indices: Optional[torch.Tensor] = None,
1077 - num_accepted_tokens: Optional[torch.Tensor] = None,
1078 - query_start_loc: Optional[torch.Tensor] = None,
1073 + bias: torch.Tensor | None = None,
1074 + activation: bool | str | None = None,
1075 + conv_state_indices: torch.Tensor | None = None,
1076 + num_accepted_tokens: torch.Tensor | None = None,
1077 + query_start_loc: torch.Tensor | None = None,
1078 max_query_len: int = -1,
1079 pad_slot_id: int = PAD_SLOT_ID,
1081 - block_idx_last_scheduled_token: Optional[torch.Tensor] = None,
1082 - initial_state_idx: Optional[torch.Tensor] = None,
1080 + block_idx_last_scheduled_token: torch.Tensor | None = None,
1081 + initial_state_idx: torch.Tensor | None = None,
1082 validate_data=False,
1083 ):
1084 """
vllm/model_executor/layers/mamba/short_conv.py
+3 -3
@@ -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, Optional
4 +from typing import TYPE_CHECKING
5
6 if TYPE_CHECKING:
7 from vllm.attention.backends.abstract import AttentionBackend
@@ -38,8 +38,8 @@ class ShortConv(MambaBase, CustomOp):
38 config,
39 dim: int,
40 layer_idx: int,
41 - model_config: Optional[ModelConfig] = None,
42 - cache_config: Optional[CacheConfig] = None,
41 + model_config: ModelConfig | None = None,
42 + cache_config: CacheConfig | None = None,
43 prefix: str = "",
44 ):
45 super().__init__()
vllm/model_executor/layers/mla.py
+10 -11
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import Optional
4
5 import torch
6
@@ -19,14 +18,14 @@ class MLAModules:
18 kv_b_proj: torch.nn.Module
19 rotary_emb: torch.nn.Module
20 o_proj: torch.nn.Module
22 - fused_qkv_a_proj: Optional[torch.nn.Module]
23 - kv_a_proj_with_mqa: Optional[torch.nn.Module]
24 - q_a_layernorm: Optional[torch.nn.Module]
25 - q_b_proj: Optional[torch.nn.Module]
26 - q_proj: Optional[torch.nn.Module]
27 - indexer: Optional[torch.nn.Module]
21 + fused_qkv_a_proj: torch.nn.Module | None
22 + kv_a_proj_with_mqa: torch.nn.Module | None
23 + q_a_layernorm: torch.nn.Module | None
24 + q_b_proj: torch.nn.Module | None
25 + q_proj: torch.nn.Module | None
26 + indexer: torch.nn.Module | None
27 is_sparse: bool
29 - topk_indices_buffer: Optional[torch.Tensor]
28 + topk_indices_buffer: torch.Tensor | None
29
30
31 @CustomOp.register("multi_head_latent_attention")
@@ -55,11 +54,11 @@ class MultiHeadLatentAttentionWrapper(CustomOp):
54 qk_nope_head_dim: int,
55 qk_rope_head_dim: int,
56 v_head_dim: int,
58 - q_lora_rank: Optional[int],
57 + q_lora_rank: int | None,
58 kv_lora_rank: int,
59 mla_modules: MLAModules,
61 - cache_config: Optional[CacheConfig] = None,
62 - quant_config: Optional[QuantizationConfig] = None,
60 + cache_config: CacheConfig | None = None,
61 + quant_config: QuantizationConfig | None = None,
62 prefix: str = "",
63 ) -> None:
64 super().__init__()
vllm/model_executor/layers/pooler.py
+27 -27
@@ -1,11 +1,11 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from abc import ABC, abstractmethod
4 -from collections.abc import Mapping, Set
4 +from collections.abc import Callable, Mapping, Set
5 from dataclasses import dataclass
6 from enum import IntEnum
7 from itertools import groupby
8 -from typing import Callable, Optional, TypeVar, Union
8 +from typing import TypeVar
9
10 import torch
11 import torch.nn as nn
@@ -24,8 +24,8 @@ from vllm.v1.pool.metadata import PoolingCursor, PoolingMetadata
24 logger = init_logger(__name__)
25
26 PoolingFn = Callable[
27 - [Union[torch.Tensor, list[torch.Tensor]], PoolingMetadata],
28 - Union[torch.Tensor, list[torch.Tensor]],
27 + [torch.Tensor | list[torch.Tensor], PoolingMetadata],
28 + torch.Tensor | list[torch.Tensor],
29 ]
30 ClassifierFn = Callable[[torch.Tensor], torch.Tensor]
31
@@ -90,7 +90,7 @@ class Pooler(nn.Module, ABC):
90 @staticmethod
91 def for_classify(
92 pooler_config: PoolerConfig,
93 - classifier: Optional[ClassifierFn],
93 + classifier: ClassifierFn | None,
94 ):
95 resolved_config = ResolvedPoolingConfig.from_config(
96 task="classify",
@@ -118,14 +118,14 @@ class Pooler(nn.Module, ABC):
118 @abstractmethod
119 def forward(
120 self,
121 - hidden_states: Union[list[torch.Tensor], torch.Tensor],
121 + hidden_states: list[torch.Tensor] | torch.Tensor,
122 pooling_metadata: PoolingMetadata,
123 ) -> PoolerOutput:
124 raise NotImplementedError
125
126
127 def get_prompt_lens(
128 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
128 + hidden_states: torch.Tensor | list[torch.Tensor],
129 pooling_metadata: PoolingMetadata,
130 ) -> torch.Tensor:
131 return pooling_metadata.prompt_lens
@@ -174,7 +174,7 @@ def get_classification_activation_function(config: PretrainedConfig):
174
175
176 def get_cross_encoder_activation_function(config: PretrainedConfig):
177 - function_name: Optional[str] = None
177 + function_name: str | None = None
178 if (
179 hasattr(config, "sentence_transformers")
180 and "activation_fn" in config.sentence_transformers
@@ -223,14 +223,14 @@ class PoolingMethod(nn.Module, ABC):
223 self,
224 hidden_states: torch.Tensor,
225 pooling_cursor: PoolingCursor,
226 - ) -> Union[list[torch.Tensor], torch.Tensor]:
226 + ) -> list[torch.Tensor] | torch.Tensor:
227 raise NotImplementedError
228
229 def forward(
230 self,
231 hidden_states: torch.Tensor,
232 pooling_metadata: PoolingMetadata,
233 - ) -> Union[list[torch.Tensor], torch.Tensor]:
233 + ) -> list[torch.Tensor] | torch.Tensor:
234 pooling_cursor = pooling_metadata.pooling_cursor
235 return self.forward_all(hidden_states, pooling_cursor)
236
@@ -243,7 +243,7 @@ class CLSPool(PoolingMethod):
243 self,
244 hidden_states: torch.Tensor,
245 pooling_cursor: PoolingCursor,
246 - ) -> Union[list[torch.Tensor], torch.Tensor]:
246 + ) -> list[torch.Tensor] | torch.Tensor:
247 assert not pooling_cursor.is_partial_prefill(), (
248 "partial prefill not supported with CLS pooling"
249 )
@@ -259,7 +259,7 @@ class LastPool(PoolingMethod):
259 self,
260 hidden_states: torch.Tensor,
261 pooling_cursor: PoolingCursor,
262 - ) -> Union[list[torch.Tensor], torch.Tensor]:
262 + ) -> list[torch.Tensor] | torch.Tensor:
263 return hidden_states[pooling_cursor.last_token_indices_gpu]
264
265
@@ -271,7 +271,7 @@ class AllPool(PoolingMethod):
271 self,
272 hidden_states: torch.Tensor,
273 pooling_cursor: PoolingCursor,
274 - ) -> Union[list[torch.Tensor], torch.Tensor]:
274 + ) -> list[torch.Tensor] | torch.Tensor:
275 assert not pooling_cursor.is_partial_prefill(), (
276 "partial prefill not supported with ALL pooling"
277 )
@@ -290,7 +290,7 @@ class MeanPool(PoolingMethod):
290 self,
291 hidden_states: torch.Tensor,
292 pooling_cursor: PoolingCursor,
293 - ) -> Union[list[torch.Tensor], torch.Tensor]:
293 + ) -> list[torch.Tensor] | torch.Tensor:
294 assert not pooling_cursor.is_partial_prefill(), (
295 "partial prefill not supported with MEAN pooling"
296 )
@@ -405,7 +405,7 @@ class PoolerHead(nn.Module):
405
406 def forward(
407 self,
408 - pooled_data: Union[list[torch.Tensor], torch.Tensor],
408 + pooled_data: list[torch.Tensor] | torch.Tensor,
409 pooling_metadata: PoolingMetadata,
410 ):
411 return self.activation(pooled_data)
@@ -418,14 +418,14 @@ class EmbeddingPoolerHead(PoolerHead):
418 # Load ST projector if available
419
420 vllm_config = get_current_vllm_config()
421 - self.projector: Optional[nn.Module] = (
421 + self.projector: nn.Module | None = (
422 _load_st_projector(vllm_config.model_config) if vllm_config else None
423 )
424 self.head_dtype = vllm_config.model_config.head_dtype
425
426 def forward(
427 self,
428 - pooled_data: Union[list[torch.Tensor], torch.Tensor],
428 + pooled_data: list[torch.Tensor] | torch.Tensor,
429 pooling_metadata: PoolingMetadata,
430 ):
431 if isinstance(pooled_data, list):
@@ -480,7 +480,7 @@ class RewardPoolerHead(PoolerHead):
480
481 def forward(
482 self,
483 - pooled_data: Union[list[torch.Tensor], torch.Tensor],
483 + pooled_data: list[torch.Tensor] | torch.Tensor,
484 pooling_metadata: PoolingMetadata,
485 ):
486 if isinstance(pooled_data, list):
@@ -541,7 +541,7 @@ class SimplePooler(Pooler):
541
542 def forward(
543 self,
544 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
544 + hidden_states: torch.Tensor | list[torch.Tensor],
545 pooling_metadata: PoolingMetadata,
546 ) -> PoolerOutput:
547 pooled_data = self.pooling(hidden_states, pooling_metadata)
@@ -560,9 +560,9 @@ class StepPooler(Pooler):
560
561 def extract_states(
562 self,
563 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
563 + hidden_states: torch.Tensor | list[torch.Tensor],
564 pooling_metadata: PoolingMetadata,
565 - ) -> Union[list[torch.Tensor], torch.Tensor]:
565 + ) -> list[torch.Tensor] | torch.Tensor:
566 pooled_data_lst = self.pooling(hidden_states, pooling_metadata)
567 prompt_token_ids = get_prompt_token_ids(pooling_metadata)
568
@@ -593,7 +593,7 @@ class StepPooler(Pooler):
593
594 def forward(
595 self,
596 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
596 + hidden_states: torch.Tensor | list[torch.Tensor],
597 pooling_metadata: PoolingMetadata,
598 ) -> PoolerOutput:
599 pooled_data = self.extract_states(hidden_states, pooling_metadata)
@@ -621,8 +621,8 @@ class ClassifierPooler(Pooler):
621 def __init__(
622 self,
623 pooling: PoolingFn,
624 - classifier: Optional[ClassifierFn],
625 - act_fn: Optional[PoolerActivation] = None,
624 + classifier: ClassifierFn | None,
625 + act_fn: PoolerActivation | None = None,
626 ) -> None:
627 super().__init__()
628
@@ -631,7 +631,7 @@ class ClassifierPooler(Pooler):
631 self.pooling = pooling
632 self.classifier = classifier
633 self.act_fn = act_fn or PoolerClassify()
634 - self.logit_bias: Optional[float] = (
634 + self.logit_bias: float | None = (
635 vllm_config.model_config.pooler_config.logit_bias
636 )
637 self.head_dtype = vllm_config.model_config.head_dtype
@@ -641,7 +641,7 @@ class ClassifierPooler(Pooler):
641
642 def forward(
643 self,
644 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
644 + hidden_states: torch.Tensor | list[torch.Tensor],
645 pooling_metadata: PoolingMetadata,
646 ) -> PoolerOutput:
647 pooled_data = self.pooling(hidden_states, pooling_metadata)
@@ -695,7 +695,7 @@ class DispatchPooler(Pooler):
695
696 def forward(
697 self,
698 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
698 + hidden_states: torch.Tensor | list[torch.Tensor],
699 pooling_metadata: PoolingMetadata,
700 ) -> PoolerOutput:
701 poolers_by_task = self.poolers_by_task
vllm/model_executor/layers/quantization/auto_round.py
+3 -3
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from fractions import Fraction
5 -from typing import TYPE_CHECKING, Any, Optional, Union
5 +from typing import TYPE_CHECKING, Any
6
7 import torch
8
@@ -46,8 +46,8 @@ class AutoRoundConfig(QuantizationConfig):
46 group_size: int,
47 sym: bool = True,
48 packing_format: str = "auto_round:auto_gptq",
49 - block_name_to_quantize: Optional[Union[str, list[str]]] = None,
50 - extra_config: Optional[dict[str, Any]] = None,
49 + block_name_to_quantize: str | list[str] | None = None,
50 + extra_config: dict[str, Any] | None = None,
51 data_type: str = "int",
52 backend: str = "auto",
53 ) -> None:
vllm/model_executor/layers/quantization/awq.py
+4 -4
@@ -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 Any, Optional, Union
4 +from typing import Any, Union
5
6 import torch
7
@@ -34,7 +34,7 @@ class AWQConfig(QuantizationConfig):
34 weight_bits: int,
35 group_size: int,
36 zero_point: bool,
37 - modules_to_not_convert: Optional[list[str]] = None,
37 + modules_to_not_convert: list[str] | None = None,
38 ) -> None:
39 super().__init__()
40 self.weight_bits = weight_bits
@@ -88,7 +88,7 @@ class AWQConfig(QuantizationConfig):
88
89 def get_quant_method(
90 self, layer: torch.nn.Module, prefix: str
91 - ) -> Optional[Union["LinearMethodBase", "QuantizeMethodBase"]]:
91 + ) -> Union["LinearMethodBase", "QuantizeMethodBase"] | None:
92 if isinstance(layer, LinearBase):
93 if is_layer_skipped_awq(prefix, self.modules_to_not_convert):
94 return UnquantizedLinearMethod()
@@ -227,7 +227,7 @@ class AWQLinearMethod(LinearMethodBase):
227 self,
228 layer: torch.nn.Module,
229 x: torch.Tensor,
230 - bias: Optional[torch.Tensor] = None,
230 + bias: torch.Tensor | None = None,
231 ) -> torch.Tensor:
232 qweight = layer.qweight
233 scales = layer.scales
vllm/model_executor/layers/quantization/awq_marlin.py
+15 -14
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional, Union
4 +from collections.abc import Callable
5 +from typing import Any, Optional
6
7 import torch
8 from torch.nn import Parameter
@@ -70,7 +71,7 @@ class AWQMarlinConfig(QuantizationConfig):
71 group_size: int,
72 zero_point: bool,
73 lm_head_quantized: bool,
73 - modules_to_not_convert: Optional[list[str]],
74 + modules_to_not_convert: list[str] | None,
75 full_config: dict[str, Any],
76 ) -> None:
77 super().__init__()
@@ -140,7 +141,7 @@ class AWQMarlinConfig(QuantizationConfig):
141 @classmethod
142 def override_quantization_method(
143 cls, hf_quant_cfg, user_quant
143 - ) -> Optional[QuantizationMethods]:
144 + ) -> QuantizationMethods | None:
145 can_convert = cls.is_awq_marlin_compatible(hf_quant_cfg)
146 is_valid_user_quant = (
147 user_quant is None or user_quant == "marlin" or user_quant == "awq_marlin"
@@ -360,7 +361,7 @@ class AWQMarlinLinearMethod(LinearMethodBase):
361 self,
362 layer: torch.nn.Module,
363 x: torch.Tensor,
363 - bias: Optional[torch.Tensor] = None,
364 + bias: torch.Tensor | None = None,
365 ) -> torch.Tensor:
366 return apply_awq_marlin_linear(
367 input=x,
@@ -555,7 +556,7 @@ class AWQMoEMethod(FusedMoEMethodBase):
556
557 def get_fused_moe_quant_config(
558 self, layer: torch.nn.Module
558 - ) -> Optional[FusedMoEQuantConfig]:
559 + ) -> FusedMoEQuantConfig | None:
560 return None
561
562 def apply(
@@ -566,21 +567,21 @@ class AWQMoEMethod(FusedMoEMethodBase):
567 top_k: int,
568 renormalize: bool,
569 use_grouped_topk: bool = False,
569 - topk_group: Optional[int] = None,
570 - num_expert_group: Optional[int] = None,
570 + topk_group: int | None = None,
571 + num_expert_group: int | None = None,
572 global_num_experts: int = -1,
572 - expert_map: Optional[torch.Tensor] = None,
573 - custom_routing_function: Optional[Callable] = None,
573 + expert_map: torch.Tensor | None = None,
574 + custom_routing_function: Callable | None = None,
575 scoring_func: str = "softmax",
576 routed_scaling_factor: float = 1.0,
576 - e_score_correction_bias: Optional[torch.Tensor] = None,
577 + e_score_correction_bias: torch.Tensor | None = None,
578 apply_router_weight_on_input: bool = False,
579 activation: str = "silu",
580 enable_eplb: bool = False,
580 - expert_load_view: Optional[torch.Tensor] = None,
581 - logical_to_physical_map: Optional[torch.Tensor] = None,
582 - logical_replica_count: Optional[torch.Tensor] = None,
583 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
581 + expert_load_view: torch.Tensor | None = None,
582 + logical_to_physical_map: torch.Tensor | None = None,
583 + logical_replica_count: torch.Tensor | None = None,
584 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
585 assert self.fused_experts is None
586
587 if enable_eplb:
vllm/model_executor/layers/quantization/base_config.py
+4 -4
@@ -3,7 +3,7 @@
3
4 import inspect
5 from abc import ABC, abstractmethod
6 -from typing import TYPE_CHECKING, Any, Optional
6 +from typing import TYPE_CHECKING, Any
7
8 import torch
9 from torch import nn
@@ -105,7 +105,7 @@ class QuantizationConfig(ABC):
105 @classmethod
106 def override_quantization_method(
107 cls, hf_quant_cfg, user_quant
108 - ) -> Optional[QuantizationMethods]:
108 + ) -> QuantizationMethods | None:
109 """
110 Detects if this quantization method can support a given checkpoint
111 format by overriding the user specified quantization method --
@@ -135,7 +135,7 @@ class QuantizationConfig(ABC):
135 @abstractmethod
136 def get_quant_method(
137 self, layer: torch.nn.Module, prefix: str
138 - ) -> Optional[QuantizeMethodBase]:
138 + ) -> QuantizeMethodBase | None:
139 """Get the quantize method to use for the quantized layer.
140
141 Args:
@@ -147,7 +147,7 @@ class QuantizationConfig(ABC):
147 """
148 raise NotImplementedError
149
150 - def get_cache_scale(self, name: str) -> Optional[str]:
150 + def get_cache_scale(self, name: str) -> str | None:
151 return None
152
153 def apply_vllm_mapper( # noqa: B027
vllm/model_executor/layers/quantization/bitblas.py
+6 -6
@@ -45,10 +45,10 @@ class BitBLASConfig(QuantizationConfig):
45 def __init__(
46 self,
47 weight_bits: int,
48 - group_size: Optional[int],
49 - desc_act: Optional[bool],
50 - is_sym: Optional[bool],
51 - quant_method: Optional[str],
48 + group_size: int | None,
49 + desc_act: bool | None,
50 + is_sym: bool | None,
51 + quant_method: str | None,
52 lm_head_quantized: bool,
53 ) -> None:
54 try:
@@ -160,7 +160,7 @@ class BitBLASConfig(QuantizationConfig):
160 @classmethod
161 def override_quantization_method(
162 cls, hf_quant_cfg, user_quant
163 - ) -> Optional[QuantizationMethods]:
163 + ) -> QuantizationMethods | None:
164 # compat: autogptq >=0.8.0 use checkpoint_format: str
165 # compat: autogptq <=0.7.1 is_bitblas_format: bool
166 is_bitblas_format = hf_quant_cfg.get(
@@ -469,7 +469,7 @@ class BitBLASLinearMethod(LinearMethodBase):
469 self,
470 layer: torch.nn.Module,
471 x: torch.Tensor,
472 - bias: Optional[torch.Tensor] = None,
472 + bias: torch.Tensor | None = None,
473 ) -> torch.Tensor:
474 qweight = layer.qweight
475 scales = layer.scales
vllm/model_executor/layers/quantization/bitsandbytes.py
+17 -16
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional, Union
4 +from collections.abc import Callable
5 +from typing import Any, Union
6
7 import torch
8 from packaging import version
@@ -41,7 +42,7 @@ class BitsAndBytesConfig(QuantizationConfig):
42 bnb_4bit_use_double_quant: bool = False,
43 llm_int8_enable_fp32_cpu_offload: bool = False,
44 llm_int8_has_fp16_weight: bool = False,
44 - llm_int8_skip_modules: Optional[list[str]] = None,
45 + llm_int8_skip_modules: list[str] | None = None,
46 llm_int8_threshold: float = 6.0,
47 ) -> None:
48 super().__init__()
@@ -138,7 +139,7 @@ class BitsAndBytesConfig(QuantizationConfig):
139
140 def get_quant_method(
141 self, layer: torch.nn.Module, prefix: str
141 - ) -> Optional[Union["LinearMethodBase", "BitsAndBytesMoEMethod"]]:
142 + ) -> Union["LinearMethodBase", "BitsAndBytesMoEMethod"] | None:
143 if isinstance(layer, LinearBase):
144 if is_layer_skipped_bnb(prefix, self.llm_int8_skip_modules):
145 return UnquantizedLinearMethod()
@@ -268,7 +269,7 @@ class BitsAndBytesLinearMethod(LinearMethodBase):
269 self,
270 layer: torch.nn.Module,
271 x: torch.Tensor,
271 - bias: Optional[torch.Tensor] = None,
272 + bias: torch.Tensor | None = None,
273 ) -> torch.Tensor:
274 if self.quant_config.load_in_8bit:
275 return self._apply_8bit_weight(layer, x, bias)
@@ -279,7 +280,7 @@ class BitsAndBytesLinearMethod(LinearMethodBase):
280 self,
281 layer: torch.nn.Module,
282 x: torch.Tensor,
282 - bias: Optional[torch.Tensor] = None,
283 + bias: torch.Tensor | None = None,
284 ) -> torch.Tensor:
285 # only load the bitsandbytes module when needed
286 from bitsandbytes import MatmulLtState, matmul
@@ -359,7 +360,7 @@ class BitsAndBytesLinearMethod(LinearMethodBase):
360 self,
361 layer: torch.nn.Module,
362 x: torch.Tensor,
362 - bias: Optional[torch.Tensor] = None,
363 + bias: torch.Tensor | None = None,
364 ) -> torch.Tensor:
365 original_type = x.dtype
366 original_shape = x.shape
@@ -489,7 +490,7 @@ class BitsAndBytesMoEMethod(FusedMoEMethodBase):
490
491 def get_fused_moe_quant_config(
492 self, layer: torch.nn.Module
492 - ) -> Optional[FusedMoEQuantConfig]:
493 + ) -> FusedMoEQuantConfig | None:
494 return None
495
496 def apply(
@@ -500,21 +501,21 @@ class BitsAndBytesMoEMethod(FusedMoEMethodBase):
501 top_k: int,
502 renormalize: bool,
503 use_grouped_topk: bool = False,
503 - topk_group: Optional[int] = None,
504 - num_expert_group: Optional[int] = None,
504 + topk_group: int | None = None,
505 + num_expert_group: int | None = None,
506 global_num_experts: int = -1,
506 - expert_map: Optional[torch.Tensor] = None,
507 - custom_routing_function: Optional[Callable] = None,
507 + expert_map: torch.Tensor | None = None,
508 + custom_routing_function: Callable | None = None,
509 scoring_func: str = "softmax",
510 routed_scaling_factor: float = 1.0,
510 - e_score_correction_bias: Optional[torch.Tensor] = None,
511 + e_score_correction_bias: torch.Tensor | None = None,
512 apply_router_weight_on_input: bool = False,
513 activation: str = "silu",
514 enable_eplb: bool = False,
514 - expert_load_view: Optional[torch.Tensor] = None,
515 - logical_to_physical_map: Optional[torch.Tensor] = None,
516 - logical_replica_count: Optional[torch.Tensor] = None,
517 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
515 + expert_load_view: torch.Tensor | None = None,
516 + logical_to_physical_map: torch.Tensor | None = None,
517 + logical_replica_count: torch.Tensor | None = None,
518 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
519 from vllm.model_executor.layers.fused_moe import fused_experts
520
521 assert self.fused_experts is None
vllm/model_executor/layers/quantization/compressed_tensors/compressed_tensors.py
+13 -13
@@ -71,7 +71,7 @@ logger = init_logger(__name__)
71 __all__ = ["CompressedTensorsLinearMethod"]
72
73 SPARSITY_CONFIG_NAME: Literal["sparsity_config"] = "sparsity_config"
74 -QUANTIZATION_SCHEME_MAP_TYPE = dict[str, Optional[dict[str, QuantizationArgs]]]
74 +QUANTIZATION_SCHEME_MAP_TYPE = dict[str, dict[str, QuantizationArgs] | None]
75
76
77 class CompressedTensorsConfig(QuantizationConfig):
@@ -82,9 +82,9 @@ class CompressedTensorsConfig(QuantizationConfig):
82 quant_format: str,
83 sparsity_scheme_map: dict[str, SparsityCompressionConfig],
84 sparsity_ignore_list: list[str],
85 - kv_cache_scheme: Optional[dict[str, Any]] = None,
86 - config: Optional[dict[str, Any]] = None,
87 - transform_config: Optional[dict[str, Any]] = None,
85 + kv_cache_scheme: dict[str, Any] | None = None,
86 + config: dict[str, Any] | None = None,
87 + transform_config: dict[str, Any] | None = None,
88 ):
89 super().__init__()
90 self.ignore = ignore
@@ -524,7 +524,7 @@ class CompressedTensorsConfig(QuantizationConfig):
524 self,
525 weight_quant: QuantizationArgs,
526 input_quant: QuantizationArgs,
527 - format: Optional[str] = None,
527 + format: str | None = None,
528 ) -> "CompressedTensorsScheme":
529 # use the per-layer format if defined, otherwise, use global format
530 format = format if format is not None else self.quant_format
@@ -631,7 +631,7 @@ class CompressedTensorsConfig(QuantizationConfig):
631 raise NotImplementedError("No compressed-tensors compatible scheme was found.")
632
633 def get_scheme(
634 - self, layer: torch.nn.Module, layer_name: Optional[str] = None
634 + self, layer: torch.nn.Module, layer_name: str | None = None
635 ) -> Optional["CompressedTensorsScheme"]:
636 """
637 compressed-tensors supports non uniform in the following way:
@@ -674,7 +674,7 @@ class CompressedTensorsConfig(QuantizationConfig):
674 sparsity_targets = self.sparsity_scheme_map.keys() - set(
675 self.sparsity_ignore_list
676 )
677 - sparsity_scheme: Optional[SparsityCompressionConfig] = None
677 + sparsity_scheme: SparsityCompressionConfig | None = None
678 with suppress(ValueError):
679 matched_target = find_matched_target(
680 layer_name=layer_name,
@@ -723,7 +723,7 @@ class CompressedTensorsConfig(QuantizationConfig):
723 logger.debug("Using scheme: %s for %s", scheme.__class__.__name__, layer_name)
724 return scheme
725
726 - def get_cache_scale(self, name: str) -> Optional[str]:
726 + def get_cache_scale(self, name: str) -> str | None:
727 """
728 Check whether the param name matches the format for k/v cache scales
729 in compressed-tensors. If this is the case, return its equivalent
@@ -751,9 +751,9 @@ class CompressedTensorsConfig(QuantizationConfig):
751
752 @staticmethod
753 def supports_cutlass_24(
754 - weight_quant: Optional[QuantizationArgs],
755 - input_quant: Optional[QuantizationArgs],
756 - sparsity_scheme: Optional[SparsityCompressionConfig] = None,
754 + weight_quant: QuantizationArgs | None,
755 + input_quant: QuantizationArgs | None,
756 + sparsity_scheme: SparsityCompressionConfig | None = None,
757 ) -> bool:
758 """
759 Check if the layer is supported by the Cutlass 2:4 Kernel
@@ -853,7 +853,7 @@ class CompressedTensorsLinearMethod(LinearMethodBase):
853 self,
854 layer: torch.nn.Module,
855 x: torch.Tensor,
856 - bias: Optional[torch.Tensor] = None,
856 + bias: torch.Tensor | None = None,
857 ):
858 """
859 Use the output of create_weights and the CompressedTensorsScheme
@@ -878,7 +878,7 @@ class CompressedTensorsKVCacheMethod(BaseKVCacheMethod):
878 super().__init__(quant_config)
879
880 @staticmethod
881 - def validate_kv_cache_scheme(kv_cache_scheme: Optional[dict[str, Any]]):
881 + def validate_kv_cache_scheme(kv_cache_scheme: dict[str, Any] | None):
882 """
883 Validator for the kv cache scheme. Useful for controlling the
884 kv cache quantization schemes, that are being supported in vLLM
vllm/model_executor/layers/quantization/compressed_tensors/compressed_tensors_moe.py
+63 -63
@@ -2,8 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import enum
5 +from collections.abc import Callable
6 from enum import Enum
6 -from typing import Callable, Optional, Union
7
8 import torch
9 from compressed_tensors import CompressionFormat
@@ -372,7 +372,7 @@ class CompressedTensorsW4A4MoeMethod(CompressedTensorsMoEMethod):
372 (layer.w2_input_global_scale), requires_grad=False
373 )
374
375 - def maybe_make_prepare_finalize(self) -> Optional[mk.FusedMoEPrepareAndFinalize]:
375 + def maybe_make_prepare_finalize(self) -> mk.FusedMoEPrepareAndFinalize | None:
376 if self.use_marlin:
377 return None
378 elif not self.allow_flashinfer:
@@ -399,7 +399,7 @@ class CompressedTensorsW4A4MoeMethod(CompressedTensorsMoEMethod):
399
400 def get_fused_moe_quant_config(
401 self, layer: torch.nn.Module
402 - ) -> Optional[FusedMoEQuantConfig]:
402 + ) -> FusedMoEQuantConfig | None:
403 if self.use_marlin:
404 return None
405
@@ -420,21 +420,21 @@ class CompressedTensorsW4A4MoeMethod(CompressedTensorsMoEMethod):
420 top_k: int,
421 renormalize: bool,
422 use_grouped_topk: bool = False,
423 - topk_group: Optional[int] = None,
424 - num_expert_group: Optional[int] = None,
423 + topk_group: int | None = None,
424 + num_expert_group: int | None = None,
425 global_num_experts: int = -1,
426 - expert_map: Optional[torch.Tensor] = None,
427 - custom_routing_function: Optional[Callable] = None,
426 + expert_map: torch.Tensor | None = None,
427 + custom_routing_function: Callable | None = None,
428 scoring_func: str = "softmax",
429 routed_scaling_factor: float = 1.0,
430 - e_score_correction_bias: Optional[torch.Tensor] = None,
430 + e_score_correction_bias: torch.Tensor | None = None,
431 apply_router_weight_on_input: bool = False,
432 activation: str = "silu",
433 enable_eplb: bool = False,
434 - expert_load_view: Optional[torch.Tensor] = None,
435 - logical_to_physical_map: Optional[torch.Tensor] = None,
436 - logical_replica_count: Optional[torch.Tensor] = None,
437 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
434 + expert_load_view: torch.Tensor | None = None,
435 + logical_to_physical_map: torch.Tensor | None = None,
436 + logical_replica_count: torch.Tensor | None = None,
437 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
438 if enable_eplb:
439 raise NotImplementedError(
440 "EPLB not supported for `CompressedTensorsW4A4MoeMethod` yet."
@@ -913,7 +913,7 @@ class CompressedTensorsW8A8Fp8MoEMethod(CompressedTensorsMoEMethod):
913 layer.w2_weight_scale
914 )
915
916 - def maybe_make_prepare_finalize(self) -> Optional[mk.FusedMoEPrepareAndFinalize]:
916 + def maybe_make_prepare_finalize(self) -> mk.FusedMoEPrepareAndFinalize | None:
917 if self.use_marlin or self.rocm_aiter_moe_enabled:
918 return None
919 else:
@@ -997,7 +997,7 @@ class CompressedTensorsW8A8Fp8MoEMethod(CompressedTensorsMoEMethod):
997
998 def get_fused_moe_quant_config(
999 self, layer: torch.nn.Module
1000 - ) -> Optional[FusedMoEQuantConfig]:
1000 + ) -> FusedMoEQuantConfig | None:
1001 if self.use_marlin:
1002 return None
1003
@@ -1022,21 +1022,21 @@ class CompressedTensorsW8A8Fp8MoEMethod(CompressedTensorsMoEMethod):
1022 top_k: int,
1023 renormalize: bool,
1024 use_grouped_topk: bool = False,
1025 - topk_group: Optional[int] = None,
1026 - num_expert_group: Optional[int] = None,
1025 + topk_group: int | None = None,
1026 + num_expert_group: int | None = None,
1027 global_num_experts: int = -1,
1028 - expert_map: Optional[torch.Tensor] = None,
1029 - custom_routing_function: Optional[Callable] = None,
1028 + expert_map: torch.Tensor | None = None,
1029 + custom_routing_function: Callable | None = None,
1030 scoring_func: str = "softmax",
1031 routed_scaling_factor: float = 1.0,
1032 - e_score_correction_bias: Optional[torch.Tensor] = None,
1032 + e_score_correction_bias: torch.Tensor | None = None,
1033 apply_router_weight_on_input: bool = False,
1034 activation: str = "silu",
1035 enable_eplb: bool = False,
1036 - expert_load_view: Optional[torch.Tensor] = None,
1037 - logical_to_physical_map: Optional[torch.Tensor] = None,
1038 - logical_replica_count: Optional[torch.Tensor] = None,
1039 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
1036 + expert_load_view: torch.Tensor | None = None,
1037 + logical_to_physical_map: torch.Tensor | None = None,
1038 + logical_replica_count: torch.Tensor | None = None,
1039 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
1040 if enable_eplb:
1041 raise NotImplementedError(
1042 "EPLB not supported for `CompressedTensorsW8A8Fp8MoEMethod` yet."
@@ -1280,7 +1280,7 @@ class CompressedTensorsW8A8Int8MoEMethod(CompressedTensorsMoEMethod):
1280
1281 def get_fused_moe_quant_config(
1282 self, layer: torch.nn.Module
1283 - ) -> Optional[FusedMoEQuantConfig]:
1283 + ) -> FusedMoEQuantConfig | None:
1284 return int8_w8a8_moe_quant_config(
1285 w1_scale=layer.w13_weight_scale,
1286 w2_scale=layer.w2_weight_scale,
@@ -1297,21 +1297,21 @@ class CompressedTensorsW8A8Int8MoEMethod(CompressedTensorsMoEMethod):
1297 top_k: int,
1298 renormalize: bool,
1299 use_grouped_topk: bool = False,
1300 - topk_group: Optional[int] = None,
1301 - num_expert_group: Optional[int] = None,
1300 + topk_group: int | None = None,
1301 + num_expert_group: int | None = None,
1302 global_num_experts: int = -1,
1303 - expert_map: Optional[torch.Tensor] = None,
1304 - custom_routing_function: Optional[Callable] = None,
1303 + expert_map: torch.Tensor | None = None,
1304 + custom_routing_function: Callable | None = None,
1305 scoring_func: str = "softmax",
1306 routed_scaling_factor: float = 1.0,
1307 - e_score_correction_bias: Optional[torch.Tensor] = None,
1307 + e_score_correction_bias: torch.Tensor | None = None,
1308 apply_router_weight_on_input: bool = False,
1309 activation: str = "silu",
1310 enable_eplb: bool = False,
1311 - expert_load_view: Optional[torch.Tensor] = None,
1312 - logical_to_physical_map: Optional[torch.Tensor] = None,
1313 - logical_replica_count: Optional[torch.Tensor] = None,
1314 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
1311 + expert_load_view: torch.Tensor | None = None,
1312 + logical_to_physical_map: torch.Tensor | None = None,
1313 + logical_replica_count: torch.Tensor | None = None,
1314 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
1315 assert self.fused_experts is None
1316
1317 if enable_eplb:
@@ -1604,7 +1604,7 @@ class CompressedTensorsWNA16MarlinMoEMethod(CompressedTensorsMoEMethod):
1604
1605 def get_fused_moe_quant_config(
1606 self, layer: torch.nn.Module
1607 - ) -> Optional[FusedMoEQuantConfig]:
1607 + ) -> FusedMoEQuantConfig | None:
1608 return None
1609
1610 def apply(
@@ -1615,21 +1615,21 @@ class CompressedTensorsWNA16MarlinMoEMethod(CompressedTensorsMoEMethod):
1615 top_k: int,
1616 renormalize: bool,
1617 use_grouped_topk: bool = False,
1618 - topk_group: Optional[int] = None,
1619 - num_expert_group: Optional[int] = None,
1618 + topk_group: int | None = None,
1619 + num_expert_group: int | None = None,
1620 global_num_experts: int = -1,
1621 - expert_map: Optional[torch.Tensor] = None,
1622 - custom_routing_function: Optional[Callable] = None,
1621 + expert_map: torch.Tensor | None = None,
1622 + custom_routing_function: Callable | None = None,
1623 scoring_func: str = "softmax",
1624 routed_scaling_factor: float = 1.0,
1625 - e_score_correction_bias: Optional[torch.Tensor] = None,
1625 + e_score_correction_bias: torch.Tensor | None = None,
1626 apply_router_weight_on_input: bool = False,
1627 activation: str = "silu",
1628 enable_eplb: bool = False,
1629 - expert_load_view: Optional[torch.Tensor] = None,
1630 - logical_to_physical_map: Optional[torch.Tensor] = None,
1631 - logical_replica_count: Optional[torch.Tensor] = None,
1632 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
1629 + expert_load_view: torch.Tensor | None = None,
1630 + logical_to_physical_map: torch.Tensor | None = None,
1631 + logical_replica_count: torch.Tensor | None = None,
1632 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
1633 assert self.fused_experts is None
1634
1635 if enable_eplb:
@@ -1856,7 +1856,7 @@ class CompressedTensorsWNA16MoEMethod(CompressedTensorsMoEMethod):
1856
1857 def get_fused_moe_quant_config(
1858 self, layer: torch.nn.Module
1859 - ) -> Optional[FusedMoEQuantConfig]:
1859 + ) -> FusedMoEQuantConfig | None:
1860 assert self.num_bits == 4 or self.num_bits == 8
1861 config_builder = (
1862 int4_w4a16_moe_quant_config
@@ -1880,21 +1880,21 @@ class CompressedTensorsWNA16MoEMethod(CompressedTensorsMoEMethod):
1880 top_k: int,
1881 renormalize: bool,
1882 use_grouped_topk: bool = False,
1883 - topk_group: Optional[int] = None,
1884 - num_expert_group: Optional[int] = None,
1883 + topk_group: int | None = None,
1884 + num_expert_group: int | None = None,
1885 global_num_experts: int = -1,
1886 - expert_map: Optional[torch.Tensor] = None,
1887 - custom_routing_function: Optional[Callable] = None,
1886 + expert_map: torch.Tensor | None = None,
1887 + custom_routing_function: Callable | None = None,
1888 scoring_func: str = "softmax",
1889 routed_scaling_factor: float = 1.0,
1890 - e_score_correction_bias: Optional[torch.Tensor] = None,
1890 + e_score_correction_bias: torch.Tensor | None = None,
1891 apply_router_weight_on_input: bool = False,
1892 activation: str = "silu",
1893 enable_eplb: bool = False,
1894 - expert_load_view: Optional[torch.Tensor] = None,
1895 - logical_to_physical_map: Optional[torch.Tensor] = None,
1896 - logical_replica_count: Optional[torch.Tensor] = None,
1897 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
1894 + expert_load_view: torch.Tensor | None = None,
1895 + logical_to_physical_map: torch.Tensor | None = None,
1896 + logical_replica_count: torch.Tensor | None = None,
1897 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
1898 assert self.fused_experts is None
1899
1900 if enable_eplb:
@@ -2092,7 +2092,7 @@ class CompressedTensorsW4A8Int8MoEMethod(CompressedTensorsMoEMethod):
2092 def _pack_matrix(
2093 int4_as_int8_2d: torch.Tensor,
2094 scales_2d: torch.Tensor,
2095 - bias_1d: Optional[torch.Tensor],
2095 + bias_1d: torch.Tensor | None,
2096 in_features: int,
2097 out_features: int,
2098 ) -> torch.Tensor:
@@ -2192,7 +2192,7 @@ class CompressedTensorsW4A8Int8MoEMethod(CompressedTensorsMoEMethod):
2192
2193 def get_fused_moe_quant_config(
2194 self, layer: torch.nn.Module
2195 - ) -> Optional[FusedMoEQuantConfig]:
2195 + ) -> FusedMoEQuantConfig | None:
2196 # CPU dynamic 4-bit MoE path does not use modular kernels or
2197 # fused_experts; quant config is not needed.
2198 return None
@@ -2205,20 +2205,20 @@ class CompressedTensorsW4A8Int8MoEMethod(CompressedTensorsMoEMethod):
2205 top_k: int,
2206 renormalize: bool,
2207 use_grouped_topk: bool = False,
2208 - topk_group: Optional[int] = None,
2209 - num_expert_group: Optional[int] = None,
2208 + topk_group: int | None = None,
2209 + num_expert_group: int | None = None,
2210 global_num_experts: int = -1,
2211 - expert_map: Optional[torch.Tensor] = None,
2212 - custom_routing_function: Optional[Callable] = None,
2211 + expert_map: torch.Tensor | None = None,
2212 + custom_routing_function: Callable | None = None,
2213 scoring_func: str = "softmax",
2214 routed_scaling_factor: float = 1.0,
2215 - e_score_correction_bias: Optional[torch.Tensor] = None,
2215 + e_score_correction_bias: torch.Tensor | None = None,
2216 apply_router_weight_on_input: bool = False,
2217 activation: str = "silu",
2218 enable_eplb: bool = False,
2219 - expert_load_view: Optional[torch.Tensor] = None,
2220 - logical_to_physical_map: Optional[torch.Tensor] = None,
2221 - logical_replica_count: Optional[torch.Tensor] = None,
2219 + expert_load_view: torch.Tensor | None = None,
2220 + logical_to_physical_map: torch.Tensor | None = None,
2221 + logical_replica_count: torch.Tensor | None = None,
2222 ) -> torch.Tensor:
2223 assert not enable_eplb, "EPLB not supported for W4A8-int MoE yet."
2224 assert activation in ("silu", "swigluoai", "swiglu"), (
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_24.py
+6 -5
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional
4 +from collections.abc import Callable
5 +from typing import Any
6
7 import torch
8 from compressed_tensors import CompressionFormat, ModelCompressor
@@ -42,9 +43,9 @@ class CompressedTensors24(CompressedTensorsScheme):
43 def __init__(
44 self,
45 quantized: bool = False,
45 - weight_quant: Optional[QuantizationArgs] = None,
46 - input_quant: Optional[QuantizationArgs] = None,
47 - model_compression_config: Optional[dict[str, Any]] = None,
46 + weight_quant: QuantizationArgs | None = None,
47 + input_quant: QuantizationArgs | None = None,
48 + model_compression_config: dict[str, Any] | None = None,
49 ):
50 self.quantized = quantized
51 self.weight_quant = weight_quant
@@ -247,7 +248,7 @@ class CompressedTensors24(CompressedTensorsScheme):
248 self,
249 layer: torch.nn.Module,
250 x: torch.Tensor,
250 - bias: Optional[torch.Tensor] = None,
251 + bias: torch.Tensor | None = None,
252 ) -> torch.Tensor:
253 """
254 Returns the output tensor for the layer with 2:4
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_scheme.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from abc import ABC, abstractmethod
5 -from typing import Optional
5
6 import torch
7
@@ -33,7 +32,7 @@ class CompressedTensorsScheme(ABC):
32
33 @abstractmethod
34 def apply_weights(
36 - self, layer: torch.nn.Module, x: torch.Tensor, bias: Optional[torch.Tensor]
35 + self, layer: torch.nn.Module, x: torch.Tensor, bias: torch.Tensor | None
36 ):
37 """
38 Run the forward pass for the particular scheme. This is where
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a16_24.py
+3 -3
@@ -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 Callable, Optional
4 +from collections.abc import Callable
5
6 import torch
7 from torch.nn import Parameter
@@ -30,7 +30,7 @@ W4A16SPARSE24_SUPPORTED_BITS = list(W4A16SPARSE24_SUPPORTED_TYPES_MAP.keys())
30
31
32 class CompressedTensorsW4A16Sparse24(CompressedTensorsScheme):
33 - def __init__(self, strategy: str, num_bits: int, group_size: Optional[int] = None):
33 + def __init__(self, strategy: str, num_bits: int, group_size: int | None = None):
34 self.strategy = strategy
35 self.group_size = group_size
36 self.tile_size = 16
@@ -143,7 +143,7 @@ class CompressedTensorsW4A16Sparse24(CompressedTensorsScheme):
143 layer.workspace = workspace
144
145 def apply_weights(
146 - self, layer: torch.nn.Module, x: torch.Tensor, bias: Optional[torch.Tensor]
146 + self, layer: torch.nn.Module, x: torch.Tensor, bias: torch.Tensor | None
147 ) -> torch.Tensor:
148 qweight = layer.weight_packed
149 meta = layer.meta
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a16_nvfp4.py
+2 -2
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Callable, Optional
3 +from collections.abc import Callable
4
5 import torch
6 from torch.nn.parameter import Parameter
@@ -110,7 +110,7 @@ class CompressedTensorsW4A16Fp4(CompressedTensorsScheme):
110 self,
111 layer: torch.nn.Module,
112 x: torch.Tensor,
113 - bias: Optional[torch.Tensor] = None,
113 + bias: torch.Tensor | None = None,
114 ) -> torch.Tensor:
115 return apply_fp4_marlin_linear(
116 input=x,
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4.py
+2 -2
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Callable, Optional
3 +from collections.abc import Callable
4
5 import torch
6 from torch.nn.parameter import Parameter
@@ -156,7 +156,7 @@ class CompressedTensorsW4A4Fp4(CompressedTensorsScheme):
156 self,
157 layer: torch.nn.Module,
158 x: torch.Tensor,
159 - bias: Optional[torch.Tensor] = None,
159 + bias: torch.Tensor | None = None,
160 ) -> torch.Tensor:
161 if envs.VLLM_USE_NVFP4_CT_EMULATIONS:
162 out = run_nvfp4_emulations(
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a8_fp8.py
+5 -5
@@ -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 Callable, Optional
4 +from collections.abc import Callable
5
6 import torch
7 from compressed_tensors.quantization import ActivationOrdering
@@ -41,9 +41,9 @@ class CompressedTensorsW4A8Fp8(CompressedTensorsScheme):
41 self,
42 strategy: str,
43 num_bits: int,
44 - group_size: Optional[int] = None,
45 - symmetric: Optional[bool] = True,
46 - actorder: Optional[ActivationOrdering] = None,
44 + group_size: int | None = None,
45 + symmetric: bool | None = True,
46 + actorder: ActivationOrdering | None = None,
47 ):
48 self.pack_factor = 32 // num_bits
49 self.strategy = strategy
@@ -178,6 +178,6 @@ class CompressedTensorsW4A8Fp8(CompressedTensorsScheme):
178 self.kernel.process_weights_after_loading(layer)
179
180 def apply_weights(
181 - self, layer: torch.nn.Module, x: torch.Tensor, bias: Optional[torch.Tensor]
181 + self, layer: torch.nn.Module, x: torch.Tensor, bias: torch.Tensor | None
182 ) -> torch.Tensor:
183 return self.kernel.apply_weights(layer, x, bias)
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a8_int.py
+3 -3
@@ -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 Callable, Optional
4 +from collections.abc import Callable
5
6 import torch
7
@@ -36,7 +36,7 @@ class CompressedTensorsW4A8Int(CompressedTensorsScheme):
36 self,
37 strategy: str,
38 num_bits: int,
39 - group_size: Optional[int] = None,
39 + group_size: int | None = None,
40 is_static_input_scheme: bool = False,
41 input_symmetric: bool = True,
42 ):
@@ -148,6 +148,6 @@ class CompressedTensorsW4A8Int(CompressedTensorsScheme):
148 self.kernel.process_weights_after_loading(layer)
149
150 def apply_weights(
151 - self, layer: torch.nn.Module, x: torch.Tensor, bias: Optional[torch.Tensor]
151 + self, layer: torch.nn.Module, x: torch.Tensor, bias: torch.Tensor | None
152 ) -> torch.Tensor:
153 return self.kernel.apply_weights(layer, x, bias)
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_w8a16_fp8.py
+2 -2
@@ -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 Callable, Optional
4 +from collections.abc import Callable
5
6 import torch
7 from compressed_tensors.quantization import QuantizationStrategy
@@ -125,7 +125,7 @@ class CompressedTensorsW8A16Fp8(CompressedTensorsScheme):
125 self,
126 layer: torch.nn.Module,
127 x: torch.Tensor,
128 - bias: Optional[torch.Tensor] = None,
128 + bias: torch.Tensor | None = None,
129 ) -> torch.Tensor:
130 return apply_fp8_marlin_linear(
131 input=x,
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_w8a8_fp8.py
+2 -2
@@ -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 Callable, Optional
4 +from collections.abc import Callable
5
6 import torch
7 from compressed_tensors.quantization import QuantizationArgs, QuantizationStrategy
@@ -179,7 +179,7 @@ class CompressedTensorsW8A8Fp8(CompressedTensorsScheme):
179 self,
180 layer: torch.nn.Module,
181 x: torch.Tensor,
182 - bias: Optional[torch.Tensor] = None,
182 + bias: torch.Tensor | None = None,
183 ) -> torch.Tensor:
184 if self.weight_block_size is not None:
185 return self.w8a8_block_fp8_linear.apply(
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_w8a8_int8.py
+2 -2
@@ -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 Callable, Optional
4 +from collections.abc import Callable
5
6 import torch
7 from compressed_tensors.quantization import QuantizationStrategy
@@ -120,6 +120,6 @@ class CompressedTensorsW8A8Int8(CompressedTensorsScheme):
120 self.kernel.process_weights_after_loading(layer)
121
122 def apply_weights(
123 - self, layer: torch.nn.Module, x: torch.Tensor, bias: Optional[torch.Tensor]
123 + self, layer: torch.nn.Module, x: torch.Tensor, bias: torch.Tensor | None
124 ) -> torch.Tensor:
125 return self.kernel.apply_weights(layer, x, bias)
vllm/model_executor/layers/quantization/compressed_tensors/schemes/compressed_tensors_wNa16.py
+5 -5
@@ -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 Callable, Optional
4 +from collections.abc import Callable
5
6 import torch
7 from compressed_tensors.quantization import ActivationOrdering
@@ -42,9 +42,9 @@ class CompressedTensorsWNA16(CompressedTensorsScheme):
42 self,
43 strategy: str,
44 num_bits: int,
45 - group_size: Optional[int] = None,
46 - symmetric: Optional[bool] = True,
47 - actorder: Optional[ActivationOrdering] = None,
45 + group_size: int | None = None,
46 + symmetric: bool | None = True,
47 + actorder: ActivationOrdering | None = None,
48 ):
49 self.pack_factor = 32 // num_bits
50 self.strategy = strategy
@@ -214,6 +214,6 @@ class CompressedTensorsWNA16(CompressedTensorsScheme):
214 self.kernel.process_weights_after_loading(layer)
215
216 def apply_weights(
217 - self, layer: torch.nn.Module, x: torch.Tensor, bias: Optional[torch.Tensor]
217 + self, layer: torch.nn.Module, x: torch.Tensor, bias: torch.Tensor | None
218 ) -> torch.Tensor:
219 return self.kernel.apply_weights(layer, x, bias)
vllm/model_executor/layers/quantization/compressed_tensors/transform/linear.py
+7 -8
@@ -1,8 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from collections.abc import Generator
3 +from collections.abc import Callable, Generator
4 from itertools import accumulate
5 -from typing import Callable, Optional
5
6 import torch
7 from compressed_tensors.transform import (
@@ -38,7 +37,7 @@ class CompressedTensorsLinearTransformMethod(LinearMethodBase):
37 def from_schemes(
38 cls,
39 quant_method: LinearMethodBase,
41 - quant_scheme: Optional[CompressedTensorsScheme],
40 + quant_scheme: CompressedTensorsScheme | None,
41 input_tfms: dict[int, TransformTuple],
42 output_tfms: dict[int, TransformTuple],
43 ) -> "CompressedTensorsLinearTransformMethod":
@@ -66,8 +65,8 @@ class CompressedTensorsLinearTransformMethod(LinearMethodBase):
65 self.input_tfms = input_tfms
66 self.output_tfms = output_tfms
67
69 - self.input_transform: Optional[HadamardTransform] = None
70 - self.output_transform: Optional[HadamardTransform] = None
68 + self.input_transform: HadamardTransform | None = None
69 + self.output_transform: HadamardTransform | None = None
70
71 def create_weights(
72 self,
@@ -151,7 +150,7 @@ class CompressedTensorsLinearTransformMethod(LinearMethodBase):
150 self,
151 layer: torch.nn.Module,
152 x: torch.Tensor,
154 - bias: Optional[torch.Tensor] = None,
153 + bias: torch.Tensor | None = None,
154 ) -> torch.Tensor:
155 if self.input_transform is not None:
156 x = self.input_transform(x)
@@ -194,7 +193,7 @@ class CompressedTensorsLinearTransformMethod(LinearMethodBase):
193 def get_linear_transform_schemes(
194 layer: torch.nn.Module,
195 layer_name: str,
197 - transform_config: Optional[TransformConfig],
196 + transform_config: TransformConfig | None,
197 packed_modules_mapping: dict[str, list[str]],
198 ) -> tuple[
199 dict[int, TransformTuple], dict[int, TransformTuple]
@@ -226,7 +225,7 @@ def get_linear_transform_schemes(
225
226
227 def get_schemes_args(
229 - transform_config: Optional[TransformConfig],
228 + transform_config: TransformConfig | None,
229 ) -> Generator[tuple[str, TransformScheme, TransformArgs]]:
230 if transform_config is None:
231 return
vllm/model_executor/layers/quantization/compressed_tensors/transform/module.py
+1 -2
@@ -1,8 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import math
4 -from collections.abc import Hashable
5 -from typing import Callable
4 +from collections.abc import Callable, Hashable
5
6 import torch
7 from compressed_tensors.transform import (
vllm/model_executor/layers/quantization/compressed_tensors/transform/schemes/linear_qutlass_nvfp4.py
+2 -3
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5
@@ -17,7 +16,7 @@ __all__ = ["is_qutlass_fp4_scheme", "QutlassNvFP4LinearMethod"]
16
17
18 def is_qutlass_fp4_scheme(
20 - quant_scheme: Optional[CompressedTensorsScheme],
19 + quant_scheme: CompressedTensorsScheme | None,
20 input_tfms: dict[int, TransformTuple],
21 ) -> bool:
22 return (
@@ -60,6 +59,6 @@ class QutlassNvFP4LinearMethod(CompressedTensorsLinearTransformMethod):
59 self,
60 layer: torch.nn.Module,
61 x: torch.Tensor,
63 - bias: Optional[torch.Tensor] = None,
62 + bias: torch.Tensor | None = None,
63 ) -> torch.Tensor:
64 raise NotImplementedError()
vllm/model_executor/layers/quantization/compressed_tensors/triton_scaled_mm.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -145,7 +144,7 @@ def triton_scaled_mm(
144 scale_a: torch.Tensor,
145 scale_b: torch.Tensor,
146 out_dtype: type[torch.dtype],
148 - bias: Optional[torch.Tensor] = None,
147 + bias: torch.Tensor | None = None,
148 block_size_m: int = 32,
149 block_size_n: int = 32,
150 block_size_k: int = 32,
vllm/model_executor/layers/quantization/compressed_tensors/utils.py
+5 -6
@@ -3,7 +3,6 @@
3
4 from collections.abc import Iterable, Mapping
5 from types import MappingProxyType
6 -from typing import Optional
6
7 import regex as re
8 from compressed_tensors import CompressionFormat
@@ -21,7 +20,7 @@ def is_activation_quantization_format(format: str) -> bool:
20
21
22 def should_ignore_layer(
24 - layer_name: Optional[str],
23 + layer_name: str | None,
24 ignore: Iterable[str] = tuple(),
25 fused_mapping: Mapping[str, list[str]] = MappingProxyType({}),
26 ) -> bool:
@@ -84,7 +83,7 @@ def check_equal_or_regex_match(layer_name: str, targets: Iterable[str]) -> bool:
83
84
85 def find_matched_target(
87 - layer_name: Optional[str],
86 + layer_name: str | None,
87 module: Module,
88 targets: Iterable[str],
89 fused_mapping: Mapping[str, list[str]] = MappingProxyType({}),
@@ -134,7 +133,7 @@ def find_matched_target(
133
134 def _find_first_match(
135 value: str, targets: Iterable[str], check_contains: bool = False
137 -) -> Optional[str]:
136 +) -> str | None:
137 """
138 Returns first element of target that matches value either
139 exactly or as a regex after 're:'. If check_contains is set to True,
@@ -176,7 +175,7 @@ def _match_fused_layer(
175 layer_name: str,
176 target_layers: Iterable[str],
177 fused_mapping: Mapping[str, list[str]],
179 -) -> Optional[str]:
178 +) -> str | None:
179 """
180 Match a fused layer name to its corresponding individual layer in
181 target_layers. Returns first value in fused_mapping which matches targets
@@ -205,7 +204,7 @@ def _match_fused_layer(
204 ]
205
206 # for each unfused component, find a match in targets
208 - unfused_matches: list[Optional[str]] = []
207 + unfused_matches: list[str | None] = []
208 for unfused in unfused_paths:
209 for target in target_layers:
210 if _is_equal_or_regex_match(unfused, target):
vllm/model_executor/layers/quantization/deepspeedfp.py
+1 -1
@@ -140,7 +140,7 @@ class DeepSpeedFPLinearMethod(LinearMethodBase):
140 self,
141 layer: torch.nn.Module,
142 x: torch.Tensor,
143 - bias: Optional[torch.Tensor] = None,
143 + bias: torch.Tensor | None = None,
144 ) -> torch.Tensor:
145 weight = layer.weight
146 y = weight.ds_dequantize()
vllm/model_executor/layers/quantization/experts_int8.py
+12 -11
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional, Union
4 +from collections.abc import Callable
5 +from typing import Any, Optional
6
7 import torch
8
@@ -129,7 +130,7 @@ class ExpertsInt8MoEMethod(FusedMoEMethodBase):
130
131 def get_fused_moe_quant_config(
132 self, layer: torch.nn.Module
132 - ) -> Optional[FusedMoEQuantConfig]:
133 + ) -> FusedMoEQuantConfig | None:
134 return int8_w8a16_moe_quant_config(
135 w1_scale=layer.w13_scale, w2_scale=layer.w2_scale, w1_zp=None, w2_zp=None
136 )
@@ -142,21 +143,21 @@ class ExpertsInt8MoEMethod(FusedMoEMethodBase):
143 top_k: int,
144 renormalize: bool,
145 use_grouped_topk: bool = False,
145 - topk_group: Optional[int] = None,
146 - num_expert_group: Optional[int] = None,
146 + topk_group: int | None = None,
147 + num_expert_group: int | None = None,
148 global_num_experts: int = -1,
148 - expert_map: Optional[torch.Tensor] = None,
149 - custom_routing_function: Optional[Callable] = None,
149 + expert_map: torch.Tensor | None = None,
150 + custom_routing_function: Callable | None = None,
151 scoring_func: str = "softmax",
152 routed_scaling_factor: float = 1.0,
152 - e_score_correction_bias: Optional[torch.Tensor] = None,
153 + e_score_correction_bias: torch.Tensor | None = None,
154 apply_router_weight_on_input: bool = False,
155 activation: str = "silu",
156 enable_eplb: bool = False,
156 - expert_load_view: Optional[torch.Tensor] = None,
157 - logical_to_physical_map: Optional[torch.Tensor] = None,
158 - logical_replica_count: Optional[torch.Tensor] = None,
159 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
157 + expert_load_view: torch.Tensor | None = None,
158 + logical_to_physical_map: torch.Tensor | None = None,
159 + logical_replica_count: torch.Tensor | None = None,
160 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
161 assert self.fused_experts is None
162
163 if enable_eplb:
vllm/model_executor/layers/quantization/fbgemm_fp8.py
+1 -1
@@ -171,7 +171,7 @@ class FBGEMMFp8LinearMethod(LinearMethodBase):
171 self,
172 layer: torch.nn.Module,
173 x: torch.Tensor,
174 - bias: Optional[torch.Tensor] = None,
174 + bias: torch.Tensor | None = None,
175 ) -> torch.Tensor:
176 if self.quant_config.use_marlin:
177 return apply_fp8_marlin_linear(
vllm/model_executor/layers/quantization/fp8.py
+19 -18
@@ -1,8 +1,9 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 +from collections.abc import Callable
5 from enum import Enum
5 -from typing import TYPE_CHECKING, Any, Callable, Optional, Union
6 +from typing import TYPE_CHECKING, Any, Optional
7
8 import torch
9 from torch.nn import Module
@@ -173,8 +174,8 @@ class Fp8Config(QuantizationConfig):
174 self,
175 is_checkpoint_fp8_serialized: bool = False,
176 activation_scheme: str = "dynamic",
176 - ignored_layers: Optional[list[str]] = None,
177 - weight_block_size: Optional[list[int]] = None,
177 + ignored_layers: list[str] | None = None,
178 + weight_block_size: list[int] | None = None,
179 ) -> None:
180 super().__init__()
181
@@ -298,7 +299,7 @@ class Fp8Config(QuantizationConfig):
299 return Fp8KVCacheMethod(self)
300 return None
301
301 - def get_cache_scale(self, name: str) -> Optional[str]:
302 + def get_cache_scale(self, name: str) -> str | None:
303 """
304 Check whether the param name matches the format for k/v cache scales
305 in compressed-tensors. If this is the case, return its equivalent
@@ -530,7 +531,7 @@ class Fp8LinearMethod(LinearMethodBase):
531 self,
532 layer: torch.nn.Module,
533 x: torch.Tensor,
533 - bias: Optional[torch.Tensor] = None,
534 + bias: torch.Tensor | None = None,
535 ) -> torch.Tensor:
536 if self.use_marlin:
537 return apply_fp8_marlin_linear(
@@ -584,12 +585,12 @@ class Fp8MoEMethod(FusedMoEMethodBase):
585 self.weight_block_size = self.quant_config.weight_block_size
586 self.block_quant: bool = self.weight_block_size is not None
587
587 - self.fused_experts: Optional[mk.FusedMoEModularKernel] = None # type: ignore
588 + self.fused_experts: mk.FusedMoEModularKernel | None = None # type: ignore
589
590 self.fp8_backend = get_fp8_moe_backend(self.block_quant)
591
592 self.use_marlin = self.fp8_backend == Fp8MoeBackend.MARLIN
592 - self.flashinfer_moe_backend: Optional[FlashinferMoeBackend] = None
593 + self.flashinfer_moe_backend: FlashinferMoeBackend | None = None
594 if self.fp8_backend == Fp8MoeBackend.FLASHINFER_TRTLLM:
595 self.flashinfer_moe_backend = FlashinferMoeBackend.TENSORRT_LLM
596 elif self.fp8_backend == Fp8MoeBackend.FLASHINFER_CUTLASS:
@@ -970,7 +971,7 @@ class Fp8MoEMethod(FusedMoEMethodBase):
971 layer.w2_weight_scale_inv
972 )
973
973 - def maybe_make_prepare_finalize(self) -> Optional[mk.FusedMoEPrepareAndFinalize]:
974 + def maybe_make_prepare_finalize(self) -> mk.FusedMoEPrepareAndFinalize | None:
975 if (
976 self.rocm_aiter_moe_enabled
977 or self.use_marlin
@@ -1043,7 +1044,7 @@ class Fp8MoEMethod(FusedMoEMethodBase):
1044
1045 def get_fused_moe_quant_config(
1046 self, layer: torch.nn.Module
1046 - ) -> Optional[FusedMoEQuantConfig]:
1047 + ) -> FusedMoEQuantConfig | None:
1048 if self.use_marlin:
1049 return None
1050
@@ -1069,21 +1070,21 @@ class Fp8MoEMethod(FusedMoEMethodBase):
1070 top_k: int,
1071 renormalize: bool,
1072 use_grouped_topk: bool = False,
1072 - topk_group: Optional[int] = None,
1073 - num_expert_group: Optional[int] = None,
1073 + topk_group: int | None = None,
1074 + num_expert_group: int | None = None,
1075 global_num_experts: int = -1,
1075 - expert_map: Optional[torch.Tensor] = None,
1076 - custom_routing_function: Optional[Callable] = None,
1076 + expert_map: torch.Tensor | None = None,
1077 + custom_routing_function: Callable | None = None,
1078 scoring_func: str = "softmax",
1079 routed_scaling_factor: float = 1.0,
1079 - e_score_correction_bias: Optional[torch.Tensor] = None,
1080 + e_score_correction_bias: torch.Tensor | None = None,
1081 apply_router_weight_on_input: bool = False,
1082 activation: str = "silu",
1083 enable_eplb: bool = False,
1083 - expert_load_view: Optional[torch.Tensor] = None,
1084 - logical_to_physical_map: Optional[torch.Tensor] = None,
1085 - logical_replica_count: Optional[torch.Tensor] = None,
1086 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
1084 + expert_load_view: torch.Tensor | None = None,
1085 + logical_to_physical_map: torch.Tensor | None = None,
1086 + logical_replica_count: torch.Tensor | None = None,
1087 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
1088 if enable_eplb:
1089 assert expert_load_view is not None
1090 assert logical_to_physical_map is not None
vllm/model_executor/layers/quantization/fp_quant.py
+5 -5
@@ -3,7 +3,7 @@
3
4 # Supports FP-Quant compression, see https://arxiv.org/abs/2509.23202
5
6 -from typing import Any, Optional
6 +from typing import Any
7
8 import torch
9 from torch.nn.parameter import Parameter
@@ -36,7 +36,7 @@ class FPQuantConfig(QuantizationConfig):
36 forward_dtype: str = "mxfp4",
37 forward_method: str = "abs_max",
38 pseudoquantization: bool = False,
39 - modules_to_not_convert: Optional[list[str]] = None,
39 + modules_to_not_convert: list[str] | None = None,
40 ) -> None:
41 super().__init__()
42 self.hadamard_group_size = hadamard_group_size
@@ -90,7 +90,7 @@ class FPQuantConfig(QuantizationConfig):
90
91 def get_quant_method(
92 self, layer: torch.nn.Module, prefix: str
93 - ) -> Optional[LinearMethodBase]:
93 + ) -> LinearMethodBase | None:
94 if self.modules_to_not_convert is not None and any(
95 prefix.endswith(module) for module in self.modules_to_not_convert
96 ):
@@ -233,7 +233,7 @@ class FPQuantLinearMethod(LinearMethodBase):
233 self,
234 layer: torch.nn.Module,
235 x: torch.Tensor,
236 - bias: Optional[torch.Tensor] = None,
236 + bias: torch.Tensor | None = None,
237 ) -> torch.Tensor:
238 return quantized_forward(
239 x,
@@ -381,7 +381,7 @@ def quantized_forward(
381 weight_scales: torch.Tensor,
382 weight_global_scale: torch.Tensor,
383 act_global_scale: torch.Tensor,
384 - bias: Optional[torch.Tensor],
384 + bias: torch.Tensor | None,
385 forward_hadamard_matrix: torch.Tensor,
386 forward_method: str,
387 forward_dtype: str,
vllm/model_executor/layers/quantization/gguf.py
+16 -15
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional, Union
4 +from collections.abc import Callable
5 +from typing import Any, Optional
6
7 import gguf
8 import torch
@@ -35,7 +36,7 @@ logger = init_logger(__name__)
36 class GGUFConfig(QuantizationConfig):
37 """Config class for GGUF."""
38
38 - def __init__(self, unquantized_modules: Optional[list[str]] = None) -> None:
39 + def __init__(self, unquantized_modules: list[str] | None = None) -> None:
40 super().__init__()
41 self.unquantized_modules = unquantized_modules or []
42
@@ -307,7 +308,7 @@ def _apply_gguf_embedding(
308 qweight: torch.Tensor,
309 qweight_type: int,
310 hidden_size: int,
310 - dtype: Optional[torch.dtype] = None,
311 + dtype: torch.dtype | None = None,
312 ) -> torch.Tensor:
313 if qweight_type in UNQUANTIZED_TYPES:
314 return torch.embedding(qweight, x)
@@ -330,7 +331,7 @@ def _apply_gguf_embedding_fake(
331 qweight: torch.Tensor,
332 qweight_type: int,
333 hidden_size: int,
333 - dtype: Optional[torch.dtype] = None,
334 + dtype: torch.dtype | None = None,
335 ) -> torch.Tensor:
336 return torch.empty(x.shape[0], hidden_size, dtype=dtype, device=x.device)
337
@@ -452,7 +453,7 @@ class GGUFLinearMethod(LinearMethodBase):
453 self,
454 layer: torch.nn.Module,
455 x: torch.Tensor,
455 - bias: Optional[torch.Tensor] = None,
456 + bias: torch.Tensor | None = None,
457 ) -> torch.Tensor:
458 shard_id = layer.qweight.shard_id
459
@@ -558,7 +559,7 @@ class GGUFMoEMethod(FusedMoEMethodBase):
559
560 def get_fused_moe_quant_config(
561 self, layer: torch.nn.Module
561 - ) -> Optional[FusedMoEQuantConfig]:
562 + ) -> FusedMoEQuantConfig | None:
563 return None
564
565 def apply(
@@ -569,21 +570,21 @@ class GGUFMoEMethod(FusedMoEMethodBase):
570 top_k: int,
571 renormalize: bool,
572 use_grouped_topk: bool = False,
572 - topk_group: Optional[int] = None,
573 - num_expert_group: Optional[int] = None,
573 + topk_group: int | None = None,
574 + num_expert_group: int | None = None,
575 global_num_experts: int = -1,
575 - expert_map: Optional[torch.Tensor] = None,
576 - custom_routing_function: Optional[Callable] = None,
576 + expert_map: torch.Tensor | None = None,
577 + custom_routing_function: Callable | None = None,
578 scoring_func: str = "softmax",
579 routed_scaling_factor: float = 1.0,
579 - e_score_correction_bias: Optional[torch.Tensor] = None,
580 + e_score_correction_bias: torch.Tensor | None = None,
581 apply_router_weight_on_input: bool = False,
582 activation: str = "silu",
583 enable_eplb: bool = False,
583 - expert_load_view: Optional[torch.Tensor] = None,
584 - logical_to_physical_map: Optional[torch.Tensor] = None,
585 - logical_replica_count: Optional[torch.Tensor] = None,
586 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
584 + expert_load_view: torch.Tensor | None = None,
585 + logical_to_physical_map: torch.Tensor | None = None,
586 + logical_replica_count: torch.Tensor | None = None,
587 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
588 assert self.fused_experts is None
589
590 if enable_eplb:
vllm/model_executor/layers/quantization/gptq.py
+6 -6
@@ -4,7 +4,7 @@
4 import enum
5 from enum import Enum
6 from fractions import Fraction
7 -from typing import TYPE_CHECKING, Any, Optional, Union
7 +from typing import TYPE_CHECKING, Any, Union
8
9 import torch
10 from safetensors.torch import _TYPES as _SAFETENSORS_TO_TORCH_DTYPE
@@ -48,9 +48,9 @@ class GPTQConfig(QuantizationConfig):
48 group_size: int,
49 desc_act: bool,
50 lm_head_quantized: bool,
51 - dynamic: dict[str, dict[str, Union[int, bool]]],
51 + dynamic: dict[str, dict[str, int | bool]],
52 autoround_version: str = "",
53 - modules_in_block_to_quantize: Optional[list[str]] = None,
53 + modules_in_block_to_quantize: list[str] | None = None,
54 ) -> None:
55 # GPTQModel use `dynamic` config property to allow per module
56 # quantization config so each module can be individually optimized.
@@ -148,7 +148,7 @@ class GPTQConfig(QuantizationConfig):
148
149 def get_quant_method(
150 self, layer: torch.nn.Module, prefix: str
151 - ) -> Optional[Union["GPTQLinearMethod", "QuantizeMethodBase"]]:
151 + ) -> Union["GPTQLinearMethod", "QuantizeMethodBase"] | None:
152 if isinstance(layer, FusedMoE):
153 # GPTQ MoE support: fall back to MoeWNA16 for broad compatibility
154 from .moe_wna16 import MoeWNA16Config
@@ -170,7 +170,7 @@ class GPTQConfig(QuantizationConfig):
170 self.modules_in_block_to_quantize
171 )
172
173 - def maybe_update_config(self, model_name: str, revision: Optional[str] = None):
173 + def maybe_update_config(self, model_name: str, revision: str | None = None):
174 if self.modules_in_block_to_quantize:
175 if is_list_of(self.modules_in_block_to_quantize, list):
176 # original modules_in_block_to_quantize: list[list[str]]
@@ -345,7 +345,7 @@ class GPTQLinearMethod(LinearMethodBase):
345 self,
346 layer: torch.nn.Module,
347 x: torch.Tensor,
348 - bias: Optional[torch.Tensor] = None,
348 + bias: torch.Tensor | None = None,
349 ) -> torch.Tensor:
350 out_shape = x.shape[:-1] + (layer.qweight.shape[-1],)
351 reshaped_x = x.reshape(-1, x.shape[-1])
vllm/model_executor/layers/quantization/gptq_bitblas.py
+3 -3
@@ -71,7 +71,7 @@ class GPTQBitBLASConfig(QuantizationConfig):
71 group_size: int,
72 desc_act: bool,
73 is_sym: bool,
74 - quant_method: Optional[str],
74 + quant_method: str | None,
75 lm_head_quantized: bool,
76 ) -> None:
77 try:
@@ -180,7 +180,7 @@ class GPTQBitBLASConfig(QuantizationConfig):
180 @classmethod
181 def override_quantization_method(
182 cls, hf_quant_cfg, user_quant
183 - ) -> Optional[QuantizationMethods]:
183 + ) -> QuantizationMethods | None:
184 can_convert = cls.is_gptq_bitblas_compatible(hf_quant_cfg)
185
186 is_valid_user_quant = (
@@ -474,7 +474,7 @@ class GPTQBitBLASLinearMethod(LinearMethodBase):
474 self,
475 layer: torch.nn.Module,
476 x: torch.Tensor,
477 - bias: Optional[torch.Tensor] = None,
477 + bias: torch.Tensor | None = None,
478 ) -> torch.Tensor:
479 out = self.kernel.apply_gptq_bitblas_linear(layer, x)
480 if bias is not None:
vllm/model_executor/layers/quantization/gptq_marlin.py
+17 -16
@@ -1,8 +1,9 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 +from collections.abc import Callable
5 from copy import deepcopy
5 -from typing import Any, Callable, Optional, Union
6 +from typing import Any, Optional
7
8 import torch
9 from safetensors.torch import _TYPES as _SAFETENSORS_TO_TORCH_DTYPE
@@ -103,9 +104,9 @@ class GPTQMarlinConfig(QuantizationConfig):
104 desc_act: bool,
105 is_sym: bool,
106 lm_head_quantized: bool,
106 - dynamic: dict[str, dict[str, Union[int, bool]]],
107 + dynamic: dict[str, dict[str, int | bool]],
108 full_config: dict[str, Any],
108 - modules_in_block_to_quantize: Optional[list[str]] = None,
109 + modules_in_block_to_quantize: list[str] | None = None,
110 ) -> None:
111 super().__init__()
112 if desc_act and group_size == -1:
@@ -211,7 +212,7 @@ class GPTQMarlinConfig(QuantizationConfig):
212 @classmethod
213 def override_quantization_method(
214 cls, hf_quant_cfg, user_quant
214 - ) -> Optional[QuantizationMethods]:
215 + ) -> QuantizationMethods | None:
216 can_convert = cls.is_gptq_marlin_compatible(hf_quant_cfg)
217
218 is_valid_user_quant = (
@@ -283,7 +284,7 @@ class GPTQMarlinConfig(QuantizationConfig):
284 self.modules_in_block_to_quantize
285 )
286
286 - def maybe_update_config(self, model_name: str, revision: Optional[str] = None):
287 + def maybe_update_config(self, model_name: str, revision: str | None = None):
288 if self.modules_in_block_to_quantize:
289 if is_list_of(self.modules_in_block_to_quantize, list):
290 # original modules_in_block_to_quantize: list[list[str]]
@@ -459,7 +460,7 @@ class GPTQMarlinLinearMethod(LinearMethodBase):
460 self,
461 layer: torch.nn.Module,
462 x: torch.Tensor,
462 - bias: Optional[torch.Tensor] = None,
463 + bias: torch.Tensor | None = None,
464 ) -> torch.Tensor:
465 return self.kernel.apply_weights(layer, x, bias)
466
@@ -714,7 +715,7 @@ class GPTQMarlinMoEMethod(FusedMoEMethodBase):
715
716 def get_fused_moe_quant_config(
717 self, layer: torch.nn.Module
717 - ) -> Optional[FusedMoEQuantConfig]:
718 + ) -> FusedMoEQuantConfig | None:
719 return None
720
721 def apply(
@@ -725,21 +726,21 @@ class GPTQMarlinMoEMethod(FusedMoEMethodBase):
726 top_k: int,
727 renormalize: bool,
728 use_grouped_topk: bool = False,
728 - topk_group: Optional[int] = None,
729 - num_expert_group: Optional[int] = None,
729 + topk_group: int | None = None,
730 + num_expert_group: int | None = None,
731 global_num_experts: int = -1,
731 - expert_map: Optional[torch.Tensor] = None,
732 - custom_routing_function: Optional[Callable] = None,
732 + expert_map: torch.Tensor | None = None,
733 + custom_routing_function: Callable | None = None,
734 scoring_func: str = "softmax",
735 routed_scaling_factor: float = 1.0,
735 - e_score_correction_bias: Optional[torch.Tensor] = None,
736 + e_score_correction_bias: torch.Tensor | None = None,
737 apply_router_weight_on_input: bool = False,
738 activation: str = "silu",
739 enable_eplb: bool = False,
739 - expert_load_view: Optional[torch.Tensor] = None,
740 - logical_to_physical_map: Optional[torch.Tensor] = None,
741 - logical_replica_count: Optional[torch.Tensor] = None,
742 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
740 + expert_load_view: torch.Tensor | None = None,
741 + logical_to_physical_map: torch.Tensor | None = None,
742 + logical_replica_count: torch.Tensor | None = None,
743 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
744 assert self.fused_experts is None
745
746 if enable_eplb:
vllm/model_executor/layers/quantization/gptq_marlin_24.py
+2 -2
@@ -114,7 +114,7 @@ class GPTQMarlin24Config(QuantizationConfig):
114 @classmethod
115 def override_quantization_method(
116 cls, hf_quant_cfg, user_quant
117 - ) -> Optional[QuantizationMethods]:
117 + ) -> QuantizationMethods | None:
118 is_marlin_24_format = hf_quant_cfg.get("checkpoint_format") == "marlin_24"
119
120 is_valid_user_quant = (
@@ -287,7 +287,7 @@ class GPTQMarlin24LinearMethod(LinearMethodBase):
287 self,
288 layer: torch.nn.Module,
289 x: torch.Tensor,
290 - bias: Optional[torch.Tensor] = None,
290 + bias: torch.Tensor | None = None,
291 ) -> torch.Tensor:
292 qweight = layer.B_24
293 meta = layer.B_meta
vllm/model_executor/layers/quantization/hqq_marlin.py
+2 -2
@@ -45,7 +45,7 @@ class HQQMarlinConfig(QuantizationConfig):
45 self,
46 weight_bits: int,
47 group_size: int,
48 - skip_modules: Optional[list[str]] = None,
48 + skip_modules: list[str] | None = None,
49 ) -> None:
50 super().__init__()
51 assert group_size == 64, "The only supported HQQ group size is currently 64."
@@ -327,7 +327,7 @@ class HQQMarlinMethod(LinearMethodBase):
327 self,
328 layer: torch.nn.Module,
329 x: torch.Tensor,
330 - bias: Optional[torch.Tensor] = None,
330 + bias: torch.Tensor | None = None,
331 ) -> torch.Tensor:
332 workspace = MarlinWorkspace(
333 self.output_size_per_partition,
vllm/model_executor/layers/quantization/input_quant_fp8.py
+6 -7
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5 import torch.nn.functional as F
@@ -30,9 +29,9 @@ class QuantFP8(CustomOp):
29 self,
30 static: bool,
31 group_shape: GroupShape,
33 - num_token_padding: Optional[int] = None,
32 + num_token_padding: int | None = None,
33 column_major_scales: bool = False,
35 - use_ue8m0: Optional[bool] = None, # for Torch compile
34 + use_ue8m0: bool | None = None, # for Torch compile
35 ):
36 """
37 :param static: static or dynamic quantization
@@ -64,8 +63,8 @@ class QuantFP8(CustomOp):
63 def forward_cuda(
64 self,
65 x: torch.Tensor,
67 - scale: Optional[torch.Tensor] = None,
68 - scale_ub: Optional[torch.Tensor] = None,
66 + scale: torch.Tensor | None = None,
67 + scale_ub: torch.Tensor | None = None,
68 ) -> tuple[torch.Tensor, torch.Tensor]:
69 if self.is_group_quant:
70 assert scale is None, "Group quantization is always dynamic"
@@ -96,8 +95,8 @@ class QuantFP8(CustomOp):
95 def forward_native(
96 self,
97 x: torch.Tensor,
99 - scale: Optional[torch.Tensor] = None,
100 - scale_ub: Optional[torch.Tensor] = None,
98 + scale: torch.Tensor | None = None,
99 + scale_ub: torch.Tensor | None = None,
100 ):
101 if self.is_group_quant:
102 assert scale is None, "Group quantization is always dynamic"
vllm/model_executor/layers/quantization/ipex_quant.py
+18 -17
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional
4 +from collections.abc import Callable
5 +from typing import Any, Optional
6
7 import torch
8 from packaging import version
@@ -50,9 +51,9 @@ class IPEXConfig(QuantizationConfig):
51 method: str,
52 weight_bits: int,
53 group_size: int,
53 - modules_to_not_convert: Optional[list[str]] = None,
54 - desc_act: Optional[bool] = None,
55 - lm_head_quantized: Optional[bool] = None,
54 + modules_to_not_convert: list[str] | None = None,
55 + desc_act: bool | None = None,
56 + lm_head_quantized: bool | None = None,
57 ) -> None:
58 super().__init__()
59 self.method = method
@@ -122,7 +123,7 @@ class IPEXConfig(QuantizationConfig):
123 @classmethod
124 def override_quantization_method(
125 cls, hf_quant_cfg, user_quant
125 - ) -> Optional[QuantizationMethods]:
126 + ) -> QuantizationMethods | None:
127 if not current_platform.is_cpu() and not current_platform.is_xpu():
128 return None
129
@@ -206,7 +207,7 @@ class IPEXGPTQLinearMethod(GPTQLinearMethod):
207 self,
208 layer: torch.nn.Module,
209 x: torch.Tensor,
209 - bias: Optional[torch.Tensor] = None,
210 + bias: torch.Tensor | None = None,
211 ) -> torch.Tensor:
212 reshaped_x = x.reshape(-1, x.shape[-1])
213 out = layer.ipex_qlinear(reshaped_x)
@@ -275,7 +276,7 @@ class IPEXAWQLinearMethod(AWQLinearMethod):
276 self,
277 layer: torch.nn.Module,
278 x: torch.Tensor,
278 - bias: Optional[torch.Tensor] = None,
279 + bias: torch.Tensor | None = None,
280 ) -> torch.Tensor:
281 reshaped_x = x.reshape(-1, x.shape[-1])
282 out = layer.ipex_qlinear(reshaped_x)
@@ -299,7 +300,7 @@ class XPUFp8LinearMethod(Fp8LinearMethod):
300 self,
301 layer: torch.nn.Module,
302 x: torch.Tensor,
302 - bias: Optional[torch.Tensor] = None,
303 + bias: torch.Tensor | None = None,
304 ) -> torch.Tensor:
305 weight = layer.weight.data
306 weight_scale = layer.weight_scale.data
@@ -410,7 +411,7 @@ class XPUFp8MoEMethod(FusedMoEMethodBase):
411
412 def get_fused_moe_quant_config(
413 self, layer: torch.nn.Module
413 - ) -> Optional[FusedMoEQuantConfig]:
414 + ) -> FusedMoEQuantConfig | None:
415 return None
416
417 def apply(
@@ -421,20 +422,20 @@ class XPUFp8MoEMethod(FusedMoEMethodBase):
422 top_k: int,
423 renormalize: bool,
424 use_grouped_topk: bool = False,
424 - topk_group: Optional[int] = None,
425 - num_expert_group: Optional[int] = None,
425 + topk_group: int | None = None,
426 + num_expert_group: int | None = None,
427 global_num_experts: int = -1,
427 - expert_map: Optional[torch.Tensor] = None,
428 - custom_routing_function: Optional[Callable] = None,
428 + expert_map: torch.Tensor | None = None,
429 + custom_routing_function: Callable | None = None,
430 scoring_func: str = "softmax",
431 routed_scaling_factor: float = 1.0,
431 - e_score_correction_bias: Optional[torch.Tensor] = None,
432 + e_score_correction_bias: torch.Tensor | None = None,
433 apply_router_weight_on_input: bool = False,
434 activation: str = "silu",
435 enable_eplb: bool = False,
435 - expert_load_view: Optional[torch.Tensor] = None,
436 - logical_to_physical_map: Optional[torch.Tensor] = None,
437 - logical_replica_count: Optional[torch.Tensor] = None,
436 + expert_load_view: torch.Tensor | None = None,
437 + logical_to_physical_map: torch.Tensor | None = None,
438 + logical_replica_count: torch.Tensor | None = None,
439 ) -> torch.Tensor:
440 return layer.ipex_fusion(
441 x,
vllm/model_executor/layers/quantization/kernels/mixed_precision/MPLinearKernel.py
+9 -9
@@ -2,8 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from abc import ABC, abstractmethod
5 +from collections.abc import Callable
6 from dataclasses import dataclass
6 -from typing import Callable, Optional
7
8 import torch
9
@@ -20,7 +20,7 @@ class MPLinearLayerConfig:
20 group_size: int
21 zero_points: bool
22 has_g_idx: bool
23 - out_type: Optional[torch.dtype] = None
23 + out_type: torch.dtype | None = None
24
25
26 class MPLinearKernel(ABC):
@@ -31,7 +31,7 @@ class MPLinearKernel(ABC):
31
32 @classmethod
33 @abstractmethod
34 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
34 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
35 raise NotImplementedError
36
37 def __init__(
@@ -39,8 +39,8 @@ class MPLinearKernel(ABC):
39 c: MPLinearLayerConfig,
40 w_q_param_name: str,
41 w_s_param_name: str,
42 - w_zp_param_name: Optional[str] = None,
43 - w_gidx_param_name: Optional[str] = None,
42 + w_zp_param_name: str | None = None,
43 + w_gidx_param_name: str | None = None,
44 ) -> None:
45 assert self.can_implement(c)
46 self.config = c
@@ -62,12 +62,12 @@ class MPLinearKernel(ABC):
62 self,
63 layer: torch.nn.Module,
64 x: torch.Tensor,
65 - bias: Optional[torch.Tensor] = None,
65 + bias: torch.Tensor | None = None,
66 ) -> torch.Tensor:
67 raise NotImplementedError
68
69 def _transform_param(
70 - self, layer: torch.nn.Module, name: Optional[str], fn: Callable
70 + self, layer: torch.nn.Module, name: str | None, fn: Callable
71 ) -> None:
72 if name is not None and getattr(layer, name, None) is not None:
73 old_param = getattr(layer, name)
@@ -83,8 +83,8 @@ class MPLinearKernel(ABC):
83 ) -> tuple[
84 torch.Tensor, # w_q
85 torch.Tensor, # w_s
86 - Optional[torch.Tensor], # w_zp,
87 - Optional[torch.Tensor], # w_gidx
86 + torch.Tensor | None, # w_zp,
87 + torch.Tensor | None, # w_gidx
88 ]:
89 return (
90 getattr(layer, self.w_q_name),
vllm/model_executor/layers/quantization/kernels/mixed_precision/__init__.py
+1 -3
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
5 -
4 import vllm.envs as envs
5 from vllm.model_executor.layers.quantization.kernels.mixed_precision.allspark import ( # noqa: E501
6 AllSparkLinearKernel,
@@ -48,7 +46,7 @@ _POSSIBLE_KERNELS: list[type[MPLinearKernel]] = [
46
47
48 def choose_mp_linear_kernel(
51 - config: MPLinearLayerConfig, compute_capability: Optional[int] = None
49 + config: MPLinearLayerConfig, compute_capability: int | None = None
50 ) -> type[MPLinearKernel]:
51 """
52 Choose an MPLinearKernel that can implement the given config for the given
vllm/model_executor/layers/quantization/kernels/mixed_precision/allspark.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -22,7 +21,7 @@ class AllSparkLinearKernel(MPLinearKernel):
21 return 80
22
23 @classmethod
25 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
24 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
25 if c.has_g_idx:
26 return False, "Act reordering currently not supported by AllSpark"
27
@@ -87,7 +86,7 @@ class AllSparkLinearKernel(MPLinearKernel):
86 self,
87 layer: torch.nn.Module,
88 x: torch.Tensor,
90 - bias: Optional[torch.Tensor] = None,
89 + bias: torch.Tensor | None = None,
90 ) -> torch.Tensor:
91 c = self.config
92 gemm_args = self.gemm_args
vllm/model_executor/layers/quantization/kernels/mixed_precision/bitblas.py
+6 -7
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6 from packaging import version
@@ -44,9 +43,9 @@ class BitBLASLinearKernel(MPLinearKernel):
43 c: MPLinearLayerConfig,
44 w_q_param_name: str,
45 w_s_param_name: str,
47 - w_zp_param_name: Optional[str] = None,
48 - w_gidx_param_name: Optional[str] = None,
49 - bitblas_quant_config: Optional[QuantizationConfig] = None,
46 + w_zp_param_name: str | None = None,
47 + w_gidx_param_name: str | None = None,
48 + bitblas_quant_config: QuantizationConfig | None = None,
49 ):
50 self.quant_config = bitblas_quant_config
51 super().__init__(
@@ -57,7 +56,7 @@ class BitBLASLinearKernel(MPLinearKernel):
56 self,
57 b_q_weight: torch.Tensor,
58 scales: torch.Tensor,
60 - qzeros: Optional[torch.Tensor] = None,
59 + qzeros: torch.Tensor | None = None,
60 ):
61 from bitblas.quantization.utils import general_compress
62
@@ -82,7 +81,7 @@ class BitBLASLinearKernel(MPLinearKernel):
81 # qzeros should be de-quantized to int zeros.
82 weight_bits = quant_config.weight_bits # type: ignore[union-attr]
83 intzeros = unpack_gptq_qzeros(qzeros, weight_bits).T.contiguous()
85 - zeros: Optional[torch.Tensor] = None
84 + zeros: torch.Tensor | None = None
85 zeros_mode = self.bitblas_matmul.config.zeros_mode # type: ignore[attr-defined]
86 if zeros_mode == "original":
87 zeros = intzeros.to(torch.float16).contiguous()
@@ -113,7 +112,7 @@ class BitBLASLinearKernel(MPLinearKernel):
112 return 70
113
114 @classmethod
116 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
115 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
116 is_bitblas_installed = True
117
118 try:
vllm/model_executor/layers/quantization/kernels/mixed_precision/conch.py
+3 -3
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from importlib.util import find_spec
5 -from typing import Final, Optional
5 +from typing import Final
6
7 import torch
8
@@ -26,7 +26,7 @@ class ConchLinearKernel(MPLinearKernel):
26 return 80
27
28 @classmethod
29 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
29 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
30 if c.weight_type not in _CONCH_SUPPORTED_WEIGHT_TYPES:
31 error_msg = (
32 f"Weight type ({c.weight_type}) not supported by "
@@ -76,7 +76,7 @@ class ConchLinearKernel(MPLinearKernel):
76 self,
77 layer: torch.nn.Module,
78 x: torch.Tensor,
79 - bias: Optional[torch.Tensor] = None,
79 + bias: torch.Tensor | None = None,
80 ) -> torch.Tensor:
81 from conch.ops.quantization.gemm import mixed_precision_gemm
82
vllm/model_executor/layers/quantization/kernels/mixed_precision/cutlass.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -26,7 +25,7 @@ class CutlassW4A8LinearKernel(MPLinearKernel):
25 return 90
26
27 @classmethod
29 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
28 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
29 if not current_platform.is_cuda():
30 return False, "CUTLASS only supported on CUDA"
31
@@ -95,7 +94,7 @@ class CutlassW4A8LinearKernel(MPLinearKernel):
94 self,
95 layer: torch.nn.Module,
96 x: torch.Tensor,
98 - bias: Optional[torch.Tensor] = None,
97 + bias: torch.Tensor | None = None,
98 ) -> torch.Tensor:
99 c = self.config
100 w_q, w_s, _, _ = self._get_weight_params(layer)
vllm/model_executor/layers/quantization/kernels/mixed_precision/dynamic_4bit.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -20,7 +19,7 @@ class Dynamic4bitLinearKernel(MPLinearKernel):
19 return 1
20
21 @classmethod
23 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
22 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
23 if not current_platform.is_cpu():
24 return False, "Only CPU is supported"
25 if c.weight_type not in cls.SUPPORTED_QUANT_TYPES:
@@ -95,7 +94,7 @@ class Dynamic4bitLinearKernel(MPLinearKernel):
94 self,
95 layer: torch.nn.Module,
96 x: torch.Tensor,
98 - bias: Optional[torch.Tensor] = None,
97 + bias: torch.Tensor | None = None,
98 ) -> torch.Tensor:
99 c = self.config
100 x_2d = x.reshape(-1, x.shape[-1])
vllm/model_executor/layers/quantization/kernels/mixed_precision/exllama.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -25,7 +24,7 @@ class ExllamaLinearKernel(MPLinearKernel):
24 return 60
25
26 @classmethod
28 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
27 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
28 if c.has_g_idx and c.partition_weight_shape[0] != c.full_weight_shape[0]:
29 return (
30 False,
@@ -137,7 +136,7 @@ class ExllamaLinearKernel(MPLinearKernel):
136 self,
137 layer: torch.nn.Module,
138 x: torch.Tensor,
140 - bias: Optional[torch.Tensor] = None,
139 + bias: torch.Tensor | None = None,
140 ) -> torch.Tensor:
141 c = self.config
142
vllm/model_executor/layers/quantization/kernels/mixed_precision/machete.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from functools import partial
5 -from typing import Optional
5
6 import torch
7
@@ -28,7 +27,7 @@ class MacheteLinearKernel(MPLinearKernel):
27 return 90
28
29 @classmethod
31 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
30 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
31 # Machete uses CUTLASS, so it can only be compatible with Nvidia
32 if not current_platform.is_cuda():
33 return False, "Machete only supported on CUDA"
@@ -129,7 +128,7 @@ class MacheteLinearKernel(MPLinearKernel):
128 self,
129 layer: torch.nn.Module,
130 x: torch.Tensor,
132 - bias: Optional[torch.Tensor] = None,
131 + bias: torch.Tensor | None = None,
132 ) -> torch.Tensor:
133 c = self.config
134 w_q, w_s, w_zp, _ = self._get_weight_params(layer)
vllm/model_executor/layers/quantization/kernels/mixed_precision/marlin.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -32,7 +31,7 @@ class MarlinLinearKernel(MPLinearKernel):
31 return 80
32
33 @classmethod
35 - def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, Optional[str]]:
34 + def can_implement(cls, c: MPLinearLayerConfig) -> tuple[bool, str | None]:
35 # Marlin uses inline PTX, so it can only be compatible with Nvidia
36 if not current_platform.is_cuda():
37 return False, "Marlin only supported on CUDA"
@@ -144,7 +143,7 @@ class MarlinLinearKernel(MPLinearKernel):
143 self,
144 layer: torch.nn.Module,
145 x: torch.Tensor,
147 - bias: Optional[torch.Tensor] = None,
146 + bias: torch.Tensor | None = None,
147 ) -> torch.Tensor:
148 c = self.config
149 w_q, w_s, w_zp, w_gidx = self._get_weight_params(layer)
vllm/model_executor/layers/quantization/kernels/scaled_mm/ScaledMMLinearKernel.py
+5 -6
@@ -3,7 +3,6 @@
3
4 from abc import ABC, abstractmethod
5 from dataclasses import dataclass
6 -from typing import Optional
6
7 import torch
8
@@ -23,7 +22,7 @@ class ScaledMMLinearKernel(ABC):
22
23 @classmethod
24 @abstractmethod
26 - def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, Optional[str]]:
25 + def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, str | None]:
26 raise NotImplementedError
27
28 def __init__(
@@ -52,7 +51,7 @@ class ScaledMMLinearKernel(ABC):
51 self,
52 layer: torch.nn.Module,
53 x: torch.Tensor,
55 - bias: Optional[torch.Tensor] = None,
54 + bias: torch.Tensor | None = None,
55 ) -> torch.Tensor:
56 raise NotImplementedError
57
@@ -61,9 +60,9 @@ class ScaledMMLinearKernel(ABC):
60 ) -> tuple[
61 torch.Tensor, # weight
62 torch.Tensor, # weight_scale
64 - Optional[torch.Tensor], # input_scale,
65 - Optional[torch.Tensor], # input_zp
66 - Optional[torch.Tensor], # azp_adj
63 + torch.Tensor | None, # input_scale,
64 + torch.Tensor | None, # input_zp
65 + torch.Tensor | None, # azp_adj
66 ]:
67 return (
68 getattr(layer, self.w_q_name),
vllm/model_executor/layers/quantization/kernels/scaled_mm/__init__.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import os
5 -from typing import Optional
5
6 from vllm.model_executor.layers.quantization.kernels.scaled_mm.aiter import (
7 AiterScaledMMLinearKernel,
@@ -35,7 +34,7 @@ _POSSIBLE_KERNELS: dict[PlatformEnum, list[type[ScaledMMLinearKernel]]] = {
34
35
36 def choose_scaled_mm_linear_kernel(
38 - config: ScaledMMLinearLayerConfig, compute_capability: Optional[int] = None
37 + config: ScaledMMLinearLayerConfig, compute_capability: int | None = None
38 ) -> type[ScaledMMLinearKernel]:
39 """
40 Choose an ScaledMMLinearKernel that can implement the given config for the
vllm/model_executor/layers/quantization/kernels/scaled_mm/aiter.py
+4 -5
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -19,7 +18,7 @@ def rocm_aiter_gemm_w8a8_impl(
18 B: torch.Tensor,
19 As: torch.Tensor,
20 Bs: torch.Tensor,
22 - bias: Optional[torch.Tensor] = None,
21 + bias: torch.Tensor | None = None,
22 output_dtype: torch.dtype = torch.float16,
23 ) -> torch.Tensor:
24 from aiter import gemm_a8w8_CK
@@ -36,7 +35,7 @@ def rocm_aiter_gemm_w8a8_fake(
35 B: torch.Tensor,
36 As: torch.Tensor,
37 Bs: torch.Tensor,
39 - bias: Optional[torch.Tensor] = None,
38 + bias: torch.Tensor | None = None,
39 output_dtype: torch.dtype = torch.float16,
40 ) -> torch.Tensor:
41 m = A.shape[0]
@@ -59,7 +58,7 @@ class AiterScaledMMLinearKernel(CutlassScaledMMLinearKernel):
58 return 90
59
60 @classmethod
62 - def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, Optional[str]]:
61 + def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, str | None]:
62 if not current_platform.is_rocm():
63 return (
64 False,
@@ -99,7 +98,7 @@ class AiterScaledMMLinearKernel(CutlassScaledMMLinearKernel):
98 self,
99 layer: torch.nn.Module,
100 x: torch.Tensor,
102 - bias: Optional[torch.Tensor] = None,
101 + bias: torch.Tensor | None = None,
102 ) -> torch.Tensor:
103 """
104 `AiterScaledMMLinearKernel` implements a fused version of
vllm/model_executor/layers/quantization/kernels/scaled_mm/cpu.py
+4 -5
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -24,7 +23,7 @@ class CPUScaledMMLinearKernel(ScaledMMLinearKernel):
23 return 75
24
25 @classmethod
27 - def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, Optional[str]]:
26 + def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, str | None]:
27 if not current_platform.is_cpu():
28 return False, "CPUScaledMM requires running on CPU."
29
@@ -173,7 +172,7 @@ class CPUScaledMMLinearKernel(ScaledMMLinearKernel):
172 self,
173 layer: torch.nn.Module,
174 x: torch.Tensor,
176 - bias: Optional[torch.Tensor] = None,
175 + bias: torch.Tensor | None = None,
176 ) -> torch.Tensor:
177 return self.linear_method(
178 layer,
@@ -185,7 +184,7 @@ class CPUScaledMMLinearKernel(ScaledMMLinearKernel):
184 self,
185 layer: torch.nn.Module,
186 x: torch.Tensor,
188 - bias: Optional[torch.Tensor] = None,
187 + bias: torch.Tensor | None = None,
188 ) -> torch.Tensor:
189 w_q, w_s, i_s, i_zp, azp_adj = self._get_weight_params(layer)
190
@@ -207,7 +206,7 @@ class CPUScaledMMLinearKernel(ScaledMMLinearKernel):
206 self,
207 layer: torch.nn.Module,
208 x: torch.Tensor,
210 - bias: Optional[torch.Tensor] = None,
209 + bias: torch.Tensor | None = None,
210 ) -> torch.Tensor:
211 w_q, w_s, _, _, _ = self._get_weight_params(layer)
212 return torch.ops._C.int8_scaled_mm_with_quant(
vllm/model_executor/layers/quantization/kernels/scaled_mm/cutlass.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -21,7 +20,7 @@ class CutlassScaledMMLinearKernel(ScaledMMLinearKernel):
20 return 75
21
22 @classmethod
24 - def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, Optional[str]]:
23 + def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, str | None]:
24 if not current_platform.is_cuda():
25 return False, "CutlassScaledMM requires running on CUDA."
26
@@ -110,7 +109,7 @@ class CutlassScaledMMLinearKernel(ScaledMMLinearKernel):
109 self,
110 layer: torch.nn.Module,
111 x: torch.Tensor,
113 - bias: Optional[torch.Tensor] = None,
112 + bias: torch.Tensor | None = None,
113 ) -> torch.Tensor:
114 w_q, w_s, i_s, i_zp, azp_adj = self._get_weight_params(layer)
115
vllm/model_executor/layers/quantization/kernels/scaled_mm/triton.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -17,7 +16,7 @@ class TritonScaledMMLinearKernel(CutlassScaledMMLinearKernel):
16 return 75
17
18 @classmethod
20 - def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, Optional[str]]:
19 + def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, str | None]:
20 if current_platform.is_cpu():
21 return (
22 False,
@@ -38,6 +37,6 @@ class TritonScaledMMLinearKernel(CutlassScaledMMLinearKernel):
37 self,
38 layer: torch.nn.Module,
39 x: torch.Tensor,
41 - bias: Optional[torch.Tensor] = None,
40 + bias: torch.Tensor | None = None,
41 ) -> torch.Tensor:
42 return super().apply_weights(layer, x, bias)
vllm/model_executor/layers/quantization/kernels/scaled_mm/xla.py
+4 -5
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import warnings
5 -from typing import Optional
5
6 import torch
7 from functorch.experimental.control_flow import cond # noqa: F401
@@ -25,7 +24,7 @@ class XLAScaledMMLinearKernel(ScaledMMLinearKernel):
24 )
25
26 @classmethod
28 - def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, Optional[str]]:
27 + def can_implement(cls, c: ScaledMMLinearLayerConfig) -> tuple[bool, str | None]:
28 if not current_platform.is_tpu():
29 return False, "ScaledMMXLA requires running on TPU."
30
@@ -77,17 +76,17 @@ class XLAScaledMMLinearKernel(ScaledMMLinearKernel):
76 message="Pred is a Python constant. When used with torch.cond, it specializes on one of the branches.", # noqa: E501
77 )
78
80 - def no_add_bias(self, x: torch.Tensor, bias: Optional[torch.Tensor]):
79 + def no_add_bias(self, x: torch.Tensor, bias: torch.Tensor | None):
80 return x
81
83 - def add_bias(self, x: torch.Tensor, bias: Optional[torch.Tensor]):
82 + def add_bias(self, x: torch.Tensor, bias: torch.Tensor | None):
83 return x + bias
84
85 def apply_weights(
86 self,
87 layer: torch.nn.Module,
88 x: torch.Tensor,
90 - bias: Optional[torch.Tensor] = None,
89 + bias: torch.Tensor | None = None,
90 ) -> torch.Tensor:
91 w_q, w_s, _, _, _ = self._get_weight_params(layer)
92
vllm/model_executor/layers/quantization/modelopt.py
+33 -32
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import TYPE_CHECKING, Any, Callable, Optional, Union
4 +from collections.abc import Callable
5 +from typing import TYPE_CHECKING, Any, Optional
6
7 import torch
8 from torch.nn import Module
@@ -92,8 +93,8 @@ class ModelOptFp8Config(QuantizationConfig):
93 def __init__(
94 self,
95 is_checkpoint_fp8_serialized: bool = False,
95 - kv_cache_quant_method: Optional[str] = None,
96 - exclude_modules: Optional[list[str]] = None,
96 + kv_cache_quant_method: str | None = None,
97 + exclude_modules: list[str] | None = None,
98 ) -> None:
99 super().__init__()
100 self.is_checkpoint_fp8_serialized = is_checkpoint_fp8_serialized
@@ -128,7 +129,7 @@ class ModelOptFp8Config(QuantizationConfig):
129 @classmethod
130 def override_quantization_method(
131 cls, hf_quant_cfg, user_quant
131 - ) -> Optional[QuantizationMethods]:
132 + ) -> QuantizationMethods | None:
133 """Detect if this ModelOpt config should be used based on
134 quantization config."""
135
@@ -319,7 +320,7 @@ class ModelOptFp8LinearMethod(LinearMethodBase):
320 self,
321 layer: torch.nn.Module,
322 x: torch.Tensor,
322 - bias: Optional[torch.Tensor] = None,
323 + bias: torch.Tensor | None = None,
324 ) -> torch.Tensor:
325 return self.fp8_linear.apply(
326 input=x,
@@ -351,7 +352,7 @@ class ModelOptFp8MoEMethod(FusedMoEMethodBase):
352 )
353
354 self.cutlass_fp8_supported = cutlass_fp8_supported()
354 - self.flashinfer_moe_backend: Optional[FlashinferMoeBackend] = None
355 + self.flashinfer_moe_backend: FlashinferMoeBackend | None = None
356 if envs.VLLM_USE_FLASHINFER_MOE_FP8 and has_flashinfer_moe():
357 self.flashinfer_moe_backend = get_flashinfer_moe_backend()
358 logger.info_once(
@@ -360,7 +361,7 @@ class ModelOptFp8MoEMethod(FusedMoEMethodBase):
361
362 def maybe_make_prepare_finalize(
363 self,
363 - ) -> Optional[mk.FusedMoEPrepareAndFinalize]:
364 + ) -> mk.FusedMoEPrepareAndFinalize | None:
365 # TRT LLM not supported with all2all yet.
366 if self.flashinfer_moe_backend == FlashinferMoeBackend.TENSORRT_LLM:
367 return None
@@ -541,7 +542,7 @@ class ModelOptFp8MoEMethod(FusedMoEMethodBase):
542
543 def get_fused_moe_quant_config(
544 self, layer: torch.nn.Module
544 - ) -> Optional[FusedMoEQuantConfig]:
545 + ) -> FusedMoEQuantConfig | None:
546 if self.flashinfer_moe_backend == FlashinferMoeBackend.TENSORRT_LLM:
547 return None
548
@@ -561,21 +562,21 @@ class ModelOptFp8MoEMethod(FusedMoEMethodBase):
562 top_k: int,
563 renormalize: bool,
564 use_grouped_topk: bool = False,
564 - topk_group: Optional[int] = None,
565 - num_expert_group: Optional[int] = None,
565 + topk_group: int | None = None,
566 + num_expert_group: int | None = None,
567 global_num_experts: int = -1,
567 - expert_map: Optional[torch.Tensor] = None,
568 - custom_routing_function: Optional[Callable] = None,
568 + expert_map: torch.Tensor | None = None,
569 + custom_routing_function: Callable | None = None,
570 scoring_func: str = "softmax",
571 routed_scaling_factor: float = 1.0,
571 - e_score_correction_bias: Optional[torch.Tensor] = None,
572 + e_score_correction_bias: torch.Tensor | None = None,
573 apply_router_weight_on_input: bool = False,
574 activation: str = "silu",
575 enable_eplb: bool = False,
575 - expert_load_view: Optional[torch.Tensor] = None,
576 - logical_to_physical_map: Optional[torch.Tensor] = None,
577 - logical_replica_count: Optional[torch.Tensor] = None,
578 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
576 + expert_load_view: torch.Tensor | None = None,
577 + logical_to_physical_map: torch.Tensor | None = None,
578 + logical_replica_count: torch.Tensor | None = None,
579 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
580 if enable_eplb:
581 raise NotImplementedError(
582 "EPLB not supported for `ModelOptFp8MoEMethod` yet."
@@ -674,7 +675,7 @@ class ModelOptNvFp4Config(QuantizationConfig):
675 def __init__(
676 self,
677 is_checkpoint_nvfp4_serialized: bool,
677 - kv_cache_quant_algo: Optional[str],
678 + kv_cache_quant_algo: str | None,
679 exclude_modules: list[str],
680 group_size: int = 16,
681 ) -> None:
@@ -713,7 +714,7 @@ class ModelOptNvFp4Config(QuantizationConfig):
714 @classmethod
715 def override_quantization_method(
716 cls, hf_quant_cfg, user_quant
716 - ) -> Optional[QuantizationMethods]:
717 + ) -> QuantizationMethods | None:
718 """Detect if this ModelOpt FP4 config should be used based on
719 quantization config."""
720 if hf_quant_cfg is None:
@@ -906,7 +907,7 @@ class ModelOptFp8KVCacheMethod(BaseKVCacheMethod):
907 Supports loading kv-cache scaling factors from FP8 checkpoints.
908 """
909
909 - def __init__(self, quant_config: Union[ModelOptFp8Config, ModelOptNvFp4Config]):
910 + def __init__(self, quant_config: ModelOptFp8Config | ModelOptNvFp4Config):
911 super().__init__(quant_config)
912
913
@@ -1071,7 +1072,7 @@ class ModelOptNvFp4LinearMethod(LinearMethodBase):
1072 self,
1073 layer: torch.nn.Module,
1074 x: torch.Tensor,
1074 - bias: Optional[torch.Tensor] = None,
1075 + bias: torch.Tensor | None = None,
1076 ) -> torch.Tensor:
1077 if self.backend == "marlin":
1078 return apply_fp4_marlin_linear(
@@ -1162,7 +1163,7 @@ class ModelOptNvFp4FusedMoE(FusedMoEMethodBase):
1163 " for ModelOptNvFp4FusedMoE."
1164 )
1165
1165 - def maybe_make_prepare_finalize(self) -> Optional[mk.FusedMoEPrepareAndFinalize]:
1166 + def maybe_make_prepare_finalize(self) -> mk.FusedMoEPrepareAndFinalize | None:
1167 if self.use_marlin or (
1168 self.allow_flashinfer
1169 and self.flashinfer_moe_backend == FlashinferMoeBackend.TENSORRT_LLM
@@ -1565,7 +1566,7 @@ class ModelOptNvFp4FusedMoE(FusedMoEMethodBase):
1566
1567 def get_fused_moe_quant_config(
1568 self, layer: torch.nn.Module
1568 - ) -> Optional[FusedMoEQuantConfig]:
1569 + ) -> FusedMoEQuantConfig | None:
1570 if (
1571 self.use_marlin
1572 or self.flashinfer_moe_backend == FlashinferMoeBackend.TENSORRT_LLM
@@ -1589,21 +1590,21 @@ class ModelOptNvFp4FusedMoE(FusedMoEMethodBase):
1590 top_k: int,
1591 renormalize: bool,
1592 use_grouped_topk: bool = False,
1592 - topk_group: Optional[int] = None,
1593 - num_expert_group: Optional[int] = None,
1593 + topk_group: int | None = None,
1594 + num_expert_group: int | None = None,
1595 global_num_experts: int = -1,
1595 - expert_map: Optional[torch.Tensor] = None,
1596 - custom_routing_function: Optional[Callable] = None,
1596 + expert_map: torch.Tensor | None = None,
1597 + custom_routing_function: Callable | None = None,
1598 scoring_func: str = "softmax",
1599 routed_scaling_factor: float = 1.0,
1599 - e_score_correction_bias: Optional[torch.Tensor] = None,
1600 + e_score_correction_bias: torch.Tensor | None = None,
1601 apply_router_weight_on_input: bool = False,
1602 activation: str = "silu",
1603 enable_eplb: bool = False,
1603 - expert_load_view: Optional[torch.Tensor] = None,
1604 - logical_to_physical_map: Optional[torch.Tensor] = None,
1605 - logical_replica_count: Optional[torch.Tensor] = None,
1606 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
1604 + expert_load_view: torch.Tensor | None = None,
1605 + logical_to_physical_map: torch.Tensor | None = None,
1606 + logical_replica_count: torch.Tensor | None = None,
1607 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
1608 if enable_eplb:
1609 raise NotImplementedError(
1610 "EPLB not supported for `ModelOptNvFp4FusedMoE` yet."
vllm/model_executor/layers/quantization/moe_wna16.py
+14 -13
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional, Union
4 +from collections.abc import Callable
5 +from typing import Any, Optional
6
7 import torch
8
@@ -40,7 +41,7 @@ class MoeWNA16Config(QuantizationConfig):
41 group_size: int,
42 has_zp: bool,
43 lm_head_quantized: bool,
43 - modules_to_not_convert: Optional[list[str]],
44 + modules_to_not_convert: list[str] | None,
45 full_config: dict[str, Any],
46 ) -> None:
47 super().__init__()
@@ -127,7 +128,7 @@ class MoeWNA16Config(QuantizationConfig):
128 @classmethod
129 def override_quantization_method(
130 cls, hf_quant_cfg, user_quant
130 - ) -> Optional[QuantizationMethods]:
131 + ) -> QuantizationMethods | None:
132 can_convert = cls.is_moe_wna16_compatible(hf_quant_cfg)
133 if can_convert and user_quant == "moe_wna16":
134 return cls.get_name()
@@ -339,7 +340,7 @@ class MoeWNA16Method(FusedMoEMethodBase):
340
341 def get_fused_moe_quant_config(
342 self, layer: torch.nn.Module
342 - ) -> Optional[FusedMoEQuantConfig]:
343 + ) -> FusedMoEQuantConfig | None:
344 weight_bits = self.quant_config.weight_bits
345 has_zp = self.quant_config.has_zp
346 assert weight_bits == 4 or weight_bits == 8
@@ -365,21 +366,21 @@ class MoeWNA16Method(FusedMoEMethodBase):
366 top_k: int,
367 renormalize: bool,
368 use_grouped_topk: bool = False,
368 - topk_group: Optional[int] = None,
369 - num_expert_group: Optional[int] = None,
369 + topk_group: int | None = None,
370 + num_expert_group: int | None = None,
371 global_num_experts: int = -1,
371 - expert_map: Optional[torch.Tensor] = None,
372 - custom_routing_function: Optional[Callable] = None,
372 + expert_map: torch.Tensor | None = None,
373 + custom_routing_function: Callable | None = None,
374 scoring_func: str = "softmax",
375 routed_scaling_factor: float = 1.0,
375 - e_score_correction_bias: Optional[torch.Tensor] = None,
376 + e_score_correction_bias: torch.Tensor | None = None,
377 apply_router_weight_on_input: bool = False,
378 activation: str = "silu",
379 enable_eplb: bool = False,
379 - expert_load_view: Optional[torch.Tensor] = None,
380 - logical_to_physical_map: Optional[torch.Tensor] = None,
381 - logical_replica_count: Optional[torch.Tensor] = None,
382 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
380 + expert_load_view: torch.Tensor | None = None,
381 + logical_to_physical_map: torch.Tensor | None = None,
382 + logical_replica_count: torch.Tensor | None = None,
383 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
384 assert self.fused_experts is None
385 if enable_eplb:
386 raise NotImplementedError("EPLB not supported for `MoeWNA16Method` yet.")
vllm/model_executor/layers/quantization/mxfp4.py
+21 -20
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +from collections.abc import Callable
4 from enum import Enum
4 -from typing import Callable, Optional, Union
5 +from typing import Optional
6
7 import torch
8 from torch.nn.parameter import Parameter
@@ -137,7 +138,7 @@ def get_mxfp4_backend():
138
139
140 class Mxfp4Config(QuantizationConfig):
140 - def __init__(self, ignored_layers: Optional[list[str]] = None):
141 + def __init__(self, ignored_layers: list[str] | None = None):
142 super().__init__()
143 self.ignored_layers = ignored_layers
144
@@ -756,7 +757,7 @@ class Mxfp4MoEMethod(FusedMoEMethodBase):
757
758 def get_fused_moe_quant_config(
759 self, layer: torch.nn.Module
759 - ) -> Optional[FusedMoEQuantConfig]:
760 + ) -> FusedMoEQuantConfig | None:
761 if self.mxfp4_backend == Mxfp4Backend.MARLIN:
762 return mxfp4_w4a16_moe_quant_config(
763 w1_bias=layer.w13_bias,
@@ -824,19 +825,19 @@ class Mxfp4MoEMethod(FusedMoEMethodBase):
825 top_k: int,
826 renormalize: bool,
827 use_grouped_topk: bool = False,
827 - topk_group: Optional[int] = None,
828 - num_expert_group: Optional[int] = None,
828 + topk_group: int | None = None,
829 + num_expert_group: int | None = None,
830 global_num_experts: int = -1,
830 - expert_map: Optional[torch.Tensor] = None,
831 - custom_routing_function: Optional[Callable] = None,
831 + expert_map: torch.Tensor | None = None,
832 + custom_routing_function: Callable | None = None,
833 scoring_func: str = "softmax",
833 - e_score_correction_bias: Optional[torch.Tensor] = None,
834 + e_score_correction_bias: torch.Tensor | None = None,
835 apply_router_weight_on_input: bool = False,
836 activation: str = "silu",
837 enable_eplb: bool = False,
837 - expert_load_view: Optional[torch.Tensor] = None,
838 - logical_to_physical_map: Optional[torch.Tensor] = None,
839 - logical_replica_count: Optional[torch.Tensor] = None,
838 + expert_load_view: torch.Tensor | None = None,
839 + logical_to_physical_map: torch.Tensor | None = None,
840 + logical_replica_count: torch.Tensor | None = None,
841 ) -> torch.Tensor:
842 assert isinstance(self.fused_experts, mk.FusedMoEModularKernel)
843
@@ -890,21 +891,21 @@ class Mxfp4MoEMethod(FusedMoEMethodBase):
891 top_k: int,
892 renormalize: bool,
893 use_grouped_topk: bool = False,
893 - topk_group: Optional[int] = None,
894 - num_expert_group: Optional[int] = None,
894 + topk_group: int | None = None,
895 + num_expert_group: int | None = None,
896 global_num_experts: int = -1,
896 - expert_map: Optional[torch.Tensor] = None,
897 - custom_routing_function: Optional[Callable] = None,
897 + expert_map: torch.Tensor | None = None,
898 + custom_routing_function: Callable | None = None,
899 scoring_func: str = "softmax",
900 routed_scaling_factor: float = 1.0,
900 - e_score_correction_bias: Optional[torch.Tensor] = None,
901 + e_score_correction_bias: torch.Tensor | None = None,
902 apply_router_weight_on_input: bool = False,
903 activation: str = "silu",
904 enable_eplb: bool = False,
904 - expert_load_view: Optional[torch.Tensor] = None,
905 - logical_to_physical_map: Optional[torch.Tensor] = None,
906 - logical_replica_count: Optional[torch.Tensor] = None,
907 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
905 + expert_load_view: torch.Tensor | None = None,
906 + logical_to_physical_map: torch.Tensor | None = None,
907 + logical_replica_count: torch.Tensor | None = None,
908 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
909 if enable_eplb:
910 raise NotImplementedError("EPLB is not supported for mxfp4")
911
vllm/model_executor/layers/quantization/petit.py
+5 -5
@@ -41,9 +41,9 @@ class PetitNvFp4Config(QuantizationConfig):
41 def __init__(
42 self,
43 is_checkpoint_nvfp4_serialized: bool = False,
44 - kv_cache_quant_algo: Optional[str] = None,
45 - group_size: Optional[int] = None,
46 - exclude_modules: Optional[list[str]] = None,
44 + kv_cache_quant_algo: str | None = None,
45 + group_size: int | None = None,
46 + exclude_modules: list[str] | None = None,
47 ) -> None:
48 self._check_hardware_support()
49 self.is_checkpoint_nvfp4_serialized = is_checkpoint_nvfp4_serialized
@@ -133,7 +133,7 @@ class PetitNvFp4Config(QuantizationConfig):
133 @classmethod
134 def override_quantization_method(
135 cls, hf_quant_cfg, user_quant
136 - ) -> Optional[QuantizationMethods]:
136 + ) -> QuantizationMethods | None:
137 if not current_platform.is_rocm():
138 return None
139
@@ -307,7 +307,7 @@ class PetitNvFp4LinearMethod(LinearMethodBase):
307 self,
308 layer: torch.nn.Module,
309 x: torch.Tensor,
310 - bias: Optional[torch.Tensor] = None,
310 + bias: torch.Tensor | None = None,
311 ) -> torch.Tensor:
312 return apply_petit_nvfp4_linear(
313 input=x,
vllm/model_executor/layers/quantization/ptpc_fp8.py
+2 -2
@@ -34,7 +34,7 @@ class PTPCFp8Config(Fp8Config):
34 def __init__(
35 self,
36 activation_scheme: str = "dynamic",
37 - ignored_layers: Optional[list[str]] = None,
37 + ignored_layers: list[str] | None = None,
38 ) -> None:
39 if not current_platform.is_rocm():
40 raise ValueError("ptpc_fp8 quantization is supported only on ROCm.")
@@ -125,7 +125,7 @@ class PTPCFp8LinearMethod(Fp8LinearMethod):
125 self,
126 layer: torch.nn.Module,
127 x: torch.Tensor,
128 - bias: Optional[torch.Tensor] = None,
128 + bias: torch.Tensor | None = None,
129 ) -> torch.Tensor:
130 return self.fp8_linear.apply(
131 input=x,
vllm/model_executor/layers/quantization/quark/quark.py
+11 -11
@@ -43,8 +43,8 @@ class QuarkConfig(QuantizationConfig):
43 def __init__(
44 self,
45 quant_config: dict[str, Any],
46 - kv_cache_group: Optional[list[str]] = None,
47 - kv_cache_config: Optional[dict[str, Any]] = None,
46 + kv_cache_group: list[str] | None = None,
47 + kv_cache_config: dict[str, Any] | None = None,
48 pack_method: str = "reorder",
49 ):
50 super().__init__()
@@ -178,8 +178,8 @@ class QuarkConfig(QuantizationConfig):
178
179 def _is_fp8_w8a8(
180 self,
181 - weight_quant: Optional[dict[str, Any]],
182 - input_quant: Optional[dict[str, Any]],
181 + weight_quant: dict[str, Any] | None,
182 + input_quant: dict[str, Any] | None,
183 ) -> bool:
184 # Confirm weights and input quantized.
185 if weight_quant is None or input_quant is None:
@@ -209,8 +209,8 @@ class QuarkConfig(QuantizationConfig):
209
210 def _is_static_tensor_w8a8(
211 self,
212 - weight_quant: Optional[dict[str, Any]],
213 - input_quant: Optional[dict[str, Any]],
212 + weight_quant: dict[str, Any] | None,
213 + input_quant: dict[str, Any] | None,
214 ) -> bool:
215 # Confirm weights and input quantized.
216 if weight_quant is None or input_quant is None:
@@ -237,8 +237,8 @@ class QuarkConfig(QuantizationConfig):
237
238 def _is_ocp_mx(
239 self,
240 - weight_quant: Optional[dict[str, Any]],
241 - input_quant: Optional[dict[str, Any]],
240 + weight_quant: dict[str, Any] | None,
241 + input_quant: dict[str, Any] | None,
242 ) -> bool:
243 # Confirm weights and input quantized.
244 if weight_quant is None or input_quant is None:
@@ -370,7 +370,7 @@ class QuarkConfig(QuantizationConfig):
370
371 return scheme
372
373 - def get_cache_scale(self, name: str) -> Optional[str]:
373 + def get_cache_scale(self, name: str) -> str | None:
374 """
375 Check whether the param name matches the format for k/v cache scales
376 in quark. If this is the case, return its equivalent param name
@@ -429,7 +429,7 @@ class QuarkLinearMethod(LinearMethodBase):
429 self,
430 layer: torch.nn.Module,
431 x: torch.Tensor,
432 - bias: Optional[torch.Tensor] = None,
432 + bias: torch.Tensor | None = None,
433 ):
434 """
435 Use the output of create_weights and the CompressedTensorsScheme
@@ -454,7 +454,7 @@ class QuarkKVCacheMethod(BaseKVCacheMethod):
454 super().__init__(quant_config)
455
456 @staticmethod
457 - def validate_kv_cache_config(kv_cache_config: Optional[dict[str, Any]]):
457 + def validate_kv_cache_config(kv_cache_config: dict[str, Any] | None):
458 """
459 Validator for the kv cache configuration. Useful for controlling the
460 kv cache quantization schemes, that are being supported in vLLM
vllm/model_executor/layers/quantization/quark/quark_moe.py
+22 -21
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional, Union
4 +from collections.abc import Callable
5 +from typing import Any
6
7 import torch
8
@@ -333,7 +334,7 @@ class QuarkW8A8Fp8MoEMethod(QuarkMoEMethod):
334
335 def get_fused_moe_quant_config(
336 self, layer: torch.nn.Module
336 - ) -> Optional[FusedMoEQuantConfig]:
337 + ) -> FusedMoEQuantConfig | None:
338 return fp8_w8a8_moe_quant_config(
339 w1_scale=layer.w13_weight_scale,
340 w2_scale=layer.w2_weight_scale,
@@ -350,21 +351,21 @@ class QuarkW8A8Fp8MoEMethod(QuarkMoEMethod):
351 top_k: int,
352 renormalize: bool,
353 use_grouped_topk: bool = False,
353 - topk_group: Optional[int] = None,
354 - num_expert_group: Optional[int] = None,
354 + topk_group: int | None = None,
355 + num_expert_group: int | None = None,
356 global_num_experts: int = -1,
356 - expert_map: Optional[torch.Tensor] = None,
357 - custom_routing_function: Optional[Callable] = None,
357 + expert_map: torch.Tensor | None = None,
358 + custom_routing_function: Callable | None = None,
359 scoring_func: str = "softmax",
360 routed_scaling_factor: float = 1.0,
360 - e_score_correction_bias: Optional[torch.Tensor] = None,
361 + e_score_correction_bias: torch.Tensor | None = None,
362 apply_router_weight_on_input: bool = False,
363 activation: str = "silu",
364 enable_eplb: bool = False,
364 - expert_load_view: Optional[torch.Tensor] = None,
365 - logical_to_physical_map: Optional[torch.Tensor] = None,
366 - logical_replica_count: Optional[torch.Tensor] = None,
367 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
365 + expert_load_view: torch.Tensor | None = None,
366 + logical_to_physical_map: torch.Tensor | None = None,
367 + logical_replica_count: torch.Tensor | None = None,
368 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
369 assert self.fused_experts is None
370
371 if enable_eplb:
@@ -568,7 +569,7 @@ class QuarkOCP_MX_MoEMethod(QuarkMoEMethod):
569
570 def get_fused_moe_quant_config(
571 self, layer: torch.nn.Module
571 - ) -> Optional[FusedMoEQuantConfig]:
572 + ) -> FusedMoEQuantConfig | None:
573 return ocp_mx_moe_quant_config(
574 quant_dtype=self.input_dtype,
575 weight_dtype=self.weight_dtype,
@@ -587,21 +588,21 @@ class QuarkOCP_MX_MoEMethod(QuarkMoEMethod):
588 top_k: int,
589 renormalize: bool,
590 use_grouped_topk: bool = False,
590 - topk_group: Optional[int] = None,
591 - num_expert_group: Optional[int] = None,
591 + topk_group: int | None = None,
592 + num_expert_group: int | None = None,
593 global_num_experts: int = -1,
593 - expert_map: Optional[torch.Tensor] = None,
594 - custom_routing_function: Optional[Callable] = None,
594 + expert_map: torch.Tensor | None = None,
595 + custom_routing_function: Callable | None = None,
596 scoring_func: str = "softmax",
597 routed_scaling_factor: float = 1.0,
597 - e_score_correction_bias: Optional[torch.Tensor] = None,
598 + e_score_correction_bias: torch.Tensor | None = None,
599 apply_router_weight_on_input: bool = False,
600 activation: str = "silu",
601 enable_eplb: bool = False,
601 - expert_load_view: Optional[torch.Tensor] = None,
602 - logical_to_physical_map: Optional[torch.Tensor] = None,
603 - logical_replica_count: Optional[torch.Tensor] = None,
604 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
602 + expert_load_view: torch.Tensor | None = None,
603 + logical_to_physical_map: torch.Tensor | None = None,
604 + logical_replica_count: torch.Tensor | None = None,
605 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
606 assert self.fused_experts is None
607
608 if enable_eplb:
vllm/model_executor/layers/quantization/quark/schemes/quark_ocp_mx.py
+7 -6
@@ -1,9 +1,10 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 +from collections.abc import Callable
5 from fractions import Fraction
6 from functools import cache, partial
6 -from typing import Any, Callable, Optional, Union
7 +from typing import Any
8
9 import torch
10 import torch.nn.functional as F
@@ -54,8 +55,8 @@ try:
55 weight: torch.Tensor,
56 weight_scale: torch.Tensor,
57 rocm_use_aiter_fp4_asm_gemm: bool = False,
57 - out_dtype: Optional[torch.dtype] = torch.bfloat16,
58 - x_scales: Optional[torch.Tensor] = None,
58 + out_dtype: torch.dtype | None = torch.bfloat16,
59 + x_scales: torch.Tensor | None = None,
60 ) -> torch.Tensor:
61 M = x.shape[0]
62 if rocm_use_aiter_fp4_asm_gemm:
@@ -95,7 +96,7 @@ try:
96 weight_scale: torch.Tensor,
97 x_scales: torch.Tensor = None,
98 rocm_use_aiter_fp4_asm_gemm: bool = False,
98 - out_dtype: Optional[torch.dtype] = torch.bfloat16,
99 + out_dtype: torch.dtype | None = torch.bfloat16,
100 ) -> torch.Tensor:
101 return torch.empty(
102 (*x.shape[:-1], weight.shape[0]), dtype=out_dtype, device=x.device
@@ -129,7 +130,7 @@ class QuarkOCP_MX(QuarkScheme):
130 )
131
132 if self.weight_dtype == "mxfp4":
132 - self.packed_factor: Union[int, Fraction] = 2
133 + self.packed_factor: int | Fraction = 2
134 self.dequant_func = dequant_mxfp4
135 else:
136 self.packed_factor = Fraction(numerator=8, denominator=6)
@@ -282,7 +283,7 @@ class QuarkOCP_MX(QuarkScheme):
283 self,
284 layer: torch.nn.Module,
285 x: torch.Tensor,
285 - bias: Optional[torch.Tensor] = None,
286 + bias: torch.Tensor | None = None,
287 ) -> torch.Tensor:
288 if self.emulate:
289 dq_w = self.dequant_func(layer.weight, layer.weight_scale, x.dtype)
vllm/model_executor/layers/quantization/quark/schemes/quark_scheme.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from abc import ABC, abstractmethod
5 -from typing import Optional
5
6 import torch
7
@@ -33,7 +32,7 @@ class QuarkScheme(ABC):
32
33 @abstractmethod
34 def apply_weights(
36 - self, layer: torch.nn.Module, x: torch.Tensor, bias: Optional[torch.Tensor]
35 + self, layer: torch.nn.Module, x: torch.Tensor, bias: torch.Tensor | None
36 ):
37 """
38 Run the forward pass for the particular scheme. This is where
vllm/model_executor/layers/quantization/quark/schemes/quark_w8a8_fp8.py
+5 -4
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Any, Callable, Optional, cast
4 +from collections.abc import Callable
5 +from typing import Any, cast
6
7 import torch
8 from torch.nn import Parameter
@@ -25,11 +26,11 @@ __all__ = ["QuarkW8A8Fp8"]
26
27 class QuarkW8A8Fp8(QuarkScheme):
28 def __init__(
28 - self, weight_config: dict[str, Any], input_config: Optional[dict[str, Any]]
29 + self, weight_config: dict[str, Any], input_config: dict[str, Any] | None
30 ):
31 self.weight_qscheme = cast(str, weight_config.get("qscheme"))
32 self.is_static_input_scheme: bool = False
32 - self.input_qscheme: Optional[str] = None
33 + self.input_qscheme: str | None = None
34 if input_config is not None:
35 self.is_static_input_scheme = not cast(bool, input_config.get("is_dynamic"))
36 self.input_qscheme = cast(str, input_config.get("qscheme"))
@@ -166,7 +167,7 @@ class QuarkW8A8Fp8(QuarkScheme):
167 self,
168 layer: torch.nn.Module,
169 x: torch.Tensor,
169 - bias: Optional[torch.Tensor] = None,
170 + bias: torch.Tensor | None = None,
171 ) -> torch.Tensor:
172 return self.fp8_linear.apply(
173 input=x,
vllm/model_executor/layers/quantization/quark/schemes/quark_w8a8_int8.py
+4 -4
@@ -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 Callable, Optional
4 +from collections.abc import Callable
5
6 import torch
7
@@ -27,8 +27,8 @@ class QuarkW8A8Int8(QuarkScheme):
27 def __init__(
28 self,
29 qscheme: str,
30 - is_static_input_scheme: Optional[bool],
31 - input_symmetric: Optional[bool],
30 + is_static_input_scheme: bool | None,
31 + input_symmetric: bool | None,
32 ):
33 self.qscheme = qscheme
34 self.is_static_input_scheme = is_static_input_scheme
@@ -134,6 +134,6 @@ class QuarkW8A8Int8(QuarkScheme):
134 self.kernel.process_weights_after_loading(layer)
135
136 def apply_weights(
137 - self, layer: torch.nn.Module, x: torch.Tensor, bias: Optional[torch.Tensor]
137 + self, layer: torch.nn.Module, x: torch.Tensor, bias: torch.Tensor | None
138 ) -> torch.Tensor:
139 return self.kernel.apply_weights(layer, x, bias)
vllm/model_executor/layers/quantization/quark/utils.py
+2 -2
@@ -3,7 +3,7 @@
3
4 from collections.abc import Iterable, Mapping
5 from types import MappingProxyType
6 -from typing import Any, Optional
6 +from typing import Any
7
8 import regex as re
9
@@ -22,7 +22,7 @@ def deep_compare(dict1: Any, dict2: Any) -> bool:
22
23
24 def should_ignore_layer(
25 - layer_name: Optional[str],
25 + layer_name: str | None,
26 ignore: Iterable[str],
27 fused_mapping: Mapping[str, list[str]] = MappingProxyType({}),
28 ) -> bool:
vllm/model_executor/layers/quantization/rtn.py
+13 -12
@@ -3,7 +3,8 @@
3 # Copyright © 2025, Oracle and/or its affiliates.
4
5 import os
6 -from typing import Any, Callable, Optional, Union
6 +from collections.abc import Callable
7 +from typing import Any, Optional
8
9 import torch
10 import torch.nn.functional as F
@@ -226,7 +227,7 @@ class RTNLinearMethod(LinearMethodBase):
227 self,
228 layer: torch.nn.Module,
229 x: torch.Tensor,
229 - bias: Optional[torch.Tensor] = None,
230 + bias: torch.Tensor | None = None,
231 ) -> torch.Tensor:
232 qweight = layer.weight
233 scale = layer.scale
@@ -320,7 +321,7 @@ class RTNMoEMethod(FusedMoEMethodBase):
321
322 def get_fused_moe_quant_config(
323 self, layer: torch.nn.Module
323 - ) -> Optional[FusedMoEQuantConfig]:
324 + ) -> FusedMoEQuantConfig | None:
325 weight_bits = self.quant_config.weight_bits
326 group_size = self.quant_config.group_size
327 assert weight_bits == 4 or weight_bits == 8
@@ -345,21 +346,21 @@ class RTNMoEMethod(FusedMoEMethodBase):
346 top_k: int,
347 renormalize: bool,
348 use_grouped_topk: bool = False,
348 - topk_group: Optional[int] = None,
349 - num_expert_group: Optional[int] = None,
349 + topk_group: int | None = None,
350 + num_expert_group: int | None = None,
351 global_num_experts: int = -1,
351 - expert_map: Optional[torch.Tensor] = None,
352 - custom_routing_function: Optional[Callable] = None,
352 + expert_map: torch.Tensor | None = None,
353 + custom_routing_function: Callable | None = None,
354 scoring_func: str = "softmax",
355 routed_scaling_factor: float = 1.0,
355 - e_score_correction_bias: Optional[torch.Tensor] = None,
356 + e_score_correction_bias: torch.Tensor | None = None,
357 apply_router_weight_on_input: bool = False,
358 activation: str = "silu",
359 enable_eplb: bool = False,
359 - expert_load_view: Optional[torch.Tensor] = None,
360 - logical_to_physical_map: Optional[torch.Tensor] = None,
361 - logical_replica_count: Optional[torch.Tensor] = None,
362 - ) -> Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]:
360 + expert_load_view: torch.Tensor | None = None,
361 + logical_to_physical_map: torch.Tensor | None = None,
362 + logical_replica_count: torch.Tensor | None = None,
363 + ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
364 assert self.fused_experts is None
365
366 if enable_eplb:
vllm/model_executor/layers/quantization/schema.py
+1 -3
@@ -13,8 +13,6 @@ possible on ROCm), the model can be optionally augmented with KV cache
13 scaling factors.
14 """
15
16 -from typing import Optional
17 -
16 from pydantic import BaseModel, ConfigDict, ValidationInfo, model_validator
17
18
@@ -75,7 +73,7 @@ class QuantParamSchema(BaseModel):
73 # TODO: Generalize and extend with more fields
74 # (e.g. weights/activations params) once functionality is enabled
75 model_config = ConfigDict(protected_namespaces=())
78 - model_type: Optional[str]
76 + model_type: str | None
77 kv_cache: KVCacheQuantSchema
78
79 @model_validator(mode="after")
vllm/model_executor/layers/quantization/torchao.py
+2 -2
@@ -63,7 +63,7 @@ class TorchAOConfig(QuantizationConfig):
63 def __init__(
64 self,
65 torchao_config,
66 - skip_modules: Optional[list[str]] = None,
66 + skip_modules: list[str] | None = None,
67 is_checkpoint_torchao_serialized: bool = False,
68 ) -> None:
69 """
@@ -301,7 +301,7 @@ class TorchAOLinearMethod(LinearMethodBase):
301 self,
302 layer: torch.nn.Module,
303 x: torch.Tensor,
304 - bias: Optional[torch.Tensor] = None,
304 + bias: torch.Tensor | None = None,
305 ) -> torch.Tensor:
306 return F.linear(x, layer.weight, bias)
307
vllm/model_executor/layers/quantization/tpu_int8.py
+1 -1
@@ -119,7 +119,7 @@ class TPUInt8LinearMethod(LinearMethodBase):
119 self,
120 layer: torch.nn.Module,
121 x: torch.Tensor,
122 - bias: Optional[torch.Tensor] = None,
122 + bias: torch.Tensor | None = None,
123 ) -> torch.Tensor:
124 try:
125 import torch_xla.experimental.custom_kernel # noqa: F401
vllm/model_executor/layers/quantization/utils/bitblas_utils.py
+6 -7
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5 from packaging import version
@@ -29,7 +28,7 @@ BITBLAS_SUPPORTED_SYM = [False, True]
28 # Determines the supported quantization types for BitBLAS based on the
29 # device's capability and whether zero-point (zp) is used.
30 def query_bitblas_supported_quant_types(
32 - has_zp: bool, device_capability: Optional[int] = None
31 + has_zp: bool, device_capability: int | None = None
32 ):
33 if device_capability is None:
34 capability_tuple = current_platform.get_device_capability()
@@ -52,10 +51,10 @@ def query_bitblas_supported_quant_types(
51
52 def _check_bitblas_supported(
53 quant_type: ScalarType,
55 - group_size: Optional[int],
54 + group_size: int | None,
55 has_zp: bool,
57 - device_capability: Optional[int] = None,
58 -) -> tuple[bool, Optional[str]]:
56 + device_capability: int | None = None,
57 +) -> tuple[bool, str | None]:
58 if device_capability is None:
59 capability_tuple = current_platform.get_device_capability()
60 device_capability = (
@@ -99,7 +98,7 @@ def check_bitblas_supported(
98 quant_type: ScalarType,
99 group_size: int,
100 has_zp: bool = False,
102 - device_capability: Optional[int] = None,
101 + device_capability: int | None = None,
102 ) -> bool:
103 cond, _ = _check_bitblas_supported(
104 quant_type, group_size, has_zp, device_capability
@@ -156,7 +155,7 @@ def check_bitblas_supports_shape(
155 input_size_per_partition: int,
156 input_size: int,
157 group_size: int,
159 -) -> tuple[bool, Optional[str]]:
158 +) -> tuple[bool, str | None]:
159 try:
160 verify_bitblas_supports_shape(
161 output_size_per_partition, input_size_per_partition, input_size, group_size
vllm/model_executor/layers/quantization/utils/flashinfer_fp4_moe.py
-2
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Utility helpers for NVFP4 + FlashInfer fused-MoE path"""
4
5 -from __future__ import annotations
6 -
5 import torch
6
7 import vllm.envs as envs
vllm/model_executor/layers/quantization/utils/flashinfer_utils.py
+7 -8
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from enum import Enum
4 -from typing import Optional
4
5 import torch
6
@@ -101,10 +100,10 @@ def apply_flashinfer_per_tensor_scale_fp8(
100 layer: torch.nn.Module,
101 hidden_states: torch.Tensor,
102 router_logits: torch.Tensor,
104 - routing_bias: Optional[torch.Tensor],
103 + routing_bias: torch.Tensor | None,
104 top_k: int,
106 - num_expert_group: Optional[int],
107 - topk_group: Optional[int],
105 + num_expert_group: int | None,
106 + topk_group: int | None,
107 global_num_experts: int,
108 apply_router_weight_on_input: bool,
109 ) -> torch.Tensor:
@@ -186,7 +185,7 @@ def register_moe_scaling_factors(layer: torch.nn.Module) -> None:
185
186
187 def build_flashinfer_fp8_cutlass_moe_prepare_finalize(
189 - moe: Optional[FusedMoEConfig],
188 + moe: FusedMoEConfig | None,
189 ) -> mk.FusedMoEPrepareAndFinalize:
190 """Create a FlashInfer CUTLASS fused-MoE prepare finalize kernel"""
191 use_dp = moe.moe_parallel_config.dp_size > 1 if moe is not None else False
@@ -194,9 +193,9 @@ def build_flashinfer_fp8_cutlass_moe_prepare_finalize(
193
194
195 def select_cutlass_fp8_gemm_impl(
197 - moe: Optional[FusedMoEConfig],
196 + moe: FusedMoEConfig | None,
197 quant_config: FusedMoEQuantConfig,
199 - out_dtype: Optional[torch.dtype] = None,
198 + out_dtype: torch.dtype | None = None,
199 ) -> mk.FusedMoEPermuteExpertsUnpermute:
200 """Return a GEMM *experts* implementation for fused-MoE layers"""
201
@@ -225,7 +224,7 @@ def flashinfer_cutlass_moe_fp8(
224 inplace: bool = False,
225 activation: str = "silu",
226 global_num_experts: int = -1,
228 - expert_map: Optional[torch.Tensor] = None,
227 + expert_map: torch.Tensor | None = None,
228 apply_router_weight_on_input: bool = False,
229 ) -> torch.Tensor:
230 quant_config = layer.quant_method.get_fused_moe_quant_config(layer)
vllm/model_executor/layers/quantization/utils/fp8_utils.py
+20 -20
@@ -5,8 +5,8 @@
5 import functools
6 import json
7 import os
8 -from collections.abc import Sequence
9 -from typing import Any, Callable, Optional, Union
8 +from collections.abc import Callable, Sequence
9 +from typing import Any
10
11 import torch
12
@@ -39,7 +39,7 @@ from vllm.utils.deep_gemm import (
39 logger = init_logger(__name__)
40
41
42 -def is_fp8(x: Union[torch.dtype, torch.Tensor]) -> bool:
42 +def is_fp8(x: torch.dtype | torch.Tensor) -> bool:
43 if isinstance(x, torch.Tensor):
44 x = x.dtype
45 return x == torch.float8_e4m3fn or x == torch.float8_e4m3fnuz
@@ -54,7 +54,7 @@ def cutlass_scaled_mm(
54 Bs: torch.Tensor,
55 block_size: list[int],
56 output_dtype: torch.dtype = torch.float16,
57 - is_hopper: Optional[bool] = None,
57 + is_hopper: bool | None = None,
58 ) -> torch.Tensor:
59 if is_hopper is None:
60 is_hopper = current_platform.is_device_capability(90)
@@ -279,8 +279,8 @@ class W8A8BlockFp8LinearOp:
279 input: torch.Tensor,
280 weight: torch.Tensor,
281 weight_scale: torch.Tensor,
282 - input_scale: Optional[torch.Tensor] = None,
283 - bias: Optional[torch.Tensor] = None,
282 + input_scale: torch.Tensor | None = None,
283 + bias: torch.Tensor | None = None,
284 ) -> torch.Tensor:
285 assert input_scale is None
286 # View input as 2D matrix for fp8 methods
@@ -394,7 +394,7 @@ class W8A8BlockFp8LinearOp:
394 ],
395 torch.Tensor,
396 ],
397 - Optional[QuantFP8],
397 + QuantFP8 | None,
398 ]:
399 if use_cutlass:
400 return self._run_cutlass, (
@@ -418,7 +418,7 @@ class W8A8BlockFp8LinearOp:
418
419
420 def input_to_float8(
421 - x: torch.Tensor, dtype: Optional[torch.dtype] = None
421 + x: torch.Tensor, dtype: torch.dtype | None = None
422 ) -> tuple[torch.Tensor, torch.Tensor]:
423 """This function quantizes input values to float8 values "
424 "with tensor-wise quantization."""
@@ -568,10 +568,10 @@ def per_token_group_quant_fp8(
568 x: torch.Tensor,
569 group_size: int,
570 eps: float = 1e-10,
571 - dtype: Optional[torch.dtype] = None,
571 + dtype: torch.dtype | None = None,
572 column_major_scales: bool = False,
573 - out_q: Optional[torch.Tensor] = None,
574 - use_ue8m0: Optional[bool] = None,
573 + out_q: torch.Tensor | None = None,
574 + use_ue8m0: bool | None = None,
575 ) -> tuple[torch.Tensor, torch.Tensor]:
576 """Function to perform per-token-group quantization on an input tensor `x`.
577 It converts the tensor values into signed float8 values and returns the
@@ -754,7 +754,7 @@ def _w8a8_triton_block_scaled_mm(
754 @functools.lru_cache
755 def get_w8a8_block_fp8_configs(
756 N: int, K: int, block_n: int, block_k: int
757 -) -> Optional[dict[int, Any]]:
757 +) -> dict[int, Any] | None:
758 """
759 Return optimized configurations for the w8a8 block fp8 kernel.
760 The return value will be a dictionary that maps an irregular grid of
@@ -1012,7 +1012,7 @@ def validate_fp8_block_shape(
1012 def create_fp8_weight_parameter(
1013 output_size_per_partition: int,
1014 input_size_per_partition: int,
1015 - weight_loader: Optional[Callable],
1015 + weight_loader: Callable | None,
1016 ) -> torch.nn.Parameter:
1017 """Create FP8 weight parameter."""
1018 from vllm.model_executor.parameter import ModelWeightParameter
@@ -1033,8 +1033,8 @@ def create_fp8_scale_parameter(
1033 parameter_type: torch.nn.Parameter,
1034 output_partition_sizes: list[int],
1035 input_size_per_partition: int,
1036 - block_size: Optional[list[int]],
1037 - weight_loader: Optional[Callable],
1036 + block_size: list[int] | None,
1037 + weight_loader: Callable | None,
1038 ) -> torch.nn.Parameter:
1039 """Create scale parameter based on quantization strategy."""
1040 if parameter_type == ChannelQuantScaleParameter:
@@ -1070,7 +1070,7 @@ def create_fp8_scale_parameter(
1070
1071
1072 def create_fp8_input_scale(
1073 - output_partition_sizes: list[int], weight_loader: Optional[Callable]
1073 + output_partition_sizes: list[int], weight_loader: Callable | None
1074 ) -> torch.nn.Parameter:
1075 """Create input scale parameter for static activation quantization."""
1076 from vllm.model_executor.parameter import PerTensorScaleParameter
@@ -1087,8 +1087,8 @@ def process_fp8_weight_tensor_strategy(
1087 weight: torch.Tensor,
1088 weight_scale: torch.Tensor,
1089 logical_widths: list[int],
1090 - input_scale: Optional[torch.Tensor] = None,
1091 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
1090 + input_scale: torch.Tensor | None = None,
1091 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
1092 """Process weights for tensor-wise quantization strategy."""
1093 from vllm.model_executor.layers.quantization.utils.w8a8_utils import (
1094 normalize_e4m3fn_to_e4m3fnuz,
@@ -1114,8 +1114,8 @@ def process_fp8_weight_tensor_strategy(
1114 def process_fp8_weight_channel_strategy(
1115 weight: torch.Tensor,
1116 weight_scale: torch.Tensor,
1117 - input_scale: Optional[torch.Tensor] = None,
1118 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
1117 + input_scale: torch.Tensor | None = None,
1118 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
1119 """Process weights for channel-wise quantization strategy."""
1120 from vllm.model_executor.layers.quantization.utils.w8a8_utils import (
1121 normalize_e4m3fn_to_e4m3fnuz,
vllm/model_executor/layers/quantization/utils/gptq_utils.py
+7 -7
@@ -4,7 +4,7 @@ from collections.abc import Mapping
4 from copy import deepcopy
5 from fractions import Fraction
6 from types import MappingProxyType
7 -from typing import TYPE_CHECKING, Optional, Union
7 +from typing import TYPE_CHECKING
8
9 import regex as re
10 import torch
@@ -25,7 +25,7 @@ else:
25
26 # Match dynamic rules with module name (prefix) and override quantize
27 # config if module (prefix) matches a rule
28 -def override_config(config: Union[GPTQConfig, GPTQMarlinConfig], prefix: str):
28 +def override_config(config: GPTQConfig | GPTQMarlinConfig, prefix: str):
29 weight_bits = get_dynamic_override(config, prefix, "bits", config.weight_bits)
30 if isinstance(weight_bits, int):
31 config.weight_bits = weight_bits
@@ -60,11 +60,11 @@ def override_config(config: Union[GPTQConfig, GPTQMarlinConfig], prefix: str):
60
61
62 def get_dynamic_override(
63 - config: Union[GPTQConfig, GPTQMarlinConfig],
63 + config: GPTQConfig | GPTQMarlinConfig,
64 layer_name: str,
65 - key: Optional[str] = None,
66 - default_value: Union[int, bool, None] = None,
67 -) -> Union[dict, int, bool, None]:
65 + key: str | None = None,
66 + default_value: int | bool | None = None,
67 +) -> dict | int | bool | None:
68 for pattern, pattern_dict in config.dynamic.items():
69 # Negative match: matched modules are excluded from quantized init
70 if pattern.startswith("-:"):
@@ -126,7 +126,7 @@ def is_layer_gptq_quantized(
126
127
128 def get_linear_quant_method(
129 - config: Union[GPTQConfig, GPTQMarlinConfig],
129 + config: GPTQConfig | GPTQMarlinConfig,
130 layer: torch.nn.Module,
131 prefix: str,
132 linear_method_cls: type,
vllm/model_executor/layers/quantization/utils/int8_utils.py
+4 -4
@@ -6,7 +6,7 @@ import functools
6 import json
7 import logging
8 import os
9 -from typing import Any, Optional
9 +from typing import Any
10
11 import torch
12
@@ -21,8 +21,8 @@ def apply_w8a8_block_int8_linear(
21 weight: torch.Tensor,
22 block_size: list[int],
23 weight_scale: torch.Tensor,
24 - input_scale: Optional[torch.Tensor] = None,
25 - bias: Optional[torch.Tensor] = None,
24 + input_scale: torch.Tensor | None = None,
25 + bias: torch.Tensor | None = None,
26 ) -> torch.Tensor:
27 assert input_scale is None
28 # View input as 2D matrix for fp8 methods
@@ -359,7 +359,7 @@ def _w8a8_block_int8_matmul(
359 @functools.lru_cache
360 def get_w8a8_block_int8_configs(
361 N: int, K: int, block_n: int, block_k: int
362 -) -> Optional[dict[int, Any]]:
362 +) -> dict[int, Any] | None:
363 """
364 Return optimized configurations for the w8a8 block fp8 kernel.
365
vllm/model_executor/layers/quantization/utils/layer_utils.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Union
4
5 import torch
6
@@ -21,7 +20,7 @@ def update_tensor_inplace(dst: torch.Tensor, src: torch.Tensor):
20 # Newly generated tensors need to replace existing tensors that are
21 # already registered as parameters by vLLM (and won't be freed)
22 def replace_parameter(
24 - mod: torch.nn.Module, name: str, new: Union[torch.Tensor, torch.nn.Parameter]
23 + mod: torch.nn.Module, name: str, new: torch.Tensor | torch.nn.Parameter
24 ) -> None:
25 old = getattr(mod, name)
26 if (
vllm/model_executor/layers/quantization/utils/machete_utils.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -41,7 +40,7 @@ def query_machete_supported_group_sizes(act_type: torch.dtype) -> list[int]:
40
41 def check_machete_supports_shape(
42 in_features: int, out_featrues: int
44 -) -> tuple[bool, Optional[str]]:
43 +) -> tuple[bool, str | None]:
44 if in_features % MACHETE_PREPACKED_BLOCK_SHAPE[0] != 0:
45 return (
46 False,
vllm/model_executor/layers/quantization/utils/marlin_utils.py
+9 -10
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import numpy
6 import torch
@@ -34,9 +33,9 @@ USE_FP32_REDUCE_DEFAULT = True
33 # without runtime zero-point. We support common cases, i.e. AWQ and GPTQ.
34 # TODO: we may want to move this into the C++ so its closer to the actual impl
35 def query_marlin_supported_quant_types(
37 - has_zp: Optional[bool] = None,
36 + has_zp: bool | None = None,
37 include_fp_type: bool = True,
39 - device_capability: Optional[int] = None,
38 + device_capability: int | None = None,
39 ):
40 if device_capability is None:
41 capability_tuple = current_platform.get_device_capability()
@@ -72,10 +71,10 @@ def query_marlin_supported_quant_types(
71
72 def _check_marlin_supported(
73 quant_type: ScalarType,
75 - group_size: Optional[int],
74 + group_size: int | None,
75 has_zp: bool,
77 - device_capability: Optional[int] = None,
78 -) -> tuple[bool, Optional[str]]:
76 + device_capability: int | None = None,
77 +) -> tuple[bool, str | None]:
78 if device_capability is None:
79 capability_tuple = current_platform.get_device_capability()
80 device_capability = (
@@ -109,7 +108,7 @@ def check_marlin_supported(
108 quant_type: ScalarType,
109 group_size: int,
110 has_zp: bool = False,
112 - device_capability: Optional[int] = None,
111 + device_capability: int | None = None,
112 ) -> bool:
113 cond, _ = _check_marlin_supported(quant_type, group_size, has_zp, device_capability)
114 return cond
@@ -164,7 +163,7 @@ def check_marlin_supports_shape(
163 input_size_per_partition: int,
164 input_size: int,
165 group_size: int,
167 -) -> tuple[bool, Optional[str]]:
166 +) -> tuple[bool, str | None]:
167 try:
168 verify_marlin_supports_shape(
169 output_size_per_partition, input_size_per_partition, input_size, group_size
@@ -445,7 +444,7 @@ def apply_gptq_marlin_linear(
444 output_size_per_partition: int,
445 input_size_per_partition: int,
446 is_k_full: bool,
448 - bias: Optional[torch.Tensor] = None,
447 + bias: torch.Tensor | None = None,
448 use_fp32_reduce: bool = USE_FP32_REDUCE_DEFAULT,
449 ) -> torch.Tensor:
450 reshaped_x = input.reshape(-1, input.shape[-1])
@@ -494,7 +493,7 @@ def apply_awq_marlin_linear(
493 quant_type: ScalarType,
494 output_size_per_partition: int,
495 input_size_per_partition: int,
497 - bias: Optional[torch.Tensor] = None,
496 + bias: torch.Tensor | None = None,
497 use_fp32_reduce: bool = USE_FP32_REDUCE_DEFAULT,
498 ) -> torch.Tensor:
499 reshaped_x = input.reshape(-1, input.shape[-1])
vllm/model_executor/layers/quantization/utils/marlin_utils_fp4.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -95,11 +94,11 @@ def apply_fp4_marlin_linear(
94 input: torch.Tensor,
95 weight: torch.Tensor,
96 weight_scale: torch.Tensor,
98 - weight_scale_2: Optional[torch.Tensor],
97 + weight_scale_2: torch.Tensor | None,
98 workspace: torch.Tensor,
99 size_n: int,
100 size_k: int,
102 - bias: Optional[torch.Tensor] = None,
101 + bias: torch.Tensor | None = None,
102 use_fp32_reduce: bool = USE_FP32_REDUCE_DEFAULT,
103 ) -> torch.Tensor:
104 # For GPUs that lack FP4 hardware support, we can leverage the
vllm/model_executor/layers/quantization/utils/marlin_utils_fp8.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -45,7 +44,7 @@ def apply_fp8_marlin_linear(
44 workspace: torch.Tensor,
45 size_n: int,
46 size_k: int,
48 - bias: Optional[torch.Tensor],
47 + bias: torch.Tensor | None,
48 use_fp32_reduce: bool = USE_FP32_REDUCE_DEFAULT,
49 ) -> torch.Tensor:
50 # For GPUs that lack FP8 hardware support, we can leverage the
vllm/model_executor/layers/quantization/utils/marlin_utils_test.py
+1 -3
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Utility functions used for tests and benchmarks"""
4
5 -from typing import Optional
6 -
5 import numpy as np
6 import torch
7
@@ -100,7 +98,7 @@ def marlin_quantize(
98 quant_type: ScalarType,
99 group_size: int,
100 act_order: bool,
103 - test_perm: Optional[torch.Tensor] = None,
101 + test_perm: torch.Tensor | None = None,
102 ):
103 size_k, size_n = w.shape
104 num_bits = quant_type.size_bits
vllm/model_executor/layers/quantization/utils/mxfp4_utils.py
+10 -9
@@ -1,6 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, Callable, Optional
3 +from collections.abc import Callable
4 +from typing import Any
5
6 import torch
7
@@ -71,17 +72,17 @@ def _swizzle_mxfp4(quant_tensor, scale, num_warps):
72
73 def _can_support_mxfp4(
74 use_grouped_topk: bool = False,
74 - topk_group: Optional[int] = None,
75 - num_expert_group: Optional[int] = None,
76 - expert_map: Optional[torch.Tensor] = None,
77 - custom_routing_function: Optional[Callable] = None,
78 - e_score_correction_bias: Optional[torch.Tensor] = None,
75 + topk_group: int | None = None,
76 + num_expert_group: int | None = None,
77 + expert_map: torch.Tensor | None = None,
78 + custom_routing_function: Callable | None = None,
79 + e_score_correction_bias: torch.Tensor | None = None,
80 apply_router_weight_on_input: bool = False,
81 scoring_func: str = "softmax",
82 activation: str = "swigluoai",
82 - expert_load_view: Optional[torch.Tensor] = None,
83 - logical_to_physical_map: Optional[torch.Tensor] = None,
84 - logical_replica_count: Optional[torch.Tensor] = None,
83 + expert_load_view: torch.Tensor | None = None,
84 + logical_to_physical_map: torch.Tensor | None = None,
85 + logical_replica_count: torch.Tensor | None = None,
86 ):
87 return not (
88 use_grouped_topk
vllm/model_executor/layers/quantization/utils/ocp_mx_utils.py
+1 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from enum import Enum
4 -from typing import Union
4
5 from vllm.logger import init_logger
6
@@ -28,9 +27,7 @@ class OCP_MX_Scheme(str, Enum):
27 w_mxfp6_e2m3_a_mxfp6_e2m3 = "w_mxfp6_e2m3_a_mxfp6_e2m3"
28
29 @classmethod
31 - def from_quant_dtype(
32 - cls, input_dtype: Union[str, None], weight_dtype: Union[str, None]
33 - ):
30 + def from_quant_dtype(cls, input_dtype: str | None, weight_dtype: str | None):
31 if input_dtype not in OCP_MX_DTYPES or weight_dtype not in OCP_MX_DTYPES:
32 return None
33 elif input_dtype == "mxfp4" and weight_dtype == "mxfp4":
vllm/model_executor/layers/quantization/utils/petit_utils.py
+4 -4
@@ -43,8 +43,8 @@ _require_petit = _import_petit_kernel
43
44
45 def _check_petit_nvfp4_supported(
46 - quant_method: str, group_size: Optional[int]
47 -) -> tuple[bool, Optional[str]]:
46 + quant_method: str, group_size: int | None
47 +) -> tuple[bool, str | None]:
48 if quant_method != "NVFP4":
49 return (
50 False,
@@ -62,7 +62,7 @@ def _check_petit_nvfp4_supported(
62 return (True, None)
63
64
65 -def verify_petit_nvfp4_supported(quant_method: str, group_size: Optional[int]) -> None:
65 +def verify_petit_nvfp4_supported(quant_method: str, group_size: int | None) -> None:
66 supported, error_msg = _check_petit_nvfp4_supported(quant_method, group_size)
67 if not supported:
68 assert error_msg is not None
@@ -98,7 +98,7 @@ def apply_petit_nvfp4_linear(
98 weight_scale_2: torch.Tensor,
99 size_n: int,
100 size_k: int,
101 - bias: Optional[torch.Tensor] = None,
101 + bias: torch.Tensor | None = None,
102 ) -> torch.Tensor:
103 # Trigger (or get) the import here as well.
104 petit_kernel = _import_petit_kernel()
vllm/model_executor/layers/quantization/utils/quant_utils.py
+6 -6
@@ -5,7 +5,7 @@
5 from collections.abc import Mapping
6 from dataclasses import dataclass
7 from types import MappingProxyType
8 -from typing import ClassVar, NamedTuple, Optional
8 +from typing import ClassVar, NamedTuple
9
10 import numpy
11 import torch
@@ -91,7 +91,7 @@ class QuantKey:
91
92 dtype: torch.dtype
93 scale: ScaleDesc
94 - scale2: Optional[ScaleDesc] = None
94 + scale2: ScaleDesc | None = None
95 symmetric: bool = True
96
97 def __str__(self):
@@ -205,7 +205,7 @@ def scaled_quantize(
205 def scaled_dequantize(
206 x_q: torch.Tensor,
207 x_s: torch.Tensor,
208 - group_shape: Optional[GroupShape] = None,
208 + group_shape: GroupShape | None = None,
209 out_dtype: torch.dtype = torch.float32,
210 ) -> tuple[torch.Tensor, torch.Tensor]:
211 if group_shape is not None:
@@ -336,7 +336,7 @@ def permute_rows(
336 q_w: torch.Tensor,
337 w_ref: torch.Tensor,
338 group_size: int,
339 - test_perm: Optional[torch.Tensor] = None,
339 + test_perm: torch.Tensor | None = None,
340 ):
341 assert q_w.shape == w_ref.shape
342
@@ -365,7 +365,7 @@ def permute_rows(
365 def quantize_weights(
366 w: torch.Tensor,
367 quant_type: ScalarType,
368 - group_size: Optional[int],
368 + group_size: int | None,
369 zero_points: bool = False,
370 ref_zero_points_after_scales: bool = False,
371 ):
@@ -466,7 +466,7 @@ def gptq_quantize_weights(
466 quant_type: ScalarType,
467 group_size: int,
468 act_order: bool,
469 - test_perm: Optional[torch.Tensor] = None,
469 + test_perm: torch.Tensor | None = None,
470 ):
471 size_k, _ = w.shape
472
vllm/model_executor/layers/quantization/utils/w8a8_utils.py
+9 -9
@@ -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 Callable, Optional, Union
4 +from collections.abc import Callable
5
6 import torch
7 from packaging import version
@@ -75,7 +75,7 @@ CUTLASS_BLOCK_FP8_SUPPORTED = cutlass_block_fp8_supported()
75
76
77 def per_tensor_dequantize(
78 - tensor: torch.Tensor, inv_scale: Union[float, torch.Tensor]
78 + tensor: torch.Tensor, inv_scale: float | torch.Tensor
79 ) -> torch.Tensor:
80 fake_qweight = tensor.to(torch.float16)
81 dq_weight = fake_qweight * inv_scale
@@ -399,7 +399,7 @@ class Fp8LinearOp:
399 self,
400 act_quant_static: bool,
401 act_quant_group_shape: GroupShape = GroupShape.PER_TENSOR,
402 - pad_output: Optional[bool] = None,
402 + pad_output: bool | None = None,
403 ):
404 if current_platform.is_rocm():
405 self.preferred_backend = "rocm"
@@ -437,10 +437,10 @@ class Fp8LinearOp:
437 input: torch.Tensor,
438 weight: torch.Tensor,
439 weight_scale: torch.Tensor,
440 - out_dtype: Optional[torch.dtype] = None,
441 - input_scale: Optional[torch.Tensor] = None,
442 - input_scale_ub: Optional[torch.Tensor] = None,
443 - bias: Optional[torch.Tensor] = None,
440 + out_dtype: torch.dtype | None = None,
441 + input_scale: torch.Tensor | None = None,
442 + input_scale_ub: torch.Tensor | None = None,
443 + bias: torch.Tensor | None = None,
444 ) -> torch.Tensor:
445 # ops.scaled_fp8_quant supports both dynamic and static quant.
446 # If dynamic, layer.input_scale is None and x_scale computed from x.
@@ -486,8 +486,8 @@ class Fp8LinearOp:
486 def normalize_e4m3fn_to_e4m3fnuz(
487 weight: torch.Tensor,
488 weight_scale: torch.Tensor,
489 - input_scale: Optional[torch.Tensor] = None,
490 -) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
489 + input_scale: torch.Tensor | None = None,
490 +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
491 assert weight.dtype == torch.float8_e4m3fn
492 # The bits pattern 10000000(-128) represents zero in e4m3fn
493 # but NaN in e4m3fnuz. So here we set it to 0.
vllm/model_executor/layers/resampler.py
+9 -11
@@ -34,8 +34,8 @@ Example models: Qwen (Qwen-VL), MiniCPM-V 2.0
34 """
35
36 import math
37 +from collections.abc import Callable
38 from functools import partial
38 -from typing import Callable, Optional, Union
39
40 import numpy as np
41 import torch
@@ -48,9 +48,7 @@ from vllm.model_executor.layers.quantization import QuantizationConfig
48 DEFAULT_LN = partial(nn.LayerNorm, eps=1e-6)
49
50
51 -def get_abs_pos(
52 - abs_pos: torch.Tensor, tgt_size: Union[torch.Tensor, int]
53 -) -> torch.Tensor:
51 +def get_abs_pos(abs_pos: torch.Tensor, tgt_size: torch.Tensor | int) -> torch.Tensor:
52 # abs_pos: L, C
53 # tgt_size: (H, W)
54 # return: M, C
@@ -124,7 +122,7 @@ def get_2d_sincos_pos_embed_from_grid(
122
123 def get_2d_sincos_pos_embed(
124 embed_dim: int,
127 - grid_size: Union[int, tuple[int, int]],
125 + grid_size: int | tuple[int, int],
126 cls_token: bool = False,
127 version: tuple[int, int] = (2, 0),
128 ) -> torch.Tensor:
@@ -168,10 +166,10 @@ class BaseResampler(nn.Module):
166 num_queries: int,
167 embed_dim: int,
168 num_heads: int,
171 - kv_dim: Optional[int] = None,
169 + kv_dim: int | None = None,
170 norm_layer: Callable[[int], nn.LayerNorm] = DEFAULT_LN,
171 do_post_projection: bool = True,
174 - quant_config: Optional[QuantizationConfig] = None,
172 + quant_config: QuantizationConfig | None = None,
173 prefix: str = "",
174 ) -> None:
175 super().__init__()
@@ -222,11 +220,11 @@ class Resampler2(BaseResampler):
220 grid_size: int,
221 embed_dim: int,
222 num_heads: int,
225 - kv_dim: Optional[int] = None,
223 + kv_dim: int | None = None,
224 norm_layer: Callable[[int], nn.LayerNorm] = DEFAULT_LN,
225 adaptive: bool = False,
226 do_post_projection: bool = True,
229 - quant_config: Optional[QuantizationConfig] = None,
227 + quant_config: QuantizationConfig | None = None,
228 prefix: str = "",
229 ) -> None:
230 super().__init__(
@@ -250,8 +248,8 @@ class Resampler2(BaseResampler):
248 def forward(
249 self,
250 x: torch.Tensor,
253 - tgt_sizes: Optional[torch.Tensor] = None,
254 - attn_mask: Optional[torch.Tensor] = None,
251 + tgt_sizes: torch.Tensor | None = None,
252 + attn_mask: torch.Tensor | None = None,
253 ) -> torch.Tensor:
254 if tgt_sizes is None:
255 tgt_sizes = int(math.sqrt(x.size(1)))
vllm/model_executor/layers/rotary_embedding/__init__.py
+4 -4
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Rotary Positional Embeddings."""
4
5 -from typing import Any, Optional
5 +from typing import Any
6
7 import torch
8
@@ -28,10 +28,10 @@ def get_rope(
28 max_position: int,
29 base: float,
30 is_neox_style: bool = True,
31 - rope_scaling: Optional[dict[str, Any]] = None,
32 - dtype: Optional[torch.dtype] = None,
31 + rope_scaling: dict[str, Any] | None = None,
32 + dtype: torch.dtype | None = None,
33 partial_rotary_factor: float = 1.0,
34 - dual_chunk_attention_config: Optional[dict[str, Any]] = None,
34 + dual_chunk_attention_config: dict[str, Any] | None = None,
35 ) -> RotaryEmbedding:
36 if dtype is None:
37 dtype = torch.get_default_dtype()
vllm/model_executor/layers/rotary_embedding/base.py
+8 -10
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Rotary Positional Embeddings Base Class."""
4
5 -from typing import Optional
6 -
5 import torch
6
7 from vllm.model_executor.custom_op import CustomOp
@@ -92,8 +90,8 @@ class RotaryEmbedding(CustomOp):
90 self,
91 positions: torch.Tensor,
92 query: torch.Tensor,
95 - key: Optional[torch.Tensor] = None,
96 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
93 + key: torch.Tensor | None = None,
94 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
95 """A PyTorch-native implementation of forward()."""
96 positions = positions.flatten()
97 num_tokens = positions.shape[0]
@@ -121,8 +119,8 @@ class RotaryEmbedding(CustomOp):
119 self,
120 positions: torch.Tensor,
121 query: torch.Tensor,
124 - key: Optional[torch.Tensor] = None,
125 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
122 + key: torch.Tensor | None = None,
123 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
124 if self.use_flashinfer:
125 torch.ops.vllm.flashinfer_rotary_embedding(
126 positions,
@@ -154,8 +152,8 @@ class RotaryEmbedding(CustomOp):
152 self,
153 positions: torch.Tensor,
154 query: torch.Tensor,
157 - key: Optional[torch.Tensor] = None,
158 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
155 + key: torch.Tensor | None = None,
156 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
157 if self.is_rocm_triton_rotary_embedding_enabled:
158 self._match_cos_sin_cache_dtype(query)
159 rocm_aiter_rotary_emb(
@@ -177,8 +175,8 @@ class RotaryEmbedding(CustomOp):
175 self,
176 positions: torch.Tensor,
177 query: torch.Tensor,
180 - key: Optional[torch.Tensor] = None,
181 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
178 + key: torch.Tensor | None = None,
179 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
180 from vllm._ipex_ops import ipex_ops as ops
181
182 self._match_cos_sin_cache_dtype(query)
vllm/model_executor/layers/rotary_embedding/common.py
+2 -2
@@ -2,9 +2,9 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import math
5 +from collections.abc import Callable
6 from functools import cache
7 from importlib.util import find_spec
7 -from typing import Callable, Optional
8
9 import torch
10
@@ -72,7 +72,7 @@ def apply_rotary_emb_dispatch(
72
73 @cache
74 def dispatch_rotary_emb_function(
75 - default: Optional[Callable[..., torch.Tensor]] = None,
75 + default: Callable[..., torch.Tensor] | None = None,
76 ) -> Callable[..., torch.Tensor]:
77 if current_platform.is_cuda():
78 return apply_rotary_emb
vllm/model_executor/layers/rotary_embedding/deepseek_scaling_rope.py
+6 -7
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import math
5 -from typing import Optional
5
6 import torch
7
@@ -110,9 +109,9 @@ class DeepseekScalingRotaryEmbedding(RotaryEmbedding):
109 self,
110 positions: torch.Tensor,
111 query: torch.Tensor,
113 - key: Optional[torch.Tensor] = None,
114 - offsets: Optional[torch.Tensor] = None,
115 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
112 + key: torch.Tensor | None = None,
113 + offsets: torch.Tensor | None = None,
114 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
115 """PyTorch-native implementation equivalent to forward()."""
116 assert key is not None
117 self._match_cos_sin_cache_dtype(query)
@@ -151,7 +150,7 @@ class DeepseekScalingRotaryEmbedding(RotaryEmbedding):
150 self,
151 positions: torch.Tensor,
152 query: torch.Tensor,
154 - key: Optional[torch.Tensor] = None,
155 - offsets: Optional[torch.Tensor] = None,
156 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
153 + key: torch.Tensor | None = None,
154 + offsets: torch.Tensor | None = None,
155 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
156 return self.forward_native(positions, query, key, offsets)
vllm/model_executor/layers/rotary_embedding/dual_chunk_rope.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -121,7 +120,7 @@ class DualChunkRotaryEmbedding(CustomOp):
120 positions: torch.Tensor,
121 query: torch.Tensor,
122 key: torch.Tensor,
124 - offsets: Optional[torch.Tensor] = None,
123 + offsets: torch.Tensor | None = None,
124 ) -> tuple[torch.Tensor, torch.Tensor]:
125 query = query.view(*query.shape[:-1], -1, self.head_size)
126 key = key.view(*key.shape[:-1], -1, self.head_size)
@@ -185,7 +184,7 @@ class DualChunkRotaryEmbedding(CustomOp):
184 positions: torch.Tensor,
185 query: torch.Tensor,
186 key: torch.Tensor,
188 - offsets: Optional[torch.Tensor] = None,
187 + offsets: torch.Tensor | None = None,
188 ) -> tuple[torch.Tensor, torch.Tensor]:
189 return self.forward_native(positions, query, key, offsets)
190
vllm/model_executor/layers/rotary_embedding/ernie45_vl_rope.py
+4 -5
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -16,8 +15,8 @@ class Ernie4_5_VLRotaryEmbedding(MRotaryEmbedding):
15 self,
16 positions: torch.Tensor,
17 query: torch.Tensor,
19 - key: Optional[torch.Tensor] = None,
20 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
18 + key: torch.Tensor | None = None,
19 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
20 assert positions.ndim == 1 or positions.ndim == 2
21 assert key is not None
22
@@ -71,6 +70,6 @@ class Ernie4_5_VLRotaryEmbedding(MRotaryEmbedding):
70 self,
71 positions: torch.Tensor,
72 query: torch.Tensor,
74 - key: Optional[torch.Tensor] = None,
75 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
73 + key: torch.Tensor | None = None,
74 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
75 return self.forward_native(positions, query, key)
vllm/model_executor/layers/rotary_embedding/linear_scaling_rope.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Union
4
5 # Adapted from
6 # https://github.com/huggingface/transformers/blob/v4.33.2/src/transformers/models/llama/modeling_llama.py
@@ -65,7 +64,7 @@ class LinearScalingRotaryEmbedding(RotaryEmbedding):
64 max_position_embeddings: int,
65 base: float,
66 is_neox_style: bool,
68 - scaling_factors: Union[list[float], float],
67 + scaling_factors: list[float] | float,
68 dtype: torch.dtype,
69 ) -> None:
70 if isinstance(scaling_factors, float):
vllm/model_executor/layers/rotary_embedding/llama4_vision_rope.py
+4 -5
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import math
5 -from typing import Optional
5
6 import torch
7
@@ -56,8 +55,8 @@ class Llama4VisionRotaryEmbedding(RotaryEmbedding):
55 def forward_native( # type: ignore[override]
56 self,
57 query: torch.Tensor,
59 - key: Optional[torch.Tensor] = None,
60 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
58 + key: torch.Tensor | None = None,
59 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
60 assert key is not None
61 # self.cos_sin_cache here is complex tensor so we cannot cast into
62 # query's dtype directly with self._match_cos_sin_cache_dtype
@@ -76,6 +75,6 @@ class Llama4VisionRotaryEmbedding(RotaryEmbedding):
75 def forward_cuda( # type: ignore[override]
76 self,
77 query: torch.Tensor,
79 - key: Optional[torch.Tensor] = None,
80 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
78 + key: torch.Tensor | None = None,
79 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
80 return self.forward_native(query, key)
vllm/model_executor/layers/rotary_embedding/mrope.py
+19 -20
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import numpy as np
6 import torch
@@ -212,11 +211,11 @@ class MRotaryEmbedding(RotaryEmbedding):
211 base: float,
212 is_neox_style: bool,
213 dtype: torch.dtype,
215 - mrope_section: Optional[list[int]] = None,
214 + mrope_section: list[int] | None = None,
215 mrope_interleaved: bool = False,
216 # YaRN parameters.
217 *,
219 - scaling_factor: Optional[float] = None,
218 + scaling_factor: float | None = None,
219 extrapolation_factor: float = 1,
220 attn_factor: float = 1,
221 beta_fast: int = 32,
@@ -265,9 +264,9 @@ class MRotaryEmbedding(RotaryEmbedding):
264 self,
265 positions: torch.Tensor,
266 query: torch.Tensor,
268 - key: Optional[torch.Tensor] = None,
269 - offsets: Optional[torch.Tensor] = None,
270 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
267 + key: torch.Tensor | None = None,
268 + offsets: torch.Tensor | None = None,
269 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
270 """PyTorch-native implementation equivalent to forward().
271
272 Args:
@@ -318,9 +317,9 @@ class MRotaryEmbedding(RotaryEmbedding):
317 self,
318 positions: torch.Tensor,
319 query: torch.Tensor,
321 - key: Optional[torch.Tensor] = None,
322 - offsets: Optional[torch.Tensor] = None,
323 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
320 + key: torch.Tensor | None = None,
321 + offsets: torch.Tensor | None = None,
322 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
323 assert positions.ndim == 1 or positions.ndim == 2
324 assert key is not None
325
@@ -363,18 +362,18 @@ class MRotaryEmbedding(RotaryEmbedding):
362 self,
363 positions: torch.Tensor,
364 query: torch.Tensor,
366 - key: Optional[torch.Tensor] = None,
367 - offsets: Optional[torch.Tensor] = None,
368 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
365 + key: torch.Tensor | None = None,
366 + offsets: torch.Tensor | None = None,
367 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
368 return self.forward_native(positions, query, key, offsets)
369
370 def forward_cpu(
371 self,
372 positions: torch.Tensor,
373 query: torch.Tensor,
375 - key: Optional[torch.Tensor] = None,
376 - offsets: Optional[torch.Tensor] = None,
377 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
374 + key: torch.Tensor | None = None,
375 + offsets: torch.Tensor | None = None,
376 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
377 return self.forward_native(positions, query, key, offsets)
378
379 @classmethod
@@ -382,12 +381,12 @@ class MRotaryEmbedding(RotaryEmbedding):
381 cls,
382 input_tokens: list[int],
383 hf_config: PretrainedConfig,
385 - image_grid_thw: Optional[Union[list[list[int]], torch.Tensor]],
386 - video_grid_thw: Optional[Union[list[list[int]], torch.Tensor]],
387 - second_per_grid_ts: Optional[list[float]],
384 + image_grid_thw: list[list[int]] | torch.Tensor | None,
385 + video_grid_thw: list[list[int]] | torch.Tensor | None,
386 + second_per_grid_ts: list[float] | None,
387 context_len: int = 0,
389 - seq_len: Optional[int] = None,
390 - audio_feature_lengths: Optional[torch.Tensor] = None,
388 + seq_len: int | None = None,
389 + audio_feature_lengths: torch.Tensor | None = None,
390 use_audio_in_video: bool = False,
391 ) -> tuple[list[list[int]], int]:
392 """Get mrope input positions and delta value."""
vllm/model_executor/layers/rotary_embedding/ntk_scaling_rope.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6
@@ -21,7 +20,7 @@ class NTKScalingRotaryEmbedding(RotaryEmbedding):
20 is_neox_style: bool,
21 scaling_factor: float,
22 dtype: torch.dtype,
24 - mixed_b: Optional[float] = None,
23 + mixed_b: float | None = None,
24 ) -> None:
25 self.scaling_factor = scaling_factor
26 self.mixed_b = mixed_b
vllm/model_executor/layers/rotary_embedding/phi3_long_rope_scaled_rope.py
+5 -6
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import math
4 -from typing import Optional
4
5 import torch
6 import torch.nn as nn
@@ -26,8 +25,8 @@ class Phi3LongRoPEScaledRotaryEmbedding(nn.Module):
25 dtype: torch.dtype,
26 short_factor: list[float],
27 long_factor: list[float],
29 - short_mscale: Optional[float] = None,
30 - long_mscale: Optional[float] = None,
28 + short_mscale: float | None = None,
29 + long_mscale: float | None = None,
30 ):
31 super().__init__()
32
@@ -106,9 +105,9 @@ class Phi3LongRoPEScaledRotaryEmbedding(nn.Module):
105 self,
106 positions: torch.Tensor,
107 query: torch.Tensor,
109 - key: Optional[torch.Tensor] = None,
110 - offsets: Optional[torch.Tensor] = None,
111 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
108 + key: torch.Tensor | None = None,
109 + offsets: torch.Tensor | None = None,
110 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
111 assert key is not None
112 query = query.view(*query.shape[:-1], -1, self.head_size)
113 key = key.view(*key.shape[:-1], -1, self.head_size)
vllm/model_executor/layers/utils.py
+6 -6
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Utility methods for model layers."""
4
5 -from typing import Callable, Optional
5 +from collections.abc import Callable
6
7 import torch
8
@@ -95,13 +95,13 @@ def default_unquantized_gemm(
95 layer: torch.nn.Module,
96 x: torch.Tensor,
97 weight: torch.Tensor,
98 - bias: Optional[torch.Tensor] = None,
98 + bias: torch.Tensor | None = None,
99 ):
100 return torch.nn.functional.linear(x, weight, bias)
101
102
103 def rocm_unquantized_gemm_impl(
104 - x: torch.Tensor, weight: torch.Tensor, bias: Optional[torch.Tensor] = None
104 + x: torch.Tensor, weight: torch.Tensor, bias: torch.Tensor | None = None
105 ) -> torch.Tensor:
106 from vllm.platforms.rocm import on_gfx9
107
@@ -131,7 +131,7 @@ def rocm_unquantized_gemm_impl(
131
132
133 def rocm_unquantized_gemm_impl_fake(
134 - x: torch.Tensor, weight: torch.Tensor, bias: Optional[torch.Tensor] = None
134 + x: torch.Tensor, weight: torch.Tensor, bias: torch.Tensor | None = None
135 ) -> torch.Tensor:
136 return x.new_empty((*x.shape[:-1], weight.shape[0]))
137
@@ -140,7 +140,7 @@ def rocm_unquantized_gemm(
140 layer: torch.nn.Module,
141 x: torch.Tensor,
142 weight: torch.Tensor,
143 - bias: Optional[torch.Tensor] = None,
143 + bias: torch.Tensor | None = None,
144 ) -> torch.Tensor:
145 return torch.ops.vllm.rocm_unquantized_gemm_impl(x, weight, bias)
146
@@ -197,7 +197,7 @@ def cpu_unquantized_gemm(
197 layer: torch.nn.Module,
198 x: torch.Tensor,
199 weight: torch.Tensor,
200 - bias: Optional[torch.Tensor] = None,
200 + bias: torch.Tensor | None = None,
201 ):
202 return layer.cpu_linear(x, weight, bias)
203
vllm/model_executor/layers/vocab_parallel_embedding.py
+8 -9
@@ -3,7 +3,6 @@
3
4 from collections.abc import Sequence
5 from dataclasses import dataclass
6 -from typing import Optional
6
7 import torch
8 import torch.nn.functional as F
@@ -65,7 +64,7 @@ class UnquantizedEmbeddingMethod(QuantizeMethodBase):
64 self,
65 layer: torch.nn.Module,
66 x: torch.Tensor,
68 - bias: Optional[torch.Tensor] = None,
67 + bias: torch.Tensor | None = None,
68 ) -> torch.Tensor:
69 return dispatch_unquantized_gemm()(layer, x, layer.weight, bias)
70
@@ -226,10 +225,10 @@ class VocabParallelEmbedding(CustomOp):
225 self,
226 num_embeddings: int,
227 embedding_dim: int,
229 - params_dtype: Optional[torch.dtype] = None,
230 - org_num_embeddings: Optional[int] = None,
228 + params_dtype: torch.dtype | None = None,
229 + org_num_embeddings: int | None = None,
230 padding_size: int = DEFAULT_VOCAB_PADDING_SIZE,
232 - quant_config: Optional[QuantizationConfig] = None,
231 + quant_config: QuantizationConfig | None = None,
232 prefix: str = "",
233 ):
234 super().__init__()
@@ -347,7 +346,7 @@ class VocabParallelEmbedding(CustomOp):
346 added_vocab_end_index,
347 )
348
350 - def get_sharded_to_full_mapping(self) -> Optional[list[int]]:
349 + def get_sharded_to_full_mapping(self) -> list[int] | None:
350 """Get a mapping that can be used to reindex the gathered
351 logits for sampling.
352
@@ -515,10 +514,10 @@ class ParallelLMHead(VocabParallelEmbedding):
514 num_embeddings: int,
515 embedding_dim: int,
516 bias: bool = False,
518 - params_dtype: Optional[torch.dtype] = None,
519 - org_num_embeddings: Optional[int] = None,
517 + params_dtype: torch.dtype | None = None,
518 + org_num_embeddings: int | None = None,
519 padding_size: int = DEFAULT_VOCAB_PADDING_SIZE,
521 - quant_config: Optional[QuantizationConfig] = None,
520 + quant_config: QuantizationConfig | None = None,
521 prefix: str = "",
522 ):
523 super().__init__(
vllm/model_executor/model_loader/__init__.py
+2 -2
@@ -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 Literal, Optional
4 +from typing import Literal
5
6 from torch import nn
7
@@ -122,7 +122,7 @@ def get_model_loader(load_config: LoadConfig) -> BaseModelLoader:
122
123
124 def get_model(
125 - *, vllm_config: VllmConfig, model_config: Optional[ModelConfig] = None
125 + *, vllm_config: VllmConfig, model_config: ModelConfig | None = None
126 ) -> nn.Module:
127 loader = get_model_loader(vllm_config.load_config)
128 if model_config is None:
vllm/model_executor/model_loader/bitsandbytes_loader.py
+5 -5
@@ -6,8 +6,8 @@ import glob
6 import itertools
7 import math
8 import os
9 -from collections.abc import Generator
10 -from typing import Any, Callable, Optional
9 +from collections.abc import Callable, Generator
10 +from typing import Any
11
12 import numpy as np
13 import torch
@@ -88,7 +88,7 @@ class BitsAndBytesModelLoader(BaseModelLoader):
88 self,
89 model_name_or_path: str,
90 allowed_patterns: list[str],
91 - revision: Optional[str] = None,
91 + revision: str | None = None,
92 ) -> tuple[str, list[str], str]:
93 """Retrieve weight files. Download the files if necessary.
94
@@ -122,7 +122,7 @@ class BitsAndBytesModelLoader(BaseModelLoader):
122 raise RuntimeError(f"No model weights found in: `{model_name_or_path}`")
123
124 def _prepare_weights(
125 - self, model_name_or_path: str, revision: Optional[str]
125 + self, model_name_or_path: str, revision: str | None
126 ) -> tuple[list[str], bool]:
127 """Prepare weight files for the model."""
128
@@ -196,7 +196,7 @@ class BitsAndBytesModelLoader(BaseModelLoader):
196 def _get_quantized_weights_iterator(
197 self,
198 model_name_or_path: str,
199 - revision: Optional[str],
199 + revision: str | None,
200 ) -> tuple[Generator[tuple[str, torch.Tensor], None, None], dict[str, Any]]:
201 """Get an iterator to the model weights with bitsandbytes quantization,
202 as well as the quantization state dictionary."""
vllm/model_executor/model_loader/default_loader.py
+5 -5
@@ -5,7 +5,7 @@ import glob
5 import os
6 import time
7 from collections.abc import Generator, Iterable
8 -from typing import Optional, cast
8 +from typing import cast
9
10 import torch
11 from torch import nn
@@ -47,7 +47,7 @@ class DefaultModelLoader(BaseModelLoader):
47 model_or_path: str
48 """The model ID or path."""
49
50 - revision: Optional[str]
50 + revision: str | None
51 """The optional model revision."""
52
53 prefix: str = ""
@@ -56,7 +56,7 @@ class DefaultModelLoader(BaseModelLoader):
56 fall_back_to_pt: bool = True
57 """Whether .pt weights can be used."""
58
59 - allow_patterns_overrides: Optional[list[str]] = None
59 + allow_patterns_overrides: list[str] | None = None
60 """If defined, weights will load exclusively using these patterns."""
61
62 counter_before_loading_weights: float = 0.0
@@ -79,9 +79,9 @@ class DefaultModelLoader(BaseModelLoader):
79 def _prepare_weights(
80 self,
81 model_name_or_path: str,
82 - revision: Optional[str],
82 + revision: str | None,
83 fall_back_to_pt: bool,
84 - allow_patterns_overrides: Optional[list[str]],
84 + allow_patterns_overrides: list[str] | None,
85 ) -> tuple[str, list[str], bool]:
86 """Prepare weights for the model.
87
vllm/model_executor/model_loader/runai_streamer_loader.py
+1 -2
@@ -3,7 +3,6 @@
3 # ruff: noqa: SIM117
4 import os
5 from collections.abc import Generator
6 -from typing import Optional
6
7 import torch
8 from torch import nn
@@ -51,7 +50,7 @@ class RunaiModelStreamerLoader(BaseModelLoader):
50 os.environ["RUNAI_STREAMER_S3_ENDPOINT"] = aws_endpoint_url
51
52 def _prepare_weights(
54 - self, model_name_or_path: str, revision: Optional[str]
53 + self, model_name_or_path: str, revision: str | None
54 ) -> list[str]:
55 """Prepare weights for the model.
56
vllm/model_executor/model_loader/sharded_state_loader.py
+4 -4
@@ -5,7 +5,7 @@ import collections
5 import glob
6 import os
7 from collections.abc import Generator
8 -from typing import Any, Optional
8 +from typing import Any
9
10 import torch
11 from torch import nn
@@ -89,7 +89,7 @@ class ShardedStateLoader(BaseModelLoader):
89 result[k] = t
90 return result
91
92 - def _prepare_weights(self, model_name_or_path: str, revision: Optional[str]):
92 + def _prepare_weights(self, model_name_or_path: str, revision: str | None):
93 if is_s3(model_name_or_path) or os.path.isdir(model_name_or_path):
94 return model_name_or_path
95 else:
@@ -171,8 +171,8 @@ class ShardedStateLoader(BaseModelLoader):
171 def save_model(
172 model: torch.nn.Module,
173 path: str,
174 - pattern: Optional[str] = None,
175 - max_size: Optional[int] = None,
174 + pattern: str | None = None,
175 + max_size: int | None = None,
176 ) -> None:
177 from safetensors.torch import save_file
178
vllm/model_executor/model_loader/tensorizer.py
+23 -25
@@ -12,7 +12,7 @@ import threading
12 import time
13 from collections.abc import Generator, MutableMapping
14 from dataclasses import asdict, dataclass, field, fields
15 -from typing import TYPE_CHECKING, Any, ClassVar, Optional, Union
15 +from typing import TYPE_CHECKING, Any, ClassVar, Optional
16
17 import regex as re
18 import torch
@@ -67,7 +67,7 @@ __all__ = [
67 logger = init_logger(__name__)
68
69
70 -def is_valid_deserialization_uri(uri: Optional[str]) -> bool:
70 +def is_valid_deserialization_uri(uri: str | None) -> bool:
71 if uri:
72 scheme = uri.lower().split("://")[0]
73 return scheme in {"s3", "http", "https"} or os.path.exists(uri)
@@ -156,25 +156,23 @@ class _NoInitOrTensorImpl:
156
157 @dataclass
158 class TensorizerConfig(MutableMapping):
159 - tensorizer_uri: Optional[str] = None
160 - tensorizer_dir: Optional[str] = None
161 - vllm_tensorized: Optional[bool] = None
162 - verify_hash: Optional[bool] = None
163 - num_readers: Optional[int] = None
164 - encryption_keyfile: Optional[str] = None
165 - s3_access_key_id: Optional[str] = None
166 - s3_secret_access_key: Optional[str] = None
167 - s3_endpoint: Optional[str] = None
168 - lora_dir: Optional[str] = None
169 - stream_kwargs: Optional[dict[str, Any]] = None
170 - serialization_kwargs: Optional[dict[str, Any]] = None
171 - deserialization_kwargs: Optional[dict[str, Any]] = None
172 - _extra_serialization_attrs: Optional[dict[str, Any]] = field(
173 - init=False, default=None
174 - )
175 - model_class: Optional[type[torch.nn.Module]] = field(init=False, default=None)
176 - hf_config: Optional[PretrainedConfig] = field(init=False, default=None)
177 - dtype: Optional[Union[str, torch.dtype]] = field(init=False, default=None)
159 + tensorizer_uri: str | None = None
160 + tensorizer_dir: str | None = None
161 + vllm_tensorized: bool | None = None
162 + verify_hash: bool | None = None
163 + num_readers: int | None = None
164 + encryption_keyfile: str | None = None
165 + s3_access_key_id: str | None = None
166 + s3_secret_access_key: str | None = None
167 + s3_endpoint: str | None = None
168 + lora_dir: str | None = None
169 + stream_kwargs: dict[str, Any] | None = None
170 + serialization_kwargs: dict[str, Any] | None = None
171 + deserialization_kwargs: dict[str, Any] | None = None
172 + _extra_serialization_attrs: dict[str, Any] | None = field(init=False, default=None)
173 + model_class: type[torch.nn.Module] | None = field(init=False, default=None)
174 + hf_config: PretrainedConfig | None = field(init=False, default=None)
175 + dtype: str | torch.dtype | None = field(init=False, default=None)
176 _is_sharded: bool = field(init=False, default=False)
177 _fields: ClassVar[tuple[str, ...]]
178 _keys: ClassVar[frozenset[str]]
@@ -362,9 +360,9 @@ TensorizerConfig._keys = frozenset(TensorizerConfig._fields)
360
361 @dataclass
362 class TensorizerArgs:
365 - tensorizer_uri: Optional[str] = None
366 - tensorizer_dir: Optional[str] = None
367 - encryption_keyfile: Optional[str] = None
363 + tensorizer_uri: str | None = None
364 + tensorizer_dir: str | None = None
365 + encryption_keyfile: str | None = None
366
367 def __init__(self, tensorizer_config: TensorizerConfig):
368 for k, v in tensorizer_config.items():
@@ -621,7 +619,7 @@ def is_vllm_tensorized(tensorizer_config: "TensorizerConfig") -> bool:
619
620
621 def serialize_extra_artifacts(
624 - tensorizer_args: TensorizerArgs, served_model_name: Union[str, list[str], None]
622 + tensorizer_args: TensorizerArgs, served_model_name: str | list[str] | None
623 ) -> None:
624 if not isinstance(served_model_name, str):
625 raise ValueError(
vllm/model_executor/model_loader/tensorizer_loader.py
+1 -2
@@ -3,7 +3,6 @@
3 # ruff: noqa: SIM117
4 import copy
5 from collections.abc import Generator
6 -from typing import Union
6
7 import torch
8 from torch import nn
@@ -140,7 +139,7 @@ class TensorizerLoader(BaseModelLoader):
139 @staticmethod
140 def save_model(
141 model: torch.nn.Module,
143 - tensorizer_config: Union[TensorizerConfig, dict],
142 + tensorizer_config: TensorizerConfig | dict,
143 model_config: ModelConfig,
144 ) -> None:
145 if isinstance(tensorizer_config, dict):
vllm/model_executor/model_loader/tpu.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import time
4 -from typing import Optional
4
5 import torch
6 import torch.nn as nn
@@ -30,7 +29,7 @@ class TPUModelLoader(DefaultModelLoader):
29 self,
30 vllm_config: VllmConfig,
31 model_config: ModelConfig,
33 - mesh: Optional[xs.Mesh] = None,
32 + mesh: xs.Mesh | None = None,
33 ) -> nn.Module:
34 # Initialize model and load weights on CPU. Then, during SPMD partition,
35 # weights are sharded and transferred to TPUs.
@@ -90,7 +89,7 @@ class TPUModelLoader(DefaultModelLoader):
89 )
90 return model
91
93 - def _check_model_is_loaded(self, mesh: Optional[xs.Mesh], model: nn.Module) -> None:
92 + def _check_model_is_loaded(self, mesh: xs.Mesh | None, model: nn.Module) -> None:
93 """
94 Ensure the model is properly loaded.
95 1. All model parameters and buffers are on XLA device.
vllm/model_executor/model_loader/utils.py
+3 -4
@@ -7,7 +7,6 @@ import inspect
7 import warnings
8 from contextlib import contextmanager
9 from dataclasses import dataclass, field
10 -from typing import Optional
10
11 import torch
12 from torch import nn
@@ -46,8 +45,8 @@ def initialize_model(
45 vllm_config: VllmConfig,
46 *,
47 prefix: str = "",
49 - model_class: Optional[type[nn.Module]] = None,
50 - model_config: Optional[ModelConfig] = None,
48 + model_class: type[nn.Module] | None = None,
49 + model_config: ModelConfig | None = None,
50 ) -> nn.Module:
51 """Initialize a model with the given configurations."""
52 if model_config is None:
@@ -268,7 +267,7 @@ class ParamMapping:
267 index,
268 )
269
271 - def get_sub_modules(self, module_name: str) -> Optional[tuple[str, list[str]]]:
270 + def get_sub_modules(self, module_name: str) -> tuple[str, list[str]] | None:
271 for key, value in self.packed_mapping.items():
272 if module_name.endswith(key):
273 return key, value
vllm/model_executor/model_loader/weight_utils.py
+18 -18
@@ -11,10 +11,10 @@ import os
11 import tempfile
12 import time
13 from collections import defaultdict
14 -from collections.abc import Generator
14 +from collections.abc import Callable, Generator
15 from contextlib import contextmanager
16 from pathlib import Path
17 -from typing import IO, Any, Callable, Optional, Union
17 +from typing import IO, Any
18
19 import filelock
20 import huggingface_hub.constants
@@ -85,7 +85,7 @@ class DisabledTqdm(tqdm):
85 super().__init__(*args, **kwargs, disable=True)
86
87
88 -def get_lock(model_name_or_path: Union[str, Path], cache_dir: Optional[str] = None):
88 +def get_lock(model_name_or_path: str | Path, cache_dir: str | None = None):
89 lock_dir = cache_dir or temp_dir
90 model_name_or_path = str(model_name_or_path)
91 os.makedirs(os.path.dirname(lock_dir), exist_ok=True)
@@ -100,7 +100,7 @@ def get_lock(model_name_or_path: Union[str, Path], cache_dir: Optional[str] = No
100
101 @contextmanager
102 def atomic_writer(
103 - filepath: Union[str, Path], mode: str = "w", encoding: Optional[str] = None
103 + filepath: str | Path, mode: str = "w", encoding: str | None = None
104 ) -> Generator[IO]:
105 """
106 Context manager that provides an atomic file writing routine.
@@ -143,11 +143,11 @@ def atomic_writer(
143
144 def maybe_download_from_modelscope(
145 model: str,
146 - revision: Optional[str] = None,
147 - download_dir: Optional[str] = None,
148 - ignore_patterns: Optional[Union[str, list[str]]] = None,
149 - allow_patterns: Optional[Union[list[str], str]] = None,
150 -) -> Optional[str]:
146 + revision: str | None = None,
147 + download_dir: str | None = None,
148 + ignore_patterns: str | list[str] | None = None,
149 + allow_patterns: list[str] | str | None = None,
150 +) -> str | None:
151 """Download model from ModelScope hub if VLLM_USE_MODELSCOPE is True.
152
153 Returns the path to the downloaded model, or None if the model is not
@@ -370,10 +370,10 @@ def get_sparse_attention_config(
370
371 def download_weights_from_hf(
372 model_name_or_path: str,
373 - cache_dir: Optional[str],
373 + cache_dir: str | None,
374 allow_patterns: list[str],
375 - revision: Optional[str] = None,
376 - ignore_patterns: Optional[Union[str, list[str]]] = None,
375 + revision: str | None = None,
376 + ignore_patterns: str | list[str] | None = None,
377 ) -> str:
378 """Download model weights from Hugging Face Hub.
379
@@ -448,8 +448,8 @@ def download_weights_from_hf(
448 def download_safetensors_index_file_from_hf(
449 model_name_or_path: str,
450 index_file: str,
451 - cache_dir: Optional[str],
452 - revision: Optional[str] = None,
451 + cache_dir: str | None,
452 + revision: str | None = None,
453 ) -> None:
454 """Download hf safetensors index file from Hugging Face Hub.
455
@@ -540,7 +540,7 @@ def enable_tqdm(use_tqdm_on_load: bool):
540
541 def np_cache_weights_iterator(
542 model_name_or_path: str,
543 - cache_dir: Optional[str],
543 + cache_dir: str | None,
544 hf_folder: str,
545 hf_weights_files: list[str],
546 use_tqdm_on_load: bool,
@@ -746,7 +746,7 @@ def fastsafetensors_weights_iterator(
746 def pt_weights_iterator(
747 hf_weights_files: list[str],
748 use_tqdm_on_load: bool,
749 - pt_load_map_location: Union[str, dict[str, str]] = "cpu",
749 + pt_load_map_location: str | dict[str, str] = "cpu",
750 ) -> Generator[tuple[str, torch.Tensor], None, None]:
751 """Iterate over the weights in the model bin/pt files."""
752 for bin_file in tqdm(
@@ -765,7 +765,7 @@ def pt_weights_iterator(
765 def multi_thread_pt_weights_iterator(
766 hf_weights_files: list[str],
767 use_tqdm_on_load: bool,
768 - pt_load_map_location: Union[str, dict[str, str]] = "cpu",
768 + pt_load_map_location: str | dict[str, str] = "cpu",
769 max_workers: int = 4,
770 ) -> Generator[tuple[str, torch.Tensor], None, None]:
771 """Multi-Thread iterate over the weights in the model bin/pt files."""
@@ -985,7 +985,7 @@ def initialize_dummy_weights(
985 param.uniform_(low, high, generator=generator)
986
987
988 -def maybe_remap_kv_scale_name(name: str, params_dict: dict) -> Optional[str]:
988 +def maybe_remap_kv_scale_name(name: str, params_dict: dict) -> str | None:
989 """Remap the name of FP8 k/v_scale parameters.
990
991 This function handles the remapping of FP8 k/v_scale parameter names.
vllm/model_executor/models/adapters.py
+4 -4
@@ -4,7 +4,7 @@
4 import ast
5 import inspect
6 from collections.abc import Iterable
7 -from typing import TYPE_CHECKING, Any, Optional, TypeVar, cast
7 +from typing import TYPE_CHECKING, Any, TypeVar, cast
8
9 import torch
10 import torch.nn as nn
@@ -32,7 +32,7 @@ _GENERATE_SUFFIXES = [
32 ]
33
34
35 -def _load_st_projector(model_config: "ModelConfig") -> Optional[nn.Module]:
35 +def _load_st_projector(model_config: "ModelConfig") -> nn.Module | None:
36 """Load Sentence-Transformers Dense projection layers."""
37
38 try:
@@ -357,8 +357,8 @@ def as_seq_cls_model(cls: _T) -> _T:
357 self,
358 input_ids: torch.Tensor,
359 positions: torch.Tensor,
360 - intermediate_tensors: Optional[IntermediateTensors] = None,
361 - inputs_embeds: Optional[torch.Tensor] = None,
360 + intermediate_tensors: IntermediateTensors | None = None,
361 + inputs_embeds: torch.Tensor | None = None,
362 ) -> torch.Tensor:
363 return super().forward(
364 input_ids, positions, intermediate_tensors, inputs_embeds
vllm/model_executor/models/aimv2.py
+2 -3
@@ -4,7 +4,6 @@
4 # A modified implementation of the AIMv2 Transformer
5 # inserted here also the image tokenizer used by Ovis2
6 from collections.abc import Iterable
7 -from typing import Optional
7
8 import torch
9 import torch.nn as nn
@@ -165,7 +164,7 @@ class AIMv2Transformer(nn.Module):
164 config: AIMv2Config,
165 quant_config: QuantizationConfig,
166 *,
168 - require_post_norm: Optional[bool] = None,
167 + require_post_norm: bool | None = None,
168 prefix: str = "",
169 ):
170 super().__init__()
@@ -196,7 +195,7 @@ class AIMv2Model(torch.nn.Module):
195 config: AIMv2Config,
196 quant_config: QuantizationConfig,
197 *,
199 - require_post_norm: Optional[bool] = None,
198 + require_post_norm: bool | None = None,
199 prefix: str = "",
200 ):
201 super().__init__()
vllm/model_executor/models/apertus.py
+18 -20
@@ -27,7 +27,7 @@
27
28 from collections.abc import Iterable
29 from itertools import islice
30 -from typing import Any, Optional, Union
30 +from typing import Any
31
32 import torch
33 from torch import nn
@@ -77,7 +77,7 @@ class ApertusMLP(nn.Module):
77 hidden_size: int,
78 intermediate_size: int,
79 hidden_act: str,
80 - quant_config: Optional[QuantizationConfig] = None,
80 + quant_config: QuantizationConfig | None = None,
81 bias: bool = False,
82 prefix: str = "",
83 reduce_results: bool = True,
@@ -120,12 +120,12 @@ class ApertusAttention(nn.Module):
120 num_heads: int,
121 num_kv_heads: int,
122 rope_theta: float = 10000,
123 - rope_scaling: Optional[dict[str, Any]] = None,
123 + rope_scaling: dict[str, Any] | None = None,
124 max_position_embeddings: int = 8192,
125 - quant_config: Optional[QuantizationConfig] = None,
125 + quant_config: QuantizationConfig | None = None,
126 bias: bool = False,
127 bias_o_proj: bool = False,
128 - cache_config: Optional[CacheConfig] = None,
128 + cache_config: CacheConfig | None = None,
129 prefix: str = "",
130 attn_type: str = AttentionType.DECODER,
131 ) -> None:
@@ -225,8 +225,8 @@ class ApertusAttention(nn.Module):
225 def _init_rotary_emb(
226 self,
227 config: ApertusConfig,
228 - rope_scaling: Optional[dict[str, Any]],
229 - quant_config: Optional[QuantizationConfig],
228 + rope_scaling: dict[str, Any] | None,
229 + quant_config: QuantizationConfig | None,
230 ) -> None:
231 is_neox_style = True
232 is_gguf = quant_config and quant_config.get_name() == "gguf"
@@ -248,8 +248,8 @@ class ApertusDecoderLayer(nn.Module):
248 def __init__(
249 self,
250 config: ApertusConfig,
251 - cache_config: Optional[CacheConfig] = None,
252 - quant_config: Optional[QuantizationConfig] = None,
251 + cache_config: CacheConfig | None = None,
252 + quant_config: QuantizationConfig | None = None,
253 prefix: str = "",
254 ) -> None:
255 super().__init__()
@@ -316,7 +316,7 @@ class ApertusDecoderLayer(nn.Module):
316 self,
317 positions: torch.Tensor,
318 hidden_states: torch.Tensor,
319 - residual: Optional[torch.Tensor],
319 + residual: torch.Tensor | None,
320 ) -> tuple[torch.Tensor, torch.Tensor]:
321 # Self Attention
322 if residual is None:
@@ -394,13 +394,11 @@ class ApertusModel(nn.Module):
394
395 def forward(
396 self,
397 - input_ids: Optional[torch.Tensor],
397 + input_ids: torch.Tensor | None,
398 positions: torch.Tensor,
399 - intermediate_tensors: Optional[IntermediateTensors],
400 - inputs_embeds: Optional[torch.Tensor] = None,
401 - ) -> Union[
402 - torch.Tensor, IntermediateTensors, tuple[torch.Tensor, list[torch.Tensor]]
403 - ]:
399 + intermediate_tensors: IntermediateTensors | None,
400 + inputs_embeds: torch.Tensor | None = None,
401 + ) -> torch.Tensor | IntermediateTensors | tuple[torch.Tensor, list[torch.Tensor]]:
402 if get_pp_group().is_first_rank:
403 if inputs_embeds is not None:
404 hidden_states = inputs_embeds
@@ -586,9 +584,9 @@ class ApertusForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
584 self,
585 input_ids: torch.Tensor,
586 positions: torch.Tensor,
589 - intermediate_tensors: Optional[IntermediateTensors] = None,
590 - inputs_embeds: Optional[torch.Tensor] = None,
591 - ) -> Union[torch.Tensor, IntermediateTensors]:
587 + intermediate_tensors: IntermediateTensors | None = None,
588 + inputs_embeds: torch.Tensor | None = None,
589 + ) -> torch.Tensor | IntermediateTensors:
590 model_output = self.model(
591 input_ids, positions, intermediate_tensors, inputs_embeds
592 )
@@ -597,7 +595,7 @@ class ApertusForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
595 def compute_logits(
596 self,
597 hidden_states: torch.Tensor,
600 - ) -> Optional[torch.Tensor]:
598 + ) -> torch.Tensor | None:
599 logits = self.logits_processor(self.lm_head, hidden_states)
600 return logits
601
vllm/model_executor/models/arcee.py
+13 -15
@@ -10,7 +10,7 @@
10
11 from collections.abc import Iterable
12 from itertools import islice
13 -from typing import Any, Optional, Union
13 +from typing import Any
14
15 import torch
16 from torch import nn
@@ -52,7 +52,7 @@ class ArceeMLP(nn.Module):
52 hidden_size: int,
53 intermediate_size: int,
54 hidden_act: str,
55 - quant_config: Optional[Any] = None,
55 + quant_config: Any | None = None,
56 bias: bool = False,
57 prefix: str = "",
58 reduce_results: bool = True,
@@ -98,8 +98,8 @@ class ArceeDecoderLayer(nn.Module):
98 def __init__(
99 self,
100 config: LlamaConfig,
101 - cache_config: Optional[Any] = None,
102 - quant_config: Optional[Any] = None,
101 + cache_config: Any | None = None,
102 + quant_config: Any | None = None,
103 prefix: str = "",
104 ) -> None:
105 super().__init__()
@@ -165,7 +165,7 @@ class ArceeDecoderLayer(nn.Module):
165 self,
166 positions: torch.Tensor,
167 hidden_states: torch.Tensor,
168 - residual: Optional[torch.Tensor],
168 + residual: torch.Tensor | None,
169 ) -> tuple[torch.Tensor, torch.Tensor]:
170 # Self-Attention block
171 if residual is None:
@@ -247,13 +247,11 @@ class ArceeModel(nn.Module):
247
248 def forward(
249 self,
250 - input_ids: Optional[torch.Tensor],
250 + input_ids: torch.Tensor | None,
251 positions: torch.Tensor,
252 - intermediate_tensors: Optional[IntermediateTensors],
253 - inputs_embeds: Optional[torch.Tensor] = None,
254 - ) -> Union[
255 - torch.Tensor, IntermediateTensors, tuple[torch.Tensor, list[torch.Tensor]]
256 - ]:
252 + intermediate_tensors: IntermediateTensors | None,
253 + inputs_embeds: torch.Tensor | None = None,
254 + ) -> torch.Tensor | IntermediateTensors | tuple[torch.Tensor, list[torch.Tensor]]:
255 # Embedding lookup (on first pipeline rank)
256 if get_pp_group().is_first_rank:
257 hidden_states = (
@@ -415,9 +413,9 @@ class ArceeForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
413 self,
414 input_ids: torch.Tensor,
415 positions: torch.Tensor,
418 - intermediate_tensors: Optional[IntermediateTensors] = None,
419 - inputs_embeds: Optional[torch.Tensor] = None,
420 - ) -> Union[torch.Tensor, IntermediateTensors]:
416 + intermediate_tensors: IntermediateTensors | None = None,
417 + inputs_embeds: torch.Tensor | None = None,
418 + ) -> torch.Tensor | IntermediateTensors:
419 model_output = self.model(
420 input_ids=input_ids,
421 positions=positions,
@@ -426,7 +424,7 @@ class ArceeForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
424 )
425 return model_output
426
429 - def compute_logits(self, hidden_states: torch.Tensor) -> Optional[torch.Tensor]:
427 + def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None:
428 # Compute final logits from hidden states (last pipeline rank only)
429 logits = self.logits_processor(self.lm_head, hidden_states)
430 return logits
vllm/model_executor/models/arctic.py
+15 -16
@@ -4,7 +4,6 @@
4
5 from collections.abc import Iterable
6 from itertools import islice
7 -from typing import Optional, Union
7
8 import torch
9 from torch import nn
@@ -63,7 +62,7 @@ class ArcticMLP(nn.Module):
62 config: ArcticConfig,
63 expert_id: int = -1,
64 is_residual_mlp: bool = False,
66 - quant_config: Optional[QuantizationConfig] = None,
65 + quant_config: QuantizationConfig | None = None,
66 reduce_results: bool = True,
67 prefix: str = "",
68 ):
@@ -107,9 +106,9 @@ class ArcticMoE(nn.Module):
106 def __init__(
107 self,
108 config: ArcticConfig,
110 - tp_size: Optional[int] = None,
111 - params_dtype: Optional[torch.dtype] = None,
112 - quant_config: Optional[QuantizationConfig] = None,
109 + tp_size: int | None = None,
110 + params_dtype: torch.dtype | None = None,
111 + quant_config: QuantizationConfig | None = None,
112 reduce_results: bool = True,
113 prefix: str = "",
114 ):
@@ -265,8 +264,8 @@ class ArcticAttention(nn.Module):
264 def __init__(
265 self,
266 config: ArcticConfig,
268 - cache_config: Optional[CacheConfig] = None,
269 - quant_config: Optional[QuantizationConfig] = None,
267 + cache_config: CacheConfig | None = None,
268 + quant_config: QuantizationConfig | None = None,
269 prefix: str = "",
270 ):
271 super().__init__()
@@ -342,8 +341,8 @@ class ArcticDecoderLayer(nn.Module):
341 def __init__(
342 self,
343 config: ArcticConfig,
345 - cache_config: Optional[CacheConfig] = None,
346 - quant_config: Optional[QuantizationConfig] = None,
344 + cache_config: CacheConfig | None = None,
345 + quant_config: QuantizationConfig | None = None,
346 prefix: str = "",
347 ) -> None:
348 super().__init__()
@@ -443,9 +442,9 @@ class ArcticModel(nn.Module):
442 self,
443 input_ids: torch.Tensor,
444 positions: torch.Tensor,
446 - intermediate_tensors: Optional[IntermediateTensors],
447 - inputs_embeds: Optional[torch.Tensor] = None,
448 - ) -> Union[torch.Tensor, IntermediateTensors]:
445 + intermediate_tensors: IntermediateTensors | None,
446 + inputs_embeds: torch.Tensor | None = None,
447 + ) -> torch.Tensor | IntermediateTensors:
448 if get_pp_group().is_first_rank:
449 if inputs_embeds is not None:
450 hidden_states = inputs_embeds
@@ -499,9 +498,9 @@ class ArcticForCausalLM(nn.Module, SupportsPP, SupportsQuant):
498 self,
499 input_ids: torch.Tensor,
500 positions: torch.Tensor,
502 - intermediate_tensors: Optional[IntermediateTensors] = None,
503 - inputs_embeds: Optional[torch.Tensor] = None,
504 - ) -> Union[torch.Tensor, IntermediateTensors]:
501 + intermediate_tensors: IntermediateTensors | None = None,
502 + inputs_embeds: torch.Tensor | None = None,
503 + ) -> torch.Tensor | IntermediateTensors:
504 hidden_states = self.model(
505 input_ids, positions, intermediate_tensors, inputs_embeds
506 )
@@ -510,7 +509,7 @@ class ArcticForCausalLM(nn.Module, SupportsPP, SupportsQuant):
509 def compute_logits(
510 self,
511 hidden_states: torch.Tensor,
513 - ) -> Optional[torch.Tensor]:
512 + ) -> torch.Tensor | None:
513 logits = self.logits_processor(self.lm_head, hidden_states)
514 return logits
515
vllm/model_executor/models/aria.py
+14 -14
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable, Mapping, Sequence
4 -from typing import Annotated, Literal, Optional, Union
4 +from typing import Annotated, Literal
5
6 import torch
7 import torch.nn as nn
@@ -71,7 +71,7 @@ class AriaImagePixelInputs(TensorSchema):
71 ]
72
73 pixel_mask: Annotated[
74 - Optional[torch.Tensor],
74 + torch.Tensor | None,
75 TensorShape("bn", "h", "w"),
76 ]
77
@@ -82,7 +82,7 @@ class AriaVisionTransformer(Idefics3VisionTransformer, SupportsQuant):
82 def __init__(
83 self,
84 config: Idefics2VisionConfig,
85 - quant_config: Optional[QuantizationConfig] = None,
85 + quant_config: QuantizationConfig | None = None,
86 prefix: str = "",
87 ) -> None:
88 super().__init__(config, quant_config=quant_config, prefix=prefix)
@@ -180,7 +180,7 @@ class AriaProjector(nn.Module):
180 def forward(
181 self,
182 x: torch.Tensor,
183 - attn_mask: Optional[torch.Tensor] = None,
183 + attn_mask: torch.Tensor | None = None,
184 ) -> torch.Tensor:
185 batch_size, num_patches = x.shape[0], x.shape[1]
186
@@ -250,7 +250,7 @@ class AriaTextMoELayer(nn.Module):
250 def __init__(
251 self,
252 config: AriaTextConfig,
253 - quant_config: Optional[QuantizationConfig],
253 + quant_config: QuantizationConfig | None,
254 prefix: str = "",
255 ) -> None:
256 super().__init__()
@@ -415,7 +415,7 @@ class AriaProcessingInfo(BaseProcessingInfo):
415 def get_hf_processor(self, **kwargs: object):
416 return self.ctx.get_hf_processor(AriaProcessor, **kwargs)
417
418 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
418 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
419 return {"image": None}
420
421 def get_num_image_tokens(self) -> int:
@@ -436,7 +436,7 @@ class AriaDummyInputsBuilder(BaseDummyInputsBuilder[AriaProcessingInfo]):
436 self,
437 seq_len: int,
438 mm_counts: Mapping[str, int],
439 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
439 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
440 ) -> MultiModalDataDict:
441 vision_config = self.info.get_vision_config()
442
@@ -517,7 +517,7 @@ class AriaForConditionalGeneration(nn.Module, SupportsMultiModal):
517 )
518
519 @classmethod
520 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
520 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
521 if modality.startswith("image"):
522 return "<|fim_prefix|><|img|><|fim_suffix|>"
523
@@ -562,7 +562,7 @@ class AriaForConditionalGeneration(nn.Module, SupportsMultiModal):
562
563 def _parse_and_validate_image_input(
564 self, **kwargs: object
565 - ) -> Optional[AriaImagePixelInputs]:
565 + ) -> AriaImagePixelInputs | None:
566 pixel_values = kwargs.pop("pixel_values", None)
567 pixel_mask = kwargs.pop("pixel_mask", None)
568
@@ -577,8 +577,8 @@ class AriaForConditionalGeneration(nn.Module, SupportsMultiModal):
577
578 def _create_patch_attention_mask(
579 self,
580 - pixel_mask: Optional[torch.Tensor],
581 - ) -> Optional[torch.Tensor]:
580 + pixel_mask: torch.Tensor | None,
581 + ) -> torch.Tensor | None:
582 if pixel_mask is None:
583 return None
584
@@ -628,10 +628,10 @@ class AriaForConditionalGeneration(nn.Module, SupportsMultiModal):
628 self,
629 input_ids: torch.Tensor,
630 positions: torch.Tensor,
631 - intermediate_tensors: Optional[IntermediateTensors] = None,
632 - inputs_embeds: Optional[torch.Tensor] = None,
631 + intermediate_tensors: IntermediateTensors | None = None,
632 + inputs_embeds: torch.Tensor | None = None,
633 **kwargs: object,
634 - ) -> Union[torch.Tensor, IntermediateTensors]:
634 + ) -> torch.Tensor | IntermediateTensors:
635 if inputs_embeds is None:
636 multimodal_embeddings = self.get_multimodal_embeddings(**kwargs)
637 inputs_embeds = self.get_input_embeddings(
vllm/model_executor/models/aya_vision.py
+10 -10
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 # Adapted from https://github.com/huggingface/transformers/tree/main/src/transformers/models/aya_vision
4 from collections.abc import Iterable, Mapping, Sequence
5 -from typing import Annotated, Literal, Optional, Union
5 +from typing import Annotated, Literal
6
7 import torch
8 from torch import nn
@@ -139,7 +139,7 @@ class AyaVisionProcessingInfo(BaseProcessingInfo):
139 def get_image_processor(self, **kwargs: object) -> GotOcr2ImageProcessor:
140 return self.get_hf_processor(**kwargs).image_processor
141
142 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
142 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
143 return {"image": None}
144
145 def get_image_size_with_most_features(self) -> ImageSize:
@@ -187,7 +187,7 @@ class AyaVisionDummyInputsBuilder(BaseDummyInputsBuilder[AyaVisionProcessingInfo
187 self,
188 seq_len: int,
189 mm_counts: Mapping[str, int],
190 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
190 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
191 ) -> MultiModalDataDict:
192 num_images = mm_counts.get("image", 0)
193 image_size = self.info.get_image_size_with_most_features()
@@ -331,7 +331,7 @@ class AyaVisionForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
331 )
332
333 @classmethod
334 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
334 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
335 if modality.startswith("image"):
336 return "<image>"
337
@@ -375,7 +375,7 @@ class AyaVisionForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
375 self,
376 vision_tower: SiglipVisionModel,
377 pixel_values: torch.Tensor,
378 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
378 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
379 return vision_tower(
380 pixel_values.to(dtype=vision_tower.dtype),
381 feature_select_strategy=self.config.vision_feature_select_strategy,
@@ -395,7 +395,7 @@ class AyaVisionForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
395
396 def _parse_and_validate_image_input(
397 self, **kwargs: object
398 - ) -> Optional[AyaVisionImagePixelInputs]:
398 + ) -> AyaVisionImagePixelInputs | None:
399 pixel_values = kwargs.pop("pixel_values", None)
400 num_patches = kwargs.pop("num_patches", None)
401 image_embeds = kwargs.pop("image_embeds", None)
@@ -428,10 +428,10 @@ class AyaVisionForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
428 self,
429 input_ids: torch.Tensor,
430 positions: torch.Tensor,
431 - intermediate_tensors: Optional[IntermediateTensors] = None,
432 - inputs_embeds: Optional[torch.Tensor] = None,
431 + intermediate_tensors: IntermediateTensors | None = None,
432 + inputs_embeds: torch.Tensor | None = None,
433 **kwargs: object,
434 - ) -> Union[torch.Tensor, IntermediateTensors]:
434 + ) -> torch.Tensor | IntermediateTensors:
435 if intermediate_tensors is not None:
436 inputs_embeds = None
437
@@ -446,5 +446,5 @@ class AyaVisionForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
446 def compute_logits(
447 self,
448 hidden_states: torch.Tensor,
449 - ) -> Optional[torch.Tensor]:
449 + ) -> torch.Tensor | None:
450 return self.language_model.compute_logits(hidden_states)
vllm/model_executor/models/baichuan.py
+13 -14
@@ -24,7 +24,6 @@
24 import math
25 from collections.abc import Iterable
26 from itertools import islice
27 -from typing import Optional, Union
27
28 import torch
29 from torch import nn
@@ -98,7 +97,7 @@ class BaiChuanMLP(nn.Module):
97 hidden_size: int,
98 intermediate_size: int,
99 hidden_act: str,
101 - quant_config: Optional[QuantizationConfig] = None,
100 + quant_config: QuantizationConfig | None = None,
101 ):
102 super().__init__()
103 self.gate_up_proj = MergedColumnParallelLinear(
@@ -130,8 +129,8 @@ class BaiChuanAttention(nn.Module):
129 position_embedding: str,
130 rope_theta: float = 10000,
131 max_position_embeddings: int = 8192,
133 - cache_config: Optional[CacheConfig] = None,
134 - quant_config: Optional[QuantizationConfig] = None,
132 + cache_config: CacheConfig | None = None,
133 + quant_config: QuantizationConfig | None = None,
134 prefix: str = "",
135 ):
136 super().__init__()
@@ -213,8 +212,8 @@ class BaiChuanDecoderLayer(nn.Module):
212 self,
213 config: PretrainedConfig,
214 position_embedding: str,
216 - cache_config: Optional[CacheConfig] = None,
217 - quant_config: Optional[QuantizationConfig] = None,
215 + cache_config: CacheConfig | None = None,
216 + quant_config: QuantizationConfig | None = None,
217 prefix: str = "",
218 ):
219 super().__init__()
@@ -246,7 +245,7 @@ class BaiChuanDecoderLayer(nn.Module):
245 self,
246 positions: torch.Tensor,
247 hidden_states: torch.Tensor,
249 - residual: Optional[torch.Tensor],
248 + residual: torch.Tensor | None,
249 ) -> tuple[torch.Tensor, torch.Tensor]:
250 # Self Attention
251 if residual is None:
@@ -305,9 +304,9 @@ class BaiChuanModel(nn.Module):
304 self,
305 input_ids: torch.Tensor,
306 positions: torch.Tensor,
308 - intermediate_tensors: Optional[IntermediateTensors],
309 - inputs_embeds: Optional[torch.Tensor] = None,
310 - ) -> Union[torch.Tensor, IntermediateTensors]:
307 + intermediate_tensors: IntermediateTensors | None,
308 + inputs_embeds: torch.Tensor | None = None,
309 + ) -> torch.Tensor | IntermediateTensors:
310 if get_pp_group().is_first_rank:
311 if inputs_embeds is not None:
312 hidden_states = inputs_embeds
@@ -422,9 +421,9 @@ class BaiChuanBaseForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsQuant
421 self,
422 input_ids: torch.Tensor,
423 positions: torch.Tensor,
425 - intermediate_tensors: Optional[IntermediateTensors] = None,
426 - inputs_embeds: Optional[torch.Tensor] = None,
427 - ) -> Union[torch.Tensor, IntermediateTensors]:
424 + intermediate_tensors: IntermediateTensors | None = None,
425 + inputs_embeds: torch.Tensor | None = None,
426 + ) -> torch.Tensor | IntermediateTensors:
427 hidden_states = self.model(
428 input_ids, positions, intermediate_tensors, inputs_embeds
429 )
@@ -433,7 +432,7 @@ class BaiChuanBaseForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsQuant
432 def compute_logits(
433 self,
434 hidden_states: torch.Tensor,
436 - ) -> Optional[torch.Tensor]:
435 + ) -> torch.Tensor | None:
436 logits = self.logits_processor(self.lm_head, hidden_states)
437 return logits
438
vllm/model_executor/models/bailing_moe.py
+16 -17
@@ -26,7 +26,6 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Optional, Union
29
30 import torch
31 import torch.nn.functional as F
@@ -75,8 +74,8 @@ class BailingAttention(nn.Module):
74 def __init__(
75 self,
76 config: PretrainedConfig,
78 - cache_config: Optional[CacheConfig] = None,
79 - quant_config: Optional[QuantizationConfig] = None,
77 + cache_config: CacheConfig | None = None,
78 + quant_config: QuantizationConfig | None = None,
79 reduce_results: bool = True,
80 prefix: str = "",
81 ):
@@ -184,8 +183,8 @@ class BailingMLP(nn.Module):
183 self,
184 intermediate_size: int,
185 config: PretrainedConfig,
187 - quant_config: Optional[QuantizationConfig] = None,
188 - reduce_results: Optional[bool] = True,
186 + quant_config: QuantizationConfig | None = None,
187 + reduce_results: bool | None = True,
188 prefix: str = "",
189 ) -> None:
190 super().__init__()
@@ -218,8 +217,8 @@ class BailingMoE(nn.Module):
217 self,
218 intermediate_size: int,
219 config: PretrainedConfig,
221 - quant_config: Optional[QuantizationConfig] = None,
222 - reduce_results: Optional[bool] = True,
220 + quant_config: QuantizationConfig | None = None,
221 + reduce_results: bool | None = True,
222 prefix: str = "",
223 ):
224 super().__init__()
@@ -340,8 +339,8 @@ class BailingMoeBlock(nn.Module):
339 def __init__(
340 self,
341 config: PretrainedConfig,
343 - cache_config: Optional[CacheConfig] = None,
344 - quant_config: Optional[QuantizationConfig] = None,
342 + cache_config: CacheConfig | None = None,
343 + quant_config: QuantizationConfig | None = None,
344 prefix: str = "",
345 ):
346 super().__init__()
@@ -370,7 +369,7 @@ class BailingMoeBlock(nn.Module):
369 self,
370 hidden_states: torch.Tensor,
371 position_ids: torch.Tensor,
373 - residual: Optional[torch.Tensor],
372 + residual: torch.Tensor | None,
373 ) -> torch.Tensor:
374 if residual is None:
375 residual = hidden_states
@@ -447,9 +446,9 @@ class BailingMoeModel(nn.Module):
446 self,
447 input_ids: torch.Tensor,
448 position_ids: torch.Tensor,
450 - intermediate_tensors: Optional[IntermediateTensors],
451 - inputs_embeds: Optional[torch.Tensor] = None,
452 - ) -> Union[torch.Tensor, IntermediateTensors]:
449 + intermediate_tensors: IntermediateTensors | None,
450 + inputs_embeds: torch.Tensor | None = None,
451 + ) -> torch.Tensor | IntermediateTensors:
452 if get_pp_group().is_first_rank:
453 if inputs_embeds is not None:
454 hidden_states = inputs_embeds
@@ -619,9 +618,9 @@ class BailingMoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
618 self,
619 input_ids: torch.Tensor,
620 positions: torch.Tensor,
622 - intermediate_tensors: Optional[IntermediateTensors] = None,
623 - inputs_embeds: Optional[torch.Tensor] = None,
624 - ) -> Union[torch.Tensor, IntermediateTensors]:
621 + intermediate_tensors: IntermediateTensors | None = None,
622 + inputs_embeds: torch.Tensor | None = None,
623 + ) -> torch.Tensor | IntermediateTensors:
624 model_output = self.model(
625 input_ids, positions, intermediate_tensors, inputs_embeds
626 )
@@ -630,7 +629,7 @@ class BailingMoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
629 def compute_logits(
630 self,
631 hidden_states: torch.Tensor,
633 - ) -> Optional[torch.Tensor]:
632 + ) -> torch.Tensor | None:
633 logits = self.logits_processor(self.lm_head, hidden_states)
634 return logits
635
vllm/model_executor/models/bamba.py
+14 -15
@@ -4,7 +4,6 @@
4
5 # Added by the IBM Team, 2024
6 from collections.abc import Iterable
7 -from typing import Optional
7
8 import torch
9 from torch import nn
@@ -52,7 +51,7 @@ class BambaMLP(nn.Module):
51 def __init__(
52 self,
53 config: BambaConfig,
55 - quant_config: Optional[QuantizationConfig] = None,
54 + quant_config: QuantizationConfig | None = None,
55 bias: bool = False,
56 ) -> None:
57 super().__init__()
@@ -87,9 +86,9 @@ class BambaMixerDecoderLayer(nn.Module):
86 self,
87 config: BambaConfig,
88 layer_idx: int,
90 - model_config: Optional[ModelConfig] = None,
91 - cache_config: Optional[CacheConfig] = None,
92 - quant_config: Optional[QuantizationConfig] = None,
89 + model_config: ModelConfig | None = None,
90 + cache_config: CacheConfig | None = None,
91 + quant_config: QuantizationConfig | None = None,
92 prefix: str = "",
93 ) -> None:
94 super().__init__()
@@ -119,7 +118,7 @@ class BambaMixerDecoderLayer(nn.Module):
118 def forward(
119 self,
120 hidden_states: torch.Tensor,
122 - residual: Optional[torch.Tensor],
121 + residual: torch.Tensor | None,
122 **kwargs,
123 ):
124 if residual is None:
@@ -141,9 +140,9 @@ class BambaAttentionDecoderLayer(nn.Module):
140 self,
141 config: BambaConfig,
142 layer_idx: int,
144 - model_config: Optional[ModelConfig] = None,
145 - cache_config: Optional[CacheConfig] = None,
146 - quant_config: Optional[QuantizationConfig] = None,
143 + model_config: ModelConfig | None = None,
144 + cache_config: CacheConfig | None = None,
145 + quant_config: QuantizationConfig | None = None,
146 prefix: str = "",
147 ) -> None:
148 super().__init__()
@@ -235,7 +234,7 @@ class BambaAttentionDecoderLayer(nn.Module):
234 self,
235 positions: torch.Tensor,
236 hidden_states: torch.Tensor,
238 - residual: Optional[torch.Tensor],
237 + residual: torch.Tensor | None,
238 **kwargs,
239 ):
240 if residual is None:
@@ -314,8 +313,8 @@ class BambaModel(nn.Module):
313 self,
314 input_ids: torch.Tensor,
315 positions: torch.Tensor,
317 - intermediate_tensors: Optional[IntermediateTensors] = None,
318 - inputs_embeds: Optional[torch.Tensor] = None,
316 + intermediate_tensors: IntermediateTensors | None = None,
317 + inputs_embeds: torch.Tensor | None = None,
318 ) -> torch.Tensor:
319 if get_pp_group().is_first_rank:
320 if inputs_embeds is not None:
@@ -497,8 +496,8 @@ class BambaForCausalLM(
496 self,
497 input_ids: torch.Tensor,
498 positions: torch.Tensor,
500 - intermediate_tensors: Optional[IntermediateTensors] = None,
501 - inputs_embeds: Optional[torch.Tensor] = None,
499 + intermediate_tensors: IntermediateTensors | None = None,
500 + inputs_embeds: torch.Tensor | None = None,
501 **kwargs,
502 ):
503 hidden_states = self.model(
@@ -510,7 +509,7 @@ class BambaForCausalLM(
509 def compute_logits(
510 self,
511 hidden_states: torch.Tensor,
513 - ) -> Optional[torch.Tensor]:
512 + ) -> torch.Tensor | None:
513 logits = self.logits_processor(self.lm_head, hidden_states)
514 return logits
515
vllm/model_executor/models/bert.py
+24 -25
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable, Set
5 -from typing import Optional, Union
5
6 import torch
7 from torch import nn
@@ -66,7 +65,7 @@ class BertEmbedding(nn.Module):
65 self,
66 input_ids: torch.Tensor,
67 position_ids: torch.Tensor,
69 - inputs_embeds: Optional[torch.Tensor] = None,
68 + inputs_embeds: torch.Tensor | None = None,
69 ) -> torch.Tensor:
70 token_type_ids = _decode_token_type_ids(input_ids)
71
@@ -103,9 +102,9 @@ class BertPooler(Pooler):
102
103 def forward(
104 self,
106 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
105 + hidden_states: torch.Tensor | list[torch.Tensor],
106 pooling_metadata: PoolingMetadata,
108 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
107 + ) -> torch.Tensor | list[torch.Tensor]:
108 pooled_output = self.pooling(hidden_states, pooling_metadata)
109
110 if isinstance(pooled_output, list):
@@ -147,8 +146,8 @@ class BertLayer(nn.Module):
146 def __init__(
147 self,
148 config: BertConfig,
150 - cache_config: Optional[CacheConfig] = None,
151 - quant_config: Optional[QuantizationConfig] = None,
149 + cache_config: CacheConfig | None = None,
150 + quant_config: QuantizationConfig | None = None,
151 prefix: str = "",
152 ):
153 super().__init__()
@@ -191,8 +190,8 @@ class BertAttention(nn.Module):
190 hidden_size: int,
191 num_attention_heads: int,
192 layer_norm_eps: float,
194 - cache_config: Optional[CacheConfig] = None,
195 - quant_config: Optional[QuantizationConfig] = None,
193 + cache_config: CacheConfig | None = None,
194 + quant_config: QuantizationConfig | None = None,
195 prefix: str = "",
196 ):
197 super().__init__()
@@ -225,8 +224,8 @@ class BertSelfAttention(nn.Module):
224 self,
225 hidden_size: int,
226 num_attention_heads: int,
228 - cache_config: Optional[CacheConfig] = None,
229 - quant_config: Optional[QuantizationConfig] = None,
227 + cache_config: CacheConfig | None = None,
228 + quant_config: QuantizationConfig | None = None,
229 prefix: str = "",
230 ):
231 super().__init__()
@@ -281,7 +280,7 @@ class BertSelfOutput(nn.Module):
280 self,
281 hidden_size: int,
282 layer_norm_eps: float,
284 - quant_config: Optional[QuantizationConfig] = None,
283 + quant_config: QuantizationConfig | None = None,
284 prefix: str = "",
285 ):
286 super().__init__()
@@ -308,7 +307,7 @@ class BertIntermediate(nn.Module):
307 hidden_size: int,
308 intermediate_size: int,
309 hidden_act: str,
311 - quant_config: Optional[QuantizationConfig] = None,
310 + quant_config: QuantizationConfig | None = None,
311 prefix: str = "",
312 ):
313 super().__init__()
@@ -333,7 +332,7 @@ class BertOutput(nn.Module):
332 hidden_size: int,
333 intermediate_size: int,
334 layer_norm_eps: float,
336 - quant_config: Optional[QuantizationConfig] = None,
335 + quant_config: QuantizationConfig | None = None,
336 prefix: str = "",
337 ):
338 super().__init__()
@@ -383,8 +382,8 @@ class BertModel(nn.Module, SupportsQuant):
382 self,
383 input_ids: torch.Tensor,
384 positions: torch.Tensor,
386 - intermediate_tensors: Optional[IntermediateTensors] = None,
387 - inputs_embeds: Optional[torch.Tensor] = None,
385 + intermediate_tensors: IntermediateTensors | None = None,
386 + inputs_embeds: torch.Tensor | None = None,
387 ) -> torch.Tensor:
388 hidden_states = self.embeddings(
389 input_ids=input_ids,
@@ -494,8 +493,8 @@ class BertEmbeddingModel(nn.Module, SupportsQuant):
493 self,
494 input_ids: torch.Tensor,
495 positions: torch.Tensor,
497 - intermediate_tensors: Optional[IntermediateTensors] = None,
498 - inputs_embeds: Optional[torch.Tensor] = None,
496 + intermediate_tensors: IntermediateTensors | None = None,
497 + inputs_embeds: torch.Tensor | None = None,
498 ) -> torch.Tensor:
499 return self.model(
500 input_ids=input_ids,
@@ -636,11 +635,11 @@ class BertForSequenceClassification(nn.Module, SupportsCrossEncoding, SupportsQu
635
636 def forward(
637 self,
639 - input_ids: Optional[torch.Tensor],
638 + input_ids: torch.Tensor | None,
639 positions: torch.Tensor,
641 - intermediate_tensors: Optional[IntermediateTensors] = None,
642 - inputs_embeds: Optional[torch.Tensor] = None,
643 - token_type_ids: Optional[torch.Tensor] = None,
640 + intermediate_tensors: IntermediateTensors | None = None,
641 + inputs_embeds: torch.Tensor | None = None,
642 + token_type_ids: torch.Tensor | None = None,
643 ) -> torch.Tensor:
644 if token_type_ids is not None:
645 assert self.bert.config.vocab_size < (1 << TOKEN_TYPE_SHIFT)
@@ -692,11 +691,11 @@ class BertForTokenClassification(nn.Module):
691
692 def forward(
693 self,
695 - input_ids: Optional[torch.Tensor],
694 + input_ids: torch.Tensor | None,
695 positions: torch.Tensor,
697 - intermediate_tensors: Optional[IntermediateTensors] = None,
698 - inputs_embeds: Optional[torch.Tensor] = None,
699 - token_type_ids: Optional[torch.Tensor] = None,
696 + intermediate_tensors: IntermediateTensors | None = None,
697 + inputs_embeds: torch.Tensor | None = None,
698 + token_type_ids: torch.Tensor | None = None,
699 ) -> torch.Tensor:
700 if token_type_ids is not None:
701 assert self.bert.config.vocab_size < (1 << TOKEN_TYPE_SHIFT)
vllm/model_executor/models/bert_with_rope.py
+18 -19
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable
4 -from typing import Optional
4
5 import torch
6 from torch import nn
@@ -67,7 +66,7 @@ class BertWithRopeEmbedding(nn.Module):
66 def forward(
67 self,
68 input_ids: torch.Tensor,
70 - token_type_ids: Optional[torch.Tensor] = None,
69 + token_type_ids: torch.Tensor | None = None,
70 ) -> torch.Tensor:
71 input_shape = input_ids.size()
72 inputs_embeds = self.word_embeddings(input_ids)
@@ -91,10 +90,10 @@ class BertWithRopeAttention(nn.Module):
90 self,
91 hidden_size: int,
92 num_attention_heads: int,
94 - cache_config: Optional[CacheConfig] = None,
95 - quant_config: Optional[QuantizationConfig] = None,
93 + cache_config: CacheConfig | None = None,
94 + quant_config: QuantizationConfig | None = None,
95 bias: bool = True,
97 - rotary_kwargs: Optional[dict] = None,
96 + rotary_kwargs: dict | None = None,
97 prefix: str = "",
98 ):
99 super().__init__()
@@ -166,7 +165,7 @@ class BertWithRopeGatedMLP(nn.Module):
165 intermediate_size: int,
166 hidden_act: str,
167 bias: bool = True,
169 - quant_config: Optional[QuantizationConfig] = None,
168 + quant_config: QuantizationConfig | None = None,
169 prefix: str = "",
170 ):
171 super().__init__()
@@ -200,7 +199,7 @@ class BertWithRopeMLP(nn.Module):
199 intermediate_size: int,
200 hidden_act: str,
201 bias: bool = True,
203 - quant_config: Optional[QuantizationConfig] = None,
202 + quant_config: QuantizationConfig | None = None,
203 prefix: str = "",
204 ):
205 super().__init__()
@@ -235,8 +234,8 @@ class NomicMoE(nn.Module):
234 hidden_size: int,
235 intermediate_size: int,
236 hidden_act: str,
238 - params_dtype: Optional[torch.dtype] = None,
239 - tp_size: Optional[int] = None,
237 + params_dtype: torch.dtype | None = None,
238 + tp_size: int | None = None,
239 ):
240 super().__init__()
241
@@ -344,11 +343,11 @@ class BertWithRopeBlock(nn.Module):
343 def __init__(
344 self,
345 config: PretrainedConfig,
347 - cache_config: Optional[CacheConfig] = None,
348 - quant_config: Optional[QuantizationConfig] = None,
346 + cache_config: CacheConfig | None = None,
347 + quant_config: QuantizationConfig | None = None,
348 moe: bool = False,
349 bias: bool = True,
351 - rotary_kwargs: Optional[dict] = None,
350 + rotary_kwargs: dict | None = None,
351 prefix: str = "",
352 ):
353 super().__init__()
@@ -406,7 +405,7 @@ class BertWithRopeEncoder(nn.Module):
405 self,
406 vllm_config: VllmConfig,
407 bias: bool = True,
409 - rotary_kwargs: Optional[dict] = None,
408 + rotary_kwargs: dict | None = None,
409 prefix: str = "",
410 ):
411 super().__init__()
@@ -471,9 +470,9 @@ class BertWithRope(nn.Module, SupportsQuant):
470 self,
471 input_ids: torch.Tensor,
472 positions: torch.Tensor,
474 - intermediate_tensors: Optional[IntermediateTensors] = None,
475 - inputs_embeds: Optional[torch.Tensor] = None,
476 - token_type_ids: Optional[torch.Tensor] = None,
473 + intermediate_tensors: IntermediateTensors | None = None,
474 + inputs_embeds: torch.Tensor | None = None,
475 + token_type_ids: torch.Tensor | None = None,
476 ) -> torch.Tensor:
477 if inputs_embeds is not None:
478 hidden_states = inputs_embeds
@@ -724,10 +723,10 @@ class GteNewForSequenceClassification(nn.Module, SupportsCrossEncoding):
723
724 def forward(
725 self,
727 - input_ids: Optional[torch.Tensor],
726 + input_ids: torch.Tensor | None,
727 positions: torch.Tensor,
729 - intermediate_tensors: Optional[IntermediateTensors] = None,
730 - inputs_embeds: Optional[torch.Tensor] = None,
728 + intermediate_tensors: IntermediateTensors | None = None,
729 + inputs_embeds: torch.Tensor | None = None,
730 ) -> torch.Tensor:
731 return self.new(
732 input_ids=input_ids,
vllm/model_executor/models/blip.py
+10 -11
@@ -4,7 +4,6 @@
4 within a vision language model."""
5
6 from collections.abc import Iterable
7 -from typing import Optional, Union
7
8 import torch
9 import torch.nn as nn
@@ -38,7 +37,7 @@ def get_blip_num_patches(*, image_size: int, patch_size: int) -> int:
37
38 # Adapted from https://github.com/huggingface/transformers/blob/v4.39.0/src/transformers/models/blip/modeling_blip.py#L164 # noqa
39 class BlipVisionEmbeddings(nn.Module):
41 - def __init__(self, config: Union[BlipVisionConfig, Blip2VisionConfig]):
40 + def __init__(self, config: BlipVisionConfig | Blip2VisionConfig):
41 super().__init__()
42
43 self.config = config
@@ -86,8 +85,8 @@ class BlipAttention(nn.Module):
85
86 def __init__(
87 self,
89 - config: Union[BlipVisionConfig, Blip2VisionConfig],
90 - quant_config: Optional[QuantizationConfig] = None,
88 + config: BlipVisionConfig | Blip2VisionConfig,
89 + quant_config: QuantizationConfig | None = None,
90 prefix: str = "",
91 ) -> None:
92 super().__init__()
@@ -151,7 +150,7 @@ class BlipMLP(nn.Module):
150 def __init__(
151 self,
152 config: BlipVisionConfig,
154 - quant_config: Optional[QuantizationConfig] = None,
153 + quant_config: QuantizationConfig | None = None,
154 prefix: str = "",
155 ) -> None:
156 super().__init__()
@@ -186,7 +185,7 @@ class BlipEncoderLayer(nn.Module):
185 def __init__(
186 self,
187 config: BlipVisionConfig,
189 - quant_config: Optional[QuantizationConfig] = None,
188 + quant_config: QuantizationConfig | None = None,
189 prefix: str = "",
190 ) -> None:
191 super().__init__()
@@ -228,8 +227,8 @@ class BlipEncoder(nn.Module):
227 def __init__(
228 self,
229 config: BlipVisionConfig,
231 - quant_config: Optional[QuantizationConfig] = None,
232 - num_hidden_layers_override: Optional[int] = None,
230 + quant_config: QuantizationConfig | None = None,
231 + num_hidden_layers_override: int | None = None,
232 prefix: str = "",
233 ) -> None:
234 super().__init__()
@@ -268,10 +267,10 @@ class BlipVisionModel(nn.Module, SupportsQuant):
267 def __init__(
268 self,
269 config: BlipVisionConfig,
271 - quant_config: Optional[QuantizationConfig] = None,
270 + quant_config: QuantizationConfig | None = None,
271 *,
273 - num_hidden_layers_override: Optional[int] = None,
274 - require_post_norm: Optional[bool] = None,
272 + num_hidden_layers_override: int | None = None,
273 + require_post_norm: bool | None = None,
274 prefix: str = "",
275 ) -> None:
276 super().__init__()
vllm/model_executor/models/blip2.py
+21 -21
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable, Mapping, Sequence
5 -from typing import Annotated, Literal, Optional, Union
5 +from typing import Annotated, Literal, TypeAlias
6
7 import torch
8 import torch.nn as nn
@@ -70,7 +70,7 @@ class Blip2ImageEmbeddingInputs(TensorSchema):
70 data: Annotated[torch.Tensor, TensorShape("bn", "f", "h")]
71
72
73 -Blip2ImageInputs = Union[Blip2ImagePixelInputs, Blip2ImageEmbeddingInputs]
73 +Blip2ImageInputs: TypeAlias = Blip2ImagePixelInputs | Blip2ImageEmbeddingInputs
74
75
76 class Blip2QFormerMultiHeadAttention(nn.Module):
@@ -78,8 +78,8 @@ class Blip2QFormerMultiHeadAttention(nn.Module):
78 self,
79 config: Blip2QFormerConfig,
80 *,
81 - quant_config: Optional[QuantizationConfig],
82 - cache_config: Optional[CacheConfig],
81 + quant_config: QuantizationConfig | None,
82 + cache_config: CacheConfig | None,
83 is_cross_attention: bool = False,
84 prefix: str = "",
85 ) -> None:
@@ -123,7 +123,7 @@ class Blip2QFormerMultiHeadAttention(nn.Module):
123 def forward(
124 self,
125 hidden_states: torch.Tensor,
126 - encoder_hidden_states: Optional[torch.FloatTensor] = None,
126 + encoder_hidden_states: torch.FloatTensor | None = None,
127 ):
128 is_cross_attention = encoder_hidden_states is not None
129
@@ -179,8 +179,8 @@ class Blip2QFormerAttention(nn.Module):
179 self,
180 config: Blip2QFormerConfig,
181 *,
182 - quant_config: Optional[QuantizationConfig],
183 - cache_config: Optional[CacheConfig],
182 + quant_config: QuantizationConfig | None,
183 + cache_config: CacheConfig | None,
184 is_cross_attention: bool = False,
185 prefix: str = "",
186 ) -> None:
@@ -199,7 +199,7 @@ class Blip2QFormerAttention(nn.Module):
199 def forward(
200 self,
201 hidden_states: torch.Tensor,
202 - encoder_hidden_states: Optional[torch.FloatTensor] = None,
202 + encoder_hidden_states: torch.FloatTensor | None = None,
203 ) -> tuple[torch.Tensor]:
204 self_output = self.attention(
205 hidden_states,
@@ -247,8 +247,8 @@ class Blip2QFormerLayer(nn.Module):
247 self,
248 config: Blip2QFormerConfig,
249 *,
250 - quant_config: Optional[QuantizationConfig],
251 - cache_config: Optional[CacheConfig],
250 + quant_config: QuantizationConfig | None,
251 + cache_config: CacheConfig | None,
252 layer_idx: int,
253 prefix: str = "",
254 ) -> None:
@@ -340,8 +340,8 @@ class Blip2QFormerEncoder(nn.Module):
340 self,
341 config: Blip2QFormerConfig,
342 *,
343 - quant_config: Optional[QuantizationConfig],
344 - cache_config: Optional[CacheConfig],
343 + quant_config: QuantizationConfig | None,
344 + cache_config: CacheConfig | None,
345 prefix: str = "",
346 ) -> None:
347 super().__init__()
@@ -385,8 +385,8 @@ class Blip2QFormerModel(nn.Module):
385 self,
386 config: Blip2QFormerConfig,
387 *,
388 - quant_config: Optional[QuantizationConfig],
389 - cache_config: Optional[CacheConfig],
388 + quant_config: QuantizationConfig | None,
389 + cache_config: CacheConfig | None,
390 prefix: str = "",
391 ) -> None:
392 super().__init__()
@@ -426,7 +426,7 @@ class Blip2ProcessingInfo(BaseProcessingInfo):
426 def get_hf_config(self):
427 return self.ctx.get_hf_config(Blip2Config)
428
429 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
429 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
430 return {"image": 1}
431
432 def get_num_image_tokens(self) -> int:
@@ -442,7 +442,7 @@ class Blip2DummyInputsBuilder(BaseDummyInputsBuilder[Blip2ProcessingInfo]):
442 self,
443 seq_len: int,
444 mm_counts: Mapping[str, int],
445 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
445 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
446 ) -> MultiModalDataDict:
447 hf_config = self.info.get_hf_config()
448 vision_config = hf_config.vision_config
@@ -526,7 +526,7 @@ class Blip2ForConditionalGeneration(
526 merge_by_field_config = True
527
528 @classmethod
529 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
529 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
530 if modality.startswith("image"):
531 return None
532
@@ -573,7 +573,7 @@ class Blip2ForConditionalGeneration(
573
574 def _parse_and_validate_image_input(
575 self, **kwargs: object
576 - ) -> Optional[Blip2ImageInputs]:
576 + ) -> Blip2ImageInputs | None:
577 pixel_values = kwargs.pop("pixel_values", None)
578 image_embeds = kwargs.pop("image_embeds", None)
579
@@ -641,8 +641,8 @@ class Blip2ForConditionalGeneration(
641 self,
642 input_ids: torch.Tensor,
643 positions: torch.Tensor,
644 - intermediate_tensors: Optional[IntermediateTensors] = None,
645 - inputs_embeds: Optional[torch.Tensor] = None,
644 + intermediate_tensors: IntermediateTensors | None = None,
645 + inputs_embeds: torch.Tensor | None = None,
646 **kwargs: object,
647 ) -> IntermediateTensors:
648 """Run forward pass for BLIP-2.
@@ -687,7 +687,7 @@ class Blip2ForConditionalGeneration(
687 def compute_logits(
688 self,
689 hidden_states: torch.Tensor,
690 - ) -> Optional[torch.Tensor]:
690 + ) -> torch.Tensor | None:
691 return self.language_model.compute_logits(hidden_states)
692
693 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/bloom.py
+12 -13
@@ -22,7 +22,6 @@
22 import math
23 from collections.abc import Iterable
24 from itertools import islice
25 -from typing import Optional, Union
25
26 import torch
27 from torch import nn
@@ -89,8 +88,8 @@ class BloomAttention(nn.Module):
88 def __init__(
89 self,
90 config: BloomConfig,
92 - cache_config: Optional[CacheConfig] = None,
93 - quant_config: Optional[QuantizationConfig] = None,
91 + cache_config: CacheConfig | None = None,
92 + quant_config: QuantizationConfig | None = None,
93 prefix: str = "",
94 ):
95 super().__init__()
@@ -152,7 +151,7 @@ class BloomMLP(nn.Module):
151 def __init__(
152 self,
153 config: BloomConfig,
155 - quant_config: Optional[QuantizationConfig] = None,
154 + quant_config: QuantizationConfig | None = None,
155 ):
156 super().__init__()
157 hidden_size = config.hidden_size
@@ -179,8 +178,8 @@ class BloomBlock(nn.Module):
178 def __init__(
179 self,
180 config: BloomConfig,
182 - cache_config: Optional[CacheConfig] = None,
183 - quant_config: Optional[QuantizationConfig] = None,
181 + cache_config: CacheConfig | None = None,
182 + quant_config: QuantizationConfig | None = None,
183 prefix: str = "",
184 ):
185 super().__init__()
@@ -274,9 +273,9 @@ class BloomModel(nn.Module):
273 self,
274 input_ids: torch.Tensor,
275 position_ids: torch.Tensor,
277 - intermediate_tensors: Optional[IntermediateTensors],
278 - inputs_embeds: Optional[torch.Tensor] = None,
279 - ) -> Union[torch.Tensor, IntermediateTensors]:
276 + intermediate_tensors: IntermediateTensors | None,
277 + inputs_embeds: torch.Tensor | None = None,
278 + ) -> torch.Tensor | IntermediateTensors:
279 if get_pp_group().is_first_rank:
280 if inputs_embeds is not None:
281 hidden_states = inputs_embeds
@@ -356,9 +355,9 @@ class BloomForCausalLM(nn.Module, SupportsPP, SupportsQuant):
355 self,
356 input_ids: torch.Tensor,
357 positions: torch.Tensor,
359 - intermediate_tensors: Optional[IntermediateTensors] = None,
360 - inputs_embeds: Optional[torch.Tensor] = None,
361 - ) -> Union[torch.Tensor, IntermediateTensors]:
358 + intermediate_tensors: IntermediateTensors | None = None,
359 + inputs_embeds: torch.Tensor | None = None,
360 + ) -> torch.Tensor | IntermediateTensors:
361 hidden_states = self.transformer(
362 input_ids, positions, intermediate_tensors, inputs_embeds
363 )
@@ -367,7 +366,7 @@ class BloomForCausalLM(nn.Module, SupportsPP, SupportsQuant):
366 def compute_logits(
367 self,
368 hidden_states: torch.Tensor,
370 - ) -> Optional[torch.Tensor]:
369 + ) -> torch.Tensor | None:
370 logits = self.logits_processor(self.lm_head, hidden_states)
371 return logits
372
vllm/model_executor/models/chameleon.py
+24 -24
@@ -4,7 +4,7 @@
4 from collections.abc import Iterable, Mapping, Sequence
5 from functools import cached_property
6 from itertools import islice
7 -from typing import Annotated, Any, Literal, Optional, Union
7 +from typing import Annotated, Any, Literal
8
9 import torch
10 import torch.nn as nn
@@ -94,7 +94,7 @@ class ChameleonProcessingInfo(BaseProcessingInfo):
94 def get_hf_processor(self, **kwargs: object):
95 return self.ctx.get_hf_processor(ChameleonProcessor, **kwargs)
96
97 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
97 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
98 return {"image": 1}
99
100 def get_num_image_tokens(self) -> int:
@@ -115,7 +115,7 @@ class ChameleonDummyInputsBuilder(BaseDummyInputsBuilder[ChameleonProcessingInfo
115 self,
116 seq_len: int,
117 mm_counts: Mapping[str, int],
118 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
118 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
119 ) -> MultiModalDataDict:
120 config = self.info.get_hf_config()
121
@@ -225,7 +225,7 @@ class ChameleonMLP(nn.Module):
225 hidden_size: int,
226 intermediate_size: int,
227 hidden_act: str,
228 - quant_config: Optional[QuantizationConfig] = None,
228 + quant_config: QuantizationConfig | None = None,
229 bias: bool = False,
230 ) -> None:
231 super().__init__()
@@ -262,11 +262,11 @@ class ChameleonAttention(nn.Module):
262 num_heads: int,
263 num_kv_heads: int,
264 rope_theta: float = 10000,
265 - rope_scaling: Optional[dict[str, Any]] = None,
265 + rope_scaling: dict[str, Any] | None = None,
266 max_position_embeddings: int = 4096,
267 - quant_config: Optional[QuantizationConfig] = None,
267 + quant_config: QuantizationConfig | None = None,
268 bias: bool = False,
269 - cache_config: Optional[CacheConfig] = None,
269 + cache_config: CacheConfig | None = None,
270 prefix: str = "",
271 ) -> None:
272 super().__init__()
@@ -357,8 +357,8 @@ class ChameleonDecoderLayer(nn.Module):
357 def __init__(
358 self,
359 config: ChameleonConfig,
360 - cache_config: Optional[CacheConfig] = None,
361 - quant_config: Optional[QuantizationConfig] = None,
360 + cache_config: CacheConfig | None = None,
361 + quant_config: QuantizationConfig | None = None,
362 prefix: str = "",
363 ) -> None:
364 super().__init__()
@@ -403,8 +403,8 @@ class ChameleonDecoderLayer(nn.Module):
403 self,
404 positions: torch.Tensor,
405 hidden_states: torch.Tensor,
406 - residual: Optional[torch.Tensor],
407 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
406 + residual: torch.Tensor | None,
407 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
408 if residual is None:
409 residual = hidden_states
410 hidden_states = self.input_layernorm(hidden_states)
@@ -426,8 +426,8 @@ class ChameleonSwinDecoderLayer(nn.Module):
426 def __init__(
427 self,
428 config: ChameleonConfig,
429 - cache_config: Optional[CacheConfig] = None,
430 - quant_config: Optional[QuantizationConfig] = None,
429 + cache_config: CacheConfig | None = None,
430 + quant_config: QuantizationConfig | None = None,
431 prefix: str = "",
432 ) -> None:
433 super().__init__()
@@ -472,7 +472,7 @@ class ChameleonSwinDecoderLayer(nn.Module):
472 self,
473 positions: torch.Tensor,
474 hidden_states: torch.Tensor,
475 - residual: Optional[torch.Tensor],
475 + residual: torch.Tensor | None,
476 ) -> tuple[torch.Tensor, torch.Tensor]:
477 residual = hidden_states
478 hidden_states = self.self_attn(
@@ -896,11 +896,11 @@ class ChameleonModel(nn.Module):
896
897 def forward(
898 self,
899 - input_ids: Optional[torch.Tensor],
899 + input_ids: torch.Tensor | None,
900 positions: torch.Tensor,
901 - intermediate_tensors: Optional[IntermediateTensors],
902 - inputs_embeds: Optional[torch.Tensor] = None,
903 - ) -> Union[torch.Tensor, IntermediateTensors]:
901 + intermediate_tensors: IntermediateTensors | None,
902 + inputs_embeds: torch.Tensor | None = None,
903 + ) -> torch.Tensor | IntermediateTensors:
904 if get_pp_group().is_first_rank:
905 if inputs_embeds is not None:
906 hidden_states = inputs_embeds
@@ -941,7 +941,7 @@ class ChameleonForConditionalGeneration(
941 }
942
943 @classmethod
944 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
944 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
945 if modality.startswith("image"):
946 return "<image>"
947
@@ -975,7 +975,7 @@ class ChameleonForConditionalGeneration(
975
976 def _parse_and_validate_image_input(
977 self, **kwargs: object
978 - ) -> Optional[ChameleonImagePixelInputs]:
978 + ) -> ChameleonImagePixelInputs | None:
979 pixel_values = kwargs.pop("pixel_values", None)
980
981 if pixel_values is None:
@@ -1008,10 +1008,10 @@ class ChameleonForConditionalGeneration(
1008 self,
1009 input_ids: torch.Tensor,
1010 positions: torch.Tensor,
1011 - intermediate_tensors: Optional[IntermediateTensors] = None,
1012 - inputs_embeds: Optional[torch.Tensor] = None,
1011 + intermediate_tensors: IntermediateTensors | None = None,
1012 + inputs_embeds: torch.Tensor | None = None,
1013 **kwargs,
1014 - ) -> Union[torch.Tensor, IntermediateTensors]:
1014 + ) -> torch.Tensor | IntermediateTensors:
1015 if intermediate_tensors is not None:
1016 inputs_embeds = None
1017
@@ -1023,7 +1023,7 @@ class ChameleonForConditionalGeneration(
1023 def compute_logits(
1024 self,
1025 hidden_states: torch.Tensor,
1026 - ) -> Optional[torch.Tensor]:
1026 + ) -> torch.Tensor | None:
1027 logits = self.logits_processor(self.lm_head, hidden_states)
1028
1029 # Disallow image tokens which does not include special
vllm/model_executor/models/chatglm.py
+15 -16
@@ -7,7 +7,6 @@
7 import json
8 from collections.abc import Iterable
9 from itertools import islice
10 -from typing import Optional, Union
10
11 import torch
12 from torch import nn
@@ -50,8 +49,8 @@ class GLMAttention(nn.Module):
49 def __init__(
50 self,
51 config: ChatGLMConfig,
53 - cache_config: Optional[CacheConfig] = None,
54 - quant_config: Optional[QuantizationConfig] = None,
52 + cache_config: CacheConfig | None = None,
53 + quant_config: QuantizationConfig | None = None,
54 prefix: str = "",
55 ):
56 super().__init__()
@@ -144,7 +143,7 @@ class GLMMLP(nn.Module):
143 def __init__(
144 self,
145 config: ChatGLMConfig,
147 - quant_config: Optional[QuantizationConfig] = None,
146 + quant_config: QuantizationConfig | None = None,
147 prefix: str = "",
148 ):
149 super().__init__()
@@ -190,8 +189,8 @@ class GLMBlock(nn.Module):
189 def __init__(
190 self,
191 config: ChatGLMConfig,
193 - cache_config: Optional[CacheConfig] = None,
194 - quant_config: Optional[QuantizationConfig] = None,
192 + cache_config: CacheConfig | None = None,
193 + quant_config: QuantizationConfig | None = None,
194 prefix: str = "",
195 ):
196 super().__init__()
@@ -263,8 +262,8 @@ class GLMTransformer(nn.Module):
262 def __init__(
263 self,
264 config: ChatGLMConfig,
266 - cache_config: Optional[CacheConfig] = None,
267 - quant_config: Optional[QuantizationConfig] = None,
265 + cache_config: CacheConfig | None = None,
266 + quant_config: QuantizationConfig | None = None,
267 prefix: str = "",
268 ):
269 super().__init__()
@@ -295,7 +294,7 @@ class GLMTransformer(nn.Module):
294 self,
295 hidden_states: torch.Tensor,
296 position_ids: torch.Tensor,
298 - ) -> Union[torch.Tensor, IntermediateTensors]:
297 + ) -> torch.Tensor | IntermediateTensors:
298 for layer in islice(self.layers, self.start_layer, self.end_layer):
299 hidden_states = layer(
300 hidden_states=hidden_states, position_ids=position_ids
@@ -361,10 +360,10 @@ class ChatGLMModel(nn.Module, SupportsQuant):
360 self,
361 input_ids: torch.Tensor,
362 positions: torch.Tensor,
364 - intermediate_tensors: Optional[IntermediateTensors] = None,
365 - inputs_embeds: Optional[torch.Tensor] = None,
363 + intermediate_tensors: IntermediateTensors | None = None,
364 + inputs_embeds: torch.Tensor | None = None,
365 **kwargs: object,
367 - ) -> Union[torch.Tensor, IntermediateTensors]:
366 + ) -> torch.Tensor | IntermediateTensors:
367 if get_pp_group().is_first_rank:
368 if inputs_embeds is not None:
369 hidden_states = inputs_embeds
@@ -459,7 +458,7 @@ class ChatGLMBaseModel(nn.Module):
458 def compute_logits(
459 self,
460 hidden_states: torch.Tensor,
462 - ) -> Optional[torch.Tensor]:
461 + ) -> torch.Tensor | None:
462 logits = self.logits_processor(self.lm_head, hidden_states)
463 return logits
464
@@ -491,9 +490,9 @@ class ChatGLMForCausalLM(ChatGLMBaseModel, SupportsLoRA, SupportsPP, SupportsQua
490 self,
491 input_ids: torch.Tensor,
492 positions: torch.Tensor,
494 - intermediate_tensors: Optional[IntermediateTensors] = None,
495 - inputs_embeds: Optional[torch.Tensor] = None,
496 - ) -> Union[torch.Tensor, IntermediateTensors]:
493 + intermediate_tensors: IntermediateTensors | None = None,
494 + inputs_embeds: torch.Tensor | None = None,
495 + ) -> torch.Tensor | IntermediateTensors:
496 hidden_states = self.transformer(
497 input_ids, positions, intermediate_tensors, inputs_embeds
498 )
vllm/model_executor/models/clip.py
+44 -44
@@ -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 cached_property
5 -from typing import Annotated, Literal, Optional, Union
5 +from typing import Annotated, Literal
6
7 import torch
8 import torch.nn as nn
@@ -125,7 +125,7 @@ class CLIPProcessingInfo(BaseProcessingInfo):
125 def get_hf_processor(self, **kwargs: object):
126 return self.ctx.get_hf_processor(CLIPProcessor, **kwargs)
127
128 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
128 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
129 return {"image": 1}
130
131 def get_num_image_tokens(
@@ -169,7 +169,7 @@ class CLIPDummyInputsBuilder(BaseDummyInputsBuilder[CLIPProcessingInfo]):
169 self,
170 seq_len: int,
171 mm_counts: Mapping[str, int],
172 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
172 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
173 ) -> MultiModalDataDict:
174 num_images = mm_counts.get("image", 0)
175
@@ -199,12 +199,12 @@ class CLIPMultiModalProcessor(BaseMultiModalProcessor[CLIPProcessingInfo]):
199
200 def apply(
201 self,
202 - prompt: Union[str, list[int]],
202 + prompt: str | list[int],
203 mm_data: MultiModalDataDict,
204 hf_processor_mm_kwargs: Mapping[str, object],
205 - tokenization_kwargs: Optional[Mapping[str, object]] = None,
205 + tokenization_kwargs: Mapping[str, object] | None = None,
206 *,
207 - mm_uuids: Optional[MultiModalUUIDDict] = None,
207 + mm_uuids: MultiModalUUIDDict | None = None,
208 ) -> MultiModalInputs:
209 if prompt and mm_data:
210 raise ValueError(
@@ -286,9 +286,9 @@ class CLIPTextEmbeddings(nn.Module):
286
287 def forward(
288 self,
289 - input_ids: Optional[torch.Tensor],
289 + input_ids: torch.Tensor | None,
290 position_ids: torch.Tensor,
291 - inputs_embeds: Optional[torch.Tensor] = None,
291 + inputs_embeds: torch.Tensor | None = None,
292 ) -> torch.Tensor:
293 if inputs_embeds is None:
294 if input_ids is None:
@@ -350,11 +350,11 @@ class CLIPVisionEmbeddings(nn.Module):
350 class CLIPAttention(nn.Module):
351 def __init__(
352 self,
353 - config: Union[CLIPTextConfig, CLIPVisionConfig],
354 - quant_config: Optional[QuantizationConfig] = None,
353 + config: CLIPTextConfig | CLIPVisionConfig,
354 + quant_config: QuantizationConfig | None = None,
355 *,
356 prefix: str = "",
357 - attn_cls: Union[type[Attention], type[MultiHeadAttention]],
357 + attn_cls: type[Attention] | type[MultiHeadAttention],
358 ) -> None:
359 super().__init__()
360
@@ -412,8 +412,8 @@ class CLIPAttention(nn.Module):
412 class CLIPMLP(nn.Module):
413 def __init__(
414 self,
415 - config: Union[CLIPTextConfig, CLIPVisionConfig],
416 - quant_config: Optional[QuantizationConfig] = None,
415 + config: CLIPTextConfig | CLIPVisionConfig,
416 + quant_config: QuantizationConfig | None = None,
417 prefix: str = "",
418 ) -> None:
419 super().__init__()
@@ -445,11 +445,11 @@ class CLIPMLP(nn.Module):
445 class CLIPEncoderLayer(nn.Module):
446 def __init__(
447 self,
448 - config: Union[CLIPTextConfig, CLIPVisionConfig],
449 - quant_config: Optional[QuantizationConfig] = None,
448 + config: CLIPTextConfig | CLIPVisionConfig,
449 + quant_config: QuantizationConfig | None = None,
450 *,
451 prefix: str = "",
452 - attn_cls: Union[type[Attention], type[MultiHeadAttention]],
452 + attn_cls: type[Attention] | type[MultiHeadAttention],
453 ) -> None:
454 super().__init__()
455 self.self_attn = CLIPAttention(
@@ -488,12 +488,12 @@ class CLIPEncoder(nn.Module):
488
489 def __init__(
490 self,
491 - config: Union[CLIPTextConfig, CLIPVisionConfig],
492 - quant_config: Optional[QuantizationConfig] = None,
493 - num_hidden_layers_override: Optional[int] = None,
491 + config: CLIPTextConfig | CLIPVisionConfig,
492 + quant_config: QuantizationConfig | None = None,
493 + num_hidden_layers_override: int | None = None,
494 *,
495 prefix: str = "",
496 - attn_cls: Union[type[Attention], type[MultiHeadAttention]],
496 + attn_cls: type[Attention] | type[MultiHeadAttention],
497 ) -> None:
498 super().__init__()
499
@@ -519,7 +519,7 @@ class CLIPEncoder(nn.Module):
519 self,
520 inputs_embeds: torch.Tensor,
521 return_all_hidden_states: bool,
522 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
522 + ) -> torch.Tensor | list[torch.Tensor]:
523 hidden_states_pool = [inputs_embeds]
524 hidden_states = inputs_embeds
525
@@ -538,7 +538,7 @@ class CLIPTextTransformer(nn.Module):
538 def __init__(
539 self,
540 config: CLIPTextConfig,
541 - quant_config: Optional[QuantizationConfig] = None,
541 + quant_config: QuantizationConfig | None = None,
542 *,
543 prefix: str = "",
544 ) -> None:
@@ -566,9 +566,9 @@ class CLIPTextTransformer(nn.Module):
566
567 def forward(
568 self,
569 - input_ids: Optional[torch.Tensor],
569 + input_ids: torch.Tensor | None,
570 position_ids: torch.Tensor,
571 - inputs_embeds: Optional[torch.Tensor] = None,
571 + inputs_embeds: torch.Tensor | None = None,
572 ) -> torch.Tensor:
573 hidden_states = self.embeddings(
574 input_ids=input_ids,
@@ -616,10 +616,10 @@ class CLIPVisionTransformer(nn.Module):
616 def __init__(
617 self,
618 config: CLIPVisionConfig,
619 - quant_config: Optional[QuantizationConfig] = None,
619 + quant_config: QuantizationConfig | None = None,
620 *,
621 - num_hidden_layers_override: Optional[int] = None,
622 - require_post_norm: Optional[bool] = None,
621 + num_hidden_layers_override: int | None = None,
622 + require_post_norm: bool | None = None,
623 prefix: str = "",
624 ) -> None:
625 super().__init__()
@@ -669,8 +669,8 @@ class CLIPVisionTransformer(nn.Module):
669 self,
670 pixel_values: torch.Tensor,
671 *,
672 - select_layers: Optional[list[int]] = None,
673 - feature_select_strategy: Optional[VisionFeatureSelectStrategy] = None,
672 + select_layers: list[int] | None = None,
673 + feature_select_strategy: VisionFeatureSelectStrategy | None = None,
674 ) -> torch.Tensor:
675 hidden_states = self.embeddings(pixel_values)
676 hidden_states = self.pre_layrnorm(hidden_states)
@@ -736,10 +736,10 @@ class CLIPVisionModel(nn.Module):
736 def __init__(
737 self,
738 config: CLIPVisionConfig,
739 - quant_config: Optional[QuantizationConfig] = None,
739 + quant_config: QuantizationConfig | None = None,
740 *,
741 - num_hidden_layers_override: Optional[int] = None,
742 - require_post_norm: Optional[bool] = None,
741 + num_hidden_layers_override: int | None = None,
742 + require_post_norm: bool | None = None,
743 prefix: str = "",
744 ) -> None:
745 super().__init__()
@@ -755,8 +755,8 @@ class CLIPVisionModel(nn.Module):
755 def forward(
756 self,
757 pixel_values: torch.Tensor,
758 - select_layers: Optional[list[int]] = None,
759 - feature_select_strategy: Optional[VisionFeatureSelectStrategy] = None,
758 + select_layers: list[int] | None = None,
759 + feature_select_strategy: VisionFeatureSelectStrategy | None = None,
760 ) -> torch.Tensor:
761 return self.vision_model(
762 pixel_values,
@@ -787,7 +787,7 @@ class CLIPEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant):
787 merge_by_field_config = True
788
789 @classmethod
790 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
790 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
791 if modality.startswith("image"):
792 return None
793
@@ -847,9 +847,9 @@ class CLIPEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant):
847
848 def get_text_features(
849 self,
850 - input_ids: Optional[torch.Tensor],
850 + input_ids: torch.Tensor | None,
851 position_ids: torch.Tensor,
852 - inputs_embeds: Optional[torch.Tensor] = None,
852 + inputs_embeds: torch.Tensor | None = None,
853 ) -> torch.Tensor:
854 pooled_output = self.text_model(
855 input_ids=input_ids,
@@ -864,7 +864,7 @@ class CLIPEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant):
864 def get_image_features(
865 self,
866 pixel_values: torch.Tensor,
867 - feature_select_strategy: Optional[VisionFeatureSelectStrategy] = None,
867 + feature_select_strategy: VisionFeatureSelectStrategy | None = None,
868 ) -> torch.Tensor:
869 if feature_select_strategy is None:
870 feature_select_strategy = _get_vision_feature_select_strategy(
@@ -883,7 +883,7 @@ class CLIPEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant):
883
884 def _parse_and_validate_image_input(
885 self, **kwargs: object
886 - ) -> Optional[CLIPImagePixelInputs]:
886 + ) -> CLIPImagePixelInputs | None:
887 pixel_values = kwargs.pop("pixel_values", None)
888 if pixel_values is None:
889 return None
@@ -906,9 +906,9 @@ class CLIPEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant):
906 def get_input_embeddings(
907 self,
908 input_ids: torch.Tensor,
909 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
909 + multimodal_embeddings: MultiModalEmbeddings | None = None,
910 *,
911 - is_multimodal: Optional[torch.Tensor] = None,
911 + is_multimodal: torch.Tensor | None = None,
912 handle_oov_mm_token: bool = False,
913 ) -> torch.Tensor:
914 self._is_text_input = (
@@ -936,10 +936,10 @@ class CLIPEmbeddingModel(nn.Module, SupportsMultiModal, SupportsQuant):
936
937 def forward(
938 self,
939 - input_ids: Optional[torch.Tensor],
939 + input_ids: torch.Tensor | None,
940 positions: torch.Tensor,
941 - intermediate_tensors: Optional[IntermediateTensors] = None,
942 - inputs_embeds: Optional[torch.Tensor] = None,
941 + intermediate_tensors: IntermediateTensors | None = None,
942 + inputs_embeds: torch.Tensor | None = None,
943 **kwargs: object,
944 ) -> torch.Tensor:
945 if intermediate_tensors is not None:
vllm/model_executor/models/cohere2_vision.py
+9 -9
@@ -4,7 +4,7 @@
4 """Command-A-Vision (Cohere2Vision) multimodal model implementation for vLLM."""
5
6 from collections.abc import Iterable, Mapping, Sequence
7 -from typing import Annotated, Literal, Optional, Union
7 +from typing import Annotated, Literal
8
9 import torch
10 from torch import nn
@@ -148,7 +148,7 @@ class Cohere2VisionProcessingInfo(BaseProcessingInfo):
148 def get_image_processor(self, **kwargs: object):
149 return self.get_hf_processor(**kwargs).image_processor
150
151 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
151 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
152 return {"image": None}
153
154 def get_image_size_with_most_features(self) -> ImageSize:
@@ -163,7 +163,7 @@ class Cohere2VisionProcessingInfo(BaseProcessingInfo):
163 *,
164 image_width: int,
165 image_height: int,
166 - processor: Optional[Cohere2VisionProcessor],
166 + processor: Cohere2VisionProcessor | None,
167 ) -> int:
168 """
169 Calculate the number of image patches for a given image.
@@ -217,7 +217,7 @@ class Cohere2VisionDummyInputsBuilder(
217 self,
218 seq_len: int,
219 mm_counts: Mapping[str, int],
220 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
220 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
221 ) -> MultiModalDataDict:
222 num_images = mm_counts.get("image", 0)
223 image_size = self.info.get_image_size_with_most_features()
@@ -404,7 +404,7 @@ class Cohere2VisionForConditionalGeneration(nn.Module, SupportsMultiModal, Suppo
404
405 def _parse_and_validate_image_input(
406 self, **kwargs: object
407 - ) -> Optional[Cohere2VisionImagePixelInputs]:
407 + ) -> Cohere2VisionImagePixelInputs | None:
408 pixel_values = kwargs.pop("pixel_values", None)
409 num_patches = kwargs.pop("num_patches", None)
410 image_embeds = kwargs.pop("image_embeds", None)
@@ -450,10 +450,10 @@ class Cohere2VisionForConditionalGeneration(nn.Module, SupportsMultiModal, Suppo
450 self,
451 input_ids: torch.Tensor,
452 positions: torch.Tensor,
453 - intermediate_tensors: Optional[IntermediateTensors] = None,
454 - inputs_embeds: Optional[torch.Tensor] = None,
453 + intermediate_tensors: IntermediateTensors | None = None,
454 + inputs_embeds: torch.Tensor | None = None,
455 **kwargs: object,
456 - ) -> Union[torch.Tensor, IntermediateTensors]:
456 + ) -> torch.Tensor | IntermediateTensors:
457 if intermediate_tensors is not None:
458 inputs_embeds = None
459
@@ -468,5 +468,5 @@ class Cohere2VisionForConditionalGeneration(nn.Module, SupportsMultiModal, Suppo
468 def compute_logits(
469 self,
470 hidden_states: torch.Tensor,
471 - ) -> Optional[torch.Tensor]:
471 + ) -> torch.Tensor | None:
472 return self.language_model.compute_logits(hidden_states)
vllm/model_executor/models/commandr.py
+16 -17
@@ -25,7 +25,6 @@
25
26 from collections.abc import Iterable
27 from itertools import islice
28 -from typing import Optional, Union
28
29 import torch
30 from torch import nn
@@ -94,8 +93,8 @@ class LayerNorm(nn.Module):
93 class CohereMLP(nn.Module):
94 def __init__(
95 self,
97 - config: Union[CohereConfig, Cohere2Config],
98 - quant_config: Optional[QuantizationConfig] = None,
96 + config: CohereConfig | Cohere2Config,
97 + quant_config: QuantizationConfig | None = None,
98 prefix: str = "",
99 ):
100 super().__init__()
@@ -128,9 +127,9 @@ class CohereMLP(nn.Module):
127 class CohereAttention(nn.Module):
128 def __init__(
129 self,
131 - config: Union[CohereConfig, Cohere2Config],
132 - cache_config: Optional[CacheConfig] = None,
133 - quant_config: Optional[QuantizationConfig] = None,
130 + config: CohereConfig | Cohere2Config,
131 + cache_config: CacheConfig | None = None,
132 + quant_config: QuantizationConfig | None = None,
133 prefix: str = "",
134 ):
135 super().__init__()
@@ -241,9 +240,9 @@ class CohereAttention(nn.Module):
240 class CohereDecoderLayer(nn.Module):
241 def __init__(
242 self,
244 - config: Union[CohereConfig, Cohere2Config],
245 - cache_config: Optional[CacheConfig] = None,
246 - quant_config: Optional[QuantizationConfig] = None,
243 + config: CohereConfig | Cohere2Config,
244 + cache_config: CacheConfig | None = None,
245 + quant_config: QuantizationConfig | None = None,
246 prefix: str = "",
247 ):
248 super().__init__()
@@ -265,7 +264,7 @@ class CohereDecoderLayer(nn.Module):
264 self,
265 positions: torch.Tensor,
266 hidden_states: torch.Tensor,
268 - residual: Optional[torch.Tensor],
267 + residual: torch.Tensor | None,
268 ) -> tuple[torch.Tensor, torch.Tensor]:
269 # Self Attention
270 residual = hidden_states
@@ -324,9 +323,9 @@ class CohereModel(nn.Module):
323 self,
324 input_ids: torch.Tensor,
325 positions: torch.Tensor,
327 - intermediate_tensors: Optional[IntermediateTensors],
328 - inputs_embeds: Optional[torch.Tensor] = None,
329 - ) -> Union[torch.Tensor, IntermediateTensors]:
326 + intermediate_tensors: IntermediateTensors | None,
327 + inputs_embeds: torch.Tensor | None = None,
328 + ) -> torch.Tensor | IntermediateTensors:
329 if get_pp_group().is_first_rank:
330 if inputs_embeds is not None:
331 hidden_states = inputs_embeds
@@ -452,9 +451,9 @@ class CohereForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsQuant):
451 self,
452 input_ids: torch.Tensor,
453 positions: torch.Tensor,
455 - intermediate_tensors: Optional[IntermediateTensors] = None,
456 - inputs_embeds: Optional[torch.Tensor] = None,
457 - ) -> Union[torch.Tensor, IntermediateTensors]:
454 + intermediate_tensors: IntermediateTensors | None = None,
455 + inputs_embeds: torch.Tensor | None = None,
456 + ) -> torch.Tensor | IntermediateTensors:
457 hidden_states = self.model(
458 input_ids, positions, intermediate_tensors, inputs_embeds
459 )
@@ -463,7 +462,7 @@ class CohereForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsQuant):
462 def compute_logits(
463 self,
464 hidden_states: torch.Tensor,
466 - ) -> Optional[torch.Tensor]:
465 + ) -> torch.Tensor | None:
466 is_not_lora = hasattr(self.model.embed_tokens, "weight")
467 if is_not_lora:
468 logits = self.logits_processor(self.model.embed_tokens, hidden_states)
vllm/model_executor/models/dbrx.py
+18 -19
@@ -3,7 +3,6 @@
3
4 from collections.abc import Iterable
5 from itertools import islice
6 -from typing import Optional, Union
6
7 import torch
8 import torch.nn as nn
@@ -54,7 +53,7 @@ class DbrxRouter(nn.Module):
53 def __init__(
54 self,
55 config: DbrxConfig,
57 - params_dtype: Optional[torch.dtype] = None,
56 + params_dtype: torch.dtype | None = None,
57 ):
58 super().__init__()
59 self.tp_size = get_tensor_model_parallel_world_size()
@@ -77,8 +76,8 @@ class DbrxExperts(FusedMoE):
76 def __init__(
77 self,
78 config: DbrxConfig,
80 - quant_config: Optional[QuantizationConfig] = None,
81 - params_dtype: Optional[torch.dtype] = None,
79 + quant_config: QuantizationConfig | None = None,
80 + params_dtype: torch.dtype | None = None,
81 prefix: str = "",
82 ):
83 super().__init__(
@@ -157,8 +156,8 @@ class DbrxMoE(nn.Module):
156 def __init__(
157 self,
158 config: DbrxConfig,
160 - quant_config: Optional[QuantizationConfig] = None,
161 - params_dtype: Optional[torch.dtype] = None,
159 + quant_config: QuantizationConfig | None = None,
160 + params_dtype: torch.dtype | None = None,
161 prefix: str = "",
162 ):
163 super().__init__()
@@ -189,8 +188,8 @@ class DbrxAttention(nn.Module):
188 def __init__(
189 self,
190 config: DbrxConfig,
192 - cache_config: Optional[CacheConfig] = None,
193 - quant_config: Optional[QuantizationConfig] = None,
191 + cache_config: CacheConfig | None = None,
192 + quant_config: QuantizationConfig | None = None,
193 prefix: str = "",
194 ):
195 super().__init__()
@@ -270,8 +269,8 @@ class DbrxFusedNormAttention(nn.Module):
269 def __init__(
270 self,
271 config: DbrxConfig,
273 - cache_config: Optional[CacheConfig] = None,
274 - quant_config: Optional[QuantizationConfig] = None,
272 + cache_config: CacheConfig | None = None,
273 + quant_config: QuantizationConfig | None = None,
274 prefix: str = "",
275 ):
276 super().__init__()
@@ -303,8 +302,8 @@ class DbrxBlock(nn.Module):
302 def __init__(
303 self,
304 config: DbrxConfig,
306 - cache_config: Optional[CacheConfig] = None,
307 - quant_config: Optional[QuantizationConfig] = None,
305 + cache_config: CacheConfig | None = None,
306 + quant_config: QuantizationConfig | None = None,
307 prefix: str = "",
308 ):
309 super().__init__()
@@ -361,9 +360,9 @@ class DbrxModel(nn.Module):
360 self,
361 input_ids: torch.Tensor,
362 position_ids: torch.Tensor,
364 - intermediate_tensors: Optional[IntermediateTensors],
365 - inputs_embeds: Optional[torch.Tensor] = None,
366 - ) -> Union[torch.Tensor, IntermediateTensors]:
363 + intermediate_tensors: IntermediateTensors | None,
364 + inputs_embeds: torch.Tensor | None = None,
365 + ) -> torch.Tensor | IntermediateTensors:
366 if get_pp_group().is_first_rank:
367 if inputs_embeds is not None:
368 hidden_states = inputs_embeds
@@ -466,9 +465,9 @@ class DbrxForCausalLM(nn.Module, SupportsPP):
465 self,
466 input_ids: torch.Tensor,
467 positions: torch.Tensor,
469 - intermediate_tensors: Optional[IntermediateTensors] = None,
470 - inputs_embeds: Optional[torch.Tensor] = None,
471 - ) -> Union[torch.Tensor, IntermediateTensors]:
468 + intermediate_tensors: IntermediateTensors | None = None,
469 + inputs_embeds: torch.Tensor | None = None,
470 + ) -> torch.Tensor | IntermediateTensors:
471 hidden_states = self.transformer(
472 input_ids, positions, intermediate_tensors, inputs_embeds
473 )
@@ -477,7 +476,7 @@ class DbrxForCausalLM(nn.Module, SupportsPP):
476 def compute_logits(
477 self,
478 hidden_states: torch.Tensor,
480 - ) -> Optional[torch.Tensor]:
479 + ) -> torch.Tensor | None:
480 logits = self.logits_processor(self.lm_head, hidden_states)
481 return logits
482
vllm/model_executor/models/deepseek.py
+16 -16
@@ -26,7 +26,7 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Any, Optional, Union
29 +from typing import Any
30
31 import torch
32 from torch import nn
@@ -76,7 +76,7 @@ class DeepseekMLP(nn.Module):
76 hidden_size: int,
77 intermediate_size: int,
78 hidden_act: str,
79 - quant_config: Optional[QuantizationConfig] = None,
79 + quant_config: QuantizationConfig | None = None,
80 reduce_results: bool = True,
81 prefix: str = "",
82 ) -> None:
@@ -108,7 +108,7 @@ class DeepseekMoE(nn.Module):
108 def __init__(
109 self,
110 config: PretrainedConfig,
111 - quant_config: Optional[QuantizationConfig] = None,
111 + quant_config: QuantizationConfig | None = None,
112 prefix: str = "",
113 ):
114 super().__init__()
@@ -203,10 +203,10 @@ class DeepseekAttention(nn.Module):
203 num_heads: int,
204 num_kv_heads: int,
205 rope_theta: float = 10000,
206 - rope_scaling: Optional[dict[str, Any]] = None,
206 + rope_scaling: dict[str, Any] | None = None,
207 max_position_embeddings: int = 8192,
208 - cache_config: Optional[CacheConfig] = None,
209 - quant_config: Optional[QuantizationConfig] = None,
208 + cache_config: CacheConfig | None = None,
209 + quant_config: QuantizationConfig | None = None,
210 prefix: str = "",
211 ) -> None:
212 super().__init__()
@@ -282,8 +282,8 @@ class DeepseekDecoderLayer(nn.Module):
282 def __init__(
283 self,
284 config: PretrainedConfig,
285 - cache_config: Optional[CacheConfig] = None,
286 - quant_config: Optional[QuantizationConfig] = None,
285 + cache_config: CacheConfig | None = None,
286 + quant_config: QuantizationConfig | None = None,
287 prefix: str = "",
288 ) -> None:
289 super().__init__()
@@ -328,7 +328,7 @@ class DeepseekDecoderLayer(nn.Module):
328 self,
329 positions: torch.Tensor,
330 hidden_states: torch.Tensor,
331 - residual: Optional[torch.Tensor],
331 + residual: torch.Tensor | None,
332 ) -> torch.Tensor:
333 # Self Attention
334 if residual is None:
@@ -382,9 +382,9 @@ class DeepseekModel(nn.Module):
382 self,
383 input_ids: torch.Tensor,
384 positions: torch.Tensor,
385 - intermediate_tensors: Optional[IntermediateTensors],
386 - inputs_embeds: Optional[torch.Tensor] = None,
387 - ) -> Union[torch.Tensor, IntermediateTensors]:
385 + intermediate_tensors: IntermediateTensors | None,
386 + inputs_embeds: torch.Tensor | None = None,
387 + ) -> torch.Tensor | IntermediateTensors:
388 if get_pp_group().is_first_rank:
389 if inputs_embeds is not None:
390 hidden_states = inputs_embeds
@@ -489,9 +489,9 @@ class DeepseekForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
489 self,
490 input_ids: torch.Tensor,
491 positions: torch.Tensor,
492 - intermediate_tensors: Optional[IntermediateTensors] = None,
493 - inputs_embeds: Optional[torch.Tensor] = None,
494 - ) -> Union[torch.Tensor, IntermediateTensors]:
492 + intermediate_tensors: IntermediateTensors | None = None,
493 + inputs_embeds: torch.Tensor | None = None,
494 + ) -> torch.Tensor | IntermediateTensors:
495 hidden_states = self.model(
496 input_ids, positions, intermediate_tensors, inputs_embeds
497 )
@@ -500,7 +500,7 @@ class DeepseekForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
500 def compute_logits(
501 self,
502 hidden_states: torch.Tensor,
503 - ) -> Optional[torch.Tensor]:
503 + ) -> torch.Tensor | None:
504 logits = self.logits_processor(self.lm_head, hidden_states)
505 return logits
506
vllm/model_executor/models/deepseek_eagle.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable
5 -from typing import Optional
5
6 import torch
7 import torch.nn as nn
@@ -224,7 +223,7 @@ class EagleDeepseekV3ForCausalLM(DeepseekV3ForCausalLM):
223 input_ids: torch.Tensor,
224 positions: torch.Tensor,
225 hidden_states: torch.Tensor,
227 - inputs_embeds: Optional[torch.Tensor] = None,
226 + inputs_embeds: torch.Tensor | None = None,
227 ) -> tuple[torch.Tensor, torch.Tensor]:
228 if inputs_embeds is not None:
229 raise NotImplementedError(
@@ -235,7 +234,7 @@ class EagleDeepseekV3ForCausalLM(DeepseekV3ForCausalLM):
234 def compute_logits(
235 self,
236 hidden_states: torch.Tensor,
238 - ) -> Optional[torch.Tensor]:
237 + ) -> torch.Tensor | None:
238 logits = self.logits_processor(self.lm_head, hidden_states)
239 return logits
240
vllm/model_executor/models/deepseek_mtp.py
+6 -7
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable
4 -from typing import Optional
4
5 import torch
6 import torch.nn as nn
@@ -30,7 +29,7 @@ class SharedHead(nn.Module):
29 self,
30 config: PretrainedConfig,
31 prefix: str,
33 - quant_config: Optional[QuantizationConfig] = None,
32 + quant_config: QuantizationConfig | None = None,
33 ) -> None:
34 super().__init__()
35 self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
@@ -84,7 +83,7 @@ class DeepSeekMultiTokenPredictorLayer(nn.Module):
83 input_ids: torch.Tensor,
84 positions: torch.Tensor,
85 previous_hidden_states: torch.Tensor,
87 - inputs_embeds: Optional[torch.Tensor] = None,
86 + inputs_embeds: torch.Tensor | None = None,
87 spec_step_index: int = 0,
88 ) -> torch.Tensor:
89 assert inputs_embeds is not None
@@ -136,7 +135,7 @@ class DeepSeekMultiTokenPredictor(nn.Module):
135 input_ids: torch.Tensor,
136 positions: torch.Tensor,
137 previous_hidden_states: torch.Tensor,
139 - inputs_embeds: Optional[torch.Tensor] = None,
138 + inputs_embeds: torch.Tensor | None = None,
139 spec_step_idx: int = 0,
140 ) -> torch.Tensor:
141 if inputs_embeds is None:
@@ -180,8 +179,8 @@ class DeepSeekMTP(nn.Module, SupportsPP):
179 input_ids: torch.Tensor,
180 positions: torch.Tensor,
181 hidden_states: torch.Tensor,
183 - intermediate_tensors: Optional[IntermediateTensors] = None,
184 - inputs_embeds: Optional[torch.Tensor] = None,
182 + intermediate_tensors: IntermediateTensors | None = None,
183 + inputs_embeds: torch.Tensor | None = None,
184 spec_step_idx: int = 0,
185 ) -> torch.Tensor:
186 hidden_states = self.model(
@@ -193,7 +192,7 @@ class DeepSeekMTP(nn.Module, SupportsPP):
192 self,
193 hidden_states: torch.Tensor,
194 spec_step_idx: int = 0,
196 - ) -> Optional[torch.Tensor]:
195 + ) -> torch.Tensor | None:
196 return self.model.compute_logits(hidden_states, spec_step_idx)
197
198 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/deepseek_v2.py
+35 -35
@@ -27,7 +27,7 @@
27 import typing
28 from collections.abc import Callable, Iterable
29 from itertools import islice
30 -from typing import Any, Optional, Union
30 +from typing import Any
31
32 import torch
33 from torch import nn
@@ -106,7 +106,7 @@ class DeepseekV2MLP(nn.Module):
106 hidden_size: int,
107 intermediate_size: int,
108 hidden_act: str,
109 - quant_config: Optional[QuantizationConfig] = None,
109 + quant_config: QuantizationConfig | None = None,
110 reduce_results: bool = True,
111 is_sequence_parallel=False,
112 prefix: str = "",
@@ -150,9 +150,9 @@ class DeepseekV2MLP(nn.Module):
150 class DeepseekV2MoE(nn.Module):
151 def __init__(
152 self,
153 - config: Union[DeepseekV2Config, DeepseekV3Config],
153 + config: DeepseekV2Config | DeepseekV3Config,
154 parallel_config: ParallelConfig,
155 - quant_config: Optional[QuantizationConfig] = None,
155 + quant_config: QuantizationConfig | None = None,
156 prefix: str = "",
157 ):
158 super().__init__()
@@ -301,7 +301,7 @@ class DeepseekV2Attention(nn.Module):
301 def __init__(
302 self,
303 vllm_config: VllmConfig,
304 - config: Union[DeepseekV2Config, DeepseekV3Config],
304 + config: DeepseekV2Config | DeepseekV3Config,
305 hidden_size: int,
306 num_heads: int,
307 qk_nope_head_dim: int,
@@ -310,11 +310,11 @@ class DeepseekV2Attention(nn.Module):
310 q_lora_rank: int,
311 kv_lora_rank: int,
312 rope_theta: float = 10000,
313 - rope_scaling: Optional[dict[str, Any]] = None,
313 + rope_scaling: dict[str, Any] | None = None,
314 max_position_embeddings: int = 8192,
315 - cache_config: Optional[CacheConfig] = None,
316 - quant_config: Optional[QuantizationConfig] = None,
317 - topk_indices_buffer: Optional[torch.Tensor] = None,
315 + cache_config: CacheConfig | None = None,
316 + quant_config: QuantizationConfig | None = None,
317 + topk_indices_buffer: torch.Tensor | None = None,
318 prefix: str = "",
319 ) -> None:
320 super().__init__()
@@ -554,12 +554,12 @@ def sparse_attn_indexer(
554 k: torch.Tensor,
555 weights: torch.Tensor,
556 quant_block_size: int,
557 - scale_fmt: Optional[str],
557 + scale_fmt: str | None,
558 topk_tokens: int,
559 head_dim: int,
560 max_model_len: int,
561 total_seq_lens: int,
562 - topk_indices_buffer: Optional[torch.Tensor],
562 + topk_indices_buffer: torch.Tensor | None,
563 ) -> torch.Tensor:
564 # careful! this will be None in dummy run
565 attn_metadata = get_forward_context().attn_metadata
@@ -727,12 +727,12 @@ def sparse_attn_indexer_fake(
727 k: torch.Tensor,
728 weights: torch.Tensor,
729 quant_block_size: int,
730 - scale_fmt: Optional[str],
730 + scale_fmt: str | None,
731 topk_tokens: int,
732 head_dim: int,
733 max_model_len: int,
734 total_seq_lens: int,
735 - topk_indices_buffer: Optional[torch.Tensor],
735 + topk_indices_buffer: torch.Tensor | None,
736 ) -> torch.Tensor:
737 # profile run
738 # NOTE(Chen): create the max possible flattened_kv. So that
@@ -758,12 +758,12 @@ class Indexer(nn.Module):
758 def __init__(
759 self,
760 vllm_config: VllmConfig,
761 - config: Union[DeepseekV2Config, DeepseekV3Config],
761 + config: DeepseekV2Config | DeepseekV3Config,
762 hidden_size: int,
763 q_lora_rank: int,
764 - quant_config: Optional[QuantizationConfig],
765 - cache_config: Optional[CacheConfig],
766 - topk_indices_buffer: Optional[torch.Tensor],
764 + quant_config: QuantizationConfig | None,
765 + cache_config: CacheConfig | None,
766 + topk_indices_buffer: torch.Tensor | None,
767 prefix: str = "",
768 ):
769 super().__init__()
@@ -880,21 +880,21 @@ class DeepseekV2MLAAttention(nn.Module):
880 def __init__(
881 self,
882 vllm_config: VllmConfig,
883 - config: Union[DeepseekV2Config, DeepseekV3Config],
883 + config: DeepseekV2Config | DeepseekV3Config,
884 hidden_size: int,
885 num_heads: int,
886 qk_nope_head_dim: int,
887 qk_rope_head_dim: int,
888 v_head_dim: int,
889 - q_lora_rank: Optional[int],
889 + q_lora_rank: int | None,
890 kv_lora_rank: int,
891 rope_theta: float = 10000,
892 - rope_scaling: Optional[dict[str, Any]] = None,
892 + rope_scaling: dict[str, Any] | None = None,
893 max_position_embeddings: int = 8192,
894 - cache_config: Optional[CacheConfig] = None,
895 - quant_config: Optional[QuantizationConfig] = None,
894 + cache_config: CacheConfig | None = None,
895 + quant_config: QuantizationConfig | None = None,
896 prefix: str = "",
897 - topk_indices_buffer: Optional[torch.Tensor] = None,
897 + topk_indices_buffer: torch.Tensor | None = None,
898 ) -> None:
899 super().__init__()
900 self.hidden_size = hidden_size
@@ -1045,8 +1045,8 @@ class DeepseekV2DecoderLayer(nn.Module):
1045 self,
1046 vllm_config: VllmConfig,
1047 prefix: str,
1048 - config: Optional[DeepseekV2Config] = None,
1049 - topk_indices_buffer: Optional[torch.Tensor] = None,
1048 + config: DeepseekV2Config | None = None,
1049 + topk_indices_buffer: torch.Tensor | None = None,
1050 ) -> None:
1051 super().__init__()
1052
@@ -1117,7 +1117,7 @@ class DeepseekV2DecoderLayer(nn.Module):
1117 self,
1118 positions: torch.Tensor,
1119 hidden_states: torch.Tensor,
1120 - residual: Optional[torch.Tensor],
1120 + residual: torch.Tensor | None,
1121 ) -> torch.Tensor:
1122 # Self Attention
1123 if residual is None:
@@ -1212,9 +1212,9 @@ class DeepseekV2Model(nn.Module):
1212 self,
1213 input_ids: torch.Tensor,
1214 positions: torch.Tensor,
1215 - intermediate_tensors: Optional[IntermediateTensors],
1216 - inputs_embeds: Optional[torch.Tensor] = None,
1217 - ) -> Union[torch.Tensor, IntermediateTensors]:
1215 + intermediate_tensors: IntermediateTensors | None,
1216 + inputs_embeds: torch.Tensor | None = None,
1217 + ) -> torch.Tensor | IntermediateTensors:
1218 if get_pp_group().is_first_rank:
1219 if inputs_embeds is not None:
1220 hidden_states = inputs_embeds
@@ -1347,9 +1347,9 @@ class DeepseekV2ForCausalLM(nn.Module, SupportsPP, MixtureOfExperts, SupportsLoR
1347 self,
1348 input_ids: torch.Tensor,
1349 positions: torch.Tensor,
1350 - intermediate_tensors: Optional[IntermediateTensors] = None,
1351 - inputs_embeds: Optional[torch.Tensor] = None,
1352 - ) -> Union[torch.Tensor, IntermediateTensors]:
1350 + intermediate_tensors: IntermediateTensors | None = None,
1351 + inputs_embeds: torch.Tensor | None = None,
1352 + ) -> torch.Tensor | IntermediateTensors:
1353 hidden_states = self.model(
1354 input_ids, positions, intermediate_tensors, inputs_embeds
1355 )
@@ -1358,7 +1358,7 @@ class DeepseekV2ForCausalLM(nn.Module, SupportsPP, MixtureOfExperts, SupportsLoR
1358 def compute_logits(
1359 self,
1360 hidden_states: torch.Tensor,
1361 - ) -> Optional[torch.Tensor]:
1361 + ) -> torch.Tensor | None:
1362 logits = self.logits_processor(self.lm_head, hidden_states)
1363 return logits
1364
@@ -1497,8 +1497,8 @@ class DeepseekV3ForCausalLM(DeepseekV2ForCausalLM):
1497 # Compatibility with
1498 # https://huggingface.co/deepseek-ai/DeepSeek-V3-Base/blob/main/configuration_deepseek.py
1499 def get_spec_layer_idx_from_weight_name(
1500 - config: Union[DeepseekV2Config, DeepseekV3Config], weight_name: str
1501 -) -> Optional[int]:
1500 + config: DeepseekV2Config | DeepseekV3Config, weight_name: str
1501 +) -> int | None:
1502 if (
1503 hasattr(config, "num_nextn_predict_layers")
1504 and config.num_nextn_predict_layers > 0
vllm/model_executor/models/deepseek_vl2.py
+15 -17
@@ -6,7 +6,7 @@
6
7 import math
8 from collections.abc import Iterable, Mapping, Sequence
9 -from typing import Annotated, Literal, Optional, Union
9 +from typing import Annotated, Literal, TypeAlias
10
11 import torch
12 import torch.nn as nn
@@ -88,14 +88,12 @@ class DeepseekVL2VImageEmbeddingInputs(TensorSchema):
88 """
89
90 type: Literal["image_embeds"]
91 - data: Annotated[
92 - Union[torch.Tensor, list[torch.Tensor]], TensorShape("bn", "f", "h")
93 - ]
91 + data: Annotated[torch.Tensor | list[torch.Tensor], TensorShape("bn", "f", "h")]
92
93
96 -DeepseekVL2ImageInputs = Union[
97 - DeepseekVL2ImagePixelInputs, DeepseekVL2VImageEmbeddingInputs
98 -]
94 +DeepseekVL2ImageInputs: TypeAlias = (
95 + DeepseekVL2ImagePixelInputs | DeepseekVL2VImageEmbeddingInputs
96 +)
97
98
99 class MlpProjector(nn.Module):
@@ -161,7 +159,7 @@ class DeepseekVL2ProcessingInfo(BaseProcessingInfo):
159 def get_hf_processor(self, **kwargs: object):
160 return self.ctx.get_hf_processor(DeepseekVLV2Processor, **kwargs)
161
164 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
162 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
163 return {"image": None}
164
165 def get_num_image_tokens(
@@ -214,7 +212,7 @@ class DeepseekVL2DummyInputsBuilder(BaseDummyInputsBuilder[DeepseekVL2Processing
212 self,
213 seq_len: int,
214 mm_counts: Mapping[str, int],
217 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
215 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
216 ) -> MultiModalDataDict:
217 num_images = mm_counts.get("image", 0)
218
@@ -310,11 +308,11 @@ class DeepseekVL2MultiModalProcessor(
308
309 def _cached_apply_hf_processor(
310 self,
313 - prompt: Union[str, list[int]],
311 + prompt: str | list[int],
312 mm_data_items: MultiModalDataItems,
313 hf_processor_mm_kwargs: Mapping[str, object],
314 tokenization_kwargs: Mapping[str, object],
317 - mm_uuids: Optional[MultiModalUUIDDict] = None,
315 + mm_uuids: MultiModalUUIDDict | None = None,
316 ) -> tuple[list[int], MultiModalProcessingInfo, bool]:
317 # The processor logic is different for len(images) <= 2 vs > 2
318 # Since the processing cache assumes that the processor output is
@@ -353,7 +351,7 @@ class DeepseekVLV2ForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
351 )
352
353 @classmethod
356 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
354 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
355 if modality.startswith("image"):
356 return "<image>"
357
@@ -454,7 +452,7 @@ class DeepseekVLV2ForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
452 def _init_vision_module(
453 self,
454 vision_config: VisionEncoderConfig,
457 - quant_config: Optional[QuantizationConfig],
455 + quant_config: QuantizationConfig | None,
456 prefix: str = "",
457 ) -> nn.Module:
458 # TODO: refactor vision model through timm wrapper from transformers
@@ -480,7 +478,7 @@ class DeepseekVLV2ForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
478
479 def _parse_and_validate_image_input(
480 self, **kwargs: object
483 - ) -> Optional[DeepseekVL2ImageInputs]:
481 + ) -> DeepseekVL2ImageInputs | None:
482 pixel_values = kwargs.pop("pixel_values", None)
483 images_spatial_crop = kwargs.pop("images_spatial_crop", None)
484 image_embeds = kwargs.pop("image_embeds", None)
@@ -637,8 +635,8 @@ class DeepseekVLV2ForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
635 self,
636 input_ids: torch.Tensor,
637 positions: torch.Tensor,
640 - intermediate_tensors: Optional[IntermediateTensors] = None,
641 - inputs_embeds: Optional[torch.Tensor] = None,
638 + intermediate_tensors: IntermediateTensors | None = None,
639 + inputs_embeds: torch.Tensor | None = None,
640 **kwargs: object,
641 ):
642 if intermediate_tensors is not None:
@@ -653,7 +651,7 @@ class DeepseekVLV2ForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
651 def compute_logits(
652 self,
653 hidden_states: torch.Tensor,
656 - ) -> Optional[torch.Tensor]:
654 + ) -> torch.Tensor | None:
655 return self.language_model.compute_logits(hidden_states)
656
657 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/dots1.py
+16 -16
@@ -27,7 +27,7 @@
27
28 from collections.abc import Iterable
29 from itertools import islice
30 -from typing import Any, Optional, Union
30 +from typing import Any
31
32 import torch
33 from torch import nn
@@ -80,7 +80,7 @@ class Dots1MLP(nn.Module):
80 hidden_size: int,
81 intermediate_size: int,
82 hidden_act: str,
83 - quant_config: Optional[QuantizationConfig] = None,
83 + quant_config: QuantizationConfig | None = None,
84 reduce_results: bool = True,
85 prefix: str = "",
86 ) -> None:
@@ -117,7 +117,7 @@ class Dots1MoE(nn.Module):
117 def __init__(
118 self,
119 config: Dots1Config,
120 - quant_config: Optional[QuantizationConfig] = None,
120 + quant_config: QuantizationConfig | None = None,
121 prefix: str = "",
122 ):
123 super().__init__()
@@ -203,10 +203,10 @@ class Dots1Attention(nn.Module):
203 num_kv_heads: int,
204 config: Dots1Config,
205 rope_theta: float = 10000,
206 - rope_scaling: Optional[dict[str, Any]] = None,
206 + rope_scaling: dict[str, Any] | None = None,
207 max_position_embeddings: int = 8192,
208 - cache_config: Optional[CacheConfig] = None,
209 - quant_config: Optional[QuantizationConfig] = None,
208 + cache_config: CacheConfig | None = None,
209 + quant_config: QuantizationConfig | None = None,
210 prefix: str = "",
211 ) -> None:
212 super().__init__()
@@ -289,8 +289,8 @@ class Dots1DecoderLayer(nn.Module):
289 config: Dots1Config,
290 prefix: str,
291 model_config: ModelConfig,
292 - cache_config: Optional[CacheConfig] = None,
293 - quant_config: Optional[QuantizationConfig] = None,
292 + cache_config: CacheConfig | None = None,
293 + quant_config: QuantizationConfig | None = None,
294 ) -> None:
295 super().__init__()
296 self.hidden_size = config.hidden_size
@@ -338,7 +338,7 @@ class Dots1DecoderLayer(nn.Module):
338 self,
339 positions: torch.Tensor,
340 hidden_states: torch.Tensor,
341 - residual: Optional[torch.Tensor],
341 + residual: torch.Tensor | None,
342 ) -> torch.Tensor:
343 if residual is None:
344 residual = hidden_states
@@ -403,9 +403,9 @@ class Dots1Model(nn.Module):
403 self,
404 input_ids: torch.Tensor,
405 positions: torch.Tensor,
406 - intermediate_tensors: Optional[IntermediateTensors],
407 - inputs_embeds: Optional[torch.Tensor] = None,
408 - ) -> Union[torch.Tensor, IntermediateTensors]:
406 + intermediate_tensors: IntermediateTensors | None,
407 + inputs_embeds: torch.Tensor | None = None,
408 + ) -> torch.Tensor | IntermediateTensors:
409 if get_pp_group().is_first_rank:
410 if inputs_embeds is not None:
411 hidden_states = inputs_embeds
@@ -546,9 +546,9 @@ class Dots1ForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
546 self,
547 input_ids: torch.Tensor,
548 positions: torch.Tensor,
549 - intermediate_tensors: Optional[IntermediateTensors] = None,
550 - inputs_embeds: Optional[torch.Tensor] = None,
551 - ) -> Union[torch.Tensor, IntermediateTensors]:
549 + intermediate_tensors: IntermediateTensors | None = None,
550 + inputs_embeds: torch.Tensor | None = None,
551 + ) -> torch.Tensor | IntermediateTensors:
552 hidden_states = self.model(
553 input_ids,
554 positions,
@@ -560,7 +560,7 @@ class Dots1ForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
560 def compute_logits(
561 self,
562 hidden_states: torch.Tensor,
563 - ) -> Optional[torch.Tensor]:
563 + ) -> torch.Tensor | None:
564 logits = self.logits_processor(self.lm_head, hidden_states)
565 return logits
566
vllm/model_executor/models/dots_ocr.py
+22 -22
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable, Mapping
4 -from typing import Annotated, Literal, Optional, Union
4 +from typing import Annotated, Literal, TypeAlias
5
6 import torch
7 import torch.nn as nn
@@ -92,7 +92,7 @@ class DotsOCRImageEmbeddingInputs(TensorSchema):
92 image_grid_thw: Annotated[torch.Tensor, TensorShape("ni", 3)]
93
94
95 -DotsOCRImageInputs = Union[DotsOCRImagePixelInputs, DotsOCRImageEmbeddingInputs]
95 +DotsOCRImageInputs: TypeAlias = DotsOCRImagePixelInputs | DotsOCRImageEmbeddingInputs
96
97
98 class DotsOCRDummyInputsBuilder(Qwen2VLDummyInputsBuilder):
@@ -104,7 +104,7 @@ class DotsOCRDummyInputsBuilder(Qwen2VLDummyInputsBuilder):
104 self,
105 seq_len: int,
106 mm_counts: Mapping[str, int],
107 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
107 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
108 ) -> MultiModalDataDict:
109 num_images = mm_counts.get("image", 0)
110
@@ -134,7 +134,7 @@ class DotsOCRProcessingInfo(Qwen2VLProcessingInfo):
134
135 return config
136
137 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
137 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
138 return {"image": None}
139
140 def get_mm_max_tokens_per_item(
@@ -253,7 +253,7 @@ class DotsVisionAttention(nn.Module):
253 num_heads: int = 16,
254 bias: bool = True,
255 *,
256 - quant_config: Optional[QuantizationConfig] = None,
256 + quant_config: QuantizationConfig | None = None,
257 prefix: str = "",
258 use_data_parallel: bool = False,
259 ) -> None:
@@ -316,10 +316,10 @@ class DotsVisionAttention(nn.Module):
316 self,
317 hidden_states: torch.Tensor,
318 cu_seqlens: torch.Tensor,
319 - rotary_pos_emb: Optional[torch.Tensor] = None,
319 + rotary_pos_emb: torch.Tensor | None = None,
320 *,
321 - max_seqlen: Optional[int] = None,
322 - seqlens: Optional[list[int]] = None,
321 + max_seqlen: int | None = None,
322 + seqlens: list[int] | None = None,
323 ) -> torch.Tensor:
324 # [S, C] -> [S, B=1, C]
325 x = hidden_states.unsqueeze(1)
@@ -394,7 +394,7 @@ class DotsSwiGLUFFN(nn.Module):
394 self,
395 config,
396 *,
397 - quant_config: Optional[QuantizationConfig] = None,
397 + quant_config: QuantizationConfig | None = None,
398 prefix: str = "",
399 use_data_parallel: bool = False,
400 ):
@@ -507,7 +507,7 @@ class DotsVisionBlock(nn.Module):
507 self,
508 config,
509 *,
510 - quant_config: Optional[QuantizationConfig] = None,
510 + quant_config: QuantizationConfig | None = None,
511 prefix: str = "",
512 use_data_parallel: bool = False,
513 ):
@@ -537,8 +537,8 @@ class DotsVisionBlock(nn.Module):
537 *,
538 cu_seqlens: torch.Tensor,
539 rotary_pos_emb: torch.Tensor,
540 - max_seqlen: Optional[int] = None,
541 - seqlens: Optional[list[int]] = None,
540 + max_seqlen: int | None = None,
541 + seqlens: list[int] | None = None,
542 ) -> torch.Tensor:
543 hidden_states = hidden_states + self.attn(
544 self.norm1(hidden_states),
@@ -555,10 +555,10 @@ class DotsVisionTransformer(nn.Module):
555 def __init__(
556 self,
557 config: DotsVisionConfig,
558 - quant_config: Optional[QuantizationConfig] = None,
558 + quant_config: QuantizationConfig | None = None,
559 *,
560 - num_hidden_layers_override: Optional[int] = None,
561 - require_post_norm: Optional[bool] = None,
560 + num_hidden_layers_override: int | None = None,
561 + require_post_norm: bool | None = None,
562 prefix: str = "",
563 use_data_parallel: bool = False,
564 ) -> None:
@@ -653,7 +653,7 @@ class DotsVisionTransformer(nn.Module):
653
654 def compute_attn_mask_seqlen(
655 self, cu_seqlens: torch.Tensor
656 - ) -> tuple[Optional[int], Optional[list[int]]]:
656 + ) -> tuple[int | None, list[int] | None]:
657 max_seqlen, seqlens = None, None
658 if (
659 self.attn_backend == _Backend.FLASH_ATTN
@@ -734,7 +734,7 @@ class DotsOCRForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA
734 supports_encoder_tp_data = True
735
736 @classmethod
737 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
737 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
738 if modality.startswith("image"):
739 return "<|img|><|imgpad|><|endofimg|>"
740
@@ -765,7 +765,7 @@ class DotsOCRForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA
765
766 def _parse_and_validate_image_input(
767 self, **kwargs: object
768 - ) -> Optional[DotsOCRImageInputs]:
768 + ) -> DotsOCRImageInputs | None:
769 pixel_values = kwargs.pop("pixel_values", None)
770 image_embeds = kwargs.pop("image_embeds", None)
771 image_grid_thw = kwargs.pop("image_grid_thw", None)
@@ -834,10 +834,10 @@ class DotsOCRForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA
834 self,
835 input_ids: torch.Tensor,
836 positions: torch.Tensor,
837 - intermediate_tensors: Optional[IntermediateTensors] = None,
838 - inputs_embeds: Optional[torch.Tensor] = None,
837 + intermediate_tensors: IntermediateTensors | None = None,
838 + inputs_embeds: torch.Tensor | None = None,
839 **kwargs,
840 - ) -> Union[torch.Tensor, IntermediateTensors]:
840 + ) -> torch.Tensor | IntermediateTensors:
841 if intermediate_tensors is not None:
842 inputs_embeds = None
843 elif inputs_embeds is None:
@@ -861,7 +861,7 @@ class DotsOCRForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA
861 def compute_logits(
862 self,
863 hidden_states: torch.Tensor,
864 - ) -> Optional[torch.Tensor]:
864 + ) -> torch.Tensor | None:
865 return self.language_model.compute_logits(hidden_states)
866
867 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/ernie45_moe.py
+17 -17
@@ -25,7 +25,7 @@
25
26 from collections.abc import Iterable
27 from itertools import islice
28 -from typing import Any, Optional, Union
28 +from typing import Any
29
30 import torch
31 from torch import nn
@@ -83,7 +83,7 @@ class Ernie4_5_MoeMLP(nn.Module):
83 intermediate_size: int,
84 hidden_act: str,
85 use_bias: bool = False,
86 - quant_config: Optional[QuantizationConfig] = None,
86 + quant_config: QuantizationConfig | None = None,
87 reduce_results: bool = True,
88 prefix: str = "",
89 ) -> None:
@@ -120,7 +120,7 @@ class Ernie4_5_MoeMoE(nn.Module):
120 def __init__(
121 self,
122 config: PretrainedConfig,
123 - quant_config: Optional[QuantizationConfig] = None,
123 + quant_config: QuantizationConfig | None = None,
124 prefix: str = "",
125 enable_eplb: bool = False,
126 ):
@@ -229,14 +229,14 @@ class Ernie4_5_MoeAttention(nn.Module):
229 hidden_size: int,
230 num_heads: int,
231 num_kv_heads: int,
232 - head_dim: Optional[int] = None,
232 + head_dim: int | None = None,
233 rope_theta: float = 500000,
234 - rope_scaling: Optional[dict[str, Any]] = None,
234 + rope_scaling: dict[str, Any] | None = None,
235 max_position_embeddings: int = 131072,
236 rms_norm_eps: float = 1e-05,
237 qkv_bias: bool = False,
238 - cache_config: Optional[CacheConfig] = None,
239 - quant_config: Optional[QuantizationConfig] = None,
238 + cache_config: CacheConfig | None = None,
239 + quant_config: QuantizationConfig | None = None,
240 prefix: str = "",
241 ) -> None:
242 super().__init__()
@@ -323,8 +323,8 @@ class Ernie4_5_MoeDecoderLayer(nn.Module):
323 def __init__(
324 self,
325 config: PretrainedConfig,
326 - cache_config: Optional[CacheConfig] = None,
327 - quant_config: Optional[QuantizationConfig] = None,
326 + cache_config: CacheConfig | None = None,
327 + quant_config: QuantizationConfig | None = None,
328 prefix: str = "",
329 enable_eplb: bool = False,
330 ) -> None:
@@ -391,7 +391,7 @@ class Ernie4_5_MoeDecoderLayer(nn.Module):
391 self,
392 positions: torch.Tensor,
393 hidden_states: torch.Tensor,
394 - residual: Optional[torch.Tensor],
394 + residual: torch.Tensor | None,
395 ) -> torch.Tensor:
396 # Self Attention
397 if residual is None:
@@ -467,9 +467,9 @@ class Ernie4_5_MoeModel(nn.Module):
467 self,
468 input_ids: torch.Tensor,
469 positions: torch.Tensor,
470 - intermediate_tensors: Optional[IntermediateTensors] = None,
471 - inputs_embeds: Optional[torch.Tensor] = None,
472 - ) -> Union[torch.Tensor, IntermediateTensors]:
470 + intermediate_tensors: IntermediateTensors | None = None,
471 + inputs_embeds: torch.Tensor | None = None,
472 + ) -> torch.Tensor | IntermediateTensors:
473 if get_pp_group().is_first_rank:
474 if inputs_embeds is not None:
475 hidden_states = inputs_embeds
@@ -737,9 +737,9 @@ class Ernie4_5_MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA, MixtureOfExpe
737 self,
738 input_ids: torch.Tensor,
739 positions: torch.Tensor,
740 - intermediate_tensors: Optional[IntermediateTensors] = None,
741 - inputs_embeds: Optional[torch.Tensor] = None,
742 - ) -> Union[torch.Tensor, IntermediateTensors]:
740 + intermediate_tensors: IntermediateTensors | None = None,
741 + inputs_embeds: torch.Tensor | None = None,
742 + ) -> torch.Tensor | IntermediateTensors:
743 hidden_states = self.model(
744 input_ids, positions, intermediate_tensors, inputs_embeds
745 )
@@ -748,7 +748,7 @@ class Ernie4_5_MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA, MixtureOfExpe
748 def compute_logits(
749 self,
750 hidden_states: torch.Tensor,
751 - ) -> Optional[torch.Tensor]:
751 + ) -> torch.Tensor | None:
752 logits = self.logits_processor(self.lm_head, hidden_states)
753 return logits
754
vllm/model_executor/models/ernie45_vl.py
+34 -34
@@ -25,9 +25,9 @@
25
26 import itertools
27 import math
28 -from collections.abc import Iterable, Mapping, Sequence
28 +from collections.abc import Callable, Iterable, Mapping, Sequence
29 from functools import partial
30 -from typing import Annotated, Any, Callable, Literal, Optional, Union
30 +from typing import Annotated, Any, Literal
31
32 import numpy as np
33 import torch
@@ -162,7 +162,7 @@ class Ernie4_5_VisionAttention(nn.Module):
162 embed_dim: int,
163 num_heads: int,
164 projection_size: int,
165 - quant_config: Optional[QuantizationConfig] = None,
165 + quant_config: QuantizationConfig | None = None,
166 prefix: str = "",
167 ) -> None:
168 super().__init__()
@@ -254,8 +254,8 @@ class Ernie4_5_VisionAttention(nn.Module):
254 x: torch.Tensor,
255 cu_seqlens: torch.Tensor,
256 rotary_pos_emb: torch.Tensor,
257 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
258 - seqlens: Optional[list[int]] = None, # Only used for xFormers
257 + max_seqlen: int | None = None, # Only used for Flash Attention
258 + seqlens: list[int] | None = None, # Only used for xFormers
259 ) -> torch.Tensor:
260 # [s, b, c] --> [s, b, head * 3 * head_dim]
261 x, _ = self.qkv(x)
@@ -332,7 +332,7 @@ class Ernie4_5_VisionMLP(nn.Module):
332 in_features: int,
333 hidden_features: int,
334 act_layer: type[nn.Module] = QuickGELU,
335 - quant_config: Optional[QuantizationConfig] = None,
335 + quant_config: QuantizationConfig | None = None,
336 prefix: str = "",
337 ):
338 super().__init__()
@@ -364,8 +364,8 @@ class Ernie4_5_VisionBlock(nn.Module):
364 num_heads: int,
365 mlp_ratio: float,
366 act_layer: type[nn.Module] = QuickGELU,
367 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
368 - quant_config: Optional[QuantizationConfig] = None,
367 + norm_layer: Callable[[int], nn.Module] | None = None,
368 + quant_config: QuantizationConfig | None = None,
369 prefix: str = "",
370 ) -> None:
371 super().__init__()
@@ -397,8 +397,8 @@ class Ernie4_5_VisionBlock(nn.Module):
397 hidden_states: torch.Tensor,
398 cu_seqlens: torch.Tensor,
399 rotary_pos_emb: torch.Tensor,
400 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
401 - seqlens: Optional[list[int]] = None, # Only used for xFormers
400 + max_seqlen: int | None = None, # Only used for Flash Attention
401 + seqlens: list[int] | None = None, # Only used for xFormers
402 ) -> torch.Tensor:
403 hidden_states = hidden_states + self.attn(
404 self.norm1(hidden_states),
@@ -456,7 +456,7 @@ class Ernie4_5_VisionTransformer(nn.Module):
456 self,
457 vision_config,
458 norm_eps: float = 1e-6,
459 - quant_config: Optional[QuantizationConfig] = None,
459 + quant_config: QuantizationConfig | None = None,
460 prefix: str = "",
461 ) -> None:
462 super().__init__()
@@ -553,7 +553,7 @@ class Ernie4_5_VisionTransformer(nn.Module):
553
554 def compute_attn_mask_seqlen(
555 self, cu_seqlens: torch.Tensor
556 - ) -> tuple[Optional[int], Optional[list[int]]]:
556 + ) -> tuple[int | None, list[int] | None]:
557 max_seqlen, seqlens = None, None
558 if (
559 self.attn_backend == _Backend.FLASH_ATTN
@@ -659,15 +659,15 @@ Ernie4_5_VLVideoInputs = Ernie4_5_VLVideoPixelInputs
659 # === Vision Processor === #
660
661
662 -def round_by_factor(number: Union[int, float], factor: int) -> int:
662 +def round_by_factor(number: int | float, factor: int) -> int:
663 return round(number / factor) * factor
664
665
666 -def ceil_by_factor(number: Union[int, float], factor: int) -> int:
666 +def ceil_by_factor(number: int | float, factor: int) -> int:
667 return math.ceil(number / factor) * factor
668
669
670 -def floor_by_factor(number: Union[int, float], factor: int) -> int:
670 +def floor_by_factor(number: int | float, factor: int) -> int:
671 return math.floor(number / factor) * factor
672
673
@@ -901,7 +901,7 @@ class Ernie4_5_VLProcessingInfo(BaseProcessingInfo):
901 def get_image_processor(self, **kwargs: object):
902 return self.get_hf_processor(**kwargs).image_processor
903
904 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
904 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
905 return {"image": None, "video": None}
906
907 def get_mm_max_tokens_per_item(
@@ -920,7 +920,7 @@ class Ernie4_5_VLProcessingInfo(BaseProcessingInfo):
920 image_height: int,
921 num_frames: int = 1,
922 do_resize: bool = True,
923 - image_processor: Optional[Any],
923 + image_processor: Any | None,
924 ) -> tuple[ImageSize, int]:
925 if image_processor is None:
926 image_processor = self.get_image_processor()
@@ -957,7 +957,7 @@ class Ernie4_5_VLProcessingInfo(BaseProcessingInfo):
957 *,
958 image_width: int,
959 image_height: int,
960 - image_processor: Optional[Any],
960 + image_processor: Any | None,
961 ) -> int:
962 _, num_image_tokens = self._get_vision_info(
963 image_width=image_width,
@@ -972,7 +972,7 @@ class Ernie4_5_VLProcessingInfo(BaseProcessingInfo):
972 image_width: int,
973 image_height: int,
974 num_frames: int,
975 - image_processor: Optional[Any],
975 + image_processor: Any | None,
976 ) -> int:
977 _, num_video_tokens = self._get_vision_info(
978 image_width=image_width,
@@ -1237,7 +1237,7 @@ class Ernie4_5_VLDummyInputsBuilder(BaseDummyInputsBuilder[Ernie4_5_VLProcessing
1237 self,
1238 seq_len: int,
1239 mm_counts: Mapping[str, int],
1240 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
1240 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
1241 ) -> MultiModalDataDict:
1242 num_images = mm_counts.get("image", 0)
1243 num_videos = mm_counts.get("video", 0)
@@ -1310,7 +1310,7 @@ class Ernie4_5_VLMoeForConditionalGeneration(
1310 )
1311
1312 @classmethod
1313 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1313 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1314 if modality.startswith("image"):
1315 return "<|IMAGE_START|><|image@placeholder|><|IMAGE_END|>"
1316 if modality.startswith("video"):
@@ -1356,7 +1356,7 @@ class Ernie4_5_VLMoeForConditionalGeneration(
1356 def compute_logits(
1357 self,
1358 hidden_states: torch.Tensor,
1359 - ) -> Optional[torch.Tensor]:
1359 + ) -> torch.Tensor | None:
1360 """compute logits"""
1361 return self.language_model.compute_logits(hidden_states)
1362
@@ -1395,12 +1395,12 @@ class Ernie4_5_VLMoeForConditionalGeneration(
1395 cls,
1396 input_tokens: list[int],
1397 hf_config: PretrainedConfig,
1398 - image_grid_thw: Union[list[list[int]], torch.Tensor],
1399 - video_grid_thw: Union[list[list[int]], torch.Tensor],
1398 + image_grid_thw: list[list[int]] | torch.Tensor,
1399 + video_grid_thw: list[list[int]] | torch.Tensor,
1400 context_len: int = 0,
1401 - seq_len: Optional[int] = None,
1402 - second_per_grid_ts: Optional[list[float]] = None,
1403 - audio_feature_lengths: Optional[torch.Tensor] = None,
1401 + seq_len: int | None = None,
1402 + second_per_grid_ts: list[float] | None = None,
1403 + audio_feature_lengths: torch.Tensor | None = None,
1404 use_audio_in_video: bool = False,
1405 ) -> tuple[torch.Tensor, int]:
1406 """Get mrope input positions and delta value for Ernie VL."""
@@ -1540,7 +1540,7 @@ class Ernie4_5_VLMoeForConditionalGeneration(
1540
1541 def _parse_and_validate_image_input(
1542 self, **kwargs: object
1543 - ) -> Optional[Ernie4_5_VLImageInputs]:
1543 + ) -> Ernie4_5_VLImageInputs | None:
1544 pixel_values = kwargs.pop("pixel_values", None)
1545 image_grid_thw = kwargs.pop("image_grid_thw", None)
1546
@@ -1556,7 +1556,7 @@ class Ernie4_5_VLMoeForConditionalGeneration(
1556
1557 def _parse_and_validate_video_input(
1558 self, **kwargs: object
1559 - ) -> Optional[Ernie4_5_VLVideoInputs]:
1559 + ) -> Ernie4_5_VLVideoInputs | None:
1560 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
1561 video_grid_thw = kwargs.pop("video_grid_thw", None)
1562
@@ -1631,7 +1631,7 @@ class Ernie4_5_VLMoeForConditionalGeneration(
1631
1632 def get_multimodal_embeddings(
1633 self, **kwargs: object
1634 - ) -> Optional[MultiModalEmbeddings]:
1634 + ) -> MultiModalEmbeddings | None:
1635 modalities = self._parse_and_validate_multimodal_inputs(**kwargs)
1636 if not modalities:
1637 return None
@@ -1657,9 +1657,9 @@ class Ernie4_5_VLMoeForConditionalGeneration(
1657 def get_input_embeddings(
1658 self,
1659 input_ids: torch.Tensor,
1660 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
1660 + multimodal_embeddings: MultiModalEmbeddings | None = None,
1661 *,
1662 - is_multimodal: Optional[torch.Tensor] = None,
1662 + is_multimodal: torch.Tensor | None = None,
1663 handle_oov_mm_token: bool = False,
1664 ) -> torch.Tensor:
1665 if multimodal_embeddings is not None and len(multimodal_embeddings) > 0:
@@ -1680,8 +1680,8 @@ class Ernie4_5_VLMoeForConditionalGeneration(
1680 self,
1681 input_ids: torch.Tensor,
1682 positions: torch.Tensor,
1683 - intermediate_tensors: Optional[IntermediateTensors] = None,
1684 - inputs_embeds: Optional[torch.Tensor] = None,
1683 + intermediate_tensors: IntermediateTensors | None = None,
1684 + inputs_embeds: torch.Tensor | None = None,
1685 **kwargs,
1686 ):
1687 forward_kwargs = {
vllm/model_executor/models/ernie45_vl_moe.py
+19 -19
@@ -25,7 +25,7 @@
25
26 from collections.abc import Iterable
27 from itertools import islice
28 -from typing import Any, Optional, Union
28 +from typing import Any
29
30 import torch
31 from torch import nn
@@ -74,7 +74,7 @@ logger = init_logger(__name__)
74
75
76 class Ernie4_5_VLMoeMLP(Ernie4_5_MoeMLP):
77 - def __init__(self, shared_experts: Optional[torch.nn.Module] = None, **kwargs):
77 + def __init__(self, shared_experts: torch.nn.Module | None = None, **kwargs):
78 super().__init__(**kwargs)
79 self.shared_experts = shared_experts
80
@@ -91,15 +91,15 @@ class Ernie4_5_VLMoeAttention(nn.Module):
91 hidden_size: int,
92 num_heads: int,
93 num_kv_heads: int,
94 - head_dim: Optional[int] = None,
94 + head_dim: int | None = None,
95 rope_theta: float = 500000,
96 - rope_scaling: Optional[dict[str, Any]] = None,
96 + rope_scaling: dict[str, Any] | None = None,
97 freq_allocation: int = 20,
98 max_position_embeddings: int = 131072,
99 rms_norm_eps: float = 1e-05,
100 qkv_bias: bool = False,
101 - cache_config: Optional[CacheConfig] = None,
102 - quant_config: Optional[QuantizationConfig] = None,
101 + cache_config: CacheConfig | None = None,
102 + quant_config: QuantizationConfig | None = None,
103 prefix: str = "",
104 ) -> None:
105 super().__init__()
@@ -192,7 +192,7 @@ class Ernie4_5_VLMoeMoE(nn.Module):
192 def __init__(
193 self,
194 config: PretrainedConfig,
195 - quant_config: Optional[QuantizationConfig] = None,
195 + quant_config: QuantizationConfig | None = None,
196 prefix: str = "",
197 ):
198 super().__init__()
@@ -390,8 +390,8 @@ class Ernie4_5_VLMoeDecoderLayer(nn.Module):
390 def __init__(
391 self,
392 config: PretrainedConfig,
393 - cache_config: Optional[CacheConfig] = None,
394 - quant_config: Optional[QuantizationConfig] = None,
393 + cache_config: CacheConfig | None = None,
394 + quant_config: QuantizationConfig | None = None,
395 prefix: str = "",
396 ) -> None:
397 super().__init__()
@@ -463,8 +463,8 @@ class Ernie4_5_VLMoeDecoderLayer(nn.Module):
463 self,
464 positions: torch.Tensor,
465 hidden_states: torch.Tensor,
466 - residual: Optional[torch.Tensor],
467 - visual_token_mask: Optional[torch.Tensor],
466 + residual: torch.Tensor | None,
467 + visual_token_mask: torch.Tensor | None,
468 **kwargs: object,
469 ) -> torch.Tensor:
470 # Self Attention
@@ -551,11 +551,11 @@ class Ernie4_5_VLMoeModel(nn.Module):
551 self,
552 input_ids: torch.Tensor,
553 positions: torch.Tensor,
554 - intermediate_tensors: Optional[IntermediateTensors] = None,
555 - inputs_embeds: Optional[torch.Tensor] = None,
556 - visual_token_mask: Optional[torch.Tensor] = None,
554 + intermediate_tensors: IntermediateTensors | None = None,
555 + inputs_embeds: torch.Tensor | None = None,
556 + visual_token_mask: torch.Tensor | None = None,
557 **kwargs: object,
558 - ) -> Union[torch.Tensor, IntermediateTensors]:
558 + ) -> torch.Tensor | IntermediateTensors:
559 if get_pp_group().is_first_rank:
560 if inputs_embeds is not None:
561 hidden_states = inputs_embeds
@@ -632,10 +632,10 @@ class Ernie4_5_VLMoeForCausalLM(nn.Module, SupportsPP):
632 self,
633 input_ids: torch.Tensor,
634 positions: torch.Tensor,
635 - intermediate_tensors: Optional[IntermediateTensors] = None,
636 - inputs_embeds: Optional[torch.Tensor] = None,
635 + intermediate_tensors: IntermediateTensors | None = None,
636 + inputs_embeds: torch.Tensor | None = None,
637 **kwargs: object,
638 - ) -> Union[torch.Tensor, IntermediateTensors]:
638 + ) -> torch.Tensor | IntermediateTensors:
639 hidden_states = self.model(
640 input_ids, positions, intermediate_tensors, inputs_embeds, **kwargs
641 )
@@ -644,7 +644,7 @@ class Ernie4_5_VLMoeForCausalLM(nn.Module, SupportsPP):
644 def compute_logits(
645 self,
646 hidden_states: torch.Tensor,
647 - ) -> Optional[torch.Tensor]:
647 + ) -> torch.Tensor | None:
648 logits = self.logits_processor(self.lm_head, hidden_states)
649 return logits
650
vllm/model_executor/models/ernie_mtp.py
+4 -5
@@ -24,7 +24,6 @@
24 """Inference-only Ernie-MTP model."""
25
26 from collections.abc import Iterable
27 -from typing import Optional
27
28 import torch
29 import torch.nn as nn
@@ -121,7 +120,7 @@ class ErnieMultiTokenPredictor(nn.Module):
120 input_ids: torch.Tensor,
121 positions: torch.Tensor,
122 previous_hidden_states: torch.Tensor,
124 - inputs_embeds: Optional[torch.Tensor] = None,
123 + inputs_embeds: torch.Tensor | None = None,
124 spec_step_idx: int = 0,
125 ) -> torch.Tensor:
126 if inputs_embeds is None:
@@ -169,8 +168,8 @@ class ErnieMTP(nn.Module, SupportsPP):
168 input_ids: torch.Tensor,
169 positions: torch.Tensor,
170 hidden_states: torch.Tensor,
172 - intermediate_tensors: Optional[IntermediateTensors] = None,
173 - inputs_embeds: Optional[torch.Tensor] = None,
171 + intermediate_tensors: IntermediateTensors | None = None,
172 + inputs_embeds: torch.Tensor | None = None,
173 spec_step_idx: int = 0,
174 ) -> torch.Tensor:
175 assert spec_step_idx == 0, "ernie_mtp only support predict one token"
@@ -183,7 +182,7 @@ class ErnieMTP(nn.Module, SupportsPP):
182 self,
183 hidden_states: torch.Tensor,
184 spec_step_idx: int = 0,
186 - ) -> Optional[torch.Tensor]:
185 + ) -> torch.Tensor | None:
186 return self.model.compute_logits(hidden_states, self.lm_head, spec_step_idx)
187
188 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/exaone.py
+19 -19
@@ -27,7 +27,7 @@
27
28 from collections.abc import Iterable
29 from itertools import islice
30 -from typing import Any, Optional, Union
30 +from typing import Any
31
32 import torch
33 from torch import nn
@@ -75,7 +75,7 @@ class ExaoneGatedMLP(nn.Module):
75 hidden_size: int,
76 intermediate_size: int,
77 hidden_act: str,
78 - quant_config: Optional[QuantizationConfig] = None,
78 + quant_config: QuantizationConfig | None = None,
79 bias: bool = False,
80 prefix: str = "",
81 ) -> None:
@@ -115,11 +115,11 @@ class ExaoneAttention(nn.Module):
115 num_heads: int,
116 num_kv_heads: int,
117 rope_theta: float = 10000,
118 - rope_scaling: Optional[dict[str, Any]] = None,
118 + rope_scaling: dict[str, Any] | None = None,
119 max_position_embeddings: int = 8192,
120 - quant_config: Optional[QuantizationConfig] = None,
120 + quant_config: QuantizationConfig | None = None,
121 bias: bool = False,
122 - cache_config: Optional[CacheConfig] = None,
122 + cache_config: CacheConfig | None = None,
123 prefix: str = "",
124 ) -> None:
125 super().__init__()
@@ -209,11 +209,11 @@ class ExaoneBlockAttention(nn.Module):
209 num_heads: int,
210 num_kv_heads: int,
211 rope_theta: float = 10000,
212 - rope_scaling: Optional[dict[str, Any]] = None,
212 + rope_scaling: dict[str, Any] | None = None,
213 max_position_embeddings: int = 8192,
214 - quant_config: Optional[QuantizationConfig] = None,
214 + quant_config: QuantizationConfig | None = None,
215 bias: bool = False,
216 - cache_config: Optional[CacheConfig] = None,
216 + cache_config: CacheConfig | None = None,
217 prefix: str = "",
218 ) -> None:
219 super().__init__()
@@ -246,8 +246,8 @@ class ExaoneDecoderLayer(nn.Module):
246 def __init__(
247 self,
248 config: PretrainedConfig,
249 - cache_config: Optional[CacheConfig] = None,
250 - quant_config: Optional[QuantizationConfig] = None,
249 + cache_config: CacheConfig | None = None,
250 + quant_config: QuantizationConfig | None = None,
251 prefix: str = "",
252 ) -> None:
253 super().__init__()
@@ -296,7 +296,7 @@ class ExaoneDecoderLayer(nn.Module):
296 self,
297 positions: torch.Tensor,
298 hidden_states: torch.Tensor,
299 - residual: Optional[torch.Tensor],
299 + residual: torch.Tensor | None,
300 ) -> tuple[torch.Tensor, torch.Tensor]:
301 # Self Attention
302 if residual is None:
@@ -369,11 +369,11 @@ class ExaoneModel(nn.Module):
369
370 def forward(
371 self,
372 - input_ids: Optional[torch.Tensor],
372 + input_ids: torch.Tensor | None,
373 positions: torch.Tensor,
374 - intermediate_tensors: Optional[IntermediateTensors],
375 - inputs_embeds: Optional[torch.Tensor] = None,
376 - ) -> Union[torch.Tensor, IntermediateTensors]:
374 + intermediate_tensors: IntermediateTensors | None,
375 + inputs_embeds: torch.Tensor | None = None,
376 + ) -> torch.Tensor | IntermediateTensors:
377 if get_pp_group().is_first_rank:
378 if inputs_embeds is not None:
379 hidden_states = inputs_embeds
@@ -536,9 +536,9 @@ class ExaoneForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
536 self,
537 input_ids: torch.Tensor,
538 positions: torch.Tensor,
539 - intermediate_tensors: Optional[IntermediateTensors] = None,
540 - inputs_embeds: Optional[torch.Tensor] = None,
541 - ) -> Union[torch.Tensor, IntermediateTensors]:
539 + intermediate_tensors: IntermediateTensors | None = None,
540 + inputs_embeds: torch.Tensor | None = None,
541 + ) -> torch.Tensor | IntermediateTensors:
542 model_output = self.transformer(
543 input_ids, positions, intermediate_tensors, inputs_embeds
544 )
@@ -547,7 +547,7 @@ class ExaoneForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
547 def compute_logits(
548 self,
549 hidden_states: torch.Tensor,
550 - ) -> Optional[torch.Tensor]:
550 + ) -> torch.Tensor | None:
551 logits = self.logits_processor(self.lm_head, hidden_states)
552 return logits
553
vllm/model_executor/models/exaone4.py
+16 -16
@@ -23,7 +23,7 @@
23
24 from collections.abc import Iterable
25 from itertools import islice
26 -from typing import Any, Optional, Union
26 +from typing import Any
27
28 import torch
29 from torch import nn
@@ -72,7 +72,7 @@ class Exaone4GatedMLP(nn.Module):
72 hidden_size: int,
73 intermediate_size: int,
74 hidden_act: str,
75 - quant_config: Optional[QuantizationConfig] = None,
75 + quant_config: QuantizationConfig | None = None,
76 bias: bool = False,
77 prefix: str = "",
78 ) -> None:
@@ -112,11 +112,11 @@ class Exaone4Attention(nn.Module):
112 num_heads: int,
113 num_kv_heads: int,
114 rope_theta: float = 1000000,
115 - rope_scaling: Optional[dict[str, Any]] = None,
115 + rope_scaling: dict[str, Any] | None = None,
116 max_position_embeddings: int = 8192,
117 - quant_config: Optional[QuantizationConfig] = None,
117 + quant_config: QuantizationConfig | None = None,
118 bias: bool = False,
119 - cache_config: Optional[CacheConfig] = None,
119 + cache_config: CacheConfig | None = None,
120 prefix: str = "",
121 ) -> None:
122 super().__init__()
@@ -222,8 +222,8 @@ class Exaone4DecoderLayer(nn.Module):
222 def __init__(
223 self,
224 config: Exaone4Config,
225 - cache_config: Optional[CacheConfig] = None,
226 - quant_config: Optional[QuantizationConfig] = None,
225 + cache_config: CacheConfig | None = None,
226 + quant_config: QuantizationConfig | None = None,
227 prefix: str = "",
228 ) -> None:
229 super().__init__()
@@ -277,7 +277,7 @@ class Exaone4DecoderLayer(nn.Module):
277 self,
278 positions: torch.Tensor,
279 hidden_states: torch.Tensor,
280 - residual: Optional[torch.Tensor],
280 + residual: torch.Tensor | None,
281 ) -> tuple[torch.Tensor, torch.Tensor]:
282 residual = hidden_states
283
@@ -356,11 +356,11 @@ class Exaone4Model(nn.Module):
356
357 def forward(
358 self,
359 - input_ids: Optional[torch.Tensor],
359 + input_ids: torch.Tensor | None,
360 positions: torch.Tensor,
361 - intermediate_tensors: Optional[IntermediateTensors],
362 - inputs_embeds: Optional[torch.Tensor] = None,
363 - ) -> Union[torch.Tensor, IntermediateTensors]:
361 + intermediate_tensors: IntermediateTensors | None,
362 + inputs_embeds: torch.Tensor | None = None,
363 + ) -> torch.Tensor | IntermediateTensors:
364 if get_pp_group().is_first_rank:
365 if inputs_embeds is not None:
366 hidden_states = inputs_embeds
@@ -523,9 +523,9 @@ class Exaone4ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
523 self,
524 input_ids: torch.Tensor,
525 positions: torch.Tensor,
526 - intermediate_tensors: Optional[IntermediateTensors] = None,
527 - inputs_embeds: Optional[torch.Tensor] = None,
528 - ) -> Union[torch.Tensor, IntermediateTensors]:
526 + intermediate_tensors: IntermediateTensors | None = None,
527 + inputs_embeds: torch.Tensor | None = None,
528 + ) -> torch.Tensor | IntermediateTensors:
529 model_output = self.model(
530 input_ids, positions, intermediate_tensors, inputs_embeds
531 )
@@ -534,7 +534,7 @@ class Exaone4ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
534 def compute_logits(
535 self,
536 hidden_states: torch.Tensor,
537 - ) -> Optional[torch.Tensor]:
537 + ) -> torch.Tensor | None:
538 logits = self.logits_processor(self.lm_head, hidden_states)
539 return logits
540
vllm/model_executor/models/falcon.py
+13 -13
@@ -23,7 +23,7 @@
23 import math
24 from collections.abc import Iterable
25 from itertools import islice
26 -from typing import Optional, Union
26 +from typing import TypeAlias
27
28 import torch
29 from torch import nn
@@ -65,7 +65,7 @@ from .utils import (
65 maybe_prefix,
66 )
67
68 -FalconConfig = Union[HF_FalconConfig, RWConfig]
68 +FalconConfig: TypeAlias = HF_FalconConfig | RWConfig
69
70
71 def _get_alibi_slopes(total_num_heads: int) -> torch.Tensor:
@@ -95,8 +95,8 @@ class FalconAttention(nn.Module):
95 def __init__(
96 self,
97 config: FalconConfig,
98 - cache_config: Optional[CacheConfig] = None,
99 - quant_config: Optional[QuantizationConfig] = None,
98 + cache_config: CacheConfig | None = None,
99 + quant_config: QuantizationConfig | None = None,
100 prefix: str = "",
101 ):
102 super().__init__()
@@ -226,7 +226,7 @@ class FalconMLP(nn.Module):
226 def __init__(
227 self,
228 config: FalconConfig,
229 - quant_config: Optional[QuantizationConfig] = None,
229 + quant_config: QuantizationConfig | None = None,
230 ):
231 super().__init__()
232 hidden_size = config.hidden_size
@@ -265,8 +265,8 @@ class FalconDecoderLayer(nn.Module):
265 def __init__(
266 self,
267 config: FalconConfig,
268 - cache_config: Optional[CacheConfig] = None,
269 - quant_config: Optional[QuantizationConfig] = None,
268 + cache_config: CacheConfig | None = None,
269 + quant_config: QuantizationConfig | None = None,
270 prefix: str = "",
271 ):
272 super().__init__()
@@ -401,9 +401,9 @@ class FalconModel(nn.Module):
401 self,
402 input_ids: torch.Tensor,
403 positions: torch.Tensor,
404 - intermediate_tensors: Optional[IntermediateTensors],
405 - inputs_embeds: Optional[torch.Tensor] = None,
406 - ) -> Union[torch.Tensor, IntermediateTensors]:
404 + intermediate_tensors: IntermediateTensors | None,
405 + inputs_embeds: torch.Tensor | None = None,
406 + ) -> torch.Tensor | IntermediateTensors:
407 if get_pp_group().is_first_rank:
408 if inputs_embeds is not None:
409 hidden_states = inputs_embeds
@@ -517,8 +517,8 @@ class FalconForCausalLM(nn.Module, SupportsPP):
517 self,
518 input_ids: torch.LongTensor,
519 positions: torch.Tensor,
520 - intermediate_tensors: Optional[IntermediateTensors] = None,
521 - inputs_embeds: Optional[torch.Tensor] = None,
520 + intermediate_tensors: IntermediateTensors | None = None,
521 + inputs_embeds: torch.Tensor | None = None,
522 ) -> torch.Tensor:
523 hidden_states = self.transformer(
524 input_ids, positions, intermediate_tensors, inputs_embeds
@@ -528,7 +528,7 @@ class FalconForCausalLM(nn.Module, SupportsPP):
528 def compute_logits(
529 self,
530 hidden_states: torch.Tensor,
531 - ) -> Optional[torch.Tensor]:
531 + ) -> torch.Tensor | None:
532 logits = self.logits_processor(self.lm_head, hidden_states)
533 return logits
534
vllm/model_executor/models/falcon_h1.py
+16 -17
@@ -4,7 +4,6 @@
4
5 from collections.abc import Iterable
6 from itertools import islice
7 -from typing import Optional
7
8 import torch
9 from torch import nn
@@ -52,7 +51,7 @@ class FalconH1MLP(nn.Module):
51 def __init__(
52 self,
53 config: FalconH1Config,
55 - quant_config: Optional[QuantizationConfig] = None,
54 + quant_config: QuantizationConfig | None = None,
55 bias: bool = False,
56 ) -> None:
57 super().__init__()
@@ -91,9 +90,9 @@ class FalconH1SSMDecoderLayer(nn.Module):
90 def __init__(
91 self,
92 config: FalconH1Config,
94 - model_config: Optional[ModelConfig] = None,
95 - cache_config: Optional[CacheConfig] = None,
96 - quant_config: Optional[QuantizationConfig] = None,
93 + model_config: ModelConfig | None = None,
94 + cache_config: CacheConfig | None = None,
95 + quant_config: QuantizationConfig | None = None,
96 prefix: str = "",
97 ) -> None:
98 super().__init__()
@@ -188,7 +187,7 @@ class FalconH1SSMDecoderLayer(nn.Module):
187 def forward(
188 self,
189 hidden_states: torch.Tensor,
191 - residual: Optional[torch.Tensor],
190 + residual: torch.Tensor | None,
191 **kwargs,
192 ):
193 output = torch.empty_like(hidden_states)
@@ -204,8 +203,8 @@ class FalconH1AttentionDecoderLayer(nn.Module):
203 def __init__(
204 self,
205 config: FalconH1Config,
207 - cache_config: Optional[CacheConfig] = None,
208 - quant_config: Optional[QuantizationConfig] = None,
206 + cache_config: CacheConfig | None = None,
207 + quant_config: QuantizationConfig | None = None,
208 prefix: str = "",
209 ) -> None:
210 super().__init__()
@@ -301,7 +300,7 @@ class FalconH1AttentionDecoderLayer(nn.Module):
300 self,
301 positions: torch.Tensor,
302 hidden_states: torch.Tensor,
304 - residual: Optional[torch.Tensor],
303 + residual: torch.Tensor | None,
304 **kwargs,
305 ):
306 hidden_states = self.self_attention(
@@ -326,9 +325,9 @@ class FalconH1ParallelHybrid(nn.Module):
325 self,
326 config: FalconH1Config,
327 layer_idx: int,
329 - model_config: Optional[ModelConfig] = None,
330 - cache_config: Optional[CacheConfig] = None,
331 - quant_config: Optional[QuantizationConfig] = None,
328 + model_config: ModelConfig | None = None,
329 + cache_config: CacheConfig | None = None,
330 + quant_config: QuantizationConfig | None = None,
331 prefix: str = "",
332 ) -> None:
333 super().__init__()
@@ -467,8 +466,8 @@ class FalconH1Model(nn.Module):
466 self,
467 input_ids: torch.Tensor,
468 positions: torch.Tensor,
470 - intermediate_tensors: Optional[IntermediateTensors] = None,
471 - inputs_embeds: Optional[torch.Tensor] = None,
469 + intermediate_tensors: IntermediateTensors | None = None,
470 + inputs_embeds: torch.Tensor | None = None,
471 ) -> torch.Tensor:
472 if get_pp_group().is_first_rank:
473 if inputs_embeds is not None:
@@ -610,8 +609,8 @@ class FalconH1ForCausalLM(nn.Module, HasInnerState, SupportsLoRA, SupportsPP, Is
609 self,
610 input_ids: torch.Tensor,
611 positions: torch.Tensor,
613 - intermediate_tensors: Optional[IntermediateTensors] = None,
614 - inputs_embeds: Optional[torch.Tensor] = None,
612 + intermediate_tensors: IntermediateTensors | None = None,
613 + inputs_embeds: torch.Tensor | None = None,
614 **kwargs,
615 ):
616 hidden_states = self.model(
@@ -626,7 +625,7 @@ class FalconH1ForCausalLM(nn.Module, HasInnerState, SupportsLoRA, SupportsPP, Is
625 def compute_logits(
626 self,
627 hidden_states: torch.Tensor,
629 - ) -> Optional[torch.Tensor]:
628 + ) -> torch.Tensor | None:
629 logits = self.logits_processor(self.lm_head, hidden_states)
630
631 return logits
vllm/model_executor/models/flex_olmo.py
+2 -4
@@ -14,8 +14,6 @@
14 # limitations under the License.
15 """Inference-only FlexOlmo model compatible with HuggingFace weights."""
16
17 -from typing import Optional
18 -
17 import torch
18 from torch import nn
19
@@ -128,8 +126,8 @@ class FlexOlmoDecoderLayer(nn.Module):
126 self,
127 positions: torch.Tensor,
128 hidden_states: torch.Tensor,
131 - residual: Optional[torch.Tensor],
132 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
129 + residual: torch.Tensor | None,
130 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
131 # Attention block.
132 residual = hidden_states
133 hidden_states = self.self_attn(positions, hidden_states)
vllm/model_executor/models/fuyu.py
+8 -8
@@ -20,7 +20,7 @@
20
21 import math
22 from collections.abc import Iterable, Mapping, Sequence
23 -from typing import Annotated, Literal, Optional
23 +from typing import Annotated, Literal
24
25 import torch
26 import torch.nn as nn
@@ -87,7 +87,7 @@ class FuyuProcessingInfo(BaseProcessingInfo):
87 def get_image_processor(self, **kwargs: object) -> FuyuImageProcessor:
88 return self.get_hf_processor(**kwargs).image_processor
89
90 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
90 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
91 return {"image": 1}
92
93 def get_image_feature_grid_size(
@@ -142,7 +142,7 @@ class FuyuDummyInputsBuilder(BaseDummyInputsBuilder[FuyuProcessingInfo]):
142 self,
143 seq_len: int,
144 mm_counts: Mapping[str, int],
145 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
145 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
146 ) -> MultiModalDataDict:
147 target_width, target_height = self.info.get_image_size_with_most_features()
148 num_images = mm_counts.get("image", 0)
@@ -271,7 +271,7 @@ class FuyuForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
271 )
272
273 @classmethod
274 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
274 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
275 if modality.startswith("image"):
276 return None
277
@@ -305,7 +305,7 @@ class FuyuForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
305
306 def _parse_and_validate_image_input(
307 self, **kwargs: object
308 - ) -> Optional[FuyuImagePatchInputs]:
308 + ) -> FuyuImagePatchInputs | None:
309 image_patches = kwargs.pop("image_patches", None)
310 patches_per_image = kwargs.pop("patches_per_image", None)
311
@@ -344,8 +344,8 @@ class FuyuForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
344 self,
345 input_ids: torch.Tensor,
346 positions: torch.Tensor,
347 - intermediate_tensors: Optional[IntermediateTensors] = None,
348 - inputs_embeds: Optional[torch.Tensor] = None,
347 + intermediate_tensors: IntermediateTensors | None = None,
348 + inputs_embeds: torch.Tensor | None = None,
349 **kwargs: object,
350 ):
351 if intermediate_tensors is not None:
@@ -362,7 +362,7 @@ class FuyuForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
362 def compute_logits(
363 self,
364 hidden_states: torch.Tensor,
365 - ) -> Optional[torch.Tensor]:
365 + ) -> torch.Tensor | None:
366 logits = self.language_model.logits_processor(
367 self.language_model.lm_head, hidden_states
368 )
vllm/model_executor/models/gemma.py
+17 -18
@@ -20,7 +20,6 @@
20 from collections.abc import Iterable
21 from functools import cache
22 from itertools import islice
23 -from typing import Optional, Union
23
24 import torch
25 from torch import nn
@@ -59,8 +58,8 @@ logger = init_logger(__name__)
58
59 @cache
60 def _get_gemma_act_fn(
62 - hidden_act: Optional[str],
63 - hidden_activation: Optional[str],
61 + hidden_act: str | None,
62 + hidden_activation: str | None,
63 ) -> nn.Module:
64 if hidden_activation is None:
65 if hidden_act is not None:
@@ -92,9 +91,9 @@ class GemmaMLP(nn.Module):
91 self,
92 hidden_size: int,
93 intermediate_size: int,
95 - hidden_act: Optional[str] = None,
96 - hidden_activation: Optional[str] = None,
97 - quant_config: Optional[QuantizationConfig] = None,
94 + hidden_act: str | None = None,
95 + hidden_activation: str | None = None,
96 + quant_config: QuantizationConfig | None = None,
97 prefix: str = "",
98 ) -> None:
99 super().__init__()
@@ -130,8 +129,8 @@ class GemmaAttention(nn.Module):
129 head_dim: int,
130 max_position_embeddings: int = 8192,
131 rope_theta: float = 10000,
133 - cache_config: Optional[CacheConfig] = None,
134 - quant_config: Optional[QuantizationConfig] = None,
132 + cache_config: CacheConfig | None = None,
133 + quant_config: QuantizationConfig | None = None,
134 prefix: str = "",
135 ) -> None:
136 super().__init__()
@@ -207,8 +206,8 @@ class GemmaDecoderLayer(nn.Module):
206 def __init__(
207 self,
208 config: GemmaConfig,
210 - cache_config: Optional[CacheConfig] = None,
211 - quant_config: Optional[QuantizationConfig] = None,
209 + cache_config: CacheConfig | None = None,
210 + quant_config: QuantizationConfig | None = None,
211 prefix: str = "",
212 ) -> None:
213 super().__init__()
@@ -241,7 +240,7 @@ class GemmaDecoderLayer(nn.Module):
240 self,
241 positions: torch.Tensor,
242 hidden_states: torch.Tensor,
244 - residual: Optional[torch.Tensor],
243 + residual: torch.Tensor | None,
244 ) -> tuple[torch.Tensor, torch.Tensor]:
245 # Self Attention
246 if residual is None:
@@ -301,9 +300,9 @@ class GemmaModel(nn.Module):
300 self,
301 input_ids: torch.Tensor,
302 positions: torch.Tensor,
304 - intermediate_tensors: Optional[IntermediateTensors],
305 - inputs_embeds: Optional[torch.Tensor] = None,
306 - ) -> Union[torch.Tensor, IntermediateTensors]:
303 + intermediate_tensors: IntermediateTensors | None,
304 + inputs_embeds: torch.Tensor | None = None,
305 + ) -> torch.Tensor | IntermediateTensors:
306 if get_pp_group().is_first_rank:
307 if inputs_embeds is not None:
308 hidden_states = inputs_embeds
@@ -406,9 +405,9 @@ class GemmaForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
405 self,
406 input_ids: torch.Tensor,
407 positions: torch.Tensor,
409 - intermediate_tensors: Optional[IntermediateTensors] = None,
410 - inputs_embeds: Optional[torch.Tensor] = None,
411 - ) -> Union[torch.Tensor, IntermediateTensors]:
408 + intermediate_tensors: IntermediateTensors | None = None,
409 + inputs_embeds: torch.Tensor | None = None,
410 + ) -> torch.Tensor | IntermediateTensors:
411 hidden_states = self.model(
412 input_ids, positions, intermediate_tensors, inputs_embeds
413 )
@@ -417,7 +416,7 @@ class GemmaForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
416 def compute_logits(
417 self,
418 hidden_states: torch.Tensor,
420 - ) -> Optional[torch.Tensor]:
419 + ) -> torch.Tensor | None:
420 logits = self.logits_processor(self.model.embed_tokens, hidden_states)
421 return logits
422
vllm/model_executor/models/gemma2.py
+15 -16
@@ -18,7 +18,6 @@
18 # limitations under the License.
19 from collections.abc import Iterable
20 from itertools import islice
21 -from typing import Optional, Union
21
22 import torch
23 from torch import nn
@@ -66,7 +65,7 @@ class Gemma2MLP(nn.Module):
65 intermediate_size: int,
66 hidden_act: str,
67 hidden_activation: str,
69 - quant_config: Optional[QuantizationConfig] = None,
68 + quant_config: QuantizationConfig | None = None,
69 ) -> None:
70 super().__init__()
71 self.gate_up_proj = MergedColumnParallelLinear(
@@ -100,9 +99,9 @@ class Gemma2Attention(nn.Module):
99 head_dim: int,
100 max_position_embeddings: int,
101 rope_theta: float,
103 - cache_config: Optional[CacheConfig] = None,
104 - quant_config: Optional[QuantizationConfig] = None,
105 - attn_logits_soft_cap: Optional[float] = None,
102 + cache_config: CacheConfig | None = None,
103 + quant_config: QuantizationConfig | None = None,
104 + attn_logits_soft_cap: float | None = None,
105 prefix: str = "",
106 ) -> None:
107 super().__init__()
@@ -183,8 +182,8 @@ class Gemma2DecoderLayer(nn.Module):
182 def __init__(
183 self,
184 config: Gemma2Config,
186 - cache_config: Optional[CacheConfig] = None,
187 - quant_config: Optional[QuantizationConfig] = None,
185 + cache_config: CacheConfig | None = None,
186 + quant_config: QuantizationConfig | None = None,
187 prefix: str = "",
188 ) -> None:
189 super().__init__()
@@ -225,7 +224,7 @@ class Gemma2DecoderLayer(nn.Module):
224 self,
225 positions: torch.Tensor,
226 hidden_states: torch.Tensor,
228 - residual: Optional[torch.Tensor],
227 + residual: torch.Tensor | None,
228 ) -> tuple[torch.Tensor, torch.Tensor]:
229 if residual is None:
230 residual = hidden_states
@@ -284,11 +283,11 @@ class Gemma2Model(nn.Module):
283
284 def forward(
285 self,
287 - input_ids: Optional[torch.Tensor],
286 + input_ids: torch.Tensor | None,
287 positions: torch.Tensor,
289 - intermediate_tensors: Optional[IntermediateTensors],
290 - inputs_embeds: Optional[torch.Tensor] = None,
291 - ) -> Union[torch.Tensor, IntermediateTensors]:
288 + intermediate_tensors: IntermediateTensors | None,
289 + inputs_embeds: torch.Tensor | None = None,
290 + ) -> torch.Tensor | IntermediateTensors:
291 if get_pp_group().is_first_rank:
292 if inputs_embeds is not None:
293 hidden_states = inputs_embeds
@@ -406,9 +405,9 @@ class Gemma2ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
405 self,
406 input_ids: torch.Tensor,
407 positions: torch.Tensor,
409 - intermediate_tensors: Optional[IntermediateTensors] = None,
410 - inputs_embeds: Optional[torch.Tensor] = None,
411 - ) -> Union[torch.Tensor, IntermediateTensors]:
408 + intermediate_tensors: IntermediateTensors | None = None,
409 + inputs_embeds: torch.Tensor | None = None,
410 + ) -> torch.Tensor | IntermediateTensors:
411 hidden_states = self.model(
412 input_ids, positions, intermediate_tensors, inputs_embeds
413 )
@@ -417,7 +416,7 @@ class Gemma2ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
416 def compute_logits(
417 self,
418 hidden_states: torch.Tensor,
420 - ) -> Optional[torch.Tensor]:
419 + ) -> torch.Tensor | None:
420 logits = self.logits_processor(self.model.embed_tokens, hidden_states)
421 return logits
422
vllm/model_executor/models/gemma3.py
+15 -16
@@ -17,7 +17,6 @@
17 # limitations under the License.
18 from collections.abc import Iterable
19 from itertools import islice
20 -from typing import Optional, Union
20
21 import torch
22 import torch.nn.functional as F
@@ -66,7 +65,7 @@ class Gemma3MLP(nn.Module):
65 hidden_size: int,
66 intermediate_size: int,
67 hidden_activation: str,
69 - quant_config: Optional[QuantizationConfig] = None,
68 + quant_config: QuantizationConfig | None = None,
69 prefix: str = "",
70 ) -> None:
71 super().__init__()
@@ -108,9 +107,9 @@ class Gemma3Attention(nn.Module):
107 num_kv_heads: int,
108 head_dim: int,
109 max_position_embeddings: int,
111 - cache_config: Optional[CacheConfig] = None,
112 - quant_config: Optional[QuantizationConfig] = None,
113 - attn_logits_soft_cap: Optional[float] = None,
110 + cache_config: CacheConfig | None = None,
111 + quant_config: QuantizationConfig | None = None,
112 + attn_logits_soft_cap: float | None = None,
113 prefix: str = "",
114 ) -> None:
115 super().__init__()
@@ -295,8 +294,8 @@ class Gemma3DecoderLayer(nn.Module):
294 def __init__(
295 self,
296 config: Gemma3TextConfig,
298 - cache_config: Optional[CacheConfig] = None,
299 - quant_config: Optional[QuantizationConfig] = None,
297 + cache_config: CacheConfig | None = None,
298 + quant_config: QuantizationConfig | None = None,
299 prefix: str = "",
300 ) -> None:
301 super().__init__()
@@ -336,7 +335,7 @@ class Gemma3DecoderLayer(nn.Module):
335 self,
336 positions: torch.Tensor,
337 hidden_states: torch.Tensor,
339 - residual: Optional[torch.Tensor],
338 + residual: torch.Tensor | None,
339 **kwargs,
340 ) -> tuple[torch.Tensor, torch.Tensor]:
341 if residual is None:
@@ -401,12 +400,12 @@ class Gemma3Model(nn.Module):
400
401 def forward(
402 self,
404 - input_ids: Optional[torch.Tensor],
403 + input_ids: torch.Tensor | None,
404 positions: torch.Tensor,
406 - intermediate_tensors: Optional[IntermediateTensors],
407 - inputs_embeds: Optional[torch.Tensor] = None,
405 + intermediate_tensors: IntermediateTensors | None,
406 + inputs_embeds: torch.Tensor | None = None,
407 **kwargs,
409 - ) -> Union[torch.Tensor, IntermediateTensors]:
408 + ) -> torch.Tensor | IntermediateTensors:
409 if get_pp_group().is_first_rank:
410 if inputs_embeds is not None:
411 hidden_states = inputs_embeds
@@ -549,10 +548,10 @@ class Gemma3ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
548 self,
549 input_ids: torch.Tensor,
550 positions: torch.Tensor,
552 - intermediate_tensors: Optional[IntermediateTensors] = None,
553 - inputs_embeds: Optional[torch.Tensor] = None,
551 + intermediate_tensors: IntermediateTensors | None = None,
552 + inputs_embeds: torch.Tensor | None = None,
553 **kwargs,
555 - ) -> Union[torch.Tensor, IntermediateTensors]:
554 + ) -> torch.Tensor | IntermediateTensors:
555 hidden_states = self.model(
556 input_ids, positions, intermediate_tensors, inputs_embeds, **kwargs
557 )
@@ -561,7 +560,7 @@ class Gemma3ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
560 def compute_logits(
561 self,
562 hidden_states: torch.Tensor,
564 - ) -> Optional[torch.Tensor]:
563 + ) -> torch.Tensor | None:
564 logits = self.logits_processor(self.model.embed_tokens, hidden_states)
565 return logits
566
vllm/model_executor/models/gemma3_mm.py
+11 -11
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import math
4 from collections.abc import Iterable, Mapping, Sequence
5 -from typing import Annotated, Any, Literal, Optional
5 +from typing import Annotated, Any, Literal
6
7 import torch
8 from torch import nn
@@ -82,7 +82,7 @@ class Gemma3ProcessingInfo(BaseProcessingInfo):
82 def get_hf_processor(self, **kwargs: object):
83 return self.ctx.get_hf_processor(Gemma3Processor, **kwargs)
84
85 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
85 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
86 return {"image": None}
87
88 def _resolve_image_kwargs(
@@ -112,7 +112,7 @@ class Gemma3ProcessingInfo(BaseProcessingInfo):
112 *,
113 image_width: int,
114 image_height: int,
115 - processor: Optional[Gemma3Processor],
115 + processor: Gemma3Processor | None,
116 ) -> int:
117 if processor is None:
118 processor = self.get_hf_processor()
@@ -182,7 +182,7 @@ class Gemma3ProcessingInfo(BaseProcessingInfo):
182 *,
183 image_width: int,
184 image_height: int,
185 - processor: Optional[Gemma3Processor],
185 + processor: Gemma3Processor | None,
186 ) -> PromptUpdateDetails[str]:
187 if processor is None:
188 processor = self.get_hf_processor()
@@ -217,7 +217,7 @@ class Gemma3ProcessingInfo(BaseProcessingInfo):
217 *,
218 image_width: int,
219 image_height: int,
220 - processor: Optional[Gemma3Processor],
220 + processor: Gemma3Processor | None,
221 ) -> int:
222 if processor is None:
223 processor = self.get_hf_processor()
@@ -256,7 +256,7 @@ class Gemma3DummyInputsBuilder(BaseDummyInputsBuilder[Gemma3ProcessingInfo]):
256 self,
257 seq_len: int,
258 mm_counts: Mapping[str, int],
259 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
259 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
260 ) -> MultiModalDataDict:
261 num_images = mm_counts.get("image", 0)
262
@@ -510,7 +510,7 @@ class Gemma3ForConditionalGeneration(
510 )
511
512 @classmethod
513 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
513 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
514 if modality.startswith("image"):
515 return "<start_of_image>"
516
@@ -555,7 +555,7 @@ class Gemma3ForConditionalGeneration(
555
556 def _parse_and_validate_image_input(
557 self, **kwargs: object
558 - ) -> Optional[Gemma3ImageInputs]:
558 + ) -> Gemma3ImageInputs | None:
559 pixel_values = kwargs.pop("pixel_values", None)
560 num_patches = kwargs.pop("num_patches", None)
561 image_embeds = kwargs.pop("image_embeds", None)
@@ -609,8 +609,8 @@ class Gemma3ForConditionalGeneration(
609 self,
610 input_ids: torch.Tensor,
611 positions: torch.Tensor,
612 - intermediate_tensors: Optional[IntermediateTensors] = None,
613 - inputs_embeds: Optional[torch.Tensor] = None,
612 + intermediate_tensors: IntermediateTensors | None = None,
613 + inputs_embeds: torch.Tensor | None = None,
614 **kwargs: object,
615 ) -> IntermediateTensors:
616 if intermediate_tensors is not None:
@@ -692,7 +692,7 @@ class Gemma3ForConditionalGeneration(
692 def compute_logits(
693 self,
694 hidden_states: torch.Tensor,
695 - ) -> Optional[torch.Tensor]:
695 + ) -> torch.Tensor | None:
696 return self.language_model.compute_logits(hidden_states)
697
698 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/gemma3n.py
+23 -24
@@ -16,7 +16,6 @@
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
18 from collections.abc import Iterable
19 -from typing import Optional, Union
19
20 import torch
21 from torch import nn
@@ -196,7 +195,7 @@ class Gemma3nLaurelBlock(nn.Module):
195 laurel_rank: int,
196 rms_norm_eps: float,
197 *,
199 - quant_config: Optional[QuantizationConfig] = None,
198 + quant_config: QuantizationConfig | None = None,
199 prefix: str,
200 ) -> None:
201 super().__init__()
@@ -236,7 +235,7 @@ class Gemma3nMLP(nn.Module):
235 intermediate_size: int,
236 hidden_activation: str,
237 activation_sparsity: float = 0.0,
239 - quant_config: Optional[QuantizationConfig] = None,
238 + quant_config: QuantizationConfig | None = None,
239 prefix: str = "",
240 ) -> None:
241 super().__init__()
@@ -285,8 +284,8 @@ class Gemma3nAttention(nn.Module):
284 num_kv_heads: int,
285 head_dim: int,
286 max_position_embeddings: int,
288 - cache_config: Optional[CacheConfig] = None,
289 - quant_config: Optional[QuantizationConfig] = None,
287 + cache_config: CacheConfig | None = None,
288 + quant_config: QuantizationConfig | None = None,
289 prefix: str = "",
290 ) -> None:
291 super().__init__()
@@ -412,8 +411,8 @@ class Gemma3nDecoderLayer(nn.Module):
411 def __init__(
412 self,
413 config: Gemma3nTextConfig,
415 - cache_config: Optional[CacheConfig] = None,
416 - quant_config: Optional[QuantizationConfig] = None,
414 + cache_config: CacheConfig | None = None,
415 + quant_config: QuantizationConfig | None = None,
416 prefix: str = "",
417 ) -> None:
418 super().__init__()
@@ -650,7 +649,7 @@ class Gemma3nSelfDecoder(nn.Module):
649 def get_per_layer_inputs(
650 self,
651 hidden_states_0: torch.Tensor,
653 - per_layer_inputs: Optional[torch.Tensor],
652 + per_layer_inputs: torch.Tensor | None,
653 ) -> torch.Tensor:
654 per_layer_projection = self.per_layer_model_projection(hidden_states_0)
655 per_layer_projection = per_layer_projection.reshape(
@@ -687,8 +686,8 @@ class Gemma3nSelfDecoder(nn.Module):
686 self,
687 input_ids: torch.Tensor,
688 positions: torch.Tensor,
690 - inputs_embeds: Optional[torch.Tensor] = None,
691 - per_layer_inputs: Optional[torch.Tensor] = None,
689 + inputs_embeds: torch.Tensor | None = None,
690 + per_layer_inputs: torch.Tensor | None = None,
691 **kwargs,
692 ) -> tuple[torch.Tensor, torch.Tensor]:
693 if inputs_embeds is not None:
@@ -870,8 +869,8 @@ class Gemma3nTextModel(nn.Module, SupportsQuant):
869 self,
870 input_ids: torch.Tensor,
871 positions: torch.Tensor,
873 - inputs_embeds: Optional[torch.Tensor] = None,
874 - per_layer_inputs: Optional[torch.Tensor] = None,
872 + inputs_embeds: torch.Tensor | None = None,
873 + per_layer_inputs: torch.Tensor | None = None,
874 **kwargs,
875 ) -> torch.Tensor:
876 logits_indices_padded, num_logits_indices = None, None
@@ -947,8 +946,8 @@ class Gemma3nTextModel(nn.Module, SupportsQuant):
946 self,
947 input_ids: torch.Tensor,
948 positions: torch.Tensor,
950 - inputs_embeds: Optional[torch.Tensor] = None,
951 - per_layer_inputs: Optional[torch.Tensor] = None,
949 + inputs_embeds: torch.Tensor | None = None,
950 + per_layer_inputs: torch.Tensor | None = None,
951 **kwargs,
952 ) -> torch.Tensor:
953 hidden_states, per_layer_inputs = self.self_decoder(
@@ -990,13 +989,13 @@ class Gemma3nTextModel(nn.Module, SupportsQuant):
989
990 def forward(
991 self,
993 - input_ids: Optional[torch.Tensor],
992 + input_ids: torch.Tensor | None,
993 positions: torch.Tensor,
995 - per_layer_inputs: Optional[torch.Tensor] = None,
996 - intermediate_tensors: Optional[IntermediateTensors] = None,
997 - inputs_embeds: Optional[torch.Tensor] = None,
994 + per_layer_inputs: torch.Tensor | None = None,
995 + intermediate_tensors: IntermediateTensors | None = None,
996 + inputs_embeds: torch.Tensor | None = None,
997 **kwargs,
999 - ) -> Union[torch.Tensor, IntermediateTensors]:
998 + ) -> torch.Tensor | IntermediateTensors:
999 if self.fast_prefill_enabled:
1000 hidden_states = self.fast_prefill_forward(
1001 input_ids,
@@ -1116,11 +1115,11 @@ class Gemma3nForCausalLM(nn.Module):
1115 input_ids: torch.Tensor,
1116 positions: torch.Tensor,
1117 *,
1119 - per_layer_inputs: Optional[torch.Tensor] = None,
1120 - intermediate_tensors: Optional[IntermediateTensors] = None,
1121 - inputs_embeds: Optional[torch.Tensor] = None,
1118 + per_layer_inputs: torch.Tensor | None = None,
1119 + intermediate_tensors: IntermediateTensors | None = None,
1120 + inputs_embeds: torch.Tensor | None = None,
1121 **kwargs,
1123 - ) -> Union[torch.Tensor, IntermediateTensors]:
1122 + ) -> torch.Tensor | IntermediateTensors:
1123 hidden_states = self.model(
1124 input_ids,
1125 positions,
@@ -1134,7 +1133,7 @@ class Gemma3nForCausalLM(nn.Module):
1133 def compute_logits(
1134 self,
1135 hidden_states: torch.Tensor,
1137 - ) -> Optional[torch.Tensor]:
1136 + ) -> torch.Tensor | None:
1137 logits = self.logits_processor(self.model.embed_tokens, hidden_states)
1138 return logits
1139
vllm/model_executor/models/glm4.py
+10 -11
@@ -24,7 +24,6 @@
24 """Inference-only GLM-4-0414 model compatible with HuggingFace weights."""
25
26 from collections.abc import Iterable
27 -from typing import Optional, Union
27
28 import torch
29 from torch import nn
@@ -56,12 +55,12 @@ class Glm4Attention(nn.Module):
55 num_heads: int,
56 num_kv_heads: int,
57 max_position: int = 4096 * 32,
59 - head_dim: Optional[int] = None,
58 + head_dim: int | None = None,
59 qkv_bias: bool = False,
60 rope_theta: float = 10000,
62 - cache_config: Optional[CacheConfig] = None,
63 - quant_config: Optional[QuantizationConfig] = None,
64 - rope_scaling: Optional[tuple] = None,
61 + cache_config: CacheConfig | None = None,
62 + quant_config: QuantizationConfig | None = None,
63 + rope_scaling: tuple | None = None,
64 prefix: str = "",
65 attn_type: str = AttentionType.DECODER,
66 ) -> None:
@@ -142,7 +141,7 @@ class Glm4DecoderLayer(nn.Module):
141 self,
142 vllm_config: VllmConfig,
143 prefix: str = "",
145 - config: Optional[Glm4Config] = None,
144 + config: Glm4Config | None = None,
145 ) -> None:
146 super().__init__()
147
@@ -189,7 +188,7 @@ class Glm4DecoderLayer(nn.Module):
188 self,
189 positions: torch.Tensor,
190 hidden_states: torch.Tensor,
192 - residual: Optional[torch.Tensor],
191 + residual: torch.Tensor | None,
192 ) -> tuple[torch.Tensor, torch.Tensor]:
193 # Self Attention
194 if residual is None:
@@ -285,9 +284,9 @@ class Glm4ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
284 self,
285 input_ids: torch.Tensor,
286 positions: torch.Tensor,
288 - intermediate_tensors: Optional[IntermediateTensors] = None,
289 - inputs_embeds: Optional[torch.Tensor] = None,
290 - ) -> Union[torch.Tensor, IntermediateTensors]:
287 + intermediate_tensors: IntermediateTensors | None = None,
288 + inputs_embeds: torch.Tensor | None = None,
289 + ) -> torch.Tensor | IntermediateTensors:
290 hidden_states = self.model(
291 input_ids, positions, intermediate_tensors, inputs_embeds
292 )
@@ -296,7 +295,7 @@ class Glm4ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
295 def compute_logits(
296 self,
297 hidden_states: torch.Tensor,
299 - ) -> Optional[torch.Tensor]:
298 + ) -> torch.Tensor | None:
299 logits = self.logits_processor(self.lm_head, hidden_states)
300 return logits
301
vllm/model_executor/models/glm4_1v.py
+26 -26
@@ -27,9 +27,9 @@
27 """Inference-only GLM-4V model compatible with HuggingFace weights."""
28
29 import math
30 -from collections.abc import Iterable, Mapping, Sequence
30 +from collections.abc import Callable, Iterable, Mapping, Sequence
31 from functools import partial
32 -from typing import Annotated, Any, Callable, Literal, Optional, Union
32 +from typing import Annotated, Any, Literal, TypeAlias
33
34 import numpy as np
35 import torch
@@ -140,7 +140,7 @@ class Glm4vImageEmbeddingInputs(TensorSchema):
140 image_grid_thw: Annotated[torch.Tensor, TensorShape("n", 3)]
141
142
143 -Glm4vImageInputs = Union[Glm4vImagePixelInputs, Glm4vImageEmbeddingInputs]
143 +Glm4vImageInputs: TypeAlias = Glm4vImagePixelInputs | Glm4vImageEmbeddingInputs
144
145
146 class Glm4vVideoPixelInputs(TensorSchema):
@@ -176,7 +176,7 @@ class Glm4vVideoEmbeddingInputs(TensorSchema):
176 video_grid_thw: Annotated[torch.Tensor, TensorShape("f", 3)]
177
178
179 -Glm4vVideoInputs = Union[Glm4vVideoPixelInputs, Glm4vVideoEmbeddingInputs]
179 +Glm4vVideoInputs: TypeAlias = Glm4vVideoPixelInputs | Glm4vVideoEmbeddingInputs
180
181 # ==== Vision Encoder ==== #
182
@@ -187,7 +187,7 @@ class Glm4vVisionMLP(nn.Module):
187 in_features: int,
188 hidden_features: int,
189 bias: bool = False,
190 - quant_config: Optional[QuantizationConfig] = None,
190 + quant_config: QuantizationConfig | None = None,
191 prefix: str = "",
192 use_data_parallel: bool = False,
193 ):
@@ -244,7 +244,7 @@ class Glm4vVisionAttention(nn.Module):
244 embed_dim: int,
245 num_heads: int,
246 projection_size: int,
247 - quant_config: Optional[QuantizationConfig] = None,
247 + quant_config: QuantizationConfig | None = None,
248 prefix: str = "",
249 use_data_parallel: bool = False,
250 ) -> None:
@@ -334,8 +334,8 @@ class Glm4vVisionAttention(nn.Module):
334 x: torch.Tensor,
335 cu_seqlens: torch.Tensor,
336 rotary_pos_emb: torch.Tensor,
337 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
338 - seqlens: Optional[list[int]] = None, # Only used for xFormers
337 + max_seqlen: int | None = None, # Only used for Flash Attention
338 + seqlens: list[int] | None = None, # Only used for xFormers
339 ) -> torch.Tensor:
340 # [s, b, c] --> [s, b, head * 3 * head_dim]
341 x, _ = self.qkv(x)
@@ -413,8 +413,8 @@ class Glm4vVisionBlock(nn.Module):
413 dim: int,
414 num_heads: int,
415 mlp_hidden_dim: int,
416 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
417 - quant_config: Optional[QuantizationConfig] = None,
416 + norm_layer: Callable[[int], nn.Module] | None = None,
417 + quant_config: QuantizationConfig | None = None,
418 prefix: str = "",
419 use_data_parallel: bool = False,
420 ) -> None:
@@ -445,8 +445,8 @@ class Glm4vVisionBlock(nn.Module):
445 x: torch.Tensor,
446 cu_seqlens: torch.Tensor,
447 rotary_pos_emb: torch.Tensor,
448 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
449 - seqlens: Optional[list[int]] = None, # Only used for xFormers
448 + max_seqlen: int | None = None, # Only used for Flash Attention
449 + seqlens: list[int] | None = None, # Only used for xFormers
450 ) -> torch.Tensor:
451 x_attn = self.attn(
452 self.norm1(x),
@@ -495,7 +495,7 @@ class Glm4vPatchMerger(nn.Module):
495 self,
496 d_model: int,
497 context_dim: int,
498 - quant_config: Optional[QuantizationConfig] = None,
498 + quant_config: QuantizationConfig | None = None,
499 bias: bool = False,
500 prefix: str = "",
501 use_data_parallel: bool = False,
@@ -693,7 +693,7 @@ class Glm4vVisionTransformer(nn.Module):
693 self,
694 vision_config: Glm4vVisionConfig,
695 norm_eps: float = 1e-6,
696 - quant_config: Optional[QuantizationConfig] = None,
696 + quant_config: QuantizationConfig | None = None,
697 prefix: str = "",
698 use_data_parallel: bool = False,
699 ) -> None:
@@ -809,7 +809,7 @@ class Glm4vVisionTransformer(nn.Module):
809 def compute_attn_mask_seqlen(
810 self,
811 cu_seqlens: torch.Tensor,
812 - ) -> tuple[Optional[int], Optional[list[int]]]:
812 + ) -> tuple[int | None, list[int] | None]:
813 max_seqlen, seqlens = None, None
814 seqlens = (cu_seqlens[1:] - cu_seqlens[:-1]).tolist()
815 if (
@@ -904,7 +904,7 @@ class Glm4vProcessingInfo(BaseProcessingInfo):
904 def get_tokenizer(self):
905 return self.ctx.tokenizer
906
907 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
907 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
908 return {"image": None, "video": 1}
909
910 def get_image_processor(self, **kwargs: object) -> Glm4vImageProcessor:
@@ -1141,7 +1141,7 @@ class Glm4vDummyInputsBuilder(BaseDummyInputsBuilder[Glm4vProcessingInfo]):
1141 self,
1142 seq_len: int,
1143 mm_counts: Mapping[str, int],
1144 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
1144 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
1145 ) -> MultiModalDataDict:
1146 num_images = mm_counts.get("image", 0)
1147 num_videos = mm_counts.get("video", 0)
@@ -1177,7 +1177,7 @@ class Glm4vDummyInputsBuilder(BaseDummyInputsBuilder[Glm4vProcessingInfo]):
1177 height: int,
1178 num_frames: int,
1179 num_videos: int,
1180 - overrides: Optional[VideoDummyOptions] = None,
1180 + overrides: VideoDummyOptions | None = None,
1181 ) -> list[VideoItem]:
1182 if overrides:
1183 if overrides.num_frames:
@@ -1419,7 +1419,7 @@ class Glm4vForConditionalGeneration(
1419 supports_encoder_tp_data = True
1420
1421 @classmethod
1422 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1422 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1423 if modality.startswith("image"):
1424 return "<|begin_of_image|><|image|><|end_of_image|>"
1425 if modality.startswith("video"):
@@ -1465,7 +1465,7 @@ class Glm4vForConditionalGeneration(
1465
1466 def _parse_and_validate_image_input(
1467 self, **kwargs: object
1468 - ) -> Optional[Glm4vImageInputs]:
1468 + ) -> Glm4vImageInputs | None:
1469 pixel_values = kwargs.pop("pixel_values", None)
1470 image_embeds = kwargs.pop("image_embeds", None)
1471 image_grid_thw = kwargs.pop("image_grid_thw", None)
@@ -1489,7 +1489,7 @@ class Glm4vForConditionalGeneration(
1489
1490 def _parse_and_validate_video_input(
1491 self, **kwargs: object
1492 - ) -> Optional[Glm4vVideoInputs]:
1492 + ) -> Glm4vVideoInputs | None:
1493 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
1494 video_embeds = kwargs.pop("video_embeds", None)
1495 video_grid_thw = kwargs.pop("video_grid_thw", None)
@@ -1594,7 +1594,7 @@ class Glm4vForConditionalGeneration(
1594
1595 def get_multimodal_embeddings(
1596 self, **kwargs: object
1597 - ) -> Optional[MultiModalEmbeddings]:
1597 + ) -> MultiModalEmbeddings | None:
1598 mm_input_by_modality = self._parse_and_validate_multimodal_inputs(**kwargs)
1599 if not mm_input_by_modality:
1600 return None
@@ -1619,10 +1619,10 @@ class Glm4vForConditionalGeneration(
1619 self,
1620 input_ids: torch.Tensor,
1621 positions: torch.Tensor,
1622 - intermediate_tensors: Optional[IntermediateTensors] = None,
1623 - inputs_embeds: Optional[torch.Tensor] = None,
1622 + intermediate_tensors: IntermediateTensors | None = None,
1623 + inputs_embeds: torch.Tensor | None = None,
1624 **kwargs: object,
1625 - ) -> Union[torch.Tensor, IntermediateTensors]:
1625 + ) -> torch.Tensor | IntermediateTensors:
1626 """Run forward pass for GLM-4V.
1627
1628 Args:
@@ -1652,7 +1652,7 @@ class Glm4vForConditionalGeneration(
1652 def compute_logits(
1653 self,
1654 hidden_states: torch.Tensor,
1655 - ) -> Optional[torch.Tensor]:
1655 + ) -> torch.Tensor | None:
1656 return self.language_model.compute_logits(hidden_states)
1657
1658 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/glm4_moe.py
+18 -18
@@ -26,7 +26,7 @@
26 import typing
27 from collections.abc import Callable, Iterable
28 from itertools import islice
29 -from typing import Any, Optional, Union
29 +from typing import Any
30
31 import torch
32 from torch import nn
@@ -81,7 +81,7 @@ class Glm4MoeMLP(nn.Module):
81 hidden_size: int,
82 intermediate_size: int,
83 hidden_act: str,
84 - quant_config: Optional[QuantizationConfig] = None,
84 + quant_config: QuantizationConfig | None = None,
85 reduce_results: bool = True,
86 prefix: str = "",
87 ) -> None:
@@ -118,7 +118,7 @@ class Glm4MoE(nn.Module):
118 def __init__(
119 self,
120 config: Glm4MoeConfig,
121 - quant_config: Optional[QuantizationConfig] = None,
121 + quant_config: QuantizationConfig | None = None,
122 prefix: str = "",
123 enable_eplb: bool = False,
124 ):
@@ -234,14 +234,14 @@ class Glm4MoeAttention(nn.Module):
234 num_heads: int,
235 num_kv_heads: int,
236 rope_theta: float = 10000,
237 - rope_scaling: Optional[dict[str, Any]] = None,
237 + rope_scaling: dict[str, Any] | None = None,
238 max_position_embeddings: int = 131072,
239 - head_dim: Optional[int] = None,
239 + head_dim: int | None = None,
240 rms_norm_eps: float = 1e-05,
241 qkv_bias: bool = False,
242 use_qk_norm: bool = False,
243 - cache_config: Optional[CacheConfig] = None,
244 - quant_config: Optional[QuantizationConfig] = None,
243 + cache_config: CacheConfig | None = None,
244 + quant_config: QuantizationConfig | None = None,
245 prefix: str = "",
246 ) -> None:
247 super().__init__()
@@ -334,8 +334,8 @@ class Glm4MoeDecoderLayer(nn.Module):
334 def __init__(
335 self,
336 config: Glm4MoeConfig,
337 - cache_config: Optional[CacheConfig] = None,
338 - quant_config: Optional[QuantizationConfig] = None,
337 + cache_config: CacheConfig | None = None,
338 + quant_config: QuantizationConfig | None = None,
339 prefix: str = "",
340 enable_eplb: bool = False,
341 ) -> None:
@@ -395,7 +395,7 @@ class Glm4MoeDecoderLayer(nn.Module):
395 self,
396 positions: torch.Tensor,
397 hidden_states: torch.Tensor,
398 - residual: Optional[torch.Tensor],
398 + residual: torch.Tensor | None,
399 ) -> tuple[torch.Tensor, torch.Tensor]:
400 if residual is None:
401 residual = hidden_states
@@ -462,9 +462,9 @@ class Glm4MoeModel(nn.Module):
462 self,
463 input_ids: torch.Tensor,
464 positions: torch.Tensor,
465 - intermediate_tensors: Optional[IntermediateTensors] = None,
466 - inputs_embeds: Optional[torch.Tensor] = None,
467 - ) -> Union[torch.Tensor, IntermediateTensors]:
465 + intermediate_tensors: IntermediateTensors | None = None,
466 + inputs_embeds: torch.Tensor | None = None,
467 + ) -> torch.Tensor | IntermediateTensors:
468 if get_pp_group().is_first_rank:
469 if inputs_embeds is not None:
470 hidden_states = inputs_embeds
@@ -704,9 +704,9 @@ class Glm4MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
704 self,
705 input_ids: torch.Tensor,
706 positions: torch.Tensor,
707 - intermediate_tensors: Optional[IntermediateTensors] = None,
708 - inputs_embeds: Optional[torch.Tensor] = None,
709 - ) -> Union[torch.Tensor, IntermediateTensors]:
707 + intermediate_tensors: IntermediateTensors | None = None,
708 + inputs_embeds: torch.Tensor | None = None,
709 + ) -> torch.Tensor | IntermediateTensors:
710 hidden_states = self.model(
711 input_ids, positions, intermediate_tensors, inputs_embeds
712 )
@@ -715,7 +715,7 @@ class Glm4MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
715 def compute_logits(
716 self,
717 hidden_states: torch.Tensor,
718 - ) -> Optional[torch.Tensor]:
718 + ) -> torch.Tensor | None:
719 logits = self.logits_processor(self.lm_head, hidden_states)
720 return logits
721
@@ -729,7 +729,7 @@ class Glm4MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
729
730 def get_spec_layer_idx_from_weight_name(
731 config: Glm4MoeConfig, weight_name: str
732 -) -> Optional[int]:
732 +) -> int | None:
733 if hasattr(config, "num_nextn_predict_layers") and (
734 config.num_nextn_predict_layers > 0
735 ):
vllm/model_executor/models/glm4_moe_mtp.py
+8 -9
@@ -24,7 +24,6 @@
24 """Inference-only GLM-4.5 MTP model compatible with HuggingFace weights."""
25
26 from collections.abc import Iterable
27 -from typing import Optional
27
28 import torch
29 import torch.nn as nn
@@ -52,7 +51,7 @@ class SharedHead(nn.Module):
51 self,
52 config: PretrainedConfig,
53 prefix: str,
55 - quant_config: Optional[QuantizationConfig] = None,
54 + quant_config: QuantizationConfig | None = None,
55 ) -> None:
56 super().__init__()
57 self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
@@ -72,8 +71,8 @@ class Glm4MoeMultiTokenPredictorLayer(nn.Module):
71 self,
72 config: PretrainedConfig,
73 prefix: str,
75 - cache_config: Optional[CacheConfig] = None,
76 - quant_config: Optional[QuantizationConfig] = None,
74 + cache_config: CacheConfig | None = None,
75 + quant_config: QuantizationConfig | None = None,
76 ) -> None:
77 super().__init__()
78 self.enorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
@@ -94,7 +93,7 @@ class Glm4MoeMultiTokenPredictorLayer(nn.Module):
93 input_ids: torch.Tensor,
94 positions: torch.Tensor,
95 previous_hidden_states: torch.Tensor,
97 - inputs_embeds: Optional[torch.Tensor] = None,
96 + inputs_embeds: torch.Tensor | None = None,
97 spec_step_index: int = 0,
98 ) -> torch.Tensor:
99 assert inputs_embeds is not None
@@ -149,7 +148,7 @@ class Glm4MoeMultiTokenPredictor(nn.Module):
148 input_ids: torch.Tensor,
149 positions: torch.Tensor,
150 previous_hidden_states: torch.Tensor,
152 - inputs_embeds: Optional[torch.Tensor] = None,
151 + inputs_embeds: torch.Tensor | None = None,
152 spec_step_idx: int = 0,
153 ) -> torch.Tensor:
154 if inputs_embeds is None:
@@ -192,8 +191,8 @@ class Glm4MoeMTP(nn.Module, SupportsPP):
191 input_ids: torch.Tensor,
192 positions: torch.Tensor,
193 hidden_states: torch.Tensor,
195 - intermediate_tensors: Optional[IntermediateTensors] = None,
196 - inputs_embeds: Optional[torch.Tensor] = None,
194 + intermediate_tensors: IntermediateTensors | None = None,
195 + inputs_embeds: torch.Tensor | None = None,
196 spec_step_idx: int = 0,
197 ) -> torch.Tensor:
198 hidden_states = self.model(
@@ -205,7 +204,7 @@ class Glm4MoeMTP(nn.Module, SupportsPP):
204 self,
205 hidden_states: torch.Tensor,
206 spec_step_idx: int = 0,
208 - ) -> Optional[torch.Tensor]:
207 + ) -> torch.Tensor | None:
208 return self.model.compute_logits(hidden_states, spec_step_idx)
209
210 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/glm4v.py
+22 -22
@@ -8,7 +8,7 @@
8 import itertools
9 from argparse import Namespace
10 from collections.abc import Mapping, Sequence
11 -from typing import Annotated, Literal, Optional, Union
11 +from typing import Annotated, Literal
12
13 import torch
14 from torch import nn
@@ -109,7 +109,7 @@ class EVA2CLIPAttention(nn.Module):
109 def __init__(
110 self,
111 config,
112 - quant_config: Optional[QuantizationConfig] = None,
112 + quant_config: QuantizationConfig | None = None,
113 prefix: str = "",
114 ):
115 super().__init__()
@@ -152,7 +152,7 @@ class EVA2CLIPMLP(nn.Module):
152 def __init__(
153 self,
154 config,
155 - quant_config: Optional[QuantizationConfig] = None,
155 + quant_config: QuantizationConfig | None = None,
156 prefix: str = "",
157 ):
158 super().__init__()
@@ -182,7 +182,7 @@ class EVA2CLIPTransformerLayer(nn.Module):
182 def __init__(
183 self,
184 config,
185 - quant_config: Optional[QuantizationConfig] = None,
185 + quant_config: QuantizationConfig | None = None,
186 prefix: str = "",
187 ):
188 super().__init__()
@@ -211,7 +211,7 @@ class EVA2CLIPTransformer(nn.Module):
211 def __init__(
212 self,
213 config,
214 - quant_config: Optional[QuantizationConfig] = None,
214 + quant_config: QuantizationConfig | None = None,
215 prefix: str = "",
216 ):
217 super().__init__()
@@ -237,7 +237,7 @@ class EVA2CLIPGLU(nn.Module):
237 self,
238 config,
239 in_features,
240 - quant_config: Optional[QuantizationConfig] = None,
240 + quant_config: QuantizationConfig | None = None,
241 prefix: str = "",
242 ):
243 """
@@ -317,7 +317,7 @@ class EVA2CLIPModel(nn.Module):
317 def __init__(
318 self,
319 config,
320 - quant_config: Optional[QuantizationConfig] = None,
320 + quant_config: QuantizationConfig | None = None,
321 prefix: str = "",
322 ):
323 super().__init__()
@@ -416,9 +416,9 @@ class GLM4VProcessor:
416
417 def __call__(
418 self,
419 - text: Optional[Union[TextInput, list[TextInput]]] = None,
420 - images: Optional[Union[ImageInput, list[ImageInput]]] = None,
421 - return_tensors: Optional[Union[str, TensorType]] = None,
419 + text: TextInput | list[TextInput] | None = None,
420 + images: ImageInput | list[ImageInput] | None = None,
421 + return_tensors: str | TensorType | None = None,
422 ) -> BatchFeature:
423 if text is None:
424 text = []
@@ -458,7 +458,7 @@ class GLM4VProcessingInfo(BaseProcessingInfo):
458 **kwargs,
459 )
460
461 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
461 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
462 return {"image": 1}
463
464 def get_num_image_tokens(self) -> int:
@@ -487,7 +487,7 @@ class GLM4VDummyInputsBuilder(BaseDummyInputsBuilder[GLM4VProcessingInfo]):
487 self,
488 seq_len: int,
489 mm_counts: Mapping[str, int],
490 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
490 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
491 ) -> MultiModalDataDict:
492 hf_config = self.info.get_hf_config()
493 vision_config = hf_config.vision_config
@@ -578,7 +578,7 @@ class GLM4VForCausalLM(
578 )
579
580 @classmethod
581 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
581 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
582 if modality.startswith("image"):
583 return "<|begin_of_image|><|endoftext|><|end_of_image|>"
584
@@ -601,7 +601,7 @@ class GLM4VForCausalLM(
601
602 def _parse_and_validate_image_input(
603 self, **kwargs: object
604 - ) -> Optional[GLMVImagePixelInputs]:
604 + ) -> GLMVImagePixelInputs | None:
605 pixel_values = kwargs.pop("pixel_values", None)
606
607 if pixel_values is not None:
@@ -624,12 +624,12 @@ class GLM4VForCausalLM(
624 cls,
625 input_tokens: list[int],
626 hf_config: PretrainedConfig,
627 - image_grid_thw: Union[list[list[int]], torch.Tensor],
628 - video_grid_thw: Union[list[list[int]], torch.Tensor],
627 + image_grid_thw: list[list[int]] | torch.Tensor,
628 + video_grid_thw: list[list[int]] | torch.Tensor,
629 context_len: int = 0,
630 - seq_len: Optional[int] = None,
631 - second_per_grid_ts: Optional[list[float]] = None,
632 - audio_feature_lengths: Optional[torch.Tensor] = None,
630 + seq_len: int | None = None,
631 + second_per_grid_ts: list[float] | None = None,
632 + audio_feature_lengths: torch.Tensor | None = None,
633 use_audio_in_video: bool = False,
634 ) -> tuple[torch.Tensor, int]:
635 """Get mrope input positions and delta value for GLM4V."""
@@ -780,10 +780,10 @@ class GLM4VForCausalLM(
780 self,
781 input_ids: torch.Tensor,
782 positions: torch.Tensor,
783 - intermediate_tensors: Optional[IntermediateTensors] = None,
784 - inputs_embeds: Optional[torch.Tensor] = None,
783 + intermediate_tensors: IntermediateTensors | None = None,
784 + inputs_embeds: torch.Tensor | None = None,
785 **kwargs: object,
786 - ) -> Union[torch.Tensor, IntermediateTensors]:
786 + ) -> torch.Tensor | IntermediateTensors:
787 if intermediate_tensors is not None:
788 inputs_embeds = None
789
vllm/model_executor/models/gpt2.py
+14 -15
@@ -22,7 +22,6 @@
22
23 from collections.abc import Iterable
24 from itertools import islice
25 -from typing import Optional, Union
25
26 import torch
27 from torch import nn
@@ -65,8 +64,8 @@ class GPT2Attention(nn.Module):
64 def __init__(
65 self,
66 config: GPT2Config,
68 - cache_config: Optional[CacheConfig] = None,
69 - quant_config: Optional[QuantizationConfig] = None,
67 + cache_config: CacheConfig | None = None,
68 + quant_config: QuantizationConfig | None = None,
69 prefix: str = "",
70 ):
71 super().__init__()
@@ -118,7 +117,7 @@ class GPT2MLP(nn.Module):
117 self,
118 intermediate_size: int,
119 config: GPT2Config,
121 - quant_config: Optional[QuantizationConfig] = None,
120 + quant_config: QuantizationConfig | None = None,
121 prefix: str = "",
122 ):
123 super().__init__()
@@ -150,8 +149,8 @@ class GPT2Block(nn.Module):
149 def __init__(
150 self,
151 config: GPT2Config,
153 - cache_config: Optional[CacheConfig] = None,
154 - quant_config: Optional[QuantizationConfig] = None,
152 + cache_config: CacheConfig | None = None,
153 + quant_config: QuantizationConfig | None = None,
154 prefix: str = "",
155 ):
156 super().__init__()
@@ -221,9 +220,9 @@ class GPT2Model(nn.Module):
220 self,
221 input_ids: torch.Tensor,
222 position_ids: torch.Tensor,
224 - intermediate_tensors: Optional[IntermediateTensors],
225 - inputs_embeds: Optional[torch.Tensor],
226 - ) -> Union[torch.Tensor, IntermediateTensors]:
223 + intermediate_tensors: IntermediateTensors | None,
224 + inputs_embeds: torch.Tensor | None,
225 + ) -> torch.Tensor | IntermediateTensors:
226 if get_pp_group().is_first_rank:
227 if inputs_embeds is None:
228 inputs_embeds = self.get_input_embeddings(input_ids)
@@ -301,9 +300,9 @@ class GPT2LMHeadModel(nn.Module, SupportsPP):
300 self,
301 input_ids: torch.Tensor,
302 positions: torch.Tensor,
304 - intermediate_tensors: Optional[IntermediateTensors] = None,
305 - inputs_embeds: Optional[torch.Tensor] = None,
306 - ) -> Union[torch.Tensor, IntermediateTensors]:
303 + intermediate_tensors: IntermediateTensors | None = None,
304 + inputs_embeds: torch.Tensor | None = None,
305 + ) -> torch.Tensor | IntermediateTensors:
306 hidden_states = self.transformer(
307 input_ids, positions, intermediate_tensors, inputs_embeds
308 )
@@ -312,7 +311,7 @@ class GPT2LMHeadModel(nn.Module, SupportsPP):
311 def compute_logits(
312 self,
313 hidden_states: torch.Tensor,
315 - ) -> Optional[torch.Tensor]:
314 + ) -> torch.Tensor | None:
315 logits = self.logits_processor(self.lm_head, hidden_states)
316 return logits
317
@@ -367,8 +366,8 @@ class GPT2ForSequenceClassification(nn.Module):
366 self,
367 input_ids: torch.Tensor,
368 positions: torch.Tensor,
370 - intermediate_tensors: Optional[IntermediateTensors] = None,
371 - inputs_embeds: Optional[torch.Tensor] = None,
369 + intermediate_tensors: IntermediateTensors | None = None,
370 + inputs_embeds: torch.Tensor | None = None,
371 ) -> torch.Tensor:
372 hidden_states = self.transformer(
373 input_ids=input_ids,
vllm/model_executor/models/gpt_bigcode.py
+12 -13
@@ -23,7 +23,6 @@
23
24 from collections.abc import Iterable
25 from itertools import islice
26 -from typing import Optional, Union
26
27 import torch
28 from torch import nn
@@ -62,8 +61,8 @@ class GPTBigCodeAttention(nn.Module):
61 def __init__(
62 self,
63 config: GPTBigCodeConfig,
65 - cache_config: Optional[CacheConfig] = None,
66 - quant_config: Optional[QuantizationConfig] = None,
64 + cache_config: CacheConfig | None = None,
65 + quant_config: QuantizationConfig | None = None,
66 prefix: str = "",
67 ):
68 super().__init__()
@@ -133,7 +132,7 @@ class GPTBigMLP(nn.Module):
132 self,
133 intermediate_size: int,
134 config: GPTBigCodeConfig,
136 - quant_config: Optional[QuantizationConfig] = None,
135 + quant_config: QuantizationConfig | None = None,
136 prefix: str = "",
137 ):
138 super().__init__()
@@ -165,8 +164,8 @@ class GPTBigCodeBlock(nn.Module):
164 def __init__(
165 self,
166 config: GPTBigCodeConfig,
168 - cache_config: Optional[CacheConfig] = None,
169 - quant_config: Optional[QuantizationConfig] = None,
167 + cache_config: CacheConfig | None = None,
168 + quant_config: QuantizationConfig | None = None,
169 prefix: str = "",
170 ):
171 super().__init__()
@@ -243,9 +242,9 @@ class GPTBigCodeModel(nn.Module):
242 self,
243 input_ids: torch.Tensor,
244 position_ids: torch.Tensor,
246 - intermediate_tensors: Optional[IntermediateTensors],
247 - inputs_embeds: Optional[torch.Tensor] = None,
248 - ) -> Union[torch.Tensor, IntermediateTensors]:
245 + intermediate_tensors: IntermediateTensors | None,
246 + inputs_embeds: torch.Tensor | None = None,
247 + ) -> torch.Tensor | IntermediateTensors:
248 if get_pp_group().is_first_rank:
249 if inputs_embeds is None:
250 inputs_embeds = self.get_input_embeddings(input_ids)
@@ -326,9 +325,9 @@ class GPTBigCodeForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
325 self,
326 input_ids: torch.Tensor,
327 positions: torch.Tensor,
329 - intermediate_tensors: Optional[IntermediateTensors] = None,
330 - inputs_embeds: Optional[torch.Tensor] = None,
331 - ) -> Union[torch.Tensor, IntermediateTensors]:
328 + intermediate_tensors: IntermediateTensors | None = None,
329 + inputs_embeds: torch.Tensor | None = None,
330 + ) -> torch.Tensor | IntermediateTensors:
331 hidden_states = self.transformer(
332 input_ids, positions, intermediate_tensors, inputs_embeds
333 )
@@ -337,7 +336,7 @@ class GPTBigCodeForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
336 def compute_logits(
337 self,
338 hidden_states: torch.Tensor,
340 - ) -> Optional[torch.Tensor]:
339 + ) -> torch.Tensor | None:
340 logits = self.logits_processor(self.lm_head, hidden_states)
341 return logits
342
vllm/model_executor/models/gpt_j.py
+12 -13
@@ -21,7 +21,6 @@
21
22 from collections.abc import Iterable
23 from itertools import islice
24 -from typing import Optional, Union
24
25 import torch
26 from torch import nn
@@ -64,8 +63,8 @@ class GPTJAttention(nn.Module):
63 def __init__(
64 self,
65 config: GPTJConfig,
67 - cache_config: Optional[CacheConfig] = None,
68 - quant_config: Optional[QuantizationConfig] = None,
66 + cache_config: CacheConfig | None = None,
67 + quant_config: QuantizationConfig | None = None,
68 prefix: str = "",
69 ):
70 super().__init__()
@@ -130,7 +129,7 @@ class GPTJMLP(nn.Module):
129 self,
130 intermediate_size: int,
131 config: GPTJConfig,
133 - quant_config: Optional[QuantizationConfig] = None,
132 + quant_config: QuantizationConfig | None = None,
133 ):
134 super().__init__()
135 hidden_size = config.n_embd
@@ -157,8 +156,8 @@ class GPTJBlock(nn.Module):
156 def __init__(
157 self,
158 config: GPTJConfig,
160 - cache_config: Optional[CacheConfig] = None,
161 - quant_config: Optional[QuantizationConfig] = None,
159 + cache_config: CacheConfig | None = None,
160 + quant_config: QuantizationConfig | None = None,
161 prefix: str = "",
162 ):
163 super().__init__()
@@ -218,9 +217,9 @@ class GPTJModel(nn.Module):
217 self,
218 input_ids: torch.Tensor,
219 position_ids: torch.Tensor,
221 - intermediate_tensors: Optional[IntermediateTensors],
222 - inputs_embeds: Optional[torch.Tensor] = None,
223 - ) -> Union[torch.Tensor, IntermediateTensors]:
220 + intermediate_tensors: IntermediateTensors | None,
221 + inputs_embeds: torch.Tensor | None = None,
222 + ) -> torch.Tensor | IntermediateTensors:
223 if get_pp_group().is_first_rank:
224 if inputs_embeds is not None:
225 hidden_states = inputs_embeds
@@ -322,9 +321,9 @@ class GPTJForCausalLM(nn.Module, SupportsPP):
321 self,
322 input_ids: torch.Tensor,
323 positions: torch.Tensor,
325 - intermediate_tensors: Optional[IntermediateTensors] = None,
326 - inputs_embeds: Optional[torch.Tensor] = None,
327 - ) -> Union[torch.Tensor, IntermediateTensors]:
324 + intermediate_tensors: IntermediateTensors | None = None,
325 + inputs_embeds: torch.Tensor | None = None,
326 + ) -> torch.Tensor | IntermediateTensors:
327 hidden_states = self.transformer(
328 input_ids, positions, intermediate_tensors, inputs_embeds
329 )
@@ -333,7 +332,7 @@ class GPTJForCausalLM(nn.Module, SupportsPP):
332 def compute_logits(
333 self,
334 hidden_states: torch.Tensor,
336 - ) -> Optional[torch.Tensor]:
335 + ) -> torch.Tensor | None:
336 logits = self.logits_processor(self.lm_head, hidden_states, self.lm_head.bias)
337 return logits
338
vllm/model_executor/models/gpt_neox.py
+12 -13
@@ -21,7 +21,6 @@
21
22 from collections.abc import Iterable
23 from itertools import islice
24 -from typing import Optional, Union
24
25 import torch
26 from torch import nn
@@ -61,8 +60,8 @@ class GPTNeoXAttention(nn.Module):
60 def __init__(
61 self,
62 config: GPTNeoXConfig,
64 - cache_config: Optional[CacheConfig] = None,
65 - quant_config: Optional[QuantizationConfig] = None,
63 + cache_config: CacheConfig | None = None,
64 + quant_config: QuantizationConfig | None = None,
65 prefix: str = "",
66 ):
67 super().__init__()
@@ -125,7 +124,7 @@ class GPTNeoXMLP(nn.Module):
124 def __init__(
125 self,
126 config: GPTNeoXConfig,
128 - quant_config: Optional[QuantizationConfig] = None,
127 + quant_config: QuantizationConfig | None = None,
128 ):
129 super().__init__()
130 self.dense_h_to_4h = ColumnParallelLinear(
@@ -151,8 +150,8 @@ class GPTNeoXLayer(nn.Module):
150 def __init__(
151 self,
152 config: GPTNeoXConfig,
154 - cache_config: Optional[CacheConfig] = None,
155 - quant_config: Optional[QuantizationConfig] = None,
153 + cache_config: CacheConfig | None = None,
154 + quant_config: QuantizationConfig | None = None,
155 prefix: str = "",
156 ):
157 super().__init__()
@@ -232,9 +231,9 @@ class GPTNeoXModel(nn.Module):
231 self,
232 input_ids: torch.Tensor,
233 position_ids: torch.Tensor,
235 - intermediate_tensors: Optional[IntermediateTensors],
236 - inputs_embeds: Optional[torch.Tensor] = None,
237 - ) -> Union[torch.Tensor, IntermediateTensors]:
234 + intermediate_tensors: IntermediateTensors | None,
235 + inputs_embeds: torch.Tensor | None = None,
236 + ) -> torch.Tensor | IntermediateTensors:
237 if get_pp_group().is_first_rank:
238 if inputs_embeds is not None:
239 hidden_states = inputs_embeds
@@ -320,9 +319,9 @@ class GPTNeoXForCausalLM(nn.Module, SupportsPP):
319 self,
320 input_ids: torch.Tensor,
321 positions: torch.Tensor,
323 - intermediate_tensors: Optional[IntermediateTensors] = None,
324 - inputs_embeds: Optional[torch.Tensor] = None,
325 - ) -> Union[torch.Tensor, IntermediateTensors]:
322 + intermediate_tensors: IntermediateTensors | None = None,
323 + inputs_embeds: torch.Tensor | None = None,
324 + ) -> torch.Tensor | IntermediateTensors:
325 hidden_states = self.gpt_neox(
326 input_ids, positions, intermediate_tensors, inputs_embeds
327 )
@@ -331,7 +330,7 @@ class GPTNeoXForCausalLM(nn.Module, SupportsPP):
330 def compute_logits(
331 self,
332 hidden_states: torch.Tensor,
334 - ) -> Optional[torch.Tensor]:
333 + ) -> torch.Tensor | None:
334 logits = self.logits_processor(self.embed_out, hidden_states)
335 return logits
336
vllm/model_executor/models/gpt_oss.py
+7 -8
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable
4 -from typing import Optional
4
5 import torch
6 import torch.distributed as dist
@@ -49,8 +48,8 @@ class OAIAttention(nn.Module):
48 def __init__(
49 self,
50 config: GptOssConfig,
52 - quant_config: Optional[QuantizationConfig] = None,
53 - cache_config: Optional[CacheConfig] = None,
51 + quant_config: QuantizationConfig | None = None,
52 + cache_config: CacheConfig | None = None,
53 prefix: str = "",
54 ):
55 super().__init__()
@@ -208,7 +207,7 @@ class TransformerBlock(torch.nn.Module):
207 self,
208 hidden_states: torch.Tensor,
209 positions: torch.Tensor,
211 - residual: Optional[torch.Tensor],
210 + residual: torch.Tensor | None,
211 ) -> torch.Tensor:
212 # Self Attention
213 if residual is None:
@@ -260,8 +259,8 @@ class GptOssModel(nn.Module):
259 self,
260 input_ids: torch.Tensor,
261 positions: torch.Tensor,
263 - intermediate_tensors: Optional[IntermediateTensors] = None,
264 - inputs_embeds: Optional[torch.Tensor] = None,
262 + intermediate_tensors: IntermediateTensors | None = None,
263 + inputs_embeds: torch.Tensor | None = None,
264 ) -> torch.Tensor:
265 if get_pp_group().is_first_rank:
266 if inputs_embeds is not None:
@@ -687,8 +686,8 @@ class GptOssForCausalLM(nn.Module, SupportsPP, SupportsEagle3):
686 self,
687 input_ids: torch.Tensor,
688 positions: torch.Tensor,
690 - intermediate_tensors: Optional[IntermediateTensors] = None,
691 - inputs_embeds: Optional[torch.Tensor] = None,
689 + intermediate_tensors: IntermediateTensors | None = None,
690 + inputs_embeds: torch.Tensor | None = None,
691 ) -> torch.Tensor:
692 return self.model(input_ids, positions, intermediate_tensors, inputs_embeds)
693
vllm/model_executor/models/granite.py
+15 -15
@@ -26,7 +26,7 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Any, Optional, Union
29 +from typing import Any
30
31 import torch
32 from torch import nn
@@ -73,7 +73,7 @@ class GraniteMLP(nn.Module):
73 hidden_size: int,
74 intermediate_size: int,
75 hidden_act: str,
76 - quant_config: Optional[QuantizationConfig] = None,
76 + quant_config: QuantizationConfig | None = None,
77 bias: bool = False,
78 prefix: str = "",
79 ) -> None:
@@ -113,11 +113,11 @@ class GraniteAttention(nn.Module):
113 num_heads: int,
114 num_kv_heads: int,
115 rope_theta: float = 10000,
116 - rope_scaling: Optional[dict[str, Any]] = None,
116 + rope_scaling: dict[str, Any] | None = None,
117 max_position_embeddings: int = 8192,
118 - quant_config: Optional[QuantizationConfig] = None,
118 + quant_config: QuantizationConfig | None = None,
119 bias: bool = False,
120 - cache_config: Optional[CacheConfig] = None,
120 + cache_config: CacheConfig | None = None,
121 prefix: str = "",
122 ) -> None:
123 super().__init__()
@@ -197,8 +197,8 @@ class GraniteDecoderLayer(nn.Module):
197 def __init__(
198 self,
199 config: GraniteConfig,
200 - cache_config: Optional[CacheConfig] = None,
201 - quant_config: Optional[QuantizationConfig] = None,
200 + cache_config: CacheConfig | None = None,
201 + quant_config: QuantizationConfig | None = None,
202 prefix: str = "",
203 ) -> None:
204 super().__init__()
@@ -323,11 +323,11 @@ class GraniteModel(nn.Module):
323
324 def forward(
325 self,
326 - input_ids: Optional[torch.Tensor],
326 + input_ids: torch.Tensor | None,
327 positions: torch.Tensor,
328 - intermediate_tensors: Optional[IntermediateTensors],
329 - inputs_embeds: Optional[torch.Tensor] = None,
330 - ) -> Union[torch.Tensor, IntermediateTensors]:
328 + intermediate_tensors: IntermediateTensors | None,
329 + inputs_embeds: torch.Tensor | None = None,
330 + ) -> torch.Tensor | IntermediateTensors:
331 if get_pp_group().is_first_rank:
332 if inputs_embeds is not None:
333 hidden_states = inputs_embeds
@@ -480,15 +480,15 @@ class GraniteForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
480 self,
481 input_ids: torch.Tensor,
482 positions: torch.Tensor,
483 - intermediate_tensors: Optional[IntermediateTensors] = None,
484 - inputs_embeds: Optional[torch.Tensor] = None,
485 - ) -> Union[torch.Tensor, IntermediateTensors]:
483 + intermediate_tensors: IntermediateTensors | None = None,
484 + inputs_embeds: torch.Tensor | None = None,
485 + ) -> torch.Tensor | IntermediateTensors:
486 model_output = self.model(
487 input_ids, positions, intermediate_tensors, inputs_embeds
488 )
489 return model_output
490
491 - def compute_logits(self, hidden_states: torch.Tensor) -> Optional[torch.Tensor]:
491 + def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None:
492 logits = self.logits_processor(self.lm_head, hidden_states)
493 return logits
494
vllm/model_executor/models/granite_speech.py
+14 -14
@@ -26,7 +26,7 @@
26
27 import math
28 from collections.abc import Iterable, Mapping
29 -from typing import Annotated, Optional, Union
29 +from typing import Annotated
30
31 import torch
32 import torch.nn.functional as F
@@ -92,7 +92,7 @@ class GraniteSpeechAudioInputs(TensorSchema):
92
93
94 class GraniteSpeechMultiModalProcessingInfo(BaseProcessingInfo):
95 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
95 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
96 return {"audio": 1}
97
98 # There is no limit to the maximum number of audio tokens that can be
@@ -196,7 +196,7 @@ class GraniteSpeechDummyInputsBuilder(
196 self,
197 seq_len: int,
198 mm_counts: Mapping[str, int],
199 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
199 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
200 ) -> MultiModalDataDict:
201 num_audios = mm_counts.get("audio", 0)
202 audio_overrides = mm_options.get("audio") if mm_options else None
@@ -222,7 +222,7 @@ class GraniteSpeechEncoderProjector(nn.Module):
222 self,
223 config: PretrainedConfig,
224 cache_config: CacheConfig,
225 - quant_config: Optional[QuantizationConfig] = None,
225 + quant_config: QuantizationConfig | None = None,
226 prefix: str = "",
227 ):
228 super().__init__()
@@ -279,7 +279,7 @@ class GraniteSpeechConformerFeedForward(nn.Module):
279 def __init__(
280 self,
281 config: PretrainedConfig,
282 - quant_config: Optional[QuantizationConfig] = None,
282 + quant_config: QuantizationConfig | None = None,
283 prefix: str = "",
284 ):
285 super().__init__()
@@ -479,7 +479,7 @@ class GraniteSpeechCTCEncoder(nn.Module):
479 self,
480 config: PretrainedConfig,
481 prefix: str,
482 - quant_config: Optional[QuantizationConfig] = None,
482 + quant_config: QuantizationConfig | None = None,
483 ):
484 super().__init__()
485 self.config = config
@@ -561,7 +561,7 @@ class GraniteSpeechForConditionalGeneration(
561 }
562
563 @classmethod
564 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
564 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
565 if modality.startswith("audio"):
566 return "<|audio|>"
567
@@ -606,7 +606,7 @@ class GraniteSpeechForConditionalGeneration(
606 def _parse_and_validate_audio_input(
607 self,
608 **kwargs: object,
609 - ) -> Optional[GraniteSpeechAudioInputs]:
609 + ) -> GraniteSpeechAudioInputs | None:
610 input_features = kwargs.pop("input_features", None)
611 input_features_mask = kwargs.pop("input_features_mask", None)
612 audio_embed_sizes = kwargs.pop("audio_embed_sizes", None)
@@ -763,9 +763,9 @@ class GraniteSpeechForConditionalGeneration(
763 def get_input_embeddings(
764 self,
765 input_ids: torch.Tensor,
766 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
766 + multimodal_embeddings: MultiModalEmbeddings | None = None,
767 *,
768 - is_multimodal: Optional[torch.Tensor] = None,
768 + is_multimodal: torch.Tensor | None = None,
769 # Multi-modal token ID may exceed vocab size
770 handle_oov_mm_token: bool = True,
771 ) -> torch.Tensor:
@@ -784,10 +784,10 @@ class GraniteSpeechForConditionalGeneration(
784 self,
785 input_ids: torch.Tensor,
786 positions: torch.Tensor,
787 - intermediate_tensors: Optional[IntermediateTensors] = None,
788 - inputs_embeds: Optional[torch.Tensor] = None,
787 + intermediate_tensors: IntermediateTensors | None = None,
788 + inputs_embeds: torch.Tensor | None = None,
789 **kwargs: object,
790 - ) -> Union[torch.Tensor, IntermediateTensors]:
790 + ) -> torch.Tensor | IntermediateTensors:
791 if intermediate_tensors is not None:
792 inputs_embeds = None
793
@@ -799,7 +799,7 @@ class GraniteSpeechForConditionalGeneration(
799 def compute_logits(
800 self,
801 hidden_states: torch.Tensor,
802 - ) -> Optional[torch.Tensor]:
802 + ) -> torch.Tensor | None:
803 return self.language_model.compute_logits(hidden_states)
804
805 def load_weights(
vllm/model_executor/models/granitemoe.py
+13 -13
@@ -26,7 +26,7 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Any, Optional
29 +from typing import Any
30
31 import torch
32 from torch import nn
@@ -79,9 +79,9 @@ class GraniteMoeMoE(nn.Module):
79 top_k: int,
80 hidden_size: int,
81 intermediate_size: int,
82 - params_dtype: Optional[torch.dtype] = None,
83 - quant_config: Optional[QuantizationConfig] = None,
84 - tp_size: Optional[int] = None,
82 + params_dtype: torch.dtype | None = None,
83 + quant_config: QuantizationConfig | None = None,
84 + tp_size: int | None = None,
85 is_sequence_parallel=False,
86 prefix: str = "",
87 ):
@@ -143,10 +143,10 @@ class GraniteMoeAttention(nn.Module):
143 num_kv_heads: int,
144 max_position: int = 4096 * 32,
145 rope_theta: float = 10000,
146 - rope_scaling: Optional[dict[str, Any]] = None,
147 - cache_config: Optional[CacheConfig] = None,
148 - quant_config: Optional[QuantizationConfig] = None,
149 - attention_multiplier: Optional[float] = None,
146 + rope_scaling: dict[str, Any] | None = None,
147 + cache_config: CacheConfig | None = None,
148 + quant_config: QuantizationConfig | None = None,
149 + attention_multiplier: float | None = None,
150 prefix: str = "",
151 ) -> None:
152 super().__init__()
@@ -330,8 +330,8 @@ class GraniteMoeModel(nn.Module):
330 self,
331 input_ids: torch.Tensor,
332 positions: torch.Tensor,
333 - intermediate_tensors: Optional[IntermediateTensors],
334 - inputs_embeds: Optional[torch.Tensor] = None,
333 + intermediate_tensors: IntermediateTensors | None,
334 + inputs_embeds: torch.Tensor | None = None,
335 ) -> torch.Tensor:
336 if get_pp_group().is_first_rank:
337 if inputs_embeds is not None:
@@ -557,15 +557,15 @@ class GraniteMoeForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
557 self,
558 input_ids: torch.Tensor,
559 positions: torch.Tensor,
560 - intermediate_tensors: Optional[IntermediateTensors] = None,
561 - inputs_embeds: Optional[torch.Tensor] = None,
560 + intermediate_tensors: IntermediateTensors | None = None,
561 + inputs_embeds: torch.Tensor | None = None,
562 ) -> torch.Tensor:
563 hidden_states = self.model(
564 input_ids, positions, intermediate_tensors, inputs_embeds
565 )
566 return hidden_states
567
568 - def compute_logits(self, hidden_states: torch.Tensor) -> Optional[torch.Tensor]:
568 + def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None:
569 logits = self.logits_processor(self.lm_head, hidden_states)
570 return logits
571
vllm/model_executor/models/granitemoehybrid.py
+16 -17
@@ -4,7 +4,6 @@
4
5 # Added by the IBM Team, 2025
6 from collections.abc import Iterable
7 -from typing import Optional
7
8 import torch
9 from torch import nn
@@ -50,9 +49,9 @@ class GraniteMoeHybridMambaDecoderLayer(nn.Module):
49 self,
50 config: GraniteMoeHybridConfig,
51 layer_idx: int,
53 - model_config: Optional[ModelConfig] = None,
54 - cache_config: Optional[CacheConfig] = None,
55 - quant_config: Optional[QuantizationConfig] = None,
52 + model_config: ModelConfig | None = None,
53 + cache_config: CacheConfig | None = None,
54 + quant_config: QuantizationConfig | None = None,
55 prefix: str = "",
56 ) -> None:
57 super().__init__()
@@ -105,7 +104,7 @@ class GraniteMoeHybridMambaDecoderLayer(nn.Module):
104 def forward(
105 self,
106 hidden_states: torch.Tensor,
108 - residual: Optional[torch.Tensor],
107 + residual: torch.Tensor | None,
108 **kwargs,
109 ):
110 residual = hidden_states
@@ -139,9 +138,9 @@ class GraniteMoeHybridAttentionDecoderLayer(nn.Module):
138 self,
139 config: GraniteMoeHybridConfig,
140 layer_idx: int,
142 - model_config: Optional[ModelConfig] = None,
143 - cache_config: Optional[CacheConfig] = None,
144 - quant_config: Optional[QuantizationConfig] = None,
141 + model_config: ModelConfig | None = None,
142 + cache_config: CacheConfig | None = None,
143 + quant_config: QuantizationConfig | None = None,
144 prefix: str = "",
145 ) -> None:
146 super().__init__()
@@ -183,7 +182,7 @@ class GraniteMoeHybridAttentionDecoderLayer(nn.Module):
182 self,
183 positions: torch.Tensor,
184 hidden_states: torch.Tensor,
186 - residual: Optional[torch.Tensor],
185 + residual: torch.Tensor | None,
186 ) -> torch.Tensor:
187 residual = hidden_states
188 hidden_states = self.input_layernorm(hidden_states)
@@ -218,9 +217,9 @@ class GraniteMoeHybridAttention(nn.Module):
217 def __init__(
218 self,
219 config: GraniteMoeHybridConfig,
221 - model_config: Optional[ModelConfig] = None,
222 - cache_config: Optional[CacheConfig] = None,
223 - quant_config: Optional[QuantizationConfig] = None,
220 + model_config: ModelConfig | None = None,
221 + cache_config: CacheConfig | None = None,
222 + quant_config: QuantizationConfig | None = None,
223 prefix: str = "",
224 ) -> None:
225 super().__init__()
@@ -374,8 +373,8 @@ class GraniteMoeHybridModel(nn.Module):
373 self,
374 input_ids: torch.Tensor,
375 positions: torch.Tensor,
377 - intermediate_tensors: Optional[IntermediateTensors] = None,
378 - inputs_embeds: Optional[torch.Tensor] = None,
376 + intermediate_tensors: IntermediateTensors | None = None,
377 + inputs_embeds: torch.Tensor | None = None,
378 ) -> torch.Tensor:
379 if get_pp_group().is_first_rank:
380 if inputs_embeds is not None:
@@ -614,8 +613,8 @@ class GraniteMoeHybridForCausalLM(
613 self,
614 input_ids: torch.Tensor,
615 positions: torch.Tensor,
617 - intermediate_tensors: Optional[IntermediateTensors] = None,
618 - inputs_embeds: Optional[torch.Tensor] = None,
616 + intermediate_tensors: IntermediateTensors | None = None,
617 + inputs_embeds: torch.Tensor | None = None,
618 **kwargs,
619 ):
620 hidden_states = self.model(
@@ -627,7 +626,7 @@ class GraniteMoeHybridForCausalLM(
626 def compute_logits(
627 self,
628 hidden_states: torch.Tensor,
630 - ) -> Optional[torch.Tensor]:
629 + ) -> torch.Tensor | None:
630 logits = self.logits_processor(self.lm_head, hidden_states)
631 return logits
632
vllm/model_executor/models/granitemoeshared.py
+8 -9
@@ -8,7 +8,6 @@ experts.
8
9 from collections.abc import Iterable
10 from itertools import islice
11 -from typing import Optional
11
12 import torch
13 from torch import nn
@@ -41,7 +40,7 @@ class GraniteMoeSharedMLP(nn.Module):
40 def __init__(
41 self,
42 config: GraniteMoeSharedConfig,
44 - quant_config: Optional[QuantizationConfig] = None,
43 + quant_config: QuantizationConfig | None = None,
44 prefix: str = "",
45 ):
46 super().__init__()
@@ -80,8 +79,8 @@ class GraniteMoeSharedDecoderLayer(nn.Module):
79 def __init__(
80 self,
81 config: GraniteMoeSharedConfig,
83 - cache_config: Optional[CacheConfig] = None,
84 - quant_config: Optional[QuantizationConfig] = None,
82 + cache_config: CacheConfig | None = None,
83 + quant_config: QuantizationConfig | None = None,
84 prefix: str = "",
85 ) -> None:
86 super().__init__()
@@ -198,8 +197,8 @@ class GraniteMoeSharedModel(nn.Module):
197 self,
198 input_ids: torch.Tensor,
199 positions: torch.Tensor,
201 - intermediate_tensors: Optional[IntermediateTensors],
202 - inputs_embeds: Optional[torch.Tensor] = None,
200 + intermediate_tensors: IntermediateTensors | None,
201 + inputs_embeds: torch.Tensor | None = None,
202 ) -> torch.Tensor:
203 if get_pp_group().is_first_rank:
204 if inputs_embeds is not None:
@@ -321,15 +320,15 @@ class GraniteMoeSharedForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
320 self,
321 input_ids: torch.Tensor,
322 positions: torch.Tensor,
324 - intermediate_tensors: Optional[IntermediateTensors] = None,
325 - inputs_embeds: Optional[torch.Tensor] = None,
323 + intermediate_tensors: IntermediateTensors | None = None,
324 + inputs_embeds: torch.Tensor | None = None,
325 ) -> torch.Tensor:
326 hidden_states = self.model(
327 input_ids, positions, intermediate_tensors, inputs_embeds
328 )
329 return hidden_states
330
332 - def compute_logits(self, hidden_states: torch.Tensor) -> Optional[torch.Tensor]:
331 + def compute_logits(self, hidden_states: torch.Tensor) -> torch.Tensor | None:
332 logits = self.logits_processor(self.lm_head, hidden_states)
333 return logits
334
vllm/model_executor/models/gritlm.py
+6 -7
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Set
4 -from typing import Optional, Union
4
5 import numpy as np
6 import torch
@@ -62,7 +61,7 @@ class GritLMMeanPool(nn.Module):
61 arr: np.ndarray,
62 target: np.ndarray,
63 start_idx: int = 0,
65 - end_idx: Optional[int] = None,
64 + end_idx: int | None = None,
65 ) -> int:
66 """
67 Find the first occurrence of `target` in `arr` starting from
@@ -152,8 +151,8 @@ class GritLMMeanPool(nn.Module):
151 def forward_one(
152 self,
153 hidden_states: torch.Tensor,
155 - prompt_len: Optional[torch.Tensor] = None,
156 - instr_len: Optional[torch.Tensor] = None,
154 + prompt_len: torch.Tensor | None = None,
155 + instr_len: torch.Tensor | None = None,
156 ) -> torch.Tensor:
157 assert prompt_len is None or prompt_len == hidden_states.shape[0], (
158 "partial prefill not supported with MEAN pooling"
@@ -166,7 +165,7 @@ class GritLMMeanPool(nn.Module):
165 hidden_states: torch.Tensor,
166 prompt_lens: torch.Tensor,
167 instr_lens: torch.Tensor,
169 - ) -> Union[list[torch.Tensor], torch.Tensor]:
168 + ) -> list[torch.Tensor] | torch.Tensor:
169 offset = 0
170 pooled_data = list[torch.Tensor]()
171
@@ -182,9 +181,9 @@ class GritLMMeanPool(nn.Module):
181
182 def forward(
183 self,
185 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
184 + hidden_states: torch.Tensor | list[torch.Tensor],
185 pooling_metadata: PoolingMetadata,
187 - ) -> Union[list[torch.Tensor], torch.Tensor]:
186 + ) -> list[torch.Tensor] | torch.Tensor:
187 prompt_lens = get_prompt_lens(hidden_states, pooling_metadata)
188 instr_lens = torch.tensor(
189 [
vllm/model_executor/models/grok1.py
+15 -16
@@ -25,7 +25,6 @@
25
26 from collections.abc import Iterable
27 from itertools import islice
28 -from typing import Optional, Union
28
29 import torch
30 import torch.nn.functional as F
@@ -86,9 +85,9 @@ class Grok1MoE(nn.Module):
85 top_k: int,
86 hidden_size: int,
87 intermediate_size: int,
89 - params_dtype: Optional[torch.dtype] = None,
90 - quant_config: Optional[QuantizationConfig] = None,
91 - tp_size: Optional[int] = None,
88 + params_dtype: torch.dtype | None = None,
89 + quant_config: QuantizationConfig | None = None,
90 + tp_size: int | None = None,
91 prefix: str = "",
92 ):
93 super().__init__()
@@ -137,8 +136,8 @@ class Grok1Attention(nn.Module):
136 num_kv_heads: int,
137 max_position: int = 4096 * 32,
138 rope_theta: float = 10000,
140 - cache_config: Optional[CacheConfig] = None,
141 - quant_config: Optional[QuantizationConfig] = None,
139 + cache_config: CacheConfig | None = None,
140 + quant_config: QuantizationConfig | None = None,
141 prefix: str = "",
142 config=None, # Added config parameter
143 ) -> None:
@@ -223,8 +222,8 @@ class Grok1DecoderLayer(nn.Module):
222 def __init__(
223 self,
224 config,
226 - cache_config: Optional[CacheConfig] = None,
227 - quant_config: Optional[QuantizationConfig] = None,
225 + cache_config: CacheConfig | None = None,
226 + quant_config: QuantizationConfig | None = None,
227 prefix: str = "",
228 ) -> None:
229 super().__init__()
@@ -273,7 +272,7 @@ class Grok1DecoderLayer(nn.Module):
272 self,
273 positions: torch.Tensor,
274 hidden_states: torch.Tensor,
276 - residual: Optional[torch.Tensor],
275 + residual: torch.Tensor | None,
276 ) -> tuple[torch.Tensor, torch.Tensor]:
277 # Self Attention
278 if residual is None:
@@ -351,9 +350,9 @@ class Grok1Model(nn.Module):
350 self,
351 input_ids: torch.Tensor,
352 positions: torch.Tensor,
354 - intermediate_tensors: Optional[IntermediateTensors],
355 - inputs_embeds: Optional[torch.Tensor] = None,
356 - ) -> Union[torch.Tensor, IntermediateTensors]:
353 + intermediate_tensors: IntermediateTensors | None,
354 + inputs_embeds: torch.Tensor | None = None,
355 + ) -> torch.Tensor | IntermediateTensors:
356 if get_pp_group().is_first_rank:
357 if inputs_embeds is not None:
358 hidden_states = inputs_embeds
@@ -544,9 +543,9 @@ class Grok1ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
543 self,
544 input_ids: torch.Tensor,
545 positions: torch.Tensor,
547 - intermediate_tensors: Optional[IntermediateTensors] = None,
548 - inputs_embeds: Optional[torch.Tensor] = None,
549 - ) -> Union[torch.Tensor, IntermediateTensors]:
546 + intermediate_tensors: IntermediateTensors | None = None,
547 + inputs_embeds: torch.Tensor | None = None,
548 + ) -> torch.Tensor | IntermediateTensors:
549 hidden_states = self.model(
550 input_ids, positions, intermediate_tensors, inputs_embeds
551 )
@@ -555,7 +554,7 @@ class Grok1ForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
554 def compute_logits(
555 self,
556 hidden_states: torch.Tensor,
558 - ) -> Optional[torch.Tensor]:
557 + ) -> torch.Tensor | None:
558 logits = self.logits_processor(self.lm_head, hidden_states)
559 return logits
560
vllm/model_executor/models/h2ovl.py
+26 -27
@@ -9,7 +9,6 @@
9 # Licensed under Apache 2.0 License [see LICENSE for details]
10 # --------------------------------------------------------
11 from collections.abc import Mapping, Sequence
12 -from typing import Optional, Union
12
13 import torch
14 from PIL import Image
@@ -67,7 +66,7 @@ def get_h2ovl_target_ratios(
66 min_num: int,
67 max_num: int,
68 *,
70 - prior_aspect_ratio: Optional[tuple[int, int]],
69 + prior_aspect_ratio: tuple[int, int] | None,
70 ) -> list[tuple[int, int]]:
71 target_ratios = get_internvl_target_ratios(min_num, max_num)
72
@@ -170,7 +169,7 @@ def _preprocess_image(
169 min_num: int,
170 max_num: int,
171 use_thumbnail: bool,
173 - prior_aspect_ratio: Optional[tuple[int, int]],
172 + prior_aspect_ratio: tuple[int, int] | None,
173 ) -> tuple[torch.Tensor, tuple[int, int]]:
174 target_ratios = get_h2ovl_target_ratios(
175 min_num,
@@ -244,10 +243,10 @@ class H2OVLProcessor(BaseInternVLProcessor):
243 config: PretrainedConfig,
244 tokenizer: AnyTokenizer,
245 *,
247 - min_dynamic_patch: Optional[int] = None,
248 - max_dynamic_patch: Optional[int] = None,
249 - dynamic_image_size: Optional[bool] = None,
250 - use_msac: Optional[bool] = None,
246 + min_dynamic_patch: int | None = None,
247 + max_dynamic_patch: int | None = None,
248 + dynamic_image_size: bool | None = None,
249 + use_msac: bool | None = None,
250 ) -> None:
251 super().__init__(
252 config,
@@ -270,7 +269,7 @@ class H2OVLProcessor(BaseInternVLProcessor):
269 def get_image_repl(
270 self,
271 feature_size: int,
273 - num_patches: Optional[int],
272 + num_patches: int | None,
273 ) -> PromptUpdateDetails[str]:
274 repl_features = IMG_CONTEXT * feature_size
275 repl_full = IMG_START + repl_features + IMG_END
@@ -280,10 +279,10 @@ class H2OVLProcessor(BaseInternVLProcessor):
279 def resolve_min_max_num(
280 self,
281 *,
283 - min_dynamic_patch: Optional[int] = None,
284 - max_dynamic_patch: Optional[int] = None,
285 - dynamic_image_size: Optional[bool] = None,
286 - use_thumbnail: Optional[bool] = None,
282 + min_dynamic_patch: int | None = None,
283 + max_dynamic_patch: int | None = None,
284 + dynamic_image_size: bool | None = None,
285 + use_thumbnail: bool | None = None,
286 ) -> tuple[int, int]:
287 min_dynamic_patch = (
288 self.min_dynamic_patch if min_dynamic_patch is None else min_dynamic_patch
@@ -308,12 +307,12 @@ class H2OVLProcessor(BaseInternVLProcessor):
307 def resolve_target_ratios(
308 self,
309 *,
311 - min_dynamic_patch: Optional[int] = None,
312 - max_dynamic_patch: Optional[int] = None,
313 - dynamic_image_size: Optional[bool] = None,
314 - use_thumbnail: Optional[bool] = None,
315 - prior_aspect_ratio: Optional[tuple[int, int]] = None,
316 - override_min_num: Optional[int] = None,
310 + min_dynamic_patch: int | None = None,
311 + max_dynamic_patch: int | None = None,
312 + dynamic_image_size: bool | None = None,
313 + use_thumbnail: bool | None = None,
314 + prior_aspect_ratio: tuple[int, int] | None = None,
315 + override_min_num: int | None = None,
316 ) -> list[tuple[int, int]]:
317 min_num, max_num = self.resolve_min_max_num(
318 min_dynamic_patch=min_dynamic_patch,
@@ -335,7 +334,7 @@ class H2OVLProcessor(BaseInternVLProcessor):
334 *,
335 image_width: int,
336 image_height: int,
338 - use_msac: Optional[bool] = None,
337 + use_msac: bool | None = None,
338 ) -> int:
339 use_msac = self.use_msac if use_msac is None else use_msac
340
@@ -385,9 +384,9 @@ class H2OVLProcessor(BaseInternVLProcessor):
384 def _images_to_pixel_values_lst(
385 self,
386 images: list[Image.Image],
388 - min_dynamic_patch: Optional[int] = None,
389 - max_dynamic_patch: Optional[int] = None,
390 - dynamic_image_size: Optional[bool] = None,
387 + min_dynamic_patch: int | None = None,
388 + max_dynamic_patch: int | None = None,
389 + dynamic_image_size: bool | None = None,
390 ) -> list[torch.Tensor]:
391 use_msac = self.use_msac if len(images) == 1 else False
392
@@ -425,8 +424,8 @@ class H2OVLProcessingInfo(BaseInternVLProcessingInfo):
424 *,
425 image_width: int,
426 image_height: int,
428 - processor: Optional[H2OVLProcessor],
429 - use_msac: Optional[bool] = None,
427 + processor: H2OVLProcessor | None,
428 + use_msac: bool | None = None,
429 ) -> int:
430 if processor is None:
431 processor = self.get_hf_processor()
@@ -493,11 +492,11 @@ class H2OVLMultiModalProcessor(BaseInternVLMultiModalProcessor[H2OVLProcessingIn
492
493 def _cached_apply_hf_processor(
494 self,
496 - prompt: Union[str, list[int]],
495 + prompt: str | list[int],
496 mm_data_items: MultiModalDataItems,
497 hf_processor_mm_kwargs: Mapping[str, object],
498 tokenization_kwargs: Mapping[str, object],
500 - mm_uuids: Optional[MultiModalUUIDDict] = None,
499 + mm_uuids: MultiModalUUIDDict | None = None,
500 ) -> tuple[list[int], MultiModalProcessingInfo, bool]:
501 # The processor logic is different for len(images) <= 1 vs > 1
502 # Since the processing cache assumes that the processor output is
@@ -530,7 +529,7 @@ class H2OVLChatModel(InternVLChatModel):
529 def _init_vision_model(
530 self,
531 config: PretrainedConfig,
533 - quant_config: Optional[QuantizationConfig],
532 + quant_config: QuantizationConfig | None,
533 *,
534 is_mono: bool,
535 prefix: str,
vllm/model_executor/models/hunyuan_v1.py
+23 -23
@@ -27,7 +27,7 @@
27 import typing
28 from collections.abc import Callable, Iterable
29 from itertools import islice
30 -from typing import Any, Optional, Union
30 +from typing import Any
31
32 import regex as re
33 import torch
@@ -102,7 +102,7 @@ class HunYuanMLP(nn.Module):
102 hidden_size: int,
103 intermediate_size: int,
104 hidden_act: str,
105 - quant_config: Optional[QuantizationConfig] = None,
105 + quant_config: QuantizationConfig | None = None,
106 bias: bool = False,
107 prefix: str = "",
108 reduce_results: bool = True,
@@ -144,11 +144,11 @@ class HunYuanAttention(nn.Module):
144 num_heads: int,
145 num_kv_heads: int,
146 rope_theta: float = 10000,
147 - rope_scaling: Optional[dict[str, Any]] = None,
147 + rope_scaling: dict[str, Any] | None = None,
148 max_position_embeddings: int = 8192,
149 - quant_config: Optional[QuantizationConfig] = None,
149 + quant_config: QuantizationConfig | None = None,
150 bias: bool = False,
151 - cache_config: Optional[CacheConfig] = None,
151 + cache_config: CacheConfig | None = None,
152 prefix: str = "",
153 layer_id: int = -1,
154 ) -> None:
@@ -227,7 +227,7 @@ class HunYuanAttention(nn.Module):
227 self,
228 positions: torch.Tensor,
229 hidden_states: torch.Tensor,
230 - kv_states: Optional[tuple[torch.Tensor]] = None,
230 + kv_states: tuple[torch.Tensor] | None = None,
231 ) -> torch.Tensor:
232 qkv, _ = self.qkv_proj(hidden_states)
233 q, k, v = qkv.split([self.q_size, self.kv_size, self.kv_size], dim=-1)
@@ -256,11 +256,11 @@ class HunYuanCrossAttention(nn.Module):
256 num_heads: int,
257 num_kv_heads: int,
258 rope_theta: float = 10000,
259 - rope_scaling: Optional[dict[str, Any]] = None,
259 + rope_scaling: dict[str, Any] | None = None,
260 max_position_embeddings: int = 8192,
261 - quant_config: Optional[QuantizationConfig] = None,
261 + quant_config: QuantizationConfig | None = None,
262 bias: bool = False,
263 - cache_config: Optional[CacheConfig] = None,
263 + cache_config: CacheConfig | None = None,
264 prefix: str = "",
265 layer_id: int = -1,
266 ) -> None:
@@ -338,7 +338,7 @@ class HunYuanCrossAttention(nn.Module):
338 self,
339 positions: torch.Tensor,
340 hidden_states: torch.Tensor,
341 - kv_states: Optional[tuple[torch.Tensor]] = None,
341 + kv_states: tuple[torch.Tensor] | None = None,
342 ) -> torch.Tensor:
343 assert kv_states is not None
344 ori_k, v = kv_states # use last layer kv,
@@ -365,7 +365,7 @@ class HunYuanSparseMoeBlock(nn.Module):
365 def __init__(
366 self,
367 config: PretrainedConfig,
368 - quant_config: Optional[QuantizationConfig] = None,
368 + quant_config: QuantizationConfig | None = None,
369 layer_id: int = -1,
370 prefix: str = "",
371 enable_eplb: bool = False,
@@ -480,8 +480,8 @@ class HunYuanDecoderLayer(nn.Module):
480 def __init__(
481 self,
482 config: PretrainedConfig,
483 - cache_config: Optional[CacheConfig] = None,
484 - quant_config: Optional[QuantizationConfig] = None,
483 + cache_config: CacheConfig | None = None,
484 + quant_config: QuantizationConfig | None = None,
485 prefix: str = "",
486 layer_id: int = -1,
487 enable_eplb: bool = False,
@@ -577,8 +577,8 @@ class HunYuanDecoderLayer(nn.Module):
577 self,
578 positions: torch.Tensor,
579 hidden_states: torch.Tensor,
580 - residual: Optional[torch.Tensor],
581 - kv_states: Optional[tuple[torch.Tensor]] = None,
580 + residual: torch.Tensor | None,
581 + kv_states: tuple[torch.Tensor] | None = None,
582 ) -> tuple[torch.Tensor, torch.Tensor]:
583 # Self Attention
584 if residual is None:
@@ -654,11 +654,11 @@ class HunYuanModel(nn.Module):
654
655 def forward(
656 self,
657 - input_ids: Optional[torch.Tensor],
657 + input_ids: torch.Tensor | None,
658 positions: torch.Tensor,
659 - intermediate_tensors: Optional[IntermediateTensors],
660 - inputs_embeds: Optional[torch.Tensor] = None,
661 - ) -> Union[torch.Tensor, IntermediateTensors]:
659 + intermediate_tensors: IntermediateTensors | None,
660 + inputs_embeds: torch.Tensor | None = None,
661 + ) -> torch.Tensor | IntermediateTensors:
662 if get_pp_group().is_first_rank:
663 if inputs_embeds is not None:
664 hidden_states = inputs_embeds
@@ -960,9 +960,9 @@ class HunyuanV1ModelBase(nn.Module, SupportsLoRA, SupportsPP):
960 self,
961 input_ids: torch.Tensor,
962 positions: torch.Tensor,
963 - intermediate_tensors: Optional[IntermediateTensors] = None,
964 - inputs_embeds: Optional[torch.Tensor] = None,
965 - ) -> Union[torch.Tensor, IntermediateTensors]:
963 + intermediate_tensors: IntermediateTensors | None = None,
964 + inputs_embeds: torch.Tensor | None = None,
965 + ) -> torch.Tensor | IntermediateTensors:
966 model_output = self.model(
967 input_ids, positions, intermediate_tensors, inputs_embeds
968 )
@@ -971,7 +971,7 @@ class HunyuanV1ModelBase(nn.Module, SupportsLoRA, SupportsPP):
971 def compute_logits(
972 self,
973 hidden_states: torch.Tensor,
974 - ) -> Optional[torch.Tensor]:
974 + ) -> torch.Tensor | None:
975 logits = self.logits_processor(self.lm_head, hidden_states)
976 return logits
977
vllm/model_executor/models/hyperclovax_vision.py
+25 -25
@@ -6,7 +6,7 @@ from collections import defaultdict
6 from collections.abc import Iterable, Mapping, Sequence
7 from functools import partial
8 from itertools import accumulate
9 -from typing import Annotated, Any, Literal, Optional, Union
9 +from typing import Annotated, Any, Literal
10
11 import numpy as np
12 import torch
@@ -115,13 +115,13 @@ class HCXVisionProcessingInfo(BaseProcessingInfo):
115 def get_vision_encoder_info(self):
116 return get_vision_encoder_info(self.get_hf_config())
117
118 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
118 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
119 return {"image": None, "video": None}
120
121 def get_num_image_tokens(
122 self,
123 *,
124 - vision_query_length: Union[int, list[int]],
124 + vision_query_length: int | list[int],
125 ) -> int:
126 if isinstance(vision_query_length, int):
127 return vision_query_length
@@ -131,7 +131,7 @@ class HCXVisionProcessingInfo(BaseProcessingInfo):
131 def get_num_video_tokens(
132 self,
133 *,
134 - vision_query_length: Union[int, list[int]],
134 + vision_query_length: int | list[int],
135 ) -> int:
136 if isinstance(vision_query_length, int):
137 return vision_query_length
@@ -166,7 +166,7 @@ class HCXVisionDummyInputsBuilder(BaseDummyInputsBuilder[HCXVisionProcessingInfo
166 self,
167 seq_len: int,
168 mm_counts: Mapping[str, int],
169 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
169 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
170 ) -> MultiModalDataDict:
171 num_images = mm_counts.get("image", 0)
172 num_videos = mm_counts.get("video", 0)
@@ -346,7 +346,7 @@ def _build_hcxvision_hf_processor(
346 info: HCXVisionProcessingInfo,
347 dummy_inputs: BaseDummyInputsBuilder[HCXVisionProcessingInfo],
348 *,
349 - cache: Optional[BaseMultiModalProcessorCache] = None,
349 + cache: BaseMultiModalProcessorCache | None = None,
350 ) -> BaseMultiModalProcessor:
351 if isinstance(info, HCXVisionProcessingInfo):
352 return HCXVisionMultiModalProcessor(
@@ -360,12 +360,12 @@ def _build_hcxvision_hf_processor(
360
361 def init_vision_tower_for_hcxvision(
362 vision_config,
363 - quant_config: Optional[QuantizationConfig],
363 + quant_config: QuantizationConfig | None,
364 *,
365 - use_nth_layer: Optional[int] = None,
366 - require_post_norm: Optional[bool] = None,
365 + use_nth_layer: int | None = None,
366 + require_post_norm: bool | None = None,
367 prefix: str = "",
368 -) -> Union[CLIPVisionModel, SiglipVisionModel]:
368 +) -> CLIPVisionModel | SiglipVisionModel:
369 num_hidden_layers = vision_config.num_hidden_layers
370 if not isinstance(use_nth_layer, int):
371 pass
@@ -473,8 +473,8 @@ class HCXVisionCAbstractor(nn.Module):
473 def forward(
474 self,
475 x: torch.Tensor,
476 - num_queries_vis_abstractors: Optional[list[list[int]]] = None,
477 - num_grids: Optional[list[int]] = None,
476 + num_queries_vis_abstractors: list[list[int]] | None = None,
477 + num_grids: list[int] | None = None,
478 ) -> torch.Tensor:
479 if self.prenorm is not None:
480 x = self.prenorm(x)
@@ -493,8 +493,8 @@ class HCXVisionCAbstractor(nn.Module):
493 def _forward(
494 self,
495 x: torch.Tensor,
496 - num_queries_vis_abstractors: Optional[list[list[int]]] = None,
497 - num_grids: Optional[list[int]] = None,
496 + num_queries_vis_abstractors: list[list[int]] | None = None,
497 + num_grids: list[int] | None = None,
498 ) -> torch.Tensor:
499 # x: [B, L, dim]
500 B, L, dim = x.shape
@@ -515,8 +515,8 @@ class HCXVisionCAbstractor(nn.Module):
515 def _forward_adaptive_num_query(
516 self,
517 x: torch.Tensor,
518 - num_queries_vis_abstractors: Optional[list[list[int]]] = None,
519 - num_grids: Optional[list[int]] = None,
518 + num_queries_vis_abstractors: list[list[int]] | None = None,
519 + num_grids: list[int] | None = None,
520 ) -> list[torch.Tensor]:
521 # self.net is consisted by 3 layers (s1, sampler, s2)
522 assert len(self.net) == 3
@@ -604,7 +604,7 @@ class HCXVisionForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
604 *,
605 vllm_config: VllmConfig,
606 prefix: str = "",
607 - **kwargs: Optional[Any],
607 + **kwargs: Any | None,
608 ) -> None:
609 super().__init__()
610
@@ -662,7 +662,7 @@ class HCXVisionForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
662 # self.reduction = self._init_reduction_type(use_sum_loss)
663
664 @classmethod
665 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
665 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
666 if modality.startswith("image"):
667 return IMAGE_TOKEN
668 if modality.startswith("video"):
@@ -673,7 +673,7 @@ class HCXVisionForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
673 def _parse_and_validate_image_input(
674 self,
675 **kwargs: object,
676 - ) -> Optional[HCXVisionImageInputs]:
676 + ) -> HCXVisionImageInputs | None:
677 pixel_values_images = kwargs.pop("pixel_values_images", None)
678
679 if pixel_values_images is None:
@@ -689,7 +689,7 @@ class HCXVisionForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
689 def _parse_and_validate_video_input(
690 self,
691 **kwargs: object,
692 - ) -> Optional[HCXVisionVideoInputs]:
692 + ) -> HCXVisionVideoInputs | None:
693 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
694
695 if pixel_values_videos is None:
@@ -762,10 +762,10 @@ class HCXVisionForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
762 self,
763 input_ids: torch.Tensor,
764 positions: torch.Tensor,
765 - intermediate_tensors: Optional[IntermediateTensors] = None,
766 - inputs_embeds: Optional[torch.Tensor] = None,
765 + intermediate_tensors: IntermediateTensors | None = None,
766 + inputs_embeds: torch.Tensor | None = None,
767 **kwargs: object,
768 - ) -> Union[torch.Tensor, IntermediateTensors]:
768 + ) -> torch.Tensor | IntermediateTensors:
769 if intermediate_tensors is not None:
770 inputs_embeds = None
771
@@ -946,7 +946,7 @@ class HCXVisionForCausalLM(nn.Module, SupportsMultiModal, SupportsPP):
946 def compute_logits(
947 self,
948 hidden_states: torch.Tensor,
949 - ) -> Optional[torch.Tensor]:
949 + ) -> torch.Tensor | None:
950 return self.language_model.compute_logits(hidden_states)
951
952 def load_weights(
@@ -1062,7 +1062,7 @@ def select_best_resolution(original_size: tuple, possible_resolutions: list) ->
1062
1063 def get_anyres_image_grid_shape(
1064 image_size: tuple[int, int],
1065 - grid_pinpoints: Union[str, list[tuple[int, int]]],
1065 + grid_pinpoints: str | list[tuple[int, int]],
1066 patch_size: int,
1067 ) -> tuple[int, int]:
1068 possible_resolutions = (
vllm/model_executor/models/idefics2_vision_model.py
+10 -11
@@ -19,7 +19,6 @@
19 """PyTorch Idefics2 model."""
20
21 from collections.abc import Iterable
22 -from typing import Optional
22
23 import torch
24 from torch import nn
@@ -77,7 +76,7 @@ class Idefics2VisionEmbeddings(nn.Module):
76 self,
77 pixel_values: torch.FloatTensor,
78 patch_attention_mask: torch.BoolTensor,
80 - tgt_sizes: Optional[torch.IntTensor] = None,
79 + tgt_sizes: torch.IntTensor | None = None,
80 ) -> torch.Tensor:
81 batch_size, _, max_im_h, max_im_w = pixel_values.shape
82 target_dtype = self.patch_embedding.weight.dtype
@@ -124,7 +123,7 @@ class Idefics2VisionAttention(nn.Module):
123 def __init__(
124 self,
125 config: Idefics2VisionConfig,
127 - quant_config: Optional[QuantizationConfig] = None,
126 + quant_config: QuantizationConfig | None = None,
127 prefix: str = "",
128 use_data_parallel: bool = False,
129 ) -> None:
@@ -185,7 +184,7 @@ class Idefics2VisionMLP(nn.Module):
184 def __init__(
185 self,
186 config: Idefics2VisionConfig,
188 - quant_config: Optional[QuantizationConfig] = None,
187 + quant_config: QuantizationConfig | None = None,
188 prefix: str = "",
189 use_data_parallel: bool = False,
190 ) -> None:
@@ -220,7 +219,7 @@ class Idefics2EncoderLayer(nn.Module):
219 def __init__(
220 self,
221 config: Idefics2Config,
223 - quant_config: Optional[QuantizationConfig] = None,
222 + quant_config: QuantizationConfig | None = None,
223 prefix: str = "",
224 use_data_parallel: bool = False,
225 ) -> None:
@@ -275,9 +274,9 @@ class Idefics2Encoder(nn.Module):
274 def __init__(
275 self,
276 config: Idefics2Config,
278 - quant_config: Optional[QuantizationConfig] = None,
277 + quant_config: QuantizationConfig | None = None,
278 *,
280 - num_hidden_layers_override: Optional[int] = None,
279 + num_hidden_layers_override: int | None = None,
280 prefix: str = "",
281 use_data_parallel: bool = False,
282 ) -> None:
@@ -326,9 +325,9 @@ class Idefics2VisionTransformer(nn.Module):
325 def __init__(
326 self,
327 config: Idefics2VisionConfig,
329 - quant_config: Optional[QuantizationConfig] = None,
328 + quant_config: QuantizationConfig | None = None,
329 *,
331 - num_hidden_layers_override: Optional[int] = None,
330 + num_hidden_layers_override: int | None = None,
331 require_post_norm: bool = True,
332 prefix: str = "",
333 use_data_parallel: bool = False,
@@ -370,8 +369,8 @@ class Idefics2VisionTransformer(nn.Module):
369 def forward(
370 self,
371 pixel_values,
373 - patch_attention_mask: Optional[torch.BoolTensor] = None,
374 - tgt_sizes: Optional[torch.IntTensor] = None,
372 + patch_attention_mask: torch.BoolTensor | None = None,
373 + tgt_sizes: torch.IntTensor | None = None,
374 ) -> torch.Tensor:
375 hidden_states = self.embeddings(
376 pixel_values=pixel_values,
vllm/model_executor/models/idefics3.py
+22 -24
@@ -18,7 +18,7 @@
18
19 import math
20 from collections.abc import Iterable, Mapping, Sequence
21 -from typing import Annotated, Literal, Optional, Union
21 +from typing import Annotated, Literal, TypeAlias
22
23 import torch
24 from torch import nn
@@ -91,14 +91,14 @@ class Idefics3ImageEmbeddingInputs(TensorSchema):
91 data: Annotated[torch.Tensor, TensorShape("bn", "f", "h")]
92
93
94 -ImageInputs = Union[Idefics3ImagePixelInputs, Idefics3ImageEmbeddingInputs]
94 +ImageInputs: TypeAlias = Idefics3ImagePixelInputs | Idefics3ImageEmbeddingInputs
95
96
97 class Idefics3ProcessingInfo(BaseProcessingInfo):
98 def get_hf_processor(self, **kwargs: object) -> Idefics3Processor:
99 return self.ctx.get_hf_processor(Idefics3Processor, **kwargs)
100
101 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
101 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
102 return {"image": None}
103
104 def _resize_output_size(
@@ -106,9 +106,9 @@ class Idefics3ProcessingInfo(BaseProcessingInfo):
106 *,
107 height: int,
108 width: int,
109 - max_len: Optional[int] = None,
109 + max_len: int | None = None,
110 min_len: int = 1,
111 - max_size: Optional[int] = None,
111 + max_size: int | None = None,
112 ) -> tuple[int, int]:
113 # Set default value for max_len if not provided
114 max_len = max(height, width) if max_len is None else max_len
@@ -165,7 +165,7 @@ class Idefics3ProcessingInfo(BaseProcessingInfo):
165 *,
166 image_width: int,
167 image_height: int,
168 - processor: Optional[Idefics3Processor],
168 + processor: Idefics3Processor | None,
169 ) -> tuple[int, int]:
170 if processor is None:
171 processor = self.get_hf_processor()
@@ -197,7 +197,7 @@ class Idefics3ProcessingInfo(BaseProcessingInfo):
197 *,
198 image_width: int,
199 image_height: int,
200 - processor: Optional[Idefics3Processor],
200 + processor: Idefics3Processor | None,
201 ) -> int:
202 grid_w, grid_h = self._get_image_feature_grid_size(
203 image_width=image_width,
@@ -208,7 +208,7 @@ class Idefics3ProcessingInfo(BaseProcessingInfo):
208 return grid_w * grid_h + 1
209
210 def _get_image_token(
211 - self, processor: Optional[Idefics3Processor]
211 + self, processor: Idefics3Processor | None
212 ) -> tuple[str, str, str]:
213 if processor is None:
214 processor = self.get_hf_processor()
@@ -223,7 +223,7 @@ class Idefics3ProcessingInfo(BaseProcessingInfo):
223 *,
224 image_width: int,
225 image_height: int,
226 - processor: Optional[Idefics3Processor],
226 + processor: Idefics3Processor | None,
227 ) -> str:
228 if processor is None:
229 processor = self.get_hf_processor()
@@ -269,7 +269,7 @@ class Idefics3ProcessingInfo(BaseProcessingInfo):
269 *,
270 image_width: int,
271 image_height: int,
272 - processor: Optional[Idefics3Processor],
272 + processor: Idefics3Processor | None,
273 ) -> int:
274 if processor is None:
275 processor = self.get_hf_processor()
@@ -305,7 +305,7 @@ class Idefics3DummyInputsBuilder(BaseDummyInputsBuilder[Idefics3ProcessingInfo])
305 self,
306 seq_len: int,
307 mm_counts: Mapping[str, int],
308 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
308 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
309 ) -> MultiModalDataDict:
310 num_images = mm_counts.get("image", 0)
311 hf_processor = self.info.get_hf_processor()
@@ -425,7 +425,7 @@ class Idefics3SimpleMLP(nn.Module):
425 def __init__(
426 self,
427 config: Idefics3Config,
428 - quant_config: Optional[QuantizationConfig] = None,
428 + quant_config: QuantizationConfig | None = None,
429 prefix: str = "",
430 ):
431 super().__init__()
@@ -448,7 +448,7 @@ class Idefics3Connector(nn.Module):
448 def __init__(
449 self,
450 config: Idefics3Config,
451 - quant_config: Optional[QuantizationConfig] = None,
451 + quant_config: QuantizationConfig | None = None,
452 prefix: str = "",
453 ):
454 super().__init__()
@@ -557,9 +557,9 @@ class Idefics3Model(nn.Module):
557 self,
558 input_ids: torch.Tensor,
559 positions: torch.Tensor,
560 - intermediate_tensors: Optional[IntermediateTensors] = None,
561 - inputs_embeds: Optional[torch.Tensor] = None,
562 - ) -> Union[torch.Tensor, IntermediateTensors]:
560 + intermediate_tensors: IntermediateTensors | None = None,
561 + inputs_embeds: torch.Tensor | None = None,
562 + ) -> torch.Tensor | IntermediateTensors:
563 hidden_states = self.text_model(
564 input_ids,
565 positions,
@@ -590,7 +590,7 @@ class Idefics3ForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsLo
590 }
591
592 @classmethod
593 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
593 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
594 if modality.startswith("image"):
595 return "<image>"
596
@@ -621,9 +621,7 @@ class Idefics3ForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsLo
621 self.lm_head.weight = self.model.text_model.embed_tokens.weight
622 self.logits_processor = LogitsProcessor(config.text_config.vocab_size)
623
624 - def _parse_and_validate_image_input(
625 - self, **kwargs: object
626 - ) -> Optional[ImageInputs]:
624 + def _parse_and_validate_image_input(self, **kwargs: object) -> ImageInputs | None:
625 pixel_values = kwargs.pop("pixel_values", None)
626 image_embeds = kwargs.pop("image_embeds", None)
627
@@ -663,7 +661,7 @@ class Idefics3ForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsLo
661 def _process_image_input(
662 self,
663 image_input: ImageInputs,
666 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
664 + ) -> torch.Tensor | list[torch.Tensor]:
665 if image_input["type"] == "image_embeds":
666 return image_input["data"]
667
@@ -687,10 +685,10 @@ class Idefics3ForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsLo
685 self,
686 input_ids: torch.Tensor,
687 positions: torch.Tensor,
690 - intermediate_tensors: Optional[IntermediateTensors] = None,
691 - inputs_embeds: Optional[torch.Tensor] = None,
688 + intermediate_tensors: IntermediateTensors | None = None,
689 + inputs_embeds: torch.Tensor | None = None,
690 **kwargs: object,
693 - ) -> Union[torch.Tensor, IntermediateTensors]:
691 + ) -> torch.Tensor | IntermediateTensors:
692 if intermediate_tensors is not None:
693 inputs_embeds = None
694
vllm/model_executor/models/interfaces.py
+67 -65
@@ -1,15 +1,13 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from collections.abc import Iterable, Mapping, MutableSequence
4 +from collections.abc import Callable, Iterable, Mapping, MutableSequence
5 from typing import (
6 TYPE_CHECKING,
7 - Callable,
7 ClassVar,
8 Literal,
10 - Optional,
9 Protocol,
12 - Union,
10 + TypeAlias,
11 overload,
12 runtime_checkable,
13 )
@@ -34,10 +32,14 @@ if TYPE_CHECKING:
32 from vllm.config import VllmConfig
33 from vllm.model_executor.models.utils import WeightsMapper
34 from vllm.sequence import IntermediateTensors
35 +else:
36 + VllmConfig = object
37 + WeightsMapper = object
38 + IntermediateTensors = object
39
40 logger = init_logger(__name__)
41
40 -MultiModalEmbeddings = Union[list[Tensor], Tensor, tuple[Tensor, ...]]
42 +MultiModalEmbeddings: TypeAlias = list[Tensor] | Tensor | tuple[Tensor, ...]
43 """
44 The output embeddings must be one of the following formats:
45
@@ -79,7 +81,7 @@ class SupportsMultiModal(Protocol):
81 """
82
83 @classmethod
82 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
84 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
85 """
86 Get the placeholder text for the `i`th `modality` item in the prompt.
87 """
@@ -127,7 +129,7 @@ class SupportsMultiModal(Protocol):
129 input_ids: Tensor,
130 get_input_embeddings: Callable[[Tensor], Tensor],
131 *,
130 - is_multimodal: Optional[Tensor],
132 + is_multimodal: Tensor | None,
133 handle_oov_mm_token: bool,
134 ) -> Tensor:
135 if handle_oov_mm_token and is_multimodal is not None:
@@ -145,9 +147,9 @@ class SupportsMultiModal(Protocol):
147 def get_input_embeddings(
148 self,
149 input_ids: Tensor,
148 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
150 + multimodal_embeddings: MultiModalEmbeddings | None = None,
151 *,
150 - is_multimodal: Optional[Tensor] = None,
152 + is_multimodal: Tensor | None = None,
153 handle_oov_mm_token: bool = False,
154 ) -> Tensor:
155 """
@@ -236,16 +238,16 @@ def supports_multimodal(model: object) -> TypeIs[SupportsMultiModal]: ...
238
239
240 def supports_multimodal(
239 - model: Union[type[object], object],
240 -) -> Union[TypeIs[type[SupportsMultiModal]], TypeIs[SupportsMultiModal]]:
241 + model: type[object] | object,
242 +) -> TypeIs[type[SupportsMultiModal]] | TypeIs[SupportsMultiModal]:
243 return getattr(model, "supports_multimodal", False)
244
245
244 -def supports_multimodal_raw_input_only(model: Union[type[object], object]) -> bool:
246 +def supports_multimodal_raw_input_only(model: type[object] | object) -> bool:
247 return getattr(model, "supports_multimodal_raw_input_only", False)
248
249
248 -def supports_multimodal_encoder_tp_data(model: Union[type[object], object]) -> bool:
250 +def supports_multimodal_encoder_tp_data(model: type[object] | object) -> bool:
251 return getattr(model, "supports_encoder_tp_data", False)
252
253
@@ -260,8 +262,8 @@ def supports_multimodal_pruning(model: object) -> TypeIs[SupportsMultiModalPruni
262
263
264 def supports_multimodal_pruning(
263 - model: Union[type[object], object],
264 -) -> Union[TypeIs[type[SupportsMultiModalPruning]], TypeIs[SupportsMultiModalPruning]]:
265 + model: type[object] | object,
266 +) -> TypeIs[type[SupportsMultiModalPruning]] | TypeIs[SupportsMultiModalPruning]:
267 return getattr(model, "supports_multimodal_pruning", False)
268
269
@@ -279,7 +281,7 @@ class SupportsScoreTemplate(Protocol):
281 """
282
283 @classmethod
282 - def get_score_template(cls, query: str, document: str) -> Optional[str]:
284 + def get_score_template(cls, query: str, document: str) -> str | None:
285 """
286 Generate a full prompt by populating the score template with query and document content.
287 """ # noqa: E501
@@ -304,8 +306,8 @@ def supports_score_template(model: object) -> TypeIs[SupportsScoreTemplate]: ...
306
307
308 def supports_score_template(
307 - model: Union[type[object], object],
308 -) -> Union[TypeIs[type[SupportsScoreTemplate]], TypeIs[SupportsScoreTemplate]]:
309 + model: type[object] | object,
310 +) -> TypeIs[type[SupportsScoreTemplate]] | TypeIs[SupportsScoreTemplate]:
311 return getattr(model, "supports_score_template", False)
312
313
@@ -348,8 +350,8 @@ def supports_lora(model: object) -> TypeIs[SupportsLoRA]: ...
350
351
352 def supports_lora(
351 - model: Union[type[object], object],
352 -) -> Union[TypeIs[type[SupportsLoRA]], TypeIs[SupportsLoRA]]:
353 + model: type[object] | object,
354 +) -> TypeIs[type[SupportsLoRA]] | TypeIs[SupportsLoRA]:
355 result = _supports_lora(model)
356
357 if not result:
@@ -379,7 +381,7 @@ def supports_lora(
381 return result
382
383
382 -def _supports_lora(model: Union[type[object], object]) -> bool:
384 +def _supports_lora(model: type[object] | object) -> bool:
385 if isinstance(model, type):
386 return isinstance(model, _SupportsLoRAType)
387
@@ -404,15 +406,15 @@ class SupportsPP(Protocol):
406 batch_size: int,
407 dtype: torch.dtype,
408 device: torch.device,
407 - ) -> "IntermediateTensors":
409 + ) -> IntermediateTensors:
410 """Called when PP rank > 0 for profiling purposes."""
411 ...
412
413 def forward(
414 self,
415 *,
414 - intermediate_tensors: Optional["IntermediateTensors"],
415 - ) -> Union[Tensor, "IntermediateTensors"]:
416 + intermediate_tensors: IntermediateTensors | None,
417 + ) -> IntermediateTensors | None:
418 """
419 Accept [`IntermediateTensors`][vllm.sequence.IntermediateTensors] when
420 PP rank > 0.
@@ -434,13 +436,13 @@ class _SupportsPPType(Protocol):
436 batch_size: int,
437 dtype: torch.dtype,
438 device: torch.device,
437 - ) -> "IntermediateTensors": ...
439 + ) -> IntermediateTensors: ...
440
441 def forward(
442 self,
443 *,
442 - intermediate_tensors: Optional["IntermediateTensors"],
443 - ) -> Union[Tensor, "IntermediateTensors"]: ...
444 + intermediate_tensors: IntermediateTensors | None,
445 + ) -> Tensor | IntermediateTensors: ...
446
447
448 @overload
@@ -452,8 +454,8 @@ def supports_pp(model: object) -> TypeIs[SupportsPP]: ...
454
455
456 def supports_pp(
455 - model: Union[type[object], object],
456 -) -> Union[bool, TypeIs[type[SupportsPP]], TypeIs[SupportsPP]]:
457 + model: type[object] | object,
458 +) -> bool | TypeIs[type[SupportsPP]] | TypeIs[SupportsPP]:
459 supports_attributes = _supports_pp_attributes(model)
460 supports_inspect = _supports_pp_inspect(model)
461
@@ -487,14 +489,14 @@ def supports_pp(
489 return supports_attributes and supports_inspect
490
491
490 -def _supports_pp_attributes(model: Union[type[object], object]) -> bool:
492 +def _supports_pp_attributes(model: type[object] | object) -> bool:
493 if isinstance(model, type):
494 return isinstance(model, _SupportsPPType)
495
496 return isinstance(model, SupportsPP)
497
498
497 -def _supports_pp_inspect(model: Union[type[object], object]) -> bool:
499 +def _supports_pp_inspect(model: type[object] | object) -> bool:
500 model_forward = getattr(model, "forward", None)
501 if not callable(model_forward):
502 return False
@@ -523,8 +525,8 @@ def has_inner_state(model: type[object]) -> TypeIs[type[HasInnerState]]: ...
525
526
527 def has_inner_state(
526 - model: Union[type[object], object],
527 -) -> Union[TypeIs[type[HasInnerState]], TypeIs[HasInnerState]]:
528 + model: type[object] | object,
529 +) -> TypeIs[type[HasInnerState]] | TypeIs[HasInnerState]:
530 return getattr(model, "has_inner_state", False)
531
532
@@ -550,8 +552,8 @@ def is_attention_free(model: type[object]) -> TypeIs[type[IsAttentionFree]]: ...
552
553
554 def is_attention_free(
553 - model: Union[type[object], object],
554 -) -> Union[TypeIs[type[IsAttentionFree]], TypeIs[IsAttentionFree]]:
555 + model: type[object] | object,
556 +) -> TypeIs[type[IsAttentionFree]] | TypeIs[IsAttentionFree]:
557 return getattr(model, "is_attention_free", False)
558
559
@@ -570,7 +572,7 @@ class IsHybrid(Protocol):
572 @classmethod
573 def get_mamba_state_shape_from_config(
574 cls,
573 - vllm_config: "VllmConfig",
575 + vllm_config: VllmConfig,
576 use_v1: bool = True,
577 ) -> tuple[tuple[int, int], tuple[int, int, int]]:
578 """Calculate shapes for Mamba's convolutional and state caches.
@@ -596,8 +598,8 @@ def is_hybrid(model: type[object]) -> TypeIs[type[IsHybrid]]: ...
598
599
600 def is_hybrid(
599 - model: Union[type[object], object],
600 -) -> Union[TypeIs[type[IsHybrid]], TypeIs[IsHybrid]]:
601 + model: type[object] | object,
602 +) -> TypeIs[type[IsHybrid]] | TypeIs[IsHybrid]:
603 return getattr(model, "is_hybrid", False)
604
605
@@ -688,8 +690,8 @@ def has_noops(model: type[object]) -> TypeIs[type[HasNoOps]]: ...
690
691
692 def has_noops(
691 - model: Union[type[object], object],
692 -) -> Union[TypeIs[type[HasNoOps]], TypeIs[HasNoOps]]:
693 + model: type[object] | object,
694 +) -> TypeIs[type[HasNoOps]] | TypeIs[HasNoOps]:
695 return getattr(model, "has_noops", False)
696
697
@@ -711,23 +713,23 @@ def supports_cross_encoding(model: object) -> TypeIs[SupportsCrossEncoding]: ...
713
714
715 def _supports_cross_encoding(
714 - model: Union[type[object], object],
715 -) -> Union[TypeIs[type[SupportsCrossEncoding]], TypeIs[SupportsCrossEncoding]]:
716 + model: type[object] | object,
717 +) -> TypeIs[type[SupportsCrossEncoding]] | TypeIs[SupportsCrossEncoding]:
718 return getattr(model, "supports_cross_encoding", False)
719
720
721 def supports_cross_encoding(
720 - model: Union[type[object], object],
721 -) -> Union[TypeIs[type[SupportsCrossEncoding]], TypeIs[SupportsCrossEncoding]]:
722 + model: type[object] | object,
723 +) -> TypeIs[type[SupportsCrossEncoding]] | TypeIs[SupportsCrossEncoding]:
724 return is_pooling_model(model) and _supports_cross_encoding(model)
725
726
727 class SupportsQuant:
728 """The interface required for all models that support quantization."""
729
728 - hf_to_vllm_mapper: ClassVar[Optional["WeightsMapper"]] = None
729 - packed_modules_mapping: ClassVar[Optional[dict[str, list[str]]]] = None
730 - quant_config: Optional[QuantizationConfig] = None
730 + hf_to_vllm_mapper: ClassVar[WeightsMapper | None] = None
731 + packed_modules_mapping: ClassVar[dict[str, list[str]] | None] = None
732 + quant_config: QuantizationConfig | None = None
733
734 def __new__(cls, *args, **kwargs) -> Self:
735 instance = super().__new__(cls)
@@ -749,7 +751,7 @@ class SupportsQuant:
751 return instance
752
753 @staticmethod
752 - def _find_quant_config(*args, **kwargs) -> Optional[QuantizationConfig]:
754 + def _find_quant_config(*args, **kwargs) -> QuantizationConfig | None:
755 """Find quant config passed through model constructor args"""
756 from vllm.config import VllmConfig # avoid circular import
757
@@ -797,10 +799,10 @@ class SupportsTranscription(Protocol):
799 audio: np.ndarray,
800 stt_config: SpeechToTextConfig,
801 model_config: ModelConfig,
800 - language: Optional[str],
802 + language: str | None,
803 task_type: Literal["transcribe", "translate"],
804 request_prompt: str,
803 - to_language: Optional[str],
805 + to_language: str | None,
806 ) -> PromptType:
807 """Get the prompt for the ASR model.
808 The model has control over the construction, as long as it
@@ -813,7 +815,7 @@ class SupportsTranscription(Protocol):
815 return {k: v for k, v in LANGUAGES.items() if k not in cls.supported_languages}
816
817 @classmethod
816 - def validate_language(cls, language: Optional[str]) -> Optional[str]:
818 + def validate_language(cls, language: str | None) -> str | None:
819 """
820 Ensure the language specified in the transcription request
821 is a valid ISO 639-1 language code. If the request language is
@@ -850,7 +852,7 @@ class SupportsTranscription(Protocol):
852 audio_duration_s: float,
853 stt_config: SpeechToTextConfig,
854 model_config: ModelConfig,
853 - ) -> Optional[int]:
855 + ) -> int | None:
856 """
857 Map from audio duration to number of audio tokens produced by the ASR
858 model, without running a forward pass.
@@ -870,8 +872,8 @@ def supports_transcription(model: object) -> TypeIs[SupportsTranscription]: ...
872
873
874 def supports_transcription(
873 - model: Union[type[object], object],
874 -) -> Union[TypeIs[type[SupportsTranscription]], TypeIs[SupportsTranscription]]:
875 + model: type[object] | object,
876 +) -> TypeIs[type[SupportsTranscription]] | TypeIs[SupportsTranscription]:
877 return getattr(model, "supports_transcription", False)
878
879
@@ -891,8 +893,8 @@ def supports_v0_only(model: object) -> TypeIs[SupportsV0Only]: ...
893
894
895 def supports_v0_only(
894 - model: Union[type[object], object],
895 -) -> Union[TypeIs[type[SupportsV0Only]], TypeIs[SupportsV0Only]]:
896 + model: type[object] | object,
897 +) -> TypeIs[type[SupportsV0Only]] | TypeIs[SupportsV0Only]:
898 return getattr(model, "supports_v0_only", False)
899
900
@@ -942,8 +944,8 @@ def supports_eagle3(model: object) -> TypeIs[SupportsEagle3]: ...
944
945
946 def supports_eagle3(
945 - model: Union[type[object], object],
946 -) -> Union[TypeIs[type[SupportsEagle3]], TypeIs[SupportsEagle3]]:
947 + model: type[object] | object,
948 +) -> TypeIs[type[SupportsEagle3]] | TypeIs[SupportsEagle3]:
949 return isinstance(model, SupportsEagle3)
950
951
@@ -964,12 +966,12 @@ class SupportsMRoPE(Protocol):
966 self,
967 input_tokens: list[int],
968 hf_config: PretrainedConfig,
967 - image_grid_thw: Optional[Union[list[list[int]], torch.Tensor]],
968 - video_grid_thw: Optional[Union[list[list[int]], torch.Tensor]],
969 - second_per_grid_ts: Optional[list[float]] = None,
969 + image_grid_thw: list[list[int]] | torch.Tensor | None,
970 + video_grid_thw: list[list[int]] | torch.Tensor | None,
971 + second_per_grid_ts: list[float] | None = None,
972 context_len: int = 0,
971 - seq_len: Optional[int] = None,
972 - audio_feature_lengths: Optional[torch.Tensor] = None,
973 + seq_len: int | None = None,
974 + audio_feature_lengths: torch.Tensor | None = None,
975 use_audio_in_video: bool = False,
976 ) -> tuple[torch.Tensor, int]:
977 """
@@ -1007,6 +1009,6 @@ def supports_mrope(model: object) -> TypeIs[SupportsMRoPE]: ...
1009
1010
1011 def supports_mrope(
1010 - model: Union[type[object], object],
1011 -) -> Union[TypeIs[type[SupportsMRoPE]], TypeIs[SupportsMRoPE]]:
1012 + model: type[object] | object,
1013 +) -> TypeIs[type[SupportsMRoPE]] | TypeIs[SupportsMRoPE]:
1014 return isinstance(model, SupportsMRoPE)
vllm/model_executor/models/interfaces_base.py
+11 -15
@@ -5,9 +5,7 @@ from typing import (
5 Any,
6 ClassVar,
7 Literal,
8 - Optional,
8 Protocol,
10 - Union,
9 overload,
10 runtime_checkable,
11 )
@@ -63,12 +61,12 @@ class VllmModel(Protocol[T_co]):
61 ) -> T_co: ...
62
63
66 -def _check_vllm_model_init(model: Union[type[object], object]) -> bool:
64 +def _check_vllm_model_init(model: type[object] | object) -> bool:
65 model_init = model.__init__
66 return supports_kw(model_init, "vllm_config")
67
68
71 -def _check_vllm_model_get_input_embeddings(model: Union[type[object], object]) -> bool:
69 +def _check_vllm_model_get_input_embeddings(model: type[object] | object) -> bool:
70 model_get_input_embeddings = getattr(model, "get_input_embeddings", None)
71 if not callable(model_get_input_embeddings):
72 logger.warning(
@@ -80,7 +78,7 @@ def _check_vllm_model_get_input_embeddings(model: Union[type[object], object]) -
78 return True
79
80
83 -def _check_vllm_model_forward(model: Union[type[object], object]) -> bool:
81 +def _check_vllm_model_forward(model: type[object] | object) -> bool:
82 model_forward = getattr(model, "forward", None)
83 if not callable(model_forward):
84 return False
@@ -108,8 +106,8 @@ def is_vllm_model(model: object) -> TypeIs[VllmModel]: ...
106
107
108 def is_vllm_model(
111 - model: Union[type[object], object],
112 -) -> Union[TypeIs[type[VllmModel]], TypeIs[VllmModel]]:
109 + model: type[object] | object,
110 +) -> TypeIs[type[VllmModel]] | TypeIs[VllmModel]:
111 return (
112 _check_vllm_model_init(model)
113 and _check_vllm_model_get_input_embeddings(model)
@@ -124,7 +122,7 @@ class VllmModelForTextGeneration(VllmModel[T], Protocol[T]):
122 def compute_logits(
123 self,
124 hidden_states: T,
127 - ) -> Optional[T]:
125 + ) -> T | None:
126 """Return `None` if TP rank > 0."""
127 ...
128
@@ -140,10 +138,8 @@ def is_text_generation_model(model: object) -> TypeIs[VllmModelForTextGeneration
138
139
140 def is_text_generation_model(
143 - model: Union[type[object], object],
144 -) -> Union[
145 - TypeIs[type[VllmModelForTextGeneration]], TypeIs[VllmModelForTextGeneration]
146 -]:
141 + model: type[object] | object,
142 +) -> TypeIs[type[VllmModelForTextGeneration]] | TypeIs[VllmModelForTextGeneration]:
143 if not is_vllm_model(model):
144 return False
145
@@ -190,8 +186,8 @@ def is_pooling_model(model: object) -> TypeIs[VllmModelForPooling]: ...
186
187
188 def is_pooling_model(
193 - model: Union[type[object], object],
194 -) -> Union[TypeIs[type[VllmModelForPooling]], TypeIs[VllmModelForPooling]]:
189 + model: type[object] | object,
190 +) -> TypeIs[type[VllmModelForPooling]] | TypeIs[VllmModelForPooling]:
191 if not is_vllm_model(model):
192 return False
193
@@ -211,5 +207,5 @@ def default_pooling_type(pooling_type: str):
207 return func
208
209
214 -def get_default_pooling_type(model: Union[type[object], object]) -> str:
210 +def get_default_pooling_type(model: type[object] | object) -> str:
211 return getattr(model, "default_pooling_type", "LAST")
vllm/model_executor/models/intern_vit.py
+12 -13
@@ -9,7 +9,6 @@
9 # --------------------------------------------------------
10 from collections.abc import Iterable
11 from functools import partial
12 -from typing import Optional
12
13 import torch
14 import torch.nn as nn
@@ -121,8 +120,8 @@ class InternVisionPatchModel(nn.Module):
120
121 def forward(
122 self,
124 - pixel_values: Optional[torch.Tensor] = None,
125 - pixel_embeds: Optional[torch.Tensor] = None,
123 + pixel_values: torch.Tensor | None = None,
124 + pixel_embeds: torch.Tensor | None = None,
125 ) -> torch.FloatTensor:
126 if pixel_values is None and pixel_embeds is None:
127 raise ValueError("You have to specify pixel_values or pixel_embeds")
@@ -144,7 +143,7 @@ class InternParallelAttention(nn.Module):
143 def __init__(
144 self,
145 config: PretrainedConfig,
147 - quant_config: Optional[QuantizationConfig] = None,
146 + quant_config: QuantizationConfig | None = None,
147 *,
148 num_dummy_heads: int = 0,
149 prefix: str = "",
@@ -240,7 +239,7 @@ class InternMLP(nn.Module):
239 def __init__(
240 self,
241 config: PretrainedConfig,
243 - quant_config: Optional[QuantizationConfig] = None,
242 + quant_config: QuantizationConfig | None = None,
243 prefix: str = "",
244 use_data_parallel: bool = False,
245 ) -> None:
@@ -277,7 +276,7 @@ class InternVisionEncoderLayer(nn.Module):
276 def __init__(
277 self,
278 config: PretrainedConfig,
280 - quant_config: Optional[QuantizationConfig] = None,
279 + quant_config: QuantizationConfig | None = None,
280 *,
281 num_dummy_heads: int = 0,
282 prefix: str = "",
@@ -312,7 +311,7 @@ class InternVisionEncoderLayer(nn.Module):
311 def _init_attn(
312 self,
313 config: PretrainedConfig,
315 - quant_config: Optional[QuantizationConfig],
314 + quant_config: QuantizationConfig | None,
315 *,
316 num_dummy_heads: int,
317 prefix: str = "",
@@ -350,9 +349,9 @@ class InternVisionEncoder(nn.Module):
349 def __init__(
350 self,
351 config: PretrainedConfig,
353 - quant_config: Optional[QuantizationConfig] = None,
352 + quant_config: QuantizationConfig | None = None,
353 *,
355 - num_hidden_layers_override: Optional[int] = None,
354 + num_hidden_layers_override: int | None = None,
355 num_dummy_heads: int = 0,
356 prefix: str = "",
357 use_data_parallel: bool = False,
@@ -395,9 +394,9 @@ class InternVisionModel(nn.Module):
394 def __init__(
395 self,
396 config: PretrainedConfig,
398 - quant_config: Optional[QuantizationConfig] = None,
397 + quant_config: QuantizationConfig | None = None,
398 *,
400 - num_hidden_layers_override: Optional[int] = None,
399 + num_hidden_layers_override: int | None = None,
400 num_dummy_heads: int = 0,
401 prefix: str = "",
402 use_data_parallel: bool = False,
@@ -422,8 +421,8 @@ class InternVisionModel(nn.Module):
421
422 def forward(
423 self,
425 - pixel_values: Optional[torch.Tensor] = None,
426 - pixel_embeds: Optional[torch.Tensor] = None,
424 + pixel_values: torch.Tensor | None = None,
425 + pixel_embeds: torch.Tensor | None = None,
426 ) -> torch.FloatTensor:
427 if pixel_values is None and pixel_embeds is None:
428 raise ValueError("You have to specify pixel_values or pixel_embeds")
vllm/model_executor/models/internlm2.py
+17 -17
@@ -4,7 +4,7 @@
4 from collections.abc import Iterable
5 from functools import partial
6 from itertools import islice
7 -from typing import Any, Optional, Union
7 +from typing import Any
8
9 import torch
10 from torch import nn
@@ -54,7 +54,7 @@ class InternLM2MLP(nn.Module):
54 hidden_size: int,
55 intermediate_size: int,
56 hidden_act: str,
57 - quant_config: Optional[QuantizationConfig] = None,
57 + quant_config: QuantizationConfig | None = None,
58 prefix: str = "",
59 ) -> None:
60 super().__init__()
@@ -92,10 +92,10 @@ class InternLM2Attention(nn.Module):
92 num_heads: int,
93 num_kv_heads: int,
94 rope_theta: float = 10000,
95 - rope_scaling: Optional[dict[str, Any]] = None,
95 + rope_scaling: dict[str, Any] | None = None,
96 max_position_embeddings: int = 8192,
97 - cache_config: Optional[CacheConfig] = None,
98 - quant_config: Optional[QuantizationConfig] = None,
97 + cache_config: CacheConfig | None = None,
98 + quant_config: QuantizationConfig | None = None,
99 prefix: str = "",
100 ) -> None:
101 super().__init__()
@@ -198,8 +198,8 @@ class InternLMDecoderLayer(nn.Module):
198 def __init__(
199 self,
200 config: PretrainedConfig,
201 - cache_config: Optional[CacheConfig] = None,
202 - quant_config: Optional[QuantizationConfig] = None,
201 + cache_config: CacheConfig | None = None,
202 + quant_config: QuantizationConfig | None = None,
203 prefix: str = "",
204 ) -> None:
205 super().__init__()
@@ -232,7 +232,7 @@ class InternLMDecoderLayer(nn.Module):
232 self,
233 positions: torch.Tensor,
234 hidden_states: torch.Tensor,
235 - residual: Optional[torch.Tensor],
235 + residual: torch.Tensor | None,
236 ) -> tuple[torch.Tensor, torch.Tensor]:
237 # Self Attention
238 if residual is None:
@@ -291,9 +291,9 @@ class InternLM2Model(nn.Module):
291 self,
292 input_ids: torch.Tensor,
293 positions: torch.Tensor,
294 - intermediate_tensors: Optional[IntermediateTensors] = None,
295 - inputs_embeds: Optional[torch.Tensor] = None,
296 - ) -> Union[torch.Tensor, IntermediateTensors]:
294 + intermediate_tensors: IntermediateTensors | None = None,
295 + inputs_embeds: torch.Tensor | None = None,
296 + ) -> torch.Tensor | IntermediateTensors:
297 if get_pp_group().is_first_rank:
298 if inputs_embeds is not None:
299 hidden_states = inputs_embeds
@@ -359,8 +359,8 @@ class InternLM2ForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
359 self,
360 input_ids: torch.Tensor,
361 positions: torch.Tensor,
362 - intermediate_tensors: Optional[IntermediateTensors],
363 - inputs_embeds: Optional[torch.Tensor] = None,
362 + intermediate_tensors: IntermediateTensors | None,
363 + inputs_embeds: torch.Tensor | None = None,
364 ) -> torch.Tensor:
365 hidden_states = self.model(
366 input_ids, positions, intermediate_tensors, inputs_embeds
@@ -370,7 +370,7 @@ class InternLM2ForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
370 def compute_logits(
371 self,
372 hidden_states: torch.Tensor,
373 - ) -> Optional[torch.Tensor]:
373 + ) -> torch.Tensor | None:
374 logits = self.logits_processor(self.output, hidden_states)
375 return logits
376
@@ -451,9 +451,9 @@ class InternLM2ForRewardModel(InternLM2ForCausalLM):
451 self,
452 input_ids: torch.Tensor,
453 positions: torch.Tensor,
454 - intermediate_tensors: Optional[IntermediateTensors] = None,
455 - inputs_embeds: Optional[torch.Tensor] = None,
456 - ) -> Union[torch.Tensor, IntermediateTensors]:
454 + intermediate_tensors: IntermediateTensors | None = None,
455 + inputs_embeds: torch.Tensor | None = None,
456 + ) -> torch.Tensor | IntermediateTensors:
457 hidden_states = self.model(
458 input_ids, positions, intermediate_tensors, inputs_embeds
459 )
vllm/model_executor/models/internlm2_ve.py
+8 -9
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from itertools import islice
5 -from typing import Optional, Union
5
6 import torch
7 from torch import nn
@@ -25,8 +24,8 @@ class InternLM2VEDecoderLayer(nn.Module):
24 def __init__(
25 self,
26 config: PretrainedConfig,
28 - cache_config: Optional[CacheConfig] = None,
29 - quant_config: Optional[QuantizationConfig] = None,
27 + cache_config: CacheConfig | None = None,
28 + quant_config: QuantizationConfig | None = None,
29 prefix: str = "",
30 ) -> None:
31 super().__init__()
@@ -66,8 +65,8 @@ class InternLM2VEDecoderLayer(nn.Module):
65 self,
66 positions: torch.Tensor,
67 hidden_states: torch.Tensor,
69 - residual: Optional[torch.Tensor],
70 - visual_token_mask: Optional[torch.Tensor] = None,
68 + residual: torch.Tensor | None,
69 + visual_token_mask: torch.Tensor | None = None,
70 ) -> tuple[torch.Tensor, torch.Tensor]:
71 # Self Attention
72 if residual is None:
@@ -107,10 +106,10 @@ class InternLM2VEModel(InternLM2Model):
106 self,
107 input_ids: torch.Tensor,
108 positions: torch.Tensor,
110 - intermediate_tensors: Optional[IntermediateTensors] = None,
111 - inputs_embeds: Optional[torch.Tensor] = None,
112 - visual_token_mask: Optional[torch.Tensor] = None,
113 - ) -> Union[torch.Tensor, IntermediateTensors]:
109 + intermediate_tensors: IntermediateTensors | None = None,
110 + inputs_embeds: torch.Tensor | None = None,
111 + visual_token_mask: torch.Tensor | None = None,
112 + ) -> torch.Tensor | IntermediateTensors:
113 if get_pp_group().is_first_rank:
114 if inputs_embeds is not None:
115 hidden_states = inputs_embeds
vllm/model_executor/models/interns1.py
+19 -23
@@ -7,7 +7,7 @@
7 # Licensed under The MIT License [see LICENSE for details]
8 # --------------------------------------------------------
9 from collections.abc import Iterable, Mapping, Sequence
10 -from typing import Annotated, Literal, Optional, Union
10 +from typing import Annotated, Literal, TypeAlias
11
12 import regex as re
13 import torch
@@ -111,12 +111,10 @@ class InternS1ImageEmbeddingInputs(TensorSchema):
111 """
112
113 type: Literal["image_embeds"] = "image_embeds"
114 - data: Annotated[
115 - Union[torch.Tensor, list[torch.Tensor]], TensorShape("ni", "tifs", "hs")
116 - ]
114 + data: Annotated[torch.Tensor | list[torch.Tensor], TensorShape("ni", "tifs", "hs")]
115
116
119 -InternS1ImageInputs = Union[InternS1ImagePixelInputs, InternS1ImageEmbeddingInputs]
117 +InternS1ImageInputs: TypeAlias = InternS1ImagePixelInputs | InternS1ImageEmbeddingInputs
118
119
120 class InternS1VideoPixelInputs(TensorSchema):
@@ -143,12 +141,10 @@ class InternS1VideoEmbeddingInputs(TensorSchema):
141 """
142
143 type: Literal["video_embeds"] = "video_embeds"
146 - data: Annotated[
147 - Union[torch.Tensor, list[torch.Tensor]], TensorShape("nv", "tvfs", "hs")
148 - ]
144 + data: Annotated[torch.Tensor | list[torch.Tensor], TensorShape("nv", "tvfs", "hs")]
145
146
151 -InternS1VideoInputs = Union[InternS1VideoPixelInputs, InternS1VideoEmbeddingInputs]
147 +InternS1VideoInputs: TypeAlias = InternS1VideoPixelInputs | InternS1VideoEmbeddingInputs
148
149
150 def resolve_interns1_min_max_num(
@@ -190,7 +186,7 @@ class InternS1ProcessingInfo(BaseProcessingInfo):
186 )
187 return hf_processor
188
193 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
189 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
190 return {"image": None, "video": None}
191
192 def get_num_image_tokens(
@@ -198,7 +194,7 @@ class InternS1ProcessingInfo(BaseProcessingInfo):
194 *,
195 image_width: int,
196 image_height: int,
201 - processor: Optional["GotOcr2ImageProcessorFast"] = None,
197 + processor: GotOcr2ImageProcessorFast | None = None,
198 ) -> int:
199 if processor is None:
200 processor = self.get_hf_processor().image_processor
@@ -213,7 +209,7 @@ class InternS1ProcessingInfo(BaseProcessingInfo):
209 num_image_tokens = self.get_hf_processor().image_seq_length * num_image_patches
210 return num_image_tokens
211
216 - def resolve_target_ratios(self, use_thumbnail: Optional[bool] = None):
212 + def resolve_target_ratios(self, use_thumbnail: bool | None = None):
213 image_processor = self.get_hf_processor().image_processor
214 min_dynamic_patch = image_processor.min_patches
215 max_dynamic_patch = image_processor.max_patches
@@ -298,7 +294,7 @@ class InternS1DummyInputsBuilder(BaseDummyInputsBuilder[InternS1ProcessingInfo])
294 self,
295 seq_len: int,
296 mm_counts: Mapping[str, int],
301 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
297 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
298 ) -> MultiModalDataDict:
299 target_width, target_height = self.info.get_image_size_with_most_features()
300 target_num_frames = self.info.get_num_frames_with_most_features(
@@ -523,7 +519,7 @@ class InternS1ForConditionalGeneration(
519 )
520
521 @classmethod
526 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
522 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
523 # transformers InternVLProcessor uses <IMG_CONTEXT> as the separator
524 # refer to https://github.com/huggingface/transformers/blob/f90de364c2484c7c325bbe05befdcf487bd75b63/src/transformers/models/internvl/processing_internvl.py#L116
525 if modality.startswith("image"):
@@ -576,7 +572,7 @@ class InternS1ForConditionalGeneration(
572 def _init_vision_model(
573 self,
574 config: PretrainedConfig,
579 - quant_config: Optional[QuantizationConfig],
575 + quant_config: QuantizationConfig | None,
576 *,
577 prefix: str,
578 ):
@@ -620,7 +616,7 @@ class InternS1ForConditionalGeneration(
616
617 def _parse_and_validate_image_input(
618 self, **kwargs: object
623 - ) -> Optional[InternS1ImageInputs]:
619 + ) -> InternS1ImageInputs | None:
620 pixel_values = kwargs.pop("pixel_values", None)
621 image_num_patches = kwargs.pop("image_num_patches", None)
622 image_embeds = kwargs.pop("image_embeds", None)
@@ -654,7 +650,7 @@ class InternS1ForConditionalGeneration(
650
651 def _parse_and_validate_video_input(
652 self, **kwargs: object
657 - ) -> Optional[InternS1VideoInputs]:
653 + ) -> InternS1VideoInputs | None:
654 pixel_values_flat_video = kwargs.pop("pixel_values_videos", None)
655 video_num_patches = kwargs.pop("video_num_patches", None)
656 video_embeds = kwargs.pop("video_embeds", None)
@@ -688,7 +684,7 @@ class InternS1ForConditionalGeneration(
684
685 def _process_vision_input(
686 self,
691 - image_input: Union[InternS1ImageInputs, InternS1VideoInputs],
687 + image_input: InternS1ImageInputs | InternS1VideoInputs,
688 ) -> tuple[torch.Tensor, ...]:
689 if (
690 image_input["type"] == "image_embeds"
@@ -763,9 +759,9 @@ class InternS1ForConditionalGeneration(
759 def get_input_embeddings(
760 self,
761 input_ids: torch.Tensor,
766 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
762 + multimodal_embeddings: MultiModalEmbeddings | None = None,
763 *,
768 - is_multimodal: Optional[torch.Tensor] = None,
764 + is_multimodal: torch.Tensor | None = None,
765 handle_oov_mm_token: bool = False,
766 ) -> torch.Tensor:
767 if multimodal_embeddings is not None and len(multimodal_embeddings) > 0:
@@ -786,8 +782,8 @@ class InternS1ForConditionalGeneration(
782 self,
783 input_ids: torch.Tensor,
784 positions: torch.Tensor,
789 - intermediate_tensors: Optional[IntermediateTensors] = None,
790 - inputs_embeds: Optional[torch.Tensor] = None,
785 + intermediate_tensors: IntermediateTensors | None = None,
786 + inputs_embeds: torch.Tensor | None = None,
787 **kwargs: object,
788 ) -> IntermediateTensors:
789 if intermediate_tensors is not None:
@@ -807,7 +803,7 @@ class InternS1ForConditionalGeneration(
803 def compute_logits(
804 self,
805 hidden_states: torch.Tensor,
810 - ) -> Optional[torch.Tensor]:
806 + ) -> torch.Tensor | None:
807 return self.language_model.compute_logits(hidden_states)
808
809 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/interns1_vit.py
+10 -11
@@ -8,7 +8,6 @@
8 # Licensed under The MIT License [see LICENSE for details]
9 # --------------------------------------------------------
10 from collections.abc import Iterable
11 -from typing import Optional
11
12 import torch
13 import torch.nn as nn
@@ -139,7 +138,7 @@ class InternS1VisionEmbeddings(nn.Module):
138 def forward(
139 self,
140 pixel_values: torch.Tensor,
142 - bool_masked_pos: Optional[torch.BoolTensor] = None,
141 + bool_masked_pos: torch.BoolTensor | None = None,
142 ) -> torch.Tensor:
143 _, _, height, width = pixel_values.shape
144 embeddings, (patch_height, patch_width) = self.patch_embeddings(pixel_values)
@@ -240,7 +239,7 @@ class InternS1VisionMLP(nn.Module):
239 def __init__(
240 self,
241 config: PretrainedConfig,
243 - quant_config: Optional[QuantizationConfig] = None,
242 + quant_config: QuantizationConfig | None = None,
243 prefix: str = "",
244 ) -> None:
245 super().__init__()
@@ -274,7 +273,7 @@ class InternS1VisionLayer(nn.Module):
273 def __init__(
274 self,
275 config: PretrainedConfig,
277 - quant_config: Optional[QuantizationConfig] = None,
276 + quant_config: QuantizationConfig | None = None,
277 *,
278 num_dummy_heads: int = 0,
279 prefix: str = "",
@@ -309,7 +308,7 @@ class InternS1VisionLayer(nn.Module):
308 def _init_attn(
309 self,
310 config: PretrainedConfig,
312 - quant_config: Optional[QuantizationConfig],
311 + quant_config: QuantizationConfig | None,
312 *,
313 num_dummy_heads: int,
314 prefix: str = "",
@@ -337,9 +336,9 @@ class InternS1VisionEncoder(nn.Module):
336 def __init__(
337 self,
338 config: PretrainedConfig,
340 - quant_config: Optional[QuantizationConfig] = None,
339 + quant_config: QuantizationConfig | None = None,
340 *,
342 - num_hidden_layers_override: Optional[int] = None,
341 + num_hidden_layers_override: int | None = None,
342 num_dummy_heads: int = 0,
343 prefix: str = "",
344 ):
@@ -376,9 +375,9 @@ class InternS1VisionModel(nn.Module):
375 def __init__(
376 self,
377 config: PretrainedConfig,
379 - quant_config: Optional[QuantizationConfig] = None,
378 + quant_config: QuantizationConfig | None = None,
379 *,
381 - num_hidden_layers_override: Optional[int] = None,
380 + num_hidden_layers_override: int | None = None,
381 num_dummy_heads: int = 0,
382 prefix: str = "",
383 ) -> None:
@@ -404,8 +403,8 @@ class InternS1VisionModel(nn.Module):
403
404 def forward(
405 self,
407 - pixel_values: Optional[torch.Tensor] = None,
408 - pixel_embeds: Optional[torch.Tensor] = None,
406 + pixel_values: torch.Tensor | None = None,
407 + pixel_embeds: torch.Tensor | None = None,
408 ) -> torch.FloatTensor:
409 if pixel_values is None and pixel_embeds is None:
410 raise ValueError("You have to specify pixel_values or pixel_embeds")
vllm/model_executor/models/internvl.py
+61 -61
@@ -10,7 +10,7 @@
10 import os
11 from abc import ABC, abstractmethod
12 from collections.abc import Iterable, Mapping, Sequence
13 -from typing import Annotated, Any, Literal, Optional, TypeVar, Union
13 +from typing import Annotated, Any, Literal, TypeAlias, TypeVar
14
15 import numpy.typing as npt
16 import torch
@@ -94,10 +94,10 @@ class InternVLImageEmbeddingInputs(TensorSchema):
94 """
95
96 type: Literal["image_embeds"]
97 - data: Annotated[Union[torch.Tensor, list[torch.Tensor]], TensorShape("n", "f", "h")]
97 + data: Annotated[torch.Tensor | list[torch.Tensor], TensorShape("n", "f", "h")]
98
99
100 -InternVLImageInputs = Union[InternVLImagePixelInputs, InternVLImageEmbeddingInputs]
100 +InternVLImageInputs: TypeAlias = InternVLImagePixelInputs | InternVLImageEmbeddingInputs
101
102
103 class InternVLVideoPixelInputs(TensorSchema):
@@ -124,10 +124,10 @@ class InternVLVideoEmbeddingInputs(TensorSchema):
124 """
125
126 type: Literal["video_embeds"]
127 - data: Annotated[Union[torch.Tensor, list[torch.Tensor]], TensorShape("n", "f", "h")]
127 + data: Annotated[torch.Tensor | list[torch.Tensor], TensorShape("n", "f", "h")]
128
129
130 -InternVLVideoInputs = Union[InternVLVideoPixelInputs, InternVLVideoEmbeddingInputs]
130 +InternVLVideoInputs: TypeAlias = InternVLVideoPixelInputs | InternVLVideoEmbeddingInputs
131
132
133 # adapted from https://huggingface.co/OpenGVLab/InternVL2-1B
@@ -349,9 +349,9 @@ class BaseInternVLProcessor(ABC):
349 config: PretrainedConfig,
350 tokenizer: AnyTokenizer,
351 *,
352 - min_dynamic_patch: Optional[int] = None,
353 - max_dynamic_patch: Optional[int] = None,
354 - dynamic_image_size: Optional[bool] = None,
352 + min_dynamic_patch: int | None = None,
353 + max_dynamic_patch: int | None = None,
354 + dynamic_image_size: bool | None = None,
355 ) -> None:
356 super().__init__()
357
@@ -391,17 +391,17 @@ class BaseInternVLProcessor(ABC):
391 def get_image_repl(
392 self,
393 feature_size: int,
394 - num_patches: Optional[int],
394 + num_patches: int | None,
395 ) -> PromptUpdateDetails[str]:
396 raise NotImplementedError
397
398 def resolve_min_max_num(
399 self,
400 *,
401 - min_dynamic_patch: Optional[int] = None,
402 - max_dynamic_patch: Optional[int] = None,
403 - dynamic_image_size: Optional[bool] = None,
404 - use_thumbnail: Optional[bool] = None,
401 + min_dynamic_patch: int | None = None,
402 + max_dynamic_patch: int | None = None,
403 + dynamic_image_size: bool | None = None,
404 + use_thumbnail: bool | None = None,
405 ) -> tuple[int, int]:
406 min_dynamic_patch = (
407 self.min_dynamic_patch if min_dynamic_patch is None else min_dynamic_patch
@@ -426,10 +426,10 @@ class BaseInternVLProcessor(ABC):
426 def resolve_target_ratios(
427 self,
428 *,
429 - min_dynamic_patch: Optional[int] = None,
430 - max_dynamic_patch: Optional[int] = None,
431 - dynamic_image_size: Optional[bool] = None,
432 - use_thumbnail: Optional[bool] = None,
429 + min_dynamic_patch: int | None = None,
430 + max_dynamic_patch: int | None = None,
431 + dynamic_image_size: bool | None = None,
432 + use_thumbnail: bool | None = None,
433 ) -> list[tuple[int, int]]:
434 min_num, max_num = self.resolve_min_max_num(
435 min_dynamic_patch=min_dynamic_patch,
@@ -463,9 +463,9 @@ class BaseInternVLProcessor(ABC):
463 def _images_to_pixel_values_lst(
464 self,
465 images: list[Image.Image],
466 - min_dynamic_patch: Optional[int] = None,
467 - max_dynamic_patch: Optional[int] = None,
468 - dynamic_image_size: Optional[bool] = None,
466 + min_dynamic_patch: int | None = None,
467 + max_dynamic_patch: int | None = None,
468 + dynamic_image_size: bool | None = None,
469 ) -> list[torch.Tensor]:
470 min_num, max_num = self.resolve_min_max_num(
471 min_dynamic_patch=min_dynamic_patch,
@@ -489,9 +489,9 @@ class BaseInternVLProcessor(ABC):
489 self,
490 text: list[str],
491 images: list[Image.Image],
492 - min_dynamic_patch: Optional[int] = None,
493 - max_dynamic_patch: Optional[int] = None,
494 - dynamic_image_size: Optional[bool] = None,
492 + min_dynamic_patch: int | None = None,
493 + max_dynamic_patch: int | None = None,
494 + dynamic_image_size: bool | None = None,
495 ) -> tuple[list[str], dict[str, torch.Tensor]]:
496 if len(images) == 0:
497 image_inputs = {}
@@ -517,7 +517,7 @@ class BaseInternVLProcessor(ABC):
517 text = [t.replace("<image>", image_repl.full, 1) for t in text]
518 return text, image_inputs
519
520 - def _make_batch_input(self, input_item: Optional[Union[Any, list[Any]]] = None):
520 + def _make_batch_input(self, input_item: Any | list[Any] | None = None):
521 if input_item is None:
522 input_item = []
523 if not isinstance(input_item, list):
@@ -526,12 +526,12 @@ class BaseInternVLProcessor(ABC):
526
527 def __call__(
528 self,
529 - text: Optional[Union[str, list[str]]] = None,
530 - images: Optional[Union[Image.Image, list[Image.Image]]] = None,
531 - min_dynamic_patch: Optional[int] = None,
532 - max_dynamic_patch: Optional[int] = None,
533 - dynamic_image_size: Optional[bool] = None,
534 - return_tensors: Optional[Union[str, TensorType]] = None,
529 + text: str | list[str] | None = None,
530 + images: Image.Image | list[Image.Image] | None = None,
531 + min_dynamic_patch: int | None = None,
532 + max_dynamic_patch: int | None = None,
533 + dynamic_image_size: bool | None = None,
534 + return_tensors: str | TensorType | None = None,
535 ) -> BatchFeature:
536 text, images = [self._make_batch_input(x) for x in (text, images)]
537
@@ -563,10 +563,10 @@ class InternVLProcessor(BaseInternVLProcessor):
563 config: PretrainedConfig,
564 tokenizer: AnyTokenizer,
565 *,
566 - min_dynamic_patch: Optional[int] = None,
567 - max_dynamic_patch: Optional[int] = None,
568 - dynamic_image_size: Optional[bool] = None,
569 - video_token: Optional[str] = None,
566 + min_dynamic_patch: int | None = None,
567 + max_dynamic_patch: int | None = None,
568 + dynamic_image_size: bool | None = None,
569 + video_token: str | None = None,
570 ) -> None:
571 super().__init__(
572 config=config,
@@ -583,7 +583,7 @@ class InternVLProcessor(BaseInternVLProcessor):
583 return self.tokenizer.get_vocab()[IMG_CONTEXT]
584
585 @property
586 - def video_token_id(self) -> Optional[int]:
586 + def video_token_id(self) -> int | None:
587 if self.video_token is None:
588 return None
589 return self.tokenizer.get_vocab().get(self.video_token, None)
@@ -595,7 +595,7 @@ class InternVLProcessor(BaseInternVLProcessor):
595 def _videos_to_pixel_values_lst(
596 self,
597 videos: list[npt.NDArray],
598 - dynamic_image_size: Optional[bool] = None,
598 + dynamic_image_size: bool | None = None,
599 ) -> list[torch.Tensor]:
600 min_num, max_num = self.resolve_min_max_num(
601 min_dynamic_patch=1,
@@ -619,7 +619,7 @@ class InternVLProcessor(BaseInternVLProcessor):
619 self,
620 text: list[str],
621 videos: list[npt.NDArray],
622 - dynamic_image_size: Optional[bool] = None,
622 + dynamic_image_size: bool | None = None,
623 ):
624 if len(videos) == 0 or not self.supports_video:
625 video_inputs = {}
@@ -646,13 +646,13 @@ class InternVLProcessor(BaseInternVLProcessor):
646
647 def __call__(
648 self,
649 - text: Optional[Union[str, list[str]]] = None,
650 - images: Optional[Union[Image.Image, list[Image.Image]]] = None,
651 - videos: Optional[Union[npt.NDArray, list[npt.NDArray]]] = None,
652 - min_dynamic_patch: Optional[int] = None,
653 - max_dynamic_patch: Optional[int] = None,
654 - dynamic_image_size: Optional[bool] = None,
655 - return_tensors: Optional[Union[str, TensorType]] = None,
649 + text: str | list[str] | None = None,
650 + images: Image.Image | list[Image.Image] | None = None,
651 + videos: npt.NDArray | list[npt.NDArray] | None = None,
652 + min_dynamic_patch: int | None = None,
653 + max_dynamic_patch: int | None = None,
654 + dynamic_image_size: bool | None = None,
655 + return_tensors: str | TensorType | None = None,
656 ) -> BatchFeature:
657 text, images, videos = [
658 self._make_batch_input(x) for x in (text, images, videos)
@@ -681,7 +681,7 @@ class InternVLProcessor(BaseInternVLProcessor):
681 def get_image_repl(
682 self,
683 feature_size: int,
684 - num_patches: Optional[int],
684 + num_patches: int | None,
685 ) -> PromptUpdateDetails[str]:
686 repl_features = IMG_CONTEXT * feature_size
687 repl_full = IMG_START + repl_features + IMG_END
@@ -691,7 +691,7 @@ class InternVLProcessor(BaseInternVLProcessor):
691 def get_video_repl(
692 self,
693 feature_size: int,
694 - num_patches: Optional[int] = None,
694 + num_patches: int | None = None,
695 video_context_token: str = IMG_CONTEXT,
696 ) -> PromptUpdateDetails[str]:
697 repl_features = video_context_token * self.num_image_token
@@ -711,7 +711,7 @@ class BaseInternVLProcessingInfo(BaseProcessingInfo):
711 def get_hf_processor(self, **kwargs: object) -> BaseInternVLProcessor:
712 raise NotImplementedError
713
714 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
714 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
715 return {"image": None}
716
717 def get_num_image_tokens(
@@ -719,7 +719,7 @@ class BaseInternVLProcessingInfo(BaseProcessingInfo):
719 *,
720 image_width: int,
721 image_height: int,
722 - processor: Optional[BaseInternVLProcessor],
722 + processor: BaseInternVLProcessor | None,
723 ) -> int:
724 if processor is None:
725 processor = self.get_hf_processor()
@@ -779,7 +779,7 @@ class BaseInternVLDummyInputsBuilder(BaseDummyInputsBuilder[_I]):
779 self,
780 seq_len: int,
781 mm_counts: Mapping[str, int],
782 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
782 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
783 ) -> MultiModalDataDict:
784 target_width, target_height = self.info.get_image_size_with_most_features()
785 num_images = mm_counts.get("image", 0)
@@ -901,7 +901,7 @@ class InternVLProcessingInfo(BaseInternVLProcessingInfo):
901 video_limit = {"video": None} if self.supports_video else {}
902 return {**super().get_supported_mm_limits(), **video_limit}
903
904 - def get_video_token(self) -> Optional[str]:
904 + def get_video_token(self) -> str | None:
905 text_model_type = self.get_hf_config().get_text_config().model_type
906 video_token_map = {
907 "qwen2": "<|video_pad|>",
@@ -951,7 +951,7 @@ class InternVLDummyInputsBuilder(
951 self,
952 seq_len: int,
953 mm_counts: Mapping[str, int],
954 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
954 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
955 ) -> MultiModalDataDict:
956 dummy_image = super().get_dummy_mm_data(
957 seq_len=seq_len, mm_counts=mm_counts, mm_options=mm_options
@@ -1079,7 +1079,7 @@ class InternVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA)
1079 supports_encoder_tp_data = True
1080
1081 @classmethod
1082 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1082 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1083 if modality.startswith("image"):
1084 return "<image>"
1085 if modality.startswith("video"):
@@ -1149,7 +1149,7 @@ class InternVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA)
1149 def _init_vision_model(
1150 self,
1151 config: PretrainedConfig,
1152 - quant_config: Optional[QuantizationConfig],
1152 + quant_config: QuantizationConfig | None,
1153 *,
1154 is_mono: bool,
1155 prefix: str,
@@ -1217,7 +1217,7 @@ class InternVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA)
1217
1218 def _parse_and_validate_image_input(
1219 self, **kwargs: object
1220 - ) -> Optional[InternVLImageInputs]:
1220 + ) -> InternVLImageInputs | None:
1221 pixel_values_flat = kwargs.pop("pixel_values_flat", None)
1222 image_num_patches = kwargs.pop("image_num_patches", None)
1223 image_embeds = kwargs.pop("image_embeds", None)
@@ -1250,7 +1250,7 @@ class InternVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA)
1250
1251 def _parse_and_validate_video_input(
1252 self, **kwargs: object
1253 - ) -> Optional[InternVLVideoPixelInputs]:
1253 + ) -> InternVLVideoPixelInputs | None:
1254 pixel_values_flat_video = kwargs.pop("pixel_values_flat_video", None)
1255 video_num_patches = kwargs.pop("video_num_patches", None)
1256 video_embeds = kwargs.pop("image_embeds", None)
@@ -1283,7 +1283,7 @@ class InternVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA)
1283
1284 def _process_vision_input(
1285 self,
1286 - image_input: Union[InternVLImageInputs, InternVLVideoInputs],
1286 + image_input: InternVLImageInputs | InternVLVideoInputs,
1287 ) -> tuple[torch.Tensor, ...]:
1288 if (
1289 image_input["type"] == "image_embeds"
@@ -1364,9 +1364,9 @@ class InternVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA)
1364 def get_input_embeddings(
1365 self,
1366 input_ids: torch.Tensor,
1367 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
1367 + multimodal_embeddings: MultiModalEmbeddings | None = None,
1368 *,
1369 - is_multimodal: Optional[torch.Tensor] = None,
1369 + is_multimodal: torch.Tensor | None = None,
1370 handle_oov_mm_token: bool = False,
1371 ) -> torch.Tensor:
1372 if multimodal_embeddings is not None and len(multimodal_embeddings) > 0:
@@ -1387,8 +1387,8 @@ class InternVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA)
1387 self,
1388 input_ids: torch.Tensor,
1389 positions: torch.Tensor,
1390 - intermediate_tensors: Optional[IntermediateTensors] = None,
1391 - inputs_embeds: Optional[torch.Tensor] = None,
1390 + intermediate_tensors: IntermediateTensors | None = None,
1391 + inputs_embeds: torch.Tensor | None = None,
1392 **kwargs: object,
1393 ) -> IntermediateTensors:
1394 if intermediate_tensors is not None:
@@ -1413,7 +1413,7 @@ class InternVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA)
1413 def compute_logits(
1414 self,
1415 hidden_states: torch.Tensor,
1416 - ) -> Optional[torch.Tensor]:
1416 + ) -> torch.Tensor | None:
1417 return self.language_model.compute_logits(hidden_states)
1418
1419 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/jais.py
+12 -13
@@ -24,7 +24,6 @@
24 import math
25 from collections.abc import Iterable
26 from itertools import islice
27 -from typing import Optional, Union
27
28 import torch
29 from torch import nn
@@ -86,8 +85,8 @@ class JAISAttention(nn.Module):
85 def __init__(
86 self,
87 config: JAISConfig,
89 - cache_config: Optional[CacheConfig] = None,
90 - quant_config: Optional[QuantizationConfig] = None,
88 + cache_config: CacheConfig | None = None,
89 + quant_config: QuantizationConfig | None = None,
90 prefix: str = "",
91 ):
92 super().__init__()
@@ -147,7 +146,7 @@ class JAISMLP(nn.Module):
146 self,
147 intermediate_size: int,
148 config: JAISConfig,
150 - quant_config: Optional[QuantizationConfig] = None,
149 + quant_config: QuantizationConfig | None = None,
150 ):
151 super().__init__()
152 hidden_size = config.hidden_size
@@ -194,8 +193,8 @@ class JAISBlock(nn.Module):
193 def __init__(
194 self,
195 config: JAISConfig,
197 - cache_config: Optional[CacheConfig] = None,
198 - quant_config: Optional[QuantizationConfig] = None,
196 + cache_config: CacheConfig | None = None,
197 + quant_config: QuantizationConfig | None = None,
198 prefix: str = "",
199 ):
200 super().__init__()
@@ -277,9 +276,9 @@ class JAISModel(nn.Module):
276 self,
277 input_ids: torch.Tensor,
278 position_ids: torch.Tensor,
280 - intermediate_tensors: Optional[IntermediateTensors] = None,
281 - inputs_embeds: Optional[torch.Tensor] = None,
282 - ) -> Union[IntermediateTensors, torch.Tensor]:
279 + intermediate_tensors: IntermediateTensors | None = None,
280 + inputs_embeds: torch.Tensor | None = None,
281 + ) -> IntermediateTensors | torch.Tensor:
282 if get_pp_group().is_first_rank:
283 if inputs_embeds is None:
284 inputs_embeds = self.get_input_embeddings(input_ids)
@@ -341,9 +340,9 @@ class JAISLMHeadModel(nn.Module, SupportsPP):
340 self,
341 input_ids: torch.Tensor,
342 positions: torch.Tensor,
344 - intermediate_tensors: Optional[IntermediateTensors] = None,
345 - inputs_embeds: Optional[torch.Tensor] = None,
346 - ) -> Union[IntermediateTensors, torch.Tensor]:
343 + intermediate_tensors: IntermediateTensors | None = None,
344 + inputs_embeds: torch.Tensor | None = None,
345 + ) -> IntermediateTensors | torch.Tensor:
346 hidden_states = self.transformer(
347 input_ids, positions, intermediate_tensors, inputs_embeds
348 )
@@ -352,7 +351,7 @@ class JAISLMHeadModel(nn.Module, SupportsPP):
351 def compute_logits(
352 self,
353 hidden_states: torch.Tensor,
355 - ) -> Optional[torch.Tensor]:
354 + ) -> torch.Tensor | None:
355 logits = self.logits_processor(self.lm_head, hidden_states)
356 return logits
357
vllm/model_executor/models/jamba.py
+19 -20
@@ -4,7 +4,6 @@
4
5 from collections.abc import Iterable
6 from itertools import islice
7 -from typing import Optional
7
8 import torch
9 from torch import nn
@@ -54,11 +53,11 @@ class JambaMoE(nn.Module):
53 def __init__(
54 self,
55 config: JambaConfig,
57 - num_experts: Optional[int] = None,
58 - top_k: Optional[int] = None,
59 - params_dtype: Optional[torch.dtype] = None,
60 - tp_size: Optional[int] = None,
61 - quant_config: Optional[QuantizationConfig] = None,
56 + num_experts: int | None = None,
57 + top_k: int | None = None,
58 + params_dtype: torch.dtype | None = None,
59 + tp_size: int | None = None,
60 + quant_config: QuantizationConfig | None = None,
61 prefix: str = "",
62 ):
63 super().__init__()
@@ -111,10 +110,10 @@ class JambaMambaDecoderLayer(nn.Module):
110 self,
111 config: JambaConfig,
112 layer_idx: int,
114 - model_config: Optional[ModelConfig] = None,
115 - cache_config: Optional[CacheConfig] = None,
116 - quant_config: Optional[QuantizationConfig] = None,
117 - is_lora_enabled: Optional[bool] = False,
113 + model_config: ModelConfig | None = None,
114 + cache_config: CacheConfig | None = None,
115 + quant_config: QuantizationConfig | None = None,
116 + is_lora_enabled: bool | None = False,
117 prefix: str = "",
118 **kwargs,
119 ) -> None:
@@ -159,7 +158,7 @@ class JambaMambaDecoderLayer(nn.Module):
158 def forward(
159 self,
160 hidden_states: torch.Tensor,
162 - residual: Optional[torch.Tensor],
161 + residual: torch.Tensor | None,
162 **kwargs,
163 ):
164 if residual is None:
@@ -181,9 +180,9 @@ class JambaAttentionDecoderLayer(nn.Module):
180 self,
181 config: JambaConfig,
182 layer_idx: int,
184 - model_config: Optional[ModelConfig] = None,
185 - cache_config: Optional[CacheConfig] = None,
186 - quant_config: Optional[QuantizationConfig] = None,
183 + model_config: ModelConfig | None = None,
184 + cache_config: CacheConfig | None = None,
185 + quant_config: QuantizationConfig | None = None,
186 prefix: str = "",
187 **kwargs,
188 ) -> None:
@@ -266,7 +265,7 @@ class JambaAttentionDecoderLayer(nn.Module):
265 self,
266 positions: torch.Tensor,
267 hidden_states: torch.Tensor,
269 - residual: Optional[torch.Tensor],
268 + residual: torch.Tensor | None,
269 **kwargs,
270 ):
271 if residual is None:
@@ -348,8 +347,8 @@ class JambaModel(nn.Module):
347 self,
348 input_ids: torch.Tensor,
349 positions: torch.Tensor,
351 - intermediate_tensors: Optional[IntermediateTensors] = None,
352 - inputs_embeds: Optional[torch.Tensor] = None,
350 + intermediate_tensors: IntermediateTensors | None = None,
351 + inputs_embeds: torch.Tensor | None = None,
352 ) -> torch.Tensor:
353 if get_pp_group().is_first_rank:
354 if inputs_embeds is not None:
@@ -523,8 +522,8 @@ class JambaForCausalLM(nn.Module, HasInnerState, SupportsLoRA, SupportsPP, IsHyb
522 self,
523 input_ids: torch.Tensor,
524 positions: torch.Tensor,
526 - intermediate_tensors: Optional[IntermediateTensors] = None,
527 - inputs_embeds: Optional[torch.Tensor] = None,
525 + intermediate_tensors: IntermediateTensors | None = None,
526 + inputs_embeds: torch.Tensor | None = None,
527 **kwargs,
528 ):
529 hidden_states = self.model(
@@ -568,7 +567,7 @@ class JambaForCausalLM(nn.Module, HasInnerState, SupportsLoRA, SupportsPP, IsHyb
567 def compute_logits(
568 self,
569 hidden_states: torch.Tensor,
571 - ) -> Optional[torch.Tensor]:
570 + ) -> torch.Tensor | None:
571 logits = self.logits_processor(self.lm_head, hidden_states)
572 return logits
573
vllm/model_executor/models/jina_vl.py
+4 -5
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable, Mapping
4 -from typing import Optional
4
5 import torch
6 import torch.nn as nn
@@ -105,14 +104,14 @@ class JinaVLForSequenceClassification(
104 )
105
106 @classmethod
108 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
107 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
108 if modality.startswith("image"):
109 return "<|vision_start|><|image_pad|><|vision_end|>"
110
111 raise ValueError("Only image modality is supported")
112
113 @classmethod
115 - def get_score_template(cls, query: str, document: str) -> Optional[str]:
114 + def get_score_template(cls, query: str, document: str) -> str | None:
115 return f"**Document**:\n{document}\n**Query**:\n{query}"
116
117 @classmethod
@@ -124,8 +123,8 @@ class JinaVLForSequenceClassification(
123 self,
124 input_ids: torch.Tensor,
125 positions: torch.Tensor,
127 - intermediate_tensors: Optional[IntermediateTensors] = None,
128 - inputs_embeds: Optional[torch.Tensor] = None,
126 + intermediate_tensors: IntermediateTensors | None = None,
127 + inputs_embeds: torch.Tensor | None = None,
128 **kwargs: object,
129 ) -> torch.Tensor:
130 hidden_states = super().forward(
vllm/model_executor/models/keye.py
+76 -100
@@ -4,7 +4,7 @@ import math
4 from abc import abstractmethod
5 from collections.abc import Iterable, Mapping, Sequence
6 from functools import partial
7 -from typing import Annotated, Any, Literal, Optional, TypeVar, Union
7 +from typing import Annotated, Any, Literal, TypeAlias, TypeVar
8
9 import numpy as np
10 import torch
@@ -153,7 +153,7 @@ class KeyeImageEmbeddingInputs(TensorSchema):
153 image_grid_thw: Annotated[torch.Tensor, TensorShape("ni", 3)]
154
155
156 -KeyeImageInputs = Union[KeyeImagePixelInputs, KeyeImageEmbeddingInputs]
156 +KeyeImageInputs: TypeAlias = KeyeImagePixelInputs | KeyeImageEmbeddingInputs
157
158
159 class KeyeVideoPixelInputs(TensorSchema):
@@ -188,7 +188,7 @@ class KeyeVideoEmbeddingInputs(TensorSchema):
188 video_grid_thw: Annotated[torch.Tensor, TensorShape("nv", 3)]
189
190
191 -KeyeVideoInputs = Union[KeyeVideoPixelInputs, KeyeVideoEmbeddingInputs]
191 +KeyeVideoInputs: TypeAlias = KeyeVideoPixelInputs | KeyeVideoEmbeddingInputs
192
193
194 class KeyeVisionEmbeddings(nn.Module):
@@ -278,15 +278,9 @@ class KeyeVisionEmbeddings(nn.Module):
278 def forward(
279 self,
280 pixel_values: torch.FloatTensor,
281 - position_ids: Optional[torch.Tensor] = None,
282 - image_grid_thw: Optional[
283 - list[
284 - Union[
285 - tuple[int, int, int],
286 - list[tuple[int, int, int]],
287 - ]
288 - ]
289 - ] = None,
281 + position_ids: torch.Tensor | None = None,
282 + image_grid_thw: list[tuple[int, int, int] | list[tuple[int, int, int]]]
283 + | None = None,
284 interpolate_pos_encoding=False,
285 ) -> torch.Tensor:
286 if pixel_values.dim() == 4:
@@ -357,7 +351,7 @@ class KeyeSiglipAttention(nn.Module):
351 def __init__(
352 self,
353 config: PretrainedConfig,
360 - quant_config: Optional[QuantizationConfig] = None,
354 + quant_config: QuantizationConfig | None = None,
355 prefix: str = "",
356 ):
357 super().__init__()
@@ -416,10 +410,10 @@ class KeyeSiglipAttention(nn.Module):
410 def forward(
411 self,
412 hidden_states: torch.Tensor,
419 - attention_mask: Optional[torch.Tensor] = None,
420 - output_attentions: Optional[bool] = False,
421 - cu_seqlens: Optional[list[torch.Tensor]] = None,
422 - rope_emb: Optional[tuple[torch.Tensor, torch.Tensor]] = None,
413 + attention_mask: torch.Tensor | None = None,
414 + output_attentions: bool | None = False,
415 + cu_seqlens: list[torch.Tensor] | None = None,
416 + rope_emb: tuple[torch.Tensor, torch.Tensor] | None = None,
417 ) -> torch.Tensor:
418 qkv, _ = self.qkv_proj(hidden_states)
419 q, k, v = qkv.split(
@@ -524,8 +518,8 @@ class SigLIPRotaryEmbedding(nn.Module):
518 class KeyeSiglipEncoderLayer(nn.Module):
519 def __init__(
520 self,
527 - config: Union[PretrainedConfig],
528 - quant_config: Optional[QuantizationConfig] = None,
521 + config: PretrainedConfig,
522 + quant_config: QuantizationConfig | None = None,
523 prefix: str = "",
524 ):
525 super().__init__()
@@ -547,9 +541,9 @@ class KeyeSiglipEncoderLayer(nn.Module):
541 self,
542 hidden_states: torch.Tensor,
543 attention_mask: torch.Tensor,
550 - output_attentions: Optional[bool] = False,
551 - cu_seqlens: Optional[list[torch.Tensor]] = None,
552 - rope_emb: Optional[tuple[torch.Tensor, torch.Tensor]] = None,
544 + output_attentions: bool | None = False,
545 + cu_seqlens: list[torch.Tensor] | None = None,
546 + rope_emb: tuple[torch.Tensor, torch.Tensor] | None = None,
547 ) -> tuple[torch.FloatTensor]:
548 residual = hidden_states
549
@@ -577,7 +571,7 @@ class KeyeSiglipEncoder(nn.Module):
571 def __init__(
572 self,
573 config: PretrainedConfig,
580 - quant_config: Optional[QuantizationConfig] = None,
574 + quant_config: QuantizationConfig | None = None,
575 prefix: str = "",
576 ):
577 super().__init__()
@@ -610,22 +604,16 @@ class KeyeSiglipEncoder(nn.Module):
604 def forward(
605 self,
606 inputs_embeds,
613 - attention_mask: Optional[torch.Tensor] = None,
614 - output_attentions: Optional[bool] = None,
615 - output_hidden_states: Optional[bool] = None,
616 - cu_seqlens: Optional[list[torch.Tensor]] = None,
617 - image_grid_thw: Optional[
618 - list[
619 - Union[
620 - tuple[int, int, int],
621 - list[tuple[int, int, int]],
622 - ]
623 - ]
624 - ] = None,
625 - height_position_ids: Optional[torch.Tensor] = None,
626 - width_position_ids: Optional[torch.Tensor] = None,
627 - use_rope: Optional[bool] = False,
628 - window_size: Optional[bool] = -1,
607 + attention_mask: torch.Tensor | None = None,
608 + output_attentions: bool | None = None,
609 + output_hidden_states: bool | None = None,
610 + cu_seqlens: list[torch.Tensor] | None = None,
611 + image_grid_thw: list[tuple[int, int, int] | list[tuple[int, int, int]]]
612 + | None = None,
613 + height_position_ids: torch.Tensor | None = None,
614 + width_position_ids: torch.Tensor | None = None,
615 + use_rope: bool | None = False,
616 + window_size: bool | None = -1,
617 vision_or_text: str = "vision",
618 ) -> BaseModelOutput:
619 device = inputs_embeds.device
@@ -676,7 +664,7 @@ class KeyeSiglipVisionTransformer(nn.Module):
664 def __init__(
665 self,
666 config: PretrainedConfig,
679 - quant_config: Optional[QuantizationConfig] = None,
667 + quant_config: QuantizationConfig | None = None,
668 prefix: str = "",
669 ):
670 super().__init__()
@@ -694,29 +682,23 @@ class KeyeSiglipVisionTransformer(nn.Module):
682 def forward(
683 self,
684 pixel_values,
697 - output_attentions: Optional[bool] = None,
698 - output_hidden_states: Optional[bool] = None,
699 - interpolate_pos_encoding: Optional[bool] = False,
700 - attention_mask: Optional[torch.Tensor] = None,
701 - sample_indices: Optional[torch.Tensor] = None,
702 - image_indices: Optional[torch.Tensor] = None,
703 - position_ids: Optional[torch.Tensor] = None,
704 - height_position_ids: Optional[torch.Tensor] = None,
705 - width_position_ids: Optional[torch.Tensor] = None,
706 - cu_seqlens: Optional[list[torch.Tensor]] = None,
707 - padding_mask: Optional[torch.Tensor] = None,
708 - vision_return_embed_list: Optional[bool] = False,
709 - image_grid_thw: Optional[
710 - list[
711 - Union[
712 - tuple[int, int, int],
713 - list[tuple[int, int, int]],
714 - ]
715 - ]
716 - ] = None,
717 - return_pooler_output: Optional[bool] = True,
718 - use_rope: Optional[bool] = False,
719 - window_size: Optional[bool] = -1,
685 + output_attentions: bool | None = None,
686 + output_hidden_states: bool | None = None,
687 + interpolate_pos_encoding: bool | None = False,
688 + attention_mask: torch.Tensor | None = None,
689 + sample_indices: torch.Tensor | None = None,
690 + image_indices: torch.Tensor | None = None,
691 + position_ids: torch.Tensor | None = None,
692 + height_position_ids: torch.Tensor | None = None,
693 + width_position_ids: torch.Tensor | None = None,
694 + cu_seqlens: list[torch.Tensor] | None = None,
695 + padding_mask: torch.Tensor | None = None,
696 + vision_return_embed_list: bool | None = False,
697 + image_grid_thw: list[tuple[int, int, int] | list[tuple[int, int, int]]]
698 + | None = None,
699 + return_pooler_output: bool | None = True,
700 + use_rope: bool | None = False,
701 + window_size: bool | None = -1,
702 ) -> BaseModelOutputWithPooling:
703 hidden_states = self.embeddings(
704 pixel_values,
@@ -763,7 +745,7 @@ class KeyeSiglipVisionModel(nn.Module):
745 def __init__(
746 self,
747 config: PretrainedConfig,
766 - quant_config: Optional[QuantizationConfig] = None,
748 + quant_config: QuantizationConfig | None = None,
749 prefix: str = "",
750 ):
751 super().__init__()
@@ -789,24 +771,18 @@ class KeyeSiglipVisionModel(nn.Module):
771 def forward(
772 self,
773 pixel_values,
792 - sample_indices: Optional[torch.Tensor] = None,
793 - output_attentions: Optional[bool] = None,
794 - output_hidden_states: Optional[bool] = None,
774 + sample_indices: torch.Tensor | None = None,
775 + output_attentions: bool | None = None,
776 + output_hidden_states: bool | None = None,
777 interpolate_pos_encoding: bool = False,
796 - position_ids: Optional[torch.Tensor] = None,
797 - vision_return_embed_list: Optional[bool] = False,
798 - image_grid_thw: Optional[
799 - list[
800 - Union[
801 - tuple[int, int, int],
802 - list[tuple[int, int, int]],
803 - ]
804 - ]
805 - ] = None,
806 - cu_seqlens: Optional[list[torch.Tensor]] = None,
807 - return_pooler_output: Optional[bool] = True,
808 - use_rope: Optional[bool] = False,
809 - window_size: Optional[bool] = -1,
778 + position_ids: torch.Tensor | None = None,
779 + vision_return_embed_list: bool | None = False,
780 + image_grid_thw: list[tuple[int, int, int] | list[tuple[int, int, int]]]
781 + | None = None,
782 + cu_seqlens: list[torch.Tensor] | None = None,
783 + return_pooler_output: bool | None = True,
784 + use_rope: bool | None = False,
785 + window_size: bool | None = -1,
786 ) -> BaseModelOutputWithPooling:
787 return self.vision_model(
788 pixel_values=pixel_values,
@@ -893,7 +869,7 @@ class Projector(nn.Module):
869 self,
870 text_config: PretrainedConfig,
871 vision_config: PretrainedConfig,
896 - quant_config: Optional[QuantizationConfig] = None,
872 + quant_config: QuantizationConfig | None = None,
873 prefix: str = "",
874 ):
875 super().__init__()
@@ -927,9 +903,9 @@ class Projector(nn.Module):
903
904 def forward(
905 self,
930 - image_features: Union[torch.Tensor, list[torch.Tensor]],
906 + image_features: torch.Tensor | list[torch.Tensor],
907 image_grid_thw: list[tuple[int, int, int]],
932 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
908 + ) -> torch.Tensor | list[torch.Tensor]:
909 m1, m2 = self.merge_kernel_size
910 if isinstance(image_features, (list, tuple)):
911 processed_features = list()
@@ -988,7 +964,7 @@ def _keye_field_config(
964 class KeyeMultiModalDataParser(MultiModalDataParser):
965 def _parse_image_data(
966 self,
991 - data: Union[dict[str, torch.Tensor], ModalityData[ImageItem]],
967 + data: dict[str, torch.Tensor] | ModalityData[ImageItem],
968 ) -> ModalityDataItems[Any, Any]:
969 if isinstance(data, dict):
970 return DictEmbeddingItems(
@@ -1005,7 +981,7 @@ class KeyeMultiModalDataParser(MultiModalDataParser):
981
982 def _parse_video_data(
983 self,
1008 - data: Union[dict[str, torch.Tensor], ModalityData[VideoItem]],
984 + data: dict[str, torch.Tensor] | ModalityData[VideoItem],
985 ) -> ModalityDataItems[Any, Any]:
986 if isinstance(data, dict):
987 return DictEmbeddingItems(
@@ -1033,7 +1009,7 @@ class KeyeProcessingInfo(BaseProcessingInfo):
1009
1010 def get_supported_mm_limits(
1011 self,
1036 - ) -> Mapping[str, Optional[int]]:
1012 + ) -> Mapping[str, int | None]:
1013 return {"image": None, "video": None}
1014
1015 def get_mm_max_tokens_per_item(
@@ -1200,7 +1176,7 @@ class KeyeBaseDummyInputsBuilder(BaseDummyInputsBuilder[_I]):
1176 self,
1177 seq_len: int,
1178 mm_counts: Mapping[str, int],
1203 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
1179 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
1180 ) -> MultiModalDataDict:
1181 num_images = mm_counts.get("image", 0)
1182 num_videos = mm_counts.get("video", 0)
@@ -1303,7 +1279,7 @@ class BaseKeyeModule(nn.Module):
1279 )
1280
1281 @classmethod
1306 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1282 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1283 if modality.startswith("image"):
1284 return "<|vision_start|><|image_pad|><|vision_end|>"
1285 if modality.startswith("video"):
@@ -1348,7 +1324,7 @@ class BaseKeyeModule(nn.Module):
1324 self,
1325 text_config: PretrainedConfig,
1326 vision_config: PretrainedConfig,
1351 - quant_config: Optional[QuantizationConfig] = None,
1327 + quant_config: QuantizationConfig | None = None,
1328 prefix: str = "",
1329 ) -> nn.Module:
1330 raise ValueError("Need projector")
@@ -1403,8 +1379,8 @@ class BaseKeyeModule(nn.Module):
1379 self,
1380 video_type: Literal["video_embeds", "pixel_values_videos"],
1381 video_grid_thw: list[torch.Tensor],
1406 - pixel_values_videos: Optional[torch.Tensor] = None,
1407 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
1382 + pixel_values_videos: torch.Tensor | None = None,
1383 + ) -> torch.Tensor | list[torch.Tensor]:
1384 siglip_position_ids = list()
1385 video_grid_hws = list()
1386 sample_indices = list()
@@ -1473,7 +1449,7 @@ class BaseKeyeModule(nn.Module):
1449
1450 def get_multimodal_embeddings(
1451 self, **kwargs: object
1476 - ) -> Optional[MultiModalEmbeddings]:
1452 + ) -> MultiModalEmbeddings | None:
1453 modalities = self._parse_and_validate_multimodal_inputs(**kwargs)
1454 if not modalities:
1455 return None
@@ -1495,10 +1471,10 @@ class BaseKeyeModule(nn.Module):
1471 self,
1472 input_ids: torch.Tensor,
1473 positions: torch.Tensor,
1498 - intermediate_tensors: Optional[IntermediateTensors] = None,
1499 - inputs_embeds: Optional[torch.Tensor] = None,
1474 + intermediate_tensors: IntermediateTensors | None = None,
1475 + inputs_embeds: torch.Tensor | None = None,
1476 **kwargs: object,
1501 - ) -> Union[torch.Tensor, IntermediateTensors]:
1477 + ) -> torch.Tensor | IntermediateTensors:
1478 """Run forward pass for Keye-VL.
1479
1480 Args:
@@ -1527,7 +1503,7 @@ class BaseKeyeModule(nn.Module):
1503 def compute_logits(
1504 self,
1505 hidden_states: torch.Tensor,
1530 - ) -> Optional[torch.Tensor]:
1506 + ) -> torch.Tensor | None:
1507 return self.language_model.compute_logits(hidden_states)
1508
1509 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
@@ -1555,14 +1531,14 @@ class KeyeForConditionalGeneration(
1531 self,
1532 text_config: PretrainedConfig,
1533 vision_config: PretrainedConfig,
1558 - quant_config: Optional[QuantizationConfig] = None,
1534 + quant_config: QuantizationConfig | None = None,
1535 prefix: str = "",
1536 ) -> nn.Module:
1537 return Projector(text_config, vision_config, quant_config, prefix)
1538
1539 def _parse_and_validate_image_input(
1540 self, **kwargs: object
1565 - ) -> Optional[KeyeImageInputs]:
1541 + ) -> KeyeImageInputs | None:
1542 pixel_values = kwargs.pop("pixel_values", None)
1543 image_embeds = kwargs.pop("image_embeds", None)
1544 image_grid_thw = kwargs.pop("image_grid_thw", None)
@@ -1586,7 +1562,7 @@ class KeyeForConditionalGeneration(
1562
1563 def _parse_and_validate_video_input(
1564 self, **kwargs: object
1589 - ) -> Optional[KeyeVideoInputs]:
1565 + ) -> KeyeVideoInputs | None:
1566 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
1567 video_embeds = kwargs.pop("video_embeds", None)
1568 video_grid_thw = kwargs.pop("video_grid_thw", None)
vllm/model_executor/models/keye_vl1_5.py
+23 -19
@@ -3,7 +3,7 @@
3 import itertools
4 from collections.abc import Mapping, Sequence
5 from functools import partial
6 -from typing import Annotated, Any, Literal, Optional, Union
6 +from typing import Annotated, Any, Literal, TypeAlias
7
8 import numpy as np
9 import torch
@@ -73,7 +73,7 @@ def split_thw(grid_thw: torch.Tensor) -> torch.Tensor:
73
74
75 def get_num_patches(
76 - grid_thw: torch.Tensor, num_frames: Union[list[int], torch.Tensor]
76 + grid_thw: torch.Tensor, num_frames: list[int] | torch.Tensor
77 ) -> list[int]:
78 """
79 Return num_patches per video.
@@ -153,7 +153,9 @@ class KeyeVL1_5ImageEmbeddingInputs(TensorSchema):
153 image_grid_thw: Annotated[torch.Tensor, TensorShape("ni", 3)]
154
155
156 -KeyeVL1_5ImageInputs = Union[KeyeVL1_5ImagePixelInputs, KeyeVL1_5ImageEmbeddingInputs]
156 +KeyeVL1_5ImageInputs: TypeAlias = (
157 + KeyeVL1_5ImagePixelInputs | KeyeVL1_5ImageEmbeddingInputs
158 +)
159
160
161 class KeyeVL1_5VideoPixelInputs(TensorSchema):
@@ -191,7 +193,9 @@ class KeyeVL1_5VideoEmbeddingInputs(TensorSchema):
193 num_frames: torch.Tensor
194
195
194 -KeyeVL1_5VideoInputs = Union[KeyeVL1_5VideoPixelInputs, KeyeVL1_5VideoEmbeddingInputs]
196 +KeyeVL1_5VideoInputs: TypeAlias = (
197 + KeyeVL1_5VideoPixelInputs | KeyeVL1_5VideoEmbeddingInputs
198 +)
199
200
201 class KeyeVL1_5Projector(nn.Module):
@@ -199,7 +203,7 @@ class KeyeVL1_5Projector(nn.Module):
203 self,
204 text_config: PretrainedConfig,
205 vision_config: PretrainedConfig,
202 - quant_config: Optional[QuantizationConfig] = None,
206 + quant_config: QuantizationConfig | None = None,
207 prefix: str = "",
208 ):
209 super().__init__()
@@ -233,9 +237,9 @@ class KeyeVL1_5Projector(nn.Module):
237
238 def forward(
239 self,
236 - image_features: Union[torch.Tensor, tuple[torch.Tensor], list[torch.Tensor]],
240 + image_features: torch.Tensor | tuple[torch.Tensor] | list[torch.Tensor],
241 image_grid_thw: list[tuple[int, int, int]],
238 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
242 + ) -> torch.Tensor | list[torch.Tensor]:
243 m1, m2 = self.merge_kernel_size
244 if isinstance(image_features, (list, tuple)):
245 processed_features = list()
@@ -275,7 +279,7 @@ class KeyeVL1_5ProcessingInfo(KeyeProcessingInfo):
279
280 def get_supported_mm_limits(
281 self,
278 - ) -> Mapping[str, Optional[int]]:
282 + ) -> Mapping[str, int | None]:
283 return {"image": None, "video": 1}
284
285
@@ -327,7 +331,7 @@ def _keye_field_config(
331 class KeyeVL1_5MultiModalDataParser(MultiModalDataParser):
332 def _parse_image_data(
333 self,
330 - data: Union[dict[str, torch.Tensor], ModalityData[ImageItem]],
334 + data: dict[str, torch.Tensor] | ModalityData[ImageItem],
335 ) -> ModalityDataItems[Any, Any]:
336 if isinstance(data, dict):
337 return DictEmbeddingItems(
@@ -344,7 +348,7 @@ class KeyeVL1_5MultiModalDataParser(MultiModalDataParser):
348
349 def _parse_video_data(
350 self,
347 - data: Union[dict[str, torch.Tensor], ModalityData[VideoItem]],
351 + data: dict[str, torch.Tensor] | ModalityData[VideoItem],
352 ) -> ModalityDataItems[Any, Any]:
353 if isinstance(data, dict):
354 return DictEmbeddingItems(
@@ -499,7 +503,7 @@ class KeyeVL1_5ForConditionalGeneration(
503 self,
504 text_config: PretrainedConfig,
505 vision_config: PretrainedConfig,
502 - quant_config: Optional[QuantizationConfig] = None,
506 + quant_config: QuantizationConfig | None = None,
507 prefix: str = "",
508 ) -> nn.Module:
509 return KeyeVL1_5Projector(text_config, vision_config, quant_config, prefix)
@@ -511,7 +515,7 @@ class KeyeVL1_5ForConditionalGeneration(
515
516 def _parse_and_validate_image_input(
517 self, **kwargs: object
514 - ) -> Optional[KeyeVL1_5ImageInputs]:
518 + ) -> KeyeVL1_5ImageInputs | None:
519 pixel_values = kwargs.pop("pixel_values", None)
520 image_embeds = kwargs.pop("image_embeds", None)
521 image_grid_thw = kwargs.pop("image_grid_thw", None)
@@ -535,7 +539,7 @@ class KeyeVL1_5ForConditionalGeneration(
539
540 def _parse_and_validate_video_input(
541 self, **kwargs: object
538 - ) -> Optional[KeyeVL1_5VideoInputs]:
542 + ) -> KeyeVL1_5VideoInputs | None:
543 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
544 video_embeds = kwargs.pop("video_embeds", None)
545 video_grid_thw = kwargs.pop("video_grid_thw", None)
@@ -595,19 +599,19 @@ class KeyeVL1_5ForConditionalGeneration(
599 cls,
600 input_tokens: list[int],
601 hf_config: PretrainedConfig,
598 - image_grid_thw: Union[list[list[int]], torch.Tensor],
599 - video_grid_thw: Union[list[list[int]], torch.Tensor],
602 + image_grid_thw: list[list[int]] | torch.Tensor,
603 + video_grid_thw: list[list[int]] | torch.Tensor,
604 context_len: int = 0,
601 - seq_len: Optional[int] = None,
602 - second_per_grid_ts: Optional[list[float]] = None,
603 - audio_feature_lengths: Optional[torch.Tensor] = None,
605 + seq_len: int | None = None,
606 + second_per_grid_ts: list[float] | None = None,
607 + audio_feature_lengths: torch.Tensor | None = None,
608 use_audio_in_video: bool = False,
609 ) -> tuple[torch.Tensor, int]:
610 if isinstance(video_grid_thw, list) and len(video_grid_thw) > 0:
611 video_grid_thw = video_grid_thw[0]
612 """Get mrope input positions and delta value (Keye series)."""
613
610 - def split_thw(grid_thw: Union[torch.Tensor, list[int]]) -> list[list[int]]:
614 + def split_thw(grid_thw: torch.Tensor | list[int]) -> list[list[int]]:
615 """
616 Split grid_thw along the t dimension.
617
vllm/model_executor/models/kimi_vl.py
+10 -10
@@ -46,7 +46,7 @@ import copy
46 import math
47 from collections.abc import Iterable, Mapping, Sequence
48 from dataclasses import dataclass
49 -from typing import Annotated, Any, Literal, Optional, Union
49 +from typing import Annotated, Any, Literal
50
51 import torch
52 from torch import nn
@@ -153,7 +153,7 @@ class KimiVLImagePixelInputs(TensorSchema):
153 type: Literal["pixel_values"] = "pixel_values"
154
155 pixel_values: Annotated[
156 - Union[torch.Tensor, list[torch.Tensor]],
156 + torch.Tensor | list[torch.Tensor],
157 TensorShape("np", 3, "ps", "ps"),
158 ]
159
@@ -169,7 +169,7 @@ class KimiVLProcessingInfo(BaseProcessingInfo):
169 def get_hf_config(self):
170 return self.ctx.get_hf_config(KimiVLConfig)
171
172 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
172 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
173 return {"image": None}
174
175 def get_num_image_tokens(
@@ -227,7 +227,7 @@ class KimiVLDummyInputsBuilder(BaseDummyInputsBuilder[KimiVLProcessingInfo]):
227 self,
228 seq_len: int,
229 mm_counts: Mapping[str, int],
230 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
230 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
231 ) -> MultiModalDataDict:
232 num_images = mm_counts.get("image", 0)
233
@@ -305,7 +305,7 @@ class KimiVLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
305 supports_encoder_tp_data = True
306
307 @classmethod
308 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
308 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
309 if modality.startswith("image"):
310 return "<|media_start|>image<|media_content|><|media_pad|><|media_end|>"
311
@@ -370,7 +370,7 @@ class KimiVLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
370
371 def _parse_and_validate_image_input(
372 self, **kwargs: object
373 - ) -> Optional[KimiVLImageInputs]:
373 + ) -> KimiVLImageInputs | None:
374 # image input type must be pixel values now
375 pixel_values = kwargs.pop("pixel_values", None)
376 image_grid_hws = kwargs.pop("image_grid_hws", None)
@@ -411,7 +411,7 @@ class KimiVLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
411 def get_language_model(self) -> torch.nn.Module:
412 return self.language_model
413
414 - def get_multimodal_embeddings(self, **kwargs: object) -> Optional[NestedTensors]:
414 + def get_multimodal_embeddings(self, **kwargs: object) -> NestedTensors | None:
415 # Validate the multimodal input keyword arguments
416 image_input = self._parse_and_validate_image_input(**kwargs)
417 if image_input is None:
@@ -425,8 +425,8 @@ class KimiVLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
425 self,
426 input_ids: torch.Tensor,
427 positions: torch.Tensor,
428 - intermediate_tensors: Optional[IntermediateTensors] = None,
429 - inputs_embeds: Optional[torch.Tensor] = None,
428 + intermediate_tensors: IntermediateTensors | None = None,
429 + inputs_embeds: torch.Tensor | None = None,
430 **kwargs: object,
431 ) -> IntermediateTensors:
432 if intermediate_tensors is not None:
@@ -570,7 +570,7 @@ class KimiVLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
570
571 def get_spec_layer_idx_from_weight_name(
572 config: DeepseekV2Config, weight_name: str
573 -) -> Optional[int]:
573 +) -> int | None:
574 if hasattr(config, "num_nextn_predict_layers") and (
575 config.num_nextn_predict_layers > 0
576 ):
vllm/model_executor/models/lfm2.py
+18 -18
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable
4 from itertools import islice
5 -from typing import Any, Optional
5 +from typing import Any
6
7 import torch
8 import torch.nn as nn
@@ -54,8 +54,8 @@ class Lfm2MLP(nn.Module):
54 ff_dim: int,
55 multiple_of: int,
56 auto_adjust_ff_dim: bool,
57 - ffn_dim_multiplier: Optional[float],
58 - quant_config: Optional[QuantizationConfig] = None,
57 + ffn_dim_multiplier: float | None,
58 + quant_config: QuantizationConfig | None = None,
59 prefix: str = "",
60 ):
61 super().__init__()
@@ -98,10 +98,10 @@ class Lfm2Attention(nn.Module):
98 num_heads: int,
99 num_kv_heads: int,
100 rope_theta: float = 10000,
101 - rope_scaling: Optional[dict[str, Any]] = None,
101 + rope_scaling: dict[str, Any] | None = None,
102 max_position_embeddings: int = 8192,
103 - cache_config: Optional[CacheConfig] = None,
104 - quant_config: Optional[QuantizationConfig] = None,
103 + cache_config: CacheConfig | None = None,
104 + quant_config: QuantizationConfig | None = None,
105 prefix: str = "",
106 ) -> None:
107 super().__init__()
@@ -190,9 +190,9 @@ class Lfm2AttentionDecoderLayer(nn.Module):
190 self,
191 config: Lfm2Config,
192 layer_idx: int,
193 - model_config: Optional[ModelConfig] = None,
194 - cache_config: Optional[CacheConfig] = None,
195 - quant_config: Optional[QuantizationConfig] = None,
193 + model_config: ModelConfig | None = None,
194 + cache_config: CacheConfig | None = None,
195 + quant_config: QuantizationConfig | None = None,
196 prefix: str = "",
197 ) -> None:
198 super().__init__()
@@ -240,7 +240,7 @@ class Lfm2AttentionDecoderLayer(nn.Module):
240 self,
241 positions: torch.Tensor,
242 hidden_states: torch.Tensor,
243 - residual: Optional[torch.Tensor],
243 + residual: torch.Tensor | None,
244 **kwargs,
245 ) -> tuple[torch.Tensor, torch.Tensor]:
246 if residual is None:
@@ -258,9 +258,9 @@ class Lfm2ShortConvDecoderLayer(nn.Module):
258 self,
259 config: Lfm2Config,
260 layer_idx: int,
261 - model_config: Optional[ModelConfig] = None,
262 - cache_config: Optional[CacheConfig] = None,
263 - quant_config: Optional[QuantizationConfig] = None,
261 + model_config: ModelConfig | None = None,
262 + cache_config: CacheConfig | None = None,
263 + quant_config: QuantizationConfig | None = None,
264 prefix: str = "",
265 ) -> None:
266 super().__init__()
@@ -289,7 +289,7 @@ class Lfm2ShortConvDecoderLayer(nn.Module):
289 def forward(
290 self,
291 hidden_states: torch.Tensor,
292 - residual: Optional[torch.Tensor],
292 + residual: torch.Tensor | None,
293 **kwargs,
294 ):
295 if residual is None:
@@ -365,8 +365,8 @@ class Lfm2Model(nn.Module):
365 self,
366 input_ids: torch.Tensor,
367 positions: torch.Tensor,
368 - intermediate_tensors: Optional[IntermediateTensors] = None,
369 - inputs_embeds: Optional[torch.Tensor] = None,
368 + intermediate_tensors: IntermediateTensors | None = None,
369 + inputs_embeds: torch.Tensor | None = None,
370 ) -> torch.Tensor:
371 if get_pp_group().is_first_rank:
372 if inputs_embeds is not None:
@@ -532,8 +532,8 @@ class Lfm2ForCausalLM(
532 self,
533 input_ids: torch.Tensor,
534 positions: torch.Tensor,
535 - intermediate_tensors: Optional[IntermediateTensors] = None,
536 - inputs_embeds: Optional[torch.Tensor] = None,
535 + intermediate_tensors: IntermediateTensors | None = None,
536 + inputs_embeds: torch.Tensor | None = None,
537 **kwargs,
538 ) -> torch.Tensor:
539 hidden_states = self.model(
vllm/model_executor/models/lfm2_moe.py
+18 -18
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable
4 from itertools import islice
5 -from typing import Any, Optional
5 +from typing import Any
6
7 import torch
8 import torch.nn as nn
@@ -65,7 +65,7 @@ class Lfm2MoeMlp(nn.Module):
65 self,
66 dim: int,
67 ff_dim: int,
68 - quant_config: Optional[QuantizationConfig] = None,
68 + quant_config: QuantizationConfig | None = None,
69 prefix: str = "",
70 ):
71 super().__init__()
@@ -96,7 +96,7 @@ class Lfm2MoeSparseMoeBlock(nn.Module):
96 def __init__(
97 self,
98 config: Lfm2MoeConfig,
99 - quant_config: Optional[QuantizationConfig] = None,
99 + quant_config: QuantizationConfig | None = None,
100 prefix: str = "",
101 enable_eplb: bool = False,
102 ):
@@ -191,10 +191,10 @@ class Lfm2MoeAttention(nn.Module):
191 num_heads: int,
192 num_kv_heads: int,
193 rope_theta: float = 10000,
194 - rope_scaling: Optional[dict[str, Any]] = None,
194 + rope_scaling: dict[str, Any] | None = None,
195 max_position_embeddings: int = 8192,
196 - cache_config: Optional[CacheConfig] = None,
197 - quant_config: Optional[QuantizationConfig] = None,
196 + cache_config: CacheConfig | None = None,
197 + quant_config: QuantizationConfig | None = None,
198 prefix: str = "",
199 ) -> None:
200 super().__init__()
@@ -283,9 +283,9 @@ class Lfm2MoeAttentionDecoderLayer(nn.Module):
283 self,
284 config: Lfm2MoeConfig,
285 layer_idx: int,
286 - model_config: Optional[ModelConfig] = None,
287 - cache_config: Optional[CacheConfig] = None,
288 - quant_config: Optional[QuantizationConfig] = None,
286 + model_config: ModelConfig | None = None,
287 + cache_config: CacheConfig | None = None,
288 + quant_config: QuantizationConfig | None = None,
289 prefix: str = "",
290 enable_eplb: bool = False,
291 ) -> None:
@@ -340,7 +340,7 @@ class Lfm2MoeAttentionDecoderLayer(nn.Module):
340 self,
341 positions: torch.Tensor,
342 hidden_states: torch.Tensor,
343 - residual: Optional[torch.Tensor],
343 + residual: torch.Tensor | None,
344 **kwargs,
345 ) -> tuple[torch.Tensor, torch.Tensor]:
346 if residual is None:
@@ -358,9 +358,9 @@ class Lfm2MoeShortConvDecoderLayer(nn.Module):
358 self,
359 config: Lfm2MoeConfig,
360 layer_idx: int,
361 - model_config: Optional[ModelConfig] = None,
362 - cache_config: Optional[CacheConfig] = None,
363 - quant_config: Optional[QuantizationConfig] = None,
361 + model_config: ModelConfig | None = None,
362 + cache_config: CacheConfig | None = None,
363 + quant_config: QuantizationConfig | None = None,
364 prefix: str = "",
365 enable_eplb: bool = False,
366 ) -> None:
@@ -396,7 +396,7 @@ class Lfm2MoeShortConvDecoderLayer(nn.Module):
396 def forward(
397 self,
398 hidden_states: torch.Tensor,
399 - residual: Optional[torch.Tensor],
399 + residual: torch.Tensor | None,
400 **kwargs,
401 ):
402 if residual is None:
@@ -479,8 +479,8 @@ class Lfm2MoeModel(nn.Module):
479 self,
480 input_ids: torch.Tensor,
481 positions: torch.Tensor,
482 - intermediate_tensors: Optional[IntermediateTensors] = None,
483 - inputs_embeds: Optional[torch.Tensor] = None,
482 + intermediate_tensors: IntermediateTensors | None = None,
483 + inputs_embeds: torch.Tensor | None = None,
484 ) -> torch.Tensor:
485 if get_pp_group().is_first_rank:
486 if inputs_embeds is not None:
@@ -774,8 +774,8 @@ class Lfm2MoeForCausalLM(
774 self,
775 input_ids: torch.Tensor,
776 positions: torch.Tensor,
777 - intermediate_tensors: Optional[IntermediateTensors] = None,
778 - inputs_embeds: Optional[torch.Tensor] = None,
777 + intermediate_tensors: IntermediateTensors | None = None,
778 + inputs_embeds: torch.Tensor | None = None,
779 **kwargs,
780 ) -> torch.Tensor:
781 hidden_states = self.model(
vllm/model_executor/models/llama.py
+18 -20
@@ -26,7 +26,7 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Any, Optional, Union
29 +from typing import Any
30
31 import torch
32 from torch import nn
@@ -76,7 +76,7 @@ class LlamaMLP(nn.Module):
76 hidden_size: int,
77 intermediate_size: int,
78 hidden_act: str,
79 - quant_config: Optional[QuantizationConfig] = None,
79 + quant_config: QuantizationConfig | None = None,
80 bias: bool = False,
81 prefix: str = "",
82 reduce_results: bool = True,
@@ -121,12 +121,12 @@ class LlamaAttention(nn.Module):
121 num_heads: int,
122 num_kv_heads: int,
123 rope_theta: float = 10000,
124 - rope_scaling: Optional[dict[str, Any]] = None,
124 + rope_scaling: dict[str, Any] | None = None,
125 max_position_embeddings: int = 8192,
126 - quant_config: Optional[QuantizationConfig] = None,
126 + quant_config: QuantizationConfig | None = None,
127 bias: bool = False,
128 bias_o_proj: bool = False,
129 - cache_config: Optional[CacheConfig] = None,
129 + cache_config: CacheConfig | None = None,
130 prefix: str = "",
131 attn_type: str = AttentionType.DECODER,
132 ) -> None:
@@ -236,8 +236,8 @@ class LlamaAttention(nn.Module):
236 def _init_rotary_emb(
237 self,
238 config: LlamaConfig,
239 - rope_scaling: Optional[dict[str, Any]],
240 - quant_config: Optional[QuantizationConfig],
239 + rope_scaling: dict[str, Any] | None,
240 + quant_config: QuantizationConfig | None,
241 ) -> None:
242 is_neox_style = True
243 is_gguf = quant_config and quant_config.get_name() == "gguf"
@@ -260,7 +260,7 @@ class LlamaDecoderLayer(nn.Module):
260 self,
261 vllm_config: VllmConfig,
262 prefix: str = "",
263 - config: Optional[LlamaConfig] = None,
263 + config: LlamaConfig | None = None,
264 ) -> None:
265 super().__init__()
266
@@ -331,7 +331,7 @@ class LlamaDecoderLayer(nn.Module):
331 self,
332 positions: torch.Tensor,
333 hidden_states: torch.Tensor,
334 - residual: Optional[torch.Tensor],
334 + residual: torch.Tensor | None,
335 ) -> tuple[torch.Tensor, torch.Tensor]:
336 # Self Attention
337 if residual is None:
@@ -346,7 +346,7 @@ class LlamaDecoderLayer(nn.Module):
346 hidden_states = self.mlp(hidden_states)
347 return hidden_states, residual
348
349 - def get_quant_config(self, vllm_config: VllmConfig) -> Optional[QuantizationConfig]:
349 + def get_quant_config(self, vllm_config: VllmConfig) -> QuantizationConfig | None:
350 """Get quantization config for this layer. Override in subclasses."""
351 return vllm_config.quant_config
352
@@ -407,13 +407,11 @@ class LlamaModel(nn.Module):
407
408 def forward(
409 self,
410 - input_ids: Optional[torch.Tensor],
410 + input_ids: torch.Tensor | None,
411 positions: torch.Tensor,
412 - intermediate_tensors: Optional[IntermediateTensors],
413 - inputs_embeds: Optional[torch.Tensor] = None,
414 - ) -> Union[
415 - torch.Tensor, IntermediateTensors, tuple[torch.Tensor, list[torch.Tensor]]
416 - ]:
412 + intermediate_tensors: IntermediateTensors | None,
413 + inputs_embeds: torch.Tensor | None = None,
414 + ) -> torch.Tensor | IntermediateTensors | tuple[torch.Tensor, list[torch.Tensor]]:
415 if get_pp_group().is_first_rank:
416 if inputs_embeds is not None:
417 hidden_states = inputs_embeds
@@ -627,9 +625,9 @@ class LlamaForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3):
625 self,
626 input_ids: torch.Tensor,
627 positions: torch.Tensor,
630 - intermediate_tensors: Optional[IntermediateTensors] = None,
631 - inputs_embeds: Optional[torch.Tensor] = None,
632 - ) -> Union[torch.Tensor, IntermediateTensors]:
628 + intermediate_tensors: IntermediateTensors | None = None,
629 + inputs_embeds: torch.Tensor | None = None,
630 + ) -> torch.Tensor | IntermediateTensors:
631 model_output = self.model(
632 input_ids, positions, intermediate_tensors, inputs_embeds
633 )
@@ -638,7 +636,7 @@ class LlamaForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3):
636 def compute_logits(
637 self,
638 hidden_states: torch.Tensor,
641 - ) -> Optional[torch.Tensor]:
639 + ) -> torch.Tensor | None:
640 logits = self.logits_processor(self.lm_head, hidden_states)
641 return logits
642
vllm/model_executor/models/llama4.py
+6 -6
@@ -19,7 +19,7 @@
19 """Inference-only LLaMA model compatible with HuggingFace weights."""
20
21 from collections.abc import Iterable
22 -from typing import Any, Optional
22 +from typing import Any
23
24 import torch
25 from torch import nn
@@ -148,12 +148,12 @@ class Llama4Attention(nn.Module):
148 num_heads: int,
149 num_kv_heads: int,
150 rope_theta: float = 10000,
151 - rope_scaling: Optional[dict[str, Any]] = None,
151 + rope_scaling: dict[str, Any] | None = None,
152 max_position_embeddings: int = 8192,
153 - quant_config: Optional[QuantizationConfig] = None,
153 + quant_config: QuantizationConfig | None = None,
154 bias: bool = False,
155 bias_o_proj: bool = False,
156 - cache_config: Optional[CacheConfig] = None,
156 + cache_config: CacheConfig | None = None,
157 prefix: str = "",
158 ) -> None:
159 super().__init__()
@@ -296,7 +296,7 @@ class Llama4DecoderLayer(nn.Module):
296 self,
297 vllm_config: VllmConfig,
298 prefix: str = "",
299 - config: Optional[Llama4TextConfig] = None,
299 + config: Llama4TextConfig | None = None,
300 ) -> None:
301 super().__init__()
302
@@ -352,7 +352,7 @@ class Llama4DecoderLayer(nn.Module):
352 self,
353 positions: torch.Tensor,
354 hidden_states: torch.Tensor,
355 - residual: Optional[torch.Tensor],
355 + residual: torch.Tensor | None,
356 ) -> tuple[torch.Tensor, torch.Tensor]:
357 # Self Attention
358 if residual is None:
vllm/model_executor/models/llama4_eagle.py
+5 -6
@@ -17,7 +17,6 @@
17 # limitations under the License.
18
19 from collections.abc import Iterable
20 -from typing import Optional
20
21 import torch
22 import torch.nn as nn
@@ -49,7 +48,7 @@ class LlamaModel(nn.Module):
48 vllm_config: VllmConfig,
49 prefix: str = "",
50 start_layer_id: int = 0,
52 - quant_config: Optional[QuantizationConfig] = None,
51 + quant_config: QuantizationConfig | None = None,
52 ) -> None:
53 super().__init__()
54 self.config = vllm_config.speculative_config.draft_model_config.hf_config
@@ -81,10 +80,10 @@ class LlamaModel(nn.Module):
80
81 def forward(
82 self,
84 - input_ids: Optional[torch.Tensor],
83 + input_ids: torch.Tensor | None,
84 positions: torch.Tensor,
85 hidden_states: torch.Tensor,
87 - inputs_embeds: Optional[torch.Tensor] = None,
86 + inputs_embeds: torch.Tensor | None = None,
87 ) -> tuple[torch.Tensor, torch.Tensor]:
88 if inputs_embeds is None:
89 inputs_embeds = self.get_input_embeddings(input_ids)
@@ -136,7 +135,7 @@ class LlamaModel(nn.Module):
135 return loaded_params
136
137 def validate_and_update_config(
139 - self, start_layer_id: int, quant_config: Optional[QuantizationConfig] = None
138 + self, start_layer_id: int, quant_config: QuantizationConfig | None = None
139 ) -> None:
140 # yoco and moe is not supported by draft model yet
141 assert self.config.yoco_global_kv_layer is None
@@ -193,7 +192,7 @@ class EagleLlama4ForCausalLM(Llama4ForCausalLM):
192 input_ids: torch.Tensor,
193 positions: torch.Tensor,
194 hidden_states: torch.Tensor,
196 - inputs_embeds: Optional[torch.Tensor] = None,
195 + inputs_embeds: torch.Tensor | None = None,
196 ) -> tuple[torch.Tensor, torch.Tensor]:
197 return self.model(input_ids, positions, hidden_states, inputs_embeds)
198
vllm/model_executor/models/llama_eagle.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable
5 -from typing import Optional
5
6 import torch
7 import torch.nn as nn
@@ -28,7 +27,7 @@ class LlamaDecoderLayer(LlamaDecoderLayer):
27 vllm_config: VllmConfig,
28 disable_input_layernorm: bool,
29 prefix: str = "",
31 - config: Optional[LlamaConfig] = None,
30 + config: LlamaConfig | None = None,
31 ) -> None:
32 super().__init__(vllm_config, prefix=prefix, config=config)
33
@@ -155,7 +154,7 @@ class EagleLlamaForCausalLM(LlamaForCausalLM):
154 input_ids: torch.Tensor,
155 positions: torch.Tensor,
156 hidden_states: torch.Tensor,
158 - inputs_embeds: Optional[torch.Tensor] = None,
157 + inputs_embeds: torch.Tensor | None = None,
158 ) -> tuple[torch.Tensor, torch.Tensor]:
159 if inputs_embeds is not None:
160 raise NotImplementedError(
vllm/model_executor/models/llama_eagle3.py
+8 -9
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable
5 -from typing import Optional
5
6 import torch
7 import torch.nn as nn
@@ -35,7 +34,7 @@ class LlamaDecoderLayer(LlamaDecoderLayer):
34 self,
35 vllm_config: VllmConfig,
36 prefix: str = "",
38 - config: Optional[LlamaConfig] = None,
37 + config: LlamaConfig | None = None,
38 layer_idx: int = 0,
39 ) -> None:
40 super().__init__(vllm_config, prefix=prefix, config=config)
@@ -66,7 +65,7 @@ class LlamaDecoderLayer(LlamaDecoderLayer):
65 else:
66 self._residual_norm = self._norm_after_residual
67
69 - def get_quant_config(self, vllm_config: VllmConfig) -> Optional[QuantizationConfig]:
68 + def get_quant_config(self, vllm_config: VllmConfig) -> QuantizationConfig | None:
69 """Use drafter's quantization config instead of verifier's."""
70 draft_model_config = vllm_config.speculative_config.draft_model_config
71 draft_load_config = vllm_config.load_config
@@ -96,7 +95,7 @@ class LlamaDecoderLayer(LlamaDecoderLayer):
95 positions: torch.Tensor,
96 embeds: torch.Tensor,
97 hidden_states: torch.Tensor,
99 - residual: Optional[torch.Tensor],
98 + residual: torch.Tensor | None,
99 ) -> tuple[torch.Tensor, torch.Tensor]:
100 if self.layer_idx == 0:
101 # First layer: concatenate embeds with hidden_states
@@ -182,7 +181,7 @@ class LlamaModel(nn.Module):
181 input_ids: torch.Tensor,
182 positions: torch.Tensor,
183 hidden_states: torch.Tensor,
185 - input_embeds: Optional[torch.Tensor] = None,
184 + input_embeds: torch.Tensor | None = None,
185 ) -> tuple[torch.Tensor, torch.Tensor]:
186 if input_embeds is None:
187 input_embeds = self.get_input_embeddings(input_ids)
@@ -268,8 +267,8 @@ class Eagle3LlamaForCausalLM(LlamaForCausalLM):
267 def get_input_embeddings(
268 self,
269 input_ids: torch.Tensor,
271 - multimodal_embeddings: Optional[NestedTensors] = None,
272 - is_multimodal: Optional[torch.Tensor] = None,
270 + multimodal_embeddings: NestedTensors | None = None,
271 + is_multimodal: torch.Tensor | None = None,
272 ) -> torch.Tensor:
273 return self.model.get_input_embeddings(input_ids)
274
@@ -278,14 +277,14 @@ class Eagle3LlamaForCausalLM(LlamaForCausalLM):
277 input_ids: torch.Tensor,
278 positions: torch.Tensor,
279 hidden_states: torch.Tensor,
281 - inputs_embeds: Optional[torch.Tensor] = None,
280 + inputs_embeds: torch.Tensor | None = None,
281 ) -> tuple[torch.Tensor, torch.Tensor]:
282 return self.model(input_ids, positions, hidden_states, inputs_embeds)
283
284 def compute_logits(
285 self,
286 hidden_states: torch.Tensor,
288 - ) -> Optional[torch.Tensor]:
287 + ) -> torch.Tensor | None:
288 logits = self.logits_processor(self.lm_head, hidden_states)
289 if self.draft_id_to_target_id is None:
290 assert logits.shape[1] == self.config.vocab_size, (
vllm/model_executor/models/llava.py
+28 -28
@@ -3,7 +3,7 @@
3
4 from abc import abstractmethod
5 from collections.abc import Iterable, Mapping, Sequence
6 -from typing import Annotated, Final, Literal, Optional, Protocol, TypeVar, Union
6 +from typing import Annotated, Final, Literal, Protocol, TypeAlias, TypeVar
7
8 import torch
9 import torch.nn as nn
@@ -93,7 +93,7 @@ class PixtralHFImagePixelInputs(TensorSchema):
93
94 type: Literal["pixel_values_pixtral"] = "pixel_values_pixtral"
95 pixel_values: Annotated[
96 - Union[torch.Tensor, list[torch.Tensor]],
96 + torch.Tensor | list[torch.Tensor],
97 TensorShape("bn", "c", "h", "w", dynamic_dims={"h", "w"}),
98 ]
99
@@ -110,9 +110,9 @@ class LlavaImageEmbeddingInputs(TensorSchema):
110 data: Annotated[torch.Tensor, TensorShape("bn", "ifs", "hs")]
111
112
113 -LlavaImageInputs = Union[
114 - LlavaImagePixelInputs, PixtralHFImagePixelInputs, LlavaImageEmbeddingInputs
115 -]
113 +LlavaImageInputs: TypeAlias = (
114 + LlavaImagePixelInputs | PixtralHFImagePixelInputs | LlavaImageEmbeddingInputs
115 +)
116
117
118 class LlavaMultiModalProjector(nn.Module):
@@ -122,7 +122,7 @@ class LlavaMultiModalProjector(nn.Module):
122 text_hidden_size: int,
123 projector_hidden_act: str,
124 multimodal_projector_bias: bool,
125 - quant_config: Optional[QuantizationConfig] = None,
125 + quant_config: QuantizationConfig | None = None,
126 prefix: str = "",
127 ):
128 super().__init__()
@@ -154,7 +154,7 @@ class LlavaLikeConfig(Protocol):
154 vision_config: Final[PretrainedConfig]
155 image_token_index: Final[int]
156 vision_feature_select_strategy: Final[str]
157 - vision_feature_layer: Final[Union[int, list[int]]]
157 + vision_feature_layer: Final[int | list[int]]
158
159
160 class LlavaLikeProcessor(Protocol):
@@ -172,7 +172,7 @@ class BaseLlavaProcessingInfo(BaseProcessingInfo):
172 def get_hf_processor(self, **kwargs: object) -> LlavaLikeProcessor:
173 raise NotImplementedError
174
175 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
175 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
176 return {"image": None}
177
178 def get_num_image_tokens(
@@ -222,7 +222,7 @@ class LlavaDummyInputsBuilder(BaseDummyInputsBuilder[_I]):
222 self,
223 seq_len: int,
224 mm_counts: Mapping[str, int],
225 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
225 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
226 ) -> MultiModalDataDict:
227 num_images = mm_counts.get("image", 0)
228
@@ -406,7 +406,7 @@ def _build_llava_or_pixtral_hf_processor(
406 info: _I,
407 dummy_inputs: BaseDummyInputsBuilder[_I],
408 *,
409 - cache: Optional[BaseMultiModalProcessorCache] = None,
409 + cache: BaseMultiModalProcessorCache | None = None,
410 ) -> BaseMultiModalProcessor:
411 if isinstance(info, PixtralHFProcessingInfo):
412 return PixtralHFMultiModalProcessor(
@@ -461,11 +461,11 @@ def _get_layer_index(feature_layer_index: int, num_hidden_layers: int) -> int:
461
462 def init_vision_tower_for_llava(
463 hf_config: LlavaLikeConfig,
464 - quant_config: Optional[QuantizationConfig],
464 + quant_config: QuantizationConfig | None,
465 *,
466 - require_post_norm: Optional[bool] = None,
466 + require_post_norm: bool | None = None,
467 prefix: str = "",
468 -) -> Union[CLIPVisionModel, SiglipVisionModel, PixtralHFVisionModel]:
468 +) -> CLIPVisionModel | SiglipVisionModel | PixtralHFVisionModel:
469 vision_config = hf_config.vision_config
470
471 # Initialize the vision tower only up to the deepest required feature layer
@@ -524,7 +524,7 @@ class LlavaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
524 )
525
526 @classmethod
527 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
527 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
528 if modality.startswith("image"):
529 return "<image>"
530
@@ -585,7 +585,7 @@ class LlavaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
585
586 def _parse_and_validate_image_input(
587 self, **kwargs: object
588 - ) -> Optional[LlavaImageInputs]:
588 + ) -> LlavaImageInputs | None:
589 pixel_values = kwargs.pop("pixel_values", None)
590 image_embeds = kwargs.pop("image_embeds", None)
591
@@ -619,9 +619,9 @@ class LlavaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
619
620 def _image_pixels_to_features(
621 self,
622 - vision_tower: Union[CLIPVisionModel, SiglipVisionModel, PixtralHFVisionModel],
623 - pixel_values: Union[torch.Tensor, list[torch.Tensor]],
624 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
622 + vision_tower: CLIPVisionModel | SiglipVisionModel | PixtralHFVisionModel,
623 + pixel_values: torch.Tensor | list[torch.Tensor],
624 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
625 # NOTE: we skip the step to select the vision feature layer since
626 # this is already done inside the vision tower
627 return vision_tower(
@@ -631,8 +631,8 @@ class LlavaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
631
632 def _process_image_pixels(
633 self,
634 - inputs: Union[LlavaImagePixelInputs, PixtralHFImagePixelInputs],
635 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
634 + inputs: LlavaImagePixelInputs | PixtralHFImagePixelInputs,
635 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
636 assert self.vision_tower is not None
637
638 pixel_values = inputs["pixel_values"]
@@ -642,7 +642,7 @@ class LlavaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
642 def _process_image_input(
643 self,
644 image_input: LlavaImageInputs,
645 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
645 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
646 if image_input["type"] == "image_embeds":
647 return image_input["data"]
648
@@ -672,10 +672,10 @@ class LlavaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
672 self,
673 input_ids: torch.Tensor,
674 positions: torch.Tensor,
675 - intermediate_tensors: Optional[IntermediateTensors] = None,
676 - inputs_embeds: Optional[torch.Tensor] = None,
675 + intermediate_tensors: IntermediateTensors | None = None,
676 + inputs_embeds: torch.Tensor | None = None,
677 **kwargs: object,
678 - ) -> Union[torch.Tensor, IntermediateTensors]:
678 + ) -> torch.Tensor | IntermediateTensors:
679 """Run forward pass for LLaVA-1.5.
680
681 One key thing to understand is the `input_ids` already accounts for the
@@ -725,7 +725,7 @@ class LlavaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
725 def compute_logits(
726 self,
727 hidden_states: torch.Tensor,
728 - ) -> Optional[torch.Tensor]:
728 + ) -> torch.Tensor | None:
729 return self.language_model.compute_logits(hidden_states)
730
731 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
@@ -754,11 +754,11 @@ class MantisProcessingInfo(LlavaProcessingInfo):
754 class MantisMultiModalProcessor(LlavaMultiModalProcessor):
755 def apply(
756 self,
757 - prompt: Union[str, list[int]],
757 + prompt: str | list[int],
758 mm_data: MultiModalDataDict,
759 hf_processor_mm_kwargs: Mapping[str, object],
760 - tokenization_kwargs: Optional[Mapping[str, object]] = None,
761 - mm_uuids: Optional[MultiModalUUIDDict] = None,
760 + tokenization_kwargs: Mapping[str, object] | None = None,
761 + mm_uuids: MultiModalUUIDDict | None = None,
762 ) -> MultiModalInputs:
763 hf_config = self.info.get_hf_config()
764 image_token_id = hf_config.image_token_index
vllm/model_executor/models/llava_next.py
+17 -15
@@ -3,7 +3,7 @@
3
4 from abc import abstractmethod
5 from collections.abc import Iterable, Mapping
6 -from typing import Annotated, Final, Literal, Optional, Protocol, TypeVar, Union
6 +from typing import Annotated, Final, Literal, Protocol, TypeAlias, TypeVar
7
8 import torch
9 import torch.nn as nn
@@ -55,11 +55,11 @@ class LlavaNextImagePixelInputs(TensorSchema):
55
56 type: Literal["pixel_values"] = "pixel_values"
57 pixel_values: Annotated[
58 - Union[torch.Tensor, list[torch.Tensor]],
58 + torch.Tensor | list[torch.Tensor],
59 TensorShape("bn", "np", 3, "h", "w", dynamic_dims={"np"}),
60 ]
61
62 - image_sizes: Annotated[Optional[torch.Tensor], TensorShape("bn", 2)]
62 + image_sizes: Annotated[torch.Tensor | None, TensorShape("bn", 2)]
63 # This should be in `(height, width)` format.
64
65
@@ -75,7 +75,9 @@ class LlavaNextImageEmbeddingInputs(TensorSchema):
75 data: Annotated[torch.Tensor, TensorShape("bn", "ifs", "hs")]
76
77
78 -LlavaNextImageInputs = Union[LlavaNextImagePixelInputs, LlavaNextImageEmbeddingInputs]
78 +LlavaNextImageInputs: TypeAlias = (
79 + LlavaNextImagePixelInputs | LlavaNextImageEmbeddingInputs
80 +)
81
82
83 class LlavaNextLikeConfig(LlavaLikeConfig, Protocol):
@@ -235,7 +237,7 @@ class LlavaNextForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
237 )
238
239 @classmethod
238 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
240 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
241 if modality.startswith("image"):
242 return "<image>"
243
@@ -294,7 +296,7 @@ class LlavaNextForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
296
297 def _parse_and_validate_image_input(
298 self, **kwargs: object
297 - ) -> Optional[LlavaNextImageInputs]:
299 + ) -> LlavaNextImageInputs | None:
300 pixel_values = kwargs.pop("pixel_values", None)
301 image_sizes = kwargs.pop("image_sizes", None)
302 image_embeds = kwargs.pop("image_embeds", None)
@@ -324,7 +326,7 @@ class LlavaNextForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
326
327 def _image_pixels_to_features(
328 self,
327 - vision_tower: Union[CLIPVisionModel, SiglipVisionModel],
329 + vision_tower: CLIPVisionModel | SiglipVisionModel,
330 pixel_values: torch.Tensor,
331 ) -> torch.Tensor:
332 # NOTE: we skip the step to select the vision feature layer since
@@ -424,7 +426,7 @@ class LlavaNextForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
426 def _process_image_pixels(
427 self,
428 inputs: LlavaNextImagePixelInputs,
427 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
429 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
430 assert self.vision_tower is not None
431
432 pixel_values = inputs["pixel_values"]
@@ -456,7 +458,7 @@ class LlavaNextForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
458 def _process_image_input(
459 self,
460 image_input: LlavaNextImageInputs,
459 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
461 + ) -> torch.Tensor | list[torch.Tensor]:
462 if image_input["type"] == "image_embeds":
463 return [image_input["data"]]
464
@@ -491,9 +493,9 @@ class LlavaNextForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
493 def get_input_embeddings(
494 self,
495 input_ids: torch.Tensor,
494 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
496 + multimodal_embeddings: MultiModalEmbeddings | None = None,
497 *,
496 - is_multimodal: Optional[torch.Tensor] = None,
498 + is_multimodal: torch.Tensor | None = None,
499 # Multi-modal token ID may exceed vocab size
500 handle_oov_mm_token: bool = True,
501 ) -> torch.Tensor:
@@ -512,10 +514,10 @@ class LlavaNextForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
514 self,
515 input_ids: torch.Tensor,
516 positions: torch.Tensor,
515 - intermediate_tensors: Optional[IntermediateTensors] = None,
516 - inputs_embeds: Optional[torch.Tensor] = None,
517 + intermediate_tensors: IntermediateTensors | None = None,
518 + inputs_embeds: torch.Tensor | None = None,
519 **kwargs: object,
518 - ) -> Union[torch.Tensor, IntermediateTensors]:
520 + ) -> torch.Tensor | IntermediateTensors:
521 """Run forward pass for LlaVA-NeXT.
522
523 One key thing to understand is the `input_ids` already accounts for the
@@ -573,7 +575,7 @@ model_executor.models.llava_next.LlavaNextProcessingInfo.get_num_image_tokens].
575 def compute_logits(
576 self,
577 hidden_states: torch.Tensor,
576 - ) -> Optional[torch.Tensor]:
578 + ) -> torch.Tensor | None:
579 return self.language_model.compute_logits(hidden_states)
580
581 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/llava_next_video.py
+11 -11
@@ -3,7 +3,7 @@
3
4 import math
5 from collections.abc import Iterable, Mapping, Sequence
6 -from typing import Annotated, Literal, Optional, Union
6 +from typing import Annotated, Literal
7
8 import torch
9 import torch.nn as nn
@@ -66,7 +66,7 @@ class LlavaNextVideoPixelInputs(TensorSchema):
66 type: Literal["pixel_values_videos"] = "pixel_values_videos"
67
68 pixel_values_videos: Annotated[
69 - Union[torch.Tensor, list[torch.Tensor]],
69 + torch.Tensor | list[torch.Tensor],
70 TensorShape("bn", "f", 3, "h", "w", dynamic_dims={"f"}),
71 ]
72
@@ -81,7 +81,7 @@ class LlavaNextVideoProcessingInfo(BaseProcessingInfo):
81 def get_hf_processor(self, **kwargs: object):
82 return self.ctx.get_hf_processor(LlavaNextVideoProcessor, **kwargs)
83
84 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
84 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
85 return {"video": 1}
86
87 def get_image_size_with_most_features(self) -> ImageSize:
@@ -165,7 +165,7 @@ class LlavaNextVideoDummyInputsBuilder(
165 self,
166 seq_len: int,
167 mm_counts: Mapping[str, int],
168 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
168 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
169 ) -> MultiModalDataDict:
170 num_videos = mm_counts.get("video", 0)
171
@@ -313,7 +313,7 @@ class LlavaNextVideoForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
313 )
314
315 @classmethod
316 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
316 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
317 if modality.startswith("image"):
318 return "<image>"
319 if modality.startswith("video"):
@@ -356,7 +356,7 @@ class LlavaNextVideoForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
356
357 def _parse_and_validate_video_input(
358 self, **kwargs: object
359 - ) -> Optional[LlavaNextVideoPixelInputs]:
359 + ) -> LlavaNextVideoPixelInputs | None:
360 """
361 A legal video input should have the following dimensions:
362 {
@@ -381,7 +381,7 @@ class LlavaNextVideoForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
381
382 def _video_pixels_to_features(
383 self,
384 - vision_tower: Union[CLIPVisionModel, SiglipVisionModel],
384 + vision_tower: CLIPVisionModel | SiglipVisionModel,
385 pixel_values: torch.Tensor,
386 ) -> torch.Tensor:
387 # NOTE: we skip the step to select the vision feature layer since
@@ -433,10 +433,10 @@ class LlavaNextVideoForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
433 self,
434 input_ids: torch.Tensor,
435 positions: torch.Tensor,
436 - intermediate_tensors: Optional[IntermediateTensors] = None,
437 - inputs_embeds: Optional[torch.Tensor] = None,
436 + intermediate_tensors: IntermediateTensors | None = None,
437 + inputs_embeds: torch.Tensor | None = None,
438 **kwargs: object,
439 - ) -> Union[torch.Tensor, IntermediateTensors]:
439 + ) -> torch.Tensor | IntermediateTensors:
440 """Run forward pass for LlaVA-NeXT-Video.
441 Args:
442 input_ids: Flattened (concatenated) input_ids corresponding to a
@@ -455,7 +455,7 @@ class LlavaNextVideoForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
455 def compute_logits(
456 self,
457 hidden_states: torch.Tensor,
458 - ) -> Optional[torch.Tensor]:
458 + ) -> torch.Tensor | None:
459 return self.language_model.compute_logits(hidden_states)
460
461 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/llava_onevision.py
+23 -23
@@ -3,7 +3,7 @@
3
4 import math
5 from collections.abc import Iterable, Mapping, Sequence
6 -from typing import Annotated, Final, Literal, Optional, Protocol, Union
6 +from typing import Annotated, Final, Literal, Protocol, TypeAlias
7
8 import torch
9 import torch.nn as nn
@@ -69,7 +69,7 @@ class LlavaOnevisionVideoPixelInputs(TensorSchema):
69 type: Literal["pixel_values_videos"] = "pixel_values_videos"
70
71 pixel_values_videos: Annotated[
72 - Union[torch.Tensor, list[torch.Tensor]],
72 + torch.Tensor | list[torch.Tensor],
73 TensorShape("bn", "f", 3, "h", "w", dynamic_dims={"f"}),
74 ]
75
@@ -90,11 +90,11 @@ class LlavaOnevisionImagePixelInputs(TensorSchema):
90 type: Literal["pixel_values"] = "pixel_values"
91
92 pixel_values: Annotated[
93 - Union[torch.Tensor, list[torch.Tensor]],
93 + torch.Tensor | list[torch.Tensor],
94 TensorShape("bn", "np", 3, "h", "w", dynamic_dims={"np"}),
95 ]
96
97 - image_sizes: Annotated[Optional[torch.Tensor], TensorShape("bn", 2)]
97 + image_sizes: Annotated[torch.Tensor | None, TensorShape("bn", 2)]
98
99
100 class LlavaOnevisionImageEmbeddingInputs(TensorSchema):
@@ -113,13 +113,13 @@ class LlavaOnevisionImageEmbeddingInputs(TensorSchema):
113 ]
114
115
116 -LlavaOnevisionImageInputs = Union[
117 - LlavaOnevisionImagePixelInputs, LlavaOnevisionImageEmbeddingInputs
118 -]
116 +LlavaOnevisionImageInputs: TypeAlias = (
117 + LlavaOnevisionImagePixelInputs | LlavaOnevisionImageEmbeddingInputs
118 +)
119
120 -LlavaOnevisionMultiInputs = Union[
121 - LlavaOnevisionImageInputs, LlavaOnevisionVideoPixelInputs
122 -]
120 +LlavaOnevisionMultiInputs: TypeAlias = (
121 + LlavaOnevisionImageInputs | LlavaOnevisionVideoPixelInputs
122 +)
123
124
125 class LlavaOnevisionLikeConfig(LlavaNextLikeConfig, Protocol):
@@ -133,7 +133,7 @@ class LlavaOnevisionProcessingInfo(LlavaNextProcessingInfo):
133 def get_hf_processor(self, **kwargs: object):
134 return self.ctx.get_hf_processor(LlavaOnevisionProcessor, **kwargs)
135
136 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
136 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
137 return {"image": None, "video": None}
138
139 # Based on: https://github.com/huggingface/text-generation-inference/blob/v3.0.1/server/text_generation_server/models/vlm_causal_lm.py#L86
@@ -276,7 +276,7 @@ class LlavaOnevisionDummyInputsBuilder(
276 self,
277 seq_len: int,
278 mm_counts: Mapping[str, int],
279 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
279 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
280 ) -> MultiModalDataDict:
281 num_images = mm_counts.get("image", 0)
282 num_videos = mm_counts.get("video", 0)
@@ -493,7 +493,7 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
493 )
494
495 @classmethod
496 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
496 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
497 if modality.startswith("image"):
498 return "<image>"
499 if modality.startswith("video"):
@@ -531,7 +531,7 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
531
532 def _parse_and_validate_image_input(
533 self, **kwargs: object
534 - ) -> Optional[LlavaOnevisionImageInputs]:
534 + ) -> LlavaOnevisionImageInputs | None:
535 pixel_values = kwargs.pop("pixel_values", None)
536 image_sizes = kwargs.pop("image_sizes", None)
537 image_embeds = kwargs.pop("image_embeds", None)
@@ -560,7 +560,7 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
560
561 def _parse_and_validate_video_input(
562 self, **kwargs: object
563 - ) -> Optional[LlavaOnevisionVideoPixelInputs]:
563 + ) -> LlavaOnevisionVideoPixelInputs | None:
564 """
565 A legal video input should have the following dimensions:
566 {
@@ -606,7 +606,7 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
606
607 def _image_pixels_to_features(
608 self,
609 - vision_tower: Union[CLIPVisionModel, SiglipVisionModel],
609 + vision_tower: CLIPVisionModel | SiglipVisionModel,
610 pixel_values: torch.Tensor,
611 ) -> torch.Tensor:
612 # NOTE: we skip the step to select the vision feature layer since
@@ -726,7 +726,7 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
726 def _process_image_pixels(
727 self,
728 inputs: LlavaOnevisionImagePixelInputs,
729 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
729 + ) -> torch.Tensor | list[torch.Tensor]:
730 assert self.vision_tower is not None
731
732 pixel_values = inputs["pixel_values"]
@@ -761,7 +761,7 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
761 def _process_image_input(
762 self,
763 image_input: LlavaOnevisionImageInputs,
764 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
764 + ) -> torch.Tensor | list[torch.Tensor]:
765 if image_input["type"] == "image_embeds":
766 return [image_input["data"]]
767
@@ -788,7 +788,7 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
788
789 def _video_pixels_to_features(
790 self,
791 - vision_tower: Union[CLIPVisionModel, SiglipVisionModel],
791 + vision_tower: CLIPVisionModel | SiglipVisionModel,
792 pixel_values: torch.Tensor,
793 ) -> torch.Tensor:
794 # NOTE: we skip the step to select the vision feature layer since
@@ -893,10 +893,10 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
893 self,
894 input_ids: torch.Tensor,
895 positions: torch.Tensor,
896 - intermediate_tensors: Optional[IntermediateTensors] = None,
897 - inputs_embeds: Optional[torch.Tensor] = None,
896 + intermediate_tensors: IntermediateTensors | None = None,
897 + inputs_embeds: torch.Tensor | None = None,
898 **kwargs: object,
899 - ) -> Union[torch.Tensor, IntermediateTensors]:
899 + ) -> torch.Tensor | IntermediateTensors:
900 """Run forward pass for LlaVA-Onevision.
901 Args:
902 input_ids: Flattened (concatenated) input_ids corresponding to a
@@ -915,7 +915,7 @@ class LlavaOnevisionForConditionalGeneration(nn.Module, SupportsMultiModal, Supp
915 def compute_logits(
916 self,
917 hidden_states: torch.Tensor,
918 - ) -> Optional[torch.Tensor]:
918 + ) -> torch.Tensor | None:
919 return self.language_model.compute_logits(hidden_states)
920
921 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/longcat_flash.py
+13 -14
@@ -36,7 +36,6 @@
36 import typing
37 from collections.abc import Callable, Iterable
38 from itertools import islice
39 -from typing import Optional, Union
39
40 import torch
41 from torch import nn
@@ -194,7 +193,7 @@ class FlashMLP(nn.Module):
193 hidden_size: int,
194 intermediate_size: int,
195 hidden_act: str,
197 - quant_config: Optional[QuantizationConfig] = None,
196 + quant_config: QuantizationConfig | None = None,
197 reduce_results: bool = True,
198 prefix: str = "",
199 ) -> None:
@@ -270,8 +269,8 @@ class LongcatMoe(nn.Module):
269 top_k: int,
270 hidden_size: int,
271 intermediate_size: int,
273 - params_dtype: Optional[torch.dtype] = None,
274 - quant_config: Optional[QuantizationConfig] = None,
272 + params_dtype: torch.dtype | None = None,
273 + quant_config: QuantizationConfig | None = None,
274 prefix: str = "",
275 enable_eplb: bool = False,
276 ):
@@ -329,8 +328,8 @@ class FlashDecoderLayer(nn.Module):
328 self,
329 vllm_config: VllmConfig,
330 config: FlashConfig,
332 - cache_config: Optional[CacheConfig] = None,
333 - quant_config: Optional[QuantizationConfig] = None,
331 + cache_config: CacheConfig | None = None,
332 + quant_config: QuantizationConfig | None = None,
333 prefix: str = "",
334 enable_eplb: bool = False,
335 ) -> None:
@@ -415,7 +414,7 @@ class FlashDecoderLayer(nn.Module):
414 self,
415 positions: torch.Tensor,
416 hidden_states: torch.Tensor,
418 - residual: Optional[torch.Tensor],
417 + residual: torch.Tensor | None,
418 ) -> tuple[torch.Tensor, torch.Tensor]:
419 if residual is None:
420 residual = hidden_states
@@ -506,9 +505,9 @@ class FlashModel(nn.Module):
505 self,
506 input_ids: torch.Tensor,
507 positions: torch.Tensor,
509 - intermediate_tensors: Optional[IntermediateTensors] = None,
510 - inputs_embeds: Optional[torch.Tensor] = None,
511 - ) -> Union[torch.Tensor, IntermediateTensors]:
508 + intermediate_tensors: IntermediateTensors | None = None,
509 + inputs_embeds: torch.Tensor | None = None,
510 + ) -> torch.Tensor | IntermediateTensors:
511 if get_pp_group().is_first_rank:
512 if inputs_embeds is not None:
513 hidden_states = inputs_embeds
@@ -592,9 +591,9 @@ class LongcatFlashForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
591 self,
592 input_ids: torch.Tensor,
593 positions: torch.Tensor,
595 - intermediate_tensors: Optional[IntermediateTensors] = None,
596 - inputs_embeds: Optional[torch.Tensor] = None,
597 - ) -> Union[torch.Tensor, IntermediateTensors]:
594 + intermediate_tensors: IntermediateTensors | None = None,
595 + inputs_embeds: torch.Tensor | None = None,
596 + ) -> torch.Tensor | IntermediateTensors:
597 hidden_states = self.model(
598 input_ids, positions, intermediate_tensors, inputs_embeds
599 )
@@ -603,7 +602,7 @@ class LongcatFlashForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
602 def compute_logits(
603 self,
604 hidden_states: torch.Tensor,
606 - ) -> Optional[torch.Tensor]:
605 + ) -> torch.Tensor | None:
606 logits = self.logits_processor(self.lm_head, hidden_states)
607 return logits
608
vllm/model_executor/models/longcat_flash_mtp.py
+8 -9
@@ -4,7 +4,6 @@
4 # Adapted from
5 # https://github.com/vllm-project/vllm/blob/v0.7.3/vllm/model_executor/models/deepseek_mtp.py
6 from collections.abc import Iterable
7 -from typing import Optional
7
8 import torch
9 import torch.nn as nn
@@ -35,7 +34,7 @@ class LongCatMultiTokenPredictorLayer(nn.Module):
34 config: PretrainedConfig,
35 prefix: str,
36 vllm_config: VllmConfig,
38 - quant_config: Optional[QuantizationConfig] = None,
37 + quant_config: QuantizationConfig | None = None,
38 ) -> None:
39 super().__init__()
40 self.enorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
@@ -55,7 +54,7 @@ class LongCatMultiTokenPredictorLayer(nn.Module):
54 input_ids: torch.Tensor,
55 positions: torch.Tensor,
56 previous_hidden_states: torch.Tensor,
58 - inputs_embeds: Optional[torch.Tensor] = None,
57 + inputs_embeds: torch.Tensor | None = None,
58 spec_step_index: int = 0,
59 ) -> torch.Tensor:
60 assert inputs_embeds is not None
@@ -78,7 +77,7 @@ class LongCatMultiTokenPredictor(nn.Module):
77 self,
78 *,
79 vllm_config: VllmConfig,
81 - quant_config: Optional[QuantizationConfig] = None,
80 + quant_config: QuantizationConfig | None = None,
81 prefix: str = "",
82 ):
83 super().__init__()
@@ -110,7 +109,7 @@ class LongCatMultiTokenPredictor(nn.Module):
109 input_ids: torch.Tensor,
110 positions: torch.Tensor,
111 previous_hidden_states: torch.Tensor,
113 - inputs_embeds: Optional[torch.Tensor] = None,
112 + inputs_embeds: torch.Tensor | None = None,
113 spec_step_idx: int = 0,
114 ) -> torch.Tensor:
115 if inputs_embeds is None:
@@ -155,8 +154,8 @@ class LongCatFlashMTP(nn.Module, SupportsPP):
154 input_ids: torch.Tensor,
155 positions: torch.Tensor,
156 hidden_states: torch.Tensor,
158 - intermediate_tensors: Optional[IntermediateTensors] = None,
159 - inputs_embeds: Optional[torch.Tensor] = None,
157 + intermediate_tensors: IntermediateTensors | None = None,
158 + inputs_embeds: torch.Tensor | None = None,
159 spec_step_idx: int = 0,
160 ) -> torch.Tensor:
161 hidden_states = self.model(
@@ -168,7 +167,7 @@ class LongCatFlashMTP(nn.Module, SupportsPP):
167 self,
168 hidden_states: torch.Tensor,
169 spec_step_idx: int = 0,
171 - ) -> Optional[torch.Tensor]:
170 + ) -> torch.Tensor | None:
171 logits = self.logits_processor(self.lm_head, hidden_states)
172 return logits
173
@@ -344,7 +343,7 @@ class LongCatFlashMTP(nn.Module, SupportsPP):
343
344 def get_spec_layer_idx_from_weight_name(
345 self, config: PretrainedConfig, weight_name: str
347 - ) -> Optional[int]:
346 + ) -> int | None:
347 if "model.mtp" in weight_name:
348 return config.num_hidden_layers * 2
349 return None
vllm/model_executor/models/mamba.py
+9 -10
@@ -4,7 +4,6 @@
4
5 from collections.abc import Iterable
6 from itertools import islice
7 -from typing import Optional
7
8 import torch
9 from torch import nn
@@ -49,10 +48,10 @@ class MambaDecoderLayer(nn.Module):
48 def __init__(
49 self,
50 config: MambaConfig,
52 - model_config: Optional[ModelConfig] = None,
53 - cache_config: Optional[CacheConfig] = None,
54 - quant_config: Optional[QuantizationConfig] = None,
55 - is_lora_enabled: Optional[bool] = False,
51 + model_config: ModelConfig | None = None,
52 + cache_config: CacheConfig | None = None,
53 + quant_config: QuantizationConfig | None = None,
54 + is_lora_enabled: bool | None = False,
55 prefix: str = "",
56 ) -> None:
57 super().__init__()
@@ -83,7 +82,7 @@ class MambaDecoderLayer(nn.Module):
82 def forward(
83 self,
84 hidden_states: torch.Tensor,
86 - residual: Optional[torch.Tensor],
85 + residual: torch.Tensor | None,
86 **kwargs,
87 ):
88 if residual is None:
@@ -149,8 +148,8 @@ class MambaModel(nn.Module):
148 self,
149 input_ids: torch.Tensor,
150 positions: torch.Tensor,
152 - intermediate_tensors: Optional[IntermediateTensors] = None,
153 - inputs_embeds: Optional[torch.Tensor] = None,
151 + intermediate_tensors: IntermediateTensors | None = None,
152 + inputs_embeds: torch.Tensor | None = None,
153 ) -> torch.Tensor:
154 if get_pp_group().is_first_rank:
155 if inputs_embeds is not None:
@@ -244,8 +243,8 @@ class MambaForCausalLM(nn.Module, HasInnerState, IsAttentionFree, SupportsPP):
243 self,
244 input_ids: torch.Tensor,
245 positions: torch.Tensor,
247 - intermediate_tensors: Optional[IntermediateTensors] = None,
248 - inputs_embeds: Optional[torch.Tensor] = None,
246 + intermediate_tensors: IntermediateTensors | None = None,
247 + inputs_embeds: torch.Tensor | None = None,
248 **kwargs,
249 ):
250 hidden_states = self.backbone(
vllm/model_executor/models/mamba2.py
+8 -9
@@ -3,7 +3,6 @@
3 """PyTorch MAMBA2 model."""
4
5 from collections.abc import Iterable
6 -from typing import Optional
6
7 import torch
8 from torch import nn
@@ -44,9 +43,9 @@ class Mamba2DecoderLayer(nn.Module):
43 def __init__(
44 self,
45 config: MambaConfig,
47 - model_config: Optional[ModelConfig] = None,
48 - cache_config: Optional[CacheConfig] = None,
49 - quant_config: Optional[QuantizationConfig] = None,
46 + model_config: ModelConfig | None = None,
47 + cache_config: CacheConfig | None = None,
48 + quant_config: QuantizationConfig | None = None,
49 prefix: str = "",
50 ) -> None:
51 super().__init__()
@@ -76,7 +75,7 @@ class Mamba2DecoderLayer(nn.Module):
75 def forward(
76 self,
77 hidden_states: torch.Tensor,
79 - residual: Optional[torch.Tensor],
78 + residual: torch.Tensor | None,
79 **kwargs,
80 ):
81 if residual is None:
@@ -142,8 +141,8 @@ class Mamba2Model(nn.Module):
141 self,
142 input_ids: torch.Tensor,
143 positions: torch.Tensor,
145 - intermediate_tensors: Optional[IntermediateTensors] = None,
146 - inputs_embeds: Optional[torch.Tensor] = None,
144 + intermediate_tensors: IntermediateTensors | None = None,
145 + inputs_embeds: torch.Tensor | None = None,
146 ) -> torch.Tensor:
147 if get_pp_group().is_first_rank:
148 if inputs_embeds is not None:
@@ -277,8 +276,8 @@ class Mamba2ForCausalLM(nn.Module, HasInnerState, IsAttentionFree):
276 self,
277 input_ids: torch.Tensor,
278 positions: torch.Tensor,
280 - intermediate_tensors: Optional[IntermediateTensors] = None,
281 - inputs_embeds: Optional[torch.Tensor] = None,
279 + intermediate_tensors: IntermediateTensors | None = None,
280 + inputs_embeds: torch.Tensor | None = None,
281 **kwargs,
282 ):
283 hidden_states = self.backbone(
vllm/model_executor/models/midashenglm.py
+26 -26
@@ -25,8 +25,8 @@
25
26 import collections
27 import collections.abc
28 -from collections.abc import Iterable, Mapping, Sequence
29 -from typing import Any, Callable, Optional, TypedDict, Union, cast
28 +from collections.abc import Callable, Iterable, Mapping, Sequence
29 +from typing import Any, TypeAlias, TypedDict, cast
30
31 import numpy as np
32 import torch
@@ -66,7 +66,7 @@ from vllm.transformers_utils.configs.midashenglm import DashengConfig
66 from .interfaces import MultiModalEmbeddings, SupportsMultiModal, SupportsPP
67 from .utils import AutoWeightsLoader, init_vllm_registered_model, maybe_prefix
68
69 -_Tuple2 = Union[int, tuple[int, int], Sequence[int]]
69 +_Tuple2: TypeAlias = int | tuple[int, int] | Sequence[int]
70
71
72 def _resolve_tuple2(x: _Tuple2) -> tuple[int, int]:
@@ -105,7 +105,7 @@ class AudioPatchEmbed(nn.Module):
105 patch_stride: _Tuple2 = 16,
106 in_chans: int = 1,
107 embed_dim: int = 768,
108 - norm_layer: Optional[Callable] = None,
108 + norm_layer: Callable | None = None,
109 flatten: bool = False,
110 ):
111 super().__init__()
@@ -151,9 +151,9 @@ class DashengMlp(nn.Module):
151 def __init__(
152 self,
153 in_features: int,
154 - hidden_features: Optional[int] = None,
155 - out_features: Optional[int] = None,
156 - quant_config: Optional[QuantizationConfig] = None,
154 + hidden_features: int | None = None,
155 + out_features: int | None = None,
156 + quant_config: QuantizationConfig | None = None,
157 prefix: str = "",
158 ):
159 super().__init__()
@@ -186,7 +186,7 @@ class DashengAttention(nn.Module):
186 dim: int,
187 num_heads: int = 8,
188 qkv_bias: bool = False,
189 - quant_config: Optional[QuantizationConfig] = None,
189 + quant_config: QuantizationConfig | None = None,
190 prefix: str = "",
191 ):
192 super().__init__()
@@ -226,7 +226,7 @@ class DashengAttention(nn.Module):
226 prefix=f"{prefix}.proj",
227 )
228
229 - def forward(self, x: torch.Tensor, mask: Optional[torch.Tensor] = None):
229 + def forward(self, x: torch.Tensor, mask: torch.Tensor | None = None):
230 B, N, C = x.shape
231
232 qkv, _ = self.qkv(x)
@@ -253,8 +253,8 @@ class DashengBlock(nn.Module):
253 num_heads: int,
254 mlp_ratio: float = 4.0,
255 qkv_bias: bool = False,
256 - init_values: Optional[float] = None,
257 - quant_config: Optional[QuantizationConfig] = None,
256 + init_values: float | None = None,
257 + quant_config: QuantizationConfig | None = None,
258 prefix: str = "",
259 ):
260 super().__init__()
@@ -285,7 +285,7 @@ class DashengBlock(nn.Module):
285 def forward(
286 self,
287 x: torch.Tensor,
288 - mask: Optional[torch.Tensor] = None,
288 + mask: torch.Tensor | None = None,
289 ) -> torch.Tensor:
290 x = x + self.ls1(self.attn(self.norm1(x), mask))
291 x = x + self.ls2(self.mlp(self.norm2(x)))
@@ -349,7 +349,7 @@ class DashengAudioTransformer(nn.Module):
349 def __init__(
350 self,
351 config: DashengConfig,
352 - quant_config: Optional[QuantizationConfig] = None,
352 + quant_config: QuantizationConfig | None = None,
353 prefix: str = "",
354 ):
355 super().__init__()
@@ -393,7 +393,7 @@ class DashengAudioTransformer(nn.Module):
393 def forward_features(
394 self,
395 x: torch.Tensor,
396 - mask: Optional[torch.Tensor] = None,
396 + mask: torch.Tensor | None = None,
397 ) -> torch.Tensor:
398 t = x.shape[-1]
399 x = x + self.time_pos_embed[:, :, :, :t]
@@ -418,8 +418,8 @@ class DashengAudioTransformer(nn.Module):
418 def forward(
419 self,
420 x: torch.Tensor,
421 - x_length: Optional[torch.Tensor] = None,
422 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
421 + x_length: torch.Tensor | None = None,
422 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
423 x = self.front_end(x)
424 x = x.to(self.time_pos_embed.dtype)
425 target_length_in_patches = self.target_length // 4
@@ -462,8 +462,8 @@ class AudioProjectorSubsample(nn.Module):
462 in_dim: int,
463 out_dim: int,
464 downsample_rate=5,
465 - dtype: Optional[torch.dtype] = None,
466 - quant_config: Optional[QuantizationConfig] = None,
465 + dtype: torch.dtype | None = None,
466 + quant_config: QuantizationConfig | None = None,
467 prefix: str = "",
468 ):
469 super().__init__()
@@ -524,7 +524,7 @@ class MiDashengLMProcessingInfo(BaseProcessingInfo):
524 feature_extractor = hf_processor.feature_extractor
525 return feature_extractor
526
527 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
527 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
528 return {"audio": None}
529
530 def get_min_audio_len(self):
@@ -550,7 +550,7 @@ class MiDashengLMDummyInputsBuilder(BaseDummyInputsBuilder[MiDashengLMProcessing
550 self,
551 seq_len: int,
552 mm_counts: Mapping[str, int],
553 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
553 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
554 ) -> MultiModalDataDict:
555 num_audios = mm_counts.get("audio", 0)
556
@@ -689,7 +689,7 @@ class MiDashengLMModel(nn.Module, SupportsMultiModal, SupportsPP):
689 }
690
691 @classmethod
692 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
692 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
693 if modality.startswith("audio"):
694 return "<|audio_bos|><|AUDIO|><|audio_eos|>"
695
@@ -750,7 +750,7 @@ class MiDashengLMModel(nn.Module, SupportsMultiModal, SupportsPP):
750
751 def _parse_and_validate_audio_input(
752 self, **kwargs: object
753 - ) -> Optional[MiDashengLMAudioInputs]:
753 + ) -> MiDashengLMAudioInputs | None:
754 input_values = kwargs.pop("input_values", None)
755 audio_length = kwargs.pop("audio_length", None)
756
@@ -820,10 +820,10 @@ class MiDashengLMModel(nn.Module, SupportsMultiModal, SupportsPP):
820 self,
821 input_ids: torch.Tensor,
822 positions: torch.Tensor,
823 - intermediate_tensors: Optional[IntermediateTensors] = None,
824 - inputs_embeds: Optional[torch.Tensor] = None,
823 + intermediate_tensors: IntermediateTensors | None = None,
824 + inputs_embeds: torch.Tensor | None = None,
825 **kwargs: object,
826 - ) -> Union[torch.Tensor, IntermediateTensors]:
826 + ) -> torch.Tensor | IntermediateTensors:
827 if intermediate_tensors is not None:
828 inputs_embeds = None
829 elif inputs_embeds is None:
@@ -845,7 +845,7 @@ class MiDashengLMModel(nn.Module, SupportsMultiModal, SupportsPP):
845 def compute_logits(
846 self,
847 hidden_states: torch.Tensor,
848 - ) -> Optional[torch.Tensor]:
848 + ) -> torch.Tensor | None:
849 return self.decoder.compute_logits(hidden_states)
850
851 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/mimo.py
+4 -5
@@ -28,7 +28,6 @@
28
29 from collections.abc import Iterable
30 from itertools import islice
31 -from typing import Optional, Union
31
32 import torch
33 import torch.nn as nn
@@ -64,9 +63,9 @@ class MiMoModel(Qwen2Model):
63 self,
64 input_ids: torch.Tensor,
65 positions: torch.Tensor,
67 - intermediate_tensors: Optional[IntermediateTensors] = None,
68 - inputs_embeds: Optional[torch.Tensor] = None,
69 - ) -> Union[torch.Tensor, IntermediateTensors]:
66 + intermediate_tensors: IntermediateTensors | None = None,
67 + inputs_embeds: torch.Tensor | None = None,
68 + ) -> torch.Tensor | IntermediateTensors:
69 if get_pp_group().is_first_rank:
70 if inputs_embeds is not None:
71 hidden_states = inputs_embeds
@@ -185,7 +184,7 @@ class MiMoForCausalLM(Qwen2ForCausalLM, nn.Module):
184 def compute_logits(
185 self,
186 hidden_states: torch.Tensor,
188 - ) -> Optional[torch.Tensor]:
187 + ) -> torch.Tensor | None:
188 hidden_states = self.model.norm(hidden_states)
189 logits = self.logits_processor(self.lm_head, hidden_states)
190 return logits
vllm/model_executor/models/mimo_mtp.py
+6 -7
@@ -21,7 +21,6 @@
21 """Inference-only MiMo-MTP model."""
22
23 from collections.abc import Iterable
24 -from typing import Optional
24
25 import torch
26 import torch.nn as nn
@@ -48,8 +47,8 @@ class MiMoMultiTokenPredictorLayer(nn.Module):
47 config: PretrainedConfig,
48 prefix: str,
49 model_config: ModelConfig,
51 - cache_config: Optional[CacheConfig] = None,
52 - quant_config: Optional[QuantizationConfig] = None,
50 + cache_config: CacheConfig | None = None,
51 + quant_config: QuantizationConfig | None = None,
52 ) -> None:
53 super().__init__()
54
@@ -129,7 +128,7 @@ class MiMoMultiTokenPredictor(nn.Module):
128 input_ids: torch.Tensor,
129 positions: torch.Tensor,
130 previous_hidden_states: torch.Tensor,
132 - inputs_embeds: Optional[torch.Tensor] = None,
131 + inputs_embeds: torch.Tensor | None = None,
132 spec_step_idx: int = 0,
133 ) -> torch.Tensor:
134 if inputs_embeds is None:
@@ -173,8 +172,8 @@ class MiMoMTP(nn.Module):
172 input_ids: torch.Tensor,
173 positions: torch.Tensor,
174 hidden_states: torch.Tensor,
176 - intermediate_tensors: Optional[IntermediateTensors] = None,
177 - inputs_embeds: Optional[torch.Tensor] = None,
175 + intermediate_tensors: IntermediateTensors | None = None,
176 + inputs_embeds: torch.Tensor | None = None,
177 spec_step_idx: int = 0,
178 ) -> torch.Tensor:
179 assert spec_step_idx == 0, "mimo_mtp only support predict one token now"
@@ -187,7 +186,7 @@ class MiMoMTP(nn.Module):
186 self,
187 hidden_states: torch.Tensor,
188 spec_step_idx: int = 0,
190 - ) -> Optional[torch.Tensor]:
189 + ) -> torch.Tensor | None:
190 return self.model.compute_logits(hidden_states, self.lm_head, spec_step_idx)
191
192 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/minicpm.py
+19 -23
@@ -27,7 +27,7 @@
27 import math
28 from collections.abc import Iterable
29 from itertools import islice
30 -from typing import Any, Optional, Union
30 +from typing import Any
31
32 import torch
33 from torch import nn
@@ -89,8 +89,8 @@ class MiniCPMMoE(nn.Module):
89 top_k: int,
90 hidden_size: int,
91 intermediate_size: int,
92 - params_dtype: Optional[torch.dtype] = None,
93 - tp_size: Optional[int] = None,
92 + params_dtype: torch.dtype | None = None,
93 + tp_size: int | None = None,
94 ):
95 super().__init__()
96 self.tp_size = tp_size or get_tensor_model_parallel_world_size()
@@ -190,7 +190,7 @@ class MiniCPMMLP(nn.Module):
190 intermediate_size: int,
191 hidden_act: str,
192 hidden_act_param: float,
193 - quant_config: Optional[QuantizationConfig] = None,
193 + quant_config: QuantizationConfig | None = None,
194 ) -> None:
195 super().__init__()
196 self.gate_up_proj = MergedColumnParallelLinear(
@@ -223,10 +223,10 @@ class MiniCPMAttention(nn.Module):
223 num_heads: int,
224 num_kv_heads: int,
225 rope_theta: float = 10000,
226 - rope_scaling: Optional[dict[str, Any]] = None,
226 + rope_scaling: dict[str, Any] | None = None,
227 max_position_embeddings: int = 8192,
228 - cache_config: Optional[CacheConfig] = None,
229 - quant_config: Optional[QuantizationConfig] = None,
228 + cache_config: CacheConfig | None = None,
229 + quant_config: QuantizationConfig | None = None,
230 prefix: str = "",
231 ) -> None:
232 super().__init__()
@@ -305,8 +305,8 @@ class MiniCPMDecoderLayer(nn.Module):
305 def __init__(
306 self,
307 config: PretrainedConfig,
308 - cache_config: Optional[CacheConfig] = None,
309 - quant_config: Optional[QuantizationConfig] = None,
308 + cache_config: CacheConfig | None = None,
309 + quant_config: QuantizationConfig | None = None,
310 prefix: str = "",
311 ) -> None:
312 super().__init__()
@@ -362,7 +362,7 @@ class MiniCPMDecoderLayer(nn.Module):
362 self,
363 positions: torch.Tensor,
364 hidden_states: torch.Tensor,
365 - residual: Optional[torch.Tensor],
365 + residual: torch.Tensor | None,
366 ) -> tuple[torch.Tensor, torch.Tensor]:
367 # Self Attention
368 residual = hidden_states
@@ -425,8 +425,8 @@ class MiniCPMModel(nn.Module):
425 self,
426 prefix: str,
427 config: PretrainedConfig,
428 - cache_config: Optional[CacheConfig],
429 - quant_config: Optional[QuantizationConfig],
428 + cache_config: CacheConfig | None,
429 + quant_config: QuantizationConfig | None,
430 ):
431 self.start_layer, self.end_layer, self.layers = make_layers(
432 config.num_hidden_layers,
@@ -444,11 +444,9 @@ class MiniCPMModel(nn.Module):
444 self,
445 input_ids: torch.Tensor,
446 positions: torch.Tensor,
447 - intermediate_tensors: Optional[IntermediateTensors] = None,
448 - inputs_embeds: Optional[torch.Tensor] = None,
449 - ) -> Union[
450 - torch.Tensor, IntermediateTensors, tuple[torch.Tensor, list[torch.Tensor]]
451 - ]:
447 + intermediate_tensors: IntermediateTensors | None = None,
448 + inputs_embeds: torch.Tensor | None = None,
449 + ) -> torch.Tensor | IntermediateTensors | tuple[torch.Tensor, list[torch.Tensor]]:
450 if get_pp_group().is_first_rank:
451 if inputs_embeds is not None:
452 hidden_states = inputs_embeds
@@ -633,11 +631,9 @@ class MiniCPMForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3):
631 self,
632 input_ids: torch.Tensor,
633 positions: torch.Tensor,
636 - intermediate_tensors: Optional[IntermediateTensors] = None,
637 - inputs_embeds: Optional[torch.Tensor] = None,
638 - ) -> Union[
639 - torch.Tensor, IntermediateTensors, tuple[torch.Tensor, list[torch.Tensor]]
640 - ]:
634 + intermediate_tensors: IntermediateTensors | None = None,
635 + inputs_embeds: torch.Tensor | None = None,
636 + ) -> torch.Tensor | IntermediateTensors | tuple[torch.Tensor, list[torch.Tensor]]:
637 model_output = self.model(
638 input_ids, positions, intermediate_tensors, inputs_embeds
639 )
@@ -658,7 +654,7 @@ class MiniCPMForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3):
654 def compute_logits(
655 self,
656 hidden_states: torch.Tensor,
661 - ) -> Optional[torch.Tensor]:
657 + ) -> torch.Tensor | None:
658 logits = self.logits_processor(self.lm_head, hidden_states)
659 return logits
660
vllm/model_executor/models/minicpm3.py
+6 -6
@@ -25,7 +25,7 @@
25 # limitations under the License.
26 """Inference-only MiniCPM3 model compatible with HuggingFace weights."""
27
28 -from typing import Any, Optional
28 +from typing import Any
29
30 import torch
31 from torch import nn
@@ -63,10 +63,10 @@ class MiniCPM3Attention(nn.Module):
63 q_lora_rank: int,
64 kv_lora_rank: int,
65 rope_theta: float = 10000,
66 - rope_scaling: Optional[dict[str, Any]] = None,
66 + rope_scaling: dict[str, Any] | None = None,
67 max_position_embeddings: int = 8192,
68 - cache_config: Optional[CacheConfig] = None,
69 - quant_config: Optional[QuantizationConfig] = None,
68 + cache_config: CacheConfig | None = None,
69 + quant_config: QuantizationConfig | None = None,
70 prefix: str = "",
71 ) -> None:
72 super().__init__()
@@ -214,8 +214,8 @@ class MiniCPM3Model(MiniCPMModel):
214 self,
215 prefix: str,
216 config: PretrainedConfig,
217 - cache_config: Optional[CacheConfig],
218 - quant_config: Optional[QuantizationConfig],
217 + cache_config: CacheConfig | None,
218 + quant_config: QuantizationConfig | None,
219 ):
220 self.start_layer, self.end_layer, self.layers = make_layers(
221 config.num_hidden_layers,
vllm/model_executor/models/minicpm_eagle.py
+7 -8
@@ -26,7 +26,6 @@
26
27 import math
28 from collections.abc import Iterable
29 -from typing import Optional, Union
29
30 import torch
31 from torch import nn
@@ -61,8 +60,8 @@ class EagleMiniCPMDecoderLayer(nn.Module):
60 def __init__(
61 self,
62 config: PretrainedConfig,
64 - cache_config: Optional[CacheConfig] = None,
65 - quant_config: Optional[QuantizationConfig] = None,
63 + cache_config: CacheConfig | None = None,
64 + quant_config: QuantizationConfig | None = None,
65 prefix: str = "",
66 ) -> None:
67 super().__init__()
@@ -118,7 +117,7 @@ class EagleMiniCPMDecoderLayer(nn.Module):
117 self,
118 positions: torch.Tensor,
119 hidden_states: torch.Tensor,
121 - residual: Optional[torch.Tensor],
120 + residual: torch.Tensor | None,
121 ) -> tuple[torch.Tensor, torch.Tensor]:
122 # Self Attention
123 residual = hidden_states
@@ -185,8 +184,8 @@ class EagleMiniCPMModel(nn.Module):
184 self,
185 prefix: str,
186 config: PretrainedConfig,
188 - cache_config: Optional[CacheConfig],
189 - quant_config: Optional[QuantizationConfig],
187 + cache_config: CacheConfig | None,
188 + quant_config: QuantizationConfig | None,
189 start_layer: int,
190 ):
191 self.eagle_layers = nn.ModuleList(
@@ -210,7 +209,7 @@ class EagleMiniCPMModel(nn.Module):
209 input_ids: torch.Tensor,
210 positions: torch.Tensor,
211 hidden_states: torch.Tensor,
213 - ) -> Union[torch.Tensor, IntermediateTensors]:
212 + ) -> torch.Tensor | IntermediateTensors:
213 input_embeds = self.get_input_embeddings(input_ids)
214 input_embeds = self.input_norm1(input_embeds)
215 hidden_states = self.input_norm2(hidden_states)
@@ -389,7 +388,7 @@ class EagleMiniCPMForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
388 def compute_logits(
389 self,
390 hidden_states: torch.Tensor,
392 - ) -> Optional[torch.Tensor]:
391 + ) -> torch.Tensor | None:
392 logits = self.logits_processor(self.lm_head, hidden_states)
393 return logits
394
vllm/model_executor/models/minicpmo.py
+16 -14
@@ -24,8 +24,8 @@
24 # limitations under the License.
25 """Inference-only MiniCPM-O model compatible with HuggingFace weights."""
26
27 -from collections.abc import Iterable, Mapping, Sequence
28 -from typing import Annotated, Any, Callable, Literal, Optional, Union
27 +from collections.abc import Callable, Iterable, Mapping, Sequence
28 +from typing import Annotated, Any, Literal, TypeAlias
29
30 import torch
31 from torch import nn
@@ -89,7 +89,7 @@ class MiniCPMOAudioFeatureInputs(TensorSchema):
89 type: Literal["audio_features"] = "audio_features"
90
91 audio_features: Annotated[
92 - Union[torch.Tensor, list[torch.Tensor]],
92 + torch.Tensor | list[torch.Tensor],
93 TensorShape("bns", "c", "l", dynamic_dims={"l"}),
94 ]
95 """
@@ -99,7 +99,7 @@ class MiniCPMOAudioFeatureInputs(TensorSchema):
99 """
100
101 audio_feature_lens: Annotated[
102 - Union[torch.Tensor, list[torch.Tensor]],
102 + torch.Tensor | list[torch.Tensor],
103 TensorShape("bn", "s"),
104 ]
105 """
@@ -121,12 +121,14 @@ class MiniCPMOAudioEmbeddingInputs(TensorSchema):
121 type: Literal["audio_embeds"] = "audio_embeds"
122
123 audio_embeds: Annotated[
124 - Union[torch.Tensor, list[torch.Tensor]],
124 + torch.Tensor | list[torch.Tensor],
125 TensorShape("bn", "s", "h", dynamic_dims={"s"}),
126 ]
127
128
129 -MiniCPMOAudioInputs = Union[MiniCPMOAudioFeatureInputs, MiniCPMOAudioEmbeddingInputs]
129 +MiniCPMOAudioInputs: TypeAlias = (
130 + MiniCPMOAudioFeatureInputs | MiniCPMOAudioEmbeddingInputs
131 +)
132
133
134 def _minicpmo_field_config(hf_inputs: Mapping[str, torch.Tensor]):
@@ -162,8 +164,8 @@ class MiniCPMOAudioEmbeddingItems(DictEmbeddingItems):
164 class MiniCPMOMultiModalDataParser(MiniCPMVMultiModalDataParser):
165 def _parse_audio_data(
166 self,
165 - data: Union[dict[str, torch.Tensor], ModalityData[AudioItem]],
166 - ) -> Optional[ModalityDataItems[Any, Any]]:
167 + data: dict[str, torch.Tensor] | ModalityData[AudioItem],
168 + ) -> ModalityDataItems[Any, Any] | None:
169 if isinstance(data, dict):
170 return MiniCPMOAudioEmbeddingItems(
171 data,
@@ -176,7 +178,7 @@ class MiniCPMOMultiModalDataParser(MiniCPMVMultiModalDataParser):
178 class MiniCPMOProcessingInfo(MiniCPMVProcessingInfo):
179 audio_pattern = "(<audio>./</audio>)"
180
179 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
181 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
182 return {**super().get_supported_mm_limits(), "audio": None}
183
184 def get_audio_placeholder(
@@ -253,7 +255,7 @@ class MiniCPMODummyInputsBuilder(MiniCPMVDummyInputsBuilder[MiniCPMOProcessingIn
255 self,
256 seq_len: int,
257 mm_counts: Mapping[str, int],
256 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
258 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
259 ) -> MultiModalDataDict:
260 num_audios = mm_counts.get("audio", 0)
261 audio_len = (
@@ -479,7 +481,7 @@ class MiniCPMWhisperEncoder(WhisperEncoder):
481 def forward(
482 self,
483 input_features: torch.Tensor,
482 - attention_mask: Optional[torch.Tensor] = None,
484 + attention_mask: torch.Tensor | None = None,
485 ) -> BaseModelOutputWithPast:
486 # Ignore copy
487 input_features = input_features.to(
@@ -549,7 +551,7 @@ class MiniCPMO(MiniCPMV2_6):
551 }
552
553 @classmethod
552 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
554 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
555 if modality.startswith("image"):
556 return "(<image>./</image>)"
557 if modality.startswith("video"):
@@ -722,7 +724,7 @@ class MiniCPMO(MiniCPMV2_6):
724
725 def _parse_and_validate_audio_input(
726 self, **kwargs: object
725 - ) -> Optional[MiniCPMOAudioInputs]:
727 + ) -> MiniCPMOAudioInputs | None:
728 audio_features = kwargs.pop("audio_features", None)
729 audio_embeds = kwargs.pop("audio_embeds", None)
730
@@ -785,7 +787,7 @@ class MiniCPMO(MiniCPMV2_6):
787 def _process_audio_input(
788 self,
789 audio_input: MiniCPMOAudioInputs,
788 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
790 + ) -> torch.Tensor | list[torch.Tensor]:
791 if audio_input["type"] == "audio_embeds":
792 return audio_input["audio_embeds"]
793
vllm/model_executor/models/minicpmv.py
+37 -37
@@ -26,10 +26,10 @@
26
27 import math
28 from collections import defaultdict
29 -from collections.abc import Iterable, Mapping, Sequence
29 +from collections.abc import Callable, Iterable, Mapping, Sequence
30 from functools import partial
31 from itertools import chain
32 -from typing import Annotated, Any, Callable, Literal, Optional, Union
32 +from typing import Annotated, Any, Literal, TypeAlias
33
34 import numpy as np
35 import torch
@@ -140,12 +140,12 @@ class MiniCPMVImageEmbeddingInputs(TensorSchema):
140
141 type: Literal["image_embeds"]
142 image_embeds: Annotated[
143 - Union[torch.Tensor, list[torch.Tensor]],
143 + torch.Tensor | list[torch.Tensor],
144 TensorShape("bn", "ns", "hs"),
145 ]
146
147
148 -MiniCPMVImageInputs = Union[MiniCPMVImagePixelInputs, MiniCPMVImageEmbeddingInputs]
148 +MiniCPMVImageInputs: TypeAlias = MiniCPMVImagePixelInputs | MiniCPMVImageEmbeddingInputs
149
150 DEFAULT_LN = partial(nn.LayerNorm, eps=1e-6)
151
@@ -156,10 +156,10 @@ class Resampler2_5(BaseResampler):
156 num_queries: int,
157 embed_dim: int,
158 num_heads: int,
159 - kv_dim: Optional[int] = None,
159 + kv_dim: int | None = None,
160 norm_layer: Callable[[int], nn.LayerNorm] = DEFAULT_LN,
161 max_size: tuple[int, int] = (70, 70),
162 - quant_config: Optional[QuantizationConfig] = None,
162 + quant_config: QuantizationConfig | None = None,
163 prefix: str = "",
164 ) -> None:
165 super().__init__(
@@ -251,11 +251,11 @@ class Resampler4_5(Resampler2_5):
251 num_queries: int,
252 embed_dim: int,
253 num_heads: int,
254 - kv_dim: Optional[int] = None,
254 + kv_dim: int | None = None,
255 norm_layer: Callable[[int], nn.LayerNorm] = DEFAULT_LN,
256 max_size: tuple[int, int] = (70, 70),
257 max_temporal_size: int = 36000,
258 - quant_config: Optional[QuantizationConfig] = None,
258 + quant_config: QuantizationConfig | None = None,
259 prefix: str = "",
260 ) -> None:
261 super().__init__(
@@ -318,7 +318,7 @@ class Resampler4_5(Resampler2_5):
318 self.max_temporal_size = max_temporal_size
319 self._set_temporal_pos_cache(self.max_temporal_size, device)
320
321 - def _init_weights(self, m: Union[nn.Linear, nn.LayerNorm]):
321 + def _init_weights(self, m: nn.Linear | nn.LayerNorm):
322 if isinstance(m, nn.Linear):
323 trunc_normal_(m.weight, std=0.02)
324 if isinstance(m, nn.Linear) and m.bias is not None:
@@ -521,8 +521,8 @@ class MiniCPMVVideoEmbeddingItems(DictEmbeddingItems):
521 class MiniCPMVMultiModalDataParser(MultiModalDataParser):
522 def _parse_image_data(
523 self,
524 - data: Union[dict[str, torch.Tensor], ModalityData[ImageItem]],
525 - ) -> Optional[ModalityDataItems[Any, Any]]:
524 + data: dict[str, torch.Tensor] | ModalityData[ImageItem],
525 + ) -> ModalityDataItems[Any, Any] | None:
526 if isinstance(data, dict):
527 return MiniCPMVImageEmbeddingItems(
528 data,
@@ -533,8 +533,8 @@ class MiniCPMVMultiModalDataParser(MultiModalDataParser):
533
534 def _parse_video_data(
535 self,
536 - data: Union[dict[str, torch.Tensor], ModalityData[VideoItem]],
537 - ) -> Optional[ModalityDataItems[Any, Any]]:
536 + data: dict[str, torch.Tensor] | ModalityData[VideoItem],
537 + ) -> ModalityDataItems[Any, Any] | None:
538 if isinstance(data, dict):
539 return MiniCPMVVideoEmbeddingItems(
540 data,
@@ -570,7 +570,7 @@ class MiniCPMVProcessingInfo(BaseProcessingInfo):
570 def get_model_version(self):
571 return get_version_by_config(self.get_hf_config())
572
573 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
573 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
574 mm_limits = {"image": None}
575 if self.get_model_version() in {(2, 6), (4, 0), (4, 5)}:
576 mm_limits["video"] = None
@@ -582,7 +582,7 @@ class MiniCPMVProcessingInfo(BaseProcessingInfo):
582 image_size: ImageSize,
583 # For MiniCPM V/O 2.6
584 image_idx: int = 0,
585 - max_slice_nums: Optional[int] = None,
585 + max_slice_nums: int | None = None,
586 use_image_id: bool = True,
587 ) -> str:
588 image_processor = self.get_image_processor()
@@ -602,8 +602,8 @@ class MiniCPMVProcessingInfo(BaseProcessingInfo):
602 self,
603 image_size: ImageSize,
604 # For MiniCPM V/O 2.6
605 - max_slice_nums: Optional[int] = None,
606 - ) -> Optional[tuple[int, int]]:
605 + max_slice_nums: int | None = None,
606 + ) -> tuple[int, int] | None:
607 image_processor = self.get_image_processor()
608 version = self.get_model_version()
609
@@ -621,7 +621,7 @@ class MiniCPMVProcessingInfo(BaseProcessingInfo):
621 def get_num_image_tokens(
622 self,
623 image_size: ImageSize,
624 - max_slice_nums: Optional[int] = None,
624 + max_slice_nums: int | None = None,
625 ) -> int:
626 image_processor = self.get_image_processor()
627
@@ -712,7 +712,7 @@ class MiniCPMVDummyInputsBuilder(BaseDummyInputsBuilder[_I]):
712 self,
713 seq_len: int,
714 mm_counts: Mapping[str, int],
715 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
715 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
716 ) -> MultiModalDataDict:
717 num_images = mm_counts.get("image", 0)
718 num_videos = mm_counts.get("video", 0)
@@ -1024,7 +1024,7 @@ class MiniCPMVBaseModel(nn.Module, SupportsMultiModal, SupportsPP):
1024 supports_encoder_tp_data = True
1025
1026 @classmethod
1027 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1027 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1028 if modality.startswith("image"):
1029 return "(<image>./</image>)"
1030 if modality.startswith("video"):
@@ -1073,7 +1073,7 @@ class MiniCPMVBaseModel(nn.Module, SupportsMultiModal, SupportsPP):
1073 self,
1074 modality: str,
1075 **kwargs: object,
1076 - ) -> Optional[MiniCPMVImageInputs]:
1076 + ) -> MiniCPMVImageInputs | None:
1077 pixel_values = kwargs.pop("pixel_values", None)
1078 image_embeds = kwargs.pop("image_embeds", None)
1079
@@ -1158,7 +1158,7 @@ class MiniCPMVBaseModel(nn.Module, SupportsMultiModal, SupportsPP):
1158 def _process_vision_input(
1159 self,
1160 image_input: MiniCPMVImageInputs,
1161 - ) -> Union[torch.Tensor, list[torch.Tensor], tuple[torch.Tensor, ...]]:
1161 + ) -> torch.Tensor | list[torch.Tensor] | tuple[torch.Tensor, ...]:
1162 if image_input["type"] == "image_embeds":
1163 return image_input["image_embeds"]
1164
@@ -1200,8 +1200,8 @@ class MiniCPMVBaseModel(nn.Module, SupportsMultiModal, SupportsPP):
1200 self,
1201 input_ids: torch.Tensor,
1202 positions: torch.Tensor,
1203 - intermediate_tensors: Optional[IntermediateTensors] = None,
1204 - inputs_embeds: Optional[torch.Tensor] = None,
1203 + intermediate_tensors: IntermediateTensors | None = None,
1204 + inputs_embeds: torch.Tensor | None = None,
1205 **kwargs: Any,
1206 ) -> torch.Tensor:
1207 if intermediate_tensors is not None:
@@ -1218,7 +1218,7 @@ class MiniCPMVBaseModel(nn.Module, SupportsMultiModal, SupportsPP):
1218 def compute_logits(
1219 self,
1220 hidden_states: torch.Tensor,
1221 - ) -> Optional[torch.Tensor]:
1221 + ) -> torch.Tensor | None:
1222 return self.llm.compute_logits(hidden_states)
1223
1224 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
@@ -1243,7 +1243,7 @@ class MiniCPMVBaseModel(nn.Module, SupportsMultiModal, SupportsPP):
1243 def init_vision_module(
1244 self,
1245 config: PretrainedConfig,
1246 - quant_config: Optional[QuantizationConfig],
1246 + quant_config: QuantizationConfig | None,
1247 prefix: str = "",
1248 ) -> nn.Module:
1249 raise NotImplementedError
@@ -1252,7 +1252,7 @@ class MiniCPMVBaseModel(nn.Module, SupportsMultiModal, SupportsPP):
1252 self,
1253 embed_dim: int,
1254 vision_dim: int,
1255 - quant_config: Optional[QuantizationConfig] = None,
1255 + quant_config: QuantizationConfig | None = None,
1256 prefix: str = "",
1257 ) -> nn.Module:
1258 raise NotImplementedError
@@ -1278,7 +1278,7 @@ class MiniCPMV2_0(MiniCPMVBaseModel):
1278 def init_vision_module(
1279 self,
1280 config: PretrainedConfig,
1281 - quant_config: Optional[QuantizationConfig],
1281 + quant_config: QuantizationConfig | None,
1282 prefix: str = "",
1283 ) -> nn.Module:
1284 # TODO: refactor vision model through timm wrapper from transformers
@@ -1313,7 +1313,7 @@ class MiniCPMV2_0(MiniCPMVBaseModel):
1313 self,
1314 embed_dim: int,
1315 vision_dim: int,
1316 - quant_config: Optional[QuantizationConfig] = None,
1316 + quant_config: QuantizationConfig | None = None,
1317 prefix: str = "",
1318 ) -> nn.Module:
1319 with set_default_torch_dtype(torch.float16):
@@ -1381,7 +1381,7 @@ class MiniCPMV2_5(MiniCPMVBaseModel, SupportsLoRA):
1381 def init_vision_module(
1382 self,
1383 config: PretrainedConfig,
1384 - quant_config: Optional[QuantizationConfig],
1384 + quant_config: QuantizationConfig | None,
1385 prefix: str = "",
1386 ) -> nn.Module:
1387 model = Idefics2VisionTransformer(
@@ -1398,7 +1398,7 @@ class MiniCPMV2_5(MiniCPMVBaseModel, SupportsLoRA):
1398 self,
1399 embed_dim: int,
1400 vision_dim: int,
1401 - quant_config: Optional[QuantizationConfig] = None,
1401 + quant_config: QuantizationConfig | None = None,
1402 prefix: str = "",
1403 ) -> nn.Module:
1404 with set_default_torch_dtype(torch.float16):
@@ -1474,7 +1474,7 @@ class MiniCPMV2_6(MiniCPMVBaseModel, SupportsLoRA):
1474 def init_vision_module(
1475 self,
1476 config: PretrainedConfig,
1477 - quant_config: Optional[QuantizationConfig] = None,
1477 + quant_config: QuantizationConfig | None = None,
1478 prefix: str = "",
1479 ) -> nn.Module:
1480 model = Idefics2VisionTransformer(
@@ -1491,7 +1491,7 @@ class MiniCPMV2_6(MiniCPMVBaseModel, SupportsLoRA):
1491 self,
1492 embed_dim: int,
1493 vision_dim: int,
1494 - quant_config: Optional[QuantizationConfig] = None,
1494 + quant_config: QuantizationConfig | None = None,
1495 prefix: str = "",
1496 ) -> nn.Module:
1497 with set_default_torch_dtype(torch.float16):
@@ -1577,7 +1577,7 @@ class MiniCPMV4_0(MiniCPMVBaseModel, SupportsLoRA):
1577 def init_vision_module(
1578 self,
1579 config: PretrainedConfig,
1580 - quant_config: Optional[QuantizationConfig] = None,
1580 + quant_config: QuantizationConfig | None = None,
1581 prefix: str = "",
1582 ) -> nn.Module:
1583 quant_config = self._maybe_ignore_quant_config(quant_config)
@@ -1595,7 +1595,7 @@ class MiniCPMV4_0(MiniCPMVBaseModel, SupportsLoRA):
1595 self,
1596 embed_dim: int,
1597 vision_dim: int,
1598 - quant_config: Optional[QuantizationConfig] = None,
1598 + quant_config: QuantizationConfig | None = None,
1599 prefix: str = "",
1600 ) -> nn.Module:
1601 quant_config = self._maybe_ignore_quant_config(quant_config)
@@ -1682,7 +1682,7 @@ class MiniCPMV4_5(MiniCPMVBaseModel, SupportsLoRA):
1682 def init_vision_module(
1683 self,
1684 config: PretrainedConfig,
1685 - quant_config: Optional[QuantizationConfig] = None,
1685 + quant_config: QuantizationConfig | None = None,
1686 prefix: str = "",
1687 ) -> nn.Module:
1688 quant_config = self._maybe_ignore_quant_config(quant_config)
@@ -1700,7 +1700,7 @@ class MiniCPMV4_5(MiniCPMVBaseModel, SupportsLoRA):
1700 self,
1701 embed_dim: int,
1702 vision_dim: int,
1703 - quant_config: Optional[QuantizationConfig] = None,
1703 + quant_config: QuantizationConfig | None = None,
1704 prefix: str = "",
1705 ) -> nn.Module:
1706 quant_config = self._maybe_ignore_quant_config(quant_config)
vllm/model_executor/models/minimax_text_01.py
+18 -18
@@ -4,7 +4,7 @@
4
5 from collections.abc import Iterable
6 from itertools import islice
7 -from typing import TYPE_CHECKING, Optional, Union
7 +from typing import TYPE_CHECKING
8
9 if TYPE_CHECKING:
10 pass
@@ -83,7 +83,7 @@ class MiniMaxText01MLP(nn.Module):
83 self,
84 hidden_size: int,
85 intermediate_size: int,
86 - quant_config: Optional[QuantizationConfig] = None,
86 + quant_config: QuantizationConfig | None = None,
87 layer_idx: int = None,
88 prefix: str = "mlp",
89 ) -> None:
@@ -121,9 +121,9 @@ class MiniMaxText01MoE(nn.Module):
121 top_k: int,
122 hidden_size: int,
123 intermediate_size: int,
124 - params_dtype: Optional[torch.dtype] = None,
124 + params_dtype: torch.dtype | None = None,
125 layer_idx: int = None,
126 - quant_config: Optional[QuantizationConfig] = None,
126 + quant_config: QuantizationConfig | None = None,
127 prefix: str = "moe",
128 ) -> None:
129 super().__init__()
@@ -191,10 +191,10 @@ class MiniMaxText01Attention(nn.Module):
191 rotary_dim: int,
192 max_position: int = 4096 * 32,
193 rope_theta: float = 10000,
194 - sliding_window: Optional[int] = None,
195 - quant_config: Optional[QuantizationConfig] = None,
194 + sliding_window: int | None = None,
195 + quant_config: QuantizationConfig | None = None,
196 layer_idx: int = None,
197 - cache_config: Optional[CacheConfig] = None,
197 + cache_config: CacheConfig | None = None,
198 prefix: str = "mha",
199 ) -> None:
200 super().__init__()
@@ -273,12 +273,12 @@ class MiniMaxText01DecoderLayer(nn.Module):
273 def __init__(
274 self,
275 config: MiniMaxConfig,
276 - model_config: Optional[ModelConfig] = None,
277 - cache_config: Optional[CacheConfig] = None,
278 - quant_config: Optional[QuantizationConfig] = None,
276 + model_config: ModelConfig | None = None,
277 + cache_config: CacheConfig | None = None,
278 + quant_config: QuantizationConfig | None = None,
279 expert_num: int = 1,
280 layer_id: int = None,
281 - linear_layer_id: Optional[int] = None,
281 + linear_layer_id: int | None = None,
282 prefix: str = "decoder",
283 ) -> None:
284 self._ilayer = layer_id
@@ -428,7 +428,7 @@ class MiniMaxText01DecoderLayer(nn.Module):
428 hidden_states: torch.Tensor,
429 positions: torch.Tensor,
430 attn_metadata: AttentionMetadata,
431 - residual: Optional[torch.Tensor],
431 + residual: torch.Tensor | None,
432 is_warmup: bool = False,
433 **kwargs,
434 ) -> tuple[torch.Tensor, torch.Tensor]:
@@ -627,12 +627,12 @@ class MiniMaxText01Model(nn.Module):
627
628 def forward(
629 self,
630 - input_ids: Optional[torch.Tensor],
630 + input_ids: torch.Tensor | None,
631 positions: torch.Tensor,
632 - intermediate_tensors: Optional[IntermediateTensors] = None,
633 - inputs_embeds: Optional[torch.Tensor] = None,
632 + intermediate_tensors: IntermediateTensors | None = None,
633 + inputs_embeds: torch.Tensor | None = None,
634 **kwargs,
635 - ) -> Union[torch.Tensor, IntermediateTensors]:
635 + ) -> torch.Tensor | IntermediateTensors:
636 forward_context = get_forward_context()
637 attn_metadata = forward_context.attn_metadata
638
@@ -722,8 +722,8 @@ class MiniMaxText01ForCausalLM(nn.Module, HasInnerState, IsHybrid):
722 self,
723 input_ids: torch.Tensor,
724 positions: torch.Tensor,
725 - intermediate_tensors: Optional[IntermediateTensors] = None,
726 - inputs_embeds: Optional[torch.Tensor] = None,
725 + intermediate_tensors: IntermediateTensors | None = None,
726 + inputs_embeds: torch.Tensor | None = None,
727 **kwargs,
728 ) -> torch.Tensor:
729 hidden_states = self.model(
vllm/model_executor/models/minimax_vl_01.py
+19 -19
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable, Mapping
4 -from typing import Annotated, Literal, Optional, Union
4 +from typing import Annotated, Literal, TypeAlias
5
6 import torch
7 import torch.nn as nn
@@ -52,11 +52,11 @@ class MiniMaxVL01ImagePixelInputs(TensorSchema):
52
53 type: Literal["pixel_values"] = "pixel_values"
54 pixel_values: Annotated[
55 - Union[torch.Tensor, list[torch.Tensor]],
55 + torch.Tensor | list[torch.Tensor],
56 TensorShape("bn", "np", 3, "h", "w", dynamic_dims={"np", "h", "w"}),
57 ]
58
59 - image_sizes: Annotated[Optional[torch.Tensor], TensorShape("bn", 2)]
59 + image_sizes: Annotated[torch.Tensor | None, TensorShape("bn", 2)]
60 # This should be in `(height, width)` format.
61
62
@@ -72,9 +72,9 @@ class MiniMaxVL01ImageEmbeddingInputs(TensorSchema):
72 data: Annotated[torch.Tensor, TensorShape("bn", "ifs", "hs")]
73
74
75 -MiniMaxVL01ImageInputs = Union[
76 - MiniMaxVL01ImagePixelInputs, MiniMaxVL01ImageEmbeddingInputs
77 -]
75 +MiniMaxVL01ImageInputs: TypeAlias = (
76 + MiniMaxVL01ImagePixelInputs | MiniMaxVL01ImageEmbeddingInputs
77 +)
78
79
80 class MiniMaxVL01MultiModalProjector(nn.Module):
@@ -84,7 +84,7 @@ class MiniMaxVL01MultiModalProjector(nn.Module):
84 text_hidden_size: int,
85 projector_hidden_act: str,
86 multimodal_projector_bias: bool,
87 - quant_config: Optional[QuantizationConfig] = None,
87 + quant_config: QuantizationConfig | None = None,
88 prefix: str = "",
89 ):
90 super().__init__()
@@ -127,7 +127,7 @@ class MiniMaxVL01ProcessingInfo(LlavaNextProcessingInfo):
127
128 return hf_processor
129
130 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
130 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
131 return {"image": None}
132
133
@@ -187,7 +187,7 @@ class MiniMaxVL01ForConditionalGeneration(nn.Module, SupportsMultiModal, Support
187 }
188
189 @classmethod
190 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
190 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
191 if modality.startswith("image"):
192 return "<image>"
193
@@ -239,9 +239,9 @@ class MiniMaxVL01ForConditionalGeneration(nn.Module, SupportsMultiModal, Support
239
240 def _image_pixels_to_features(
241 self,
242 - vision_tower: Union[CLIPVisionModel, SiglipVisionModel, PixtralHFVisionModel],
243 - pixel_values: Union[torch.Tensor, list[torch.Tensor]],
244 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
242 + vision_tower: CLIPVisionModel | SiglipVisionModel | PixtralHFVisionModel,
243 + pixel_values: torch.Tensor | list[torch.Tensor],
244 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
245 # NOTE: we skip the step to select the vision feature layer since
246 # this is already done inside the vision tower
247 feature_select_strategy = self.config.vision_feature_select_strategy
@@ -302,7 +302,7 @@ class MiniMaxVL01ForConditionalGeneration(nn.Module, SupportsMultiModal, Support
302 def _process_image_pixels(
303 self,
304 inputs: MiniMaxVL01ImagePixelInputs,
305 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
305 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
306 assert self.vision_tower is not None
307
308 pixel_values = inputs["pixel_values"]
@@ -311,7 +311,7 @@ class MiniMaxVL01ForConditionalGeneration(nn.Module, SupportsMultiModal, Support
311 def _process_image_input(
312 self,
313 image_input: MiniMaxVL01ImageInputs,
314 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
314 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
315 if image_input["type"] == "image_embeds":
316 return image_input["data"]
317
@@ -330,7 +330,7 @@ class MiniMaxVL01ForConditionalGeneration(nn.Module, SupportsMultiModal, Support
330
331 def _parse_and_validate_image_input(
332 self, **kwargs: object
333 - ) -> Optional[MiniMaxVL01ImageInputs]:
333 + ) -> MiniMaxVL01ImageInputs | None:
334 pixel_values = kwargs.pop("pixel_values", None)
335 image_sizes = kwargs.pop("image_sizes", None)
336 image_embeds = kwargs.pop("image_embeds", None)
@@ -364,10 +364,10 @@ class MiniMaxVL01ForConditionalGeneration(nn.Module, SupportsMultiModal, Support
364 self,
365 input_ids: torch.Tensor,
366 positions: torch.Tensor,
367 - intermediate_tensors: Optional[IntermediateTensors] = None,
368 - inputs_embeds: Optional[torch.Tensor] = None,
367 + intermediate_tensors: IntermediateTensors | None = None,
368 + inputs_embeds: torch.Tensor | None = None,
369 **kwargs: object,
370 - ) -> Union[torch.Tensor, IntermediateTensors]:
370 + ) -> torch.Tensor | IntermediateTensors:
371 if intermediate_tensors is not None:
372 inputs_embeds = None
373 elif inputs_embeds is None:
@@ -388,7 +388,7 @@ class MiniMaxVL01ForConditionalGeneration(nn.Module, SupportsMultiModal, Support
388 def compute_logits(
389 self,
390 hidden_states: torch.Tensor,
391 - ) -> Optional[torch.Tensor]:
391 + ) -> torch.Tensor | None:
392 return self.language_model.compute_logits(hidden_states)
393
394 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/mistral3.py
+16 -16
@@ -3,7 +3,7 @@
3
4 from abc import abstractmethod
5 from collections.abc import Iterable, Mapping, Sequence
6 -from typing import Annotated, Final, Literal, Optional, Protocol, TypeVar, Union
6 +from typing import Annotated, Final, Literal, Protocol, TypeVar
7
8 import torch
9 import torch.nn as nn
@@ -72,7 +72,7 @@ class Mistral3ImagePixelInputs(TensorSchema):
72 # Note that `height` or `width` may be different per batch and image,
73 # in which case the data is passed as a list instead of a batched tensor.
74 pixel_values: Annotated[
75 - Union[torch.Tensor, list[torch.Tensor]],
75 + torch.Tensor | list[torch.Tensor],
76 TensorShape("bn", 3, "h", "w", dynamic_dims={"h", "w"}),
77 ]
78
@@ -136,7 +136,7 @@ class Mistral3MultiModalProjector(nn.Module):
136 patch_size: int,
137 projector_hidden_act: str,
138 multimodal_projector_bias: bool,
139 - quant_config: Optional[QuantizationConfig] = None,
139 + quant_config: QuantizationConfig | None = None,
140 prefix: str = "",
141 ):
142 super().__init__()
@@ -179,7 +179,7 @@ class LlavaLikeConfig(Protocol):
179 vision_config: Final[PretrainedConfig]
180 image_token_index: Final[int]
181 vision_feature_select_strategy: Final[str]
182 - vision_feature_layer: Final[Union[int, list[int]]]
182 + vision_feature_layer: Final[int | list[int]]
183
184
185 class LlavaLikeProcessor(Protocol):
@@ -197,7 +197,7 @@ class BaseLlavaProcessingInfo(BaseProcessingInfo):
197 def get_hf_processor(self, **kwargs: object) -> LlavaLikeProcessor:
198 raise NotImplementedError
199
200 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
200 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
201 return {"image": None}
202
203 def get_num_image_tokens(
@@ -234,7 +234,7 @@ class Mistral3DummyInputsBuilder(BaseDummyInputsBuilder[_I]):
234 self,
235 seq_len: int,
236 mm_counts: Mapping[str, int],
237 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
237 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
238 ) -> MultiModalDataDict:
239 num_images = mm_counts.get("image", 0)
240
@@ -348,7 +348,7 @@ def _build_mistral3_processor(
348 info: _I,
349 dummy_inputs: BaseDummyInputsBuilder[_I],
350 *,
351 - cache: Optional[BaseMultiModalProcessorCache] = None,
351 + cache: BaseMultiModalProcessorCache | None = None,
352 ) -> BaseMultiModalProcessor:
353 assert isinstance(info, Mistral3ProcessingInfo)
354 return Mistral3MultiModalProcessor(
@@ -394,9 +394,9 @@ def _get_layer_index(feature_layer_index: int, num_hidden_layers: int) -> int:
394
395 def init_vision_tower_for_llava(
396 hf_config: LlavaLikeConfig,
397 - quant_config: Optional[QuantizationConfig],
397 + quant_config: QuantizationConfig | None,
398 *,
399 - require_post_norm: Optional[bool] = None,
399 + require_post_norm: bool | None = None,
400 prefix: str = "",
401 ) -> PixtralHFVisionModel:
402 vision_config = hf_config.vision_config
@@ -441,7 +441,7 @@ class Mistral3ForConditionalGeneration(
441 )
442
443 @classmethod
444 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
444 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
445 if modality.startswith("image"):
446 return None
447
@@ -504,7 +504,7 @@ class Mistral3ForConditionalGeneration(
504
505 def _parse_and_validate_image_input(
506 self, **kwargs: object
507 - ) -> Optional[Mistral3ImagePixelInputs]:
507 + ) -> Mistral3ImagePixelInputs | None:
508 pixel_values = kwargs.pop("pixel_values", None)
509 image_embeds = kwargs.pop("image_embeds", None)
510
@@ -519,7 +519,7 @@ class Mistral3ForConditionalGeneration(
519 def _process_image_input(
520 self,
521 image_input: Mistral3ImagePixelInputs,
522 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
522 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
523 if image_input["type"] == "image_embeds":
524 return image_input["data"]
525
@@ -562,10 +562,10 @@ class Mistral3ForConditionalGeneration(
562 self,
563 input_ids: torch.Tensor,
564 positions: torch.Tensor,
565 - intermediate_tensors: Optional[IntermediateTensors] = None,
566 - inputs_embeds: Optional[torch.Tensor] = None,
565 + intermediate_tensors: IntermediateTensors | None = None,
566 + inputs_embeds: torch.Tensor | None = None,
567 **kwargs: object,
568 - ) -> Union[torch.Tensor, IntermediateTensors]:
568 + ) -> torch.Tensor | IntermediateTensors:
569 """Run forward pass for Mistral3.
570
571 One key thing to understand is the `input_ids` already accounts for the
@@ -615,7 +615,7 @@ class Mistral3ForConditionalGeneration(
615 def compute_logits(
616 self,
617 hidden_states: torch.Tensor,
618 - ) -> Optional[torch.Tensor]:
618 + ) -> torch.Tensor | None:
619 return self.language_model.compute_logits(hidden_states)
620
621 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/mixtral.py
+16 -17
@@ -27,7 +27,6 @@
27 import typing
28 from collections.abc import Callable, Iterable
29 from itertools import islice
30 -from typing import Optional, Union
30
31 import torch
32 from torch import nn
@@ -88,10 +87,10 @@ class MixtralMoE(nn.Module):
87 top_k: int,
88 hidden_size: int,
89 intermediate_size: int,
91 - params_dtype: Optional[torch.dtype] = None,
92 - quant_config: Optional[QuantizationConfig] = None,
93 - tp_size: Optional[int] = None,
94 - dp_size: Optional[int] = None,
90 + params_dtype: torch.dtype | None = None,
91 + quant_config: QuantizationConfig | None = None,
92 + tp_size: int | None = None,
93 + dp_size: int | None = None,
94 prefix: str = "",
95 enable_eplb: bool = False,
96 ):
@@ -163,8 +162,8 @@ class MixtralAttention(nn.Module):
162 num_kv_heads: int,
163 max_position: int = 4096 * 32,
164 rope_theta: float = 10000,
166 - cache_config: Optional[CacheConfig] = None,
167 - quant_config: Optional[QuantizationConfig] = None,
165 + cache_config: CacheConfig | None = None,
166 + quant_config: QuantizationConfig | None = None,
167 prefix: str = "",
168 ) -> None:
169 super().__init__()
@@ -242,8 +241,8 @@ class MixtralDecoderLayer(nn.Module):
241 def __init__(
242 self,
243 config: MixtralConfig,
245 - cache_config: Optional[CacheConfig] = None,
246 - quant_config: Optional[QuantizationConfig] = None,
244 + cache_config: CacheConfig | None = None,
245 + quant_config: QuantizationConfig | None = None,
246 prefix: str = "",
247 enable_eplb: bool = False,
248 ) -> None:
@@ -280,7 +279,7 @@ class MixtralDecoderLayer(nn.Module):
279 self,
280 positions: torch.Tensor,
281 hidden_states: torch.Tensor,
283 - residual: Optional[torch.Tensor],
282 + residual: torch.Tensor | None,
283 ) -> torch.Tensor:
284 # Self Attention
285 if residual is None:
@@ -353,9 +352,9 @@ class MixtralModel(nn.Module):
352 self,
353 input_ids: torch.Tensor,
354 positions: torch.Tensor,
356 - intermediate_tensors: Optional[IntermediateTensors],
357 - inputs_embeds: Optional[torch.Tensor] = None,
358 - ) -> Union[torch.Tensor, IntermediateTensors]:
355 + intermediate_tensors: IntermediateTensors | None,
356 + inputs_embeds: torch.Tensor | None = None,
357 + ) -> torch.Tensor | IntermediateTensors:
358 if get_pp_group().is_first_rank:
359 if inputs_embeds is not None:
360 hidden_states = inputs_embeds
@@ -615,9 +614,9 @@ class MixtralForCausalLM(nn.Module, SupportsLoRA, SupportsPP, MixtureOfExperts):
614 self,
615 input_ids: torch.Tensor,
616 positions: torch.Tensor,
618 - intermediate_tensors: Optional[IntermediateTensors] = None,
619 - inputs_embeds: Optional[torch.Tensor] = None,
620 - ) -> Union[torch.Tensor, IntermediateTensors]:
617 + intermediate_tensors: IntermediateTensors | None = None,
618 + inputs_embeds: torch.Tensor | None = None,
619 + ) -> torch.Tensor | IntermediateTensors:
620 hidden_states = self.model(
621 input_ids, positions, intermediate_tensors, inputs_embeds
622 )
@@ -626,7 +625,7 @@ class MixtralForCausalLM(nn.Module, SupportsLoRA, SupportsPP, MixtureOfExperts):
625 def compute_logits(
626 self,
627 hidden_states: torch.Tensor,
629 - ) -> Optional[torch.Tensor]:
628 + ) -> torch.Tensor | None:
629 logits = self.logits_processor(self.lm_head, hidden_states)
630 return logits
631
vllm/model_executor/models/mllama4.py
+17 -17
@@ -19,7 +19,7 @@
19 import math
20 from collections.abc import Iterable, Mapping
21 from itertools import tee
22 -from typing import Annotated, Literal, Optional, Union
22 +from typing import Annotated, Literal
23
24 import torch
25 from torch import nn
@@ -115,7 +115,7 @@ class Llama4VisionMLP(nn.Module):
115 output_size: int,
116 bias: bool,
117 output_activation: bool,
118 - quant_config: Optional[QuantizationConfig] = None,
118 + quant_config: QuantizationConfig | None = None,
119 prefix: str = "",
120 use_data_parallel: bool = False,
121 ):
@@ -152,7 +152,7 @@ class Llama4MultiModalProjector(nn.Module):
152 def __init__(
153 self,
154 config,
155 - quant_config: Optional[QuantizationConfig] = None,
155 + quant_config: QuantizationConfig | None = None,
156 prefix: str = "",
157 ):
158 super().__init__()
@@ -199,7 +199,7 @@ class Llama4VisionPixelShuffleMLP(nn.Module):
199 def __init__(
200 self,
201 config,
202 - quant_config: Optional[QuantizationConfig] = None,
202 + quant_config: QuantizationConfig | None = None,
203 prefix: str = "",
204 use_data_parallel: bool = False,
205 ):
@@ -229,7 +229,7 @@ class Llama4VisionAttention(nn.Module):
229 def __init__(
230 self,
231 config: Llama4VisionConfig,
232 - quant_config: Optional[QuantizationConfig],
232 + quant_config: QuantizationConfig | None,
233 prefix: str = "",
234 use_data_parallel: bool = False,
235 ):
@@ -323,7 +323,7 @@ class Llama4VisionEncoderLayer(nn.Module):
323 def __init__(
324 self,
325 config: Llama4VisionConfig,
326 - quant_config: Optional[QuantizationConfig],
326 + quant_config: QuantizationConfig | None,
327 prefix: str = "",
328 use_data_parallel: bool = False,
329 ):
@@ -376,7 +376,7 @@ class Llama4VisionEncoder(nn.Module):
376 def __init__(
377 self,
378 config: Llama4VisionConfig,
379 - quant_config: Optional[QuantizationConfig],
379 + quant_config: QuantizationConfig | None,
380 prefix: str = "",
381 use_data_parallel: bool = False,
382 ):
@@ -419,7 +419,7 @@ class Llama4UnfoldConvolution(nn.Module):
419 def __init__(
420 self,
421 config: Llama4VisionConfig,
422 - quant_config: Optional[QuantizationConfig] = None,
422 + quant_config: QuantizationConfig | None = None,
423 prefix: str = "",
424 use_data_parallel: bool = False,
425 ):
@@ -449,7 +449,7 @@ class Llama4VisionModel(nn.Module):
449 def __init__(
450 self,
451 config: Llama4VisionConfig,
452 - quant_config: Optional[QuantizationConfig] = None,
452 + quant_config: QuantizationConfig | None = None,
453 prefix: str = "",
454 use_data_parallel: bool = False,
455 ):
@@ -547,7 +547,7 @@ class Mllama4ProcessingInfo(BaseProcessingInfo):
547 Llama4Processor, use_fast=kwargs.pop("use_fast", True), **kwargs
548 )
549
550 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
550 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
551 # Although vLLM can support more images from an infra capability
552 # perspective, we do not recommend using >10 images in practice.
553 return {"image": None}
@@ -699,7 +699,7 @@ class Mllama4DummyInputsBuilder(BaseDummyInputsBuilder[Mllama4ProcessingInfo]):
699 self,
700 seq_len: int,
701 mm_counts: Mapping[str, int],
702 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
702 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
703 ) -> MultiModalDataDict:
704 num_images = mm_counts.get("image", 0)
705
@@ -733,7 +733,7 @@ class Llama4ForConditionalGeneration(
733 supports_encoder_tp_data = True
734
735 @classmethod
736 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
736 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
737 if modality.startswith("image"):
738 return "<|image|>"
739
@@ -792,7 +792,7 @@ class Llama4ForConditionalGeneration(
792
793 def _parse_and_validate_image_input(
794 self, **kwargs: object
795 - ) -> Optional[Llama4ImagePatchInputs]:
795 + ) -> Llama4ImagePatchInputs | None:
796 # num_images, 1, num_chunks, channel, image_size, image_size
797 pixel_values = kwargs.pop("pixel_values", None)
798 if pixel_values is None:
@@ -849,10 +849,10 @@ class Llama4ForConditionalGeneration(
849 self,
850 input_ids: torch.Tensor,
851 positions: torch.Tensor,
852 - intermediate_tensors: Optional[IntermediateTensors] = None,
853 - inputs_embeds: Optional[torch.Tensor] = None,
852 + intermediate_tensors: IntermediateTensors | None = None,
853 + inputs_embeds: torch.Tensor | None = None,
854 **kwargs: object,
855 - ) -> Union[torch.Tensor, IntermediateTensors]:
855 + ) -> torch.Tensor | IntermediateTensors:
856 if intermediate_tensors is not None:
857 inputs_embeds = None
858
@@ -863,7 +863,7 @@ class Llama4ForConditionalGeneration(
863 def compute_logits(
864 self,
865 hidden_states: torch.Tensor,
866 - ) -> Optional[torch.Tensor]:
866 + ) -> torch.Tensor | None:
867 return self.language_model.compute_logits(hidden_states)
868
869 def separate_weights(
vllm/model_executor/models/modernbert.py
+13 -14
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable, Set
4 -from typing import Optional, Union
4
5 import torch
6 from torch import nn
@@ -50,7 +49,7 @@ class ModernBertEmbeddings(nn.Module):
49 def forward(
50 self,
51 input_ids: torch.Tensor,
53 - inputs_embeds: Optional[torch.Tensor] = None,
52 + inputs_embeds: torch.Tensor | None = None,
53 ) -> torch.Tensor:
54 if inputs_embeds is not None:
55 return self.norm(inputs_embeds)
@@ -74,7 +73,7 @@ class ModernBertRotaryEmbedding(RotaryEmbedding):
73
74
75 class ModernBertAttention(nn.Module):
77 - def __init__(self, config: ModernBertConfig, layer_id: Optional[int] = None):
76 + def __init__(self, config: ModernBertConfig, layer_id: int | None = None):
77 super().__init__()
78 self.config = config
79 self.hidden_size = config.hidden_size
@@ -151,7 +150,7 @@ class ModernBertMLP(nn.Module):
150
151 class ModernBertLayer(nn.Module):
152 def __init__(
154 - self, config: ModernBertConfig, prefix: str = "", layer_id: Optional[int] = None
153 + self, config: ModernBertConfig, prefix: str = "", layer_id: int | None = None
154 ):
155 super().__init__()
156 self.config = config
@@ -243,8 +242,8 @@ class ModernBertModel(nn.Module):
242 self,
243 input_ids: torch.Tensor,
244 positions: torch.Tensor,
246 - intermediate_tensors: Optional[IntermediateTensors] = None,
247 - inputs_embeds: Optional[torch.Tensor] = None,
245 + intermediate_tensors: IntermediateTensors | None = None,
246 + inputs_embeds: torch.Tensor | None = None,
247 ) -> torch.Tensor:
248 if inputs_embeds is not None:
249 hidden_states = inputs_embeds
@@ -287,9 +286,9 @@ class ModernBertPooler(Pooler):
286
287 def forward(
288 self,
290 - hidden_states: Union[torch.Tensor, list[torch.Tensor]],
289 + hidden_states: torch.Tensor | list[torch.Tensor],
290 pooling_metadata: PoolingMetadata,
292 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
291 + ) -> torch.Tensor | list[torch.Tensor]:
292 pooled_output = self.pooling(hidden_states, pooling_metadata)
293
294 if isinstance(pooled_output, list):
@@ -370,10 +369,10 @@ class ModernBertForSequenceClassification(nn.Module, SupportsCrossEncoding):
369
370 def forward(
371 self,
373 - input_ids: Optional[torch.LongTensor],
372 + input_ids: torch.LongTensor | None,
373 positions: torch.Tensor,
375 - intermediate_tensors: Optional[IntermediateTensors] = None,
376 - inputs_embeds: Optional[torch.Tensor] = None,
374 + intermediate_tensors: IntermediateTensors | None = None,
375 + inputs_embeds: torch.Tensor | None = None,
376 ) -> torch.Tensor:
377 return self.model(
378 input_ids=input_ids,
@@ -436,10 +435,10 @@ class ModernBertForTokenClassification(nn.Module):
435
436 def forward(
437 self,
439 - input_ids: Optional[torch.Tensor],
438 + input_ids: torch.Tensor | None,
439 positions: torch.Tensor,
441 - intermediate_tensors: Optional[IntermediateTensors] = None,
442 - inputs_embeds: Optional[torch.Tensor] = None,
440 + intermediate_tensors: IntermediateTensors | None = None,
441 + inputs_embeds: torch.Tensor | None = None,
442 ) -> torch.Tensor:
443 hidden_states = self.model(
444 input_ids=input_ids,
vllm/model_executor/models/module_mapping.py
+4 -5
@@ -5,7 +5,6 @@
5 # https://github.com/modelscope/ms-swift/blob/v2.4.2/swift/utils/module_mapping.py
6
7 from dataclasses import dataclass, field
8 -from typing import Union
8
9
10 @dataclass
@@ -55,10 +54,10 @@ class MultiModelKeys(ModelKeys):
54
55 @staticmethod
56 def from_string_field(
58 - language_model: Union[str, list[str]] = None,
59 - connector: Union[str, list[str]] = None,
60 - tower_model: Union[str, list[str]] = None,
61 - generator: Union[str, list[str]] = None,
57 + language_model: str | list[str] = None,
58 + connector: str | list[str] = None,
59 + tower_model: str | list[str] = None,
60 + generator: str | list[str] = None,
61 **kwargs,
62 ) -> "MultiModelKeys":
63 def to_list(value):
vllm/model_executor/models/molmo.py
+40 -40
@@ -6,7 +6,7 @@ from collections.abc import Iterable, Mapping, Sequence
6 from dataclasses import dataclass
7 from functools import cached_property, partial
8 from itertools import islice
9 -from typing import Annotated, Optional, Union
9 +from typing import Annotated
10
11 import numpy as np
12 import torch
@@ -104,18 +104,18 @@ class MolmoImageInputs(TensorSchema):
104 """
105
106 images: Annotated[
107 - Union[torch.Tensor, list[torch.Tensor]],
107 + torch.Tensor | list[torch.Tensor],
108 TensorShape("bn", "nc", "np", "pd", dynamic_dims={"nc"}),
109 ]
110 # Number of crops may vary per batch and image, so pass it as a list.
111
112 image_masks: Annotated[
113 - Optional[Union[torch.Tensor, list[torch.Tensor]]],
113 + torch.Tensor | list[torch.Tensor] | None,
114 TensorShape("bn", "nc", "np", dynamic_dims={"nc"}),
115 ]
116
117 image_input_idx: Annotated[
118 - Union[torch.Tensor, list[torch.Tensor]],
118 + torch.Tensor | list[torch.Tensor],
119 TensorShape("bn", "nc", "tp", dynamic_dims={"nc"}),
120 ]
121 # An index tensor that maps image features to their corresponding patch tokens.
@@ -151,7 +151,7 @@ class ViTMLP(nn.Module):
151 def __init__(
152 self,
153 config: VisionBackboneConfig,
154 - quant_config: Optional[QuantizationConfig] = None,
154 + quant_config: QuantizationConfig | None = None,
155 ):
156 super().__init__()
157 self.w1 = ColumnParallelLinear(
@@ -185,7 +185,7 @@ class MultiHeadDotProductAttention(nn.Module):
185 config: VisionBackboneConfig,
186 use_bias: bool = True,
187 nlayers: int = 1,
188 - quant_config: Optional[QuantizationConfig] = None,
188 + quant_config: QuantizationConfig | None = None,
189 ):
190 super().__init__()
191
@@ -238,7 +238,7 @@ class MultiHeadDotProductAttention(nn.Module):
238 )
239
240 def forward(
241 - self, inputs_q: torch.Tensor, inputs_kv: Optional[torch.Tensor] = None
241 + self, inputs_q: torch.Tensor, inputs_kv: torch.Tensor | None = None
242 ) -> torch.Tensor:
243 if inputs_kv is not None:
244 inputs_k = inputs_kv
@@ -263,7 +263,7 @@ class ResidualAttentionBlock(nn.Module):
263 def __init__(
264 self,
265 config: VisionBackboneConfig,
266 - quant_config: Optional[QuantizationConfig] = None,
266 + quant_config: QuantizationConfig | None = None,
267 ):
268 super().__init__()
269 self.attention = MultiHeadDotProductAttention(config, quant_config=quant_config)
@@ -289,7 +289,7 @@ class BlockCollection(nn.Module):
289 def __init__(
290 self,
291 config: VisionBackboneConfig,
292 - quant_config: Optional[QuantizationConfig] = None,
292 + quant_config: QuantizationConfig | None = None,
293 ):
294 super().__init__()
295 self.resblocks = nn.ModuleList(
@@ -317,7 +317,7 @@ class VisionTransformer(nn.Module):
317 def __init__(
318 self,
319 config: VisionBackboneConfig,
320 - quant_config: Optional[QuantizationConfig] = None,
320 + quant_config: QuantizationConfig | None = None,
321 ):
322 super().__init__()
323 scale = config.image_emb_dim**-0.5
@@ -367,7 +367,7 @@ class VisionTransformer(nn.Module):
367 return x
368
369 def forward(
370 - self, x: torch.Tensor, patch_num: Optional[int] = None
370 + self, x: torch.Tensor, patch_num: int | None = None
371 ) -> list[torch.Tensor]:
372 """
373 : param x: (batch_size, num_patch, n_pixels)
@@ -396,8 +396,8 @@ class MolmoAttention(nn.Module):
396 def __init__(
397 self,
398 config: PretrainedConfig,
399 - cache_config: Optional[CacheConfig] = None,
400 - quant_config: Optional[QuantizationConfig] = None,
399 + cache_config: CacheConfig | None = None,
400 + quant_config: QuantizationConfig | None = None,
401 prefix: str = "",
402 ) -> None:
403 super().__init__()
@@ -432,9 +432,9 @@ class MolmoAttention(nn.Module):
432 quant_config=quant_config,
433 )
434
435 - self.tp_rank: Optional[int] = None
436 - self.k_norm: Optional[nn.Module] = None
437 - self.q_norm: Optional[nn.Module] = None
435 + self.tp_rank: int | None = None
436 + self.k_norm: nn.Module | None = None
437 + self.q_norm: nn.Module | None = None
438 if config.attention_layer_norm:
439 self.tp_rank = get_tensor_model_parallel_rank()
440 self.k_norm = RMSNorm(
@@ -503,8 +503,8 @@ class LanguageModelMLP(nn.Module):
503 def __init__(
504 self,
505 config: PretrainedConfig,
506 - input_dim: Optional[int] = None,
507 - quant_config: Optional[QuantizationConfig] = None,
506 + input_dim: int | None = None,
507 + quant_config: QuantizationConfig | None = None,
508 ) -> None:
509 super().__init__()
510 self.hidden_size = config.hidden_size
@@ -542,8 +542,8 @@ class ImageProjectorMLP(nn.Module):
542 def __init__(
543 self,
544 config: PretrainedConfig,
545 - input_dim: Optional[int] = None,
546 - quant_config: Optional[QuantizationConfig] = None,
545 + input_dim: int | None = None,
546 + quant_config: QuantizationConfig | None = None,
547 ) -> None:
548 super().__init__()
549 self.hidden_size = config.hidden_size
@@ -580,8 +580,8 @@ class MolmoDecoderLayer(nn.Module):
580 def __init__(
581 self,
582 config: PretrainedConfig,
583 - cache_config: Optional[CacheConfig] = None,
584 - quant_config: Optional[QuantizationConfig] = None,
583 + cache_config: CacheConfig | None = None,
584 + quant_config: QuantizationConfig | None = None,
585 prefix: str = "",
586 ) -> None:
587 super().__init__()
@@ -604,8 +604,8 @@ class MolmoDecoderLayer(nn.Module):
604 self,
605 positions: torch.Tensor,
606 hidden_states: torch.Tensor,
607 - residual: Optional[torch.Tensor],
608 - ) -> tuple[torch.Tensor, Optional[tuple[torch.Tensor, torch.Tensor]]]:
607 + residual: torch.Tensor | None,
608 + ) -> tuple[torch.Tensor, tuple[torch.Tensor, torch.Tensor] | None]:
609 # Self Attention
610 if residual is None:
611 residual = hidden_states
@@ -627,8 +627,8 @@ class MolmoDecoderNormAfterLayer(MolmoDecoderLayer):
627 self,
628 positions: torch.Tensor,
629 hidden_states: torch.Tensor,
630 - residual: Optional[torch.Tensor],
631 - ) -> tuple[torch.Tensor, Optional[tuple[torch.Tensor, torch.Tensor]]]:
630 + residual: torch.Tensor | None,
631 + ) -> tuple[torch.Tensor, tuple[torch.Tensor, torch.Tensor] | None]:
632 # Self Attention
633 residual = hidden_states
634 hidden_states = self.self_attn(
@@ -654,7 +654,7 @@ class MolmoVisionBackbone(nn.Module, SupportsQuant):
654 self,
655 config: PretrainedConfig,
656 vision_config: VisionBackboneConfig,
657 - quant_config: Optional[QuantizationConfig] = None,
657 + quant_config: QuantizationConfig | None = None,
658 ) -> None:
659 super().__init__()
660 self.vit_layers = VIT_LAYERS
@@ -849,8 +849,8 @@ class MolmoModel(nn.Module, SupportsQuant):
849 self,
850 input_ids: torch.Tensor,
851 positions: torch.Tensor,
852 - intermediate_tensors: Optional[IntermediateTensors] = None,
853 - inputs_embeds: Optional[torch.Tensor] = None,
852 + intermediate_tensors: IntermediateTensors | None = None,
853 + inputs_embeds: torch.Tensor | None = None,
854 ) -> torch.Tensor:
855 if get_pp_group().is_first_rank:
856 if inputs_embeds is not None:
@@ -1064,7 +1064,7 @@ class MolmoProcessorWrapper:
1064 return image_token_length_h
1065
1066 @property
1067 - def message_format(self) -> Optional[str]:
1067 + def message_format(self) -> str | None:
1068 return "role"
1069
1070 @property
@@ -1145,9 +1145,9 @@ class MolmoProcessorWrapper:
1145
1146 def __call__(
1147 self,
1148 - text: Optional[Union[TextInput, list[TextInput]]] = None,
1149 - images: Optional[Union[ImageInput, list[ImageInput]]] = None,
1150 - return_tensors: Optional[Union[str, TensorType]] = None,
1148 + text: TextInput | list[TextInput] | None = None,
1149 + images: ImageInput | list[ImageInput] | None = None,
1150 + return_tensors: str | TensorType | None = None,
1151 **kwargs,
1152 ) -> BatchFeature:
1153 outputs = self.processor.process( # type: ignore
@@ -1189,7 +1189,7 @@ class MolmoProcessingInfo(BaseProcessingInfo):
1189 processor = self.ctx.get_hf_processor(**kwargs)
1190 return MolmoProcessorWrapper(processor)
1191
1192 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
1192 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
1193 return {"image": None}
1194
1195 def get_num_image_tokens(
@@ -1197,7 +1197,7 @@ class MolmoProcessingInfo(BaseProcessingInfo):
1197 *,
1198 image_width: int,
1199 image_height: int,
1200 - processor: Optional[MolmoProcessorWrapper],
1200 + processor: MolmoProcessorWrapper | None,
1201 ) -> int:
1202 if processor is None:
1203 processor = self.get_hf_processor()
@@ -1250,7 +1250,7 @@ class MolmoDummyInputsBuilder(BaseDummyInputsBuilder[MolmoProcessingInfo]):
1250 self,
1251 seq_len: int,
1252 mm_counts: Mapping[str, int],
1253 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
1253 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
1254 ) -> MultiModalDataDict:
1255 target_width, target_height = self.info.get_image_size_with_most_features()
1256 num_images = mm_counts.get("image", 0)
@@ -1398,7 +1398,7 @@ class MolmoForCausalLM(
1398 }
1399
1400 @classmethod
1401 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1401 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1402 if modality.startswith("image"):
1403 return None
1404
@@ -1442,7 +1442,7 @@ class MolmoForCausalLM(
1442 def _parse_and_validate_image_input(
1443 self,
1444 **kwargs: object,
1445 - ) -> Optional[MolmoImageInputs]:
1445 + ) -> MolmoImageInputs | None:
1446 images = kwargs.pop("images", None)
1447 image_masks = kwargs.pop("image_masks", None)
1448 image_input_idx = kwargs.pop("image_input_idx", None)
@@ -1522,8 +1522,8 @@ class MolmoForCausalLM(
1522 self,
1523 input_ids: torch.LongTensor,
1524 positions: torch.LongTensor,
1525 - intermediate_tensors: Optional[IntermediateTensors] = None,
1526 - inputs_embeds: Optional[torch.Tensor] = None,
1525 + intermediate_tensors: IntermediateTensors | None = None,
1526 + inputs_embeds: torch.Tensor | None = None,
1527 **kwargs: object,
1528 ) -> torch.Tensor:
1529 if intermediate_tensors is not None:
vllm/model_executor/models/moonvit.py
+7 -8
@@ -45,7 +45,6 @@
45 from collections.abc import Sequence
46 from copy import deepcopy
47 from functools import cached_property
48 -from typing import Optional, Union
48
49 import torch
50 import torch.nn as nn
@@ -68,8 +67,8 @@ def multihead_attention(
67 q: torch.Tensor,
68 k: torch.Tensor,
69 v: torch.Tensor,
71 - q_cu_seqlens: Optional[torch.Tensor] = None,
72 - k_cu_seqlens: Optional[torch.Tensor] = None,
70 + q_cu_seqlens: torch.Tensor | None = None,
71 + k_cu_seqlens: torch.Tensor | None = None,
72 ) -> torch.Tensor:
73 """Multi-head attention using flash attention 2.
74
@@ -121,8 +120,8 @@ def sdpa_attention(
120 q: torch.Tensor,
121 k: torch.Tensor,
122 v: torch.Tensor,
124 - q_cu_seqlens: Optional[torch.Tensor] = None,
125 - k_cu_seqlens: Optional[torch.Tensor] = None,
123 + q_cu_seqlens: torch.Tensor | None = None,
124 + k_cu_seqlens: torch.Tensor | None = None,
125 ) -> torch.Tensor:
126 """SDPA attention.
127
@@ -230,7 +229,7 @@ class MoonVisionPatchEmbed(nn.Module):
229 self,
230 out_dim: int,
231 in_dim: int = 3,
233 - patch_size: Union[int, tuple[int, int]] = (14, 14),
232 + patch_size: int | tuple[int, int] = (14, 14),
233 pos_emb_height: int = 14,
234 pos_emb_width: int = 14,
235 ):
@@ -460,7 +459,7 @@ class MoonVitEncoderLayer(nn.Module):
459 self,
460 x: torch.Tensor,
461 cu_seqlens: torch.Tensor,
463 - rope_freqs_cis: Optional[torch.Tensor] = None,
462 + rope_freqs_cis: torch.Tensor | None = None,
463 ):
464 """
465 Args:
@@ -491,7 +490,7 @@ class MoonVitEncoderLayer(nn.Module):
490 self,
491 hidden_states: torch.Tensor,
492 cu_seqlens: torch.Tensor,
494 - rope_freqs_cis: Union[torch.Tensor, None] = None,
493 + rope_freqs_cis: torch.Tensor | None = None,
494 ) -> torch.Tensor:
495 """
496 Args:
vllm/model_executor/models/mpt.py
+12 -13
@@ -5,7 +5,6 @@
5 import math
6 from collections.abc import Iterable
7 from itertools import islice
8 -from typing import Optional, Union
8
9 import torch
10 import torch.nn as nn
@@ -58,8 +57,8 @@ class MPTAttention(nn.Module):
57 def __init__(
58 self,
59 config: MptConfig,
61 - cache_config: Optional[CacheConfig] = None,
62 - quant_config: Optional[QuantizationConfig] = None,
60 + cache_config: CacheConfig | None = None,
61 + quant_config: QuantizationConfig | None = None,
62 prefix: str = "",
63 ):
64 super().__init__()
@@ -152,7 +151,7 @@ class MPTMLP(nn.Module):
151 def __init__(
152 self,
153 config: MptConfig,
155 - quant_config: Optional[QuantizationConfig] = None,
154 + quant_config: QuantizationConfig | None = None,
155 ):
156 super().__init__()
157 hidden_size = config.d_model
@@ -183,8 +182,8 @@ class MPTBlock(nn.Module):
182 def __init__(
183 self,
184 config: MptConfig,
186 - cache_config: Optional[CacheConfig] = None,
187 - quant_config: Optional[QuantizationConfig] = None,
185 + cache_config: CacheConfig | None = None,
186 + quant_config: QuantizationConfig | None = None,
187 prefix: str = "",
188 ):
189 super().__init__()
@@ -251,9 +250,9 @@ class MPTModel(nn.Module):
250 self,
251 input_ids: torch.Tensor,
252 position_ids: torch.Tensor,
254 - intermediate_tensors: Optional[IntermediateTensors],
255 - inputs_embeds: Optional[torch.Tensor] = None,
256 - ) -> Union[torch.Tensor, IntermediateTensors]:
253 + intermediate_tensors: IntermediateTensors | None,
254 + inputs_embeds: torch.Tensor | None = None,
255 + ) -> torch.Tensor | IntermediateTensors:
256 if get_pp_group().is_first_rank:
257 if inputs_embeds is not None:
258 hidden_states = inputs_embeds
@@ -311,9 +310,9 @@ class MPTForCausalLM(nn.Module, SupportsPP):
310 self,
311 input_ids: torch.Tensor,
312 positions: torch.Tensor,
314 - intermediate_tensors: Optional[IntermediateTensors] = None,
315 - inputs_embeds: Optional[torch.Tensor] = None,
316 - ) -> Union[torch.Tensor, IntermediateTensors]:
313 + intermediate_tensors: IntermediateTensors | None = None,
314 + inputs_embeds: torch.Tensor | None = None,
315 + ) -> torch.Tensor | IntermediateTensors:
316 hidden_states = self.transformer(
317 input_ids, positions, intermediate_tensors, inputs_embeds
318 )
@@ -322,7 +321,7 @@ class MPTForCausalLM(nn.Module, SupportsPP):
321 def compute_logits(
322 self,
323 hidden_states: torch.Tensor,
325 - ) -> Optional[torch.Tensor]:
324 + ) -> torch.Tensor | None:
325 logits = self.logits_processor(self.lm_head, hidden_states)
326 return logits
327
vllm/model_executor/models/nano_nemotron_vl.py
+45 -45
@@ -11,7 +11,7 @@ import copy
11 import warnings
12 from abc import ABC, abstractmethod
13 from collections.abc import Iterable, Mapping, Sequence
14 -from typing import Annotated, Any, Literal, Optional, TypedDict, TypeVar, Union
14 +from typing import Annotated, Any, Literal, TypeAlias, TypedDict, TypeVar
15
16 import numpy.typing as npt
17 import torch
@@ -110,7 +110,7 @@ class NanoNemotronVLImagePixelInputs(TypedDict):
110
111 class NanoNemotronVLImageEmbeddinInputs(TypedDict):
112 type: Literal["image_embeds"]
113 - data: Union[torch.Tensor, list[torch.Tensor]]
113 + data: torch.Tensor | list[torch.Tensor]
114 """
115 A tensor of shape `(num_images, total_image_feature_size, hidden_size)`
116 or a list of tensors of shape `(total_image_feature_size, hidden_size)`
@@ -119,9 +119,9 @@ class NanoNemotronVLImageEmbeddinInputs(TypedDict):
119 """
120
121
122 -NanoNemotronVLImageInputs = Union[
123 - NanoNemotronVLImagePixelInputs, NanoNemotronVLImageEmbeddinInputs
124 -]
122 +NanoNemotronVLImageInputs: TypeAlias = (
123 + NanoNemotronVLImagePixelInputs | NanoNemotronVLImageEmbeddinInputs
124 +)
125
126
127 class NanoNemotronVLVideoPixelInputs(TensorSchema):
@@ -148,12 +148,12 @@ class NanoNemotronVLVideoEmbeddingInputs(TensorSchema):
148 """
149
150 type: Literal["video_embeds"]
151 - data: Annotated[Union[torch.Tensor, list[torch.Tensor]], TensorShape("n", "f", "h")]
151 + data: Annotated[torch.Tensor | list[torch.Tensor], TensorShape("n", "f", "h")]
152
153
154 -NanoNemotronVLVideoInputs = Union[
155 - NanoNemotronVLVideoPixelInputs, NanoNemotronVLVideoEmbeddingInputs
156 -]
154 +NanoNemotronVLVideoInputs: TypeAlias = (
155 + NanoNemotronVLVideoPixelInputs | NanoNemotronVLVideoEmbeddingInputs
156 +)
157
158
159 def dynamic_preprocess(
@@ -262,7 +262,7 @@ class BaseNanoNemotronVLProcessor(ABC):
262 config: PretrainedConfig,
263 tokenizer: AnyTokenizer,
264 *args,
265 - max_num_tiles: Optional[int] = None,
265 + max_num_tiles: int | None = None,
266 **kwargs,
267 ) -> None:
268 super().__init__()
@@ -291,7 +291,7 @@ class BaseNanoNemotronVLProcessor(ABC):
291 def get_image_repl(
292 self,
293 feature_size: int,
294 - num_patches: Optional[int],
294 + num_patches: int | None,
295 ) -> PromptUpdateDetails[str]:
296 raise NotImplementedError
297
@@ -354,7 +354,7 @@ class BaseNanoNemotronVLProcessor(ABC):
354 text = [t.replace("<image>", image_repl.full, 1) for t in text]
355 return text, image_inputs
356
357 - def _make_batch_input(self, input_item: Optional[Union[Any, list[Any]]] = None):
357 + def _make_batch_input(self, input_item: Any | list[Any] | None = None):
358 if input_item is None:
359 input_item = []
360 if not isinstance(input_item, list):
@@ -363,10 +363,10 @@ class BaseNanoNemotronVLProcessor(ABC):
363
364 def __call__(
365 self,
366 - text: Optional[Union[str, list[str]]] = None,
367 - images: Optional[Union[Image.Image, list[Image.Image]]] = None,
368 - return_tensors: Optional[Union[str, TensorType]] = None,
369 - max_num_tiles: Optional[int] = None,
366 + text: str | list[str] | None = None,
367 + images: Image.Image | list[Image.Image] | None = None,
368 + return_tensors: str | TensorType | None = None,
369 + max_num_tiles: int | None = None,
370 ) -> BatchFeature:
371 # Use default if not provided
372 if max_num_tiles is None:
@@ -399,12 +399,12 @@ class NanoNemotronVLProcessor(BaseNanoNemotronVLProcessor):
399 config: PretrainedConfig,
400 tokenizer: AnyTokenizer,
401 *,
402 - max_num_tiles: Optional[int] = None,
403 - min_dynamic_patch: Optional[int] = None,
404 - max_dynamic_patch: Optional[int] = None,
405 - dynamic_image_size: Optional[bool] = None,
406 - video_token: Optional[str] = None,
407 - video_pruning_rate: Optional[float] = None,
402 + max_num_tiles: int | None = None,
403 + min_dynamic_patch: int | None = None,
404 + max_dynamic_patch: int | None = None,
405 + dynamic_image_size: bool | None = None,
406 + video_token: str | None = None,
407 + video_pruning_rate: float | None = None,
408 ) -> None:
409 super().__init__(
410 config=config,
@@ -423,7 +423,7 @@ class NanoNemotronVLProcessor(BaseNanoNemotronVLProcessor):
423 return self.video_token_id is not None
424
425 @property
426 - def video_token_id(self) -> Optional[int]:
426 + def video_token_id(self) -> int | None:
427 if self.video_token is None:
428 return None
429 return self.tokenizer.get_vocab().get(self.video_token, None)
@@ -436,7 +436,7 @@ class NanoNemotronVLProcessor(BaseNanoNemotronVLProcessor):
436 self,
437 videos: list[npt.NDArray],
438 max_num_tiles: int,
439 - dynamic_image_size: Optional[bool] = None,
439 + dynamic_image_size: bool | None = None,
440 ) -> list[torch.Tensor]:
441 return [
442 video_to_pixel_values(
@@ -453,7 +453,7 @@ class NanoNemotronVLProcessor(BaseNanoNemotronVLProcessor):
453 text: list[str],
454 videos: list[npt.NDArray],
455 max_num_tiles: int,
456 - dynamic_image_size: Optional[bool] = None,
456 + dynamic_image_size: bool | None = None,
457 ):
458 if len(videos) == 0 or not self.supports_video:
459 video_inputs = {}
@@ -508,12 +508,12 @@ class NanoNemotronVLProcessor(BaseNanoNemotronVLProcessor):
508
509 def __call__(
510 self,
511 - text: Optional[Union[str, list[str]]] = None,
512 - images: Optional[Union[Image.Image, list[Image.Image]]] = None,
513 - videos: Optional[Union[npt.NDArray, list[npt.NDArray]]] = None,
514 - return_tensors: Optional[Union[str, TensorType]] = None,
515 - max_num_tiles: Optional[int] = None,
516 - dynamic_image_size: Optional[bool] = None,
511 + text: str | list[str] | None = None,
512 + images: Image.Image | list[Image.Image] | None = None,
513 + videos: npt.NDArray | list[npt.NDArray] | None = None,
514 + return_tensors: str | TensorType | None = None,
515 + max_num_tiles: int | None = None,
516 + dynamic_image_size: bool | None = None,
517 ) -> BatchFeature:
518 # Use default if not provided
519 if max_num_tiles is None:
@@ -545,7 +545,7 @@ class NanoNemotronVLProcessor(BaseNanoNemotronVLProcessor):
545 def get_image_repl(
546 self,
547 feature_size: int,
548 - num_patches: Optional[int],
548 + num_patches: int | None,
549 ) -> PromptUpdateDetails[str]:
550 repl_features = IMG_CONTEXT * feature_size
551 repl_full = IMG_START + repl_features + IMG_END
@@ -598,7 +598,7 @@ class BaseNanoNemotronVLProcessingInfo(BaseProcessingInfo):
598 ) -> BaseNanoNemotronVLProcessor:
599 raise NotImplementedError
600
601 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
601 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
602 return {"image": None}
603
604 def get_num_image_tokens(
@@ -607,7 +607,7 @@ class BaseNanoNemotronVLProcessingInfo(BaseProcessingInfo):
607 image_width: int,
608 image_height: int,
609 max_num_tiles: int,
610 - processor: Optional[BaseNanoNemotronVLProcessor],
610 + processor: BaseNanoNemotronVLProcessor | None,
611 ) -> int:
612 if processor is None:
613 processor = self.get_hf_processor()
@@ -673,10 +673,10 @@ class NanoNemotronVLProcessingInfo(BaseNanoNemotronVLProcessingInfo):
673 video_limit = {"video": None} if self.supports_video else {}
674 return {**super().get_supported_mm_limits(), **video_limit}
675
676 - def get_video_token(self) -> Optional[str]:
676 + def get_video_token(self) -> str | None:
677 return IMG_CONTEXT
678
679 - def get_video_pruning_rate(self) -> Optional[float]:
679 + def get_video_pruning_rate(self) -> float | None:
680 return self.ctx.get_mm_config().video_pruning_rate
681
682 def get_num_frames_with_most_features(
@@ -929,7 +929,7 @@ class NanoNemotronVLDummyInputsBuilder(BaseDummyInputsBuilder[_I]):
929 self,
930 seq_len: int,
931 mm_counts: Mapping[str, int],
932 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
932 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
933 ) -> MultiModalDataDict:
934 # Use default max_num_tiles for dummy data generation
935 max_num_tiles = 12
@@ -964,7 +964,7 @@ class NanoNemotronVLDummyInputsBuilder(
964 self,
965 seq_len: int,
966 mm_counts: Mapping[str, int],
967 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
967 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
968 ) -> MultiModalDataDict:
969 dummy_image = super().get_dummy_mm_data(
970 seq_len=seq_len, mm_counts=mm_counts, mm_options=mm_options
@@ -1000,7 +1000,7 @@ class NemotronH_Nano_VL_V2(
1000 nn.Module, HasInnerState, IsHybrid, SupportsMultiModal, SupportsMultiModalPruning
1001 ):
1002 @classmethod
1003 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1003 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1004 if modality.startswith("image"):
1005 return "<image>"
1006 if modality.startswith("video"):
@@ -1097,7 +1097,7 @@ class NemotronH_Nano_VL_V2(
1097
1098 def _parse_and_validate_image_input(
1099 self, **kwargs: object
1100 - ) -> Optional[NanoNemotronVLImageInputs]:
1100 + ) -> NanoNemotronVLImageInputs | None:
1101 pixel_values_flat = kwargs.pop("pixel_values_flat", None)
1102 image_num_patches = kwargs.pop("image_num_patches", None)
1103 image_embeds = kwargs.pop("image_embeds", None)
@@ -1274,7 +1274,7 @@ class NemotronH_Nano_VL_V2(
1274
1275 def _parse_and_validate_video_input(
1276 self, **kwargs: object
1277 - ) -> Optional[NanoNemotronVLVideoPixelInputs]:
1277 + ) -> NanoNemotronVLVideoPixelInputs | None:
1278 pixel_values_flat_video = kwargs.pop("pixel_values_flat_video", None)
1279 video_num_patches = kwargs.pop("video_num_patches", None)
1280 video_embeds = kwargs.pop("video_embeds", None)
@@ -1365,10 +1365,10 @@ class NemotronH_Nano_VL_V2(
1365 self,
1366 input_ids: torch.Tensor,
1367 positions: torch.Tensor,
1368 - intermediate_tensors: Optional[IntermediateTensors] = None,
1369 - inputs_embeds: Optional[torch.Tensor] = None,
1368 + intermediate_tensors: IntermediateTensors | None = None,
1369 + inputs_embeds: torch.Tensor | None = None,
1370 **kwargs: object,
1371 - ) -> Union[torch.Tensor, IntermediateTensors]:
1371 + ) -> torch.Tensor | IntermediateTensors:
1372 if intermediate_tensors is not None:
1373 input_ids = None
1374 inputs_embeds = None
@@ -1396,7 +1396,7 @@ class NemotronH_Nano_VL_V2(
1396 def compute_logits(
1397 self,
1398 hidden_states: torch.Tensor,
1399 - ) -> Optional[torch.Tensor]:
1399 + ) -> torch.Tensor | None:
1400 return self.language_model.compute_logits(hidden_states)
1401
1402 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]):
vllm/model_executor/models/nemotron.py
+18 -18
@@ -26,7 +26,7 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Any, Optional, Union
29 +from typing import Any
30
31 import torch
32 from torch import nn
@@ -85,7 +85,7 @@ def _cast_if_autocast_enabled(*args):
85 class NemotronLayerNorm1P(nn.LayerNorm):
86 def __init__(
87 self,
88 - normalized_shape: Union[int, list[int], torch.Size],
88 + normalized_shape: int | list[int] | torch.Size,
89 eps: float = 1e-5,
90 elementwise_affine: bool = True,
91 bias: bool = True,
@@ -97,7 +97,7 @@ class NemotronLayerNorm1P(nn.LayerNorm):
97 def forward(
98 self,
99 x: torch.Tensor,
100 - residual: Optional[torch.Tensor] = None,
100 + residual: torch.Tensor | None = None,
101 ) -> torch.Tensor:
102 if residual is not None:
103 x = x + residual
@@ -116,7 +116,7 @@ class NemotronMLP(nn.Module):
116 hidden_size: int,
117 intermediate_size: int,
118 hidden_act: str,
119 - quant_config: Optional[QuantizationConfig] = None,
119 + quant_config: QuantizationConfig | None = None,
120 bias: bool = False,
121 prefix: str = "",
122 ) -> None:
@@ -152,11 +152,11 @@ class NemotronAttention(nn.Module):
152 num_heads: int,
153 num_kv_heads: int,
154 rope_theta: float = 10000,
155 - rope_scaling: Optional[dict[str, Any]] = None,
155 + rope_scaling: dict[str, Any] | None = None,
156 max_position_embeddings: int = 8192,
157 - quant_config: Optional[QuantizationConfig] = None,
157 + quant_config: QuantizationConfig | None = None,
158 bias: bool = False,
159 - cache_config: Optional[CacheConfig] = None,
159 + cache_config: CacheConfig | None = None,
160 prefix: str = "",
161 ) -> None:
162 super().__init__()
@@ -238,8 +238,8 @@ class NemotronDecoderLayer(nn.Module):
238 def __init__(
239 self,
240 config: NemotronConfig,
241 - cache_config: Optional[CacheConfig] = None,
242 - quant_config: Optional[QuantizationConfig] = None,
241 + cache_config: CacheConfig | None = None,
242 + quant_config: QuantizationConfig | None = None,
243 prefix: str = "",
244 ) -> None:
245 super().__init__()
@@ -292,7 +292,7 @@ class NemotronDecoderLayer(nn.Module):
292 self,
293 positions: torch.Tensor,
294 hidden_states: torch.Tensor,
295 - residual: Optional[torch.Tensor],
295 + residual: torch.Tensor | None,
296 ) -> tuple[torch.Tensor, torch.Tensor]:
297 # Self Attention
298 if residual is None:
@@ -363,11 +363,11 @@ class NemotronModel(nn.Module):
363
364 def forward(
365 self,
366 - input_ids: Optional[torch.Tensor],
366 + input_ids: torch.Tensor | None,
367 positions: torch.Tensor,
368 - intermediate_tensors: Optional[IntermediateTensors],
369 - inputs_embeds: Optional[torch.Tensor] = None,
370 - ) -> Union[torch.Tensor, IntermediateTensors]:
368 + intermediate_tensors: IntermediateTensors | None,
369 + inputs_embeds: torch.Tensor | None = None,
370 + ) -> torch.Tensor | IntermediateTensors:
371 if get_pp_group().is_first_rank:
372 if inputs_embeds is not None:
373 hidden_states = inputs_embeds
@@ -514,9 +514,9 @@ class NemotronForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
514 self,
515 input_ids: torch.Tensor,
516 positions: torch.Tensor,
517 - intermediate_tensors: Optional[IntermediateTensors] = None,
518 - inputs_embeds: Optional[torch.Tensor] = None,
519 - ) -> Union[torch.Tensor, IntermediateTensors]:
517 + intermediate_tensors: IntermediateTensors | None = None,
518 + inputs_embeds: torch.Tensor | None = None,
519 + ) -> torch.Tensor | IntermediateTensors:
520 model_output = self.model(
521 input_ids, positions, intermediate_tensors, inputs_embeds
522 )
@@ -525,7 +525,7 @@ class NemotronForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
525 def compute_logits(
526 self,
527 hidden_states: torch.Tensor,
528 - ) -> Optional[torch.Tensor]:
528 + ) -> torch.Tensor | None:
529 logits = self.logits_processor(self.lm_head, hidden_states)
530 return logits
531
vllm/model_executor/models/nemotron_h.py
+21 -22
@@ -19,7 +19,6 @@
19 """Inference-only NemotronH model."""
20
21 from collections.abc import Iterable
22 -from typing import Optional
22
23 import torch
24 from torch import nn
@@ -75,7 +74,7 @@ class NemotronHMLP(nn.Module):
74 self,
75 config: NemotronHConfig,
76 layer_idx: int,
78 - quant_config: Optional[QuantizationConfig] = None,
77 + quant_config: QuantizationConfig | None = None,
78 bias: bool = False,
79 prefix: str = "",
80 ) -> None:
@@ -119,9 +118,9 @@ class NemotronHMLPDecoderLayer(nn.Module):
118 self,
119 config: NemotronHConfig,
120 layer_idx: int,
122 - model_config: Optional[ModelConfig] = None,
123 - cache_config: Optional[CacheConfig] = None,
124 - quant_config: Optional[QuantizationConfig] = None,
121 + model_config: ModelConfig | None = None,
122 + cache_config: CacheConfig | None = None,
123 + quant_config: QuantizationConfig | None = None,
124 prefix: str = "",
125 ) -> None:
126 super().__init__()
@@ -140,7 +139,7 @@ class NemotronHMLPDecoderLayer(nn.Module):
139 def forward(
140 self,
141 hidden_states: torch.Tensor,
143 - residual: Optional[torch.Tensor],
142 + residual: torch.Tensor | None,
143 **kwargs,
144 ):
145 if residual is None:
@@ -158,9 +157,9 @@ class NemotronHMambaDecoderLayer(nn.Module):
157 self,
158 config: NemotronHConfig,
159 layer_idx: int,
161 - model_config: Optional[ModelConfig] = None,
162 - cache_config: Optional[CacheConfig] = None,
163 - quant_config: Optional[QuantizationConfig] = None,
160 + model_config: ModelConfig | None = None,
161 + cache_config: CacheConfig | None = None,
162 + quant_config: QuantizationConfig | None = None,
163 prefix: str = "",
164 ) -> None:
165 super().__init__()
@@ -188,7 +187,7 @@ class NemotronHMambaDecoderLayer(nn.Module):
187 def forward(
188 self,
189 hidden_states: torch.Tensor,
191 - residual: Optional[torch.Tensor],
190 + residual: torch.Tensor | None,
191 **kwargs,
192 ):
193 if residual is None:
@@ -207,9 +206,9 @@ class NemotronHAttention(nn.Module):
206 self,
207 config: NemotronHConfig,
208 layer_idx: int,
210 - model_config: Optional[ModelConfig] = None,
211 - cache_config: Optional[CacheConfig] = None,
212 - quant_config: Optional[QuantizationConfig] = None,
209 + model_config: ModelConfig | None = None,
210 + cache_config: CacheConfig | None = None,
211 + quant_config: QuantizationConfig | None = None,
212 prefix: str = "",
213 ) -> None:
214 super().__init__()
@@ -279,9 +278,9 @@ class NemotronHAttentionDecoderLayer(nn.Module):
278 self,
279 config: NemotronHConfig,
280 layer_idx: int,
282 - model_config: Optional[ModelConfig] = None,
283 - cache_config: Optional[CacheConfig] = None,
284 - quant_config: Optional[QuantizationConfig] = None,
281 + model_config: ModelConfig | None = None,
282 + cache_config: CacheConfig | None = None,
283 + quant_config: QuantizationConfig | None = None,
284 prefix: str = "",
285 ) -> None:
286 super().__init__()
@@ -301,7 +300,7 @@ class NemotronHAttentionDecoderLayer(nn.Module):
300 self,
301 positions: torch.Tensor,
302 hidden_states: torch.Tensor,
304 - residual: Optional[torch.Tensor],
303 + residual: torch.Tensor | None,
304 **kwargs,
305 ):
306 if residual is None:
@@ -377,8 +376,8 @@ class NemotronHModel(nn.Module):
376 self,
377 input_ids: torch.Tensor,
378 positions: torch.Tensor,
380 - intermediate_tensors: Optional[IntermediateTensors] = None,
381 - inputs_embeds: Optional[torch.Tensor] = None,
379 + intermediate_tensors: IntermediateTensors | None = None,
380 + inputs_embeds: torch.Tensor | None = None,
381 ) -> torch.Tensor:
382 if get_pp_group().is_first_rank:
383 if inputs_embeds is not None:
@@ -553,8 +552,8 @@ class NemotronHForCausalLM(
552 self,
553 input_ids: torch.Tensor,
554 positions: torch.Tensor,
556 - intermediate_tensors: Optional[IntermediateTensors] = None,
557 - inputs_embeds: Optional[torch.Tensor] = None,
555 + intermediate_tensors: IntermediateTensors | None = None,
556 + inputs_embeds: torch.Tensor | None = None,
557 **kwargs,
558 ):
559 hidden_states = self.model(
@@ -566,7 +565,7 @@ class NemotronHForCausalLM(
565 def compute_logits(
566 self,
567 hidden_states: torch.Tensor,
569 - ) -> Optional[torch.Tensor]:
568 + ) -> torch.Tensor | None:
569 logits = self.logits_processor(self.lm_head, hidden_states)
570 return logits
571
vllm/model_executor/models/nemotron_nas.py
+17 -17
@@ -26,7 +26,7 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Any, Optional, Union
29 +from typing import Any
30
31 import torch
32 from torch import nn
@@ -84,12 +84,12 @@ class DeciLMAttention(LlamaAttention):
84 num_heads: int,
85 num_kv_heads: int,
86 rope_theta: float = 10000,
87 - rope_scaling: Optional[dict[str, Any]] = None,
87 + rope_scaling: dict[str, Any] | None = None,
88 max_position_embeddings: int = 8192,
89 - quant_config: Optional[QuantizationConfig] = None,
89 + quant_config: QuantizationConfig | None = None,
90 bias: bool = False,
91 bias_o_proj: bool = False,
92 - cache_config: Optional[CacheConfig] = None,
92 + cache_config: CacheConfig | None = None,
93 prefix: str = "",
94 attn_type: str = AttentionType.DECODER,
95 ) -> None:
@@ -112,8 +112,8 @@ class DeciLMAttention(LlamaAttention):
112 def _init_rotary_emb(
113 self,
114 config,
115 - rope_scaling: Optional[dict[str, Any]],
116 - quant_config: Optional[QuantizationConfig],
115 + rope_scaling: dict[str, Any] | None,
116 + quant_config: QuantizationConfig | None,
117 ) -> None:
118 # Enables YARN for Mistral and LLaMA4 derivatives.
119 is_neox_style = True
@@ -139,8 +139,8 @@ class DeciLMDecoderLayer(nn.Module):
139 self,
140 config: LlamaConfig,
141 layer_idx: int,
142 - cache_config: Optional[CacheConfig] = None,
143 - quant_config: Optional[QuantizationConfig] = None,
142 + cache_config: CacheConfig | None = None,
143 + quant_config: QuantizationConfig | None = None,
144 prefix: str = "",
145 ) -> None:
146 super().__init__()
@@ -210,7 +210,7 @@ class DeciLMDecoderLayer(nn.Module):
210 self,
211 positions: torch.Tensor,
212 hidden_states: torch.Tensor,
213 - residual: Optional[torch.Tensor],
213 + residual: torch.Tensor | None,
214 ) -> tuple[torch.Tensor, torch.Tensor]:
215 # Self Attention
216
@@ -303,11 +303,11 @@ class DeciModel(nn.Module):
303
304 def forward(
305 self,
306 - input_ids: Optional[torch.Tensor],
306 + input_ids: torch.Tensor | None,
307 positions: torch.Tensor,
308 - intermediate_tensors: Optional[IntermediateTensors],
309 - inputs_embeds: Optional[torch.Tensor] = None,
310 - ) -> Union[torch.Tensor, IntermediateTensors]:
308 + intermediate_tensors: IntermediateTensors | None,
309 + inputs_embeds: torch.Tensor | None = None,
310 + ) -> torch.Tensor | IntermediateTensors:
311 if get_pp_group().is_first_rank:
312 if inputs_embeds is not None:
313 hidden_states = inputs_embeds
@@ -487,9 +487,9 @@ class DeciLMForCausalLM(nn.Module, SupportsLoRA, SupportsPP, HasNoOps):
487 self,
488 input_ids: torch.Tensor,
489 positions: torch.Tensor,
490 - intermediate_tensors: Optional[IntermediateTensors] = None,
491 - inputs_embeds: Optional[torch.Tensor] = None,
492 - ) -> Union[torch.Tensor, IntermediateTensors]:
490 + intermediate_tensors: IntermediateTensors | None = None,
491 + inputs_embeds: torch.Tensor | None = None,
492 + ) -> torch.Tensor | IntermediateTensors:
493 model_output = self.model(
494 input_ids, positions, intermediate_tensors, inputs_embeds
495 )
@@ -498,7 +498,7 @@ class DeciLMForCausalLM(nn.Module, SupportsLoRA, SupportsPP, HasNoOps):
498 def compute_logits(
499 self,
500 hidden_states: torch.Tensor,
501 - ) -> Optional[torch.Tensor]:
501 + ) -> torch.Tensor | None:
502 logits = self.logits_processor(self.lm_head, hidden_states)
503 return logits
504
vllm/model_executor/models/nemotron_vl.py
+18 -19
@@ -9,7 +9,6 @@
9 # --------------------------------------------------------
10 from abc import ABC
11 from collections.abc import Iterable
12 -from typing import Optional
12
13 import torch
14 import torch.nn as nn
@@ -207,9 +206,9 @@ class NemotronVLProcessor(InternVLProcessor):
206 tokenizer: AnyTokenizer,
207 image_processor: BaseImageProcessorFast,
208 *,
210 - min_dynamic_patch: Optional[int] = None,
211 - max_dynamic_patch: Optional[int] = None,
212 - dynamic_image_size: Optional[bool] = None,
209 + min_dynamic_patch: int | None = None,
210 + max_dynamic_patch: int | None = None,
211 + dynamic_image_size: bool | None = None,
212 ) -> None:
213 ABC.__init__(self)
214 self.config = config
@@ -266,9 +265,9 @@ class NemotronVLProcessor(InternVLProcessor):
265 def _images_to_pixel_values_lst(
266 self,
267 images: list[Image.Image],
269 - min_dynamic_patch: Optional[int] = None,
270 - max_dynamic_patch: Optional[int] = None,
271 - dynamic_image_size: Optional[bool] = None,
268 + min_dynamic_patch: int | None = None,
269 + max_dynamic_patch: int | None = None,
270 + dynamic_image_size: bool | None = None,
271 ) -> list[torch.Tensor]:
272 min_num, max_num = self.resolve_min_max_num(
273 min_dynamic_patch=min_dynamic_patch,
@@ -292,9 +291,9 @@ class NemotronVLProcessor(InternVLProcessor):
291 self,
292 text: list[str],
293 images: list[Image.Image],
295 - min_dynamic_patch: Optional[int] = None,
296 - max_dynamic_patch: Optional[int] = None,
297 - dynamic_image_size: Optional[bool] = None,
294 + min_dynamic_patch: int | None = None,
295 + max_dynamic_patch: int | None = None,
296 + dynamic_image_size: bool | None = None,
297 ) -> tuple[list[str], dict[str, torch.Tensor]]:
298 if len(images) == 0:
299 image_inputs = {}
@@ -326,7 +325,7 @@ class NemotronVLProcessor(InternVLProcessor):
325 def get_image_repl(
326 self,
327 feature_size: int,
329 - num_patches: Optional[int],
328 + num_patches: int | None,
329 ) -> PromptUpdateDetails[str]:
330 repl_features = IMG_CONTEXT * feature_size
331 repl_full = IMG_START + repl_features + IMG_END
@@ -362,7 +361,7 @@ class LlamaNemotronVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, Suppor
361 merge_by_field_config = True
362
363 @classmethod
365 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
364 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
365 if modality.startswith("image"):
366 return "<image>"
367
@@ -426,7 +425,7 @@ class LlamaNemotronVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, Suppor
425 def _init_vision_model(
426 self,
427 config: PretrainedConfig,
429 - quant_config: Optional[QuantizationConfig],
428 + quant_config: QuantizationConfig | None,
429 *,
430 prefix: str,
431 ):
@@ -482,7 +481,7 @@ class LlamaNemotronVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, Suppor
481
482 def _parse_and_validate_image_input(
483 self, **kwargs: object
485 - ) -> Optional[InternVLImageInputs]:
484 + ) -> InternVLImageInputs | None:
485 pixel_values_flat = kwargs.pop("pixel_values_flat", None)
486 image_num_patches = kwargs.pop("image_num_patches", None)
487 image_embeds = kwargs.pop("image_embeds", None)
@@ -581,9 +580,9 @@ class LlamaNemotronVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, Suppor
580 def get_input_embeddings(
581 self,
582 input_ids: torch.Tensor,
584 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
583 + multimodal_embeddings: MultiModalEmbeddings | None = None,
584 *,
586 - is_multimodal: Optional[torch.Tensor] = None,
585 + is_multimodal: torch.Tensor | None = None,
586 handle_oov_mm_token: bool = False,
587 ) -> torch.Tensor:
588 if multimodal_embeddings is not None and len(multimodal_embeddings) > 0:
@@ -604,8 +603,8 @@ class LlamaNemotronVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, Suppor
603 self,
604 input_ids: torch.Tensor,
605 positions: torch.Tensor,
607 - intermediate_tensors: Optional[IntermediateTensors] = None,
608 - inputs_embeds: Optional[torch.Tensor] = None,
606 + intermediate_tensors: IntermediateTensors | None = None,
607 + inputs_embeds: torch.Tensor | None = None,
608 **kwargs: object,
609 ) -> IntermediateTensors:
610 if intermediate_tensors is not None:
@@ -630,7 +629,7 @@ class LlamaNemotronVLChatModel(nn.Module, SupportsMultiModal, SupportsPP, Suppor
629 def compute_logits(
630 self,
631 hidden_states: torch.Tensor,
633 - ) -> Optional[torch.Tensor]:
632 + ) -> torch.Tensor | None:
633 return self.language_model.compute_logits(hidden_states)
634
635 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/nvlm_d.py
+3 -4
@@ -8,7 +8,6 @@
8 # Licensed under Apache 2.0 License [see LICENSE for details]
9 # --------------------------------------------------------
10 from collections.abc import Mapping, Sequence
11 -from typing import Optional
11
12 import torch
13 import torch.nn as nn
@@ -49,7 +48,7 @@ class NVLMProcessor(BaseInternVLProcessor):
48 def get_image_repl(
49 self,
50 feature_size: int,
52 - num_patches: Optional[int],
51 + num_patches: int | None,
52 ) -> PromptUpdateDetails[str]:
53 if num_patches is None:
54 raise NotImplementedError("Embedding inputs are not supported")
@@ -93,7 +92,7 @@ class NVLMDummyInputsBuilder(BaseInternVLDummyInputsBuilder[NVLMProcessingInfo])
92 self,
93 seq_len: int,
94 mm_counts: Mapping[str, int],
96 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
95 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
96 ) -> MultiModalDataDict:
97 target_width, target_height = self.info.get_image_size_with_most_features()
98 num_images = mm_counts.get("image", 0)
@@ -189,7 +188,7 @@ class NVLM_D_Model(InternVLChatModel):
188 def _init_vision_model(
189 self,
190 config: PretrainedConfig,
192 - quant_config: Optional[QuantizationConfig],
191 + quant_config: QuantizationConfig | None,
192 *,
193 is_mono: bool,
194 prefix: str,
vllm/model_executor/models/olmo.py
+13 -14
@@ -26,7 +26,6 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Optional, Union
29
30 import torch
31 from torch import nn
@@ -72,8 +71,8 @@ class OlmoAttention(nn.Module):
71 def __init__(
72 self,
73 config: OlmoConfig,
75 - cache_config: Optional[CacheConfig] = None,
76 - quant_config: Optional[QuantizationConfig] = None,
74 + cache_config: CacheConfig | None = None,
75 + quant_config: QuantizationConfig | None = None,
76 prefix: str = "",
77 ):
78 super().__init__()
@@ -152,7 +151,7 @@ class OlmoMLP(nn.Module):
151 def __init__(
152 self,
153 config: OlmoConfig,
155 - quant_config: Optional[QuantizationConfig] = None,
154 + quant_config: QuantizationConfig | None = None,
155 prefix: str = "",
156 ):
157 super().__init__()
@@ -201,8 +200,8 @@ class OlmoDecoderLayer(nn.Module):
200 def __init__(
201 self,
202 config: OlmoConfig,
204 - cache_config: Optional[CacheConfig] = None,
205 - quant_config: Optional[QuantizationConfig] = None,
203 + cache_config: CacheConfig | None = None,
204 + quant_config: QuantizationConfig | None = None,
205 prefix: str = "",
206 ):
207 super().__init__()
@@ -226,7 +225,7 @@ class OlmoDecoderLayer(nn.Module):
225 self,
226 positions: torch.Tensor,
227 hidden_states: torch.Tensor,
229 - ) -> tuple[torch.Tensor, Optional[tuple[torch.Tensor, torch.Tensor]]]:
228 + ) -> tuple[torch.Tensor, tuple[torch.Tensor, torch.Tensor] | None]:
229 # Attention block.
230 residual = hidden_states
231 hidden_states = self.input_layernorm(hidden_states)
@@ -276,9 +275,9 @@ class OlmoModel(nn.Module):
275 self,
276 input_ids: torch.Tensor,
277 positions: torch.Tensor,
279 - intermediate_tensors: Optional[IntermediateTensors],
280 - inputs_embeds: Optional[torch.Tensor] = None,
281 - ) -> Union[torch.Tensor, IntermediateTensors]:
278 + intermediate_tensors: IntermediateTensors | None,
279 + inputs_embeds: torch.Tensor | None = None,
280 + ) -> torch.Tensor | IntermediateTensors:
281 """
282 :param input_ids: A tensor of shape `(batch_size, seq_len)`.
283 """
@@ -389,9 +388,9 @@ class OlmoForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
388 self,
389 input_ids: torch.Tensor,
390 positions: torch.Tensor,
392 - intermediate_tensors: Optional[IntermediateTensors] = None,
393 - inputs_embeds: Optional[torch.Tensor] = None,
394 - ) -> Union[torch.Tensor, IntermediateTensors]:
391 + intermediate_tensors: IntermediateTensors | None = None,
392 + inputs_embeds: torch.Tensor | None = None,
393 + ) -> torch.Tensor | IntermediateTensors:
394 hidden_states = self.model(
395 input_ids=input_ids,
396 positions=positions,
@@ -403,7 +402,7 @@ class OlmoForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
402 def compute_logits(
403 self,
404 hidden_states: torch.Tensor,
406 - ) -> Optional[torch.Tensor]:
405 + ) -> torch.Tensor | None:
406 logits = self.logits_processor(self.lm_head, hidden_states)
407 return logits
408
vllm/model_executor/models/olmo2.py
+7 -8
@@ -27,7 +27,6 @@
27 from collections.abc import Iterable
28 from functools import partial
29 from itertools import islice
30 -from typing import Optional, Union
30
31 import torch
32 from torch import nn
@@ -312,9 +311,9 @@ class Olmo2Model(nn.Module):
311 self,
312 input_ids: torch.Tensor,
313 positions: torch.Tensor,
315 - intermediate_tensors: Optional[IntermediateTensors],
316 - inputs_embeds: Optional[torch.Tensor] = None,
317 - ) -> Union[torch.Tensor, IntermediateTensors]:
314 + intermediate_tensors: IntermediateTensors | None,
315 + inputs_embeds: torch.Tensor | None = None,
316 + ) -> torch.Tensor | IntermediateTensors:
317 """
318 :param input_ids: A tensor of shape `(batch_size, seq_len)`.
319 """
@@ -429,9 +428,9 @@ class Olmo2ForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
428 self,
429 input_ids: torch.Tensor,
430 positions: torch.Tensor,
432 - intermediate_tensors: Optional[IntermediateTensors] = None,
433 - inputs_embeds: Optional[torch.Tensor] = None,
434 - ) -> Union[torch.Tensor, IntermediateTensors]:
431 + intermediate_tensors: IntermediateTensors | None = None,
432 + inputs_embeds: torch.Tensor | None = None,
433 + ) -> torch.Tensor | IntermediateTensors:
434 hidden_states = self.model(
435 input_ids=input_ids,
436 positions=positions,
@@ -443,7 +442,7 @@ class Olmo2ForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
442 def compute_logits(
443 self,
444 hidden_states: torch.Tensor,
446 - ) -> Optional[torch.Tensor]:
445 + ) -> torch.Tensor | None:
446 logits = self.logits_processor(self.lm_head, hidden_states)
447 return logits
448
vllm/model_executor/models/olmoe.py
+10 -11
@@ -17,7 +17,6 @@
17 from collections.abc import Iterable
18 from functools import partial
19 from itertools import islice
20 -from typing import Optional, Union
20
21 import torch
22 from torch import nn
@@ -77,9 +76,9 @@ class OlmoeMoE(nn.Module):
76 top_k: int,
77 hidden_size: int,
78 intermediate_size: int,
80 - params_dtype: Optional[torch.dtype] = None,
81 - quant_config: Optional[QuantizationConfig] = None,
82 - tp_size: Optional[int] = None,
79 + params_dtype: torch.dtype | None = None,
80 + quant_config: QuantizationConfig | None = None,
81 + tp_size: int | None = None,
82 prefix: str = "",
83 ):
84 super().__init__()
@@ -245,7 +244,7 @@ class OlmoeDecoderLayer(nn.Module):
244 self,
245 positions: torch.Tensor,
246 hidden_states: torch.Tensor,
248 - residual: Optional[torch.Tensor],
247 + residual: torch.Tensor | None,
248 ) -> torch.Tensor:
249 # Self Attention
250 if residual is None:
@@ -302,9 +301,9 @@ class OlmoeModel(nn.Module):
301 self,
302 input_ids: torch.Tensor,
303 positions: torch.Tensor,
305 - intermediate_tensors: Optional[IntermediateTensors],
306 - inputs_embeds: Optional[torch.Tensor] = None,
307 - ) -> Union[torch.Tensor, IntermediateTensors]:
304 + intermediate_tensors: IntermediateTensors | None,
305 + inputs_embeds: torch.Tensor | None = None,
306 + ) -> torch.Tensor | IntermediateTensors:
307 if get_pp_group().is_first_rank:
308 if inputs_embeds is not None:
309 hidden_states = inputs_embeds
@@ -483,9 +482,9 @@ class OlmoeForCausalLM(nn.Module, SupportsPP):
482 self,
483 input_ids: torch.Tensor,
484 positions: torch.Tensor,
486 - intermediate_tensors: Optional[IntermediateTensors] = None,
487 - inputs_embeds: Optional[torch.Tensor] = None,
488 - ) -> Union[torch.Tensor, IntermediateTensors]:
485 + intermediate_tensors: IntermediateTensors | None = None,
486 + inputs_embeds: torch.Tensor | None = None,
487 + ) -> torch.Tensor | IntermediateTensors:
488 hidden_states = self.model(
489 input_ids, positions, intermediate_tensors, inputs_embeds
490 )
vllm/model_executor/models/opt.py
+16 -17
@@ -22,7 +22,6 @@
22
23 from collections.abc import Iterable
24 from itertools import islice
25 -from typing import Optional, Union
25
26 import torch
27 from torch import nn
@@ -77,8 +76,8 @@ class OPTAttention(nn.Module):
76 embed_dim: int,
77 num_heads: int,
78 bias: bool = True,
80 - cache_config: Optional[CacheConfig] = None,
81 - quant_config: Optional[QuantizationConfig] = None,
79 + cache_config: CacheConfig | None = None,
80 + quant_config: QuantizationConfig | None = None,
81 prefix: str = "",
82 ) -> None:
83 super().__init__()
@@ -129,8 +128,8 @@ class OPTDecoderLayer(nn.Module):
128 def __init__(
129 self,
130 config: OPTConfig,
132 - cache_config: Optional[CacheConfig] = None,
133 - quant_config: Optional[QuantizationConfig] = None,
131 + cache_config: CacheConfig | None = None,
132 + quant_config: QuantizationConfig | None = None,
133 prefix: str = "",
134 ):
135 super().__init__()
@@ -202,8 +201,8 @@ class OPTDecoder(nn.Module):
201 def __init__(
202 self,
203 config: OPTConfig,
205 - cache_config: Optional[CacheConfig] = None,
206 - quant_config: Optional[QuantizationConfig] = None,
204 + cache_config: CacheConfig | None = None,
205 + quant_config: QuantizationConfig | None = None,
206 prefix: str = "",
207 ):
208 super().__init__()
@@ -270,9 +269,9 @@ class OPTDecoder(nn.Module):
269 self,
270 input_ids: torch.Tensor,
271 positions: torch.Tensor,
273 - intermediate_tensors: Optional[IntermediateTensors],
274 - inputs_embeds: Optional[torch.Tensor] = None,
275 - ) -> Union[torch.Tensor, IntermediateTensors]:
272 + intermediate_tensors: IntermediateTensors | None,
273 + inputs_embeds: torch.Tensor | None = None,
274 + ) -> torch.Tensor | IntermediateTensors:
275 if get_pp_group().is_first_rank:
276 if inputs_embeds is None:
277 inputs_embeds = self.get_input_embeddings(input_ids)
@@ -319,9 +318,9 @@ class OPTModel(nn.Module):
318 self,
319 input_ids: torch.Tensor,
320 positions: torch.Tensor,
322 - intermediate_tensors: Optional[IntermediateTensors],
323 - inputs_embeds: Optional[torch.Tensor] = None,
324 - ) -> Union[torch.Tensor, IntermediateTensors]:
321 + intermediate_tensors: IntermediateTensors | None,
322 + inputs_embeds: torch.Tensor | None = None,
323 + ) -> torch.Tensor | IntermediateTensors:
324 return self.decoder(
325 input_ids, positions, intermediate_tensors, inputs_embeds=inputs_embeds
326 )
@@ -402,9 +401,9 @@ class OPTForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
401 self,
402 input_ids: torch.Tensor,
403 positions: torch.Tensor,
405 - intermediate_tensors: Optional[IntermediateTensors] = None,
406 - inputs_embeds: Optional[torch.Tensor] = None,
407 - ) -> Union[torch.Tensor, IntermediateTensors]:
404 + intermediate_tensors: IntermediateTensors | None = None,
405 + inputs_embeds: torch.Tensor | None = None,
406 + ) -> torch.Tensor | IntermediateTensors:
407 hidden_states = self.model(
408 input_ids, positions, intermediate_tensors, inputs_embeds
409 )
@@ -413,7 +412,7 @@ class OPTForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
412 def compute_logits(
413 self,
414 hidden_states: torch.Tensor,
416 - ) -> Optional[torch.Tensor]:
415 + ) -> torch.Tensor | None:
416 logits = self.logits_processor(self.lm_head, hidden_states)
417 return logits
418
vllm/model_executor/models/orion.py
+14 -14
@@ -9,7 +9,7 @@
9
10 from collections.abc import Iterable
11 from itertools import islice
12 -from typing import Any, Optional, Union
12 +from typing import Any
13
14 import torch
15 from torch import nn
@@ -51,7 +51,7 @@ class OrionMLP(nn.Module):
51 hidden_size: int,
52 intermediate_size: int,
53 hidden_act: str,
54 - quant_config: Optional[QuantizationConfig] = None,
54 + quant_config: QuantizationConfig | None = None,
55 ) -> None:
56 super().__init__()
57 self.gate_up_proj = MergedColumnParallelLinear(
@@ -80,10 +80,10 @@ class OrionAttention(nn.Module):
80 num_heads: int,
81 num_kv_heads: int,
82 rope_theta: float = 10000,
83 - rope_scaling: Optional[dict[str, Any]] = None,
83 + rope_scaling: dict[str, Any] | None = None,
84 max_position_embeddings: int = 8192,
85 - cache_config: Optional[CacheConfig] = None,
86 - quant_config: Optional[QuantizationConfig] = None,
85 + cache_config: CacheConfig | None = None,
86 + quant_config: QuantizationConfig | None = None,
87 prefix: str = "",
88 ) -> None:
89 super().__init__()
@@ -158,8 +158,8 @@ class OrionDecoderLayer(nn.Module):
158 def __init__(
159 self,
160 config: PretrainedConfig,
161 - cache_config: Optional[CacheConfig] = None,
162 - quant_config: Optional[QuantizationConfig] = None,
161 + cache_config: CacheConfig | None = None,
162 + quant_config: QuantizationConfig | None = None,
163 prefix: str = "",
164 ) -> None:
165 super().__init__()
@@ -250,9 +250,9 @@ class OrionModel(nn.Module):
250 self,
251 input_ids: torch.Tensor,
252 positions: torch.Tensor,
253 - intermediate_tensors: Optional[IntermediateTensors],
254 - inputs_embeds: Optional[torch.Tensor] = None,
255 - ) -> Union[torch.Tensor, IntermediateTensors]:
253 + intermediate_tensors: IntermediateTensors | None,
254 + inputs_embeds: torch.Tensor | None = None,
255 + ) -> torch.Tensor | IntermediateTensors:
256 if get_pp_group().is_first_rank:
257 if inputs_embeds is not None:
258 hidden_states = inputs_embeds
@@ -340,9 +340,9 @@ class OrionForCausalLM(nn.Module, SupportsPP):
340 self,
341 input_ids: torch.Tensor,
342 positions: torch.Tensor,
343 - intermediate_tensors: Optional[IntermediateTensors] = None,
344 - inputs_embeds: Optional[torch.Tensor] = None,
345 - ) -> Union[torch.Tensor, IntermediateTensors]:
343 + intermediate_tensors: IntermediateTensors | None = None,
344 + inputs_embeds: torch.Tensor | None = None,
345 + ) -> torch.Tensor | IntermediateTensors:
346 hidden_states = self.model(
347 input_ids, positions, intermediate_tensors, inputs_embeds
348 )
@@ -351,7 +351,7 @@ class OrionForCausalLM(nn.Module, SupportsPP):
351 def compute_logits(
352 self,
353 hidden_states: torch.Tensor,
354 - ) -> Optional[torch.Tensor]:
354 + ) -> torch.Tensor | None:
355 logits = self.logits_processor(self.lm_head, hidden_states)
356 return logits
357
vllm/model_executor/models/ovis.py
+11 -11
@@ -20,7 +20,7 @@
20
21 import math
22 from collections.abc import Iterable, Mapping
23 -from typing import Annotated, Literal, Optional, Union
23 +from typing import Annotated, Literal
24
25 import torch
26 import torch.nn as nn
@@ -87,7 +87,7 @@ class VisualTokenizer(torch.nn.Module):
87 def __init__(
88 self,
89 config: PretrainedConfig,
90 - quant_config: Optional[QuantizationConfig] = None,
90 + quant_config: QuantizationConfig | None = None,
91 prefix: str = "",
92 ):
93 super().__init__()
@@ -114,7 +114,7 @@ class VisualTokenizer(torch.nn.Module):
114 def _init_backbone(
115 self,
116 config: PretrainedConfig,
117 - quant_config: Optional[QuantizationConfig] = None,
117 + quant_config: QuantizationConfig | None = None,
118 prefix: str = "",
119 ) -> nn.Module:
120 model_type = config.backbone_config.model_type
@@ -282,7 +282,7 @@ class OvisProcessingInfo(BaseProcessingInfo):
282 text_model_type = hf_text_config.model_type
283 return IMAGE_PAD_TOKEN_MAP.get(text_model_type)
284
285 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
285 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
286 return {"image": None}
287
288 def get_image_size_with_most_features(self) -> ImageSize:
@@ -302,7 +302,7 @@ class OvisDummyInputsBuilder(BaseDummyInputsBuilder[OvisProcessingInfo]):
302 self,
303 seq_len: int,
304 mm_counts: Mapping[str, int],
305 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
305 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
306 ) -> MultiModalDataDict:
307 num_images = mm_counts.get("image", 0)
308
@@ -417,7 +417,7 @@ class Ovis(nn.Module, SupportsMultiModal, SupportsPP):
417 merge_by_field_config = True
418
419 @classmethod
420 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
420 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
421 if modality.startswith("image"):
422 return "<image>"
423
@@ -453,7 +453,7 @@ class Ovis(nn.Module, SupportsMultiModal, SupportsPP):
453
454 def _parse_and_validate_image_input(
455 self, **kwargs: object
456 - ) -> Optional[OvisImagePatchInputs]:
456 + ) -> OvisImagePatchInputs | None:
457 pixel_values = kwargs.pop("pixel_values", None)
458 indicator_tokens = kwargs.pop("indicator_tokens", None)
459
@@ -527,10 +527,10 @@ class Ovis(nn.Module, SupportsMultiModal, SupportsPP):
527 self,
528 input_ids: torch.Tensor,
529 positions: torch.Tensor,
530 - intermediate_tensors: Optional[IntermediateTensors] = None,
531 - inputs_embeds: Optional[torch.Tensor] = None,
530 + intermediate_tensors: IntermediateTensors | None = None,
531 + inputs_embeds: torch.Tensor | None = None,
532 **kwargs: object,
533 - ) -> Union[torch.Tensor, IntermediateTensors]:
533 + ) -> torch.Tensor | IntermediateTensors:
534 if intermediate_tensors is not None:
535 inputs_embeds = None
536
@@ -547,7 +547,7 @@ class Ovis(nn.Module, SupportsMultiModal, SupportsPP):
547 def compute_logits(
548 self,
549 hidden_states: torch.Tensor,
550 - ) -> Optional[torch.Tensor]:
550 + ) -> torch.Tensor | None:
551 logits = self.llm.compute_logits(hidden_states)
552 return logits
553
vllm/model_executor/models/ovis2_5.py
+13 -13
@@ -4,7 +4,7 @@
4
5 from collections.abc import Iterable, Mapping
6 from functools import partial
7 -from typing import Annotated, Literal, Optional, Union
7 +from typing import Annotated, Literal
8
9 import torch
10 import torch.nn as nn
@@ -102,7 +102,7 @@ class VisualTokenizer(torch.nn.Module):
102 self,
103 config: PretrainedConfig,
104 visual_vocab_size: int,
105 - quant_config: Optional[QuantizationConfig] = None,
105 + quant_config: QuantizationConfig | None = None,
106 prefix: str = "",
107 use_data_parallel: bool = False,
108 ):
@@ -129,7 +129,7 @@ class VisualTokenizer(torch.nn.Module):
129 def _init_backbone(
130 self,
131 config: PretrainedConfig,
132 - quant_config: Optional[QuantizationConfig] = None,
132 + quant_config: QuantizationConfig | None = None,
133 prefix: str = "",
134 use_data_parallel: bool = False,
135 ):
@@ -205,7 +205,7 @@ class Ovis2_5ProcessingInfo(BaseProcessingInfo):
205 def get_image_processor(self) -> BaseImageProcessor:
206 return self.get_hf_processor().image_processor # type: ignore
207
208 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
208 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
209 return {"image": None, "video": 1}
210
211 def get_image_size_with_most_features(self) -> ImageSize:
@@ -274,7 +274,7 @@ class Ovis2_5ProcessingInfo(BaseProcessingInfo):
274 image_width: int,
275 image_height: int,
276 num_frames: int,
277 - image_processor: Optional[BaseImageProcessor],
277 + image_processor: BaseImageProcessor | None,
278 ) -> int:
279 num_video_tokens = self.get_num_image_tokens(
280 image_width=image_width, image_height=image_height, num_frames=num_frames
@@ -305,7 +305,7 @@ class Ovis2_5DummyInputsBuilder(BaseDummyInputsBuilder[Ovis2_5ProcessingInfo]):
305 self,
306 seq_len: int,
307 mm_counts: Mapping[str, int],
308 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
308 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
309 ) -> MultiModalDataDict:
310 num_images = mm_counts.get("image", 0)
311 num_videos = mm_counts.get("video", 0)
@@ -482,7 +482,7 @@ class Ovis2_5(nn.Module, SupportsMultiModal, SupportsPP):
482
483 def _parse_and_validate_image_input(
484 self, **kwargs: object
485 - ) -> Optional[Ovis2_5ImagePatchInputs]:
485 + ) -> Ovis2_5ImagePatchInputs | None:
486 pixel_values = kwargs.pop("pixel_values", None)
487 indicator_tokens = kwargs.pop("indicator_tokens", None)
488 grids = kwargs.pop("grids", None)
@@ -516,7 +516,7 @@ class Ovis2_5(nn.Module, SupportsMultiModal, SupportsPP):
516
517 def _parse_and_validate_video_input(
518 self, **kwargs: object
519 - ) -> Optional[Ovis2_5VideoPatchInputs]:
519 + ) -> Ovis2_5VideoPatchInputs | None:
520 pixel_values = kwargs.pop("video_pixel_values", None)
521 indicator_tokens = kwargs.pop("video_indicator_tokens", None)
522 grids = kwargs.pop("video_grids", None)
@@ -549,7 +549,7 @@ class Ovis2_5(nn.Module, SupportsMultiModal, SupportsPP):
549 raise AssertionError("This line should be unreachable.")
550
551 def _process_visual_input(
552 - self, visual_input: Union[Ovis2_5ImagePatchInputs, Ovis2_5VideoPatchInputs]
552 + self, visual_input: Ovis2_5ImagePatchInputs | Ovis2_5VideoPatchInputs
553 ) -> MultiModalEmbeddings:
554 image_patches_flat = visual_input["flat_data"]
555 patches_per_image = visual_input["patches_per_item"]
@@ -629,10 +629,10 @@ class Ovis2_5(nn.Module, SupportsMultiModal, SupportsPP):
629 self,
630 input_ids: torch.Tensor,
631 positions: torch.Tensor,
632 - intermediate_tensors: Optional[IntermediateTensors] = None,
633 - inputs_embeds: Optional[torch.Tensor] = None,
632 + intermediate_tensors: IntermediateTensors | None = None,
633 + inputs_embeds: torch.Tensor | None = None,
634 **kwargs: object,
635 - ) -> Union[torch.Tensor, IntermediateTensors]:
635 + ) -> torch.Tensor | IntermediateTensors:
636 if intermediate_tensors is not None:
637 inputs_embeds = None
638
@@ -649,7 +649,7 @@ class Ovis2_5(nn.Module, SupportsMultiModal, SupportsPP):
649 def compute_logits(
650 self,
651 hidden_states: torch.Tensor,
652 - ) -> Optional[torch.Tensor]:
652 + ) -> torch.Tensor | None:
653 logits = self.llm.compute_logits(hidden_states)
654 return logits
655
vllm/model_executor/models/paligemma.py
+14 -12
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable, Mapping, Sequence
4 -from typing import Annotated, Literal, Optional, Union
4 +from typing import Annotated, Literal, TypeAlias
5
6 import torch
7 from torch import nn
@@ -74,7 +74,9 @@ class PaliGemmaImageEmbeddingInputs(TensorSchema):
74 data: Annotated[torch.Tensor, TensorShape("bn", "ifs", "hs")]
75
76
77 -PaliGemmaImageInputs = Union[PaliGemmaImagePixelInputs, PaliGemmaImageEmbeddingInputs]
77 +PaliGemmaImageInputs: TypeAlias = (
78 + PaliGemmaImagePixelInputs | PaliGemmaImageEmbeddingInputs
79 +)
80
81
82 class PaliGemmaMultiModalProjector(nn.Module):
@@ -95,7 +97,7 @@ class PaliGemmaProcessingInfo(BaseProcessingInfo):
97 def get_vision_encoder_info(self):
98 return get_vision_encoder_info(self.get_hf_config())
99
98 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
100 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
101 return {"image": 1}
102
103 def get_num_image_tokens(
@@ -120,7 +122,7 @@ class PaliGemmaDummyInputsBuilder(BaseDummyInputsBuilder[PaliGemmaProcessingInfo
122 self,
123 seq_len: int,
124 mm_counts: Mapping[str, int],
123 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
125 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
126 ) -> MultiModalDataDict:
127 hf_config = self.info.get_hf_config()
128 vision_config = hf_config.vision_config
@@ -217,11 +219,11 @@ class PaliGemmaMultiModalProcessor(BaseMultiModalProcessor[PaliGemmaProcessingIn
219
220 def apply(
221 self,
220 - prompt: Union[str, list[int]],
222 + prompt: str | list[int],
223 mm_data: MultiModalDataDict,
224 hf_processor_mm_kwargs: Mapping[str, object],
223 - tokenization_kwargs: Optional[Mapping[str, object]] = None,
224 - mm_uuids: Optional[MultiModalUUIDDict] = None,
225 + tokenization_kwargs: Mapping[str, object] | None = None,
226 + mm_uuids: MultiModalUUIDDict | None = None,
227 ) -> MultiModalInputs:
228 mm_inputs = super().apply(
229 prompt,
@@ -273,7 +275,7 @@ class PaliGemmaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
275 )
276
277 @classmethod
276 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
278 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
279 if modality.startswith("image"):
280 return None
281
@@ -317,7 +319,7 @@ class PaliGemmaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
319
320 def _parse_and_validate_image_input(
321 self, **kwargs: object
320 - ) -> Optional[PaliGemmaImageInputs]:
322 + ) -> PaliGemmaImageInputs | None:
323 pixel_values = kwargs.pop("pixel_values", None)
324 image_embeds = kwargs.pop("image_embeds", None)
325
@@ -386,8 +388,8 @@ class PaliGemmaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
388 self,
389 input_ids: torch.Tensor,
390 positions: torch.Tensor,
389 - intermediate_tensors: Optional[IntermediateTensors] = None,
390 - inputs_embeds: Optional[torch.Tensor] = None,
391 + intermediate_tensors: IntermediateTensors | None = None,
392 + inputs_embeds: torch.Tensor | None = None,
393 **kwargs: object,
394 ) -> IntermediateTensors:
395 if intermediate_tensors is not None:
@@ -402,7 +404,7 @@ class PaliGemmaForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsP
404 def compute_logits(
405 self,
406 hidden_states: torch.Tensor,
405 - ) -> Optional[torch.Tensor]:
407 + ) -> torch.Tensor | None:
408 return self.language_model.compute_logits(hidden_states)
409
410 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/persimmon.py
+11 -12
@@ -25,7 +25,6 @@
25
26 from collections.abc import Iterable
27 from itertools import islice
28 -from typing import Optional, Union
28
29 import torch
30 from torch import nn
@@ -63,7 +62,7 @@ from .utils import (
62
63 class PersimmonMLP(nn.Module):
64 def __init__(
66 - self, config: PersimmonConfig, quant_config: Optional[QuantizationConfig] = None
65 + self, config: PersimmonConfig, quant_config: QuantizationConfig | None = None
66 ):
67 super().__init__()
68 self.dense_h_to_4h = ColumnParallelLinear(
@@ -85,8 +84,8 @@ class PersimmonAttention(nn.Module):
84 def __init__(
85 self,
86 config: PersimmonConfig,
88 - cache_config: Optional[CacheConfig] = None,
89 - quant_config: Optional[QuantizationConfig] = None,
87 + cache_config: CacheConfig | None = None,
88 + quant_config: QuantizationConfig | None = None,
89 prefix: str = "",
90 ):
91 super().__init__()
@@ -181,8 +180,8 @@ class PersimmonDecoderLayer(nn.Module):
180 def __init__(
181 self,
182 config: PersimmonConfig,
184 - cache_config: Optional[CacheConfig] = None,
185 - quant_config: Optional[QuantizationConfig] = None,
183 + cache_config: CacheConfig | None = None,
184 + quant_config: QuantizationConfig | None = None,
185 prefix: str = "",
186 ):
187 super().__init__()
@@ -263,9 +262,9 @@ class PersimmonModel(nn.Module):
262 self,
263 input_ids: torch.Tensor,
264 positions: torch.Tensor,
266 - intermediate_tensors: Optional[IntermediateTensors],
267 - inputs_embeds: Optional[torch.Tensor] = None,
268 - ) -> Union[torch.Tensor, IntermediateTensors]:
265 + intermediate_tensors: IntermediateTensors | None,
266 + inputs_embeds: torch.Tensor | None = None,
267 + ) -> torch.Tensor | IntermediateTensors:
268 if get_pp_group().is_first_rank:
269 if inputs_embeds is not None:
270 hidden_states = inputs_embeds
@@ -340,8 +339,8 @@ class PersimmonForCausalLM(nn.Module, SupportsPP):
339 self,
340 input_ids: torch.Tensor,
341 positions: torch.Tensor,
343 - intermediate_tensors: Optional[IntermediateTensors] = None,
344 - inputs_embeds: Optional[torch.Tensor] = None,
342 + intermediate_tensors: IntermediateTensors | None = None,
343 + inputs_embeds: torch.Tensor | None = None,
344 ):
345 hidden_states = self.model(
346 input_ids=input_ids,
@@ -354,7 +353,7 @@ class PersimmonForCausalLM(nn.Module, SupportsPP):
353 def compute_logits(
354 self,
355 hidden_states: torch.Tensor,
357 - ) -> Optional[torch.Tensor]:
356 + ) -> torch.Tensor | None:
357 logits = self.logits_processor(self.lm_head, hidden_states)
358 return logits
359
vllm/model_executor/models/phi.py
+12 -13
@@ -40,7 +40,6 @@
40
41 from collections.abc import Iterable
42 from itertools import islice
43 -from typing import Optional, Union
43
44 import torch
45 from torch import nn
@@ -80,8 +79,8 @@ class PhiAttention(nn.Module):
79 def __init__(
80 self,
81 config: PhiConfig,
83 - cache_config: Optional[CacheConfig] = None,
84 - quant_config: Optional[QuantizationConfig] = None,
82 + cache_config: CacheConfig | None = None,
83 + quant_config: QuantizationConfig | None = None,
84 prefix: str = "",
85 ):
86 super().__init__()
@@ -149,7 +148,7 @@ class PhiAttention(nn.Module):
148
149 class PhiMLP(nn.Module):
150 def __init__(
152 - self, config: PhiConfig, quant_config: Optional[QuantizationConfig] = None
151 + self, config: PhiConfig, quant_config: QuantizationConfig | None = None
152 ):
153 super().__init__()
154
@@ -179,8 +178,8 @@ class PhiLayer(nn.Module):
178 def __init__(
179 self,
180 config: PhiConfig,
182 - cache_config: Optional[CacheConfig] = None,
183 - quant_config: Optional[QuantizationConfig] = None,
181 + cache_config: CacheConfig | None = None,
182 + quant_config: QuantizationConfig | None = None,
183 prefix: str = "",
184 ):
185 super().__init__()
@@ -241,9 +240,9 @@ class PhiModel(nn.Module):
240 self,
241 input_ids: torch.Tensor,
242 positions: torch.Tensor,
244 - intermediate_tensors: Optional[IntermediateTensors],
245 - inputs_embeds: Optional[torch.Tensor] = None,
246 - ) -> Union[torch.Tensor, IntermediateTensors]:
243 + intermediate_tensors: IntermediateTensors | None,
244 + inputs_embeds: torch.Tensor | None = None,
245 + ) -> torch.Tensor | IntermediateTensors:
246 if get_pp_group().is_first_rank:
247 if inputs_embeds is not None:
248 hidden_states = inputs_embeds
@@ -348,9 +347,9 @@ class PhiForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
347 self,
348 input_ids: torch.Tensor,
349 positions: torch.Tensor,
351 - intermediate_tensors: Optional[IntermediateTensors] = None,
352 - inputs_embeds: Optional[torch.Tensor] = None,
353 - ) -> Union[torch.Tensor, IntermediateTensors]:
350 + intermediate_tensors: IntermediateTensors | None = None,
351 + inputs_embeds: torch.Tensor | None = None,
352 + ) -> torch.Tensor | IntermediateTensors:
353 hidden_states = self.model(
354 input_ids, positions, intermediate_tensors, inputs_embeds
355 )
@@ -360,7 +359,7 @@ class PhiForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
359 def compute_logits(
360 self,
361 hidden_states: torch.Tensor,
363 - ) -> Optional[torch.Tensor]:
362 + ) -> torch.Tensor | None:
363 logits = self.logits_processor(self.lm_head, hidden_states, self.lm_head.bias)
364 return logits
365
vllm/model_executor/models/phi3v.py
+17 -17
@@ -16,7 +16,7 @@
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
18 from collections.abc import Iterable, Mapping, Sequence
19 -from typing import Annotated, Any, Literal, Optional, Union
19 +from typing import Annotated, Any, Literal, TypeAlias
20
21 import regex as re
22 import torch
@@ -96,7 +96,7 @@ CLIP_VIT_LARGE_PATCH14_336_CONFIG = CLIPVisionConfig(
96
97 def _init_img_processor(
98 hf_config: PretrainedConfig,
99 - quant_config: Optional[QuantizationConfig],
99 + quant_config: QuantizationConfig | None,
100 prefix: str = "",
101 ) -> CLIPVisionModel:
102 clip_config = CLIP_VIT_LARGE_PATCH14_336_CONFIG
@@ -132,14 +132,14 @@ class Phi3VImagePixelInputs(TensorSchema):
132
133 # Supports either a stacked tensor or a list of (p, 3, h, w) tensors
134 pixel_values: Annotated[
135 - Union[torch.Tensor, list[torch.Tensor]],
135 + torch.Tensor | list[torch.Tensor],
136 TensorShape(
137 "bn", "p", 3, "h", "w", dynamic_dims={"p"}
138 ), # 'p' may vary across items
139 ]
140
141 # Stacked tensor with height and width for each image
142 - image_sizes: Annotated[Optional[torch.Tensor], TensorShape("bn", 2)]
142 + image_sizes: Annotated[torch.Tensor | None, TensorShape("bn", 2)]
143
144
145 class Phi3VImageEmbeddingInputs(TensorSchema):
@@ -153,12 +153,12 @@ class Phi3VImageEmbeddingInputs(TensorSchema):
153
154 type: Literal["image_embeds"] = "image_embeds"
155 data: Annotated[
156 - Union[torch.Tensor, list[torch.Tensor]],
156 + torch.Tensor | list[torch.Tensor],
157 TensorShape("bn", "f", "h"),
158 ]
159
160
161 -Phi3VImageInputs = Union[Phi3VImagePixelInputs, Phi3VImageEmbeddingInputs]
161 +Phi3VImageInputs: TypeAlias = Phi3VImagePixelInputs | Phi3VImageEmbeddingInputs
162
163
164 class Phi3ImageEmbeddingBase(nn.Module):
@@ -192,7 +192,7 @@ class Phi3HDImageEmbedding(Phi3ImageEmbeddingBase):
192 def __init__(
193 self,
194 config: PretrainedConfig,
195 - quant_config: Optional[QuantizationConfig],
195 + quant_config: QuantizationConfig | None,
196 prefix: str = "",
197 ) -> None:
198 super().__init__()
@@ -350,7 +350,7 @@ class Phi3HDImageEmbedding(Phi3ImageEmbeddingBase):
350
351
352 class Phi3VProcessingInfo(BaseProcessingInfo):
353 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
353 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
354 return {"image": None}
355
356 def get_num_image_tokens(
@@ -358,7 +358,7 @@ class Phi3VProcessingInfo(BaseProcessingInfo):
358 *,
359 image_width: int,
360 image_height: int,
361 - processor: Optional[ProcessorMixin] = None,
361 + processor: ProcessorMixin | None = None,
362 ) -> int:
363 if processor is None:
364 processor = self.get_hf_processor()
@@ -386,7 +386,7 @@ class Phi3VDummyInputsBuilder(BaseDummyInputsBuilder[Phi3VProcessingInfo]):
386 self,
387 seq_len: int,
388 mm_counts: Mapping[str, int],
389 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
389 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
390 ) -> MultiModalDataDict:
391 num_images = mm_counts.get("image", 0)
392
@@ -574,7 +574,7 @@ class Phi3VForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsQuant)
574 )
575
576 @classmethod
577 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
577 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
578 if modality.startswith("image"):
579 return f"<|image_{i}|>"
580
@@ -620,7 +620,7 @@ class Phi3VForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsQuant)
620
621 def _parse_and_validate_image_input(
622 self, **kwargs: object
623 - ) -> Optional[Phi3VImageInputs]:
623 + ) -> Phi3VImageInputs | None:
624 pixel_values = kwargs.pop("pixel_values", None)
625 image_sizes = kwargs.pop("image_sizes", None)
626 image_embeds = kwargs.pop("image_embeds", None)
@@ -684,9 +684,9 @@ class Phi3VForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsQuant)
684 def get_input_embeddings(
685 self,
686 input_ids: torch.Tensor,
687 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
687 + multimodal_embeddings: MultiModalEmbeddings | None = None,
688 *,
689 - is_multimodal: Optional[torch.Tensor] = None,
689 + is_multimodal: torch.Tensor | None = None,
690 handle_oov_mm_token: bool = False,
691 ) -> torch.Tensor:
692 inputs_embeds = self._get_text_embeddings(
@@ -716,8 +716,8 @@ class Phi3VForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsQuant)
716 self,
717 input_ids: torch.Tensor,
718 positions: torch.Tensor,
719 - intermediate_tensors: Optional[IntermediateTensors] = None,
720 - inputs_embeds: Optional[torch.Tensor] = None,
719 + intermediate_tensors: IntermediateTensors | None = None,
720 + inputs_embeds: torch.Tensor | None = None,
721 **kwargs: object,
722 ):
723 if intermediate_tensors is not None:
@@ -732,7 +732,7 @@ class Phi3VForCausalLM(nn.Module, SupportsMultiModal, SupportsPP, SupportsQuant)
732 def compute_logits(
733 self,
734 hidden_states: torch.Tensor,
735 - ) -> Optional[torch.Tensor]:
735 + ) -> torch.Tensor | None:
736 return self.language_model.compute_logits(hidden_states)
737
738 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/phi4_multimodal.py
+24 -24
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import math
4 from collections.abc import Iterable, Mapping, Sequence
5 -from typing import Annotated, Any, Literal, Optional, Union
5 +from typing import Annotated, Any, Literal, TypeAlias
6
7 import numpy as np
8 import torch
@@ -147,7 +147,7 @@ class Phi4MMImageEmbedding(nn.Module):
147 def get_img_features(
148 self,
149 img_embeds: torch.FloatTensor,
150 - attention_mask: Optional[torch.Tensor] = None,
150 + attention_mask: torch.Tensor | None = None,
151 ) -> torch.FloatTensor:
152 img_feature = self.img_processor(
153 img_embeds, patch_attention_mask=attention_mask
@@ -172,8 +172,8 @@ class Phi4MMImageEmbedding(nn.Module):
172 def forward(
173 self,
174 image_pixel_values: torch.FloatTensor,
175 - image_sizes: Optional[torch.Tensor] = None,
176 - image_attention_mask: Optional[torch.Tensor] = None,
175 + image_sizes: torch.Tensor | None = None,
176 + image_attention_mask: torch.Tensor | None = None,
177 ) -> torch.FloatTensor:
178 image_pixel_values = image_pixel_values.to(
179 self.img_processor.embeddings.patch_embedding.weight.dtype
@@ -278,7 +278,7 @@ class Phi4MultimodalAudioMLP(nn.Module):
278 def __init__(
279 self,
280 config: Phi4MultimodalAudioConfig,
281 - quant_config: Optional[QuantizationConfig] = None,
281 + quant_config: QuantizationConfig | None = None,
282 prefix: str = "",
283 ):
284 super().__init__()
@@ -311,7 +311,7 @@ class Phi4MultimodalAudioAttention(nn.Module):
311 def __init__(
312 self,
313 config: Phi4MultimodalAudioConfig,
314 - quant_config: Optional[QuantizationConfig] = None,
314 + quant_config: QuantizationConfig | None = None,
315 prefix: str = "",
316 ):
317 super().__init__()
@@ -522,7 +522,7 @@ class Phi4MultimodalAudioModel(nn.Module):
522 pad_mask = pad_mask & enc_streaming_mask
523 return pad_mask
524
525 - def forward(self, hidden_states: torch.Tensor, mask: Optional[torch.Tensor] = None):
525 + def forward(self, hidden_states: torch.Tensor, mask: torch.Tensor | None = None):
526 hidden_states = self.encoder_embedding(hidden_states)
527 hidden_states, hs_mask, mask = self.forward_embeddings(hidden_states, mask)
528
@@ -673,7 +673,7 @@ class Phi4MMImagePixelInputs(TensorSchema):
673 type: Literal["pixel_values"]
674
675 data: Annotated[
676 - Union[torch.Tensor, list[torch.Tensor]],
676 + torch.Tensor | list[torch.Tensor],
677 TensorShape(
678 "bn", "p", 3, "h", "w", dynamic_dims={"p"}
679 ), # may be different per batch and image
@@ -706,7 +706,7 @@ class Phi4MMImageEmbeddingInputs(TensorSchema):
706 type: Literal["image_embeds"]
707
708 data: Annotated[
709 - Union[torch.Tensor, list[torch.Tensor]],
709 + torch.Tensor | list[torch.Tensor],
710 TensorShape("bn", "f", "h"),
711 ]
712
@@ -722,7 +722,7 @@ class Phi4MMAudioFeatureInputs(TensorSchema):
722 type: Literal["audio_features"]
723
724 data: Annotated[
725 - Union[torch.Tensor, list[torch.Tensor]],
725 + torch.Tensor | list[torch.Tensor],
726 TensorShape("bn", "t", 80, dynamic_dims={"t"}),
727 ]
728
@@ -744,8 +744,8 @@ class Phi4MMAudioEmbeddingInputs(TensorSchema):
744 ]
745
746
747 -Phi4MMImageInput = Union[Phi4MMImagePixelInputs, Phi4MMImageEmbeddingInputs]
748 -Phi4MMAudioInputs = Union[Phi4MMAudioFeatureInputs, Phi4MMAudioEmbeddingInputs]
747 +Phi4MMImageInput: TypeAlias = Phi4MMImagePixelInputs | Phi4MMImageEmbeddingInputs
748 +Phi4MMAudioInputs: TypeAlias = Phi4MMAudioFeatureInputs | Phi4MMAudioEmbeddingInputs
749
750
751 def cat_with_pad(tensors, dim, padding_value=0):
@@ -786,7 +786,7 @@ class Phi4MMProcessingInfo(BaseProcessingInfo):
786
787 def get_image_processor(
788 self,
789 - processor: Optional[Phi4MMProcessor] = None,
789 + processor: Phi4MMProcessor | None = None,
790 ) -> Phi4MultimodalImageProcessorFast:
791 if processor is None:
792 processor = self.get_hf_processor()
@@ -794,11 +794,11 @@ class Phi4MMProcessingInfo(BaseProcessingInfo):
794
795 def get_dynamic_hd(
796 self,
797 - processor: Optional[Phi4MMProcessor] = None,
797 + processor: Phi4MMProcessor | None = None,
798 ) -> int:
799 return self.get_image_processor(processor).dynamic_hd
800
801 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
801 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
802 return {"audio": None, "image": None}
803
804 def _find_target_aspect_ratio(
@@ -936,7 +936,7 @@ class Phi4MMProcessingInfo(BaseProcessingInfo):
936 *,
937 image_width: int,
938 image_height: int,
939 - processor: Optional[Phi4MMProcessor] = None,
939 + processor: Phi4MMProcessor | None = None,
940 ) -> int:
941 hf_config = self.get_hf_config()
942 vision_config = hf_config.vision_config
@@ -959,7 +959,7 @@ class Phi4MMProcessingInfo(BaseProcessingInfo):
959
960 def get_image_size_with_most_features(
961 self,
962 - processor: Optional[Phi4MMProcessor] = None,
962 + processor: Phi4MMProcessor | None = None,
963 ) -> ImageSize:
964 vit_image_size = self.get_hf_config().vision_config.image_size
965
@@ -1038,7 +1038,7 @@ class Phi4MMDummyInputsBuilder(BaseDummyInputsBuilder[Phi4MMProcessingInfo]):
1038 self,
1039 seq_len: int,
1040 mm_counts: Mapping[str, int],
1041 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
1041 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
1042 ) -> MultiModalDataDict:
1043 num_audios = mm_counts.get("audio", 0)
1044 num_images = mm_counts.get("image", 0)
@@ -1216,7 +1216,7 @@ class Phi4MultimodalForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1216 )
1217
1218 @classmethod
1219 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1219 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1220 if modality.startswith("image"):
1221 return "<|image|>"
1222 if modality.startswith("audio"):
@@ -1253,7 +1253,7 @@ class Phi4MultimodalForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1253
1254 def _parse_and_validate_audio_input(
1255 self, **kwargs: object
1256 - ) -> Optional[Phi4MMAudioInputs]:
1256 + ) -> Phi4MMAudioInputs | None:
1257 """
1258 Parse and validate the audio input to the model. This handles both
1259 audio features and audio embeddings, but only the former is used for
@@ -1314,7 +1314,7 @@ class Phi4MultimodalForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1314
1315 def _parse_and_validate_image_input(
1316 self, **kwargs: object
1317 - ) -> Optional[Phi4MMImagePixelInputs]:
1317 + ) -> Phi4MMImagePixelInputs | None:
1318 image_pixel_values: NestedTensors = kwargs.get("image_pixel_values")
1319 if image_pixel_values is None:
1320 return None
@@ -1445,8 +1445,8 @@ class Phi4MultimodalForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1445 self,
1446 input_ids: torch.Tensor,
1447 positions: torch.Tensor,
1448 - intermediate_tensors: Optional[IntermediateTensors] = None,
1449 - inputs_embeds: Optional[torch.Tensor] = None,
1448 + intermediate_tensors: IntermediateTensors | None = None,
1449 + inputs_embeds: torch.Tensor | None = None,
1450 **kwargs: object,
1451 ) -> torch.Tensor:
1452 if intermediate_tensors is not None:
@@ -1464,7 +1464,7 @@ class Phi4MultimodalForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1464 def compute_logits(
1465 self,
1466 hidden_states: torch.Tensor,
1467 - ) -> Optional[torch.Tensor]:
1467 + ) -> torch.Tensor | None:
1468 return self.language_model.compute_logits(hidden_states)
1469
1470 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/phi4mm.py
+16 -16
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import math
4 from collections.abc import Iterable, Mapping, Sequence
5 -from typing import Annotated, Any, Literal, Optional, Union
5 +from typing import Annotated, Any, Literal, TypeAlias
6
7 import numpy as np
8 import torch
@@ -122,7 +122,7 @@ class Phi4MMImageEncoder(nn.Module):
122 def __init__(
123 self,
124 config: PretrainedConfig,
125 - quant_config: Optional[QuantizationConfig],
125 + quant_config: QuantizationConfig | None,
126 prefix: str = "",
127 model_dir: str = "",
128 ) -> None:
@@ -468,7 +468,7 @@ class Phi4MMImagePixelInputs(TensorSchema):
468 type: Literal["pixel_values"]
469
470 data: Annotated[
471 - Union[torch.Tensor, list[torch.Tensor]],
471 + torch.Tensor | list[torch.Tensor],
472 TensorShape(
473 "bn", "p", 3, "h", "w", dynamic_dims={"p"}
474 ), # may be different per batch and image
@@ -500,7 +500,7 @@ class Phi4MMAudioFeatureInputs(TensorSchema):
500 type: Literal["audio_features"]
501
502 data: Annotated[
503 - Union[torch.Tensor, list[torch.Tensor]],
503 + torch.Tensor | list[torch.Tensor],
504 TensorShape("bn", "t", 80, dynamic_dims={"t"}),
505 ]
506
@@ -521,7 +521,7 @@ class Phi4MMAudioEmbeddingInputs(TensorSchema):
521 ]
522
523
524 -Phi4MMAudioInputs = Union[Phi4MMAudioFeatureInputs, Phi4MMAudioEmbeddingInputs]
524 +Phi4MMAudioInputs: TypeAlias = Phi4MMAudioFeatureInputs | Phi4MMAudioEmbeddingInputs
525
526
527 def cat_with_pad(tensors, dim, padding_value=0):
@@ -561,7 +561,7 @@ class Phi4MMProcessingInfo(BaseProcessingInfo):
561
562 def get_dynamic_hd(
563 self,
564 - processor: Optional[ProcessorMixin] = None,
564 + processor: ProcessorMixin | None = None,
565 ) -> int:
566 if processor is None:
567 processor = self.get_hf_processor()
@@ -571,7 +571,7 @@ class Phi4MMProcessingInfo(BaseProcessingInfo):
571 def get_feature_extractor(self, **kwargs: object) -> SequenceFeatureExtractor:
572 return self.get_hf_processor(**kwargs).audio_processor
573
574 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
574 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
575 return {"audio": None, "image": None}
576
577 def _find_target_aspect_ratio(
@@ -709,7 +709,7 @@ class Phi4MMProcessingInfo(BaseProcessingInfo):
709 *,
710 image_width: int,
711 image_height: int,
712 - processor: Optional[ProcessorMixin] = None,
712 + processor: ProcessorMixin | None = None,
713 ) -> int:
714 hf_config = self.get_hf_config()
715 vision_encoder_name = hf_config.img_processor
@@ -735,7 +735,7 @@ class Phi4MMProcessingInfo(BaseProcessingInfo):
735
736 def get_image_size_with_most_features(
737 self,
738 - processor: Optional[ProcessorMixin] = None,
738 + processor: ProcessorMixin | None = None,
739 ) -> ImageSize:
740 hf_config = self.get_hf_config()
741 vision_encoder_name = hf_config.img_processor
@@ -819,7 +819,7 @@ class Phi4MMDummyInputsBuilder(BaseDummyInputsBuilder[Phi4MMProcessingInfo]):
819 self,
820 seq_len: int,
821 mm_counts: Mapping[str, int],
822 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
822 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
823 ) -> MultiModalDataDict:
824 num_audios = mm_counts.get("audio", 0)
825 num_images = mm_counts.get("image", 0)
@@ -1008,7 +1008,7 @@ class Phi4MMForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1008 )
1009
1010 @classmethod
1011 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1011 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1012 if modality.startswith("image"):
1013 return f"<|image_{i}|>"
1014 if modality.startswith("audio"):
@@ -1074,7 +1074,7 @@ class Phi4MMForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1074
1075 def _parse_and_validate_audio_input(
1076 self, **kwargs: object
1077 - ) -> Optional[Phi4MMAudioInputs]:
1077 + ) -> Phi4MMAudioInputs | None:
1078 """
1079 Parse and validate the audio input to the model. This handles both
1080 audio features and audio embeddings, but only the former is used for
@@ -1135,7 +1135,7 @@ class Phi4MMForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1135
1136 def _parse_and_validate_image_input(
1137 self, **kwargs: object
1138 - ) -> Optional[Phi4MMImagePixelInputs]:
1138 + ) -> Phi4MMImagePixelInputs | None:
1139 input_image_embeds: NestedTensors = kwargs.get("input_image_embeds")
1140 if input_image_embeds is None:
1141 return None
@@ -1263,8 +1263,8 @@ class Phi4MMForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1263 self,
1264 input_ids: torch.Tensor,
1265 positions: torch.Tensor,
1266 - intermediate_tensors: Optional[IntermediateTensors] = None,
1267 - inputs_embeds: Optional[torch.Tensor] = None,
1266 + intermediate_tensors: IntermediateTensors | None = None,
1267 + inputs_embeds: torch.Tensor | None = None,
1268 **kwargs: object,
1269 ) -> torch.Tensor:
1270 if intermediate_tensors is not None:
@@ -1282,7 +1282,7 @@ class Phi4MMForCausalLM(nn.Module, SupportsLoRA, SupportsMultiModal):
1282 def compute_logits(
1283 self,
1284 hidden_states: torch.Tensor,
1285 - ) -> Optional[torch.Tensor]:
1285 + ) -> torch.Tensor | None:
1286 logits = self.logits_processor(self.lm_head, hidden_states)
1287 return logits
1288
vllm/model_executor/models/phi4mm_audio.py
+38 -38
@@ -7,7 +7,7 @@
7 #!/usr/bin/env python3
8 import abc
9 import math
10 -from typing import Any, Literal, Optional, Union
10 +from typing import Any, Literal
11
12 import numpy as np
13 import torch
@@ -221,7 +221,7 @@ class ConformerEncoderLayer(nn.Module):
221 pos_k: torch.Tensor,
222 pos_v: torch.Tensor,
223 mask: torch.Tensor,
224 - relative_attention_bias: Optional[Tensor] = None,
224 + relative_attention_bias: Tensor | None = None,
225 ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
226 """ConformerEncoder forward.
227
@@ -329,8 +329,8 @@ class TransformerEncoderBase(abc.ABC, nn.Module):
329 def __init__(
330 self,
331 input_size: int,
332 - chunk_size: Union[int, list[int]],
333 - left_chunk: Union[int, list[int]],
332 + chunk_size: int | list[int],
333 + left_chunk: int | list[int],
334 attention_dim: int = 256,
335 attention_heads: int = 4,
336 input_layer: str = "nemo_conv",
@@ -339,12 +339,12 @@ class TransformerEncoderBase(abc.ABC, nn.Module):
339 time_reduction: int = 4,
340 dropout_rate: float = 0.0,
341 padding_idx: int = -1,
342 - relative_attention_bias_args: Optional[dict[str, Any]] = None,
342 + relative_attention_bias_args: dict[str, Any] | None = None,
343 positional_dropout_rate: float = 0.0,
344 - nemo_conv_settings: Optional[dict[str, Any]] = None,
344 + nemo_conv_settings: dict[str, Any] | None = None,
345 conv2d_extra_padding: Literal["feat", "feat_time", "none", True] = "none",
346 attention_group_size: int = 1,
347 - encoder_embedding_config: Optional[dict[str, Any]] = None,
347 + encoder_embedding_config: dict[str, Any] | None = None,
348 ) -> None:
349 super().__init__()
350 self.input_size = input_size
@@ -411,8 +411,8 @@ class TransformerEncoderBase(abc.ABC, nn.Module):
411 )
412
413 def compute_lens_change(
414 - self, feature_lens: Union[int, torch.Tensor]
415 - ) -> Union[int, torch.Tensor]:
414 + self, feature_lens: int | torch.Tensor
415 + ) -> int | torch.Tensor:
416 """feature_lens: int
417 return updated feature lens.
418
@@ -452,8 +452,8 @@ class TransformerEncoderBase(abc.ABC, nn.Module):
452
453 def _chunk_size_selection(
454 self,
455 - chunk_size: Optional[Union[int, list[int]]] = None,
456 - left_chunk: Optional[Union[int, list[int]]] = None,
455 + chunk_size: int | list[int] | None = None,
456 + left_chunk: int | list[int] | None = None,
457 ) -> tuple[int, int]:
458 """If chunk size is a list, we will randomly select a chunk size."""
459
@@ -503,7 +503,7 @@ class TransformerEncoderBase(abc.ABC, nn.Module):
503
504 def _position_embedding(
505 self, input_tensor: torch.Tensor
506 - ) -> tuple[Optional[torch.Tensor], Optional[torch.Tensor]]:
506 + ) -> tuple[torch.Tensor | None, torch.Tensor | None]:
507 pos_k = None
508 pos_v = None
509 if self.relative_attention_bias_layer is None:
@@ -516,8 +516,8 @@ class TransformerEncoderBase(abc.ABC, nn.Module):
516 self,
517 seq_len: int,
518 batch_size: int,
519 - chunk_size: Union[int, list[int]],
520 - left_chunk: Union[int, list[int]],
519 + chunk_size: int | list[int],
520 + left_chunk: int | list[int],
521 ) -> torch.Tensor:
522 chunk_size_train_eff, left_chunk_train_eff = self._chunk_size_selection(
523 chunk_size, left_chunk
@@ -540,25 +540,25 @@ class TransformerEncoderBase(abc.ABC, nn.Module):
540 self,
541 xs_pad: torch.Tensor,
542 masks: torch.Tensor,
543 - chunk_size_nc: Optional[Union[int, list[int]]] = None,
544 - left_chunk_nc: Optional[Union[int, list[int]]] = None,
545 - ) -> Union[
543 + chunk_size_nc: int | list[int] | None = None,
544 + left_chunk_nc: int | list[int] | None = None,
545 + ) -> (
546 tuple[
547 torch.Tensor,
548 - Optional[torch.Tensor],
549 - Optional[torch.Tensor],
548 + torch.Tensor | None,
549 + torch.Tensor | None,
550 torch.Tensor,
551 torch.Tensor,
552 - ],
553 - tuple[
552 + ]
553 + | tuple[
554 torch.Tensor,
555 - Optional[torch.Tensor],
556 - Optional[torch.Tensor],
555 + torch.Tensor | None,
556 + torch.Tensor | None,
557 torch.Tensor,
558 torch.Tensor,
559 torch.Tensor,
560 - ],
561 - ]:
560 + ]
561 + ):
562 """Forwarding the inputs through the top embedding layers
563
564 Args:
@@ -803,9 +803,9 @@ class ConformerEncoder(TransformerEncoderBase):
803 def __init__( # pylint: disable-all
804 self,
805 input_size: int,
806 - chunk_size: Union[int, list[int]],
807 - left_chunk: Union[int, list[int]],
808 - num_lang: Optional[int] = None,
806 + chunk_size: int | list[int],
807 + left_chunk: int | list[int],
808 + num_lang: int | None = None,
809 attention_dim: int = 256,
810 attention_heads: int = 4,
811 linear_units: int = 2048,
@@ -832,14 +832,14 @@ class ConformerEncoder(TransformerEncoderBase):
832 extra_layer_output_idx: int = -1,
833 extra_multi_layer_output_idxs: list[int] = [], # noqa
834 activation_checkpointing: str = "",
835 - relative_attention_bias_args: Optional[dict[str, Any]] = None,
835 + relative_attention_bias_args: dict[str, Any] | None = None,
836 time_reduction: int = 4,
837 use_pt_scaled_dot_product_attention: bool = False,
838 - nemo_conv_settings: Optional[dict[str, Any]] = None,
838 + nemo_conv_settings: dict[str, Any] | None = None,
839 conv2d_extra_padding: Literal["feat", "feat_time", "none", True] = "none",
840 replication_pad_for_subsample_embedding: bool = False,
841 attention_group_size: int = 1,
842 - encoder_embedding_config: Optional[dict[str, Any]] = None,
842 + encoder_embedding_config: dict[str, Any] | None = None,
843 ) -> None:
844 super().__init__(
845 input_size,
@@ -908,12 +908,12 @@ class ConformerEncoder(TransformerEncoderBase):
908
909 def init_relative_attention_bias(
910 self, input_tensor: torch.Tensor
911 - ) -> Optional[torch.Tensor]:
911 + ) -> torch.Tensor | None:
912 if self.relative_attention_bias_layer:
913 return self.relative_attention_bias_layer(input_tensor)
914
915 def calculate_hs_mask(
916 - self, xs_pad: torch.Tensor, device: torch.device, mask: Optional[torch.Tensor]
916 + self, xs_pad: torch.Tensor, device: torch.device, mask: torch.Tensor | None
917 ) -> torch.Tensor:
918 max_audio_length = xs_pad.shape[1]
919 batch_size = xs_pad.shape[0]
@@ -1066,9 +1066,9 @@ class WindowQformer(nn.Module):
1066 def forward(
1067 self,
1068 audio_embed: torch.Tensor,
1069 - mask: Optional[torch.Tensor],
1070 - embed_len: Optional[int] = None,
1071 - ) -> tuple[torch.Tensor, Optional[int]]:
1069 + mask: torch.Tensor | None,
1070 + embed_len: int | None = None,
1071 + ) -> tuple[torch.Tensor, int | None]:
1072 """forward decoder"""
1073 # audio_embed: N x T x D => N x D x T
1074
@@ -1224,7 +1224,7 @@ class AudioEmbedding(nn.Module):
1224 def get_audio_features(
1225 self,
1226 input_embeds: torch.Tensor,
1227 - audio_attention_mask: Optional[torch.Tensor] = None,
1227 + audio_attention_mask: torch.Tensor | None = None,
1228 audio_projection_mode: str = "speech",
1229 ) -> torch.Tensor:
1230 """
@@ -1278,7 +1278,7 @@ class AudioEmbedding(nn.Module):
1278 def forward(
1279 self,
1280 audio_features: torch.Tensor,
1281 - audio_attention_mask: Optional[torch.Tensor] = None,
1281 + audio_attention_mask: torch.Tensor | None = None,
1282 audio_projection_mode: str = "speech",
1283 ) -> torch.Tensor:
1284 """
vllm/model_executor/models/phi4mm_utils.py
+17 -20
@@ -6,7 +6,6 @@
6 # but implemented by the Phi-Speech team
7 #!/usr/bin/env python3
8 import math
9 -from typing import Optional, Union
9
10 import torch
11 import torch.nn.functional as F
@@ -917,7 +916,7 @@ class CausalConv1D(nn.Conv1d):
916 out_channels: int,
917 kernel_size: int,
918 stride: int = 1,
920 - padding: Union[str, int] = 0,
919 + padding: str | int = 0,
920 dilation: int = 1,
921 groups: int = 1,
922 bias: bool = True,
@@ -962,8 +961,8 @@ class CausalConv1D(nn.Conv1d):
961 )
962
963 def update_cache(
965 - self, x: Tensor, cache: Optional[Tensor] = None
966 - ) -> tuple[Tensor, Optional[Tensor]]:
964 + self, x: Tensor, cache: Tensor | None = None
965 + ) -> tuple[Tensor, Tensor | None]:
966 if cache is None:
967 new_x = F.pad(x, pad=(self._left_padding, self._right_padding))
968 next_cache = cache
@@ -978,8 +977,8 @@ class CausalConv1D(nn.Conv1d):
977 return new_x, next_cache
978
979 def forward(
981 - self, x: Tensor, cache: Optional[Tensor] = None
982 - ) -> Union[Tensor, tuple[Tensor, Optional[Tensor]]]:
980 + self, x: Tensor, cache: Tensor | None = None
981 + ) -> Tensor | tuple[Tensor, Tensor | None]:
982 x, cache = self.update_cache(x, cache=cache)
983 x = super().forward(x)
984 if cache is None:
@@ -1002,7 +1001,7 @@ class CausalConv2D(nn.Conv2d):
1001 out_channels: int,
1002 kernel_size: int,
1003 stride: int = 1,
1005 - padding: Union[str, int] = 0,
1004 + padding: str | int = 0,
1005 dilation: int = 1,
1006 groups: int = 1,
1007 bias: bool = True,
@@ -1371,9 +1370,7 @@ class NemoConvSubsampling(torch.nn.Module):
1370 def get_streaming_cache_size(self) -> list[int]:
1371 return [0, self.subsampling_factor + 1]
1372
1374 - def forward(
1375 - self, x: Tensor, mask: Optional[Tensor]
1376 - ) -> tuple[Tensor, Optional[Tensor]]:
1373 + def forward(self, x: Tensor, mask: Tensor | None) -> tuple[Tensor, Tensor | None]:
1374 """
1375 Forward method for NeMo subsampling.
1376
@@ -1615,10 +1612,10 @@ class AttModule(nn.Module):
1612 def forward(
1613 self,
1614 x: Tensor,
1618 - memory: Optional[Tensor] = None,
1619 - pos_emb: Optional[Tensor] = None,
1620 - att_mask: Optional[Tensor] = None,
1621 - ) -> tuple[Tensor, Tensor, Optional[Tensor], Optional[Tensor]]:
1615 + memory: Tensor | None = None,
1616 + pos_emb: Tensor | None = None,
1617 + att_mask: Tensor | None = None,
1618 + ) -> tuple[Tensor, Tensor, Tensor | None, Tensor | None]:
1619 """AttModule forward
1620
1621 Args:
@@ -1640,7 +1637,7 @@ class AttBlock(BlockBase, AttModule):
1637
1638 def masked_softmax(
1639 scores: Tensor,
1643 - mask: Optional[Tensor],
1640 + mask: Tensor | None,
1641 ) -> Tensor:
1642 if mask is not None:
1643 mask = mask.unsqueeze(1).eq(0) # (batch, 1, time1, time2)
@@ -1720,7 +1717,7 @@ class MultiHeadedAttention(nn.Module):
1717 self.linear_v = nn.Linear(n_value, attention_inner_dim // group_size)
1718 self.linear_out = nn.Linear(attention_inner_dim // group_size, n_value)
1719
1723 - self.attn = torch.jit.Attribute(None, Optional[Tensor])
1720 + self.attn = torch.jit.Attribute(None, Tensor | None)
1721 self.dropout = nn.Dropout(p=dropout_rate)
1722 self.dropout_rate = dropout_rate
1723 self.use_pt_scaled_dot_product_attention = use_pt_scaled_dot_product_attention
@@ -1741,10 +1738,10 @@ class MultiHeadedAttention(nn.Module):
1738 query: Tensor,
1739 key: Tensor,
1740 value: Tensor,
1744 - pos_k: Optional[Tensor],
1745 - pos_v: Optional[Tensor],
1746 - mask: Optional[Tensor],
1747 - relative_attention_bias: Optional[Tensor] = None,
1741 + pos_k: Tensor | None,
1742 + pos_v: Tensor | None,
1743 + mask: Tensor | None,
1744 + relative_attention_bias: Tensor | None = None,
1745 ) -> Tensor:
1746 """Compute 'Scaled Dot Product Attention'.
1747
vllm/model_executor/models/phimoe.py
+16 -17
@@ -26,7 +26,6 @@
26
27 from collections.abc import Iterable
28 from itertools import islice
29 -from typing import Optional, Union
29
30 import torch
31 from torch import nn
@@ -257,9 +256,9 @@ class PhiMoE(nn.Module):
256 top_k: int,
257 hidden_size: int,
258 intermediate_size: int,
260 - params_dtype: Optional[torch.dtype] = None,
261 - quant_config: Optional[QuantizationConfig] = None,
262 - tp_size: Optional[int] = None,
259 + params_dtype: torch.dtype | None = None,
260 + quant_config: QuantizationConfig | None = None,
261 + tp_size: int | None = None,
262 prefix: str = "",
263 ):
264 super().__init__()
@@ -304,12 +303,12 @@ class PhiMoEAttention(nn.Module):
303 hidden_size: int,
304 num_heads: int,
305 num_kv_heads: int,
307 - head_dim: Optional[int] = None,
306 + head_dim: int | None = None,
307 max_position: int = 4096 * 32,
308 rope_theta: float = 10000,
310 - cache_config: Optional[CacheConfig] = None,
311 - quant_config: Optional[QuantizationConfig] = None,
312 - rope_scaling: Optional[dict] = None,
309 + cache_config: CacheConfig | None = None,
310 + quant_config: QuantizationConfig | None = None,
311 + rope_scaling: dict | None = None,
312 prefix: str = "",
313 ) -> None:
314 super().__init__()
@@ -386,8 +385,8 @@ class PhiMoEDecoderLayer(nn.Module):
385 def __init__(
386 self,
387 config: PhiMoEConfig,
389 - cache_config: Optional[CacheConfig] = None,
390 - quant_config: Optional[QuantizationConfig] = None,
388 + cache_config: CacheConfig | None = None,
389 + quant_config: QuantizationConfig | None = None,
390 prefix: str = "",
391 ) -> None:
392 super().__init__()
@@ -427,7 +426,7 @@ class PhiMoEDecoderLayer(nn.Module):
426 self,
427 positions: torch.Tensor,
428 hidden_states: torch.Tensor,
430 - residual: Optional[torch.Tensor],
429 + residual: torch.Tensor | None,
430 ) -> torch.Tensor:
431 residual = hidden_states
432
@@ -496,9 +495,9 @@ class PhiMoEModel(nn.Module):
495 self,
496 input_ids: torch.Tensor,
497 positions: torch.Tensor,
499 - intermediate_tensors: Optional[IntermediateTensors],
500 - inputs_embeds: Optional[torch.Tensor] = None,
501 - ) -> Union[torch.Tensor, IntermediateTensors]:
498 + intermediate_tensors: IntermediateTensors | None,
499 + inputs_embeds: torch.Tensor | None = None,
500 + ) -> torch.Tensor | IntermediateTensors:
501 if get_pp_group().is_first_rank:
502 if inputs_embeds is not None:
503 hidden_states = inputs_embeds
@@ -674,9 +673,9 @@ class PhiMoEForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
673 self,
674 input_ids: torch.Tensor,
675 positions: torch.Tensor,
677 - intermediate_tensors: Optional[IntermediateTensors] = None,
678 - inputs_embeds: Optional[torch.Tensor] = None,
679 - ) -> Union[torch.Tensor, IntermediateTensors]:
676 + intermediate_tensors: IntermediateTensors | None = None,
677 + inputs_embeds: torch.Tensor | None = None,
678 + ) -> torch.Tensor | IntermediateTensors:
679 hidden_states = self.model(
680 input_ids, positions, intermediate_tensors, inputs_embeds
681 )
vllm/model_executor/models/pixtral.py
+31 -31
@@ -5,7 +5,7 @@ import math
5 from collections.abc import Iterable, Mapping, Sequence
6 from dataclasses import dataclass, fields
7 from functools import cached_property
8 -from typing import Annotated, Literal, Optional, Union
8 +from typing import Annotated, Literal
9
10 import torch
11 import torch.nn as nn
@@ -100,7 +100,7 @@ class PixtralImagePixelInputs(TensorSchema):
100 type: Literal["pixel_values"] = "pixel_values"
101
102 images: Annotated[
103 - Union[torch.Tensor, list[torch.Tensor]],
103 + torch.Tensor | list[torch.Tensor],
104 TensorShape("bn", 3, "h", "w", dynamic_dims={"h", "w"}),
105 ]
106
@@ -144,9 +144,9 @@ class PixtralProcessorAdapter:
144
145 def __call__(
146 self,
147 - text: Optional[Union[TextInput, list[TextInput]]] = None,
148 - images: Optional[Union[ImageInput, list[ImageInput]]] = None,
149 - return_tensors: Optional[Union[str, TensorType]] = None,
147 + text: TextInput | list[TextInput] | None = None,
148 + images: ImageInput | list[ImageInput] | None = None,
149 + return_tensors: str | TensorType | None = None,
150 **kwargs,
151 ) -> Mapping[str, NestedTensors]:
152 if text is None:
@@ -203,12 +203,12 @@ class PixtralProcessingInfo(BaseProcessingInfo):
203 def get_hf_processor(self) -> PixtralProcessorAdapter:
204 return PixtralProcessorAdapter(self.get_tokenizer())
205
206 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
206 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
207 return {"image": None}
208
209 def get_vision_config(
210 self,
211 - processor: Optional[PixtralProcessorAdapter] = None,
211 + processor: PixtralProcessorAdapter | None = None,
212 ):
213 if processor is None:
214 processor = self.get_hf_processor()
@@ -223,7 +223,7 @@ class PixtralProcessingInfo(BaseProcessingInfo):
223 *,
224 image_width: int,
225 image_height: int,
226 - processor: Optional[PixtralProcessorAdapter] = None,
226 + processor: PixtralProcessorAdapter | None = None,
227 ) -> int:
228 if processor is None:
229 processor = self.get_hf_processor()
@@ -249,7 +249,7 @@ class PixtralDummyInputsBuilder(BaseDummyInputsBuilder[PixtralProcessingInfo]):
249 self,
250 seq_len: int,
251 mm_counts: Mapping[str, int],
252 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
252 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
253 ) -> MultiModalDataDict:
254 num_images = mm_counts.get("image", 0)
255
@@ -270,7 +270,7 @@ class PixtralDummyInputsBuilder(BaseDummyInputsBuilder[PixtralProcessingInfo]):
270 self,
271 seq_len: int,
272 mm_counts: Mapping[str, int],
273 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
273 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
274 ) -> ProcessorInputs:
275 tokenizer = self.info.get_tokenizer()
276
@@ -342,11 +342,11 @@ class PixtralMultiModalProcessor(BaseMultiModalProcessor[PixtralProcessingInfo])
342
343 def _cached_apply_hf_processor(
344 self,
345 - prompt: Union[str, list[int]],
345 + prompt: str | list[int],
346 mm_data_items: MultiModalDataItems,
347 hf_processor_mm_kwargs: Mapping[str, object],
348 tokenization_kwargs: Mapping[str, object],
349 - mm_uuids: Optional[MultiModalUUIDDict] = None,
349 + mm_uuids: MultiModalUUIDDict | None = None,
350 ) -> tuple[list[int], MultiModalProcessingInfo, bool]:
351 prompt_ids, mm_info, _ = super()._cached_apply_hf_processor(
352 prompt=prompt,
@@ -369,7 +369,7 @@ class PixtralForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
369 merge_by_field_config = True
370
371 @classmethod
372 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
372 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
373 if modality.startswith("image"):
374 return None
375
@@ -420,7 +420,7 @@ class PixtralForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
420
421 def _parse_and_validate_image_input(
422 self, **kwargs: object
423 - ) -> Optional[PixtralImagePixelInputs]:
423 + ) -> PixtralImagePixelInputs | None:
424 images = kwargs.pop("images", None)
425 if images is None:
426 return None
@@ -472,10 +472,10 @@ class PixtralForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
472 self,
473 input_ids: torch.Tensor,
474 positions: torch.Tensor,
475 - intermediate_tensors: Optional[IntermediateTensors] = None,
476 - inputs_embeds: Optional[torch.Tensor] = None,
475 + intermediate_tensors: IntermediateTensors | None = None,
476 + inputs_embeds: torch.Tensor | None = None,
477 **kwargs: object,
478 - ) -> Union[torch.Tensor, IntermediateTensors]:
478 + ) -> torch.Tensor | IntermediateTensors:
479 """Run forward pass for pixtral."""
480 if intermediate_tensors is not None:
481 inputs_embeds = None
@@ -489,7 +489,7 @@ class PixtralForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
489 def compute_logits(
490 self,
491 hidden_states: torch.Tensor,
492 - ) -> Optional[torch.Tensor]:
492 + ) -> torch.Tensor | None:
493 return self.language_model.compute_logits(hidden_states)
494
495 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]):
@@ -717,7 +717,7 @@ class Transformer(nn.Module):
717 self,
718 x: torch.Tensor,
719 mask: torch.Tensor,
720 - freqs_cis: Optional[torch.Tensor],
720 + freqs_cis: torch.Tensor | None,
721 ) -> torch.Tensor:
722 for layer in self.layers:
723 x = layer(x, mask=mask, freqs_cis=freqs_cis)
@@ -759,7 +759,7 @@ class VisionTransformer(nn.Module):
759
760 head_dim = self.args.hidden_size // self.args.num_attention_heads
761 assert head_dim % 2 == 0, "ROPE requires even head_dim"
762 - self._freqs_cis: Optional[torch.Tensor] = None
762 + self._freqs_cis: torch.Tensor | None = None
763
764 @property
765 def max_patches_per_side(self) -> int:
@@ -1015,7 +1015,7 @@ class PixtralHFMLP(nn.Module):
1015 def __init__(
1016 self,
1017 config: PixtralVisionConfig,
1018 - quant_config: Optional[QuantizationConfig] = None,
1018 + quant_config: QuantizationConfig | None = None,
1019 *,
1020 prefix: str = "",
1021 ) -> None:
@@ -1049,7 +1049,7 @@ class PixtralHFAttention(nn.Module):
1049 def __init__(
1050 self,
1051 config: PixtralVisionConfig,
1052 - quant_config: Optional[QuantizationConfig] = None,
1052 + quant_config: QuantizationConfig | None = None,
1053 *,
1054 prefix: str = "",
1055 ) -> None:
@@ -1084,7 +1084,7 @@ class PixtralHFAttention(nn.Module):
1084 hidden_states: torch.Tensor,
1085 attention_mask: torch.Tensor,
1086 position_embeddings: torch.Tensor,
1087 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
1087 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
1088 batch, patches, _ = hidden_states.size()
1089
1090 qkv_states, _ = self.qkv_proj(hidden_states)
@@ -1119,7 +1119,7 @@ class PixtralHFTransformerBlock(nn.Module):
1119 def __init__(
1120 self,
1121 config: PixtralVisionConfig,
1122 - quant_config: Optional[QuantizationConfig] = None,
1122 + quant_config: QuantizationConfig | None = None,
1123 *,
1124 prefix: str = "",
1125 ) -> None:
@@ -1155,9 +1155,9 @@ class PixtralHFTransformer(nn.Module):
1155 def __init__(
1156 self,
1157 config: PixtralVisionConfig,
1158 - quant_config: Optional[QuantizationConfig] = None,
1158 + quant_config: QuantizationConfig | None = None,
1159 *,
1160 - num_hidden_layers_override: Optional[int] = None,
1160 + num_hidden_layers_override: int | None = None,
1161 prefix: str = "",
1162 ) -> None:
1163 super().__init__()
@@ -1202,10 +1202,10 @@ class PixtralHFVisionModel(nn.Module):
1202 def __init__(
1203 self,
1204 config: PixtralVisionConfig,
1205 - quant_config: Optional[QuantizationConfig] = None,
1205 + quant_config: QuantizationConfig | None = None,
1206 *,
1207 - num_hidden_layers_override: Optional[int] = None,
1208 - require_post_norm: Optional[bool] = None,
1207 + num_hidden_layers_override: int | None = None,
1208 + require_post_norm: bool | None = None,
1209 prefix: str = "",
1210 ) -> None:
1211 super().__init__()
@@ -1247,8 +1247,8 @@ class PixtralHFVisionModel(nn.Module):
1247 self,
1248 pixel_values: list[torch.Tensor],
1249 *,
1250 - select_layers: Optional[list[int]] = None,
1251 - feature_select_strategy: Optional[VisionFeatureSelectStrategy] = None,
1250 + select_layers: list[int] | None = None,
1251 + feature_select_strategy: VisionFeatureSelectStrategy | None = None,
1252 ) -> tuple[torch.Tensor, ...]:
1253 """
1254 Args:
vllm/model_executor/models/plamo2.py
+9 -9
@@ -4,7 +4,7 @@
4
5 from collections.abc import Iterable
6 from itertools import islice
7 -from typing import TYPE_CHECKING, Optional
7 +from typing import TYPE_CHECKING
8
9 if TYPE_CHECKING:
10 from vllm.attention.backends.abstract import AttentionBackend
@@ -504,7 +504,7 @@ class DenseMLP(nn.Module):
504 def __init__(
505 self,
506 config: Plamo2Config,
507 - quant_config: Optional[QuantizationConfig] = None,
507 + quant_config: QuantizationConfig | None = None,
508 prefix: str = "",
509 ) -> None:
510 super().__init__()
@@ -672,7 +672,7 @@ class Plamo2DecoderLayer(nn.Module):
672 self,
673 positions: torch.Tensor,
674 hidden_states: torch.Tensor,
675 - residual: Optional[torch.Tensor],
675 + residual: torch.Tensor | None,
676 **kwargs,
677 ):
678 if residual is None:
@@ -728,7 +728,7 @@ class Plamo2Decoder(torch.nn.Module):
728 self,
729 positions: torch.Tensor,
730 hidden_states: torch.Tensor,
731 - residual: Optional[torch.Tensor],
731 + residual: torch.Tensor | None,
732 ) -> torch.Tensor:
733 for layer in islice(self.layers, self.start_layer, self.end_layer):
734 hidden_states, residual = layer(
@@ -770,8 +770,8 @@ class Plamo2Model(torch.nn.Module):
770 self,
771 input_ids: torch.Tensor,
772 positions: torch.Tensor,
773 - intermediate_tensors: Optional[IntermediateTensors] = None,
774 - inputs_embeds: Optional[torch.Tensor] = None,
773 + intermediate_tensors: IntermediateTensors | None = None,
774 + inputs_embeds: torch.Tensor | None = None,
775 ) -> torch.Tensor:
776 if get_pp_group().is_first_rank:
777 if inputs_embeds is not None:
@@ -851,8 +851,8 @@ class Plamo2ForCausalLM(torch.nn.Module, HasInnerState, SupportsPP, IsHybrid):
851 self,
852 input_ids: torch.Tensor,
853 positions: torch.Tensor,
854 - intermediate_tensors: Optional[IntermediateTensors] = None,
855 - inputs_embeds: Optional[torch.Tensor] = None,
854 + intermediate_tensors: IntermediateTensors | None = None,
855 + inputs_embeds: torch.Tensor | None = None,
856 **kwargs,
857 ):
858 hidden_states = self.model(
@@ -901,7 +901,7 @@ class Plamo2ForCausalLM(torch.nn.Module, HasInnerState, SupportsPP, IsHybrid):
901 def compute_logits(
902 self,
903 hidden_states: torch.Tensor,
904 - ) -> Optional[torch.Tensor]:
904 + ) -> torch.Tensor | None:
905 logits = self.logits_processor(self.lm_head, hidden_states)
906 return logits
907
vllm/model_executor/models/qwen.py
+15 -15
@@ -10,7 +10,7 @@
10 import json
11 from collections.abc import Iterable
12 from itertools import islice
13 -from typing import Any, Optional, Union
13 +from typing import Any
14
15 import torch
16 from torch import nn
@@ -55,7 +55,7 @@ class QWenMLP(nn.Module):
55 hidden_size: int,
56 intermediate_size: int,
57 hidden_act: str = "silu",
58 - quant_config: Optional[QuantizationConfig] = None,
58 + quant_config: QuantizationConfig | None = None,
59 ):
60 super().__init__()
61 self.gate_up_proj = MergedColumnParallelLinear(
@@ -84,9 +84,9 @@ class QWenAttention(nn.Module):
84 num_heads: int,
85 max_position_embeddings: int,
86 rope_theta: float = 10000,
87 - rope_scaling: Optional[dict[str, Any]] = None,
88 - cache_config: Optional[CacheConfig] = None,
89 - quant_config: Optional[QuantizationConfig] = None,
87 + rope_scaling: dict[str, Any] | None = None,
88 + cache_config: CacheConfig | None = None,
89 + quant_config: QuantizationConfig | None = None,
90 prefix: str = "",
91 ):
92 super().__init__()
@@ -144,8 +144,8 @@ class QWenBlock(nn.Module):
144 def __init__(
145 self,
146 config: PretrainedConfig,
147 - cache_config: Optional[CacheConfig] = None,
148 - quant_config: Optional[QuantizationConfig] = None,
147 + cache_config: CacheConfig | None = None,
148 + quant_config: QuantizationConfig | None = None,
149 prefix: str = "",
150 ):
151 super().__init__()
@@ -174,7 +174,7 @@ class QWenBlock(nn.Module):
174 self,
175 positions: torch.Tensor,
176 hidden_states: torch.Tensor,
177 - residual: Optional[torch.Tensor],
177 + residual: torch.Tensor | None,
178 ) -> tuple[torch.Tensor, torch.Tensor]:
179 # Self Attention
180 if residual is None:
@@ -226,9 +226,9 @@ class QWenModel(nn.Module):
226 self,
227 input_ids: torch.Tensor,
228 positions: torch.Tensor,
229 - intermediate_tensors: Optional[IntermediateTensors],
230 - inputs_embeds: Optional[torch.Tensor] = None,
231 - ) -> Union[torch.Tensor, IntermediateTensors]:
229 + intermediate_tensors: IntermediateTensors | None,
230 + inputs_embeds: torch.Tensor | None = None,
231 + ) -> torch.Tensor | IntermediateTensors:
232 if get_pp_group().is_first_rank:
233 if inputs_embeds is not None:
234 hidden_states = inputs_embeds
@@ -288,7 +288,7 @@ class QWenBaseModel(nn.Module):
288 def compute_logits(
289 self,
290 hidden_states: torch.Tensor,
291 - ) -> Optional[torch.Tensor]:
291 + ) -> torch.Tensor | None:
292 logits = self.logits_processor(self.lm_head, hidden_states)
293 return logits
294
@@ -357,9 +357,9 @@ class QWenLMHeadModel(QWenBaseModel, SupportsPP, SupportsLoRA):
357 self,
358 input_ids: torch.Tensor,
359 positions: torch.Tensor,
360 - intermediate_tensors: Optional[IntermediateTensors] = None,
361 - inputs_embeds: Optional[torch.Tensor] = None,
362 - ) -> Union[torch.Tensor, IntermediateTensors]:
360 + intermediate_tensors: IntermediateTensors | None = None,
361 + inputs_embeds: torch.Tensor | None = None,
362 + ) -> torch.Tensor | IntermediateTensors:
363 hidden_states = self.transformer(
364 input_ids, positions, intermediate_tensors, inputs_embeds
365 )
vllm/model_executor/models/qwen2.py
+16 -16
@@ -27,7 +27,7 @@
27
28 from collections.abc import Iterable
29 from itertools import islice
30 -from typing import Any, Optional, Union
30 +from typing import Any
31
32 import torch
33 from torch import nn
@@ -77,7 +77,7 @@ class Qwen2MLP(nn.Module):
77 hidden_size: int,
78 intermediate_size: int,
79 hidden_act: str,
80 - quant_config: Optional[QuantizationConfig] = None,
80 + quant_config: QuantizationConfig | None = None,
81 prefix: str = "",
82 ) -> None:
83 super().__init__()
@@ -116,12 +116,12 @@ class Qwen2Attention(nn.Module):
116 num_kv_heads: int,
117 max_position: int = 4096 * 32,
118 rope_theta: float = 10000,
119 - cache_config: Optional[CacheConfig] = None,
120 - quant_config: Optional[QuantizationConfig] = None,
121 - rope_scaling: Optional[tuple] = None,
119 + cache_config: CacheConfig | None = None,
120 + quant_config: QuantizationConfig | None = None,
121 + rope_scaling: tuple | None = None,
122 prefix: str = "",
123 attn_type: str = AttentionType.DECODER,
124 - dual_chunk_attention_config: Optional[dict[str, Any]] = None,
124 + dual_chunk_attention_config: dict[str, Any] | None = None,
125 ) -> None:
126 super().__init__()
127 self.hidden_size = hidden_size
@@ -210,8 +210,8 @@ class Qwen2DecoderLayer(nn.Module):
210 def __init__(
211 self,
212 config: Qwen2Config,
213 - cache_config: Optional[CacheConfig] = None,
214 - quant_config: Optional[QuantizationConfig] = None,
213 + cache_config: CacheConfig | None = None,
214 + quant_config: QuantizationConfig | None = None,
215 prefix: str = "",
216 ) -> None:
217 super().__init__()
@@ -261,7 +261,7 @@ class Qwen2DecoderLayer(nn.Module):
261 self,
262 positions: torch.Tensor,
263 hidden_states: torch.Tensor,
264 - residual: Optional[torch.Tensor],
264 + residual: torch.Tensor | None,
265 ) -> tuple[torch.Tensor, torch.Tensor]:
266 # Self Attention
267 if residual is None:
@@ -362,9 +362,9 @@ class Qwen2Model(nn.Module):
362 self,
363 input_ids: torch.Tensor,
364 positions: torch.Tensor,
365 - intermediate_tensors: Optional[IntermediateTensors] = None,
366 - inputs_embeds: Optional[torch.Tensor] = None,
367 - ) -> Union[torch.Tensor, IntermediateTensors]:
365 + intermediate_tensors: IntermediateTensors | None = None,
366 + inputs_embeds: torch.Tensor | None = None,
367 + ) -> torch.Tensor | IntermediateTensors:
368 if get_pp_group().is_first_rank:
369 if inputs_embeds is not None:
370 hidden_states = inputs_embeds
@@ -520,9 +520,9 @@ class Qwen2ForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3):
520 self,
521 input_ids: torch.Tensor,
522 positions: torch.Tensor,
523 - intermediate_tensors: Optional[IntermediateTensors] = None,
524 - inputs_embeds: Optional[torch.Tensor] = None,
525 - ) -> Union[torch.Tensor, IntermediateTensors]:
523 + intermediate_tensors: IntermediateTensors | None = None,
524 + inputs_embeds: torch.Tensor | None = None,
525 + ) -> torch.Tensor | IntermediateTensors:
526 hidden_states = self.model(
527 input_ids, positions, intermediate_tensors, inputs_embeds
528 )
@@ -531,7 +531,7 @@ class Qwen2ForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3):
531 def compute_logits(
532 self,
533 hidden_states: torch.Tensor,
534 - ) -> Optional[torch.Tensor]:
534 + ) -> torch.Tensor | None:
535 logits = self.logits_processor(self.lm_head, hidden_states)
536 return logits
537
vllm/model_executor/models/qwen2_5_omni_thinker.py
+24 -24
@@ -22,10 +22,10 @@
22 # limitations under the License.
23 """Inference-only Qwen2.5-Omni model (thinker part)."""
24
25 -from collections.abc import Iterable, Mapping, Sequence
25 +from collections.abc import Callable, Iterable, Mapping, Sequence
26 from copy import copy
27 from functools import partial
28 -from typing import Annotated, Any, Callable, Literal, Optional, Union
28 +from typing import Annotated, Any, Literal
29
30 import torch
31 import torch.nn as nn
@@ -125,7 +125,7 @@ class Qwen2_5OmniAudioFeatureInputs(TensorSchema):
125
126 type: Literal["audio_features"]
127 input_features: Annotated[
128 - Union[torch.Tensor, list[torch.Tensor]],
128 + torch.Tensor | list[torch.Tensor],
129 TensorShape("nmb", "tsl"),
130 ]
131
@@ -191,7 +191,7 @@ class Qwen2_5OmniThinkerMultiModalDataParser(Qwen2VLMultiModalDataParser):
191
192 def _parse_audio_data(
193 self,
194 - data: Union[dict[str, torch.Tensor], ModalityData[ImageItem]],
194 + data: dict[str, torch.Tensor] | ModalityData[ImageItem],
195 ) -> ModalityDataItems[Any, Any]:
196 if isinstance(data, dict):
197 return DictEmbeddingItems(
@@ -225,7 +225,7 @@ class Qwen2_5OmniThinkerProcessingInfo(
225 assert isinstance(feature_extractor, WhisperFeatureExtractor)
226 return feature_extractor
227
228 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
228 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
229 return {"audio": None, "image": None, "video": None}
230
231
@@ -253,7 +253,7 @@ class Qwen2_5OmniThinkerDummyInputsBuilder(
253 self,
254 seq_len: int,
255 mm_counts: Mapping[str, int],
256 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
256 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
257 ) -> MultiModalDataDict:
258 num_audios = mm_counts.get("audio", 0)
259 num_images = mm_counts.get("image", 0)
@@ -420,7 +420,7 @@ class Qwen2_5OmniThinkerMultiModalProcessor(
420 cls,
421 thinker_config: PretrainedConfig,
422 audio_len: int,
423 - video_grid_thw: Union[list[int], torch.Tensor],
423 + video_grid_thw: list[int] | torch.Tensor,
424 video_second_per_grid_t: float,
425 ) -> list[int]:
426 """Get video prompt updates when `use_audio_in_video` is True.
@@ -580,7 +580,7 @@ class Qwen2_5OmniThinkerMultiModalProcessor(
580
581 def _apply_hf_processor_main(
582 self,
583 - prompt: Union[str, list[int]],
583 + prompt: str | list[int],
584 mm_items: MultiModalDataItems,
585 hf_processor_mm_kwargs: Mapping[str, object],
586 tokenization_kwargs: Mapping[str, object],
@@ -665,7 +665,7 @@ class Qwen2_5OmniConditionalGenerationMixin:
665
666 def _parse_and_validate_audio_input(
667 self, **kwargs: object
668 - ) -> Optional[Qwen2_5OmniAudioFeatureInputs]:
668 + ) -> Qwen2_5OmniAudioFeatureInputs | None:
669 input_audio_features = kwargs.pop("input_audio_features", None)
670 audio_feature_lengths = kwargs.pop("audio_feature_lengths", None)
671 feature_attention_mask = kwargs.pop("feature_attention_mask", None)
@@ -693,7 +693,7 @@ class Qwen2_5OmniConditionalGenerationMixin:
693 def _parse_and_validate_image_input(
694 self,
695 **kwargs: dict[str, Any],
696 - ) -> Optional[Qwen2_5_VLImageInputs]:
696 + ) -> Qwen2_5_VLImageInputs | None:
697 pixel_values = kwargs.pop("pixel_values", None)
698 image_embeds = kwargs.pop("image_embeds", None)
699 image_grid_thw = kwargs.pop("image_grid_thw", None)
@@ -743,7 +743,7 @@ class Qwen2_5OmniConditionalGenerationMixin:
743 def _parse_and_validate_video_input(
744 self,
745 **kwargs: dict[str, Any],
746 - ) -> Optional[Qwen2_5_VLVideoInputs]:
746 + ) -> Qwen2_5_VLVideoInputs | None:
747 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
748 video_embeds = kwargs.pop("video_embeds", None)
749 video_grid_thw = kwargs.pop("video_grid_thw", None)
@@ -892,7 +892,7 @@ class Qwen2_5OmniThinkerForConditionalGeneration(
892 }
893
894 @classmethod
895 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
895 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
896 if modality.startswith("image"):
897 return "<|vision_start|><|IMAGE|><|vision_end|>"
898 if modality.startswith("video"):
@@ -991,12 +991,12 @@ class Qwen2_5OmniThinkerForConditionalGeneration(
991 cls,
992 input_tokens: list[int],
993 hf_config: PretrainedConfig,
994 - image_grid_thw: Union[list[list[int]], torch.Tensor],
995 - video_grid_thw: Union[list[list[int]], torch.Tensor],
996 - second_per_grid_ts: Optional[list[float]] = None,
994 + image_grid_thw: list[list[int]] | torch.Tensor,
995 + video_grid_thw: list[list[int]] | torch.Tensor,
996 + second_per_grid_ts: list[float] | None = None,
997 context_len: int = 0,
998 - seq_len: Optional[int] = None,
999 - audio_feature_lengths: Optional[torch.Tensor] = None,
998 + seq_len: int | None = None,
999 + audio_feature_lengths: torch.Tensor | None = None,
1000 use_audio_in_video: bool = False,
1001 ) -> tuple[torch.Tensor, int]:
1002 """Get mrope input positions and delta value (Qwen2.5-Omni version).
@@ -1225,9 +1225,9 @@ class Qwen2_5OmniThinkerForConditionalGeneration(
1225 def get_input_embeddings(
1226 self,
1227 input_ids: torch.Tensor,
1228 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
1228 + multimodal_embeddings: MultiModalEmbeddings | None = None,
1229 *,
1230 - is_multimodal: Optional[torch.Tensor] = None,
1230 + is_multimodal: torch.Tensor | None = None,
1231 handle_oov_mm_token: bool = False,
1232 ) -> torch.Tensor:
1233 # This is to satisfy the type checker for each overload
@@ -1241,7 +1241,7 @@ class Qwen2_5OmniThinkerForConditionalGeneration(
1241 handle_oov_mm_token=handle_oov_mm_token,
1242 )
1243
1244 - def get_multimodal_embeddings_v0(self, **kwargs: object) -> Optional[NestedTensors]:
1244 + def get_multimodal_embeddings_v0(self, **kwargs: object) -> NestedTensors | None:
1245 audio_input = self._parse_and_validate_audio_input(**kwargs)
1246 image_input = self._parse_and_validate_image_input(**kwargs)
1247 video_input = self._parse_and_validate_video_input(**kwargs)
@@ -1266,10 +1266,10 @@ class Qwen2_5OmniThinkerForConditionalGeneration(
1266 self,
1267 input_ids: torch.Tensor,
1268 positions: torch.Tensor,
1269 - intermediate_tensors: Optional[IntermediateTensors] = None,
1270 - inputs_embeds: Optional[torch.Tensor] = None,
1269 + intermediate_tensors: IntermediateTensors | None = None,
1270 + inputs_embeds: torch.Tensor | None = None,
1271 **kwargs: object,
1272 - ) -> Union[torch.Tensor, IntermediateTensors]:
1272 + ) -> torch.Tensor | IntermediateTensors:
1273 if intermediate_tensors is not None:
1274 inputs_embeds = None
1275
@@ -1281,7 +1281,7 @@ class Qwen2_5OmniThinkerForConditionalGeneration(
1281 def compute_logits(
1282 self,
1283 hidden_states: torch.Tensor,
1284 - ) -> Optional[torch.Tensor]:
1284 + ) -> torch.Tensor | None:
1285 return self.language_model.compute_logits(hidden_states)
1286
1287 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/qwen2_5_vl.py
+32 -32
@@ -26,9 +26,9 @@
26 # limitations under the License.
27 """Inference-only Qwen2.5-VL model compatible with HuggingFace weights."""
28
29 -from collections.abc import Iterable, Mapping, Sequence
29 +from collections.abc import Callable, Iterable, Mapping, Sequence
30 from functools import lru_cache, partial
31 -from typing import Annotated, Any, Callable, Literal, Optional, Union
31 +from typing import Annotated, Any, Literal, TypeAlias
32
33 import torch
34 import torch.nn as nn
@@ -161,9 +161,9 @@ class Qwen2_5_VLImageEmbeddingInputs(TensorSchema):
161 ]
162
163
164 -Qwen2_5_VLImageInputs = Union[
165 - Qwen2_5_VLImagePixelInputs, Qwen2_5_VLImageEmbeddingInputs
166 -]
164 +Qwen2_5_VLImageInputs: TypeAlias = (
165 + Qwen2_5_VLImagePixelInputs | Qwen2_5_VLImageEmbeddingInputs
166 +)
167
168
169 class Qwen2_5_VLVideoPixelInputs(TensorSchema):
@@ -197,7 +197,7 @@ class Qwen2_5_VLVideoPixelInputs(TensorSchema):
197 ]
198
199 second_per_grid_ts: Annotated[
200 - Optional[torch.Tensor],
200 + torch.Tensor | None,
201 TensorShape("nv"),
202 ]
203
@@ -231,9 +231,9 @@ class Qwen2_5_VLVideoEmbeddingInputs(TensorSchema):
231 ]
232
233
234 -Qwen2_5_VLVideoInputs = Union[
235 - Qwen2_5_VLVideoPixelInputs, Qwen2_5_VLVideoEmbeddingInputs
236 -]
234 +Qwen2_5_VLVideoInputs: TypeAlias = (
235 + Qwen2_5_VLVideoPixelInputs | Qwen2_5_VLVideoEmbeddingInputs
236 +)
237
238 # === Vision Encoder === #
239
@@ -245,7 +245,7 @@ class Qwen2_5_VisionMLP(nn.Module):
245 hidden_features: int,
246 bias: bool = False,
247 act_fn: Callable[[torch.Tensor], torch.Tensor] = F.silu,
248 - quant_config: Optional[QuantizationConfig] = None,
248 + quant_config: QuantizationConfig | None = None,
249 prefix: str = "",
250 use_data_parallel: bool = False,
251 ):
@@ -301,7 +301,7 @@ class Qwen2_5_VisionAttention(nn.Module):
301 embed_dim: int,
302 num_heads: int,
303 projection_size: int,
304 - quant_config: Optional[QuantizationConfig] = None,
304 + quant_config: QuantizationConfig | None = None,
305 prefix: str = "",
306 use_data_parallel: bool = False,
307 attn_backend: _Backend = _Backend.TORCH_SDPA,
@@ -386,8 +386,8 @@ class Qwen2_5_VisionAttention(nn.Module):
386 x: torch.Tensor,
387 cu_seqlens: torch.Tensor,
388 rotary_pos_emb: torch.Tensor,
389 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
390 - seqlens: Optional[list[int]] = None, # Only used for xFormers
389 + max_seqlen: int | None = None, # Only used for Flash Attention
390 + seqlens: list[int] | None = None, # Only used for xFormers
391 ) -> torch.Tensor:
392 # [s, b, c] --> [s, b, head * 3 * head_dim]
393 x, _ = self.qkv(x)
@@ -466,8 +466,8 @@ class Qwen2_5_VisionBlock(nn.Module):
466 num_heads: int,
467 mlp_hidden_dim: int,
468 act_fn: Callable[[torch.Tensor], torch.Tensor] = F.silu,
469 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
470 - quant_config: Optional[QuantizationConfig] = None,
469 + norm_layer: Callable[[int], nn.Module] | None = None,
470 + quant_config: QuantizationConfig | None = None,
471 prefix: str = "",
472 use_data_parallel: bool = False,
473 attn_backend: _Backend = _Backend.TORCH_SDPA,
@@ -503,8 +503,8 @@ class Qwen2_5_VisionBlock(nn.Module):
503 x: torch.Tensor,
504 cu_seqlens: torch.Tensor,
505 rotary_pos_emb: torch.Tensor,
506 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
507 - seqlens: Optional[list[int]] = None, # Only used for xFormers
506 + max_seqlen: int | None = None, # Only used for Flash Attention
507 + seqlens: list[int] | None = None, # Only used for xFormers
508 ) -> torch.Tensor:
509 x_attn = self.attn(
510 self.norm1(x),
@@ -552,9 +552,9 @@ class Qwen2_5_VisionPatchMerger(nn.Module):
552 self,
553 d_model: int,
554 context_dim: int,
555 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
555 + norm_layer: Callable[[int], nn.Module] | None = None,
556 spatial_merge_size: int = 2,
557 - quant_config: Optional[QuantizationConfig] = None,
557 + quant_config: QuantizationConfig | None = None,
558 prefix: str = "",
559 use_data_parallel: bool = False,
560 ) -> None:
@@ -634,7 +634,7 @@ class Qwen2_5_VisionTransformer(nn.Module):
634 self,
635 vision_config: Qwen2_5_VLVisionConfig,
636 norm_eps: float = 1e-6,
637 - quant_config: Optional[QuantizationConfig] = None,
637 + quant_config: QuantizationConfig | None = None,
638 prefix: str = "",
639 use_data_parallel: bool = False,
640 ) -> None:
@@ -815,7 +815,7 @@ class Qwen2_5_VisionTransformer(nn.Module):
815 def compute_attn_mask_seqlen(
816 self,
817 cu_seqlens: torch.Tensor,
818 - ) -> tuple[Optional[int], Optional[list[int]]]:
818 + ) -> tuple[int | None, list[int] | None]:
819 max_seqlen, seqlens = None, None
820 if (
821 self.attn_backend == _Backend.FLASH_ATTN
@@ -1080,12 +1080,12 @@ class Qwen2_5_VLForConditionalGeneration(
1080 cls,
1081 input_tokens: list[int],
1082 hf_config: PretrainedConfig,
1083 - image_grid_thw: Union[list[list[int]], torch.Tensor],
1084 - video_grid_thw: Union[list[list[int]], torch.Tensor],
1083 + image_grid_thw: list[list[int]] | torch.Tensor,
1084 + video_grid_thw: list[list[int]] | torch.Tensor,
1085 second_per_grid_ts: list[float],
1086 context_len: int = 0,
1087 - seq_len: Optional[int] = None,
1088 - audio_feature_lengths: Optional[torch.Tensor] = None,
1087 + seq_len: int | None = None,
1088 + audio_feature_lengths: torch.Tensor | None = None,
1089 use_audio_in_video: bool = False,
1090 ) -> tuple[torch.Tensor, int]:
1091 """Get mrope input positions and delta value."""
@@ -1202,7 +1202,7 @@ class Qwen2_5_VLForConditionalGeneration(
1202 return llm_positions, mrope_position_delta
1203
1204 @classmethod
1205 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1205 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1206 if modality.startswith("image"):
1207 return "<|vision_start|><|image_pad|><|vision_end|>"
1208 if modality.startswith("video"):
@@ -1273,7 +1273,7 @@ class Qwen2_5_VLForConditionalGeneration(
1273
1274 def _parse_and_validate_image_input(
1275 self, **kwargs: object
1276 - ) -> Optional[Qwen2_5_VLImageInputs]:
1276 + ) -> Qwen2_5_VLImageInputs | None:
1277 pixel_values = kwargs.pop("pixel_values", None)
1278 image_embeds = kwargs.pop("image_embeds", None)
1279 image_grid_thw = kwargs.pop("image_grid_thw", None)
@@ -1311,7 +1311,7 @@ class Qwen2_5_VLForConditionalGeneration(
1311
1312 def _parse_and_validate_video_input(
1313 self, **kwargs: object
1314 - ) -> Optional[Qwen2_5_VLVideoInputs]:
1314 + ) -> Qwen2_5_VLVideoInputs | None:
1315 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
1316 video_embeds = kwargs.pop("video_embeds", None)
1317 video_grid_thw = kwargs.pop("video_grid_thw", None)
@@ -1605,10 +1605,10 @@ class Qwen2_5_VLForConditionalGeneration(
1605 self,
1606 input_ids: torch.Tensor,
1607 positions: torch.Tensor,
1608 - intermediate_tensors: Optional[IntermediateTensors] = None,
1609 - inputs_embeds: Optional[torch.Tensor] = None,
1608 + intermediate_tensors: IntermediateTensors | None = None,
1609 + inputs_embeds: torch.Tensor | None = None,
1610 **kwargs: object,
1611 - ) -> Union[torch.Tensor, IntermediateTensors]:
1611 + ) -> torch.Tensor | IntermediateTensors:
1612 """Run forward pass for Qwen2.5-VL.
1613
1614 Args:
@@ -1634,7 +1634,7 @@ class Qwen2_5_VLForConditionalGeneration(
1634 def compute_logits(
1635 self,
1636 hidden_states: torch.Tensor,
1637 - ) -> Optional[torch.Tensor]:
1637 + ) -> torch.Tensor | None:
1638 return self.language_model.compute_logits(hidden_states)
1639
1640 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/qwen2_audio.py
+14 -14
@@ -24,7 +24,7 @@
24 """Inference-only Qwen2-Audio model compatible with HuggingFace weights."""
25
26 from collections.abc import Iterable, Mapping, Sequence
27 -from typing import Annotated, Any, Literal, Optional, Union
27 +from typing import Annotated, Any, Literal, TypeAlias
28
29 import torch
30 import torch.nn as nn
@@ -78,7 +78,7 @@ class Qwen2AudioFeatureInputs(TensorSchema):
78
79 type: Literal["audio_features"]
80 input_features: Annotated[
81 - Union[torch.Tensor, list[torch.Tensor]],
81 + torch.Tensor | list[torch.Tensor],
82 TensorShape("na", "nmb", 3000),
83 ]
84
@@ -105,7 +105,7 @@ class Qwen2AudioEmbeddingInputs(TensorSchema):
105 ]
106
107
108 -Qwen2AudioInputs = Union[Qwen2AudioFeatureInputs, Qwen2AudioEmbeddingInputs]
108 +Qwen2AudioInputs: TypeAlias = Qwen2AudioFeatureInputs | Qwen2AudioEmbeddingInputs
109
110 # === Audio Encoder === #
111
@@ -140,7 +140,7 @@ class Qwen2AudioProcessingInfo(BaseProcessingInfo):
140 assert isinstance(feature_extractor, WhisperFeatureExtractor)
141 return feature_extractor
142
143 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
143 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
144 return {"audio": None}
145
146
@@ -157,7 +157,7 @@ class Qwen2AudioDummyInputsBuilder(BaseDummyInputsBuilder[Qwen2AudioProcessingIn
157 self,
158 seq_len: int,
159 mm_counts: Mapping[str, int],
160 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
160 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
161 ) -> MultiModalDataDict:
162 feature_extractor = self.info.get_feature_extractor()
163
@@ -185,8 +185,8 @@ def _qwen2audio_field_config(hf_inputs: Mapping[str, torch.Tensor]):
185 class Qwen2AudioMultiModalDataParser(MultiModalDataParser):
186 def _parse_audio_data(
187 self,
188 - data: Union[dict[str, torch.Tensor], ModalityData[AudioItem]],
189 - ) -> Optional[ModalityDataItems[Any, Any]]:
188 + data: dict[str, torch.Tensor] | ModalityData[AudioItem],
189 + ) -> ModalityDataItems[Any, Any] | None:
190 if isinstance(data, dict):
191 return DictEmbeddingItems(
192 data,
@@ -314,7 +314,7 @@ class Qwen2AudioMultiModalProcessor(BaseMultiModalProcessor[Qwen2AudioProcessing
314 )
315 class Qwen2AudioForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP):
316 @classmethod
317 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
317 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
318 if modality.startswith("audio"):
319 return f"Audio {i}: <|audio_bos|><|AUDIO|><|audio_eos|>"
320
@@ -358,7 +358,7 @@ class Qwen2AudioForConditionalGeneration(nn.Module, SupportsMultiModal, Supports
358
359 def _parse_and_validate_audio_input(
360 self, **kwargs: object
361 - ) -> Optional[Qwen2AudioInputs]:
361 + ) -> Qwen2AudioInputs | None:
362 input_features = kwargs.pop("input_features", None)
363 audio_embeds = kwargs.pop("audio_embeds", None)
364 feature_attention_mask = kwargs.pop("feature_attention_mask", None)
@@ -395,7 +395,7 @@ class Qwen2AudioForConditionalGeneration(nn.Module, SupportsMultiModal, Supports
395
396 def _process_audio_input(
397 self, audio_input: Qwen2AudioInputs
398 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
398 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
399 if audio_input["type"] == "audio_embeds":
400 audio_embeds = audio_input["audio_embeds"]
401 return tuple(audio_embeds)
@@ -471,10 +471,10 @@ class Qwen2AudioForConditionalGeneration(nn.Module, SupportsMultiModal, Supports
471 self,
472 input_ids: torch.Tensor,
473 positions: torch.Tensor,
474 - intermediate_tensors: Optional[IntermediateTensors] = None,
475 - inputs_embeds: Optional[torch.Tensor] = None,
474 + intermediate_tensors: IntermediateTensors | None = None,
475 + inputs_embeds: torch.Tensor | None = None,
476 **kwargs: object,
477 - ) -> Union[torch.Tensor, IntermediateTensors]:
477 + ) -> torch.Tensor | IntermediateTensors:
478 if intermediate_tensors is not None:
479 inputs_embeds = None
480
@@ -486,7 +486,7 @@ class Qwen2AudioForConditionalGeneration(nn.Module, SupportsMultiModal, Supports
486 def compute_logits(
487 self,
488 hidden_states: torch.Tensor,
489 - ) -> Optional[torch.Tensor]:
489 + ) -> torch.Tensor | None:
490 return self.language_model.compute_logits(hidden_states)
491
492 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/qwen2_moe.py
+19 -24
@@ -27,7 +27,7 @@
27
28 from collections.abc import Iterable
29 from itertools import islice
30 -from typing import Any, Optional, Union
30 +from typing import Any
31
32 import torch
33 import torch.nn.functional as F
@@ -77,9 +77,9 @@ class Qwen2MoeMLP(nn.Module):
77 hidden_size: int,
78 intermediate_size: int,
79 hidden_act: str,
80 - quant_config: Optional[QuantizationConfig] = None,
80 + quant_config: QuantizationConfig | None = None,
81 reduce_results: bool = True,
82 - expert_gate: Optional[torch.nn.Linear] = None,
82 + expert_gate: torch.nn.Linear | None = None,
83 prefix: str = "",
84 ) -> None:
85 super().__init__()
@@ -120,7 +120,7 @@ class Qwen2MoeSparseMoeBlock(nn.Module):
120 def __init__(
121 self,
122 config: Qwen2MoeConfig,
123 - quant_config: Optional[QuantizationConfig] = None,
123 + quant_config: QuantizationConfig | None = None,
124 prefix: str = "",
125 ):
126 super().__init__()
@@ -195,12 +195,12 @@ class Qwen2MoeAttention(nn.Module):
195 num_heads: int,
196 num_kv_heads: int,
197 rope_theta: float = 10000,
198 - rope_scaling: Optional[dict[str, Any]] = None,
198 + rope_scaling: dict[str, Any] | None = None,
199 max_position_embeddings: int = 8192,
200 - cache_config: Optional[CacheConfig] = None,
201 - quant_config: Optional[QuantizationConfig] = None,
200 + cache_config: CacheConfig | None = None,
201 + quant_config: QuantizationConfig | None = None,
202 prefix: str = "",
203 - dual_chunk_attention_config: Optional[dict[str, Any]] = None,
203 + dual_chunk_attention_config: dict[str, Any] | None = None,
204 ) -> None:
205 super().__init__()
206 self.hidden_size = hidden_size
@@ -285,8 +285,8 @@ class Qwen2MoeDecoderLayer(nn.Module):
285 def __init__(
286 self,
287 config: Qwen2MoeConfig,
288 - cache_config: Optional[CacheConfig] = None,
289 - quant_config: Optional[QuantizationConfig] = None,
288 + cache_config: CacheConfig | None = None,
289 + quant_config: QuantizationConfig | None = None,
290 prefix: str = "",
291 ) -> None:
292 super().__init__()
@@ -339,7 +339,7 @@ class Qwen2MoeDecoderLayer(nn.Module):
339 self,
340 positions: torch.Tensor,
341 hidden_states: torch.Tensor,
342 - residual: Optional[torch.Tensor],
342 + residual: torch.Tensor | None,
343 ) -> torch.Tensor:
344 # Self Attention
345 if residual is None:
@@ -396,9 +396,9 @@ class Qwen2MoeModel(nn.Module):
396 self,
397 input_ids: torch.Tensor,
398 positions: torch.Tensor,
399 - intermediate_tensors: Optional[IntermediateTensors] = None,
400 - inputs_embeds: Optional[torch.Tensor] = None,
401 - ) -> Union[torch.Tensor, IntermediateTensors]:
399 + intermediate_tensors: IntermediateTensors | None = None,
400 + inputs_embeds: torch.Tensor | None = None,
401 + ) -> torch.Tensor | IntermediateTensors:
402 if get_pp_group().is_first_rank:
403 if inputs_embeds is not None:
404 hidden_states = inputs_embeds
@@ -548,12 +548,7 @@ class Qwen2MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
548 getattr(config, "mlp_only_layers", [])
549 or config.shared_expert_intermediate_size > 0
550 ):
551 - self.packed_modules_mapping["gate_up_proj"] = (
552 - [
553 - "gate_proj",
554 - "up_proj",
555 - ],
556 - )
551 + self.packed_modules_mapping["gate_up_proj"] = ["gate_proj", "up_proj"]
552
553 self.model = Qwen2MoeModel(
554 vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
@@ -578,9 +573,9 @@ class Qwen2MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
573 self,
574 input_ids: torch.Tensor,
575 positions: torch.Tensor,
581 - intermediate_tensors: Optional[IntermediateTensors] = None,
582 - inputs_embeds: Optional[torch.Tensor] = None,
583 - ) -> Union[torch.Tensor, IntermediateTensors]:
576 + intermediate_tensors: IntermediateTensors | None = None,
577 + inputs_embeds: torch.Tensor | None = None,
578 + ) -> torch.Tensor | IntermediateTensors:
579 hidden_states = self.model(
580 input_ids, positions, intermediate_tensors, inputs_embeds
581 )
@@ -589,7 +584,7 @@ class Qwen2MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA):
584 def compute_logits(
585 self,
586 hidden_states: torch.Tensor,
592 - ) -> Optional[torch.Tensor]:
587 + ) -> torch.Tensor | None:
588 logits = self.logits_processor(self.lm_head, hidden_states)
589 return logits
590
vllm/model_executor/models/qwen2_rm.py
+3 -4
@@ -8,7 +8,6 @@
8 """Inference-only Qwen2-RM model compatible with HuggingFace weights."""
9
10 from collections.abc import Iterable
11 -from typing import Optional, Union
11
12 import torch
13 from torch import nn
@@ -83,9 +82,9 @@ class Qwen2RewardBaseModel(nn.Module, SupportsLoRA, SupportsPP):
82 self,
83 input_ids: torch.Tensor,
84 positions: torch.Tensor,
86 - intermediate_tensors: Optional[IntermediateTensors] = None,
87 - inputs_embeds: Optional[torch.Tensor] = None,
88 - ) -> Union[torch.Tensor, IntermediateTensors]:
85 + intermediate_tensors: IntermediateTensors | None = None,
86 + inputs_embeds: torch.Tensor | None = None,
87 + ) -> torch.Tensor | IntermediateTensors:
88 hidden_states = self.model(
89 input_ids, positions, intermediate_tensors, inputs_embeds
90 )
vllm/model_executor/models/qwen2_vl.py
+38 -38
@@ -25,9 +25,9 @@
25 # limitations under the License.
26 """Inference-only Qwen2-VL model compatible with HuggingFace weights."""
27
28 -from collections.abc import Iterable, Mapping, Sequence
28 +from collections.abc import Callable, Iterable, Mapping, Sequence
29 from functools import partial
30 -from typing import Annotated, Any, Callable, Literal, Optional, Union
30 +from typing import Annotated, Any, Literal, TypeAlias
31
32 import torch
33 import torch.nn as nn
@@ -167,7 +167,7 @@ class Qwen2VLImageEmbeddingInputs(TensorSchema):
167 ]
168
169
170 -Qwen2VLImageInputs = Union[Qwen2VLImagePixelInputs, Qwen2VLImageEmbeddingInputs]
170 +Qwen2VLImageInputs: TypeAlias = Qwen2VLImagePixelInputs | Qwen2VLImageEmbeddingInputs
171
172
173 class Qwen2VLVideoPixelInputs(TensorSchema):
@@ -228,7 +228,7 @@ class Qwen2VLVideoEmbeddingInputs(TensorSchema):
228 ]
229
230
231 -Qwen2VLVideoInputs = Union[Qwen2VLVideoPixelInputs, Qwen2VLVideoEmbeddingInputs]
231 +Qwen2VLVideoInputs: TypeAlias = Qwen2VLVideoPixelInputs | Qwen2VLVideoEmbeddingInputs
232
233 # === Vision Encoder === #
234
@@ -239,7 +239,7 @@ class Qwen2VisionMLP(nn.Module):
239 in_features: int,
240 hidden_features: int,
241 act_layer: type[nn.Module] = QuickGELU,
242 - quant_config: Optional[QuantizationConfig] = None,
242 + quant_config: QuantizationConfig | None = None,
243 prefix: str = "",
244 use_data_parallel: bool = False,
245 ):
@@ -317,7 +317,7 @@ class Qwen2VisionAttention(nn.Module):
317 embed_dim: int,
318 num_heads: int,
319 projection_size: int,
320 - quant_config: Optional[QuantizationConfig] = None,
320 + quant_config: QuantizationConfig | None = None,
321 prefix: str = "",
322 use_data_parallel: bool = False,
323 ) -> None:
@@ -413,8 +413,8 @@ class Qwen2VisionAttention(nn.Module):
413 x: torch.Tensor,
414 cu_seqlens: torch.Tensor,
415 rotary_pos_emb: torch.Tensor,
416 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
417 - seqlens: Optional[list[int]] = None, # Only used for xFormers
416 + max_seqlen: int | None = None, # Only used for Flash Attention
417 + seqlens: list[int] | None = None, # Only used for xFormers
418 ) -> torch.Tensor:
419 # [s, b, c] --> [s, b, 3 * head * head_dim]
420 x, _ = self.qkv(x)
@@ -493,8 +493,8 @@ class Qwen2VisionBlock(nn.Module):
493 num_heads: int,
494 mlp_ratio: float,
495 act_layer: type[nn.Module] = QuickGELU,
496 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
497 - quant_config: Optional[QuantizationConfig] = None,
496 + norm_layer: Callable[[int], nn.Module] | None = None,
497 + quant_config: QuantizationConfig | None = None,
498 prefix: str = "",
499 use_data_parallel: bool = False,
500 ) -> None:
@@ -527,8 +527,8 @@ class Qwen2VisionBlock(nn.Module):
527 x: torch.Tensor,
528 cu_seqlens: torch.Tensor,
529 rotary_pos_emb: torch.Tensor,
530 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
531 - seqlens: Optional[list[int]] = None, # Only used for xFormers
530 + max_seqlen: int | None = None, # Only used for Flash Attention
531 + seqlens: list[int] | None = None, # Only used for xFormers
532 ) -> torch.Tensor:
533 x = x + self.attn(
534 self.norm1(x),
@@ -576,9 +576,9 @@ class Qwen2VisionPatchMerger(nn.Module):
576 self,
577 d_model: int,
578 context_dim: int,
579 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
579 + norm_layer: Callable[[int], nn.Module] | None = None,
580 spatial_merge_size: int = 2,
581 - quant_config: Optional[QuantizationConfig] = None,
581 + quant_config: QuantizationConfig | None = None,
582 prefix: str = "",
583 use_data_parallel: bool = False,
584 ) -> None:
@@ -659,7 +659,7 @@ class Qwen2VisionTransformer(nn.Module):
659 self,
660 vision_config: Qwen2VLVisionConfig,
661 norm_eps: float = 1e-6,
662 - quant_config: Optional[QuantizationConfig] = None,
662 + quant_config: QuantizationConfig | None = None,
663 prefix: str = "",
664 use_data_parallel: bool = False,
665 ) -> None:
@@ -766,7 +766,7 @@ class Qwen2VisionTransformer(nn.Module):
766
767 def compute_attn_mask_seqlen(
768 self, cu_seqlens: torch.Tensor
769 - ) -> tuple[Optional[int], Optional[list[int]]]:
769 + ) -> tuple[int | None, list[int] | None]:
770 max_seqlen, seqlens = None, None
771 if (
772 self.attn_backend == _Backend.FLASH_ATTN
@@ -889,8 +889,8 @@ class Qwen2VLMultiModalDataParser(MultiModalDataParser):
889
890 def _parse_image_data(
891 self,
892 - data: Union[dict[str, torch.Tensor], ModalityData[ImageItem]],
893 - ) -> Optional[ModalityDataItems[Any, Any]]:
892 + data: dict[str, torch.Tensor] | ModalityData[ImageItem],
893 + ) -> ModalityDataItems[Any, Any] | None:
894 if isinstance(data, dict):
895 return DictEmbeddingItems(
896 data,
@@ -903,8 +903,8 @@ class Qwen2VLMultiModalDataParser(MultiModalDataParser):
903
904 def _parse_video_data(
905 self,
906 - data: Union[dict[str, torch.Tensor], ModalityData[VideoItem]],
907 - ) -> Optional[ModalityDataItems[Any, Any]]:
906 + data: dict[str, torch.Tensor] | ModalityData[VideoItem],
907 + ) -> ModalityDataItems[Any, Any] | None:
908 if isinstance(data, dict):
909 return DictEmbeddingItems(
910 data,
@@ -930,7 +930,7 @@ class Qwen2VLProcessingInfo(BaseProcessingInfo):
930 def get_image_processor(self, **kwargs: object) -> Qwen2VLImageProcessor:
931 return self.get_hf_processor(**kwargs).image_processor
932
933 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
933 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
934 return {"image": None, "video": None}
935
936 def get_mm_max_tokens_per_item(
@@ -949,7 +949,7 @@ class Qwen2VLProcessingInfo(BaseProcessingInfo):
949 image_height: int,
950 num_frames: int = 1,
951 do_resize: bool = True,
952 - image_processor: Optional[Qwen2VLImageProcessor],
952 + image_processor: Qwen2VLImageProcessor | None,
953 ) -> tuple[ImageSize, int]:
954 if image_processor is None:
955 image_processor = self.get_image_processor()
@@ -990,7 +990,7 @@ class Qwen2VLProcessingInfo(BaseProcessingInfo):
990 *,
991 image_width: int,
992 image_height: int,
993 - image_processor: Optional[Qwen2VLImageProcessor],
993 + image_processor: Qwen2VLImageProcessor | None,
994 ) -> int:
995 _, num_image_tokens = self._get_vision_info(
996 image_width=image_width,
@@ -1006,7 +1006,7 @@ class Qwen2VLProcessingInfo(BaseProcessingInfo):
1006 image_width: int,
1007 image_height: int,
1008 num_frames: int,
1009 - image_processor: Optional[Qwen2VLImageProcessor],
1009 + image_processor: Qwen2VLImageProcessor | None,
1010 ) -> int:
1011 _, num_video_tokens = self._get_vision_info(
1012 image_width=image_width,
@@ -1100,7 +1100,7 @@ class Qwen2VLDummyInputsBuilder(BaseDummyInputsBuilder[Qwen2VLProcessingInfo]):
1100 self,
1101 seq_len: int,
1102 mm_counts: Mapping[str, int],
1103 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
1103 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
1104 ) -> MultiModalDataDict:
1105 num_images = mm_counts.get("image", 0)
1106 num_videos = mm_counts.get("video", 0)
@@ -1207,12 +1207,12 @@ class Qwen2VLForConditionalGeneration(
1207 self,
1208 input_tokens: list[int],
1209 hf_config: PretrainedConfig,
1210 - image_grid_thw: Optional[Union[list[list[int]], torch.Tensor]],
1211 - video_grid_thw: Optional[Union[list[list[int]], torch.Tensor]],
1212 - second_per_grid_ts: Optional[list[float]] = None,
1210 + image_grid_thw: list[list[int]] | torch.Tensor | None,
1211 + video_grid_thw: list[list[int]] | torch.Tensor | None,
1212 + second_per_grid_ts: list[float] | None = None,
1213 context_len: int = 0,
1214 - seq_len: Optional[int] = None,
1215 - audio_feature_lengths: Optional[torch.Tensor] = None,
1214 + seq_len: int | None = None,
1215 + audio_feature_lengths: torch.Tensor | None = None,
1216 use_audio_in_video: bool = False,
1217 ) -> tuple[torch.Tensor, int]:
1218 """Get M-RoPE input positions for Qwen2-VL model."""
@@ -1335,7 +1335,7 @@ class Qwen2VLForConditionalGeneration(
1335 return llm_positions, mrope_position_delta
1336
1337 @classmethod
1338 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1338 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1339 if modality.startswith("image"):
1340 return "<|vision_start|><|image_pad|><|vision_end|>"
1341 if modality.startswith("video"):
@@ -1396,7 +1396,7 @@ class Qwen2VLForConditionalGeneration(
1396
1397 def _parse_and_validate_image_input(
1398 self, **kwargs: object
1399 - ) -> Optional[Qwen2VLImageInputs]:
1399 + ) -> Qwen2VLImageInputs | None:
1400 pixel_values = kwargs.pop("pixel_values", None)
1401 image_embeds = kwargs.pop("image_embeds", None)
1402 image_grid_thw = kwargs.pop("image_grid_thw", None)
@@ -1434,7 +1434,7 @@ class Qwen2VLForConditionalGeneration(
1434
1435 def _parse_and_validate_video_input(
1436 self, **kwargs: object
1437 - ) -> Optional[Qwen2VLVideoInputs]:
1437 + ) -> Qwen2VLVideoInputs | None:
1438 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
1439 video_embeds = kwargs.pop("video_embeds", None)
1440 video_grid_thw = kwargs.pop("video_grid_thw", None)
@@ -1574,10 +1574,10 @@ class Qwen2VLForConditionalGeneration(
1574 self,
1575 input_ids: torch.Tensor,
1576 positions: torch.Tensor,
1577 - intermediate_tensors: Optional[IntermediateTensors] = None,
1578 - inputs_embeds: Optional[torch.Tensor] = None,
1577 + intermediate_tensors: IntermediateTensors | None = None,
1578 + inputs_embeds: torch.Tensor | None = None,
1579 **kwargs: object,
1580 - ) -> Union[torch.Tensor, IntermediateTensors]:
1580 + ) -> torch.Tensor | IntermediateTensors:
1581 """Run forward pass for Qwen2-VL.
1582
1583 Args:
@@ -1606,7 +1606,7 @@ class Qwen2VLForConditionalGeneration(
1606 def compute_logits(
1607 self,
1608 hidden_states: torch.Tensor,
1609 - ) -> Optional[torch.Tensor]:
1609 + ) -> torch.Tensor | None:
1610 return self.language_model.compute_logits(hidden_states)
1611
1612 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
@@ -1634,7 +1634,7 @@ class Tarsier2MultiModalProcessor(Qwen2VLMultiModalProcessor):
1634 class Tarsier2ImageProcessor(Qwen2VLImageProcessor):
1635 def __init__(
1636 self,
1637 - size: Optional[dict[str, int]] = None,
1637 + size: dict[str, int] | None = None,
1638 **kwargs,
1639 ) -> None:
1640 if size is not None and "min_pixels" in size and "max_pixels" in size:
vllm/model_executor/models/qwen3.py
+13 -13
@@ -24,7 +24,7 @@
24 """Inference-only Qwen3 model compatible with HuggingFace weights."""
25
26 from collections.abc import Iterable
27 -from typing import Any, Optional, Union
27 +from typing import Any
28
29 import torch
30 from torch import nn
@@ -58,16 +58,16 @@ class Qwen3Attention(nn.Module):
58 num_heads: int,
59 num_kv_heads: int,
60 max_position: int = 4096 * 32,
61 - head_dim: Optional[int] = None,
61 + head_dim: int | None = None,
62 rms_norm_eps: float = 1e-06,
63 qkv_bias: bool = False,
64 rope_theta: float = 10000,
65 - cache_config: Optional[CacheConfig] = None,
66 - quant_config: Optional[QuantizationConfig] = None,
67 - rope_scaling: Optional[tuple] = None,
65 + cache_config: CacheConfig | None = None,
66 + quant_config: QuantizationConfig | None = None,
67 + rope_scaling: tuple | None = None,
68 prefix: str = "",
69 attn_type: str = AttentionType.DECODER,
70 - dual_chunk_attention_config: Optional[dict[str, Any]] = None,
70 + dual_chunk_attention_config: dict[str, Any] | None = None,
71 ) -> None:
72 super().__init__()
73 self.hidden_size = hidden_size
@@ -160,8 +160,8 @@ class Qwen3DecoderLayer(nn.Module):
160 def __init__(
161 self,
162 config: Qwen3Config,
163 - cache_config: Optional[CacheConfig] = None,
164 - quant_config: Optional[QuantizationConfig] = None,
163 + cache_config: CacheConfig | None = None,
164 + quant_config: QuantizationConfig | None = None,
165 prefix: str = "",
166 ) -> None:
167 super().__init__()
@@ -214,7 +214,7 @@ class Qwen3DecoderLayer(nn.Module):
214 self,
215 positions: torch.Tensor,
216 hidden_states: torch.Tensor,
217 - residual: Optional[torch.Tensor],
217 + residual: torch.Tensor | None,
218 ) -> tuple[torch.Tensor, torch.Tensor]:
219 # Self Attention
220 if residual is None:
@@ -315,9 +315,9 @@ class Qwen3ForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3):
315 self,
316 input_ids: torch.Tensor,
317 positions: torch.Tensor,
318 - intermediate_tensors: Optional[IntermediateTensors] = None,
319 - inputs_embeds: Optional[torch.Tensor] = None,
320 - ) -> Union[torch.Tensor, IntermediateTensors]:
318 + intermediate_tensors: IntermediateTensors | None = None,
319 + inputs_embeds: torch.Tensor | None = None,
320 + ) -> torch.Tensor | IntermediateTensors:
321 hidden_states = self.model(
322 input_ids, positions, intermediate_tensors, inputs_embeds
323 )
@@ -326,7 +326,7 @@ class Qwen3ForCausalLM(nn.Module, SupportsLoRA, SupportsPP, SupportsEagle3):
326 def compute_logits(
327 self,
328 hidden_states: torch.Tensor,
329 - ) -> Optional[torch.Tensor]:
329 + ) -> torch.Tensor | None:
330 logits = self.logits_processor(self.lm_head, hidden_states)
331 return logits
332
vllm/model_executor/models/qwen3_moe.py
+16 -23
@@ -26,7 +26,7 @@
26 import typing
27 from collections.abc import Callable, Iterable
28 from itertools import islice
29 -from typing import Any, Optional, Union
29 +from typing import Any
30
31 import torch
32 from torch import nn
@@ -84,7 +84,7 @@ class Qwen3MoeMLP(nn.Module):
84 hidden_size: int,
85 intermediate_size: int,
86 hidden_act: str,
87 - quant_config: Optional[QuantizationConfig] = None,
87 + quant_config: QuantizationConfig | None = None,
88 reduce_results: bool = True,
89 prefix: str = "",
90 ) -> None:
@@ -215,15 +215,15 @@ class Qwen3MoeAttention(nn.Module):
215 num_heads: int,
216 num_kv_heads: int,
217 rope_theta: float = 10000,
218 - rope_scaling: Optional[dict[str, Any]] = None,
218 + rope_scaling: dict[str, Any] | None = None,
219 max_position_embeddings: int = 8192,
220 - head_dim: Optional[int] = None,
220 + head_dim: int | None = None,
221 rms_norm_eps: float = 1e-06,
222 qkv_bias: bool = False,
223 - cache_config: Optional[CacheConfig] = None,
224 - quant_config: Optional[QuantizationConfig] = None,
223 + cache_config: CacheConfig | None = None,
224 + quant_config: QuantizationConfig | None = None,
225 prefix: str = "",
226 - dual_chunk_attention_config: Optional[dict[str, Any]] = None,
226 + dual_chunk_attention_config: dict[str, Any] | None = None,
227 ) -> None:
228 super().__init__()
229 self.hidden_size = hidden_size
@@ -374,7 +374,7 @@ class Qwen3MoeDecoderLayer(nn.Module):
374 self,
375 positions: torch.Tensor,
376 hidden_states: torch.Tensor,
377 - residual: Optional[torch.Tensor],
377 + residual: torch.Tensor | None,
378 ) -> tuple[torch.Tensor, torch.Tensor]:
379 # Self Attention
380 if residual is None:
@@ -432,11 +432,9 @@ class Qwen3MoeModel(nn.Module):
432 self,
433 input_ids: torch.Tensor,
434 positions: torch.Tensor,
435 - intermediate_tensors: Optional[IntermediateTensors] = None,
436 - inputs_embeds: Optional[torch.Tensor] = None,
437 - ) -> Union[
438 - torch.Tensor, IntermediateTensors, tuple[torch.Tensor, list[torch.Tensor]]
439 - ]:
435 + intermediate_tensors: IntermediateTensors | None = None,
436 + inputs_embeds: torch.Tensor | None = None,
437 + ) -> torch.Tensor | IntermediateTensors | tuple[torch.Tensor, list[torch.Tensor]]:
438 if get_pp_group().is_first_rank:
439 if inputs_embeds is not None:
440 hidden_states = inputs_embeds
@@ -647,12 +645,7 @@ class Qwen3MoeForCausalLM(
645 self.quant_config = quant_config
646 # Only perform the following mapping when Qwen3MoeMLP exists
647 if getattr(config, "mlp_only_layers", []):
650 - self.packed_modules_mapping["gate_up_proj"] = (
651 - [
652 - "gate_proj",
653 - "up_proj",
654 - ],
655 - )
648 + self.packed_modules_mapping["gate_up_proj"] = ["gate_proj", "up_proj"]
649 self.model = Qwen3MoeModel(
650 vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
651 )
@@ -742,9 +735,9 @@ class Qwen3MoeForCausalLM(
735 self,
736 input_ids: torch.Tensor,
737 positions: torch.Tensor,
745 - intermediate_tensors: Optional[IntermediateTensors] = None,
746 - inputs_embeds: Optional[torch.Tensor] = None,
747 - ) -> Union[torch.Tensor, IntermediateTensors]:
738 + intermediate_tensors: IntermediateTensors | None = None,
739 + inputs_embeds: torch.Tensor | None = None,
740 + ) -> torch.Tensor | IntermediateTensors:
741 hidden_states = self.model(
742 input_ids, positions, intermediate_tensors, inputs_embeds
743 )
@@ -753,7 +746,7 @@ class Qwen3MoeForCausalLM(
746 def compute_logits(
747 self,
748 hidden_states: torch.Tensor,
756 - ) -> Optional[torch.Tensor]:
749 + ) -> torch.Tensor | None:
750 logits = self.logits_processor(self.lm_head, hidden_states)
751 return logits
752
vllm/model_executor/models/qwen3_next.py
+13 -14
@@ -4,7 +4,6 @@
4
5 from collections.abc import Iterable
6 from itertools import islice
7 -from typing import Optional
7
8 import torch
9 from einops import rearrange
@@ -233,10 +232,10 @@ class Qwen3NextGatedDeltaNet(nn.Module, MambaBase):
232 def __init__(
233 self,
234 config: Qwen3NextConfig,
236 - model_config: Optional[ModelConfig] = None,
237 - cache_config: Optional[CacheConfig] = None,
238 - quant_config: Optional[QuantizationConfig] = None,
239 - speculative_config: Optional[SpeculativeConfig] = None,
235 + model_config: ModelConfig | None = None,
236 + cache_config: CacheConfig | None = None,
237 + quant_config: QuantizationConfig | None = None,
238 + speculative_config: SpeculativeConfig | None = None,
239 prefix: str = "",
240 ) -> None:
241 super().__init__()
@@ -661,9 +660,9 @@ class Qwen3NextAttention(nn.Module):
660 def __init__(
661 self,
662 config: Qwen3NextConfig,
664 - model_config: Optional[ModelConfig] = None,
665 - cache_config: Optional[CacheConfig] = None,
666 - quant_config: Optional[QuantizationConfig] = None,
663 + model_config: ModelConfig | None = None,
664 + cache_config: CacheConfig | None = None,
665 + quant_config: QuantizationConfig | None = None,
666 prefix: str = "",
667 ) -> None:
668 super().__init__()
@@ -863,7 +862,7 @@ class Qwen3NextDecoderLayer(nn.Module):
862 def forward(
863 self,
864 hidden_states: torch.Tensor,
866 - residual: Optional[torch.Tensor],
865 + residual: torch.Tensor | None,
866 positions: torch.Tensor = None,
867 **kwargs: object,
868 ):
@@ -971,8 +970,8 @@ class Qwen3NextModel(nn.Module):
970 self,
971 input_ids: torch.Tensor,
972 positions: torch.Tensor,
974 - intermediate_tensors: Optional[IntermediateTensors] = None,
975 - inputs_embeds: Optional[torch.Tensor] = None,
973 + intermediate_tensors: IntermediateTensors | None = None,
974 + inputs_embeds: torch.Tensor | None = None,
975 ) -> torch.Tensor:
976 if get_pp_group().is_first_rank:
977 if inputs_embeds is not None:
@@ -1207,8 +1206,8 @@ class Qwen3NextForCausalLM(
1206 self,
1207 input_ids: torch.Tensor,
1208 positions: torch.Tensor,
1210 - intermediate_tensors: Optional[IntermediateTensors] = None,
1211 - inputs_embeds: Optional[torch.Tensor] = None,
1209 + intermediate_tensors: IntermediateTensors | None = None,
1210 + inputs_embeds: torch.Tensor | None = None,
1211 **kwargs: object,
1212 ):
1213 hidden_states = self.model(
@@ -1251,7 +1250,7 @@ class Qwen3NextForCausalLM(
1250 def compute_logits(
1251 self,
1252 hidden_states: torch.Tensor,
1254 - ) -> Optional[torch.Tensor]:
1253 + ) -> torch.Tensor | None:
1254 return self.logits_processor(self.lm_head, hidden_states)
1255
1256 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/qwen3_next_mtp.py
+5 -6
@@ -3,7 +3,6 @@
3 """Inference-only Qwen3Next MTP model."""
4
5 from collections.abc import Iterable
6 -from typing import Optional
6
7 import torch
8 from torch import nn
@@ -108,8 +107,8 @@ class Qwen3NextMultiTokenPredictor(nn.Module):
107 input_ids: torch.Tensor,
108 positions: torch.Tensor,
109 hidden_states: torch.Tensor,
111 - intermediate_tensors: Optional[IntermediateTensors] = None,
112 - inputs_embeds: Optional[torch.Tensor] = None,
110 + intermediate_tensors: IntermediateTensors | None = None,
111 + inputs_embeds: torch.Tensor | None = None,
112 spec_step_idx: int = 0,
113 ) -> torch.Tensor:
114 if get_pp_group().is_first_rank:
@@ -275,8 +274,8 @@ class Qwen3NextMTP(nn.Module, SupportsPP):
274 input_ids: torch.Tensor,
275 positions: torch.Tensor,
276 hidden_states: torch.Tensor,
278 - intermediate_tensors: Optional[IntermediateTensors] = None,
279 - inputs_embeds: Optional[torch.Tensor] = None,
277 + intermediate_tensors: IntermediateTensors | None = None,
278 + inputs_embeds: torch.Tensor | None = None,
279 **kwargs: object,
280 ):
281 hidden_states = self.model(
@@ -288,7 +287,7 @@ class Qwen3NextMTP(nn.Module, SupportsPP):
287 self,
288 hidden_states: torch.Tensor,
289 spec_step_idx: int = 0,
291 - ) -> Optional[torch.Tensor]:
290 + ) -> torch.Tensor | None:
291 return self.logits_processor(self.lm_head, hidden_states)
292
293 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/qwen3_omni_moe_thinker.py
+30 -30
@@ -22,9 +22,9 @@
22 # limitations under the License.
23 """Inference-only Qwen3-Omni-Moe model (thinker part)."""
24
25 -from collections.abc import Iterable, Mapping, Sequence
25 +from collections.abc import Callable, Iterable, Mapping, Sequence
26 from functools import partial
27 -from typing import Any, Callable, Optional, Union
27 +from typing import Any
28
29 import numpy as np
30 import torch
@@ -156,7 +156,7 @@ class Qwen3_VisionMLP(nn.Module):
156 hidden_features: int,
157 bias: bool = False,
158 act_fn: Callable[[torch.Tensor], torch.Tensor] = F.silu,
159 - quant_config: Optional[QuantizationConfig] = None,
159 + quant_config: QuantizationConfig | None = None,
160 prefix: str = "",
161 ):
162 super().__init__()
@@ -190,8 +190,8 @@ class Qwen3_VisionBlock(nn.Module):
190 num_heads: int,
191 mlp_hidden_dim: int,
192 act_fn: Callable[[torch.Tensor], torch.Tensor] = F.silu,
193 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
194 - quant_config: Optional[QuantizationConfig] = None,
193 + norm_layer: Callable[[int], nn.Module] | None = None,
194 + quant_config: QuantizationConfig | None = None,
195 prefix: str = "",
196 ) -> None:
197 super().__init__()
@@ -220,8 +220,8 @@ class Qwen3_VisionBlock(nn.Module):
220 x: torch.Tensor,
221 cu_seqlens: torch.Tensor,
222 rotary_pos_emb: torch.Tensor,
223 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
224 - seqlens: Optional[list[int]] = None, # Only used for xFormers
223 + max_seqlen: int | None = None, # Only used for Flash Attention
224 + seqlens: list[int] | None = None, # Only used for xFormers
225 ) -> torch.Tensor:
226 x = x + self.attn(
227 self.norm1(x),
@@ -240,10 +240,10 @@ class Qwen3_VisionPatchMerger(nn.Module):
240 self,
241 d_model: int,
242 context_dim: int,
243 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
243 + norm_layer: Callable[[int], nn.Module] | None = None,
244 spatial_merge_size: int = 2,
245 use_postshuffle_norm: bool = False,
246 - quant_config: Optional[QuantizationConfig] = None,
246 + quant_config: QuantizationConfig | None = None,
247 prefix: str = "",
248 ) -> None:
249 super().__init__()
@@ -297,7 +297,7 @@ class Qwen3Omni_VisionTransformer(nn.Module):
297 self,
298 vision_config,
299 norm_eps: float = 1e-6,
300 - quant_config: Optional[QuantizationConfig] = None,
300 + quant_config: QuantizationConfig | None = None,
301 prefix: str = "",
302 ) -> None:
303 super().__init__()
@@ -482,7 +482,7 @@ class Qwen3Omni_VisionTransformer(nn.Module):
482 def compute_attn_mask_seqlen(
483 self,
484 cu_seqlens: torch.Tensor,
485 - ) -> tuple[Optional[int], Optional[list[int]]]:
485 + ) -> tuple[int | None, list[int] | None]:
486 max_seqlen, seqlens = None, None
487 if self.attn_backend == _Backend.FLASH_ATTN:
488 max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max().item()
@@ -595,10 +595,10 @@ class Qwen3MoeLLMModel(Qwen3MoeModel):
595 self,
596 input_ids: torch.Tensor,
597 positions: torch.Tensor,
598 - intermediate_tensors: Optional[IntermediateTensors] = None,
599 - inputs_embeds: Optional[torch.Tensor] = None,
600 - deepstack_input_embeds: Optional[IntermediateTensors] = None,
601 - ) -> Union[torch.Tensor, IntermediateTensors]:
598 + intermediate_tensors: IntermediateTensors | None = None,
599 + inputs_embeds: torch.Tensor | None = None,
600 + deepstack_input_embeds: IntermediateTensors | None = None,
601 + ) -> torch.Tensor | IntermediateTensors:
602 if get_pp_group().is_first_rank:
603 if inputs_embeds is not None:
604 hidden_states = inputs_embeds
@@ -683,7 +683,7 @@ class Qwen3OmniMoeThinkerProcessingInfo(
683 assert isinstance(feature_extractor, WhisperFeatureExtractor)
684 return feature_extractor
685
686 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
686 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
687 return {"audio": None, "image": None, "video": None}
688
689
@@ -818,7 +818,7 @@ class Qwen3OmniMoeThinkerMultiModalProcessor(
818 self,
819 thinker_config: PretrainedConfig,
820 audio_len: int,
821 - video_grid_thw: Union[list[int], torch.Tensor],
821 + video_grid_thw: list[int] | torch.Tensor,
822 video_second_per_grid_t: float,
823 ) -> list[int]:
824 shift = 0
@@ -1100,7 +1100,7 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1100 )
1101
1102 @classmethod
1103 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1103 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1104 if modality.startswith("image"):
1105 return "<|vision_start|><|image_pad|><|vision_end|>"
1106 if modality.startswith("video"):
@@ -1246,7 +1246,7 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1246
1247 def get_multimodal_embeddings(
1248 self, **kwargs: object
1249 - ) -> Optional[MultiModalEmbeddings]:
1249 + ) -> MultiModalEmbeddings | None:
1250 mm_input_by_modality = self._parse_and_validate_multimodal_inputs(**kwargs)
1251 if not mm_input_by_modality:
1252 return []
@@ -1273,9 +1273,9 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1273 def get_input_embeddings(
1274 self,
1275 input_ids: torch.Tensor,
1276 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
1276 + multimodal_embeddings: MultiModalEmbeddings | None = None,
1277 *,
1278 - is_multimodal: Optional[torch.Tensor] = None,
1278 + is_multimodal: torch.Tensor | None = None,
1279 handle_oov_mm_token: bool = False,
1280 ) -> torch.Tensor:
1281 inputs_embeds = self._get_text_embeddings(
@@ -1356,10 +1356,10 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1356 self,
1357 input_ids: torch.Tensor,
1358 positions: torch.Tensor,
1359 - intermediate_tensors: Optional[IntermediateTensors] = None,
1360 - inputs_embeds: Optional[torch.Tensor] = None,
1359 + intermediate_tensors: IntermediateTensors | None = None,
1360 + inputs_embeds: torch.Tensor | None = None,
1361 **kwargs: object,
1362 - ) -> Union[torch.Tensor, IntermediateTensors]:
1362 + ) -> torch.Tensor | IntermediateTensors:
1363 if intermediate_tensors is not None:
1364 inputs_embeds = None
1365
@@ -1391,7 +1391,7 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1391 def compute_logits(
1392 self,
1393 hidden_states: torch.Tensor,
1394 - ) -> Optional[torch.Tensor]:
1394 + ) -> torch.Tensor | None:
1395 return self.language_model.compute_logits(hidden_states)
1396
1397 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
@@ -1408,12 +1408,12 @@ class Qwen3OmniMoeThinkerForConditionalGeneration(
1408 self,
1409 input_tokens: list[int],
1410 hf_config: PretrainedConfig,
1411 - image_grid_thw: Optional[Union[list[list[int]], torch.Tensor]],
1412 - video_grid_thw: Optional[Union[list[list[int]], torch.Tensor]],
1413 - second_per_grid_ts: Optional[list[float]] = None,
1411 + image_grid_thw: list[list[int]] | torch.Tensor | None,
1412 + video_grid_thw: list[list[int]] | torch.Tensor | None,
1413 + second_per_grid_ts: list[float] | None = None,
1414 context_len: int = 0,
1415 - seq_len: Optional[int] = None,
1416 - audio_feature_lengths: Optional[torch.Tensor] = None,
1415 + seq_len: int | None = None,
1416 + audio_feature_lengths: torch.Tensor | None = None,
1417 use_audio_in_video: bool = False,
1418 ) -> tuple[torch.Tensor, int]:
1419 config = hf_config.thinker_config
vllm/model_executor/models/qwen3_vl.py
+34 -36
@@ -24,10 +24,10 @@
24 # limitations under the License.
25 """Inference-only Qwen3VL model compatible with HuggingFace weights."""
26
27 -from collections.abc import Iterable, Mapping, Sequence
27 +from collections.abc import Callable, Iterable, Mapping, Sequence
28 from functools import partial
29 from itertools import islice
30 -from typing import Any, Callable, Optional, Union
30 +from typing import Any
31
32 import numpy as np
33 import torch
@@ -151,7 +151,7 @@ class Qwen3_VisionMLP(nn.Module):
151 hidden_features: int,
152 bias: bool = False,
153 act_fn: Callable[[torch.Tensor], torch.Tensor] = F.silu,
154 - quant_config: Optional[QuantizationConfig] = None,
154 + quant_config: QuantizationConfig | None = None,
155 prefix: str = "",
156 use_data_parallel: bool = False,
157 ):
@@ -188,8 +188,8 @@ class Qwen3_VisionBlock(nn.Module):
188 num_heads: int,
189 mlp_hidden_dim: int,
190 act_fn: Callable[[torch.Tensor], torch.Tensor] = F.silu,
191 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
192 - quant_config: Optional[QuantizationConfig] = None,
191 + norm_layer: Callable[[int], nn.Module] | None = None,
192 + quant_config: QuantizationConfig | None = None,
193 prefix: str = "",
194 use_data_parallel: bool = False,
195 attn_backend: _Backend = _Backend.TORCH_SDPA,
@@ -225,8 +225,8 @@ class Qwen3_VisionBlock(nn.Module):
225 x: torch.Tensor,
226 cu_seqlens: torch.Tensor,
227 rotary_pos_emb: torch.Tensor,
228 - max_seqlen: Optional[int] = None, # Only used for Flash Attention
229 - seqlens: Optional[list[int]] = None, # Only used for xFormers
228 + max_seqlen: int | None = None, # Only used for Flash Attention
229 + seqlens: list[int] | None = None, # Only used for xFormers
230 ) -> torch.Tensor:
231 x = x + self.attn(
232 self.norm1(x),
@@ -245,10 +245,10 @@ class Qwen3_VisionPatchMerger(nn.Module):
245 self,
246 d_model: int,
247 context_dim: int,
248 - norm_layer: Optional[Callable[[int], nn.Module]] = None,
248 + norm_layer: Callable[[int], nn.Module] | None = None,
249 spatial_merge_size: int = 2,
250 use_postshuffle_norm: bool = False,
251 - quant_config: Optional[QuantizationConfig] = None,
251 + quant_config: QuantizationConfig | None = None,
252 prefix: str = "",
253 use_data_parallel: bool = False,
254 ) -> None:
@@ -297,7 +297,7 @@ class Qwen3_VisionTransformer(nn.Module):
297 self,
298 vision_config: Qwen3VLVisionConfig,
299 norm_eps: float = 1e-6,
300 - quant_config: Optional[QuantizationConfig] = None,
300 + quant_config: QuantizationConfig | None = None,
301 prefix: str = "",
302 use_data_parallel: bool = False,
303 ) -> None:
@@ -511,7 +511,7 @@ class Qwen3_VisionTransformer(nn.Module):
511 def compute_attn_mask_seqlen(
512 self,
513 cu_seqlens: torch.Tensor,
514 - ) -> tuple[Optional[int], Optional[list[int]]]:
514 + ) -> tuple[int | None, list[int] | None]:
515 max_seqlen, seqlens = None, None
516 if (
517 self.attn_backend == _Backend.FLASH_ATTN
@@ -625,9 +625,7 @@ class Qwen3VLProcessingInfo(Qwen2VLProcessingInfo):
625 image_height: int,
626 num_frames: int = 2,
627 do_resize: bool = True,
628 - image_processor: Optional[
629 - Union[Qwen2VLImageProcessorFast, Qwen3VLVideoProcessor]
630 - ],
628 + image_processor: Qwen2VLImageProcessorFast | Qwen3VLVideoProcessor | None,
629 ) -> tuple[ImageSize, int]:
630 if image_processor is None and num_frames > 1:
631 image_processor = self.get_video_processor()
@@ -726,8 +724,8 @@ class Qwen3VLProcessingInfo(Qwen2VLProcessingInfo):
724 self,
725 metadata: dict[str, Any],
726 out_item: MultiModalKwargsItem,
729 - do_sample_frames: Optional[bool] = None,
730 - sampled_fps: Optional[float] = None,
727 + do_sample_frames: bool | None = None,
728 + sampled_fps: float | None = None,
729 ) -> list[int]:
730 video_processor = self.get_video_processor()
731 merge_size = video_processor.merge_size
@@ -778,7 +776,7 @@ class Qwen3VLDummyInputsBuilder(BaseDummyInputsBuilder[Qwen3VLProcessingInfo]):
776 self,
777 seq_len: int,
778 mm_counts: Mapping[str, int],
781 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
779 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
780 ) -> MultiModalDataDict:
781 num_images = mm_counts.get("image", 0)
782 num_videos = mm_counts.get("video", 0)
@@ -1096,11 +1094,11 @@ class Qwen3LLMModel(Qwen3Model):
1094 self,
1095 input_ids: torch.Tensor,
1096 positions: torch.Tensor,
1099 - intermediate_tensors: Optional[IntermediateTensors] = None,
1100 - inputs_embeds: Optional[torch.Tensor] = None,
1097 + intermediate_tensors: IntermediateTensors | None = None,
1098 + inputs_embeds: torch.Tensor | None = None,
1099 # args for deepstack
1102 - deepstack_input_embeds: Optional[IntermediateTensors] = None,
1103 - ) -> Union[torch.Tensor, IntermediateTensors]:
1100 + deepstack_input_embeds: IntermediateTensors | None = None,
1101 + ) -> torch.Tensor | IntermediateTensors:
1102 if get_pp_group().is_first_rank:
1103 if inputs_embeds is not None:
1104 hidden_states = inputs_embeds
@@ -1201,7 +1199,7 @@ class Qwen3VLForConditionalGeneration(
1199 )
1200
1201 @classmethod
1204 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
1202 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
1203 if modality.startswith("image"):
1204 return "<|vision_start|><|image_pad|><|vision_end|>"
1205 if modality.startswith("video"):
@@ -1314,7 +1312,7 @@ class Qwen3VLForConditionalGeneration(
1312
1313 def _parse_and_validate_image_input(
1314 self, **kwargs: object
1317 - ) -> Optional[Qwen2_5_VLImageInputs]:
1315 + ) -> Qwen2_5_VLImageInputs | None:
1316 pixel_values = kwargs.pop("pixel_values", None)
1317 image_embeds = kwargs.pop("image_embeds", None)
1318 image_grid_thw = kwargs.pop("image_grid_thw", None)
@@ -1363,7 +1361,7 @@ class Qwen3VLForConditionalGeneration(
1361
1362 def _parse_and_validate_video_input(
1363 self, **kwargs: object
1366 - ) -> Optional[Qwen2_5_VLVideoInputs]:
1364 + ) -> Qwen2_5_VLVideoInputs | None:
1365 pixel_values_videos = kwargs.pop("pixel_values_videos", None)
1366 video_embeds = kwargs.pop("video_embeds", None)
1367 video_grid_thw = kwargs.pop("video_grid_thw", None)
@@ -1486,12 +1484,12 @@ class Qwen3VLForConditionalGeneration(
1484 cls,
1485 input_tokens: list[int],
1486 hf_config: PretrainedConfig,
1489 - image_grid_thw: Union[list[list[int]], torch.Tensor],
1490 - video_grid_thw: Union[list[list[int]], torch.Tensor],
1487 + image_grid_thw: list[list[int]] | torch.Tensor,
1488 + video_grid_thw: list[list[int]] | torch.Tensor,
1489 context_len: int = 0,
1492 - seq_len: Optional[int] = None,
1493 - second_per_grid_ts: Optional[list[float]] = None,
1494 - audio_feature_lengths: Optional[torch.Tensor] = None,
1490 + seq_len: int | None = None,
1491 + second_per_grid_ts: list[float] | None = None,
1492 + audio_feature_lengths: torch.Tensor | None = None,
1493 use_audio_in_video: bool = False,
1494 ) -> tuple[torch.Tensor, int]:
1495 """Get mrope input positions and delta value."""
@@ -1596,7 +1594,7 @@ class Qwen3VLForConditionalGeneration(
1594
1595 def get_multimodal_embeddings(
1596 self, **kwargs: object
1599 - ) -> Optional[MultiModalEmbeddings]:
1597 + ) -> MultiModalEmbeddings | None:
1598 mm_input_by_modality = self._parse_and_validate_multimodal_inputs(**kwargs)
1599 if not mm_input_by_modality:
1600 return None
@@ -1661,9 +1659,9 @@ class Qwen3VLForConditionalGeneration(
1659 def get_input_embeddings(
1660 self,
1661 input_ids: torch.Tensor,
1664 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
1662 + multimodal_embeddings: MultiModalEmbeddings | None = None,
1663 *,
1666 - is_multimodal: Optional[torch.Tensor] = None,
1664 + is_multimodal: torch.Tensor | None = None,
1665 handle_oov_mm_token: bool = False,
1666 ) -> torch.Tensor:
1667 inputs_embeds = self._get_text_embeddings(
@@ -1710,10 +1708,10 @@ class Qwen3VLForConditionalGeneration(
1708 self,
1709 input_ids: torch.Tensor,
1710 positions: torch.Tensor,
1713 - intermediate_tensors: Optional[IntermediateTensors] = None,
1714 - inputs_embeds: Optional[torch.Tensor] = None,
1711 + intermediate_tensors: IntermediateTensors | None = None,
1712 + inputs_embeds: torch.Tensor | None = None,
1713 **kwargs: object,
1716 - ) -> Union[torch.Tensor, IntermediateTensors]:
1714 + ) -> torch.Tensor | IntermediateTensors:
1715 """Run forward pass for Qwen3VL.
1716
1717 Args:
@@ -1769,7 +1767,7 @@ class Qwen3VLForConditionalGeneration(
1767 def compute_logits(
1768 self,
1769 hidden_states: torch.Tensor,
1772 - ) -> Optional[torch.Tensor]:
1770 + ) -> torch.Tensor | None:
1771 return self.language_model.compute_logits(hidden_states)
1772
1773 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/qwen3_vl_moe.py
+5 -6
@@ -25,9 +25,8 @@
25 """Inference-only Qwen3-VL-MoE model compatible with HuggingFace weights."""
26
27 import typing
28 -from collections.abc import Iterable
28 +from collections.abc import Callable, Iterable
29 from itertools import islice
30 -from typing import Callable, Optional, Union
30
31 import torch
32 from transformers.models.qwen3_vl_moe.configuration_qwen3_vl_moe import Qwen3VLMoeConfig
@@ -90,10 +89,10 @@ class Qwen3MoeLLMModel(Qwen3MoeModel):
89 self,
90 input_ids: torch.Tensor,
91 positions: torch.Tensor,
93 - intermediate_tensors: Optional[IntermediateTensors] = None,
94 - inputs_embeds: Optional[torch.Tensor] = None,
95 - deepstack_input_embeds: Optional[IntermediateTensors] = None,
96 - ) -> Union[torch.Tensor, IntermediateTensors]:
92 + intermediate_tensors: IntermediateTensors | None = None,
93 + inputs_embeds: torch.Tensor | None = None,
94 + deepstack_input_embeds: IntermediateTensors | None = None,
95 + ) -> torch.Tensor | IntermediateTensors:
96 if get_pp_group().is_first_rank:
97 if inputs_embeds is not None:
98 hidden_states = inputs_embeds
vllm/model_executor/models/qwen_vl.py
+28 -28
@@ -9,9 +9,9 @@
9 import copy
10 import math
11 import unicodedata
12 -from collections.abc import Collection, Mapping, Sequence, Set
12 +from collections.abc import Callable, Collection, Mapping, Sequence, Set
13 from functools import lru_cache, partial
14 -from typing import Annotated, Callable, Literal, Optional, Union
14 +from typing import Annotated, Literal, TypeAlias
15
16 import regex as re
17 import torch
@@ -93,7 +93,7 @@ class QwenImageEmbeddingInputs(TensorSchema):
93 data: Annotated[torch.Tensor, TensorShape("bn", 256, "hs")]
94
95
96 -QwenImageInputs = Union[QwenImagePixelInputs, QwenImageEmbeddingInputs]
96 +QwenImageInputs: TypeAlias = QwenImagePixelInputs | QwenImageEmbeddingInputs
97
98
99 class VisualAttention(nn.Module):
@@ -107,8 +107,8 @@ class VisualAttention(nn.Module):
107 embed_dim: int,
108 num_heads: int,
109 bias: bool = True,
110 - kdim: Optional[int] = None,
111 - vdim: Optional[int] = None,
110 + kdim: int | None = None,
111 + vdim: int | None = None,
112 ):
113 super().__init__()
114 self.embed_dim = embed_dim
@@ -135,7 +135,7 @@ class VisualAttention(nn.Module):
135 def forward(
136 self,
137 x: torch.Tensor,
138 - attn_mask: Optional[torch.Tensor] = None,
138 + attn_mask: torch.Tensor | None = None,
139 ) -> torch.Tensor:
140 # query/key/value: [sq, b, h]
141 sq, b, _ = x.size()
@@ -213,7 +213,7 @@ class QwenVLMLP(nn.Module):
213 self,
214 hidden_size: int,
215 intermediate_size: int,
216 - quant_config: Optional[QuantizationConfig] = None,
216 + quant_config: QuantizationConfig | None = None,
217 ):
218 super().__init__()
219 self.c_fc = ColumnParallelLinear(
@@ -241,7 +241,7 @@ class VisualAttentionBlock(nn.Module):
241 n_head: int,
242 mlp_ratio: float = 4.0,
243 norm_layer: Callable[[int], nn.Module] = nn.LayerNorm,
244 - quant_config: Optional[QuantizationConfig] = None,
244 + quant_config: QuantizationConfig | None = None,
245 ):
246 super().__init__()
247
@@ -258,7 +258,7 @@ class VisualAttentionBlock(nn.Module):
258 def attention(
259 self,
260 x: torch.Tensor,
261 - attn_mask: Optional[torch.Tensor] = None,
261 + attn_mask: torch.Tensor | None = None,
262 ) -> torch.Tensor:
263 attn_mask = attn_mask.to(x.dtype) if attn_mask is not None else None
264 return self.attn(x, attn_mask=attn_mask)
@@ -266,7 +266,7 @@ class VisualAttentionBlock(nn.Module):
266 def forward(
267 self,
268 x: torch.Tensor,
269 - attn_mask: Optional[torch.Tensor] = None,
269 + attn_mask: torch.Tensor | None = None,
270 ) -> torch.Tensor:
271 x = x + self.attention(self.ln_1(x), attn_mask=attn_mask)
272 x = x + self.mlp(self.ln_2(x))
@@ -281,7 +281,7 @@ class TransformerBlock(nn.Module):
281 heads: int,
282 mlp_ratio: float = 4.0,
283 norm_layer: Callable[[int], nn.Module] = nn.LayerNorm,
284 - quant_config: Optional[QuantizationConfig] = None,
284 + quant_config: QuantizationConfig | None = None,
285 ):
286 super().__init__()
287 self.width = width
@@ -307,7 +307,7 @@ class TransformerBlock(nn.Module):
307 return self.resblocks[0].mlp.c_fc.weight.device
308
309 def forward(
310 - self, x: torch.Tensor, attn_mask: Optional[torch.Tensor] = None
310 + self, x: torch.Tensor, attn_mask: torch.Tensor | None = None
311 ) -> torch.Tensor:
312 for r in self.resblocks:
313 x = r(x, attn_mask=attn_mask)
@@ -326,7 +326,7 @@ class VisionTransformer(nn.Module):
326 n_queries: int = 256,
327 output_dim: int = 512,
328 image_start_id: int = 151857,
329 - quant_config: Optional[QuantizationConfig] = None,
329 + quant_config: QuantizationConfig | None = None,
330 **kwargs,
331 ):
332 super().__init__()
@@ -434,10 +434,10 @@ def _get_tokenizer_without_image_pad(
434 def tokenize(
435 self,
436 text: str,
437 - allowed_special: Union[Set[str], str] = "all",
438 - disallowed_special: Union[Collection[str], str] = (),
437 + allowed_special: Set[str] | str = "all",
438 + disallowed_special: Collection[str] | str = (),
439 **kwargs,
440 - ) -> list[Union[bytes, str]]:
440 + ) -> list[bytes | str]:
441 text = unicodedata.normalize("NFC", text)
442
443 return [
@@ -451,9 +451,9 @@ def _get_tokenizer_without_image_pad(
451
452 def _decode(
453 self,
454 - token_ids: Union[int, list[int]],
454 + token_ids: int | list[int],
455 skip_special_tokens: bool = False,
456 - errors: Optional[str] = None,
456 + errors: str | None = None,
457 **kwargs,
458 ) -> str:
459 if isinstance(token_ids, int):
@@ -523,9 +523,9 @@ class QwenVLProcessor:
523
524 def __call__(
525 self,
526 - text: Optional[Union[TextInput, list[TextInput]]] = None,
527 - images: Optional[Union[ImageInput, list[ImageInput]]] = None,
528 - return_tensors: Optional[Union[str, TensorType]] = None,
526 + text: TextInput | list[TextInput] | None = None,
527 + images: ImageInput | list[ImageInput] | None = None,
528 + return_tensors: str | TensorType | None = None,
529 ) -> BatchFeature:
530 if text is None:
531 text = []
@@ -568,7 +568,7 @@ class QwenVLProcessingInfo(BaseProcessingInfo):
568 **kwargs,
569 )
570
571 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
571 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
572 return {"image": None}
573
574 def get_num_image_tokens(self) -> int:
@@ -597,7 +597,7 @@ class QwenVLDummyInputsBuilder(BaseDummyInputsBuilder[QwenVLProcessingInfo]):
597 self,
598 seq_len: int,
599 mm_counts: Mapping[str, int],
600 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
600 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
601 ) -> MultiModalDataDict:
602 hf_config = self.info.get_hf_config()
603 vision_config = hf_config.visual
@@ -722,7 +722,7 @@ class QwenVLForConditionalGeneration(
722 )
723
724 @classmethod
725 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
725 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
726 if modality.startswith("image"):
727 return f"Picture {i}: <img></img>"
728
@@ -745,7 +745,7 @@ class QwenVLForConditionalGeneration(
745
746 def _parse_and_validate_image_input(
747 self, **kwargs: object
748 - ) -> Optional[QwenImageInputs]:
748 + ) -> QwenImageInputs | None:
749 pixel_values = kwargs.pop("pixel_values", None)
750 image_embeds = kwargs.pop("image_embeds", None)
751
@@ -799,10 +799,10 @@ class QwenVLForConditionalGeneration(
799 self,
800 input_ids: torch.Tensor,
801 positions: torch.Tensor,
802 - intermediate_tensors: Optional[IntermediateTensors] = None,
803 - inputs_embeds: Optional[torch.Tensor] = None,
802 + intermediate_tensors: IntermediateTensors | None = None,
803 + inputs_embeds: torch.Tensor | None = None,
804 **kwargs: object,
805 - ) -> Union[torch.Tensor, IntermediateTensors]:
805 + ) -> torch.Tensor | IntermediateTensors:
806 if intermediate_tensors is not None:
807 inputs_embeds = None
808
vllm/model_executor/models/radio.py
+19 -19
@@ -11,7 +11,7 @@
11 import math
12 from collections.abc import Iterable
13 from itertools import repeat
14 -from typing import Optional, Union
14 +from typing import TypeAlias
15
16 import torch
17 import torch.nn as nn
@@ -23,8 +23,8 @@ from vllm.model_executor.layers.quantization import QuantizationConfig
23 from vllm.model_executor.model_loader.weight_utils import default_weight_loader
24 from vllm.model_executor.models.intern_vit import InternVisionEncoder
25
26 -input_dim_t = Union[int, tuple[int, int]]
27 -norm_t = Union[tuple[float, float, float], torch.Tensor]
26 +input_dim_t: TypeAlias = int | tuple[int, int]
27 +norm_t: TypeAlias = tuple[float, float, float] | torch.Tensor
28
29
30 def _ntuple(n):
@@ -75,8 +75,8 @@ class ClsToken(nn.Module):
75 ndim: int,
76 num_tokens: int = 1,
77 enabled: bool = True,
78 - register_multiple: Optional[int] = None,
79 - num_registers: Optional[int] = None,
78 + register_multiple: int | None = None,
79 + num_registers: int | None = None,
80 ):
81 super().__init__()
82
@@ -128,12 +128,12 @@ class ViTPatchGenerator(nn.Module):
128 abs_pos: bool = True,
129 normalize_patches: bool = False,
130 cls_token: bool = False,
131 - max_input_dims: Optional[input_dim_t] = None,
131 + max_input_dims: input_dim_t | None = None,
132 pos_dropout: float = 0.0,
133 return_pos_enc: bool = False,
134 num_cls_tokens: int = 1,
135 - register_multiple: Optional[int] = None,
136 - num_registers: Optional[int] = None,
135 + register_multiple: int | None = None,
136 + num_registers: int | None = None,
137 patch_bias: bool = False,
138 device=None,
139 dtype=None,
@@ -275,8 +275,8 @@ class ViTPatchGenerator(nn.Module):
275 def apply_pos_enc(
276 self,
277 patches: torch.Tensor,
278 - patch_idxs: Optional[torch.Tensor] = None,
279 - input_size: Optional[tuple[int, int]] = None,
278 + patch_idxs: torch.Tensor | None = None,
279 + input_size: tuple[int, int] | None = None,
280 ) -> torch.Tensor:
281 if not self.abs_pos:
282 return patches
@@ -299,8 +299,8 @@ class ViTPatchGenerator(nn.Module):
299 def get_pos_enc(
300 self,
301 batch_size: int,
302 - patch_idxs: Optional[torch.Tensor] = None,
303 - input_size: Optional[tuple[int, int]] = None,
302 + patch_idxs: torch.Tensor | None = None,
303 + input_size: tuple[int, int] | None = None,
304 ) -> torch.Tensor:
305 if input_size is None:
306 input_dims = self.input_dims
@@ -440,9 +440,9 @@ class RadioInternVisionModel(nn.Module):
440 def __init__(
441 self,
442 config: PretrainedConfig = None,
443 - quant_config: Optional[QuantizationConfig] = None,
443 + quant_config: QuantizationConfig | None = None,
444 *,
445 - num_hidden_layers_override: Optional[int] = None,
445 + num_hidden_layers_override: int | None = None,
446 num_dummy_heads: int = 0,
447 prefix: str = "",
448 ) -> None:
@@ -472,7 +472,7 @@ class RadioInternVisionModel(nn.Module):
472 prefix=f"{prefix}.encoder",
473 )
474
475 - def _init_img_size(self, patch_size, img_size: Union[int, tuple[int, int]]):
475 + def _init_img_size(self, patch_size, img_size: int | tuple[int, int]):
476 if img_size is None:
477 return None, None, None
478 img_size = to_2tuple(img_size)
@@ -498,9 +498,9 @@ class RadioModel(nn.Module):
498 def __init__(
499 self,
500 config: PretrainedConfig,
501 - quant_config: Optional[QuantizationConfig] = None,
501 + quant_config: QuantizationConfig | None = None,
502 *,
503 - num_hidden_layers_override: Optional[int] = None,
503 + num_hidden_layers_override: int | None = None,
504 num_dummy_heads: int = 0,
505 prefix: str = "",
506 ) -> None:
@@ -522,8 +522,8 @@ class RadioModel(nn.Module):
522
523 def forward(
524 self,
525 - pixel_values: Optional[torch.Tensor] = None,
526 - pixel_embeds: Optional[torch.Tensor] = None,
525 + pixel_values: torch.Tensor | None = None,
526 + pixel_embeds: torch.Tensor | None = None,
527 ) -> torch.FloatTensor:
528 x = self.input_conditioner(pixel_values)
529 y = self.model(x)
vllm/model_executor/models/registry.py
+23 -23
@@ -14,11 +14,11 @@ import subprocess
14 import sys
15 import tempfile
16 from abc import ABC, abstractmethod
17 -from collections.abc import Set
17 +from collections.abc import Callable, Set
18 from dataclasses import asdict, dataclass, field
19 from functools import lru_cache
20 from pathlib import Path
21 -from typing import Callable, Optional, TypeVar, Union
21 +from typing import TypeVar
22
23 import torch.nn as nn
24 import transformers
@@ -654,7 +654,7 @@ class _LazyRegisteredModel(_BaseRegisteredModel):
654 def _try_load_model_cls(
655 model_arch: str,
656 model: _BaseRegisteredModel,
657 -) -> Optional[type[nn.Module]]:
657 +) -> type[nn.Module] | None:
658 from vllm.platforms import current_platform
659
660 current_platform.verify_model_arch(model_arch)
@@ -669,7 +669,7 @@ def _try_load_model_cls(
669 def _try_inspect_model_cls(
670 model_arch: str,
671 model: _BaseRegisteredModel,
672 -) -> Optional[_ModelInfo]:
672 +) -> _ModelInfo | None:
673 try:
674 return model.inspect_model_cls()
675 except Exception:
@@ -688,7 +688,7 @@ class _ModelRegistry:
688 def register_model(
689 self,
690 model_arch: str,
691 - model_cls: Union[type[nn.Module], str],
691 + model_cls: type[nn.Module] | str,
692 ) -> None:
693 """
694 Register an external model to be used in vLLM.
@@ -756,13 +756,13 @@ class _ModelRegistry:
756 f"Supported architectures: {all_supported_archs}"
757 )
758
759 - def _try_load_model_cls(self, model_arch: str) -> Optional[type[nn.Module]]:
759 + def _try_load_model_cls(self, model_arch: str) -> type[nn.Module] | None:
760 if model_arch not in self.models:
761 return None
762
763 return _try_load_model_cls(model_arch, self.models[model_arch])
764
765 - def _try_inspect_model_cls(self, model_arch: str) -> Optional[_ModelInfo]:
765 + def _try_inspect_model_cls(self, model_arch: str) -> _ModelInfo | None:
766 if model_arch not in self.models:
767 return None
768
@@ -772,7 +772,7 @@ class _ModelRegistry:
772 self,
773 architecture: str,
774 model_config: ModelConfig,
775 - ) -> Optional[str]:
775 + ) -> str | None:
776 if architecture in _TRANSFORMERS_BACKEND_MODELS:
777 return architecture
778
@@ -862,7 +862,7 @@ class _ModelRegistry:
862
863 def inspect_model_cls(
864 self,
865 - architectures: Union[str, list[str]],
865 + architectures: str | list[str],
866 model_config: ModelConfig,
867 ) -> tuple[_ModelInfo, str]:
868 if isinstance(architectures, str):
@@ -914,7 +914,7 @@ class _ModelRegistry:
914
915 def resolve_model_cls(
916 self,
917 - architectures: Union[str, list[str]],
917 + architectures: str | list[str],
918 model_config: ModelConfig,
919 ) -> tuple[type[nn.Module], str]:
920 if isinstance(architectures, str):
@@ -968,7 +968,7 @@ class _ModelRegistry:
968
969 def is_text_generation_model(
970 self,
971 - architectures: Union[str, list[str]],
971 + architectures: str | list[str],
972 model_config: ModelConfig,
973 ) -> bool:
974 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -976,7 +976,7 @@ class _ModelRegistry:
976
977 def is_pooling_model(
978 self,
979 - architectures: Union[str, list[str]],
979 + architectures: str | list[str],
980 model_config: ModelConfig,
981 ) -> bool:
982 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -984,7 +984,7 @@ class _ModelRegistry:
984
985 def is_cross_encoder_model(
986 self,
987 - architectures: Union[str, list[str]],
987 + architectures: str | list[str],
988 model_config: ModelConfig,
989 ) -> bool:
990 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -992,7 +992,7 @@ class _ModelRegistry:
992
993 def is_multimodal_model(
994 self,
995 - architectures: Union[str, list[str]],
995 + architectures: str | list[str],
996 model_config: ModelConfig,
997 ) -> bool:
998 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1000,7 +1000,7 @@ class _ModelRegistry:
1000
1001 def is_multimodal_raw_input_only_model(
1002 self,
1003 - architectures: Union[str, list[str]],
1003 + architectures: str | list[str],
1004 model_config: ModelConfig,
1005 ) -> bool:
1006 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1008,7 +1008,7 @@ class _ModelRegistry:
1008
1009 def is_pp_supported_model(
1010 self,
1011 - architectures: Union[str, list[str]],
1011 + architectures: str | list[str],
1012 model_config: ModelConfig,
1013 ) -> bool:
1014 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1016,7 +1016,7 @@ class _ModelRegistry:
1016
1017 def model_has_inner_state(
1018 self,
1019 - architectures: Union[str, list[str]],
1019 + architectures: str | list[str],
1020 model_config: ModelConfig,
1021 ) -> bool:
1022 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1024,7 +1024,7 @@ class _ModelRegistry:
1024
1025 def is_attention_free_model(
1026 self,
1027 - architectures: Union[str, list[str]],
1027 + architectures: str | list[str],
1028 model_config: ModelConfig,
1029 ) -> bool:
1030 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1032,7 +1032,7 @@ class _ModelRegistry:
1032
1033 def is_hybrid_model(
1034 self,
1035 - architectures: Union[str, list[str]],
1035 + architectures: str | list[str],
1036 model_config: ModelConfig,
1037 ) -> bool:
1038 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1040,7 +1040,7 @@ class _ModelRegistry:
1040
1041 def is_noops_model(
1042 self,
1043 - architectures: Union[str, list[str]],
1043 + architectures: str | list[str],
1044 model_config: ModelConfig,
1045 ) -> bool:
1046 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1048,7 +1048,7 @@ class _ModelRegistry:
1048
1049 def is_transcription_model(
1050 self,
1051 - architectures: Union[str, list[str]],
1051 + architectures: str | list[str],
1052 model_config: ModelConfig,
1053 ) -> bool:
1054 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1056,7 +1056,7 @@ class _ModelRegistry:
1056
1057 def is_transcription_only_model(
1058 self,
1059 - architectures: Union[str, list[str]],
1059 + architectures: str | list[str],
1060 model_config: ModelConfig,
1061 ) -> bool:
1062 model_cls, _ = self.inspect_model_cls(architectures, model_config)
@@ -1064,7 +1064,7 @@ class _ModelRegistry:
1064
1065 def is_v1_compatible(
1066 self,
1067 - architectures: Union[str, list[str]],
1067 + architectures: str | list[str],
1068 model_config: ModelConfig,
1069 ) -> bool:
1070 model_cls, _ = self.inspect_model_cls(architectures, model_config)
vllm/model_executor/models/roberta.py
+8 -9
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable
5 -from typing import Optional, Union
5
6 import torch
7 from torch import nn
@@ -68,7 +67,7 @@ class RobertaEmbedding(nn.Module):
67 self,
68 input_ids: torch.Tensor,
69 position_ids: torch.Tensor,
71 - inputs_embeds: Optional[torch.Tensor] = None,
70 + inputs_embeds: torch.Tensor | None = None,
71 ) -> torch.Tensor:
72 token_type_ids = _decode_token_type_ids(input_ids)
73
@@ -124,8 +123,8 @@ class RobertaEmbeddingModel(BertEmbeddingModel):
123 self,
124 input_ids: torch.Tensor,
125 positions: torch.Tensor,
127 - intermediate_tensors: Optional[IntermediateTensors] = None,
128 - inputs_embeds: Optional[torch.Tensor] = None,
126 + intermediate_tensors: IntermediateTensors | None = None,
127 + inputs_embeds: torch.Tensor | None = None,
128 ) -> torch.Tensor:
129 # Fix Roberta positions here outside of the CUDA graph.
130 # Because we need the to extract the sequences from
@@ -143,7 +142,7 @@ class RobertaEmbeddingModel(BertEmbeddingModel):
142
143 def _build_model(
144 self, vllm_config: VllmConfig, prefix: str = ""
146 - ) -> Union[BertModel, BertWithRope]:
145 + ) -> BertModel | BertWithRope:
146 if vllm_config.model_config.hf_config.position_embedding_type == "rotary":
147 return JinaRobertaModel(vllm_config=vllm_config, prefix=prefix)
148 else:
@@ -240,11 +239,11 @@ class RobertaForSequenceClassification(nn.Module, SupportsCrossEncoding):
239
240 def forward(
241 self,
243 - input_ids: Optional[torch.Tensor],
242 + input_ids: torch.Tensor | None,
243 positions: torch.Tensor,
245 - intermediate_tensors: Optional[IntermediateTensors] = None,
246 - inputs_embeds: Optional[torch.Tensor] = None,
247 - token_type_ids: Optional[torch.Tensor] = None,
244 + intermediate_tensors: IntermediateTensors | None = None,
245 + inputs_embeds: torch.Tensor | None = None,
246 + token_type_ids: torch.Tensor | None = None,
247 ) -> torch.Tensor:
248 replace_roberta_positions(
249 input_ids=input_ids, position_ids=positions, padding_idx=self.padding_idx
vllm/model_executor/models/rvl.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Mapping
5 -from typing import Optional
5
6 import torch
7 import torch.nn as nn
@@ -41,7 +40,7 @@ class RVLDummyInputsBuilder(LlavaDummyInputsBuilder[RVLProcessingInfo]):
40 self,
41 seq_len: int,
42 mm_counts: Mapping[str, int],
44 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
43 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
44 ) -> MultiModalDataDict:
45 num_images = mm_counts.get("image", 0)
46
vllm/model_executor/models/seed_oss.py
+14 -15
@@ -25,7 +25,6 @@
25
26 from collections.abc import Iterable
27 from itertools import islice
28 -from typing import Optional, Union
28
29 import torch
30 from torch import nn
@@ -75,7 +74,7 @@ class SeedOssMLP(nn.Module):
74 hidden_size: int,
75 intermediate_size: int,
76 hidden_act: str,
78 - quant_config: Optional[QuantizationConfig] = None,
77 + quant_config: QuantizationConfig | None = None,
78 prefix: str = "",
79 ) -> None:
80 super().__init__()
@@ -115,9 +114,9 @@ class SeedOssAttention(nn.Module):
114 head_dim: int,
115 max_position: int = 4096 * 32,
116 rope_theta: float = 10000,
118 - cache_config: Optional[CacheConfig] = None,
119 - quant_config: Optional[QuantizationConfig] = None,
120 - rope_scaling: Optional[tuple] = None,
117 + cache_config: CacheConfig | None = None,
118 + quant_config: QuantizationConfig | None = None,
119 + rope_scaling: tuple | None = None,
120 prefix: str = "",
121 attn_type: str = AttentionType.DECODER,
122 ) -> None:
@@ -195,8 +194,8 @@ class SeedOssDecoderLayer(nn.Module):
194 def __init__(
195 self,
196 config: SeedOssConfig,
198 - cache_config: Optional[CacheConfig] = None,
199 - quant_config: Optional[QuantizationConfig] = None,
197 + cache_config: CacheConfig | None = None,
198 + quant_config: QuantizationConfig | None = None,
199 prefix: str = "",
200 ) -> None:
201 super().__init__()
@@ -243,7 +242,7 @@ class SeedOssDecoderLayer(nn.Module):
242 self,
243 positions: torch.Tensor,
244 hidden_states: torch.Tensor,
246 - residual: Optional[torch.Tensor],
245 + residual: torch.Tensor | None,
246 ) -> tuple[torch.Tensor, torch.Tensor]:
247 # Self Attention
248 if residual is None:
@@ -342,9 +341,9 @@ class SeedOssModel(nn.Module):
341 self,
342 input_ids: torch.Tensor,
343 positions: torch.Tensor,
345 - intermediate_tensors: Optional[IntermediateTensors] = None,
346 - inputs_embeds: Optional[torch.Tensor] = None,
347 - ) -> Union[torch.Tensor, IntermediateTensors]:
344 + intermediate_tensors: IntermediateTensors | None = None,
345 + inputs_embeds: torch.Tensor | None = None,
346 + ) -> torch.Tensor | IntermediateTensors:
347 if get_pp_group().is_first_rank:
348 if inputs_embeds is not None:
349 hidden_states = inputs_embeds
@@ -477,9 +476,9 @@ class SeedOssForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
476 self,
477 input_ids: torch.Tensor,
478 positions: torch.Tensor,
480 - intermediate_tensors: Optional[IntermediateTensors] = None,
481 - inputs_embeds: Optional[torch.Tensor] = None,
482 - ) -> Union[torch.Tensor, IntermediateTensors]:
479 + intermediate_tensors: IntermediateTensors | None = None,
480 + inputs_embeds: torch.Tensor | None = None,
481 + ) -> torch.Tensor | IntermediateTensors:
482 hidden_states = self.model(
483 input_ids, positions, intermediate_tensors, inputs_embeds
484 )
@@ -488,7 +487,7 @@ class SeedOssForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
487 def compute_logits(
488 self,
489 hidden_states: torch.Tensor,
491 - ) -> Optional[torch.Tensor]:
490 + ) -> torch.Tensor | None:
491 logits = self.logits_processor(self.lm_head, hidden_states)
492 return logits
493
vllm/model_executor/models/siglip.py
+17 -18
@@ -5,7 +5,6 @@ within a vision language model."""
5
6 import math
7 from collections.abc import Iterable
8 -from typing import Optional, Union
8
9 import torch
10 from torch import nn
@@ -153,7 +152,7 @@ class SiglipAttention(nn.Module):
152 def __init__(
153 self,
154 config: SiglipVisionConfig,
156 - quant_config: Optional[QuantizationConfig] = None,
155 + quant_config: QuantizationConfig | None = None,
156 prefix: str = "",
157 ) -> None:
158 super().__init__()
@@ -211,7 +210,7 @@ class SiglipMLP(nn.Module):
210 def __init__(
211 self,
212 config: SiglipVisionConfig,
214 - quant_config: Optional[QuantizationConfig] = None,
213 + quant_config: QuantizationConfig | None = None,
214 prefix: str = "",
215 ) -> None:
216 super().__init__()
@@ -251,7 +250,7 @@ class SiglipEncoderLayer(nn.Module):
250 def __init__(
251 self,
252 config: SiglipVisionConfig,
254 - quant_config: Optional[QuantizationConfig] = None,
253 + quant_config: QuantizationConfig | None = None,
254 prefix: str = "",
255 ) -> None:
256 super().__init__()
@@ -293,8 +292,8 @@ class SiglipEncoder(nn.Module):
292 def __init__(
293 self,
294 config: SiglipVisionConfig,
296 - quant_config: Optional[QuantizationConfig] = None,
297 - num_hidden_layers_override: Optional[int] = None,
295 + quant_config: QuantizationConfig | None = None,
296 + num_hidden_layers_override: int | None = None,
297 prefix: str = "",
298 ) -> None:
299 super().__init__()
@@ -321,7 +320,7 @@ class SiglipEncoder(nn.Module):
320 self,
321 inputs_embeds: torch.Tensor,
322 return_all_hidden_states: bool,
324 - ) -> Union[torch.Tensor, list[torch.Tensor]]:
323 + ) -> torch.Tensor | list[torch.Tensor]:
324 hidden_states_pool = [inputs_embeds]
325 hidden_states = inputs_embeds
326
@@ -342,7 +341,7 @@ class SiglipMultiheadAttentionPoolingHead(nn.Module):
341 def __init__(
342 self,
343 config: SiglipVisionConfig,
345 - quant_config: Optional[QuantizationConfig] = None,
344 + quant_config: QuantizationConfig | None = None,
345 prefix: str = "",
346 ) -> None:
347 super().__init__()
@@ -375,10 +374,10 @@ class SiglipVisionTransformer(nn.Module):
374 def __init__(
375 self,
376 config: SiglipVisionConfig,
378 - quant_config: Optional[QuantizationConfig] = None,
377 + quant_config: QuantizationConfig | None = None,
378 *,
380 - num_hidden_layers_override: Optional[int] = None,
381 - require_post_norm: Optional[bool] = None,
379 + num_hidden_layers_override: int | None = None,
380 + require_post_norm: bool | None = None,
381 prefix: str = "",
382 ) -> None:
383 super().__init__()
@@ -426,8 +425,8 @@ class SiglipVisionTransformer(nn.Module):
425 pixel_values: torch.Tensor,
426 *,
427 interpolate_pos_encoding: bool = False,
429 - select_layers: Optional[list[int]] = None,
430 - feature_select_strategy: Optional[VisionFeatureSelectStrategy] = None,
428 + select_layers: list[int] | None = None,
429 + feature_select_strategy: VisionFeatureSelectStrategy | None = None,
430 ) -> torch.Tensor:
431 hidden_states = self.embeddings(
432 pixel_values,
@@ -464,10 +463,10 @@ class SiglipVisionModel(nn.Module):
463 def __init__(
464 self,
465 config: SiglipVisionConfig,
467 - quant_config: Optional[QuantizationConfig] = None,
466 + quant_config: QuantizationConfig | None = None,
467 *,
469 - num_hidden_layers_override: Optional[int] = None,
470 - require_post_norm: Optional[bool] = None,
468 + num_hidden_layers_override: int | None = None,
469 + require_post_norm: bool | None = None,
470 prefix: str = "",
471 ) -> None:
472 super().__init__()
@@ -491,8 +490,8 @@ class SiglipVisionModel(nn.Module):
490 self,
491 pixel_values: torch.Tensor,
492 interpolate_pos_encoding: bool = False,
494 - select_layers: Optional[list[int]] = None,
495 - feature_select_strategy: Optional[VisionFeatureSelectStrategy] = None,
493 + select_layers: list[int] | None = None,
494 + feature_select_strategy: VisionFeatureSelectStrategy | None = None,
495 ) -> torch.Tensor:
496 return self.vision_model(
497 pixel_values=pixel_values,
vllm/model_executor/models/siglip2navit.py
+9 -10
@@ -4,7 +4,6 @@
4 within a vision language model."""
5
6 from collections.abc import Iterable
7 -from typing import Optional
7
8 import torch
9 from einops import rearrange, repeat
@@ -82,7 +81,7 @@ class Siglip2VisionEmbeddings(nn.Module):
81 def forward(
82 self,
83 pixel_values: torch.FloatTensor,
85 - grid_thws: Optional[torch.LongTensor] = None,
84 + grid_thws: torch.LongTensor | None = None,
85 ) -> torch.Tensor:
86 """
87 Args:
@@ -206,7 +205,7 @@ class Siglip2Attention(nn.Module):
205 def __init__(
206 self,
207 config: Siglip2VisionConfig,
209 - quant_config: Optional[QuantizationConfig] = None,
208 + quant_config: QuantizationConfig | None = None,
209 prefix: str = "",
210 use_data_parallel: bool = False,
211 ):
@@ -275,8 +274,8 @@ class Siglip2Attention(nn.Module):
274 self,
275 hidden_states: torch.Tensor,
276 cu_seqlens: torch.Tensor,
278 - position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None,
279 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
277 + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
278 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
279 """Input shape: Batch x Time x Channel"""
280
281 seq_length, embed_dim = hidden_states.shape
@@ -337,7 +336,7 @@ class Siglip2MLP(nn.Module):
336 def __init__(
337 self,
338 config: Siglip2VisionConfig,
340 - quant_config: Optional[QuantizationConfig] = None,
339 + quant_config: QuantizationConfig | None = None,
340 prefix: str = "",
341 use_data_parallel: bool = False,
342 ):
@@ -370,7 +369,7 @@ class Siglip2EncoderLayer(nn.Module):
369 def __init__(
370 self,
371 config: Siglip2VisionConfig,
373 - quant_config: Optional[QuantizationConfig] = None,
372 + quant_config: QuantizationConfig | None = None,
373 prefix: str = "",
374 use_data_parallel: bool = False,
375 ):
@@ -432,7 +431,7 @@ class Siglip2Encoder(nn.Module):
431 def __init__(
432 self,
433 config: Siglip2VisionConfig,
435 - quant_config: Optional[QuantizationConfig] = None,
434 + quant_config: QuantizationConfig | None = None,
435 prefix: str = "",
436 use_data_parallel: bool = False,
437 ):
@@ -616,7 +615,7 @@ class Siglip2VisionTransformer(nn.Module):
615 def __init__(
616 self,
617 config: Siglip2VisionConfig,
619 - quant_config: Optional[QuantizationConfig] = None,
618 + quant_config: QuantizationConfig | None = None,
619 prefix: str = "",
620 use_data_parallel: bool = False,
621 ):
@@ -655,7 +654,7 @@ class Siglip2NavitModel(torch.nn.Module):
654 def __init__(
655 self,
656 config: Siglip2VisionConfig,
658 - quant_config: Optional[QuantizationConfig] = None,
657 + quant_config: QuantizationConfig | None = None,
658 prefix: str = "",
659 use_data_parallel: bool = False,
660 ):
vllm/model_executor/models/skyworkr1v.py
+38 -38
@@ -8,7 +8,7 @@
8 # Licensed under The MIT License [see LICENSE for details]
9 # --------------------------------------------------------
10 from collections.abc import Iterable, Mapping, Sequence
11 -from typing import Annotated, Literal, Optional, Union
11 +from typing import Annotated, Literal, TypeAlias
12
13 import torch
14 import torch.nn as nn
@@ -96,14 +96,14 @@ class SkyworkR1VImageEmbeddingInputs(TensorSchema):
96 type: Literal["image_embeds"] = "image_embeds"
97
98 data: Annotated[
99 - Union[torch.Tensor, list[torch.Tensor]],
99 + torch.Tensor | list[torch.Tensor],
100 TensorShape("ni", "ifs", "hs"),
101 ]
102
103
104 -SkyworkR1VImageInputs = Union[
105 - SkyworkR1VImagePixelInputs, SkyworkR1VImageEmbeddingInputs
106 -]
104 +SkyworkR1VImageInputs: TypeAlias = (
105 + SkyworkR1VImagePixelInputs | SkyworkR1VImageEmbeddingInputs
106 +)
107
108
109 # adapted from https://huggingface.co/Skywork/Skywork-R1V-38B/
@@ -284,9 +284,9 @@ class SkyworkR1VProcessor:
284 config: PretrainedConfig,
285 tokenizer: AnyTokenizer,
286 *,
287 - min_dynamic_patch: Optional[int] = None,
288 - max_dynamic_patch: Optional[int] = None,
289 - dynamic_image_size: Optional[bool] = None,
287 + min_dynamic_patch: int | None = None,
288 + max_dynamic_patch: int | None = None,
289 + dynamic_image_size: bool | None = None,
290 ) -> None:
291 super().__init__()
292
@@ -324,7 +324,7 @@ class SkyworkR1VProcessor:
324 def get_image_repl(
325 self,
326 feature_size: int,
327 - num_patches: Optional[int],
327 + num_patches: int | None,
328 ) -> PromptUpdateDetails[str]:
329 repl_features = IMG_CONTEXT * feature_size
330 repl_full = IMG_START + repl_features + IMG_END
@@ -334,10 +334,10 @@ class SkyworkR1VProcessor:
334 def resolve_min_max_num(
335 self,
336 *,
337 - min_dynamic_patch: Optional[int] = None,
338 - max_dynamic_patch: Optional[int] = None,
339 - dynamic_image_size: Optional[bool] = None,
340 - use_thumbnail: Optional[bool] = None,
337 + min_dynamic_patch: int | None = None,
338 + max_dynamic_patch: int | None = None,
339 + dynamic_image_size: bool | None = None,
340 + use_thumbnail: bool | None = None,
341 ) -> tuple[int, int]:
342 min_dynamic_patch = (
343 self.min_dynamic_patch if min_dynamic_patch is None else min_dynamic_patch
@@ -362,10 +362,10 @@ class SkyworkR1VProcessor:
362 def resolve_target_ratios(
363 self,
364 *,
365 - min_dynamic_patch: Optional[int] = None,
366 - max_dynamic_patch: Optional[int] = None,
367 - dynamic_image_size: Optional[bool] = None,
368 - use_thumbnail: Optional[bool] = None,
365 + min_dynamic_patch: int | None = None,
366 + max_dynamic_patch: int | None = None,
367 + dynamic_image_size: bool | None = None,
368 + use_thumbnail: bool | None = None,
369 ) -> list[tuple[int, int]]:
370 min_num, max_num = self.resolve_min_max_num(
371 min_dynamic_patch=min_dynamic_patch,
@@ -399,9 +399,9 @@ class SkyworkR1VProcessor:
399 def _images_to_pixel_values_lst(
400 self,
401 images: list[Image.Image],
402 - min_dynamic_patch: Optional[int] = None,
403 - max_dynamic_patch: Optional[int] = None,
404 - dynamic_image_size: Optional[bool] = None,
402 + min_dynamic_patch: int | None = None,
403 + max_dynamic_patch: int | None = None,
404 + dynamic_image_size: bool | None = None,
405 ) -> list[torch.Tensor]:
406 min_num, max_num = self.resolve_min_max_num(
407 min_dynamic_patch=min_dynamic_patch,
@@ -423,12 +423,12 @@ class SkyworkR1VProcessor:
423
424 def __call__(
425 self,
426 - text: Optional[Union[str, list[str]]] = None,
427 - images: Optional[Union[Image.Image, list[Image.Image]]] = None,
428 - min_dynamic_patch: Optional[int] = None,
429 - max_dynamic_patch: Optional[int] = None,
430 - dynamic_image_size: Optional[bool] = None,
431 - return_tensors: Optional[Union[str, TensorType]] = None,
426 + text: str | list[str] | None = None,
427 + images: Image.Image | list[Image.Image] | None = None,
428 + min_dynamic_patch: int | None = None,
429 + max_dynamic_patch: int | None = None,
430 + dynamic_image_size: bool | None = None,
431 + return_tensors: str | TensorType | None = None,
432 ) -> BatchFeature:
433 if text is None:
434 text = []
@@ -479,7 +479,7 @@ class SkyworkR1VProcessingInfo(BaseProcessingInfo):
479 **kwargs,
480 )
481
482 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
482 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
483 return {"image": None}
484
485 def get_num_image_tokens(
@@ -487,7 +487,7 @@ class SkyworkR1VProcessingInfo(BaseProcessingInfo):
487 *,
488 image_width: int,
489 image_height: int,
490 - processor: Optional[SkyworkR1VProcessor],
490 + processor: SkyworkR1VProcessor | None,
491 ) -> int:
492 if processor is None:
493 processor = self.get_hf_processor()
@@ -532,7 +532,7 @@ class SkyworkR1VDummyInputsBuilder(BaseDummyInputsBuilder[SkyworkR1VProcessingIn
532 self,
533 seq_len: int,
534 mm_counts: Mapping[str, int],
535 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
535 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
536 ) -> MultiModalDataDict:
537 target_width, target_height = self.info.get_image_size_with_most_features()
538 num_images = mm_counts.get("image", 0)
@@ -650,7 +650,7 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
650 merge_by_field_config = True
651
652 @classmethod
653 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
653 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
654 if modality.startswith("image"):
655 return "<image>"
656
@@ -715,7 +715,7 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
715 def _init_vision_model(
716 self,
717 config: PretrainedConfig,
718 - quant_config: Optional[QuantizationConfig],
718 + quant_config: QuantizationConfig | None,
719 *,
720 is_mono: bool,
721 prefix: str,
@@ -784,7 +784,7 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
784
785 def _parse_and_validate_image_input(
786 self, **kwargs: object
787 - ) -> Optional[SkyworkR1VImageInputs]:
787 + ) -> SkyworkR1VImageInputs | None:
788 pixel_values_flat = kwargs.pop("pixel_values_flat", None)
789 image_num_patches = kwargs.pop("image_num_patches", None)
790 image_embeds = kwargs.pop("image_embeds", None)
@@ -818,7 +818,7 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
818 def _process_image_input(
819 self,
820 image_input: SkyworkR1VImageInputs,
821 - ) -> Union[torch.Tensor, list[torch.Tensor], tuple[torch.Tensor, ...]]:
821 + ) -> torch.Tensor | list[torch.Tensor] | tuple[torch.Tensor, ...]:
822 if image_input["type"] == "image_embeds":
823 return image_input["data"]
824
@@ -864,9 +864,9 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
864 def get_input_embeddings(
865 self,
866 input_ids: torch.Tensor,
867 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
867 + multimodal_embeddings: MultiModalEmbeddings | None = None,
868 *,
869 - is_multimodal: Optional[torch.Tensor] = None,
869 + is_multimodal: torch.Tensor | None = None,
870 handle_oov_mm_token: bool = False,
871 ) -> torch.Tensor:
872 if multimodal_embeddings is not None and len(multimodal_embeddings) > 0:
@@ -887,8 +887,8 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
887 self,
888 input_ids: torch.Tensor,
889 positions: torch.Tensor,
890 - intermediate_tensors: Optional[IntermediateTensors] = None,
891 - inputs_embeds: Optional[torch.Tensor] = None,
890 + intermediate_tensors: IntermediateTensors | None = None,
891 + inputs_embeds: torch.Tensor | None = None,
892 **kwargs: object,
893 ) -> IntermediateTensors:
894 if intermediate_tensors is not None:
@@ -913,7 +913,7 @@ class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
913 def compute_logits(
914 self,
915 hidden_states: torch.Tensor,
916 - ) -> Optional[torch.Tensor]:
916 + ) -> torch.Tensor | None:
917 return self.language_model.compute_logits(hidden_states)
918
919 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/smolvlm.py
+1 -4
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 from transformers import SmolVLMProcessor
6
@@ -17,9 +16,7 @@ class SmolVLMProcessingInfo(Idefics3ProcessingInfo):
16 def get_hf_processor(self, **kwargs: object) -> SmolVLMProcessor:
17 return self.ctx.get_hf_processor(SmolVLMProcessor, **kwargs)
18
20 - def _get_image_token(
21 - self, processor: Optional[SmolVLMProcessor]
22 - ) -> tuple[str, str]:
19 + def _get_image_token(self, processor: SmolVLMProcessor | None) -> tuple[str, str]:
20 if processor is None:
21 processor = self.get_hf_processor()
22 image_token = processor.image_token
vllm/model_executor/models/solar.py
+15 -15
@@ -25,7 +25,7 @@
25 """Inference-only Solar model compatible with HuggingFace weights."""
26
27 from collections.abc import Iterable
28 -from typing import Any, Optional, Union
28 +from typing import Any
29
30 import torch
31 from torch import nn
@@ -73,7 +73,7 @@ class SolarMLP(nn.Module):
73 hidden_size: int,
74 intermediate_size: int,
75 hidden_act: str,
76 - quant_config: Optional[QuantizationConfig] = None,
76 + quant_config: QuantizationConfig | None = None,
77 bias: bool = False,
78 prefix: str = "",
79 ) -> None:
@@ -113,11 +113,11 @@ class SolarAttention(nn.Module):
113 num_heads: int,
114 num_kv_heads: int,
115 rope_theta: float = 10000,
116 - rope_scaling: Optional[dict[str, Any]] = None,
116 + rope_scaling: dict[str, Any] | None = None,
117 max_position_embeddings: int = 8192,
118 - quant_config: Optional[QuantizationConfig] = None,
118 + quant_config: QuantizationConfig | None = None,
119 bias: bool = False,
120 - cache_config: Optional[CacheConfig] = None,
120 + cache_config: CacheConfig | None = None,
121 prefix: str = "",
122 ) -> None:
123 super().__init__()
@@ -197,8 +197,8 @@ class SolarDecoderLayer(nn.Module):
197 def __init__(
198 self,
199 config: PretrainedConfig,
200 - cache_config: Optional[CacheConfig] = None,
201 - quant_config: Optional[QuantizationConfig] = None,
200 + cache_config: CacheConfig | None = None,
201 + quant_config: QuantizationConfig | None = None,
202 prefix: str = "",
203 ) -> None:
204 super().__init__()
@@ -250,7 +250,7 @@ class SolarDecoderLayer(nn.Module):
250 self,
251 positions: torch.Tensor,
252 hidden_states: torch.Tensor,
253 - residual: Optional[torch.Tensor],
253 + residual: torch.Tensor | None,
254 ) -> tuple[torch.Tensor, torch.Tensor]:
255 # Self Attention
256 if residual is None:
@@ -322,11 +322,11 @@ class SolarModel(nn.Module):
322
323 def forward(
324 self,
325 - input_ids: Optional[torch.Tensor],
325 + input_ids: torch.Tensor | None,
326 positions: torch.Tensor,
327 - intermediate_tensors: Optional[IntermediateTensors],
328 - inputs_embeds: Optional[torch.Tensor] = None,
329 - ) -> Union[torch.Tensor, IntermediateTensors]:
327 + intermediate_tensors: IntermediateTensors | None,
328 + inputs_embeds: torch.Tensor | None = None,
329 + ) -> torch.Tensor | IntermediateTensors:
330 if get_pp_group().is_first_rank:
331 if inputs_embeds is not None:
332 hidden_states = inputs_embeds
@@ -501,9 +501,9 @@ class SolarForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
501 self,
502 input_ids: torch.Tensor,
503 positions: torch.Tensor,
504 - intermediate_tensors: Optional[IntermediateTensors] = None,
505 - inputs_embeds: Optional[torch.Tensor] = None,
506 - ) -> Union[torch.Tensor, IntermediateTensors]:
504 + intermediate_tensors: IntermediateTensors | None = None,
505 + inputs_embeds: torch.Tensor | None = None,
506 + ) -> torch.Tensor | IntermediateTensors:
507 model_output = self.model(
508 input_ids, positions, intermediate_tensors, inputs_embeds
509 )
vllm/model_executor/models/stablelm.py
+12 -13
@@ -24,7 +24,6 @@ model compatible with HuggingFace weights."""
24
25 from collections.abc import Iterable
26 from itertools import islice
27 -from typing import Optional, Union
27
28 import torch
29 from torch import nn
@@ -63,7 +62,7 @@ class StablelmMLP(nn.Module):
62 def __init__(
63 self,
64 config: StableLmConfig,
66 - quant_config: Optional[QuantizationConfig] = None,
65 + quant_config: QuantizationConfig | None = None,
66 prefix: str = "",
67 ) -> None:
68 super().__init__()
@@ -97,8 +96,8 @@ class StablelmAttention(nn.Module):
96 def __init__(
97 self,
98 config: StableLmConfig,
100 - cache_config: Optional[CacheConfig] = None,
101 - quant_config: Optional[QuantizationConfig] = None,
99 + cache_config: CacheConfig | None = None,
100 + quant_config: QuantizationConfig | None = None,
101 prefix: str = "",
102 ) -> None:
103 super().__init__()
@@ -184,8 +183,8 @@ class StablelmDecoderLayer(nn.Module):
183 def __init__(
184 self,
185 config: StableLmConfig,
187 - cache_config: Optional[CacheConfig] = None,
188 - quant_config: Optional[QuantizationConfig] = None,
186 + cache_config: CacheConfig | None = None,
187 + quant_config: QuantizationConfig | None = None,
188 prefix: str = "",
189 ) -> None:
190 super().__init__()
@@ -254,9 +253,9 @@ class StableLMEpochModel(nn.Module):
253 self,
254 input_ids: torch.Tensor,
255 positions: torch.Tensor,
257 - intermediate_tensors: Optional[IntermediateTensors],
258 - inputs_embeds: Optional[torch.Tensor] = None,
259 - ) -> Union[torch.Tensor, IntermediateTensors]:
256 + intermediate_tensors: IntermediateTensors | None,
257 + inputs_embeds: torch.Tensor | None = None,
258 + ) -> torch.Tensor | IntermediateTensors:
259 if get_pp_group().is_first_rank:
260 if inputs_embeds is not None:
261 hidden_states = inputs_embeds
@@ -340,9 +339,9 @@ class StablelmForCausalLM(nn.Module, SupportsPP):
339 self,
340 input_ids: torch.Tensor,
341 positions: torch.Tensor,
343 - intermediate_tensors: Optional[IntermediateTensors] = None,
344 - inputs_embeds: Optional[torch.Tensor] = None,
345 - ) -> Union[torch.Tensor, IntermediateTensors]:
342 + intermediate_tensors: IntermediateTensors | None = None,
343 + inputs_embeds: torch.Tensor | None = None,
344 + ) -> torch.Tensor | IntermediateTensors:
345 hidden_states = self.model(
346 input_ids, positions, intermediate_tensors, inputs_embeds
347 )
@@ -351,7 +350,7 @@ class StablelmForCausalLM(nn.Module, SupportsPP):
350 def compute_logits(
351 self,
352 hidden_states: torch.Tensor,
354 - ) -> Optional[torch.Tensor]:
353 + ) -> torch.Tensor | None:
354 logits = self.logits_processor(self.lm_head, hidden_states)
355 return logits
356
vllm/model_executor/models/starcoder2.py
+12 -13
@@ -23,7 +23,6 @@
23
24 from collections.abc import Iterable
25 from itertools import islice
26 -from typing import Optional, Union
26
27 import torch
28 from torch import nn
@@ -67,8 +66,8 @@ class Starcoder2Attention(nn.Module):
66 def __init__(
67 self,
68 config: Starcoder2Config,
70 - cache_config: Optional[CacheConfig] = None,
71 - quant_config: Optional[QuantizationConfig] = None,
69 + cache_config: CacheConfig | None = None,
70 + quant_config: QuantizationConfig | None = None,
71 prefix: str = "",
72 ):
73 super().__init__()
@@ -147,7 +146,7 @@ class Starcoder2MLP(nn.Module):
146 def __init__(
147 self,
148 config: Starcoder2Config,
150 - quant_config: Optional[QuantizationConfig] = None,
149 + quant_config: QuantizationConfig | None = None,
150 prefix: str = "",
151 ):
152 super().__init__()
@@ -178,8 +177,8 @@ class Starcoder2DecoderLayer(nn.Module):
177 def __init__(
178 self,
179 config: Starcoder2Config,
181 - cache_config: Optional[CacheConfig] = None,
182 - quant_config: Optional[QuantizationConfig] = None,
180 + cache_config: CacheConfig | None = None,
181 + quant_config: QuantizationConfig | None = None,
182 prefix: str = "",
183 ):
184 super().__init__()
@@ -258,9 +257,9 @@ class Starcoder2Model(nn.Module):
257 self,
258 input_ids: torch.Tensor,
259 positions: torch.Tensor,
261 - intermediate_tensors: Optional[IntermediateTensors],
262 - inputs_embeds: Optional[torch.Tensor] = None,
263 - ) -> Union[torch.Tensor, IntermediateTensors]:
260 + intermediate_tensors: IntermediateTensors | None,
261 + inputs_embeds: torch.Tensor | None = None,
262 + ) -> torch.Tensor | IntermediateTensors:
263 if get_pp_group().is_first_rank:
264 if inputs_embeds is not None:
265 hidden_states = inputs_embeds
@@ -347,9 +346,9 @@ class Starcoder2ForCausalLM(nn.Module, SupportsPP):
346 self,
347 input_ids: torch.Tensor,
348 positions: torch.Tensor,
350 - intermediate_tensors: Optional[IntermediateTensors] = None,
351 - inputs_embeds: Optional[torch.Tensor] = None,
352 - ) -> Union[torch.Tensor, IntermediateTensors]:
349 + intermediate_tensors: IntermediateTensors | None = None,
350 + inputs_embeds: torch.Tensor | None = None,
351 + ) -> torch.Tensor | IntermediateTensors:
352 hidden_states = self.model(
353 input_ids, positions, intermediate_tensors, inputs_embeds
354 )
@@ -358,7 +357,7 @@ class Starcoder2ForCausalLM(nn.Module, SupportsPP):
357 def compute_logits(
358 self,
359 hidden_states: torch.Tensor,
361 - ) -> Optional[torch.Tensor]:
360 + ) -> torch.Tensor | None:
361 logits = self.logits_processor(self.lm_head, hidden_states)
362 return logits
363
vllm/model_executor/models/step3_text.py
+14 -14
@@ -4,7 +4,7 @@
4
5 from collections.abc import Iterable
6 from itertools import islice
7 -from typing import Any, Optional
7 +from typing import Any
8
9 import torch
10 from torch import nn
@@ -54,7 +54,7 @@ class FusedMoEBlock(nn.Module):
54 def __init__(
55 self,
56 config: ModelConfig,
57 - quant_config: Optional[QuantizationConfig] = None,
57 + quant_config: QuantizationConfig | None = None,
58 prefix: str = "",
59 ):
60 super().__init__()
@@ -106,7 +106,7 @@ class Step3TextMLP(nn.Module):
106 hidden_size: int,
107 intermediate_size: int,
108 hidden_act: str,
109 - quant_config: Optional[QuantizationConfig] = None,
109 + quant_config: QuantizationConfig | None = None,
110 prefix: str = "",
111 ) -> None:
112 super().__init__()
@@ -146,12 +146,12 @@ class Step3TextAttention(nn.Module):
146 num_kv_heads: int,
147 norm_eps: float,
148 rope_theta: int,
149 - share_q_dim: Optional[int] = None,
150 - rope_scaling: Optional[dict[str, Any]] = None,
149 + share_q_dim: int | None = None,
150 + rope_scaling: dict[str, Any] | None = None,
151 max_position_embedding: int = 8192,
152 head_dim: int = 256,
153 - cache_config: Optional[CacheConfig] = None,
154 - quant_config: Optional[QuantizationConfig] = None,
153 + cache_config: CacheConfig | None = None,
154 + quant_config: QuantizationConfig | None = None,
155 prefix: str = "",
156 ):
157 super().__init__()
@@ -229,8 +229,8 @@ class Step3TextDecoderLayer(nn.Module):
229 def __init__(
230 self,
231 config: ModelConfig,
232 - cache_config: Optional[CacheConfig] = None,
233 - quant_config: Optional[QuantizationConfig] = None,
232 + cache_config: CacheConfig | None = None,
233 + quant_config: QuantizationConfig | None = None,
234 prefix: str = "",
235 ) -> None:
236 super().__init__()
@@ -291,7 +291,7 @@ class Step3TextDecoderLayer(nn.Module):
291 self,
292 positions: torch.Tensor,
293 hidden_states: torch.Tensor,
294 - residual: Optional[torch.Tensor],
294 + residual: torch.Tensor | None,
295 ) -> tuple[torch.Tensor, torch.Tensor]:
296 if residual is None:
297 residual = hidden_states
@@ -362,8 +362,8 @@ class Step3TextModel(nn.Module):
362 self,
363 input_ids: torch.Tensor,
364 positions: torch.Tensor,
365 - intermediate_tensors: Optional[IntermediateTensors] = None,
366 - inputs_embeds: Optional[torch.Tensor] = None,
365 + intermediate_tensors: IntermediateTensors | None = None,
366 + inputs_embeds: torch.Tensor | None = None,
367 ) -> torch.Tensor:
368 if get_pp_group().is_first_rank:
369 if inputs_embeds is not None:
@@ -436,8 +436,8 @@ class Step3TextForCausalLM(nn.Module, SupportsPP):
436 self,
437 input_ids: torch.Tensor,
438 positions: torch.Tensor,
439 - intermediate_tensors: Optional[IntermediateTensors] = None,
440 - inputs_embeds: Optional[torch.Tensor] = None,
439 + intermediate_tensors: IntermediateTensors | None = None,
440 + inputs_embeds: torch.Tensor | None = None,
441 ):
442 hidden_states = self.model(
443 input_ids, positions, intermediate_tensors, inputs_embeds
vllm/model_executor/models/step3_vl.py
+22 -22
@@ -4,7 +4,7 @@ import math
4 from collections.abc import Iterable, Mapping, Sequence
5 from itertools import product
6 from math import ceil, sqrt
7 -from typing import Annotated, Any, Literal, Optional, Union
7 +from typing import Annotated, Any, Literal, TypeAlias
8
9 import numpy as np
10 import torch
@@ -71,7 +71,7 @@ class Step3VLImagePixelInputs(TensorSchema):
71 type: Literal["pixel_values"]
72 pixel_values: Annotated[torch.Tensor, TensorShape("bn", 3, "h", "w")]
73 patch_pixel_values: Annotated[
74 - Optional[torch.Tensor], TensorShape("bnp", 3, "hp", "wp")
74 + torch.Tensor | None, TensorShape("bnp", 3, "hp", "wp")
75 ]
76 num_patches: Annotated[torch.Tensor, TensorShape("bn")]
77
@@ -88,7 +88,7 @@ class Step3VLImageEmbeddingInputs(TensorSchema):
88 data: Annotated[torch.Tensor, TensorShape("bn", "f", "h")]
89
90
91 -Step3VLImageInputs = Union[Step3VLImagePixelInputs, Step3VLImageEmbeddingInputs]
91 +Step3VLImageInputs: TypeAlias = Step3VLImagePixelInputs | Step3VLImageEmbeddingInputs
92
93 ImageWithPatches = tuple[Image.Image, list[Image.Image], list[int] | None]
94
@@ -409,7 +409,7 @@ class Step3VLProcessor:
409 self,
410 num_images: int,
411 num_patches: int,
412 - patch_new_line_idx: Optional[list[bool]],
412 + patch_new_line_idx: list[bool] | None,
413 ) -> tuple[str, list[int]]:
414 if num_patches > 0:
415 patch_repl, patch_repl_ids = self._get_patch_repl(
@@ -438,9 +438,9 @@ class Step3VLProcessor:
438
439 def __call__(
440 self,
441 - text: Optional[Union[str, list[str]]] = None,
442 - images: Optional[Union[Image.Image, list[Image.Image]]] = None,
443 - return_tensors: Optional[Union[str, TensorType]] = None,
441 + text: str | list[str] | None = None,
442 + images: Image.Image | list[Image.Image] | None = None,
443 + return_tensors: str | TensorType | None = None,
444 ) -> BatchFeature:
445 if text is None:
446 text = []
@@ -513,7 +513,7 @@ class Step3VLProcessingInfo(BaseProcessingInfo):
513 self.get_tokenizer(),
514 )
515
516 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
516 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
517 return {"image": None}
518
519 def get_max_image_tokens(self) -> int:
@@ -556,7 +556,7 @@ class Step3VLDummyInputsBuilder(BaseDummyInputsBuilder[Step3VLProcessingInfo]):
556 self,
557 seq_len: int,
558 mm_counts: Mapping[str, int],
559 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
559 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
560 ) -> MultiModalDataDict:
561 target_width, target_height = self.info.get_image_size_with_most_features()
562 num_images = mm_counts.get("image", 0)
@@ -716,7 +716,7 @@ class Step3VisionAttention(nn.Module):
716 def __init__(
717 self,
718 config,
719 - quant_config: Optional[QuantizationConfig] = None,
719 + quant_config: QuantizationConfig | None = None,
720 prefix: str = "",
721 use_data_parallel: bool = False,
722 ):
@@ -778,7 +778,7 @@ class Step3VisionMLP(nn.Module):
778 def __init__(
779 self,
780 config,
781 - quant_config: Optional[QuantizationConfig] = None,
781 + quant_config: QuantizationConfig | None = None,
782 prefix: str = "",
783 use_data_parallel: bool = False,
784 ):
@@ -813,7 +813,7 @@ class Step3VisionEncoderLayer(nn.Module):
813 def __init__(
814 self,
815 config: Step3VisionEncoderConfig,
816 - quant_config: Optional[QuantizationConfig] = None,
816 + quant_config: QuantizationConfig | None = None,
817 prefix: str = "",
818 use_data_parallel: bool = False,
819 ):
@@ -848,7 +848,7 @@ class Step3VisionEncoder(nn.Module):
848 def __init__(
849 self,
850 config: Step3VisionEncoderConfig,
851 - quant_config: Optional[QuantizationConfig] = None,
851 + quant_config: QuantizationConfig | None = None,
852 prefix: str = "",
853 use_data_parallel: bool = False,
854 ):
@@ -881,7 +881,7 @@ class Step3VisionTransformer(nn.Module):
881 def __init__(
882 self,
883 config: Step3VisionEncoderConfig,
884 - quant_config: Optional[QuantizationConfig] = None,
884 + quant_config: QuantizationConfig | None = None,
885 prefix: str = "",
886 use_data_parallel: bool = False,
887 ):
@@ -927,7 +927,7 @@ class Step3VLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
927 supports_encoder_tp_data = True
928
929 @classmethod
930 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
930 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
931 if modality.startswith("image"):
932 return "<im_patch>"
933
@@ -994,7 +994,7 @@ class Step3VLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
994
995 def _parse_and_validate_image_input(
996 self, **kwargs: object
997 - ) -> Optional[Step3VLImageInputs]:
997 + ) -> Step3VLImageInputs | None:
998 pixel_values = kwargs.pop("pixel_values", None)
999 patch_pixel_values = kwargs.pop("patch_pixel_values", None)
1000 num_patches = kwargs.pop("num_patches", None)
@@ -1085,9 +1085,9 @@ class Step3VLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
1085 def get_input_embeddings(
1086 self,
1087 input_ids: torch.Tensor,
1088 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
1088 + multimodal_embeddings: MultiModalEmbeddings | None = None,
1089 *,
1090 - is_multimodal: Optional[torch.Tensor] = None,
1090 + is_multimodal: torch.Tensor | None = None,
1091 # Multi-modal token ID may exceed vocab size
1092 handle_oov_mm_token: bool = True,
1093 ) -> torch.Tensor:
@@ -1106,10 +1106,10 @@ class Step3VLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
1106 self,
1107 input_ids: torch.Tensor,
1108 positions: torch.Tensor,
1109 - intermediate_tensors: Optional[IntermediateTensors] = None,
1110 - inputs_embeds: Optional[torch.Tensor] = None,
1109 + intermediate_tensors: IntermediateTensors | None = None,
1110 + inputs_embeds: torch.Tensor | None = None,
1111 **kwargs: object,
1112 - ) -> Union[torch.Tensor, IntermediateTensors]:
1112 + ) -> torch.Tensor | IntermediateTensors:
1113 if intermediate_tensors is not None:
1114 inputs_embeds = None
1115 elif inputs_embeds is None:
@@ -1130,7 +1130,7 @@ class Step3VLForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
1130 def compute_logits(
1131 self,
1132 hidden_states: torch.Tensor,
1133 - ) -> Optional[torch.Tensor]:
1133 + ) -> torch.Tensor | None:
1134 return self.language_model.compute_logits(hidden_states)
1135
1136 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]):
vllm/model_executor/models/swin.py
+25 -26
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Iterable
5 -from typing import Optional
5
6 import torch
7 import torch.nn as nn
@@ -28,7 +27,7 @@ class SwinSelfAttention(nn.Module):
27 dim: int,
28 num_heads: int,
29 window_size: int,
31 - quant_config: Optional[QuantizationConfig] = None,
30 + quant_config: QuantizationConfig | None = None,
31 prefix: str = "",
32 ) -> None:
33 super().__init__()
@@ -102,9 +101,9 @@ class SwinSelfAttention(nn.Module):
101 def forward(
102 self,
103 hidden_states: torch.Tensor,
105 - attention_mask: Optional[torch.FloatTensor] = None,
106 - head_mask: Optional[torch.FloatTensor] = None,
107 - output_attentions: Optional[bool] = False,
104 + attention_mask: torch.FloatTensor | None = None,
105 + head_mask: torch.FloatTensor | None = None,
106 + output_attentions: bool | None = False,
107 ) -> tuple[torch.Tensor, ...]:
108 batch_size, dim, num_channels = hidden_states.shape
109
@@ -155,7 +154,7 @@ class SwinSelfOutput(nn.Module):
154 self,
155 config: SwinConfig,
156 dim: int,
158 - quant_config: Optional[QuantizationConfig] = None,
157 + quant_config: QuantizationConfig | None = None,
158 prefix: str = "",
159 ) -> None:
160 super().__init__()
@@ -181,7 +180,7 @@ class SwinAttention(nn.Module):
180 dim: int,
181 num_heads: int,
182 window_size: int,
184 - quant_config: Optional[QuantizationConfig] = None,
183 + quant_config: QuantizationConfig | None = None,
184 prefix: str = "",
185 ) -> None:
186 super().__init__()
@@ -201,9 +200,9 @@ class SwinAttention(nn.Module):
200 def forward(
201 self,
202 hidden_states: torch.Tensor,
204 - attention_mask: Optional[torch.FloatTensor] = None,
205 - head_mask: Optional[torch.FloatTensor] = None,
206 - output_attentions: Optional[bool] = False,
203 + attention_mask: torch.FloatTensor | None = None,
204 + head_mask: torch.FloatTensor | None = None,
205 + output_attentions: bool | None = False,
206 ) -> tuple[torch.Tensor]:
207 self_outputs = self.self(
208 hidden_states, attention_mask, head_mask, output_attentions
@@ -218,7 +217,7 @@ class SwinIntermediate(nn.Module):
217 self,
218 config: SwinConfig,
219 dim: int,
221 - quant_config: Optional[QuantizationConfig] = None,
220 + quant_config: QuantizationConfig | None = None,
221 prefix: str = "",
222 ) -> None:
223 super().__init__()
@@ -241,7 +240,7 @@ class SwinOutput(nn.Module):
240 self,
241 config: SwinConfig,
242 dim: int,
244 - quant_config: Optional[QuantizationConfig] = None,
243 + quant_config: QuantizationConfig | None = None,
244 prefix: str = "",
245 ) -> None:
246 super().__init__()
@@ -266,7 +265,7 @@ class SwinLayer(HFSwinLayer):
265 num_heads: int,
266 drop_path_rate: float = 0.0,
267 shift_size: int = 0,
269 - quant_config: Optional[QuantizationConfig] = None,
268 + quant_config: QuantizationConfig | None = None,
269 prefix: str = "",
270 ) -> None:
271 super().__init__(
@@ -303,8 +302,8 @@ class SwinStage(nn.Module):
302 depth: int,
303 num_heads: int,
304 drop_path: list[float],
306 - downsample: Optional[SwinPatchMerging] = None,
307 - quant_config: Optional[QuantizationConfig] = None,
305 + downsample: SwinPatchMerging | None = None,
306 + quant_config: QuantizationConfig | None = None,
307 prefix: str = "",
308 ) -> None:
309 super().__init__()
@@ -340,9 +339,9 @@ class SwinStage(nn.Module):
339 self,
340 hidden_states: torch.Tensor,
341 input_dimensions: tuple[int, int],
343 - head_mask: Optional[torch.FloatTensor] = None,
344 - output_attentions: Optional[bool] = False,
345 - always_partition: Optional[bool] = False,
342 + head_mask: torch.FloatTensor | None = None,
343 + output_attentions: bool | None = False,
344 + always_partition: bool | None = False,
345 ) -> tuple[torch.Tensor]:
346 height, width = input_dimensions
347 for i, layer_module in enumerate(self.blocks):
@@ -384,7 +383,7 @@ class SwinEncoder(nn.Module):
383 self,
384 config: SwinConfig,
385 grid_size: int,
387 - quant_config: Optional[QuantizationConfig] = None,
386 + quant_config: QuantizationConfig | None = None,
387 prefix: str = "",
388 ) -> None:
389 super().__init__()
@@ -426,9 +425,9 @@ class SwinEncoder(nn.Module):
425 self,
426 hidden_states: torch.Tensor,
427 input_dimensions: tuple[int, int],
429 - head_mask: Optional[torch.FloatTensor] = None,
430 - output_attentions: Optional[bool] = False,
431 - always_partition: Optional[bool] = False,
428 + head_mask: torch.FloatTensor | None = None,
429 + output_attentions: bool | None = False,
430 + always_partition: bool | None = False,
431 ) -> tuple[torch.Tensor]:
432 for i, layer_module in enumerate(self.layers):
433 layer_head_mask = head_mask[i] if head_mask is not None else None
@@ -455,7 +454,7 @@ class SwinModel(nn.Module):
454 def __init__(
455 self,
456 config: SwinConfig,
458 - quant_config: Optional[QuantizationConfig] = None,
457 + quant_config: QuantizationConfig | None = None,
458 prefix: str = "",
459 ) -> None:
460 super().__init__()
@@ -473,9 +472,9 @@ class SwinModel(nn.Module):
472
473 def forward(
474 self,
476 - pixel_values: Optional[torch.FloatTensor] = None,
477 - head_mask: Optional[torch.FloatTensor] = None,
478 - output_attentions: Optional[bool] = None,
475 + pixel_values: torch.FloatTensor | None = None,
476 + head_mask: torch.FloatTensor | None = None,
477 + output_attentions: bool | None = None,
478 ) -> tuple[torch.Tensor]:
479 embedding_output, input_dimensions = self.embeddings(pixel_values)
480
vllm/model_executor/models/tarsier.py
+24 -23
@@ -3,7 +3,7 @@
3
4 import math
5 from collections.abc import Iterable, Mapping, Sequence
6 -from typing import Annotated, Final, Literal, Optional, Protocol, TypeVar, Union
6 +from typing import Annotated, Final, Literal, Protocol, TypeAlias, TypeVar
7
8 import torch
9 import torch.nn as nn
@@ -81,7 +81,7 @@ class TarsierImageEmbeddingInputs(TensorSchema):
81 data: Annotated[torch.Tensor, TensorShape("bn", "ifs", "hs")]
82
83
84 -TarsierImageInputs = Union[TarsierImagePixelInputs, TarsierImageEmbeddingInputs]
84 +TarsierImageInputs: TypeAlias = TarsierImagePixelInputs | TarsierImageEmbeddingInputs
85
86
87 class TarsierHfConfig(Protocol): # Based on the Tarsier's LlavaConfig
@@ -89,7 +89,7 @@ class TarsierHfConfig(Protocol): # Based on the Tarsier's LlavaConfig
89 text_config: Final[PretrainedConfig] # Added from Tarsier's LlavaConfig
90 image_token_index: Final[int]
91 vision_feature_select_strategy: Final[str]
92 - vision_feature_layer: Final[Union[int, list[int]]]
92 + vision_feature_layer: Final[int | list[int]]
93 projector_hidden_act: Final[str]
94 image_newline_idx: Final[int]
95 image_new_idx: Final[int]
@@ -109,9 +109,10 @@ class TarsierProcessor(LlavaProcessor):
109 def __call__(
110 self,
111 images: ImageInput = None,
112 - text: Union[
113 - TextInput, PreTokenizedInput, list[TextInput], list[PreTokenizedInput]
114 - ] = None,
112 + text: TextInput
113 + | PreTokenizedInput
114 + | list[TextInput]
115 + | list[PreTokenizedInput] = None,
116 audio=None,
117 videos=None,
118 **kwargs: Unpack[TarsierProcessorKwargs],
@@ -173,7 +174,7 @@ class TarsierMultiModalProjector(nn.Module):
174 text_hidden_size: int,
175 projector_hidden_act: str,
176 multimodal_projector_bias: bool,
176 - quant_config: Optional[QuantizationConfig] = None,
177 + quant_config: QuantizationConfig | None = None,
178 prefix: str = "",
179 ):
180 super().__init__()
@@ -215,7 +216,7 @@ class TarsierProcessingInfo(BaseProcessingInfo):
216
217 return self.ctx.get_hf_processor(TarsierProcessor, **kwargs)
218
218 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
219 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
220 return {"image": None}
221
222 def get_num_image_tokens(
@@ -331,7 +332,7 @@ def _build_tarsier_hf_processor(
332 info: _I_Tarsier,
333 dummy_inputs: BaseDummyInputsBuilder[_I_Tarsier],
334 *,
334 - cache: Optional[BaseMultiModalProcessorCache] = None,
335 + cache: BaseMultiModalProcessorCache | None = None,
336 ) -> BaseMultiModalProcessor:
337 if isinstance(info, TarsierProcessingInfo):
338 return TarsierMultiModalProcessor(
@@ -344,11 +345,11 @@ def _build_tarsier_hf_processor(
345
346 def init_vision_tower_for_tarsier(
347 hf_config: TarsierHfConfig, # Use the Tarsier specific config protocol
347 - quant_config: Optional[QuantizationConfig],
348 + quant_config: QuantizationConfig | None,
349 *,
349 - require_post_norm: Optional[bool] = None,
350 + require_post_norm: bool | None = None,
351 prefix: str = "",
351 -) -> Union[CLIPVisionModel, SiglipVisionModel]:
352 +) -> CLIPVisionModel | SiglipVisionModel:
353 vision_config = hf_config.vision_config
354
355 feature_layers = hf_config.vision_feature_layer
@@ -407,7 +408,7 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
408 }
409
410 @classmethod
410 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
411 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
412 if modality.startswith("image"):
413 return "<image>"
414
@@ -456,7 +457,7 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
457
458 def _parse_and_validate_image_input(
459 self, **kwargs: object
459 - ) -> Optional[TarsierImageInputs]:
460 + ) -> TarsierImageInputs | None:
461 pixel_values = kwargs.pop("pixel_values", None)
462 image_embeds = kwargs.pop("image_embeds", None)
463
@@ -479,9 +480,9 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
480
481 def _image_pixels_to_features(
482 self,
482 - vision_tower: Union[CLIPVisionModel, SiglipVisionModel],
483 - pixel_values: Union[torch.Tensor, list[torch.Tensor]],
484 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
483 + vision_tower: CLIPVisionModel | SiglipVisionModel,
484 + pixel_values: torch.Tensor | list[torch.Tensor],
485 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
486 # From vLLM LLaVA, vision tower output handling
487 return vision_tower(
488 pixel_values,
@@ -540,7 +541,7 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
541 def _process_image_pixels(
542 self,
543 inputs: TarsierImagePixelInputs,
543 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
544 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
545 assert self.vision_tower is not None
546 pixel_values = inputs["pixel_values"]
547 image_features_selected = self._image_pixels_to_features(
@@ -559,7 +560,7 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
560 def _process_image_input(
561 self,
562 image_input: TarsierImageInputs,
562 - ) -> Union[torch.Tensor, tuple[torch.Tensor, ...]]:
563 + ) -> torch.Tensor | tuple[torch.Tensor, ...]:
564 if image_input["type"] == "image_embeds":
565 projected_features = image_input["data"]
566 if isinstance(projected_features, torch.Tensor):
@@ -585,10 +586,10 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
586 self,
587 input_ids: torch.Tensor,
588 positions: torch.Tensor,
588 - intermediate_tensors: Optional[IntermediateTensors] = None,
589 - inputs_embeds: Optional[torch.Tensor] = None,
589 + intermediate_tensors: IntermediateTensors | None = None,
590 + inputs_embeds: torch.Tensor | None = None,
591 **kwargs: object,
591 - ) -> Union[torch.Tensor, IntermediateTensors]:
592 + ) -> torch.Tensor | IntermediateTensors:
593 if intermediate_tensors is not None:
594 inputs_embeds = None
595 elif inputs_embeds is None:
@@ -610,7 +611,7 @@ class TarsierForConditionalGeneration(nn.Module, SupportsMultiModal, SupportsPP)
611 def compute_logits(
612 self,
613 hidden_states: torch.Tensor,
613 - ) -> Optional[torch.Tensor]:
614 + ) -> torch.Tensor | None:
615 return self.language_model.compute_logits(hidden_states)
616
617 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
vllm/model_executor/models/terratorch.py
+16 -16
@@ -18,8 +18,8 @@
18 """Wrapper around `Terratorch` models"""
19
20 from collections import OrderedDict
21 -from collections.abc import Iterable, Mapping, Sequence
22 -from typing import Any, Callable, Optional, Union
21 +from collections.abc import Callable, Iterable, Mapping, Sequence
22 +from typing import Any
23
24 import torch
25 import torch.nn as nn
@@ -96,7 +96,7 @@ def _terratorch_field_factory(
96
97
98 class TerratorchProcessingInfo(BaseProcessingInfo):
99 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
99 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
100 return {"image": None}
101
102
@@ -114,7 +114,7 @@ class TerratorchInputBuilder(BaseDummyInputsBuilder[TerratorchProcessingInfo]):
114 self,
115 seq_len: int,
116 mm_counts: Mapping[str, int],
117 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
117 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
118 ) -> MultiModalDataDict:
119 # Dummy data is generated based on the 'input' section
120 # defined in the HF configuration file
@@ -136,8 +136,8 @@ class TerratorchMultiModalDataParser(MultiModalDataParser):
136
137 def _parse_image_data(
138 self,
139 - data: Union[dict[str, torch.Tensor], ModalityData[ImageItem]],
140 - ) -> Optional[ModalityDataItems[Any, Any]]:
139 + data: dict[str, torch.Tensor] | ModalityData[ImageItem],
140 + ) -> ModalityDataItems[Any, Any] | None:
141 if isinstance(data, dict):
142 terratorch_fields = _terratorch_field_names(self._pretrained_cfg)
143
@@ -157,7 +157,7 @@ class TerratorchMultiModalProcessor(BaseMultiModalProcessor):
157 info: TerratorchProcessingInfo,
158 dummy_inputs: "BaseDummyInputsBuilder[TerratorchProcessingInfo]",
159 *,
160 - cache: Optional[MultiModalProcessorOnlyCache] = None,
160 + cache: MultiModalProcessorOnlyCache | None = None,
161 ) -> None:
162 self.pretrained_cfg = info.get_hf_config().to_dict()["pretrained_cfg"]
163 super().__init__(info=info, dummy_inputs=dummy_inputs, cache=cache)
@@ -182,11 +182,11 @@ class TerratorchMultiModalProcessor(BaseMultiModalProcessor):
182
183 def apply(
184 self,
185 - prompt: Union[str, list[int]],
185 + prompt: str | list[int],
186 mm_data: MultiModalDataDict,
187 hf_processor_mm_kwargs: Mapping[str, object],
188 - tokenization_kwargs: Optional[Mapping[str, object]] = None,
189 - mm_uuids: Optional[MultiModalUUIDDict] = None,
188 + tokenization_kwargs: Mapping[str, object] | None = None,
189 + mm_uuids: MultiModalUUIDDict | None = None,
190 ) -> MultiModalInputs:
191 if "image" in mm_data:
192 image_data = mm_data["image"]
@@ -232,7 +232,7 @@ class Terratorch(nn.Module, IsAttentionFree, SupportsMultiModal):
232 is_pooling_model = True
233
234 @classmethod
235 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
235 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
236 if modality.startswith("image"):
237 return None
238
@@ -256,9 +256,9 @@ class Terratorch(nn.Module, IsAttentionFree, SupportsMultiModal):
256 def get_input_embeddings(
257 self,
258 input_ids: torch.Tensor,
259 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
259 + multimodal_embeddings: MultiModalEmbeddings | None = None,
260 *,
261 - is_multimodal: Optional[torch.Tensor] = None,
261 + is_multimodal: torch.Tensor | None = None,
262 handle_oov_mm_token: bool = False,
263 ) -> torch.Tensor:
264 # We do not really use any input tokens and therefore no embeddings
@@ -269,10 +269,10 @@ class Terratorch(nn.Module, IsAttentionFree, SupportsMultiModal):
269
270 def forward(
271 self,
272 - input_ids: Optional[torch.Tensor],
272 + input_ids: torch.Tensor | None,
273 positions: torch.Tensor,
274 - intermediate_tensors: Optional[IntermediateTensors] = None,
275 - inputs_embeds: Optional[torch.Tensor] = None,
274 + intermediate_tensors: IntermediateTensors | None = None,
275 + inputs_embeds: torch.Tensor | None = None,
276 **kwargs: object,
277 ):
278 model_output = self.inference_runner.forward(**kwargs)
vllm/model_executor/models/transformers.py
+23 -23
@@ -19,7 +19,7 @@
19 from collections.abc import Iterable, Mapping
20 from contextlib import contextmanager
21 from pathlib import Path
22 -from typing import Literal, Optional, Union
22 +from typing import Literal
23
24 import regex as re
25 import torch
@@ -103,9 +103,9 @@ def vllm_flash_attention_forward(
103 value: torch.Tensor,
104 attention_mask: torch.Tensor,
105 # Transformers kwargs
106 - scaling: Optional[float] = None,
106 + scaling: float | None = None,
107 # vLLM kwargs
108 - attention_instances: Optional[dict[Attention]] = None,
108 + attention_instances: dict[Attention] | None = None,
109 **kwargs,
110 ):
111 self_attn = attention_instances[module.layer_idx]
@@ -147,10 +147,10 @@ Style = Literal["colwise", "colwise_rep", "rowwise", "rowwise_rep", "replicate"]
147 def replace_linear_class(
148 linear: nn.Linear,
149 style: Style = "replicate",
150 - quant_config: Optional[QuantizationConfig] = None,
150 + quant_config: QuantizationConfig | None = None,
151 *,
152 prefix: str = "",
153 -) -> Union[ColumnParallelLinear, RowParallelLinear, ReplicatedLinear]:
153 +) -> ColumnParallelLinear | RowParallelLinear | ReplicatedLinear:
154 """
155 Replace nn.Linear with one of vLLM's tensor parallel linear classes.
156
@@ -312,7 +312,7 @@ class MultiModalDummyInputsBuilder(BaseDummyInputsBuilder[MultiModalProcessingIn
312 self,
313 seq_len: int,
314 mm_counts: Mapping[str, int],
315 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
315 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
316 ) -> MultiModalDataDict:
317 num_images = mm_counts.get("image", 0)
318
@@ -388,11 +388,11 @@ class MultiModalProcessor(BaseMultiModalProcessor[MultiModalProcessingInfo]):
388
389 def apply(
390 self,
391 - prompt: Union[str, list[int]],
391 + prompt: str | list[int],
392 mm_data: MultiModalDataDict,
393 hf_processor_mm_kwargs: Mapping[str, object],
394 - tokenization_kwargs: Optional[Mapping[str, object]] = None,
395 - mm_uuids: Optional[MultiModalUUIDDict] = None,
394 + tokenization_kwargs: Mapping[str, object] | None = None,
395 + mm_uuids: MultiModalUUIDDict | None = None,
396 ) -> MultiModalInputs:
397 """
398 Process multi-modal inputs to be used in vLLM.
@@ -498,7 +498,7 @@ class TransformersBase(nn.Module, SupportsQuant, SupportsLoRA, SupportsPP):
498 self.device_config: DeviceConfig = vllm_config.device_config
499 self.model_config: ModelConfig = vllm_config.model_config
500 self.parallel_config: ParallelConfig = vllm_config.parallel_config
501 - self.quant_config: Optional[QuantizationConfig] = vllm_config.quant_config
501 + self.quant_config: QuantizationConfig | None = vllm_config.quant_config
502
503 self.pp_group = get_pp_group()
504 self.tp_group = get_tp_group()
@@ -714,7 +714,7 @@ class TransformersBase(nn.Module, SupportsQuant, SupportsLoRA, SupportsPP):
714 )
715 return attention_instances
716
717 - def init_parameters(self, module: nn.Module, dtype: Optional[torch.dtype] = None):
717 + def init_parameters(self, module: nn.Module, dtype: torch.dtype | None = None):
718 """
719 If a `parameter` is on the `meta` device, then its parent
720 `module` is the original module created by:
@@ -725,7 +725,7 @@ class TransformersBase(nn.Module, SupportsQuant, SupportsLoRA, SupportsPP):
725 ```
726 """
727
728 - def _init_parameters(module: nn.Module, dtype: Optional[torch.dtype]):
728 + def _init_parameters(module: nn.Module, dtype: torch.dtype | None):
729 for name, param in module.named_parameters(recurse=False):
730 if param.device == torch.device("meta"):
731 new_param = nn.Parameter(
@@ -743,12 +743,12 @@ class TransformersBase(nn.Module, SupportsQuant, SupportsLoRA, SupportsPP):
743
744 def forward(
745 self,
746 - input_ids: Optional[torch.Tensor],
746 + input_ids: torch.Tensor | None,
747 positions: torch.Tensor,
748 - intermediate_tensors: Optional[IntermediateTensors] = None,
749 - inputs_embeds: Optional[torch.Tensor] = None,
748 + intermediate_tensors: IntermediateTensors | None = None,
749 + inputs_embeds: torch.Tensor | None = None,
750 **kwargs,
751 - ) -> Union[torch.Tensor, IntermediateTensors]:
751 + ) -> torch.Tensor | IntermediateTensors:
752 if not self.pp_group.is_first_rank:
753 assert intermediate_tensors is not None
754 input_ids = None
@@ -841,7 +841,7 @@ class TransformersForCausalLM(TransformersBase):
841 def compute_logits(
842 self,
843 hidden_states: torch.Tensor,
844 - ) -> Optional[torch.Tensor]:
844 + ) -> torch.Tensor | None:
845 logits = self.logits_processor(self.lm_head, hidden_states)
846 return logits
847
@@ -895,12 +895,12 @@ class TransformersForMultimodalLM(TransformersForCausalLM, SupportsMultiModal):
895
896 def forward(
897 self,
898 - input_ids: Optional[torch.Tensor],
898 + input_ids: torch.Tensor | None,
899 positions: torch.Tensor,
900 - intermediate_tensors: Optional[IntermediateTensors] = None,
901 - inputs_embeds: Optional[torch.Tensor] = None,
900 + intermediate_tensors: IntermediateTensors | None = None,
901 + inputs_embeds: torch.Tensor | None = None,
902 **kwargs: object,
903 - ) -> Union[torch.Tensor, IntermediateTensors]:
903 + ) -> torch.Tensor | IntermediateTensors:
904 # Gemma3 and PaliGemma needs `token_type_ids` to work correctly
905 # Other models will not have `token_type_ids` in kwargs
906 kwargs = {k: v for k, v in kwargs.items() if k == "token_type_ids"}
@@ -924,8 +924,8 @@ class TransformersForMultimodalLM(TransformersForCausalLM, SupportsMultiModal):
924 return LanguageModelWrapper(self)
925
926 def get_multimodal_embeddings(self, **kwargs):
927 - pixel_values: Optional[torch.Tensor] = kwargs.pop("pixel_values", None)
928 - image_embeds: Optional[torch.Tensor] = kwargs.pop("image_embeds", None)
927 + pixel_values: torch.Tensor | None = kwargs.pop("pixel_values", None)
928 + image_embeds: torch.Tensor | None = kwargs.pop("image_embeds", None)
929 # Model might use `image_patches` instead of `pixel_values`
930 if pixel_values is None:
931 pixel_values = kwargs.pop("image_patches", None)
vllm/model_executor/models/transformers_pooling.py
+4 -6
@@ -16,8 +16,6 @@
16 # limitations under the License.
17 """Wrapper around `transformers` models for pooling tasks."""
18
19 -from typing import Optional, Union
20 -
19 import torch
20 from transformers import AutoModelForSequenceClassification
21
@@ -109,11 +107,11 @@ class TransformersPoolingBase(TransformersBase, VllmModelForPooling):
107
108 def forward(
109 self,
112 - input_ids: Optional[torch.Tensor],
110 + input_ids: torch.Tensor | None,
111 positions: torch.Tensor,
114 - intermediate_tensors: Optional[IntermediateTensors] = None,
115 - inputs_embeds: Optional[torch.Tensor] = None,
116 - ) -> Union[torch.Tensor, IntermediateTensors]:
112 + intermediate_tensors: IntermediateTensors | None = None,
113 + inputs_embeds: torch.Tensor | None = None,
114 + ) -> torch.Tensor | IntermediateTensors:
115 if self.is_roberta:
116 # RoBERTa-specific positions padding
117 positions += self.padding_idx + 1
vllm/model_executor/models/ultravox.py
+19 -17
@@ -5,7 +5,7 @@
5 """PyTorch Ultravox model."""
6
7 from collections.abc import Iterable, Mapping, Sequence
8 -from typing import Annotated, Any, Literal, Optional, Union
8 +from typing import Annotated, Any, Literal, TypeAlias
9
10 import torch
11 from torch import nn
@@ -68,7 +68,7 @@ class UltravoxAudioFeatureInputs(TensorSchema):
68
69 type: Literal["audio_features"]
70 data: Annotated[
71 - Union[torch.Tensor, list[torch.Tensor], list[list[torch.Tensor]]],
71 + torch.Tensor | list[torch.Tensor] | list[list[torch.Tensor]],
72 TensorShape("bn", "nmb", "t"),
73 ]
74 lens: Annotated[torch.Tensor, TensorShape("bn")]
@@ -92,11 +92,13 @@ class UltravoxAudioEmbeddingInputs(TensorSchema):
92
93 type: Literal["audio_embeds"]
94 data: Annotated[
95 - Union[torch.Tensor, list[torch.Tensor]], TensorShape("b", "na", "afs", "hs")
95 + torch.Tensor | list[torch.Tensor], TensorShape("b", "na", "afs", "hs")
96 ]
97
98
99 -UltravoxAudioInputs = Union[UltravoxAudioFeatureInputs, UltravoxAudioEmbeddingInputs]
99 +UltravoxAudioInputs: TypeAlias = (
100 + UltravoxAudioFeatureInputs | UltravoxAudioEmbeddingInputs
101 +)
102
103
104 class UltravoxProcessingInfo(BaseProcessingInfo):
@@ -119,7 +121,7 @@ class UltravoxProcessingInfo(BaseProcessingInfo):
121 assert isinstance(feature_extractor, WhisperFeatureExtractor)
122 return feature_extractor
123
122 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
124 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
125 return {"audio": None}
126
127
@@ -133,7 +135,7 @@ class UltravoxDummyInputsBuilder(BaseDummyInputsBuilder[UltravoxProcessingInfo])
135 self,
136 seq_len: int,
137 mm_counts: Mapping[str, int],
136 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
138 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
139 ) -> MultiModalDataDict:
140 feature_extractor = self.info.get_feature_extractor()
141
@@ -346,7 +348,7 @@ class ModifiedWhisperEncoder(WhisperEncoder):
348 )
349
350 def get_attention_mask_by_audio_len(
349 - self, audio_lens: Optional[torch.Tensor], hidden_states: torch.Tensor
351 + self, audio_lens: torch.Tensor | None, hidden_states: torch.Tensor
352 ):
353 """
354 Create attention mask based on audio lengths to mask out padding tokens
@@ -376,7 +378,7 @@ class ModifiedWhisperEncoder(WhisperEncoder):
378 def forward(
379 self,
380 input_features: torch.Tensor,
379 - audio_lens: Optional[torch.Tensor] = None,
381 + audio_lens: torch.Tensor | None = None,
382 ):
383 expected_seq_length = self.max_context_length
384 if input_features.shape[-1] > expected_seq_length:
@@ -431,7 +433,7 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
433 )
434
435 @classmethod
434 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
436 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
437 if modality.startswith("audio"):
438 return "<|audio|>"
439
@@ -514,7 +516,7 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
516
517 def _parse_and_validate_audio_input(
518 self, **kwargs: object
517 - ) -> Optional[UltravoxAudioInputs]:
519 + ) -> UltravoxAudioInputs | None:
520 audio_features = kwargs.pop("audio_features", None)
521 audio_embeds = kwargs.pop("audio_embeds", None)
522 audio_lens = kwargs.pop("audio_lens", None)
@@ -541,7 +543,7 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
543 def _process_audio_input(
544 self,
545 audio_input: UltravoxAudioInputs,
544 - ) -> Union[NestedTensors, tuple[torch.Tensor, ...]]:
546 + ) -> NestedTensors | tuple[torch.Tensor, ...]:
547 if audio_input["type"] == "audio_embeds":
548 return audio_input["data"]
549
@@ -587,9 +589,9 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
589 def get_input_embeddings(
590 self,
591 input_ids: torch.Tensor,
590 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
592 + multimodal_embeddings: MultiModalEmbeddings | None = None,
593 *,
592 - is_multimodal: Optional[torch.Tensor] = None,
594 + is_multimodal: torch.Tensor | None = None,
595 # Multi-modal token ID may exceed vocab size
596 handle_oov_mm_token: bool = True,
597 ) -> torch.Tensor:
@@ -608,10 +610,10 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
610 self,
611 input_ids: torch.Tensor,
612 positions: torch.Tensor,
611 - intermediate_tensors: Optional[torch.Tensor] = None,
612 - inputs_embeds: Optional[torch.Tensor] = None,
613 + intermediate_tensors: torch.Tensor | None = None,
614 + inputs_embeds: torch.Tensor | None = None,
615 **kwargs,
614 - ) -> Union[torch.Tensor, IntermediateTensors]:
616 + ) -> torch.Tensor | IntermediateTensors:
617 """Run forward pass for Ultravox
618
619 One key thing to understand is the `input_ids` already accounts for the
@@ -651,7 +653,7 @@ class UltravoxModel(nn.Module, SupportsMultiModal, SupportsPP, SupportsLoRA):
653
654
655 def pad_and_concat_to_dim3(
654 - features: Union[torch.Tensor, list[torch.Tensor], list[list[torch.Tensor]]],
656 + features: torch.Tensor | list[torch.Tensor] | list[list[torch.Tensor]],
657 ) -> torch.Tensor:
658 """
659 Pad and concatenate a list of tensors.
vllm/model_executor/models/utils.py
+16 -16
@@ -4,7 +4,7 @@
4 import itertools
5 from collections.abc import Iterable, Mapping
6 from dataclasses import dataclass, field
7 -from typing import Any, Literal, Optional, Protocol, Union, overload
7 +from typing import Any, Literal, Protocol, overload
8
9 import torch
10 import torch.nn as nn
@@ -32,7 +32,7 @@ from vllm.utils import (
32
33 logger = init_logger(__name__)
34
35 -WeightsMapping = Mapping[str, Optional[str]]
35 +WeightsMapping = Mapping[str, str | None]
36 """If a key maps to a value of `None`, the corresponding weight is ignored."""
37
38
@@ -44,7 +44,7 @@ class WeightsMapper:
44 orig_to_new_prefix: WeightsMapping = field(default_factory=dict)
45 orig_to_new_suffix: WeightsMapping = field(default_factory=dict)
46
47 - def _map_name(self, key: str) -> Optional[str]:
47 + def _map_name(self, key: str) -> str | None:
48 for substr, new_key in self.orig_to_new_substr.items():
49 if substr in key:
50 if new_key is None:
@@ -120,10 +120,10 @@ class AutoWeightsLoader:
120 self,
121 module: nn.Module,
122 *,
123 - skip_prefixes: Optional[list[str]] = None,
124 - skip_substrs: Optional[list[str]] = None,
125 - ignore_unexpected_prefixes: Optional[list[str]] = None,
126 - ignore_unexpected_suffixes: Optional[list[str]] = None,
123 + skip_prefixes: list[str] | None = None,
124 + skip_substrs: list[str] | None = None,
125 + ignore_unexpected_prefixes: list[str] | None = None,
126 + ignore_unexpected_suffixes: list[str] | None = None,
127 ) -> None:
128 super().__init__()
129
@@ -306,7 +306,7 @@ class AutoWeightsLoader:
306 self,
307 weights: Iterable[tuple[str, torch.Tensor]],
308 *,
309 - mapper: Optional[WeightsMapper] = None,
309 + mapper: WeightsMapper | None = None,
310 ) -> set[str]:
311 if mapper is not None:
312 weights = mapper.apply(weights)
@@ -323,8 +323,8 @@ def init_vllm_registered_model(
323 vllm_config: VllmConfig,
324 *,
325 prefix: str = "",
326 - hf_config: Optional[PretrainedConfig] = None,
327 - architectures: Optional[list[str]] = None,
326 + hf_config: PretrainedConfig | None = None,
327 + architectures: list[str] | None = None,
328 ) -> nn.Module:
329 """
330 Helper function to initialize an inner model registered to vLLM,
@@ -352,7 +352,7 @@ def flatten_bn(x: list[torch.Tensor]) -> list[torch.Tensor]: ...
352
353 @overload
354 def flatten_bn(
355 - x: Union[list[torch.Tensor], torch.Tensor],
355 + x: list[torch.Tensor] | torch.Tensor,
356 *,
357 concat: Literal[True],
358 ) -> torch.Tensor: ...
@@ -360,17 +360,17 @@ def flatten_bn(
360
361 @overload
362 def flatten_bn(
363 - x: Union[list[torch.Tensor], torch.Tensor],
363 + x: list[torch.Tensor] | torch.Tensor,
364 *,
365 concat: bool = False,
366 -) -> Union[list[torch.Tensor], torch.Tensor]: ...
366 +) -> list[torch.Tensor] | torch.Tensor: ...
367
368
369 def flatten_bn(
370 - x: Union[list[torch.Tensor], torch.Tensor],
370 + x: list[torch.Tensor] | torch.Tensor,
371 *,
372 concat: bool = False,
373 -) -> Union[list[torch.Tensor], torch.Tensor]:
373 +) -> list[torch.Tensor] | torch.Tensor:
374 """
375 Flatten the ``B`` and ``N`` dimensions of batched multimodal inputs.
376
@@ -472,7 +472,7 @@ def merge_multimodal_embeddings(
472 input_ids: torch.Tensor,
473 inputs_embeds: torch.Tensor,
474 multimodal_embeddings: NestedTensors,
475 - placeholder_token_id: Union[int, list[int]],
475 + placeholder_token_id: int | list[int],
476 ) -> torch.Tensor:
477 """
478 Merge ``multimodal_embeddings`` into ``inputs_embeds`` by overwriting the
vllm/model_executor/models/vision.py
+13 -13
@@ -4,7 +4,8 @@
4 import itertools
5 import math
6 from abc import ABC, abstractmethod
7 -from typing import Callable, Final, Generic, Literal, Optional, Protocol, TypeVar, Union
7 +from collections.abc import Callable
8 +from typing import Final, Generic, Literal, Protocol, TypeAlias, TypeVar
9
10 import torch
11 from transformers import PretrainedConfig
@@ -84,7 +85,7 @@ def get_vit_attn_backend(head_size: int, dtype: torch.dtype) -> _Backend:
85 # Lazy import to avoid circular dependency
86 from vllm.attention.selector import get_env_variable_attn_backend
87
87 - selected_backend: Optional[_Backend] = get_env_variable_attn_backend()
88 + selected_backend: _Backend | None = get_env_variable_attn_backend()
89 if selected_backend is not None:
90 return selected_backend
91
@@ -93,14 +94,13 @@ def get_vit_attn_backend(head_size: int, dtype: torch.dtype) -> _Backend:
94
95 VisionFeatureSelectStrategyStr = Literal["class", "default", "full"]
96
96 -VisionFeatureSelectStrategy = Union[
97 - VisionFeatureSelectStrategyStr,
98 - Callable[[torch.Tensor], torch.Tensor],
99 -]
97 +VisionFeatureSelectStrategy: TypeAlias = (
98 + VisionFeatureSelectStrategyStr | Callable[[torch.Tensor], torch.Tensor]
99 +)
100
101
102 def _get_vision_feature_selector(
103 - strategy: Union[VisionFeatureSelectStrategy, str],
103 + strategy: VisionFeatureSelectStrategy | str,
104 ) -> Callable[[torch.Tensor], torch.Tensor]:
105 if callable(strategy):
106 return strategy
@@ -121,7 +121,7 @@ def _get_vision_feature_selector(
121
122 def get_num_selected_vision_tokens(
123 num_vision_tokens: int,
124 - strategy: Union[VisionFeatureSelectStrategy, str],
124 + strategy: VisionFeatureSelectStrategy | str,
125 ) -> int:
126 if callable(strategy):
127 dummy_features = torch.empty(1, num_vision_tokens, 64) # [B, L, D]
@@ -141,12 +141,12 @@ def get_num_selected_vision_tokens(
141
142
143 def resolve_visual_encoder_outputs(
144 - encoder_outputs: Union[torch.Tensor, list[torch.Tensor]],
145 - post_layer_norm: Optional[torch.nn.LayerNorm],
144 + encoder_outputs: torch.Tensor | list[torch.Tensor],
145 + post_layer_norm: torch.nn.LayerNorm | None,
146 *,
147 - select_layers: Optional[list[int]] = None,
148 - max_possible_layers: Optional[int] = None,
149 - feature_select_strategy: Optional[VisionFeatureSelectStrategy] = None,
147 + select_layers: list[int] | None = None,
148 + max_possible_layers: int | None = None,
149 + feature_select_strategy: VisionFeatureSelectStrategy | None = None,
150 ) -> torch.Tensor:
151 """Given the outputs a visual encoder module that may correspond to the
152 output of the last layer, or a list of hidden states to be stacked,
vllm/model_executor/models/voxtral.py
+19 -19
@@ -5,7 +5,7 @@ import math
5 from collections.abc import Iterable, Mapping, Sequence
6 from functools import cached_property
7 from math import ceil
8 -from typing import Literal, Optional, Union, cast
8 +from typing import Literal, cast
9
10 import numpy as np
11 import regex as re
@@ -125,9 +125,9 @@ class VoxtralProcessorAdapter:
125
126 def __call__(
127 self,
128 - text: Optional[Union[TextInput, list[TextInput]]] = None,
129 - audios: Optional[Union[np.ndarray, list[np.ndarray]]] = None,
130 - return_tensors: Optional[Union[str, TensorType]] = None,
128 + text: TextInput | list[TextInput] | None = None,
129 + audios: np.ndarray | list[np.ndarray] | None = None,
130 + return_tensors: str | TensorType | None = None,
131 **kwargs,
132 ) -> Mapping[str, NestedTensors]:
133 if text is None:
@@ -188,7 +188,7 @@ class VoxtralProcessingInfo(BaseProcessingInfo):
188 def get_hf_processor(self) -> VoxtralProcessorAdapter:
189 return VoxtralProcessorAdapter(self.get_tokenizer())
190
191 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
191 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
192 return {"audio": 5} # Performance tends to degrade after 5
193
194 def get_mm_max_tokens_per_item(
@@ -216,7 +216,7 @@ class VoxtralDummyInputsBuilder(BaseDummyInputsBuilder[VoxtralProcessingInfo]):
216 self,
217 seq_len: int,
218 mm_counts: Mapping[str, int],
219 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
219 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
220 ) -> MultiModalDataDict:
221 num_audios = mm_counts.get("audio", 0)
222
@@ -234,7 +234,7 @@ class VoxtralDummyInputsBuilder(BaseDummyInputsBuilder[VoxtralProcessingInfo]):
234 self,
235 seq_len: int,
236 mm_counts: Mapping[str, int],
237 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
237 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
238 ) -> ProcessorInputs:
239 tokenizer = self.info.get_tokenizer()
240
@@ -303,11 +303,11 @@ class VoxtralMultiModalProcessor(BaseMultiModalProcessor[VoxtralProcessingInfo])
303
304 def _cached_apply_hf_processor(
305 self,
306 - prompt: Union[str, list[int]],
306 + prompt: str | list[int],
307 mm_data_items: MultiModalDataItems,
308 hf_processor_mm_kwargs: Mapping[str, object],
309 tokenization_kwargs: Mapping[str, object],
310 - mm_uuids: Optional[MultiModalUUIDDict] = None,
310 + mm_uuids: MultiModalUUIDDict | None = None,
311 ) -> tuple[list[int], MultiModalProcessingInfo, bool]:
312 prompt_ids, mm_info, _ = super()._cached_apply_hf_processor(
313 prompt=prompt,
@@ -386,10 +386,10 @@ class VoxtralForConditionalGeneration(
386 self,
387 input_ids: torch.Tensor,
388 positions: torch.Tensor,
389 - intermediate_tensors: Optional[IntermediateTensors] = None,
390 - inputs_embeds: Optional[torch.Tensor] = None,
389 + intermediate_tensors: IntermediateTensors | None = None,
390 + inputs_embeds: torch.Tensor | None = None,
391 **kwargs: object,
392 - ) -> Union[torch.Tensor, IntermediateTensors]:
392 + ) -> torch.Tensor | IntermediateTensors:
393 if intermediate_tensors is not None:
394 inputs_embeds = None
395
@@ -401,7 +401,7 @@ class VoxtralForConditionalGeneration(
401
402 def get_multimodal_embeddings(
403 self, **kwargs
404 - ) -> Union[list[torch.Tensor], torch.Tensor, tuple[torch.Tensor, ...], None]:
404 + ) -> list[torch.Tensor] | torch.Tensor | tuple[torch.Tensor, ...] | None:
405 audio_inputs = self._parse_and_validate_audio_arrays(**kwargs)
406 if audio_inputs is None:
407 return None
@@ -433,7 +433,7 @@ class VoxtralForConditionalGeneration(
433
434 def _parse_and_validate_audio_arrays(
435 self, **kwargs: object
436 - ) -> Union[list[torch.Tensor], None]:
436 + ) -> list[torch.Tensor] | None:
437 audio_arrays = kwargs.pop("audio_arrays", None)
438 if audio_arrays is None:
439 return None
@@ -450,7 +450,7 @@ class VoxtralForConditionalGeneration(
450 def compute_logits(
451 self,
452 hidden_states: torch.Tensor,
453 - ) -> Optional[torch.Tensor]:
453 + ) -> torch.Tensor | None:
454 return self.language_model.compute_logits(hidden_states)
455
456 @classmethod
@@ -475,10 +475,10 @@ class VoxtralForConditionalGeneration(
475 audio: np.ndarray,
476 model_config: ModelConfig,
477 stt_config: SpeechToTextConfig,
478 - language: Optional[str],
478 + language: str | None,
479 task_type: Literal["transcribe", "translate"],
480 request_prompt: str,
481 - to_language: Optional[str],
481 + to_language: str | None,
482 ) -> PromptType:
483 tokenizer = cached_tokenizer_from_config(model_config)
484 audio = Audio(audio, int(stt_config.sample_rate), format="wav") # lossless
@@ -500,7 +500,7 @@ class VoxtralForConditionalGeneration(
500 audio_duration_s: float,
501 stt_config: SpeechToTextConfig,
502 model_config: ModelConfig,
503 - ) -> Optional[int]:
503 + ) -> int | None:
504 """
505 Map from audio duration to number of audio tokens produced by the ASR
506 model, without running a forward pass.
@@ -793,7 +793,7 @@ class VoxtralEncoderModel(nn.Module):
793 return torch.stack(chunked_features), chunks_per_example
794
795 def forward(
796 - self, input_features: Union[torch.Tensor, list[torch.Tensor]]
796 + self, input_features: torch.Tensor | list[torch.Tensor]
797 ) -> list[torch.Tensor]:
798 if not isinstance(input_features, list):
799 input_features = [input_features]
vllm/model_executor/models/whisper.py
+28 -28
@@ -4,7 +4,7 @@
4 import math
5 from collections.abc import Iterable, Mapping, Sequence
6 from contextlib import nullcontext
7 -from typing import Annotated, Literal, Optional, Union, cast
7 +from typing import Annotated, Literal, cast
8
9 import numpy as np
10 import torch
@@ -137,7 +137,7 @@ class WhisperAudioInputs(TensorSchema):
137 """
138
139 input_features: Annotated[
140 - Optional[list[torch.Tensor]],
140 + list[torch.Tensor] | None,
141 TensorShape("b", "nmb", "t"),
142 ]
143
@@ -185,8 +185,8 @@ class WhisperAttention(nn.Module):
185 num_heads: int,
186 bias: bool = True,
187 attn_type: AttentionType = AttentionType.DECODER,
188 - cache_config: Optional[CacheConfig] = None,
189 - quant_config: Optional[QuantizationConfig] = None,
188 + cache_config: CacheConfig | None = None,
189 + quant_config: QuantizationConfig | None = None,
190 prefix: str = "",
191 ):
192 super().__init__()
@@ -258,7 +258,7 @@ class WhisperAttention(nn.Module):
258 self,
259 embed_dim: int,
260 bias: bool = True,
261 - quant_config: Optional[QuantizationConfig] = None,
261 + quant_config: QuantizationConfig | None = None,
262 prefix: str = "",
263 ) -> None:
264 self.qkv_proj = QKVParallelLinear(
@@ -291,8 +291,8 @@ class WhisperCrossAttention(WhisperAttention):
291 embed_dim: int,
292 num_heads: int,
293 bias: bool = True,
294 - cache_config: Optional[CacheConfig] = None,
295 - quant_config: Optional[QuantizationConfig] = None,
294 + cache_config: CacheConfig | None = None,
295 + quant_config: QuantizationConfig | None = None,
296 prefix: str = "",
297 ):
298 super().__init__(
@@ -309,7 +309,7 @@ class WhisperCrossAttention(WhisperAttention):
309 self,
310 embed_dim: int,
311 bias: bool = True,
312 - quant_config: Optional[QuantizationConfig] = None,
312 + quant_config: QuantizationConfig | None = None,
313 prefix: str = "",
314 ) -> None:
315 self.q_proj = ColumnParallelLinear(
@@ -332,7 +332,7 @@ class WhisperCrossAttention(WhisperAttention):
332 def forward(
333 self,
334 hidden_states: torch.Tensor,
335 - encoder_hidden_states: Optional[torch.Tensor],
335 + encoder_hidden_states: torch.Tensor | None,
336 ):
337 q, _ = self.q_proj(hidden_states)
338
@@ -357,7 +357,7 @@ class WhisperMLP(nn.Module):
357 embed_dim: int,
358 ffn_dim: int,
359 act_fn: str,
360 - quant_config: Optional[QuantizationConfig] = None,
360 + quant_config: QuantizationConfig | None = None,
361 prefix: str = "",
362 ):
363 super().__init__()
@@ -463,7 +463,7 @@ class WhisperDecoderLayer(nn.Module):
463 def forward(
464 self,
465 hidden_states: torch.Tensor,
466 - encoder_hidden_states: Optional[torch.Tensor],
466 + encoder_hidden_states: torch.Tensor | None,
467 ):
468 residual = hidden_states
469 hidden_states = self.self_attn_layer_norm(hidden_states)
@@ -521,7 +521,7 @@ class WhisperEncoder(nn.Module):
521 sinusoids(*self.embed_positions.weight.shape)
522 )
523
524 - def forward(self, input_features: Union[torch.Tensor, list[torch.Tensor]]):
524 + def forward(self, input_features: torch.Tensor | list[torch.Tensor]):
525 hidden_states = []
526 for features in input_features:
527 embeds = nn.functional.gelu(self.conv1(features))
@@ -569,7 +569,7 @@ class WhisperDecoder(nn.Module):
569 self,
570 input_ids,
571 positions: torch.Tensor,
572 - encoder_hidden_states: Optional[torch.Tensor],
572 + encoder_hidden_states: torch.Tensor | None,
573 ):
574 inputs_embeds = self.get_input_embeddings(input_ids)
575 positions = self.embed_positions(positions)
@@ -600,8 +600,8 @@ class WhisperModel(nn.Module):
600
601 def forward(
602 self,
603 - input_features: Optional[Union[torch.Tensor, list[torch.Tensor]]],
604 - input_ids: Optional[torch.Tensor],
603 + input_features: torch.Tensor | list[torch.Tensor] | None,
604 + input_ids: torch.Tensor | None,
605 positions: torch.Tensor,
606 ) -> torch.Tensor:
607 encoder_outputs = self.get_encoder_outputs(input_features)
@@ -614,8 +614,8 @@ class WhisperModel(nn.Module):
614
615 def get_encoder_outputs(
616 self,
617 - input_features: Optional[Union[torch.Tensor, list[torch.Tensor]]],
618 - ) -> Optional[torch.Tensor]:
617 + input_features: torch.Tensor | list[torch.Tensor] | None,
618 + ) -> torch.Tensor | None:
619 if input_features is None:
620 return None
621 return self.encoder(input_features)
@@ -670,7 +670,7 @@ class WhisperProcessingInfo(BaseProcessingInfo):
670 processor_class.tokenizer_class = tokenizer_class
671 return self.ctx.get_hf_processor(processor_class, **kwargs)
672
673 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
673 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
674 return {"audio": 1}
675
676 def get_feature_extractor(self, **kwargs: object) -> WhisperFeatureExtractor:
@@ -693,7 +693,7 @@ class WhisperDummyInputsBuilder(BaseDummyInputsBuilder[WhisperProcessingInfo]):
693 self,
694 seq_len: int,
695 mm_counts: Mapping[str, int],
696 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
696 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
697 ) -> MultiModalDataDict:
698 feature_extractor = self.info.get_feature_extractor()
699
@@ -721,9 +721,9 @@ class WhisperMultiModalProcessor(EncDecMultiModalProcessor[WhisperProcessingInfo
721
722 def create_encoder_prompt(
723 self,
724 - prompt: Union[str, list[int]],
724 + prompt: str | list[int],
725 mm_data: MultiModalDataDict,
726 - ) -> Union[str, list[int]]:
726 + ) -> str | list[int]:
727 # Strictly speaking, whisper encoder only accept audio features.
728 # We create a dummy encoder prompt here which will be padded to
729 # num_audio_tokens. So that we can create dummy data from this
@@ -804,7 +804,7 @@ class WhisperForConditionalGeneration(
804 supported_languages = ISO639_1_SUPPORTED_LANGS
805
806 @classmethod
807 - def validate_language(cls, language: Optional[str]) -> Optional[str]:
807 + def validate_language(cls, language: str | None) -> str | None:
808 if language is None:
809 # TODO language should be optional and can be guessed.
810 # For now we default to en. See
@@ -823,10 +823,10 @@ class WhisperForConditionalGeneration(
823 audio: np.ndarray,
824 model_config: ModelConfig, # not needed here
825 stt_config: SpeechToTextConfig,
826 - language: Optional[str],
826 + language: str | None,
827 task_type: Literal["transcribe", "translate"],
828 request_prompt: str,
829 - to_language: Optional[str],
829 + to_language: str | None,
830 ) -> PromptType:
831 if language is None:
832 raise ValueError(
@@ -849,7 +849,7 @@ class WhisperForConditionalGeneration(
849 return cast(PromptType, prompt)
850
851 @classmethod
852 - def get_placeholder_str(cls, modality: str, i: int) -> Optional[str]:
852 + def get_placeholder_str(cls, modality: str, i: int) -> str | None:
853 if modality.startswith("audio"):
854 return None
855
@@ -872,7 +872,7 @@ class WhisperForConditionalGeneration(
872 audio_duration_s: float,
873 stt_config: SpeechToTextConfig,
874 model_config: ModelConfig,
875 - ) -> Optional[int]:
875 + ) -> int | None:
876 processor = cached_get_processor(model_config.model)
877 hop_length = processor.feature_extractor.hop_length
878 assert hop_length is not None
@@ -928,9 +928,9 @@ class WhisperForConditionalGeneration(
928 def get_input_embeddings(
929 self,
930 input_ids: torch.Tensor,
931 - multimodal_embeddings: Optional[MultiModalEmbeddings] = None,
931 + multimodal_embeddings: MultiModalEmbeddings | None = None,
932 *,
933 - is_multimodal: Optional[torch.Tensor] = None,
933 + is_multimodal: torch.Tensor | None = None,
934 handle_oov_mm_token: bool = False,
935 ) -> torch.Tensor:
936 # This method just returns the decoder sequence embeddings since
vllm/model_executor/models/zamba2.py
+21 -21
@@ -10,7 +10,7 @@ model alternates between state space model layers and attention-based layers.
10
11 from collections.abc import Iterable
12 from itertools import cycle
13 -from typing import Any, Optional, Union
13 +from typing import Any
14
15 import torch
16 from torch import nn
@@ -60,8 +60,8 @@ class Zamba2LoRA(nn.Module):
60 self,
61 input_dim: int,
62 rank: int,
63 - output_dim: Union[int, list[int]],
64 - quant_config: Optional[QuantizationConfig] = None,
63 + output_dim: int | list[int],
64 + quant_config: QuantizationConfig | None = None,
65 prefix: str = "",
66 ):
67 """Initialize the attention layer.
@@ -106,8 +106,8 @@ class Zamba2Attention(nn.Module):
106 config: Zamba2Config,
107 bare_block_idx: int,
108 num_hybrid_layers: int,
109 - cache_config: Optional[CacheConfig] = None,
110 - quant_config: Optional[QuantizationConfig] = None,
109 + cache_config: CacheConfig | None = None,
110 + quant_config: QuantizationConfig | None = None,
111 prefix: str = "",
112 ) -> None:
113 """Initialize the attention layer.
@@ -288,7 +288,7 @@ class Zamba2MLP(nn.Module):
288 config: Zamba2Config,
289 bare_block_idx: int,
290 num_hybrid_layers: dict[int, int],
291 - quant_config: Optional[QuantizationConfig] = None,
291 + quant_config: QuantizationConfig | None = None,
292 prefix: str = "",
293 ) -> None:
294 """Initialize the MLP layer.
@@ -386,8 +386,8 @@ class Zamba2AttentionDecoderLayer(nn.Module):
386 config: Zamba2Config,
387 bare_block_idx: int,
388 num_hybrid_layers: int,
389 - cache_config: Optional[CacheConfig] = None,
390 - quant_config: Optional[QuantizationConfig] = None,
389 + cache_config: CacheConfig | None = None,
390 + quant_config: QuantizationConfig | None = None,
391 prefix: str = "",
392 ) -> None:
393 """Initialize the decoder layer.
@@ -484,9 +484,9 @@ class Zamba2MambaDecoderLayer(nn.Module):
484 def __init__(
485 self,
486 config: Zamba2Config,
487 - model_config: Optional[ModelConfig] = None,
488 - cache_config: Optional[CacheConfig] = None,
489 - quant_config: Optional[QuantizationConfig] = None,
487 + model_config: ModelConfig | None = None,
488 + cache_config: CacheConfig | None = None,
489 + quant_config: QuantizationConfig | None = None,
490 prefix: str = "",
491 ) -> None:
492 """Initialize the Mamba decoder layer.
@@ -523,9 +523,9 @@ class Zamba2MambaDecoderLayer(nn.Module):
523 def forward(
524 self,
525 hidden_states: torch.Tensor,
526 - transformer_hidden_states: Optional[torch.Tensor] = None,
527 - positions: Optional[torch.Tensor] = None,
528 - original_hidden_states: Optional[torch.Tensor] = None,
526 + transformer_hidden_states: torch.Tensor | None = None,
527 + positions: torch.Tensor | None = None,
528 + original_hidden_states: torch.Tensor | None = None,
529 ) -> torch.Tensor:
530 """Forward pass through the Mamba decoder layer.
531
@@ -581,9 +581,9 @@ class Zamba2HybridLayer(nn.Module):
581 shared_transformer: Zamba2AttentionDecoderLayer,
582 config: Zamba2Config,
583 block_idx: int,
584 - model_config: Optional[ModelConfig] = None,
585 - cache_config: Optional[CacheConfig] = None,
586 - quant_config: Optional[QuantizationConfig] = None,
584 + model_config: ModelConfig | None = None,
585 + cache_config: CacheConfig | None = None,
586 + quant_config: QuantizationConfig | None = None,
587 prefix: str = "",
588 ) -> None:
589 """Initialize the hybrid layer.
@@ -764,8 +764,8 @@ class Zamba2Model(nn.Module):
764 self,
765 input_ids: torch.Tensor,
766 positions: torch.Tensor,
767 - inputs_embeds: Optional[torch.Tensor] = None,
768 - ) -> Union[torch.Tensor, IntermediateTensors]:
767 + inputs_embeds: torch.Tensor | None = None,
768 + ) -> torch.Tensor | IntermediateTensors:
769 """Forward pass through the model.
770
771 Args:
@@ -947,7 +947,7 @@ class Zamba2ForCausalLM(nn.Module, HasInnerState, IsHybrid):
947 self,
948 input_ids: torch.Tensor,
949 positions: torch.Tensor,
950 - inputs_embeds: Optional[torch.Tensor] = None,
950 + inputs_embeds: torch.Tensor | None = None,
951 **kwargs: Any,
952 ) -> torch.Tensor:
953 """Forward pass through the model.
@@ -973,7 +973,7 @@ class Zamba2ForCausalLM(nn.Module, HasInnerState, IsHybrid):
973 def compute_logits(
974 self,
975 hidden_states: torch.Tensor,
976 - ) -> Optional[torch.Tensor]:
976 + ) -> torch.Tensor | None:
977 """Compute logits for next token prediction.
978
979 Args:
vllm/model_executor/parameter.py
+12 -13
@@ -1,9 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from collections.abc import Hashable
4 +from collections.abc import Callable, Hashable
5 from fractions import Fraction
6 -from typing import Callable, Optional, Union
6 from weakref import WeakValueDictionary
7
8 import torch
@@ -36,7 +35,7 @@ class BasevLLMParameter(Parameter):
35 into the parameter when the provided weight loader is called.
36 """
37
39 - def __new__(cls, data: Optional[torch.Tensor], **kwargs):
38 + def __new__(cls, data: torch.Tensor | None, **kwargs):
39 return super().__new__(cls, data=data, requires_grad=False)
40
41 def __init__(self, data: torch.Tensor, weight_loader: Callable):
@@ -109,7 +108,7 @@ class BasevLLMParameter(Parameter):
108 def load_qkv_weight(self, loaded_weight: torch.Tensor, **kwargs):
109 self._assert_and_load(loaded_weight)
110
112 - def _shard_id_as_int(self, shard_id: Union[str, int]) -> int:
111 + def _shard_id_as_int(self, shard_id: str | int) -> int:
112 if isinstance(shard_id, int):
113 return shard_id
114
@@ -290,7 +289,7 @@ class PerTensorScaleParameter(BasevLLMParameter):
289 super().load_row_parallel_weight(*args, **kwargs)
290
291 def _load_into_shard_id(
293 - self, loaded_weight: torch.Tensor, shard_id: Union[str, int], **kwargs
292 + self, loaded_weight: torch.Tensor, shard_id: str | int, **kwargs
293 ):
294 """
295 Slice the parameter data based on the shard id for
@@ -320,10 +319,10 @@ class PackedColumnParameter(_ColumnvLLMParameter):
319
320 def __init__(
321 self,
323 - packed_factor: Union[int, Fraction],
322 + packed_factor: int | Fraction,
323 packed_dim: int,
325 - marlin_tile_size: Optional[int] = None,
326 - bitblas_tile_size: Optional[int] = None,
324 + marlin_tile_size: int | None = None,
325 + bitblas_tile_size: int | None = None,
326 **kwargs,
327 ):
328 self._packed_factor = packed_factor
@@ -371,10 +370,10 @@ class PackedvLLMParameter(ModelWeightParameter):
370
371 def __init__(
372 self,
374 - packed_factor: Union[int, Fraction],
373 + packed_factor: int | Fraction,
374 packed_dim: int,
376 - marlin_tile_size: Optional[int] = None,
377 - bitblas_tile_size: Optional[int] = None,
375 + marlin_tile_size: int | None = None,
376 + bitblas_tile_size: int | None = None,
377 **kwargs,
378 ):
379 self._packed_factor = packed_factor
@@ -437,7 +436,7 @@ class SharedWeightParameter(BasevLLMParameter):
436 local_tensors: set[torch.Tensor]
437
438 # dictionary mapping partition indices to associated parameters
440 - partitions: dict[int, Union[ModelWeightParameter, Parameter]]
439 + partitions: dict[int, ModelWeightParameter | Parameter]
440
441 def __new__(cls, **kwargs):
442 return super().__new__(cls, data=None, **kwargs)
@@ -547,7 +546,7 @@ class SharedWeightParameter(BasevLLMParameter):
546 self,
547 param: BasevLLMParameter,
548 loaded_weight: torch.Tensor,
550 - loaded_weight_shard_id: Optional[Union[str, int]],
549 + loaded_weight_shard_id: str | int | None,
550 ):
551 raise ValueError(
552 "When loading partition weights of "
vllm/model_executor/utils.py
+2 -2
@@ -3,7 +3,7 @@
3 """Utils for model executor."""
4
5 import copy
6 -from typing import Any, Optional
6 +from typing import Any
7
8 import torch
9
@@ -16,7 +16,7 @@ def set_random_seed(seed: int) -> None:
16
17 def set_weight_attrs(
18 weight: torch.Tensor,
19 - weight_attrs: Optional[dict[str, Any]],
19 + weight_attrs: dict[str, Any] | None,
20 ):
21 """Set attributes on a weight tensor.
22
vllm/multimodal/audio.py
+2 -2
@@ -3,7 +3,7 @@
3 import base64
4 from io import BytesIO
5 from pathlib import Path
6 -from typing import Literal, Optional
6 +from typing import Literal
7
8 import numpy as np
9 import numpy.typing as npt
@@ -53,7 +53,7 @@ class AudioResampler:
53
54 def __init__(
55 self,
56 - target_sr: Optional[float] = None,
56 + target_sr: float | None = None,
57 method: Literal["librosa", "scipy"] = "librosa",
58 ):
59 self.target_sr = target_sr
vllm/multimodal/cache.py
+20 -20
@@ -5,10 +5,10 @@ import sys
5 from abc import ABC, abstractmethod
6 from collections.abc import Mapping, Sequence
7 from multiprocessing.synchronize import Lock as LockType
8 -from typing import TYPE_CHECKING, Generic, Optional, TypeVar, Union, cast
8 +from typing import TYPE_CHECKING, Generic, TypeAlias, TypeVar, cast
9
10 import torch
11 -from typing_extensions import TypeAlias, override
11 +from typing_extensions import override
12
13 from vllm.distributed.device_communicators.shm_object_storage import (
14 MsgpackSerde,
@@ -85,14 +85,14 @@ class MultiModalProcessorCacheItemMetadata:
85 self.prompt_updates = prompt_updates
86
87
88 -MultiModalCacheValue = Union[
89 - MultiModalProcessorCacheItem,
90 - MultiModalProcessorCacheItemMetadata,
91 - MultiModalKwargsItems,
92 - MultiModalKwargsItem,
93 - MultiModalKwargs,
94 - Mapping[str, NestedTensors],
95 -]
88 +MultiModalCacheValue: TypeAlias = (
89 + MultiModalProcessorCacheItem
90 + | MultiModalProcessorCacheItemMetadata
91 + | MultiModalKwargsItems
92 + | MultiModalKwargsItem
93 + | MultiModalKwargs
94 + | Mapping[str, NestedTensors]
95 +)
96
97 _V = TypeVar("_V", bound=MultiModalCacheValue)
98
@@ -256,13 +256,13 @@ class BaseMultiModalCache(ABC, Generic[_I, _O]):
256 raise NotImplementedError
257
258
259 -MultiModalProcessorCacheInItem: TypeAlias = Optional[
260 - tuple[MultiModalKwargsItem, Sequence["ResolvedPromptUpdate"]]
261 -]
259 +MultiModalProcessorCacheInItem: TypeAlias = (
260 + tuple[MultiModalKwargsItem, Sequence["ResolvedPromptUpdate"]] | None
261 +)
262
263
264 MultiModalProcessorCacheOutItem: TypeAlias = tuple[
265 - Optional[MultiModalKwargsItem], Sequence["ResolvedPromptUpdate"]
265 + MultiModalKwargsItem | None, Sequence["ResolvedPromptUpdate"]
266 ]
267
268
@@ -575,7 +575,7 @@ def _enable_mm_input_shm_cache(vllm_config: "VllmConfig") -> bool:
575 def processor_cache_from_config(
576 vllm_config: "VllmConfig",
577 mm_registry: "MultiModalRegistry",
578 -) -> Optional[BaseMultiModalProcessorCache]:
578 +) -> BaseMultiModalProcessorCache | None:
579 """Return a `BaseMultiModalProcessorCache`, if enabled."""
580 model_config = vllm_config.model_config
581
@@ -602,7 +602,7 @@ def processor_only_cache_from_config(
602
603
604 class BaseMultiModalReceiverCache(
605 - BaseMultiModalCache[Optional[MultiModalKwargsItem], MultiModalKwargsItem]
605 + BaseMultiModalCache[MultiModalKwargsItem | None, MultiModalKwargsItem]
606 ):
607 """The required interface for caches on P1."""
608
@@ -640,7 +640,7 @@ class MultiModalReceiverCache(BaseMultiModalReceiverCache):
640 @override
641 def get_and_update_item(
642 self,
643 - mm_item: Optional[MultiModalKwargsItem],
643 + mm_item: MultiModalKwargsItem | None,
644 mm_hash: str,
645 ) -> MultiModalKwargsItem:
646 if (cached_item := self._cache.get(mm_hash)) is not None:
@@ -692,7 +692,7 @@ class ShmObjectStoreReceiverCache(BaseMultiModalReceiverCache):
692 @override
693 def get_and_update_item(
694 self,
695 - mm_item: Optional[MultiModalKwargsItem],
695 + mm_item: MultiModalKwargsItem | None,
696 mm_hash: str,
697 ) -> MultiModalKwargsItem:
698 assert mm_item is not None, f"Expected an address item for {mm_hash=}"
@@ -711,7 +711,7 @@ class ShmObjectStoreReceiverCache(BaseMultiModalReceiverCache):
711 def engine_receiver_cache_from_config(
712 vllm_config: "VllmConfig",
713 mm_registry: "MultiModalRegistry",
714 -) -> Optional[BaseMultiModalReceiverCache]:
714 +) -> BaseMultiModalReceiverCache | None:
715 """
716 This is used in the engine process.
717 Return a `BaseMultiModalReceiverCache` only when IPC caching is enabled and
@@ -735,7 +735,7 @@ def worker_receiver_cache_from_config(
735 vllm_config: "VllmConfig",
736 mm_registry: "MultiModalRegistry",
737 shared_worker_lock: LockType,
738 -) -> Optional[BaseMultiModalReceiverCache]:
738 +) -> BaseMultiModalReceiverCache | None:
739 """
740 This is used in the worker process.
741 Return a `BaseMultiModalReceiverCache` only when IPC caching is enabled and
vllm/multimodal/evs.py
+1 -2
@@ -9,7 +9,6 @@
9 # license agreement from NVIDIA CORPORATION is strictly prohibited.
10
11 import typing
12 -from typing import Union
12
13 import torch
14
@@ -38,7 +37,7 @@ def compute_retained_tokens_count(
37
38 def compute_retention_mask(
39 video_embeds: torch.Tensor,
41 - video_size_thw: Union[torch.LongTensor, tuple[int, int, int]],
40 + video_size_thw: torch.LongTensor | tuple[int, int, int],
41 spatial_merge_size: int,
42 q: float,
43 ) -> torch.Tensor:
vllm/multimodal/hasher.py
+2 -3
@@ -4,7 +4,6 @@
4 import pickle
5 import uuid
6 from collections.abc import Iterable
7 -from typing import Union
7
8 import numpy as np
9 import torch
@@ -18,7 +17,7 @@ logger = init_logger(__name__)
17
18 class MultiModalHasher:
19 @classmethod
21 - def serialize_item(cls, obj: object) -> Iterable[Union[bytes, memoryview]]:
20 + def serialize_item(cls, obj: object) -> Iterable[bytes | memoryview]:
21 # Simple cases
22 if isinstance(obj, (bytes, memoryview)):
23 return (obj,)
@@ -84,7 +83,7 @@ class MultiModalHasher:
83 cls,
84 key: str,
85 obj: object,
87 - ) -> Iterable[Union[bytes, memoryview]]:
86 + ) -> Iterable[bytes | memoryview]:
87 # Recursive cases
88 if isinstance(obj, (list, tuple)):
89 for i, elem in enumerate(obj):
vllm/multimodal/image.py
+1 -2
@@ -3,7 +3,6 @@
3
4 from io import BytesIO
5 from pathlib import Path
6 -from typing import Union
6
7 import pybase64
8 import torch
@@ -26,7 +25,7 @@ def rescale_image_size(
25
26 def rgba_to_rgb(
27 image: Image.Image,
29 - background_color: Union[tuple[int, int, int], list[int]] = (255, 255, 255),
28 + background_color: tuple[int, int, int] | list[int] = (255, 255, 255),
29 ) -> Image.Image:
30 """Convert an RGBA image to RGB with filled background color."""
31 assert image.mode == "RGBA"
vllm/multimodal/inputs.py
+21 -11
@@ -7,10 +7,20 @@ from collections.abc import Mapping, Sequence
7 from dataclasses import dataclass
8 from functools import partial
9 from itertools import accumulate
10 -from typing import TYPE_CHECKING, Any, Literal, Optional, TypedDict, Union, cast, final
10 +from typing import (
11 + TYPE_CHECKING,
12 + Any,
13 + Literal,
14 + Optional,
15 + TypeAlias,
16 + TypedDict,
17 + Union,
18 + cast,
19 + final,
20 +)
21
22 import numpy as np
13 -from typing_extensions import NotRequired, TypeAlias, TypeVar, deprecated
23 +from typing_extensions import NotRequired, TypeVar, deprecated
24
25 from vllm.utils import LazyLoader, full_groupby, is_list_of
26 from vllm.utils.jsontree import json_map_leaves
@@ -85,7 +95,7 @@ which are treated as audio embeddings;
95 these are directly passed to the model without HF processing.
96 """
97
88 -ModalityData: TypeAlias = Union[_T, list[Optional[_T]], None]
98 +ModalityData: TypeAlias = _T | list[_T | None] | None
99 """
100 Either a single data item, or a list of data items. Can only be None if UUID
101 is provided.
@@ -117,7 +127,7 @@ The built-in modalities are defined by
127 [`MultiModalDataBuiltins`][vllm.multimodal.inputs.MultiModalDataBuiltins].
128 """
129
120 -MultiModalUUIDDict: TypeAlias = Mapping[str, Union[list[Optional[str]], str]]
130 +MultiModalUUIDDict: TypeAlias = Mapping[str, list[str | None] | str]
131 """
132 A dictionary containing user-provided UUIDs for items in each modality.
133 If a UUID for an item is not provided, its entry will be `None` and
@@ -412,7 +422,7 @@ class MultiModalFlatField(BaseMultiModalField):
422 [`MultiModalFieldConfig.flat_from_sizes`][vllm.multimodal.inputs.MultiModalFieldConfig.flat_from_sizes]
423 """
424
415 - slices: Union[Sequence[slice], Sequence[Sequence[slice]]]
425 + slices: Sequence[slice] | Sequence[Sequence[slice]]
426 dim: int = 0
427
428 def build_elems(
@@ -524,7 +534,7 @@ class MultiModalFieldConfig:
534 @staticmethod
535 def flat(
536 modality: str,
527 - slices: Union[Sequence[slice], Sequence[Sequence[slice]]],
537 + slices: Sequence[slice] | Sequence[Sequence[slice]],
538 dim: int = 0,
539 ):
540 """
@@ -729,7 +739,7 @@ class MultiModalKwargsItem(UserDict[str, MultiModalFieldElem]):
739 _I = TypeVar(
740 "_I",
741 MultiModalKwargsItem,
732 - Optional[MultiModalKwargsItem],
742 + MultiModalKwargsItem | None,
743 default=MultiModalKwargsItem,
744 )
745
@@ -818,10 +828,10 @@ class MultiModalKwargsItems(UserDict[str, Sequence[_I]]):
828 )
829
830
821 -MultiModalKwargsOptionalItems: TypeAlias = Union[
822 - MultiModalKwargsItems[MultiModalKwargsItem],
823 - MultiModalKwargsItems[Optional[MultiModalKwargsItem]],
824 -]
831 +MultiModalKwargsOptionalItems: TypeAlias = (
832 + MultiModalKwargsItems[MultiModalKwargsItem]
833 + | MultiModalKwargsItems[MultiModalKwargsItem | None]
834 +)
835
836
837 class MultiModalKwargs(UserDict[str, NestedTensors]):
vllm/multimodal/parse.py
+22 -24
@@ -10,14 +10,14 @@ from typing import (
10 Generic,
11 Literal,
12 NamedTuple,
13 - Optional,
13 + TypeAlias,
14 + TypeGuard,
15 TypeVar,
15 - Union,
16 )
17
18 import numpy as np
19 import torch
20 -from typing_extensions import TypeAlias, TypeGuard, assert_never
20 +from typing_extensions import assert_never
21
22 from vllm.utils import LazyLoader, is_list_of
23
@@ -111,7 +111,7 @@ class ProcessorBatchItems(ModalityDataItems[Sequence[_T], _T]):
111
112
113 class EmbeddingItems(
114 - ModalityDataItems[Union[torch.Tensor, list[torch.Tensor]], torch.Tensor]
114 + ModalityDataItems[torch.Tensor | list[torch.Tensor], torch.Tensor]
115 ):
116 """
117 Base class for data items that are expressed as a batched embedding tensor,
@@ -195,7 +195,7 @@ class DictEmbeddingItems(
195
196
197 class AudioProcessorItems(ProcessorBatchItems[HfAudioItem]):
198 - def __init__(self, data: Optional[Sequence[HfAudioItem]]) -> None:
198 + def __init__(self, data: Sequence[HfAudioItem] | None) -> None:
199 if data is None:
200 data = [None]
201 super().__init__(data, "audio")
@@ -206,7 +206,7 @@ class AudioProcessorItems(ProcessorBatchItems[HfAudioItem]):
206
207
208 class AudioEmbeddingItems(EmbeddingItems):
209 - def __init__(self, data: Union[torch.Tensor, list[torch.Tensor]]) -> None:
209 + def __init__(self, data: torch.Tensor | list[torch.Tensor]) -> None:
210 super().__init__(data, "audio")
211
212
@@ -216,7 +216,7 @@ class ImageSize(NamedTuple):
216
217
218 class ImageProcessorItems(ProcessorBatchItems[HfImageItem]):
219 - def __init__(self, data: Optional[Sequence[HfImageItem]]) -> None:
219 + def __init__(self, data: Sequence[HfImageItem] | None) -> None:
220 if data is None:
221 data = [None]
222 super().__init__(data, "image")
@@ -234,17 +234,15 @@ class ImageProcessorItems(ProcessorBatchItems[HfImageItem]):
234
235
236 class ImageEmbeddingItems(EmbeddingItems):
237 - def __init__(self, data: Union[torch.Tensor, list[torch.Tensor]]) -> None:
237 + def __init__(self, data: torch.Tensor | list[torch.Tensor]) -> None:
238 super().__init__(data, "image")
239
240
241 class VideoProcessorItems(ProcessorBatchItems[HfVideoItem]):
242 def __init__(
243 self,
244 - data: Optional[Sequence[HfVideoItem]],
245 - metadata: Optional[
246 - Union[dict[str, Any], list[Optional[dict[str, Any]]]]
247 - ] = None,
244 + data: Sequence[HfVideoItem] | None,
245 + metadata: dict[str, Any] | list[dict[str, Any] | None] | None = None,
246 ) -> None:
247 if data is None:
248 data = [None]
@@ -267,7 +265,7 @@ class VideoProcessorItems(ProcessorBatchItems[HfVideoItem]):
265
266
267 class VideoEmbeddingItems(EmbeddingItems):
270 - def __init__(self, data: Union[torch.Tensor, list[torch.Tensor]]) -> None:
268 + def __init__(self, data: torch.Tensor | list[torch.Tensor]) -> None:
269 super().__init__(data, "video")
270
271
@@ -306,7 +304,7 @@ class MultiModalDataItems(UserDict[str, ModalityDataItems[Any, Any]]):
304 def get_items(
305 self,
306 modality: str,
309 - typ: Union[type[_D], tuple[type[_D], ...]],
307 + typ: type[_D] | tuple[type[_D], ...],
308 ) -> _D:
309 """
310 Get the data items belonging to a modality,
@@ -331,7 +329,7 @@ class MultiModalDataItems(UserDict[str, ModalityDataItems[Any, Any]]):
329
330
331 ModalityDataParser: TypeAlias = Callable[
334 - [ModalityData[Any]], Optional[ModalityDataItems[Any, Any]]
332 + [ModalityData[Any]], ModalityDataItems[Any, Any] | None
333 ]
334
335
@@ -348,7 +346,7 @@ class MultiModalDataParser:
346 def __init__(
347 self,
348 *,
351 - target_sr: Optional[float] = None,
349 + target_sr: float | None = None,
350 audio_resample_method: Literal["librosa", "scipy"] = "librosa",
351 video_needs_metadata: bool = False,
352 ) -> None:
@@ -362,7 +360,7 @@ class MultiModalDataParser:
360
361 def _is_embeddings(
362 self, data: object
365 - ) -> TypeGuard[Union[torch.Tensor, list[torch.Tensor]]]:
363 + ) -> TypeGuard[torch.Tensor | list[torch.Tensor]]:
364 if isinstance(data, torch.Tensor):
365 return data.ndim == 3
366 if is_list_of(data, torch.Tensor):
@@ -381,7 +379,7 @@ class MultiModalDataParser:
379 def _get_audio_with_sr(
380 self,
381 audio: AudioItem,
384 - ) -> tuple[np.ndarray, Optional[float]]:
382 + ) -> tuple[np.ndarray, float | None]:
383 if isinstance(audio, tuple):
384 return audio
385 if isinstance(audio, list):
@@ -396,7 +394,7 @@ class MultiModalDataParser:
394 def _get_video_with_metadata(
395 self,
396 video: VideoItem,
399 - ) -> tuple[np.ndarray, Optional[dict[str, Any]]]:
397 + ) -> tuple[np.ndarray, dict[str, Any] | None]:
398 if isinstance(video, tuple):
399 return video
400 if isinstance(video, list):
@@ -411,7 +409,7 @@ class MultiModalDataParser:
409 def _parse_audio_data(
410 self,
411 data: ModalityData[AudioItem],
414 - ) -> Optional[ModalityDataItems[Any, Any]]:
412 + ) -> ModalityDataItems[Any, Any] | None:
413 if data is None:
414 return AudioProcessorItems(None)
415
@@ -451,7 +449,7 @@ class MultiModalDataParser:
449 def _parse_image_data(
450 self,
451 data: ModalityData[ImageItem],
454 - ) -> Optional[ModalityDataItems[Any, Any]]:
452 + ) -> ModalityDataItems[Any, Any] | None:
453 if data is None:
454 return ImageProcessorItems(None)
455
@@ -477,7 +475,7 @@ class MultiModalDataParser:
475 def _parse_video_data(
476 self,
477 data: ModalityData[VideoItem],
480 - ) -> Optional[ModalityDataItems[Any, Any]]:
478 + ) -> ModalityDataItems[Any, Any] | None:
479 if data is None:
480 return VideoProcessorItems(None)
481
@@ -500,8 +498,8 @@ class MultiModalDataParser:
498 else:
499 data_items = data
500
503 - new_videos = list[tuple[np.ndarray, Optional[dict[str, Any]]]]()
504 - metadata_lst: list[Optional[dict[str, Any]]] = []
501 + new_videos = list[tuple[np.ndarray, dict[str, Any] | None]]()
502 + metadata_lst: list[dict[str, Any] | None] = []
503 for data_item in data_items:
504 video, metadata = self._get_video_with_metadata(data_item)
505 if self.video_needs_metadata:
vllm/multimodal/processing.py
+69 -62
@@ -12,9 +12,8 @@ from typing import (
12 Any,
13 Generic,
14 NamedTuple,
15 - Optional,
15 Protocol,
17 - Union,
16 + TypeAlias,
17 cast,
18 overload,
19 )
@@ -57,12 +56,20 @@ if TYPE_CHECKING:
56
57 from .cache import BaseMultiModalProcessorCache
58 from .profiling import BaseDummyInputsBuilder
59 +else:
60 + PretrainedConfig = object
61 + BatchFeature = object
62 + ProcessorMixin = object
63 +
64 + ModelConfig = object
65 +
66 + BaseMultiModalProcessorCache = object
67
68 logger = init_logger(__name__)
69
70 _S = TypeVar("_S", str, list[int])
71
65 -PromptSeq = Union[str, list[int]]
72 +PromptSeq: TypeAlias = str | list[int]
73 """A token sequence (list of token IDs) or text."""
74
75
@@ -71,7 +78,7 @@ def _cached_encode(
78 tokenizer: AnyTokenizer,
79 text: str,
80 *,
74 - add_special_tokens: Optional[bool] = None,
81 + add_special_tokens: bool | None = None,
82 ) -> list[int]:
83 return encode_tokens(tokenizer, text, add_special_tokens=add_special_tokens)
84
@@ -81,7 +88,7 @@ def _cached_decode(
88 tokenizer: AnyTokenizer,
89 token_ids: tuple[int, ...],
90 *,
84 - skip_special_tokens: Optional[bool] = None,
91 + skip_special_tokens: bool | None = None,
92 ) -> str:
93 return decode_tokens(
94 tokenizer, list(token_ids), skip_special_tokens=skip_special_tokens
@@ -108,7 +115,7 @@ class _GetMatchIndex(Protocol):
115 tokenizer: AnyTokenizer,
116 prompt: PromptSeq,
117 start_idx: int = 0,
111 - ) -> Optional[int]: ...
118 + ) -> int | None: ...
119
120
121 @dataclass
@@ -138,7 +145,7 @@ class PromptIndexTargets:
145 tokenizer: AnyTokenizer,
146 prompt: PromptSeq,
147 start_idx: int = 0,
141 - ) -> Optional[int]:
148 + ) -> int | None:
149 if start_idx != 0:
150 return None
151
@@ -168,12 +175,12 @@ class PromptIndexTargets:
175 return PromptIndex(lambda tokenizer, prompt, start_idx=0: len(prompt))
176
177
171 -UpdateTarget = Union[PromptSeq, PromptIndex]
178 +UpdateTarget: TypeAlias = PromptSeq | PromptIndex
179 """
180 The token sequence or text to update.
181 """
182
176 -PromptUpdateTarget = Union[Callable[[int], UpdateTarget], UpdateTarget]
183 +PromptUpdateTarget: TypeAlias = Callable[[int], UpdateTarget] | UpdateTarget
184 """
185 Given the index of the processed item within
186 [`modality`][vllm.multimodal.processing.PromptUpdate.modality],
@@ -191,7 +198,7 @@ class PromptUpdateDetails(Generic[_S]):
198 full: _S
199 """The full content."""
200
194 - is_embed: Optional[Callable[[AnyTokenizer, PromptSeq], torch.Tensor]] = None
201 + is_embed: Callable[[AnyTokenizer, PromptSeq], torch.Tensor] | None = None
202 """
203 Given [`full`][vllm.multimodal.processing.PromptUpdateDetails.full],
204 return a boolean mask of shape `(len(full),)` indicating which positions
@@ -236,7 +243,7 @@ class PromptUpdateDetails(Generic[_S]):
243 return PromptUpdateDetails(full=seq, is_embed=is_embed)
244
245
239 -PromptUpdateInfo = Union[PromptSeq, PromptUpdateDetails]
246 +PromptUpdateInfo: TypeAlias = PromptSeq | PromptUpdateDetails
247 """
248 The token sequence or text that are part of the update.
249
@@ -245,7 +252,7 @@ use [`PromptUpdateDetails`][vllm.multimodal.processing.PromptUpdateDetails] to
252 specify which part.
253 """
254
248 -PromptUpdateContent = Union[Callable[[int], PromptUpdateInfo], PromptUpdateInfo]
255 +PromptUpdateContent: TypeAlias = Callable[[int], PromptUpdateInfo] | PromptUpdateInfo
256 """
257 Given the index of the processed item within
258 [`modality`][vllm.multimodal.processing.PromptUpdate.modality],
@@ -472,7 +479,7 @@ class _HasModalityProp(Protocol):
479 def modality(self) -> str: ...
480
481
475 -_M = TypeVar("_M", bound=Union[_HasModalityAttr, _HasModalityProp])
482 +_M = TypeVar("_M", bound=_HasModalityAttr | _HasModalityProp)
483
484
485 def full_groupby_modality(values: Iterable[_M]) -> ItemsView[str, list[_M]]:
@@ -554,7 +561,7 @@ class ResolvedPromptUpdate:
561
562 def iter_matches(
563 self,
557 - prompt: Union[list[int], str],
564 + prompt: list[int] | str,
565 tokenizer: AnyTokenizer,
566 *,
567 start_idx: int = 0,
@@ -642,7 +649,7 @@ class PlaceholderFeaturesInfo:
649 item_idx: int
650 start_idx: int
651 tokens: list[int]
645 - is_embed: Optional[torch.Tensor]
652 + is_embed: torch.Tensor | None
653
654 @property
655 def length(self) -> int:
@@ -668,8 +675,8 @@ def _find_matches(
675 *,
676 prev_end_idx: int = 0,
677 current_result: "MultiModalPromptUpdatesApplyResult",
671 -) -> tuple[Optional[UpdateMode], list[_MatchToApply]]:
672 - mode: Optional[UpdateMode] = None
678 +) -> tuple[UpdateMode | None, list[_MatchToApply]]:
679 + mode: UpdateMode | None = None
680 mm_matches = dict[tuple[str, int], tuple[PromptTargetMatch, int]]()
681
682 for modality, modality_updates in mm_prompt_updates.items():
@@ -723,7 +730,7 @@ def _apply_matches(
730 ) -> tuple[list[_S], "MultiModalPromptUpdatesApplyResult"]:
731 prompt_len = len(prompt)
732
726 - out_seqs = list[Union[str, list[int]]]()
733 + out_seqs = list[str | list[int]]()
734 out_result: MultiModalPromptUpdatesApplyResult = {
735 m: [None] * len(items) for m, items in mm_prompt_updates.items()
736 }
@@ -880,8 +887,8 @@ def find_mm_placeholders(
887
888
889 _T = TypeVar("_T")
883 -_C = TypeVar("_C", bound="PretrainedConfig", default="PretrainedConfig")
884 -_P = TypeVar("_P", bound="ProcessorMixin", default="ProcessorMixin")
890 +_C = TypeVar("_C", bound=PretrainedConfig, default=PretrainedConfig)
891 +_P = TypeVar("_P", bound=ProcessorMixin, default=ProcessorMixin)
892
893
894 @dataclass(frozen=True)
@@ -891,25 +898,25 @@ class InputProcessingContext:
898 modify the inputs.
899 """
900
894 - model_config: "ModelConfig"
901 + model_config: ModelConfig
902 """The configuration of the model."""
903
904 tokenizer: AnyTokenizer
905 """The tokenizer used to tokenize the inputs."""
906
907 @overload
901 - def get_hf_config(self, /) -> "PretrainedConfig": ...
908 + def get_hf_config(self, /) -> PretrainedConfig: ...
909
910 @overload
911 def get_hf_config(
912 self,
906 - typ: Union[type[_C], tuple[type[_C], ...]],
913 + typ: type[_C] | tuple[type[_C], ...],
914 /,
915 ) -> _C: ...
916
917 def get_hf_config(
918 self,
912 - typ: Optional[Union[type[Any], tuple[type[Any], ...]]] = None,
919 + typ: type[Any] | tuple[type[Any], ...] | None = None,
920 /,
921 ) -> Any:
922 """
@@ -955,19 +962,19 @@ class InputProcessingContext:
962 return mm_config
963
964 @overload
958 - def get_hf_processor(self, /, **kwargs: object) -> "ProcessorMixin": ...
965 + def get_hf_processor(self, /, **kwargs: object) -> ProcessorMixin: ...
966
967 @overload
968 def get_hf_processor(
969 self,
963 - typ: Union[type[_P], tuple[type[_P], ...]],
970 + typ: type[_P] | tuple[type[_P], ...],
971 /,
972 **kwargs: object,
973 ) -> _P: ...
974
975 def get_hf_processor(
976 self,
970 - typ: Optional[Union[type[Any], tuple[type[Any], ...]]] = None,
977 + typ: type[Any] | tuple[type[Any], ...] | None = None,
978 /,
979 **kwargs: object,
980 ) -> Any:
@@ -1026,13 +1033,13 @@ class InputProcessingContext:
1033
1034 def call_hf_processor(
1035 self,
1029 - hf_processor: "ProcessorMixin",
1036 + hf_processor: ProcessorMixin,
1037 data: Mapping[str, object],
1038 kwargs: Mapping[str, object] = {},
1039 *,
1040 num_tries: int = 1,
1041 max_tries: int = 5,
1035 - ) -> Union["BatchFeature", JSONTree]:
1042 + ) -> BatchFeature | JSONTree:
1043 """
1044 Call `hf_processor` on the prompt `data`
1045 (text, image, audio...) with configurable options `kwargs`.
@@ -1113,10 +1120,10 @@ class BaseProcessingInfo:
1120 def get_tokenizer(self) -> AnyTokenizer:
1121 return self.ctx.tokenizer
1122
1116 - def get_hf_config(self) -> "PretrainedConfig":
1123 + def get_hf_config(self) -> PretrainedConfig:
1124 return self.ctx.get_hf_config()
1125
1119 - def get_hf_processor(self, **kwargs: object) -> "ProcessorMixin":
1126 + def get_hf_processor(self, **kwargs: object) -> ProcessorMixin:
1127 """
1128 Subclasses can override this method to handle
1129 specific kwargs from model config or user inputs.
@@ -1124,7 +1131,7 @@ class BaseProcessingInfo:
1131 return self.ctx.get_hf_processor(**kwargs)
1132
1133 @abstractmethod
1127 - def get_supported_mm_limits(self) -> Mapping[str, Optional[int]]:
1134 + def get_supported_mm_limits(self) -> Mapping[str, int | None]:
1135 """
1136 Return the maximum supported number of items for each modality.
1137
@@ -1156,7 +1163,7 @@ class BaseProcessingInfo:
1163 self,
1164 seq_len: int,
1165 mm_counts: Mapping[str, int],
1159 - ) -> Optional[Mapping[str, int]]:
1166 + ) -> Mapping[str, int] | None:
1167 """
1168 Return the maximum number of tokens per item of for each modality.
1169
@@ -1193,7 +1200,7 @@ A collection of prompt updates with a similar structure as
1200 [`MultiModalKwargsItems`][vllm.multimodal.inputs.MultiModalKwargsItems].
1201 """
1202
1196 -MultiModalPromptUpdatesApplyResult = Mapping[str, list[Optional[int]]]
1203 +MultiModalPromptUpdatesApplyResult = Mapping[str, list[int | None]]
1204 """
1205 For an item `MultiModalPromptUpdates[k][i]`,
1206 `MultiModalPromptUpdatesApplyResult[k][i]` represents the index of the
@@ -1220,7 +1227,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1227 info: _I,
1228 dummy_inputs: "BaseDummyInputsBuilder[_I]",
1229 *,
1223 - cache: Optional["BaseMultiModalProcessorCache"] = None,
1230 + cache: BaseMultiModalProcessorCache | None = None,
1231 ) -> None:
1232 super().__init__()
1233
@@ -1248,7 +1255,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1255 mm_data: MultiModalDataDict,
1256 hf_processor_mm_kwargs: Mapping[str, object],
1257 *,
1251 - mm_uuids: Optional[MultiModalUUIDDict] = None,
1258 + mm_uuids: MultiModalUUIDDict | None = None,
1259 ) -> MultiModalInputs:
1260 return self.apply(prompt, mm_data, hf_processor_mm_kwargs, mm_uuids=mm_uuids)
1261
@@ -1305,7 +1312,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1312 @abstractmethod
1313 def _get_mm_fields_config(
1314 self,
1308 - hf_inputs: "BatchFeature",
1315 + hf_inputs: BatchFeature,
1316 hf_processor_mm_kwargs: Mapping[str, object],
1317 ) -> Mapping[str, MultiModalFieldConfig]:
1318 """Given the HF-processed data, output the metadata of each field."""
@@ -1411,7 +1418,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1418 mm_data: Mapping[str, object],
1419 mm_kwargs: Mapping[str, object],
1420 tok_kwargs: Mapping[str, object],
1414 - ) -> "BatchFeature":
1421 + ) -> BatchFeature:
1422 """
1423 Call the HF processor on the prompt text and
1424 associated multi-modal data.
@@ -1447,7 +1454,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1454 mm_items: MultiModalDataItems,
1455 hf_processor_mm_kwargs: Mapping[str, object],
1456 tokenization_kwargs: Mapping[str, object],
1450 - ) -> tuple[list[int], "BatchFeature", bool]:
1457 + ) -> tuple[list[int], BatchFeature, bool]:
1458 """
1459 Apply the HF processor on the prompt text and multi-modal data
1460 together.
@@ -1518,7 +1525,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1525 mm_items: MultiModalDataItems,
1526 hf_processor_mm_kwargs: Mapping[str, object],
1527 tokenization_kwargs: Mapping[str, object],
1521 - ) -> "BatchFeature":
1528 + ) -> BatchFeature:
1529 """
1530 Apply the HF processor on the multi-modal data only.
1531
@@ -1540,13 +1547,13 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1547
1548 def _apply_hf_processor_main(
1549 self,
1543 - prompt: Union[str, list[int]],
1550 + prompt: str | list[int],
1551 mm_items: MultiModalDataItems,
1552 hf_processor_mm_kwargs: Mapping[str, object],
1553 tokenization_kwargs: Mapping[str, object],
1554 *,
1555 enable_hf_prompt_update: bool,
1549 - ) -> tuple[list[int], "BatchFeature", bool]:
1556 + ) -> tuple[list[int], BatchFeature, bool]:
1557 """
1558 Apply the HF processor on the prompt text and multi-modal data.
1559
@@ -1585,7 +1592,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1592 hf_processor_mm_kwargs: Mapping[str, object],
1593 tokenization_kwargs: Mapping[str, object],
1594 *,
1588 - mm_uuids: Optional[MultiModalUUIDDict] = None,
1595 + mm_uuids: MultiModalUUIDDict | None = None,
1596 ) -> MultiModalHashes:
1597 """Create MM hashes to be returned.
1598
@@ -1647,7 +1654,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1654
1655 def _get_cache_missing_items(
1656 self,
1650 - cache: "BaseMultiModalProcessorCache",
1657 + cache: BaseMultiModalProcessorCache,
1658 mm_data_items: MultiModalDataItems,
1659 mm_hashes: MultiModalHashes,
1660 ) -> MultiModalDataItems:
@@ -1692,7 +1699,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1699
1700 def _merge_mm_kwargs(
1701 self,
1695 - cache: "BaseMultiModalProcessorCache",
1702 + cache: BaseMultiModalProcessorCache,
1703 mm_hashes: MultiModalHashes,
1704 mm_missing_kwargs: MultiModalKwargsItems,
1705 mm_missing_prompt_updates: MultiModalPromptUpdates,
@@ -1705,7 +1712,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1712
1713 mm_missing_next_idx = defaultdict[str, int](lambda: 0)
1714
1708 - merged_kwargs = defaultdict[str, list[Optional[MultiModalKwargsItem]]](list)
1715 + merged_kwargs = defaultdict[str, list[MultiModalKwargsItem | None]](list)
1716 merged_prompt_updates = defaultdict[str, list[Sequence[ResolvedPromptUpdate]]](
1717 list
1718 )
@@ -1714,7 +1721,7 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1721 missing_prompt_updates = mm_missing_prompt_updates.get(modality, [])
1722
1723 for item_idx, item_hash in enumerate(hashes):
1717 - kwargs: Optional[MultiModalKwargsItem]
1724 + kwargs: MultiModalKwargsItem | None
1725 if not mm_is_cached[modality][item_idx]:
1726 missing_next_idx = mm_missing_next_idx[modality]
1727 kwargs = missing_kwargs[missing_next_idx]
@@ -1743,12 +1750,12 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1750
1751 def _apply_hf_processor(
1752 self,
1746 - prompt: Union[str, list[int]],
1753 + prompt: str | list[int],
1754 mm_data_items: MultiModalDataItems,
1755 hf_processor_mm_kwargs: Mapping[str, object],
1756 tokenization_kwargs: Mapping[str, object],
1757 *,
1751 - mm_uuids: Optional[MultiModalUUIDDict] = None,
1758 + mm_uuids: MultiModalUUIDDict | None = None,
1759 ) -> tuple[list[int], MultiModalProcessingInfo, bool]:
1760 (
1761 prompt_ids,
@@ -1791,12 +1798,12 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
1798
1799 def _cached_apply_hf_processor(
1800 self,
1794 - prompt: Union[str, list[int]],
1801 + prompt: str | list[int],
1802 mm_data_items: MultiModalDataItems,
1803 hf_processor_mm_kwargs: Mapping[str, object],
1804 tokenization_kwargs: Mapping[str, object],
1805 *,
1799 - mm_uuids: Optional[MultiModalUUIDDict] = None,
1806 + mm_uuids: MultiModalUUIDDict | None = None,
1807 ) -> tuple[list[int], MultiModalProcessingInfo, bool]:
1808 """
1809 Apply the HF processor on the full prompt text,
@@ -2026,12 +2033,12 @@ class BaseMultiModalProcessor(ABC, Generic[_I]):
2033
2034 def apply(
2035 self,
2029 - prompt: Union[str, list[int]],
2036 + prompt: str | list[int],
2037 mm_data: MultiModalDataDict,
2038 hf_processor_mm_kwargs: Mapping[str, object],
2032 - tokenization_kwargs: Optional[Mapping[str, object]] = None,
2039 + tokenization_kwargs: Mapping[str, object] | None = None,
2040 *,
2034 - mm_uuids: Optional[MultiModalUUIDDict] = None,
2041 + mm_uuids: MultiModalUUIDDict | None = None,
2042 ) -> MultiModalInputs:
2043 """
2044 Process multi-modal inputs to be used in vLLM.
@@ -2090,9 +2097,9 @@ class EncDecMultiModalProcessor(BaseMultiModalProcessor[_I]):
2097 @abstractmethod
2098 def create_encoder_prompt(
2099 self,
2093 - prompt: Union[str, list[int]],
2100 + prompt: str | list[int],
2101 mm_data: MultiModalDataDict,
2095 - ) -> Union[str, list[int]]:
2102 + ) -> str | list[int]:
2103 """
2104 Create input prompt for the encoder. HF processor will be applied on
2105 this prompt during profiling and generation.
@@ -2105,15 +2112,15 @@ class EncDecMultiModalProcessor(BaseMultiModalProcessor[_I]):
2112
2113 def create_decoder_prompt(
2114 self,
2108 - prompt: Union[str, list[int]],
2115 + prompt: str | list[int],
2116 mm_data: MultiModalDataDict,
2110 - ) -> Union[str, list[int]]:
2117 + ) -> str | list[int]:
2118 """Create input prompt for the decoder."""
2119 return prompt
2120
2121 def _get_enc_dec_inputs(
2122 self,
2116 - prompt: Union[str, list[int]],
2123 + prompt: str | list[int],
2124 mm_data: MultiModalDataDict,
2125 encoder_inputs: MultiModalInputs,
2126 ):
@@ -2135,12 +2142,12 @@ class EncDecMultiModalProcessor(BaseMultiModalProcessor[_I]):
2142
2143 def apply(
2144 self,
2138 - prompt: Union[str, list[int]],
2145 + prompt: str | list[int],
2146 mm_data: MultiModalDataDict,
2147 hf_processor_mm_kwargs: Mapping[str, object],
2141 - tokenization_kwargs: Optional[Mapping[str, object]] = None,
2148 + tokenization_kwargs: Mapping[str, object] | None = None,
2149 *,
2143 - mm_uuids: Optional[MultiModalUUIDDict] = None,
2150 + mm_uuids: MultiModalUUIDDict | None = None,
2151 ) -> MultiModalEncDecInputs:
2152 """
2153 Process multi-modal inputs to be used in vLLM.
vllm/multimodal/profiling.py
+15 -15
@@ -3,7 +3,7 @@
3 from abc import ABC, abstractmethod
4 from collections.abc import Mapping
5 from dataclasses import dataclass, field
6 -from typing import Generic, NamedTuple, Optional, TypeVar, Union, cast
6 +from typing import Generic, NamedTuple, TypeVar, cast
7
8 import numpy as np
9 import numpy.typing as npt
@@ -41,7 +41,7 @@ class ProcessorInputs:
41 [`vllm.multimodal.processing.BaseMultiModalProcessor.apply`][].
42 """
43
44 - prompt: Union[str, list[int]]
44 + prompt: str | list[int]
45 mm_data: MultiModalDataDict
46 hf_processor_mm_kwargs: Mapping[str, object] = field(default_factory=dict)
47 tokenization_kwargs: Mapping[str, object] = field(default_factory=dict)
@@ -87,7 +87,7 @@ class BaseDummyInputsBuilder(ABC, Generic[_I]):
87 self,
88 seq_len: int,
89 mm_counts: Mapping[str, int],
90 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
90 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
91 ) -> MultiModalDataDict:
92 """
93 Build the multimodal input which, after processing, results in
@@ -107,7 +107,7 @@ class BaseDummyInputsBuilder(ABC, Generic[_I]):
107 self,
108 seq_len: int,
109 mm_counts: Mapping[str, int],
110 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
110 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
111 ) -> ProcessorInputs:
112 """
113 Build the input which, after processing, results in
@@ -136,7 +136,7 @@ class BaseDummyInputsBuilder(ABC, Generic[_I]):
136 *,
137 length: int,
138 num_audios: int,
139 - overrides: Optional[AudioDummyOptions] = None,
139 + overrides: AudioDummyOptions | None = None,
140 ) -> list[npt.NDArray]:
141 if num_audios == 0:
142 return []
@@ -158,7 +158,7 @@ class BaseDummyInputsBuilder(ABC, Generic[_I]):
158 width: int,
159 height: int,
160 num_images: int,
161 - overrides: Optional[ImageDummyOptions] = None,
161 + overrides: ImageDummyOptions | None = None,
162 ) -> list[Image.Image]:
163 if num_images == 0:
164 return []
@@ -191,7 +191,7 @@ class BaseDummyInputsBuilder(ABC, Generic[_I]):
191 height: int,
192 num_frames: int,
193 num_videos: int,
194 - overrides: Optional[VideoDummyOptions] = None,
194 + overrides: VideoDummyOptions | None = None,
195 ) -> list[npt.NDArray]:
196 if num_videos == 0:
197 return []
@@ -254,8 +254,8 @@ class MultiModalProfiler(Generic[_I]):
254 def _get_dummy_mm_inputs(
255 self,
256 seq_len: int,
257 - mm_counts: Optional[Mapping[str, int]] = None,
258 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
257 + mm_counts: Mapping[str, int] | None = None,
258 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
259 ) -> MultiModalInputs:
260 if mm_counts is None:
261 mm_counts = self.get_mm_limits()
@@ -290,8 +290,8 @@ class MultiModalProfiler(Generic[_I]):
290 def get_encoder_dummy_data(
291 self,
292 seq_len: int,
293 - mm_counts: Optional[Mapping[str, int]] = None,
294 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
293 + mm_counts: Mapping[str, int] | None = None,
294 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
295 ) -> DummyEncoderData:
296 mm_inputs = self._get_dummy_mm_inputs(seq_len, mm_counts, mm_options)
297 mm_inputs = cast(MultiModalEncDecInputs, mm_inputs)
@@ -324,8 +324,8 @@ class MultiModalProfiler(Generic[_I]):
324 def get_decoder_dummy_data(
325 self,
326 seq_len: int,
327 - mm_counts: Optional[Mapping[str, int]] = None,
328 - mm_options: Optional[Mapping[str, BaseDummyOptions]] = None,
327 + mm_counts: Mapping[str, int] | None = None,
328 + mm_options: Mapping[str, BaseDummyOptions] | None = None,
329 ) -> DummyDecoderData:
330 mm_inputs = self._get_dummy_mm_inputs(seq_len, mm_counts, mm_options)
331
@@ -344,7 +344,7 @@ class MultiModalProfiler(Generic[_I]):
344 def _get_mm_max_tokens(
345 self,
346 seq_len: int,
347 - mm_counts: Optional[Mapping[str, int]] = None,
347 + mm_counts: Mapping[str, int] | None = None,
348 mm_embeddings_only: bool = True,
349 ) -> Mapping[str, int]:
350 if mm_counts is None:
@@ -363,7 +363,7 @@ class MultiModalProfiler(Generic[_I]):
363 def get_mm_max_contiguous_tokens(
364 self,
365 seq_len: int,
366 - mm_counts: Optional[Mapping[str, int]] = None,
366 + mm_counts: Mapping[str, int] | None = None,
367 ):
368 """
369 Returns the maximum length of the multimodal (image placeholders+text)
vllm/multimodal/registry.py
+15 -15
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Mapping
4 from dataclasses import dataclass
5 -from typing import TYPE_CHECKING, Generic, Optional, Protocol, TypeVar
5 +from typing import TYPE_CHECKING, Generic, Protocol, TypeVar
6
7 import torch.nn as nn
8
@@ -69,7 +69,7 @@ class MultiModalProcessorFactory(Protocol[_I]): # type: ignore[misc]
69 info: _I,
70 dummy_inputs: BaseDummyInputsBuilder[_I],
71 *,
72 - cache: Optional[BaseMultiModalProcessorCache] = None,
72 + cache: BaseMultiModalProcessorCache | None = None,
73 ) -> BaseMultiModalProcessor[_I]: ...
74
75
@@ -83,7 +83,7 @@ class _ProcessorFactories(Generic[_I]):
83 self,
84 ctx: InputProcessingContext,
85 *,
86 - cache: Optional[BaseMultiModalProcessorCache] = None,
86 + cache: BaseMultiModalProcessorCache | None = None,
87 ):
88 info = self.info(ctx)
89 dummy_inputs_builder = self.dummy_inputs(info)
@@ -101,7 +101,7 @@ class MultiModalRegistry:
101 def _extract_mm_options(
102 self,
103 model_config: "ModelConfig",
104 - ) -> Optional[Mapping[str, BaseDummyOptions]]:
104 + ) -> Mapping[str, BaseDummyOptions] | None:
105 """
106 Extract multimodal dummy options from model config.
107
@@ -151,7 +151,7 @@ class MultiModalRegistry:
151 self,
152 model_config: "ModelConfig",
153 *,
154 - cache: Optional[BaseMultiModalProcessorCache] = None,
154 + cache: BaseMultiModalProcessorCache | None = None,
155 ) -> Mapping[str, int]:
156 """
157 Get the maximum number of tokens per data item from each modality based
@@ -175,7 +175,7 @@ class MultiModalRegistry:
175 self,
176 model_config: "ModelConfig",
177 *,
178 - cache: Optional[BaseMultiModalProcessorCache] = None,
178 + cache: BaseMultiModalProcessorCache | None = None,
179 ) -> Mapping[str, int]:
180 """
181 Get the maximum number of tokens per data item from each modality based
@@ -202,7 +202,7 @@ class MultiModalRegistry:
202 self,
203 model_config: "ModelConfig",
204 *,
205 - cache: Optional[BaseMultiModalProcessorCache] = None,
205 + cache: BaseMultiModalProcessorCache | None = None,
206 ) -> Mapping[str, int]:
207 """
208 Get the maximum number of multi-modal input instances for each modality
@@ -259,7 +259,7 @@ class MultiModalRegistry:
259 def _create_processing_ctx(
260 self,
261 model_config: "ModelConfig",
262 - tokenizer: Optional[AnyTokenizer] = None,
262 + tokenizer: AnyTokenizer | None = None,
263 ) -> InputProcessingContext:
264 if tokenizer is None and not model_config.skip_tokenizer_init:
265 tokenizer = cached_tokenizer_from_config(model_config)
@@ -269,7 +269,7 @@ class MultiModalRegistry:
269 self,
270 model_config: "ModelConfig",
271 *,
272 - tokenizer: Optional[AnyTokenizer] = None,
272 + tokenizer: AnyTokenizer | None = None,
273 ) -> BaseProcessingInfo:
274 model_cls = self._get_model_cls(model_config)
275 factories = self._processor_factories[model_cls]
@@ -280,8 +280,8 @@ class MultiModalRegistry:
280 self,
281 model_config: "ModelConfig",
282 *,
283 - tokenizer: Optional[AnyTokenizer] = None,
284 - cache: Optional[BaseMultiModalProcessorCache] = None,
283 + tokenizer: AnyTokenizer | None = None,
284 + cache: BaseMultiModalProcessorCache | None = None,
285 ) -> BaseMultiModalProcessor[BaseProcessingInfo]:
286 """
287 Create a multi-modal processor for a specific model and tokenizer.
@@ -300,9 +300,9 @@ class MultiModalRegistry:
300 self,
301 model_config: "ModelConfig",
302 seq_len: int,
303 - mm_counts: Optional[Mapping[str, int]] = None,
303 + mm_counts: Mapping[str, int] | None = None,
304 *,
305 - cache: Optional[BaseMultiModalProcessorCache] = None,
305 + cache: BaseMultiModalProcessorCache | None = None,
306 ) -> DummyDecoderData:
307 """
308 Create dummy data for profiling the memory usage of a model.
@@ -333,9 +333,9 @@ class MultiModalRegistry:
333 self,
334 model_config: "ModelConfig",
335 seq_len: int,
336 - mm_counts: Optional[Mapping[str, int]] = None,
336 + mm_counts: Mapping[str, int] | None = None,
337 *,
338 - cache: Optional[BaseMultiModalProcessorCache] = None,
338 + cache: BaseMultiModalProcessorCache | None = None,
339 ) -> DummyEncoderData:
340 """
341 Create dummy data for profiling the memory usage of a model.
vllm/multimodal/utils.py
+12 -12
@@ -7,7 +7,7 @@ from collections.abc import Iterable
7 from concurrent.futures import ThreadPoolExecutor
8 from itertools import groupby
9 from pathlib import Path
10 -from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
10 +from typing import TYPE_CHECKING, Any, TypeVar
11 from urllib.parse import ParseResult, urlparse
12 from urllib.request import url2pathname
13
@@ -49,11 +49,11 @@ atexit.register(global_thread_pool.shutdown)
49 class MediaConnector:
50 def __init__(
51 self,
52 - media_io_kwargs: Optional[dict[str, dict[str, Any]]] = None,
52 + media_io_kwargs: dict[str, dict[str, Any]] | None = None,
53 connection: HTTPConnection = global_http_connection,
54 *,
55 allowed_local_media_path: str = "",
56 - allowed_media_domains: Optional[list[str]] = None,
56 + allowed_media_domains: list[str] | None = None,
57 ) -> None:
58 """
59 Args:
@@ -143,7 +143,7 @@ class MediaConnector:
143 url: str,
144 media_io: MediaIO[_M],
145 *,
146 - fetch_timeout: Optional[int] = None,
146 + fetch_timeout: int | None = None,
147 ) -> _M: # type: ignore[type-var]
148 url_spec = urlparse(url)
149
@@ -173,7 +173,7 @@ class MediaConnector:
173 url: str,
174 media_io: MediaIO[_M],
175 *,
176 - fetch_timeout: Optional[int] = None,
176 + fetch_timeout: int | None = None,
177 ) -> _M:
178 url_spec = urlparse(url)
179 loop = asyncio.get_running_loop()
@@ -207,7 +207,7 @@ class MediaConnector:
207 def fetch_audio(
208 self,
209 audio_url: str,
210 - ) -> tuple[np.ndarray, Union[int, float]]:
210 + ) -> tuple[np.ndarray, int | float]:
211 """
212 Load audio from a URL.
213 """
@@ -222,7 +222,7 @@ class MediaConnector:
222 async def fetch_audio_async(
223 self,
224 audio_url: str,
225 - ) -> tuple[np.ndarray, Union[int, float]]:
225 + ) -> tuple[np.ndarray, int | float]:
226 """
227 Asynchronously fetch audio from a URL.
228 """
@@ -396,7 +396,7 @@ def group_mm_kwargs_by_modality(
396 *,
397 device: torch.types.Device = None,
398 pin_memory: bool = False,
399 - merge_by_field_config: Optional[bool] = None,
399 + merge_by_field_config: bool | None = None,
400 ) -> Iterable[tuple[str, int, BatchedTensorInputs]]:
401 """Group consecutive `MultiModalKwargsItem`s from `mm_kwargs` with the same
402 modality together into the same `MultiModalKwargs` instance.
@@ -452,8 +452,8 @@ def group_mm_kwargs_by_modality(
452
453 def fetch_audio(
454 audio_url: str,
455 - audio_io_kwargs: Optional[dict[str, Any]] = None,
456 -) -> tuple[np.ndarray, Union[int, float]]:
455 + audio_io_kwargs: dict[str, Any] | None = None,
456 +) -> tuple[np.ndarray, int | float]:
457 """
458 Args:
459 audio_url: URL of the audio file to fetch.
@@ -466,7 +466,7 @@ def fetch_audio(
466
467 def fetch_image(
468 image_url: str,
469 - image_io_kwargs: Optional[dict[str, Any]] = None,
469 + image_io_kwargs: dict[str, Any] | None = None,
470 ) -> Image.Image:
471 """
472 Args:
@@ -480,7 +480,7 @@ def fetch_image(
480
481 def fetch_video(
482 video_url: str,
483 - video_io_kwargs: Optional[dict[str, Any]] = None,
483 + video_io_kwargs: dict[str, Any] | None = None,
484 ) -> tuple[npt.NDArray, dict[str, Any]]:
485 """
486 Args:
vllm/multimodal/video.py
+2 -2
@@ -6,7 +6,7 @@ from abc import abstractmethod
6 from functools import partial
7 from io import BytesIO
8 from pathlib import Path
9 -from typing import Any, Union
9 +from typing import Any
10
11 import numpy as np
12 import numpy.typing as npt
@@ -192,7 +192,7 @@ class OpenCVDynamicVideoBackend(OpenCVVideoBackend):
192
193 # Refer to:
194 # https://github.com/huggingface/transformers/blob/v4.55.4/src/transformers/models/glm4v/video_processing_glm4v.py#L103-L140
195 - frame_indices: Union[range, list[int]]
195 + frame_indices: range | list[int]
196 if duration <= max_duration:
197 n = int(math.floor(duration * fps))
198 frame_indices = sorted(
vllm/outputs.py
+16 -16
@@ -4,7 +4,7 @@
4 from collections.abc import MutableSequence
5 from collections.abc import Sequence as GenericSequence
6 from dataclasses import dataclass
7 -from typing import Any, Generic, Optional, Union
7 +from typing import Any, Generic
8
9 import torch
10 from typing_extensions import TypeVar
@@ -41,11 +41,11 @@ class CompletionOutput:
41 index: int
42 text: str
43 token_ids: GenericSequence[int]
44 - cumulative_logprob: Optional[float]
45 - logprobs: Optional[SampleLogprobs]
46 - finish_reason: Optional[str] = None
47 - stop_reason: Union[int, str, None] = None
48 - lora_request: Optional[LoRARequest] = None
44 + cumulative_logprob: float | None
45 + logprobs: SampleLogprobs | None
46 + finish_reason: str | None = None
47 + stop_reason: int | str | None = None
48 + lora_request: LoRARequest | None = None
49
50 def finished(self) -> bool:
51 return self.finish_reason is not None
@@ -108,19 +108,19 @@ class RequestOutput:
108 def __init__(
109 self,
110 request_id: str,
111 - prompt: Optional[str],
112 - prompt_token_ids: Optional[list[int]],
113 - prompt_logprobs: Optional[PromptLogprobs],
111 + prompt: str | None,
112 + prompt_token_ids: list[int] | None,
113 + prompt_logprobs: PromptLogprobs | None,
114 outputs: list[CompletionOutput],
115 finished: bool,
116 - metrics: Optional[Union[RequestMetrics, RequestStateStats]] = None,
117 - lora_request: Optional[LoRARequest] = None,
118 - encoder_prompt: Optional[str] = None,
119 - encoder_prompt_token_ids: Optional[list[int]] = None,
120 - num_cached_tokens: Optional[int] = None,
116 + metrics: RequestMetrics | RequestStateStats | None = None,
117 + lora_request: LoRARequest | None = None,
118 + encoder_prompt: str | None = None,
119 + encoder_prompt_token_ids: list[int] | None = None,
120 + num_cached_tokens: int | None = None,
121 *,
122 - multi_modal_placeholders: Optional[MultiModalPlaceholderDict] = None,
123 - kv_transfer_params: Optional[dict[str, Any]] = None,
122 + multi_modal_placeholders: MultiModalPlaceholderDict | None = None,
123 + kv_transfer_params: dict[str, Any] | None = None,
124 # Forward compatibility, code that uses args added in new release can
125 # still run with older versions of vLLM without breaking.
126 **kwargs: Any,
vllm/platforms/__init__.py
+6 -6
@@ -3,7 +3,7 @@
3 import logging
4 import traceback
5 from itertools import chain
6 -from typing import TYPE_CHECKING, Optional
6 +from typing import TYPE_CHECKING
7
8 from vllm import envs
9 from vllm.plugins import load_plugins_by_group
@@ -31,7 +31,7 @@ def vllm_version_matches_substr(substr: str) -> bool:
31 return substr in vllm_version
32
33
34 -def tpu_platform_plugin() -> Optional[str]:
34 +def tpu_platform_plugin() -> str | None:
35 logger.debug("Checking if TPU platform is available.")
36
37 # Check for Pathways TPU proxy
@@ -55,7 +55,7 @@ def tpu_platform_plugin() -> Optional[str]:
55 return None
56
57
58 -def cuda_platform_plugin() -> Optional[str]:
58 +def cuda_platform_plugin() -> str | None:
59 is_cuda = False
60 logger.debug("Checking if CUDA platform is available.")
61 try:
@@ -106,7 +106,7 @@ def cuda_platform_plugin() -> Optional[str]:
106 return "vllm.platforms.cuda.CudaPlatform" if is_cuda else None
107
108
109 -def rocm_platform_plugin() -> Optional[str]:
109 +def rocm_platform_plugin() -> str | None:
110 is_rocm = False
111 logger.debug("Checking if ROCm platform is available.")
112 try:
@@ -127,7 +127,7 @@ def rocm_platform_plugin() -> Optional[str]:
127 return "vllm.platforms.rocm.RocmPlatform" if is_rocm else None
128
129
130 -def xpu_platform_plugin() -> Optional[str]:
130 +def xpu_platform_plugin() -> str | None:
131 is_xpu = False
132 logger.debug("Checking if XPU platform is available.")
133 try:
@@ -154,7 +154,7 @@ def xpu_platform_plugin() -> Optional[str]:
154 return "vllm.platforms.xpu.XPUPlatform" if is_xpu else None
155
156
157 -def cpu_platform_plugin() -> Optional[str]:
157 +def cpu_platform_plugin() -> str | None:
158 is_cpu = False
159 logger.debug("Checking if CPU platform is available.")
160 try:
vllm/platforms/cpu.py
+3 -3
@@ -4,13 +4,13 @@
4 import json
5 import os
6 import platform
7 -import re
7 import subprocess
8 import sys
9 from dataclasses import dataclass
10 from importlib.util import find_spec
12 -from typing import TYPE_CHECKING, Optional
11 +from typing import TYPE_CHECKING
12
13 +import regex as re
14 import torch
15
16 from vllm.logger import init_logger
@@ -128,7 +128,7 @@ class CpuPlatform(Platform):
128 selected_backend: "_Backend",
129 head_size: int,
130 dtype: torch.dtype,
131 - kv_cache_dtype: Optional[str],
131 + kv_cache_dtype: str | None,
132 block_size: int,
133 use_v1: bool,
134 use_mla: bool,
vllm/platforms/cuda.py
+6 -5
@@ -5,9 +5,10 @@ pynvml. However, it should not initialize cuda context.
5 """
6
7 import os
8 +from collections.abc import Callable
9 from datetime import timedelta
10 from functools import cache, wraps
10 -from typing import TYPE_CHECKING, Callable, Optional, TypeVar, Union
11 +from typing import TYPE_CHECKING, TypeVar
12
13 import torch
14 from torch.distributed import PrefixStore, ProcessGroup
@@ -85,7 +86,7 @@ class CudaPlatformBase(Platform):
86 _ = torch.zeros(1, device=device)
87
88 @classmethod
88 - def get_device_capability(cls, device_id: int = 0) -> Optional[DeviceCapability]:
89 + def get_device_capability(cls, device_id: int = 0) -> DeviceCapability | None:
90 raise NotImplementedError
91
92 @classmethod
@@ -210,7 +211,7 @@ class CudaPlatformBase(Platform):
211
212 @classmethod
213 def get_current_memory_usage(
213 - cls, device: Optional[torch.types.Device] = None
214 + cls, device: torch.types.Device | None = None
215 ) -> float:
216 torch.cuda.empty_cache()
217 torch.cuda.reset_peak_memory_stats(device)
@@ -594,7 +595,7 @@ class NvmlCudaPlatform(CudaPlatformBase):
595 @classmethod
596 @cache
597 @with_nvml_context
597 - def get_device_capability(cls, device_id: int = 0) -> Optional[DeviceCapability]:
598 + def get_device_capability(cls, device_id: int = 0) -> DeviceCapability | None:
599 try:
600 physical_device_id = cls.device_id_to_physical_device_id(device_id)
601 handle = pynvml.nvmlDeviceGetHandleByIndex(physical_device_id)
@@ -607,7 +608,7 @@ class NvmlCudaPlatform(CudaPlatformBase):
608 @with_nvml_context
609 def has_device_capability(
610 cls,
610 - capability: Union[tuple[int, int], int],
611 + capability: tuple[int, int] | int,
612 device_id: int = 0,
613 ) -> bool:
614 try:
vllm/platforms/interface.py
+20 -22
@@ -8,7 +8,7 @@ import random
8 import sys
9 from datetime import timedelta
10 from platform import uname
11 -from typing import TYPE_CHECKING, Any, NamedTuple, Optional, Union
11 +from typing import TYPE_CHECKING, Any, NamedTuple
12
13 import numpy as np
14 import torch
@@ -20,18 +20,16 @@ from vllm.logger import init_logger
20 if TYPE_CHECKING:
21 from vllm.attention.backends.registry import _Backend
22 from vllm.config import ModelConfig, VllmConfig
23 - from vllm.lora.request import LoRARequest
23 from vllm.pooling_params import PoolingParams
24 from vllm.sampling_params import SamplingParams
25 from vllm.utils import FlexibleArgumentParser
26 else:
28 - _Backend = None
29 - ModelConfig = None
30 - VllmConfig = None
31 - LoRARequest = None
32 - PoolingParams = None
33 - SamplingParams = None
34 - FlexibleArgumentParser = None
27 + _Backend = object
28 + ModelConfig = object
29 + VllmConfig = object
30 + PoolingParams = object
31 + SamplingParams = object
32 + FlexibleArgumentParser = object
33
34 logger = init_logger(__name__)
35
@@ -113,7 +111,7 @@ class Platform:
111
112 additional_env_vars: list[str] = []
113
116 - _global_graph_pool: Optional[Any] = None
114 + _global_graph_pool: Any | None = None
115
116 @property
117 def supported_dtypes(self) -> list[torch.dtype]:
@@ -180,7 +178,7 @@ class Platform:
178 import vllm._moe_C # noqa: F401
179
180 @classmethod
183 - def get_vit_attn_backend(cls, head_size: int, dtype: torch.dtype) -> "_Backend":
181 + def get_vit_attn_backend(cls, head_size: int, dtype: torch.dtype) -> _Backend:
182 from vllm.attention.backends.registry import _Backend
183
184 return _Backend.TORCH_SDPA
@@ -188,10 +186,10 @@ class Platform:
186 @classmethod
187 def get_attn_backend_cls(
188 cls,
191 - selected_backend: "_Backend",
189 + selected_backend: _Backend,
190 head_size: int,
191 dtype: torch.dtype,
194 - kv_cache_dtype: Optional[str],
192 + kv_cache_dtype: str | None,
193 block_size: int,
194 use_v1: bool,
195 use_mla: bool,
@@ -205,14 +203,14 @@ class Platform:
203 def get_device_capability(
204 cls,
205 device_id: int = 0,
208 - ) -> Optional[DeviceCapability]:
206 + ) -> DeviceCapability | None:
207 """Stateless version of [torch.cuda.get_device_capability][]."""
208 return None
209
210 @classmethod
211 def has_device_capability(
212 cls,
215 - capability: Union[tuple[int, int], int],
213 + capability: tuple[int, int] | int,
214 device_id: int = 0,
215 ) -> bool:
216 """
@@ -236,7 +234,7 @@ class Platform:
234 @classmethod
235 def is_device_capability(
236 cls,
239 - capability: Union[tuple[int, int], int],
237 + capability: tuple[int, int] | int,
238 device_id: int = 0,
239 ) -> bool:
240 """
@@ -283,7 +281,7 @@ class Platform:
281 return torch.inference_mode(mode=True)
282
283 @classmethod
286 - def seed_everything(cls, seed: Optional[int] = None) -> None:
284 + def seed_everything(cls, seed: int | None = None) -> None:
285 """
286 Set the seed of each random module.
287 `torch.manual_seed` will set seed on all devices.
@@ -304,7 +302,7 @@ class Platform:
302
303 @classmethod
304 def pre_register_and_update(
307 - cls, parser: Optional[FlexibleArgumentParser] = None
305 + cls, parser: FlexibleArgumentParser | None = None
306 ) -> None:
307 """
308 Do some pre-registration or update action for the current platform.
@@ -389,7 +387,7 @@ class Platform:
387
388 @classmethod
389 def get_current_memory_usage(
392 - cls, device: Optional[torch.types.Device] = None
390 + cls, device: torch.types.Device | None = None
391 ) -> float:
392 """
393 Return the memory usage in bytes.
@@ -501,7 +499,7 @@ class Platform:
499 def validate_request(
500 cls,
501 prompt: PromptType,
504 - params: Union[SamplingParams, PoolingParams],
502 + params: SamplingParams | PoolingParams,
503 processed_inputs: ProcessorInputs,
504 ) -> None:
505 """Raises if this request is unsupported on this platform"""
@@ -557,7 +555,7 @@ class Platform:
555
556 @classmethod
557 def is_kv_cache_dtype_supported(
560 - cls, kv_cache_dtype: str, model_config: "ModelConfig"
558 + cls, kv_cache_dtype: str, model_config: ModelConfig
559 ) -> bool:
560 """
561 Returns if the kv_cache_dtype is supported by the current platform.
@@ -617,7 +615,7 @@ class Platform:
615 return {}
616
617 @classmethod
620 - def get_nixl_memory_type(cls) -> Optional[str]:
618 + def get_nixl_memory_type(cls) -> str | None:
619 """
620 Returns the nixl memory type for the current platform.
621 """
vllm/platforms/rocm.py
+5 -5
@@ -4,7 +4,7 @@
4 import os
5 from datetime import timedelta
6 from functools import cache, lru_cache, wraps
7 -from typing import TYPE_CHECKING, Optional
7 +from typing import TYPE_CHECKING
8
9 import torch
10 from torch.distributed import PrefixStore, ProcessGroup
@@ -140,8 +140,8 @@ def use_rocm_custom_paged_attention(
140 max_seq_len: int,
141 sliding_window: int,
142 kv_cache_dtype: str,
143 - alibi_slopes: Optional[torch.Tensor] = None,
144 - sinks: Optional[torch.Tensor] = None,
143 + alibi_slopes: torch.Tensor | None = None,
144 + sinks: torch.Tensor | None = None,
145 ) -> bool:
146 GPU_ARCH = torch.cuda.get_device_properties("cuda").gcnArchName
147 ON_GFX9 = any(arch in GPU_ARCH for arch in ["gfx90a", "gfx942", "gfx950"])
@@ -320,7 +320,7 @@ class RocmPlatform(Platform):
320
321 @classmethod
322 @lru_cache(maxsize=8)
323 - def get_device_capability(cls, device_id: int = 0) -> Optional[DeviceCapability]:
323 + def get_device_capability(cls, device_id: int = 0) -> DeviceCapability | None:
324 major, minor = torch.cuda.get_device_capability(device_id)
325 return DeviceCapability(major=major, minor=minor)
326
@@ -420,7 +420,7 @@ class RocmPlatform(Platform):
420
421 @classmethod
422 def get_current_memory_usage(
423 - cls, device: Optional[torch.types.Device] = None
423 + cls, device: torch.types.Device | None = None
424 ) -> float:
425 torch.cuda.reset_peak_memory_stats(device)
426 return torch.cuda.mem_get_info(device)[1] - torch.cuda.mem_get_info(device)[0]
vllm/platforms/tpu.py
+3 -3
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import contextlib
5 -from typing import TYPE_CHECKING, Optional, Union, cast
5 +from typing import TYPE_CHECKING, cast
6
7 import torch
8 from tpu_info import device
@@ -57,7 +57,7 @@ class TpuPlatform(Platform):
57 selected_backend: "_Backend",
58 head_size: int,
59 dtype: torch.dtype,
60 - kv_cache_dtype: Optional[str],
60 + kv_cache_dtype: str | None,
61 block_size: int,
62 use_v1: bool,
63 use_mla: bool,
@@ -211,7 +211,7 @@ class TpuPlatform(Platform):
211 def validate_request(
212 cls,
213 prompt: PromptType,
214 - params: Union[SamplingParams, PoolingParams],
214 + params: SamplingParams | PoolingParams,
215 processed_inputs: ProcessorInputs,
216 ) -> None:
217 """Raises if this request is unsupported on this platform"""
vllm/platforms/xpu.py
+4 -4
@@ -3,7 +3,7 @@
3
4 import contextlib
5 import os
6 -from typing import TYPE_CHECKING, Optional
6 +from typing import TYPE_CHECKING
7
8 import torch
9
@@ -47,7 +47,7 @@ class XPUPlatform(Platform):
47 selected_backend: "_Backend",
48 head_size: int,
49 dtype: torch.dtype,
50 - kv_cache_dtype: Optional[str],
50 + kv_cache_dtype: str | None,
51 block_size: int,
52 use_v1: bool,
53 use_mla: bool,
@@ -113,7 +113,7 @@ class XPUPlatform(Platform):
113 def get_device_capability(
114 cls,
115 device_id: int = 0,
116 - ) -> Optional[DeviceCapability]:
116 + ) -> DeviceCapability | None:
117 # capacity format differs from cuda's and will cause unexpected
118 # failure, so use None directly
119 return None
@@ -213,7 +213,7 @@ class XPUPlatform(Platform):
213
214 @classmethod
215 def get_current_memory_usage(
216 - cls, device: Optional[torch.types.Device] = None
216 + cls, device: torch.types.Device | None = None
217 ) -> float:
218 torch.xpu.reset_peak_memory_stats(device)
219 return torch.xpu.max_memory_allocated(device)
vllm/plugins/__init__.py
+2 -1
@@ -2,7 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import logging
5 -from typing import Any, Callable
5 +from collections.abc import Callable
6 +from typing import Any
7
8 import vllm.envs as envs
9
vllm/plugins/io_processors/__init__.py
-2
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import logging
5
6 from vllm.config import VllmConfig
vllm/plugins/io_processors/interface.py
+7 -7
@@ -3,7 +3,7 @@
3
4 from abc import ABC, abstractmethod
5 from collections.abc import AsyncGenerator, Sequence
6 -from typing import Any, Generic, Optional, TypeVar, Union
6 +from typing import Any, Generic, TypeVar
7
8 from vllm.config import VllmConfig
9 from vllm.entrypoints.openai.protocol import IOProcessorResponse
@@ -22,24 +22,24 @@ class IOProcessor(ABC, Generic[IOProcessorInput, IOProcessorOutput]):
22 def pre_process(
23 self,
24 prompt: IOProcessorInput,
25 - request_id: Optional[str] = None,
25 + request_id: str | None = None,
26 **kwargs,
27 - ) -> Union[PromptType, Sequence[PromptType]]:
27 + ) -> PromptType | Sequence[PromptType]:
28 raise NotImplementedError
29
30 async def pre_process_async(
31 self,
32 prompt: IOProcessorInput,
33 - request_id: Optional[str] = None,
33 + request_id: str | None = None,
34 **kwargs,
35 - ) -> Union[PromptType, Sequence[PromptType]]:
35 + ) -> PromptType | Sequence[PromptType]:
36 return self.pre_process(prompt, request_id, **kwargs)
37
38 @abstractmethod
39 def post_process(
40 self,
41 model_output: Sequence[PoolingRequestOutput],
42 - request_id: Optional[str] = None,
42 + request_id: str | None = None,
43 **kwargs,
44 ) -> IOProcessorOutput:
45 raise NotImplementedError
@@ -47,7 +47,7 @@ class IOProcessor(ABC, Generic[IOProcessorInput, IOProcessorOutput]):
47 async def post_process_async(
48 self,
49 model_output: AsyncGenerator[tuple[int, PoolingRequestOutput]],
50 - request_id: Optional[str] = None,
50 + request_id: str | None = None,
51 **kwargs,
52 ) -> IOProcessorOutput:
53 # We cannot guarantee outputs are returned in the same order they were
vllm/plugins/lora_resolvers/filesystem_resolver.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import json
4 import os
5 -from typing import Optional
5
6 import vllm.envs as envs
7 from vllm.lora.request import LoRARequest
@@ -15,7 +14,7 @@ class FilesystemResolver(LoRAResolver):
14
15 async def resolve_lora(
16 self, base_model_name: str, lora_name: str
18 - ) -> Optional[LoRARequest]:
17 + ) -> LoRARequest | None:
18 lora_path = os.path.join(self.lora_cache_dir, lora_name)
19 if os.path.exists(lora_path):
20 adapter_config_path = os.path.join(
vllm/pooling_params.py
+9 -9
@@ -34,32 +34,32 @@ class PoolingParams(
34 """
35
36 # --8<-- [start:common-pooling-params]
37 - truncate_prompt_tokens: Optional[Annotated[int, msgspec.Meta(ge=-1)]] = None
37 + truncate_prompt_tokens: Annotated[int, msgspec.Meta(ge=-1)] | None = None
38 # --8<-- [end:common-pooling-params]
39
40 ## for embeddings models
41 # --8<-- [start:embedding-pooling-params]
42 - dimensions: Optional[int] = None
43 - normalize: Optional[bool] = None
42 + dimensions: int | None = None
43 + normalize: bool | None = None
44 # --8<-- [end:embedding-pooling-params]
45
46 ## for classification, scoring and rerank
47 # --8<-- [start:classification-pooling-params]
48 - activation: Optional[bool] = None
48 + activation: bool | None = None
49 # --8<-- [end:classification-pooling-params]
50
51 ## for reward models
52 - softmax: Optional[bool] = None
53 - step_tag_id: Optional[int] = None
54 - returned_token_ids: Optional[list[int]] = None
52 + softmax: bool | None = None
53 + step_tag_id: int | None = None
54 + returned_token_ids: list[int] | None = None
55
56 - task: Optional[PoolingTask] = None
56 + task: PoolingTask | None = None
57 """Internal use only."""
58
59 requires_token_ids: bool = False
60 """Internal use only."""
61
62 - extra_kwargs: Optional[dict[str, Any]] = None
62 + extra_kwargs: dict[str, Any] | None = None
63 """Internal use only."""
64
65 output_kind: RequestOutputKind = RequestOutputKind.FINAL_ONLY
vllm/profiler/layerwise_profile.py
+10 -9
@@ -3,8 +3,9 @@
3
4 import copy
5 from collections import defaultdict
6 +from collections.abc import Callable
7 from dataclasses import asdict, dataclass, field
7 -from typing import Any, Callable, Optional, TypeAlias, Union
8 +from typing import Any, Optional, TypeAlias
9
10 import pandas as pd
11 from torch._C._autograd import DeviceType, _KinetoEvent, _ProfilerResult
@@ -62,14 +63,14 @@ class ModelStatsEntry:
63 trace: str
64
65
65 -StatsEntry: TypeAlias = Union[ModelStatsEntry, SummaryStatsEntry]
66 +StatsEntry: TypeAlias = ModelStatsEntry | SummaryStatsEntry
67
68
69 @dataclass
70 class _StatsTreeNode:
71 entry: StatsEntry
72 children: list[StatsEntry]
72 - parent: Optional[StatsEntry]
73 + parent: StatsEntry | None
74
75
76 @dataclass
@@ -82,7 +83,7 @@ class LayerwiseProfileResults(profile):
83 _summary_stats_tree: list[_StatsTreeNode] = field(init=False)
84
85 # profile metadata
85 - num_running_seqs: Optional[int] = None
86 + num_running_seqs: int | None = None
87
88 def __post_init__(self):
89 self._build_correlation_map()
@@ -150,7 +151,7 @@ class LayerwiseProfileResults(profile):
151 @staticmethod
152 def _indent_row_names_based_on_depth(
153 depths_rows: list[tuple[int, StatsEntry]],
153 - indent_style: Union[Callable[[int], str], str] = " ",
154 + indent_style: Callable[[int], str] | str = " ",
155 ):
156 indented_rows = []
157 for depth, row in depths_rows:
@@ -171,7 +172,7 @@ class LayerwiseProfileResults(profile):
172 event_tree = self._kineto_results.experimental_event_tree()
173
174 def _df_traversal(
174 - event: _ProfilerEvent, curr_node: Optional[_ModuleTreeNode] = None
175 + event: _ProfilerEvent, curr_node: _ModuleTreeNode | None = None
176 ):
177 # For the tensor parallel case for now only look at task 1
178 if event.start_tid != 1:
@@ -242,7 +243,7 @@ class LayerwiseProfileResults(profile):
243
244 def build_summary_stats_tree_df(
245 node: _ModuleTreeNode,
245 - parent: Optional[_StatsTreeNode] = None,
246 + parent: _StatsTreeNode | None = None,
247 summary_trace: tuple[str] = (),
248 ):
249 if event_has_module(node.event):
@@ -287,7 +288,7 @@ class LayerwiseProfileResults(profile):
288 self._summary_stats_tree.append(build_summary_stats_tree_df(root))
289
290 def build_model_stats_tree_df(
290 - node: _ModuleTreeNode, parent: Optional[_StatsTreeNode] = None
291 + node: _ModuleTreeNode, parent: _StatsTreeNode | None = None
292 ):
293 if event_has_module(
294 node.event,
@@ -357,7 +358,7 @@ class LayerwiseProfileResults(profile):
358
359
360 class layerwise_profile(profile):
360 - def __init__(self, num_running_seqs: Optional[int] = None):
361 + def __init__(self, num_running_seqs: int | None = None):
362 """
363 layerwise profile constructor.
364
vllm/profiler/utils.py
+2 -2
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import dataclasses
5 -from typing import Callable, Union
5 +from collections.abc import Callable
6
7 from torch._C._profiler import _EventType, _ProfilerEvent, _TensorMetadata
8
@@ -78,7 +78,7 @@ class TablePrinter:
78
79
80 def indent_string(
81 - string: str, indent: int, indent_style: Union[Callable[[int], str], str] = " "
81 + string: str, indent: int, indent_style: Callable[[int], str] | str = " "
82 ) -> str:
83 if indent:
84 if isinstance(indent_style, str):
vllm/ray/ray_env.py
+3 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import json
4 import os
5 -from typing import Optional
5
6 import vllm.envs as envs
7 from vllm.logger import init_logger
@@ -32,9 +31,9 @@ except json.JSONDecodeError:
31
32
33 def get_env_vars_to_copy(
35 - exclude_vars: Optional[set[str]] = None,
36 - additional_vars: Optional[set[str]] = None,
37 - destination: Optional[str] = None,
34 + exclude_vars: set[str] | None = None,
35 + additional_vars: set[str] | None = None,
36 + destination: str | None = None,
37 ) -> set[str]:
38 """
39 Get the environment variables to copy to downstream Ray actors.
vllm/reasoning/abs_reasoning_parsers.py
+8 -10
@@ -1,13 +1,11 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import os
5 from abc import abstractmethod
8 -from collections.abc import Sequence
6 +from collections.abc import Callable, Sequence
7 from functools import cached_property
10 -from typing import TYPE_CHECKING, Any, Callable, Union
8 +from typing import TYPE_CHECKING, Any
9
10 from vllm.logger import init_logger
11 from vllm.utils import import_from_path, is_list_of
@@ -78,7 +76,7 @@ class ReasoningParser:
76 def extract_reasoning_content(
77 self,
78 model_output: str,
81 - request: Union[ChatCompletionRequest, ResponsesRequest],
79 + request: ChatCompletionRequest | ResponsesRequest,
80 ) -> tuple[str | None, str | None]:
81 """
82 Extract reasoning content from a complete model-generated string.
@@ -107,7 +105,7 @@ class ReasoningParser:
105 previous_token_ids: Sequence[int],
106 current_token_ids: Sequence[int],
107 delta_token_ids: Sequence[int],
110 - ) -> Union[DeltaMessage, None]:
108 + ) -> DeltaMessage | None:
109 """
110 Instance method that should be implemented for extracting reasoning
111 from an incomplete response; for use when handling reasoning calls and
@@ -136,7 +134,7 @@ class ReasoningParserManager:
134 def _register_module(
135 cls,
136 module: type,
139 - module_name: Union[str, list[str]] | None = None,
137 + module_name: str | list[str] | None = None,
138 force: bool = True,
139 ) -> None:
140 if not issubclass(module, ReasoningParser):
@@ -158,10 +156,10 @@ class ReasoningParserManager:
156 @classmethod
157 def register_module(
158 cls,
161 - name: Union[str, list[str]] | None = None,
159 + name: str | list[str] | None = None,
160 force: bool = True,
163 - module: Union[type, None] = None,
164 - ) -> Union[type, Callable]:
161 + module: type | None = None,
162 + ) -> type | Callable:
163 """
164 Register module with the given name or name list. it can be used as a
165 decoder(with module as None) or normal function(with module as not
vllm/reasoning/basic_parsers.py
+3 -4
@@ -3,7 +3,6 @@
3
4 from abc import abstractmethod
5 from collections.abc import Sequence
6 -from typing import Optional, Union
6
7 from vllm.entrypoints.openai.protocol import (
8 ChatCompletionRequest,
@@ -79,7 +78,7 @@ class BaseThinkingReasoningParser(ReasoningParser):
78 previous_token_ids: Sequence[int],
79 current_token_ids: Sequence[int],
80 delta_token_ids: Sequence[int],
82 - ) -> Union[DeltaMessage, None]:
81 + ) -> DeltaMessage | None:
82 """
83 Extract reasoning content from a delta message.
84 Handles streaming output where previous + delta = current.
@@ -135,8 +134,8 @@ class BaseThinkingReasoningParser(ReasoningParser):
134 return DeltaMessage(content=delta_text)
135
136 def extract_reasoning_content(
138 - self, model_output: str, request: Union[ChatCompletionRequest, ResponsesRequest]
139 - ) -> tuple[Optional[str], Optional[str]]:
137 + self, model_output: str, request: ChatCompletionRequest | ResponsesRequest
138 + ) -> tuple[str | None, str | None]:
139 """
140 Extract reasoning content from the model output.
141
vllm/reasoning/deepseek_r1_reasoning_parser.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Union
5
6 from vllm.entrypoints.openai.protocol import DeltaMessage
7 from vllm.reasoning.abs_reasoning_parsers import ReasoningParserManager
@@ -36,7 +35,7 @@ class DeepSeekR1ReasoningParser(BaseThinkingReasoningParser):
35 previous_token_ids: Sequence[int],
36 current_token_ids: Sequence[int],
37 delta_token_ids: Sequence[int],
39 - ) -> Union[DeltaMessage, None]:
38 + ) -> DeltaMessage | None:
39 ret = super().extract_reasoning_content_streaming(
40 previous_text,
41 current_text,
vllm/reasoning/glm4_moe_reasoning_parser.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Optional, Union
5
6 from transformers import PreTrainedTokenizerBase
7
@@ -80,7 +79,7 @@ class Glm4MoeModelReasoningParser(ReasoningParser):
79 previous_token_ids: Sequence[int],
80 current_token_ids: Sequence[int],
81 delta_token_ids: Sequence[int],
83 - ) -> Union[DeltaMessage, None]:
82 + ) -> DeltaMessage | None:
83 """
84 Extract reasoning content from a delta message.
85 Handles streaming output where previous + delta = current.
@@ -137,7 +136,7 @@ class Glm4MoeModelReasoningParser(ReasoningParser):
136
137 def extract_reasoning_content(
138 self, model_output: str, request: ChatCompletionRequest
140 - ) -> tuple[Optional[str], Optional[str]]:
139 + ) -> tuple[str | None, str | None]:
140 """
141 Extract reasoning content from the model output.
142
vllm/reasoning/gptoss_reasoning_parser.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Optional, Union
5
6 from transformers import PreTrainedTokenizerBase
7
@@ -53,7 +52,7 @@ class GptOssReasoningParser(ReasoningParser):
52 previous_token_ids: Sequence[int],
53 current_token_ids: Sequence[int],
54 delta_token_ids: Sequence[int],
56 - ) -> Union[DeltaMessage, None]:
55 + ) -> DeltaMessage | None:
56 prev_reasoning, prev_content, _ = parse_chat_output(list(previous_token_ids))
57 cur_reasoning, cur_content, _ = parse_chat_output(list(current_token_ids))
58 reasoning_delta = None
@@ -78,7 +77,7 @@ class GptOssReasoningParser(ReasoningParser):
77 self,
78 model_output: str,
79 request: ChatCompletionRequest,
81 - ) -> tuple[Optional[str], Optional[str]]:
80 + ) -> tuple[str | None, str | None]:
81 raise NotImplementedError(
82 "gpt-oss has a special branch for parsing reasoning in non-streaming mode. This method shouldn't be used." # noqa: E501
83 )
vllm/reasoning/granite_reasoning_parser.py
+3 -4
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Optional, Union
5
6 import regex as re
7 from transformers import PreTrainedTokenizerBase
@@ -53,7 +52,7 @@ class GraniteReasoningParser(ReasoningParser):
52
53 def extract_reasoning_content(
54 self, model_output: str, request: ChatCompletionRequest
56 - ) -> tuple[Optional[str], Optional[str]]:
55 + ) -> tuple[str | None, str | None]:
56 """Extract the reasoning content & content sections, respectively.
57 If the sequence doesn't match what we expect, i.e., the model generates
58 something else, all content is considered non-reasoning content.
@@ -82,7 +81,7 @@ class GraniteReasoningParser(ReasoningParser):
81 previous_token_ids: Sequence[int],
82 current_token_ids: Sequence[int],
83 delta_token_ids: Sequence[int],
85 - ) -> Union[DeltaMessage, None]:
84 + ) -> DeltaMessage | None:
85 """Extract the reasoning content / content emitted by granite models;
86 If the sequence doesn't match what we expect, i.e., the model generates
87 something else, all content is considered non-reasoning content.
@@ -322,7 +321,7 @@ class GraniteReasoningParser(ReasoningParser):
321
322 def _get_content_sections(
323 self, current_text: str
325 - ) -> tuple[Optional[str], Optional[int], Optional[str]]:
324 + ) -> tuple[str | None, int | None, str | None]:
325 """Parse the text to extract the reasoning content / content
326 if we have them.
327
vllm/reasoning/hunyuan_a13b_reasoning_parser.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Optional, Union
5
6 import regex as re
7 from transformers import PreTrainedTokenizerBase
@@ -90,7 +89,7 @@ class HunyuanA13BReasoningParser(ReasoningParser):
89
90 def extract_reasoning_content(
91 self, model_output: str, request: ChatCompletionRequest
93 - ) -> tuple[Optional[str], Optional[str]]:
92 + ) -> tuple[str | None, str | None]:
93 """Extract the reasoning content & content sections, respectively.
94 If the sequence doesn't match what we expect, i.e., the model generates
95 something else, all content is considered non-reasoning content.
@@ -150,7 +149,7 @@ class HunyuanA13BReasoningParser(ReasoningParser):
149 previous_token_ids: Sequence[int],
150 current_token_ids: Sequence[int],
151 delta_token_ids: Sequence[int],
153 - ) -> Union[DeltaMessage, None]:
152 + ) -> DeltaMessage | None:
153 """Extract content using token ID sequence state machine"""
154 # Define sequences
155 think_start_sequence = self.think_start_ids
vllm/reasoning/olmo3_reasoning_parser.py
+8 -8
@@ -4,7 +4,7 @@
4 import dataclasses as dt
5 import enum
6 from collections.abc import Sequence
7 -from typing import TYPE_CHECKING, Optional, Union
7 +from typing import TYPE_CHECKING
8
9 import regex as re
10
@@ -36,7 +36,7 @@ class Indices:
36 return self.end - self.start
37
38
39 -def string_overlap(a: str, b: str) -> tuple[Optional[Indices], Optional[Indices]]:
39 +def string_overlap(a: str, b: str) -> tuple[Indices | None, Indices | None]:
40 """
41 Find the longest overlap where the end of string a matches the start
42 of string b.
@@ -90,7 +90,7 @@ class Olmo3ReasoningBuffer:
90 # is when we switch to content state.
91 state: Olmo3ReasoningState = Olmo3ReasoningState.REASONING
92
93 - def process_buffer(self) -> Optional[DeltaMessage]:
93 + def process_buffer(self) -> DeltaMessage | None:
94 start_think_idx = self.buffer.find(self.think_start)
95
96 if start_think_idx >= 0:
@@ -142,12 +142,12 @@ class Olmo3ReasoningBuffer:
142 # is the length of the text buffer
143 return len(self.buffer)
144
145 - def add_text(self, delta_text: str) -> Optional[DeltaMessage]:
145 + def add_text(self, delta_text: str) -> DeltaMessage | None:
146 # we start by adding the delta text to the buffer
147 self.buffer += delta_text
148
149 # setting this to empty before starting
150 - delta_message: Optional[DeltaMessage] = None
150 + delta_message: DeltaMessage | None = None
151
152 # we start by computing the overlap between the delta_text
153 # and start/end of think tokens.
@@ -254,8 +254,8 @@ class Olmo3ReasoningParser(ReasoningParser):
254 def extract_reasoning_content(
255 self,
256 model_output: str,
257 - request: Union[ChatCompletionRequest, ResponsesRequest],
258 - ) -> tuple[Optional[str], Optional[str]]:
257 + request: ChatCompletionRequest | ResponsesRequest,
258 + ) -> tuple[str | None, str | None]:
259 """Extract the reasoning content & content sections, respectively.
260 If the sequence doesn't match what we expect, i.e., the model generates
261 something else, all content is considered non-reasoning content.
@@ -287,7 +287,7 @@ class Olmo3ReasoningParser(ReasoningParser):
287 previous_token_ids: Sequence[int],
288 current_token_ids: Sequence[int],
289 delta_token_ids: Sequence[int],
290 - ) -> Union[DeltaMessage, None]:
290 + ) -> DeltaMessage | None:
291 """Extract content using token ID sequence state machine"""
292
293 delta_message = self.buffer.add_text(delta_text)
vllm/reasoning/qwen3_reasoning_parser.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 from vllm.entrypoints.openai.protocol import ChatCompletionRequest, ResponsesRequest
6 from vllm.reasoning.abs_reasoning_parsers import ReasoningParserManager
@@ -31,8 +30,8 @@ class Qwen3ReasoningParser(BaseThinkingReasoningParser):
30 return "</think>"
31
32 def extract_reasoning_content(
34 - self, model_output: str, request: Union[ChatCompletionRequest, ResponsesRequest]
35 - ) -> tuple[Optional[str], Optional[str]]:
33 + self, model_output: str, request: ChatCompletionRequest | ResponsesRequest
34 + ) -> tuple[str | None, str | None]:
35 """
36 Extract reasoning content from the model output.
37
vllm/reasoning/step3_reasoning_parser.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from collections.abc import Sequence
5 -from typing import Optional, Union
5
6 import regex as re
7 from transformers import PreTrainedTokenizerBase
@@ -50,7 +49,7 @@ class Step3ReasoningParser(ReasoningParser):
49 previous_token_ids: Sequence[int],
50 current_token_ids: Sequence[int],
51 delta_token_ids: Sequence[int],
53 - ) -> Union[DeltaMessage, None]:
52 + ) -> DeltaMessage | None:
53 """
54 Extract reasoning content from a delta message.
55 Handles streaming output where previous + delta = current.
@@ -81,7 +80,7 @@ class Step3ReasoningParser(ReasoningParser):
80
81 def extract_reasoning_content(
82 self, model_output: str, request: ChatCompletionRequest
84 - ) -> tuple[Optional[str], Optional[str]]:
83 + ) -> tuple[str | None, str | None]:
84 # Check if the model output contains the </think> token
85 if self.think_end_token not in model_output:
86 # If no </think> token, everything is reasoning content
vllm/sampling_params.py
+51 -51
@@ -7,7 +7,7 @@ import warnings
7 from dataclasses import field
8 from enum import Enum, IntEnum
9 from functools import cached_property
10 -from typing import Annotated, Any, Optional, Union
10 +from typing import Annotated, Any
11
12 import msgspec
13 from pydantic.dataclasses import dataclass
@@ -32,19 +32,19 @@ class SamplingType(IntEnum):
32 @dataclass
33 class StructuredOutputsParams:
34 # One of these fields will be used to build a logit processor.
35 - json: Optional[Union[str, dict]] = None
36 - regex: Optional[str] = None
37 - choice: Optional[list[str]] = None
38 - grammar: Optional[str] = None
39 - json_object: Optional[bool] = None
35 + json: str | dict | None = None
36 + regex: str | None = None
37 + choice: list[str] | None = None
38 + grammar: str | None = None
39 + json_object: bool | None = None
40 # These are other options that can be set.
41 disable_fallback: bool = False
42 disable_any_whitespace: bool = False
43 disable_additional_properties: bool = False
44 - whitespace_pattern: Optional[str] = None
45 - structural_tag: Optional[str] = None
44 + whitespace_pattern: str | None = None
45 + structural_tag: str | None = None
46
47 - _backend: Optional[str] = field(default=None, init=False)
47 + _backend: str | None = field(default=None, init=False)
48 """CAUTION: Should only be set by Processor._validate_structured_output"""
49 _backend_was_auto: bool = field(default=False, init=False)
50 """CAUTION: Should only be set by Processor._validate_structured_output"""
@@ -110,12 +110,12 @@ class SamplingParams(
110 are generated and streamed cumulatively per request. To see all `n`
111 outputs upon completion, use `output_kind=RequestOutputKind.FINAL_ONLY`
112 in `SamplingParams`."""
113 - best_of: Optional[int] = None
113 + best_of: int | None = None
114 """Number of output sequences that are generated from the prompt. From
115 these `best_of` sequences, the top `n` sequences are returned. `best_of`
116 must be greater than or equal to `n`. By default, `best_of` is set to `n`.
117 Warning, this is only supported in V0."""
118 - _real_n: Optional[int] = None
118 + _real_n: int | None = None
119 presence_penalty: float = 0.0
120 """Penalizes new tokens based on whether they appear in the generated text
121 so far. Values > 0 encourage the model to use new tokens, while values < 0
@@ -142,24 +142,24 @@ class SamplingParams(
142 """Represents the minimum probability for a token to be considered,
143 relative to the probability of the most likely token. Must be in [0, 1].
144 Set to 0 to disable this."""
145 - seed: Optional[int] = None
145 + seed: int | None = None
146 """Random seed to use for the generation."""
147 - stop: Optional[Union[str, list[str]]] = None
147 + stop: str | list[str] | None = None
148 """String(s) that stop the generation when they are generated. The returned
149 output will not contain the stop strings."""
150 - stop_token_ids: Optional[list[int]] = None
150 + stop_token_ids: list[int] | None = None
151 """Token IDs that stop the generation when they are generated. The returned
152 output will contain the stop tokens unless the stop tokens are special
153 tokens."""
154 ignore_eos: bool = False
155 """Whether to ignore the EOS token and continue generating
156 tokens after the EOS token is generated."""
157 - max_tokens: Optional[int] = 16
157 + max_tokens: int | None = 16
158 """Maximum number of tokens to generate per output sequence."""
159 min_tokens: int = 0
160 """Minimum number of tokens to generate per output sequence before EOS or
161 `stop_token_ids` can be generated"""
162 - logprobs: Optional[int] = None
162 + logprobs: int | None = None
163 """Number of log probabilities to return per output token. When set to
164 `None`, no probability is returned. If set to a non-`None` value, the
165 result includes the log probabilities of the specified number of most
@@ -167,7 +167,7 @@ class SamplingParams(
167 follows the OpenAI API: The API will always return the log probability of
168 the sampled token, so there may be up to `logprobs+1` elements in the
169 response. When set to -1, return all `vocab_size` log probabilities."""
170 - prompt_logprobs: Optional[int] = None
170 + prompt_logprobs: int | None = None
171 """Number of log probabilities to return per prompt token.
172 When set to -1, return all `vocab_size` log probabilities."""
173 # NOTE: This parameter is only exposed at the engine level for now.
@@ -179,14 +179,14 @@ class SamplingParams(
179 """Whether to skip special tokens in the output."""
180 spaces_between_special_tokens: bool = True
181 """Whether to add spaces between special tokens in the output."""
182 - # Optional[list[LogitsProcessor]] type. We use Any here because
183 - # Optional[list[LogitsProcessor]] type is not supported by msgspec.
184 - logits_processors: Optional[Any] = None
182 + # `list[LogitsProcessor] | None` type. We use Any here because
183 + # `list[LogitsProcessor] | None` type is not supported by msgspec.
184 + logits_processors: Any | None = None
185 """Functions that modify logits based on previously generated tokens, and
186 optionally prompt tokens as a first argument."""
187 include_stop_str_in_output: bool = False
188 """Whether to include the stop strings in output text."""
189 - truncate_prompt_tokens: Optional[Annotated[int, msgspec.Meta(ge=-1)]] = None
189 + truncate_prompt_tokens: Annotated[int, msgspec.Meta(ge=-1)] | None = None
190 """If set to -1, will use the truncation size supported by the model. If
191 set to an integer k, will use only the last k tokens from the prompt
192 (i.e., left truncation). If set to `None`, truncation is disabled."""
@@ -198,60 +198,60 @@ class SamplingParams(
198 _all_stop_token_ids: set[int] = msgspec.field(default_factory=set)
199
200 # Fields used to construct logits processors
201 - structured_outputs: Optional[StructuredOutputsParams] = None
201 + structured_outputs: StructuredOutputsParams | None = None
202 """Parameters for configuring structured outputs."""
203 - guided_decoding: Optional[GuidedDecodingParams] = None
203 + guided_decoding: GuidedDecodingParams | None = None
204 """Deprecated alias for structured_outputs."""
205 - logit_bias: Optional[dict[int, float]] = None
205 + logit_bias: dict[int, float] | None = None
206 """If provided, the engine will construct a logits processor that applies
207 these logit biases."""
208 - allowed_token_ids: Optional[list[int]] = None
208 + allowed_token_ids: list[int] | None = None
209 """If provided, the engine will construct a logits processor which only
210 retains scores for the given token ids."""
211 - extra_args: Optional[dict[str, Any]] = None
211 + extra_args: dict[str, Any] | None = None
212 """Arbitrary additional args, that can be used by custom sampling
213 implementations, plugins, etc. Not used by any in-tree sampling
214 implementations."""
215
216 # Fields used for bad words
217 - bad_words: Optional[list[str]] = None
217 + bad_words: list[str] | None = None
218 """Words that are not allowed to be generated. More precisely, only the
219 last token of a corresponding token sequence is not allowed when the next
220 generated token can complete the sequence."""
221 - _bad_words_token_ids: Optional[list[list[int]]] = None
221 + _bad_words_token_ids: list[list[int]] | None = None
222
223 @staticmethod
224 def from_optional(
225 - n: Optional[int] = 1,
226 - best_of: Optional[int] = None,
227 - presence_penalty: Optional[float] = 0.0,
228 - frequency_penalty: Optional[float] = 0.0,
229 - repetition_penalty: Optional[float] = 1.0,
230 - temperature: Optional[float] = 1.0,
231 - top_p: Optional[float] = 1.0,
225 + n: int | None = 1,
226 + best_of: int | None = None,
227 + presence_penalty: float | None = 0.0,
228 + frequency_penalty: float | None = 0.0,
229 + repetition_penalty: float | None = 1.0,
230 + temperature: float | None = 1.0,
231 + top_p: float | None = 1.0,
232 top_k: int = 0,
233 min_p: float = 0.0,
234 - seed: Optional[int] = None,
235 - stop: Optional[Union[str, list[str]]] = None,
236 - stop_token_ids: Optional[list[int]] = None,
237 - bad_words: Optional[list[str]] = None,
234 + seed: int | None = None,
235 + stop: str | list[str] | None = None,
236 + stop_token_ids: list[int] | None = None,
237 + bad_words: list[str] | None = None,
238 include_stop_str_in_output: bool = False,
239 ignore_eos: bool = False,
240 - max_tokens: Optional[int] = 16,
240 + max_tokens: int | None = 16,
241 min_tokens: int = 0,
242 - logprobs: Optional[int] = None,
243 - prompt_logprobs: Optional[int] = None,
242 + logprobs: int | None = None,
243 + prompt_logprobs: int | None = None,
244 detokenize: bool = True,
245 skip_special_tokens: bool = True,
246 spaces_between_special_tokens: bool = True,
247 - logits_processors: Optional[list[LogitsProcessor]] = None,
248 - truncate_prompt_tokens: Optional[Annotated[int, msgspec.Meta(ge=-1)]] = None,
247 + logits_processors: list[LogitsProcessor] | None = None,
248 + truncate_prompt_tokens: Annotated[int, msgspec.Meta(ge=-1)] | None = None,
249 output_kind: RequestOutputKind = RequestOutputKind.CUMULATIVE,
250 - structured_outputs: Optional[StructuredOutputsParams] = None,
251 - guided_decoding: Optional[GuidedDecodingParams] = None,
252 - logit_bias: Optional[Union[dict[int, float], dict[str, float]]] = None,
253 - allowed_token_ids: Optional[list[int]] = None,
254 - extra_args: Optional[dict[str, Any]] = None,
250 + structured_outputs: StructuredOutputsParams | None = None,
251 + guided_decoding: GuidedDecodingParams | None = None,
252 + logit_bias: dict[int, float] | dict[str, float] | None = None,
253 + allowed_token_ids: list[int] | None = None,
254 + extra_args: dict[str, Any] | None = None,
255 ) -> "SamplingParams":
256 if logit_bias is not None:
257 # Convert token_id to integer
@@ -483,7 +483,7 @@ class SamplingParams(
483 def update_from_generation_config(
484 self,
485 generation_config: dict[str, Any],
486 - model_eos_token_id: Optional[int] = None,
486 + model_eos_token_id: int | None = None,
487 ) -> None:
488 """Update if there are non-default values from generation_config"""
489
@@ -559,7 +559,7 @@ class SamplingParams(
559 return self._all_stop_token_ids
560
561 @property
562 - def bad_words_token_ids(self) -> Optional[list[list[int]]]:
562 + def bad_words_token_ids(self) -> list[list[int]] | None:
563 # For internal use only. Backward compatibility not guaranteed
564 return self._bad_words_token_ids
565
vllm/scalar_type.py
+6 -7
@@ -5,7 +5,6 @@ import functools
5 import struct
6 from dataclasses import dataclass
7 from enum import Enum
8 -from typing import Optional, Union
8
9 _SCALAR_TYPES_ID_MAP = {}
10
@@ -105,7 +104,7 @@ class ScalarType:
104 double_raw = self._floating_point_max_int()
105 return struct.unpack("!d", struct.pack("!Q", double_raw))[0]
106
108 - def _raw_max(self) -> Union[int, float]:
107 + def _raw_max(self) -> int | float:
108 if self.is_floating_point():
109 return self._floating_point_max()
110 else:
@@ -114,7 +113,7 @@ class ScalarType:
113 )
114 return (1 << self.mantissa) - 1
115
117 - def _raw_min(self) -> Union[int, float]:
116 + def _raw_min(self) -> int | float:
117 if self.is_floating_point():
118 assert self.is_signed(), (
119 "We currently assume all floating point types are signed"
@@ -168,14 +167,14 @@ class ScalarType:
167 def size_bits(self) -> int:
168 return self.exponent + self.mantissa + int(self.signed)
169
171 - def min(self) -> Union[int, float]:
170 + def min(self) -> int | float:
171 """
172 Min representable value for this scalar type.
173 (accounting for bias if there is one)
174 """
175 return self._raw_min() - self.bias
176
178 - def max(self) -> Union[int, float]:
177 + def max(self) -> int | float:
178 """
179 Max representable value for this scalar type.
180 (accounting for bias if there is one)
@@ -265,14 +264,14 @@ class ScalarType:
264 #
265
266 @classmethod
268 - def int_(cls, size_bits: int, bias: Optional[int]) -> "ScalarType":
267 + def int_(cls, size_bits: int, bias: int | None) -> "ScalarType":
268 "Create a signed integer scalar type (size_bits includes sign-bit)."
269 ret = cls(0, size_bits - 1, True, bias if bias else 0)
270 ret.id # noqa B018: make sure the id is cached
271 return ret
272
273 @classmethod
275 - def uint(cls, size_bits: int, bias: Optional[int]) -> "ScalarType":
274 + def uint(cls, size_bits: int, bias: int | None) -> "ScalarType":
275 """Create an unsigned integer scalar type."""
276 ret = cls(0, size_bits, False, bias if bias else 0)
277 ret.id # noqa B018: make sure the id is cached
vllm/sequence.py
+10 -10
@@ -3,7 +3,7 @@
3 """Sequence and its related classes."""
4
5 from dataclasses import dataclass
6 -from typing import TYPE_CHECKING, Any, Optional, Union
6 +from typing import TYPE_CHECKING, Any
7
8 import msgspec
9 import torch
@@ -39,13 +39,13 @@ class RequestMetrics:
39
40 arrival_time: float
41 last_token_time: float
42 - first_scheduled_time: Optional[float]
43 - first_token_time: Optional[float]
44 - time_in_queue: Optional[float]
45 - finished_time: Optional[float] = None
46 - scheduler_time: Optional[float] = None
47 - model_forward_time: Optional[float] = None
48 - model_execute_time: Optional[float] = None
42 + first_scheduled_time: float | None
43 + first_token_time: float | None
44 + time_in_queue: float | None
45 + finished_time: float | None = None
46 + scheduler_time: float | None = None
47 + model_forward_time: float | None = None
48 + model_execute_time: float | None = None
49
50
51 # cannot use msgspec.Struct here because Dynamo does not support it
@@ -59,7 +59,7 @@ class IntermediateTensors:
59 """
60
61 tensors: dict[str, torch.Tensor]
62 - kv_connector_output: Optional[KVConnectorOutput]
62 + kv_connector_output: KVConnectorOutput | None
63
64 def __init__(self, tensors):
65 # manually define this function, so that
@@ -68,7 +68,7 @@ class IntermediateTensors:
68 # a string, and we will lose the information about the source file.
69 self.tensors = tensors
70
71 - def __getitem__(self, key: Union[str, slice]):
71 + def __getitem__(self, key: str | slice):
72 if isinstance(key, str):
73 return self.tensors[key]
74 elif isinstance(key, slice):
vllm/tracing.py
+3 -4
@@ -3,7 +3,6 @@
3
4 import os
5 from collections.abc import Mapping
6 -from typing import Optional
6
7 from vllm.logger import init_logger
8 from vllm.utils import run_once
@@ -13,7 +12,7 @@ TRACE_HEADERS = ["traceparent", "tracestate"]
12 logger = init_logger(__name__)
13
14 _is_otel_imported = False
16 -otel_import_error_traceback: Optional[str] = None
15 +otel_import_error_traceback: str | None = None
16 try:
17 from opentelemetry.context.context import Context
18 from opentelemetry.sdk.environment_variables import (
@@ -55,7 +54,7 @@ def is_otel_available() -> bool:
54
55 def init_tracer(
56 instrumenting_module_name: str, otlp_traces_endpoint: str
58 -) -> Optional[Tracer]:
57 +) -> Tracer | None:
58 if not is_otel_available():
59 raise ValueError(
60 "OpenTelemetry is not available. Unable to initialize "
@@ -88,7 +87,7 @@ def get_span_exporter(endpoint):
87 return OTLPSpanExporter(endpoint=endpoint)
88
89
91 -def extract_trace_context(headers: Optional[Mapping[str, str]]) -> Optional[Context]:
90 +def extract_trace_context(headers: Mapping[str, str] | None) -> Context | None:
91 if is_otel_available():
92 headers = headers or {}
93 return TraceContextTextMapPropagator().extract(headers)
vllm/transformers_utils/chat_templates/registry.py
+6 -5
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +from collections.abc import Callable
4 from pathlib import Path
4 -from typing import Callable, Optional, Union
5 +from typing import TypeAlias
6
7 from vllm.logger import init_logger
8
@@ -9,17 +10,17 @@ logger = init_logger(__file__)
10
11 CHAT_TEMPLATES_DIR = Path(__file__).parent
12
12 -ChatTemplatePath = Union[Path, Callable[[str], Optional[Path]]]
13 +ChatTemplatePath: TypeAlias = Path | Callable[[str], Path | None]
14
15
15 -def _get_qwen_chat_template_fallback(tokenizer_name_or_path: str) -> Optional[Path]:
16 +def _get_qwen_chat_template_fallback(tokenizer_name_or_path: str) -> Path | None:
17 if tokenizer_name_or_path.endswith("-Chat"):
18 return CHAT_TEMPLATES_DIR / "template_chatml.jinja"
19
20 return CHAT_TEMPLATES_DIR / "template_basic.jinja"
21
22
22 -def _get_minicpmv_chat_template_fallback(tokenizer_name_or_path: str) -> Optional[Path]:
23 +def _get_minicpmv_chat_template_fallback(tokenizer_name_or_path: str) -> Path | None:
24 # MiniCPM-V-4.5 version uses a dedicated template
25 if "4.5" in tokenizer_name_or_path or "4_5" in tokenizer_name_or_path:
26 return CHAT_TEMPLATES_DIR / "template_minicpmv45.jinja"
@@ -58,7 +59,7 @@ def register_chat_template_fallback_path(
59 def get_chat_template_fallback_path(
60 model_type: str,
61 tokenizer_name_or_path: str,
61 -) -> Optional[Path]:
62 +) -> Path | None:
63 chat_template = _MODEL_TYPE_TO_CHAT_TEMPLATE_FALLBACK.get(model_type)
64 if callable(chat_template):
65 chat_template = chat_template(tokenizer_name_or_path)
vllm/transformers_utils/config.py
+47 -46
@@ -4,10 +4,11 @@
4 import json
5 import os
6 import time
7 +from collections.abc import Callable
8 from dataclasses import asdict
9 from functools import cache, partial
10 from pathlib import Path
10 -from typing import Any, Callable, Literal, Optional, TypeVar, Union
11 +from typing import Any, Literal, TypeVar
12
13 import huggingface_hub
14 from huggingface_hub import (
@@ -47,7 +48,7 @@ MISTRAL_CONFIG_NAME = "params.json"
48 logger = init_logger(__name__)
49
50
50 -def _get_hf_token() -> Optional[str]:
51 +def _get_hf_token() -> str | None:
52 """
53 Get the HuggingFace token from environment variable.
54
@@ -108,10 +109,10 @@ _AUTO_CONFIG_KWARGS_OVERRIDES: dict[str, dict[str, Any]] = {
109 class HFConfigParser(ConfigParserBase):
110 def parse(
111 self,
111 - model: Union[str, Path],
112 + model: str | Path,
113 trust_remote_code: bool,
113 - revision: Optional[str] = None,
114 - code_revision: Optional[str] = None,
114 + revision: str | None = None,
115 + code_revision: str | None = None,
116 **kwargs,
117 ) -> tuple[dict, PretrainedConfig]:
118 kwargs["local_files_only"] = huggingface_hub.constants.HF_HUB_OFFLINE
@@ -173,10 +174,10 @@ class HFConfigParser(ConfigParserBase):
174 class MistralConfigParser(ConfigParserBase):
175 def parse(
176 self,
176 - model: Union[str, Path],
177 + model: str | Path,
178 trust_remote_code: bool,
178 - revision: Optional[str] = None,
179 - code_revision: Optional[str] = None,
179 + revision: str | None = None,
180 + code_revision: str | None = None,
181 **kwargs,
182 ) -> tuple[dict, PretrainedConfig]:
183 # This function loads a params.json config which
@@ -247,8 +248,8 @@ def register_config_parser(config_format: str):
248 ... self,
249 ... model: Union[str, Path],
250 ... trust_remote_code: bool,
250 - ... revision: Optional[str] = None,
251 - ... code_revision: Optional[str] = None,
251 + ... revision: str | None = None,
252 + ... code_revision: str | None = None,
253 ... **kwargs,
254 ... ) -> tuple[dict, PretrainedConfig]:
255 ... raise NotImplementedError
@@ -310,9 +311,9 @@ def with_retry(
311 def list_repo_files(
312 repo_id: str,
313 *,
313 - revision: Optional[str] = None,
314 - repo_type: Optional[str] = None,
315 - token: Union[str, bool, None] = None,
314 + revision: str | None = None,
315 + repo_type: str | None = None,
316 + token: str | bool | None = None,
317 ) -> list[str]:
318 def lookup_files() -> list[str]:
319 # directly list files if model is local
@@ -348,9 +349,9 @@ def file_exists(
349 repo_id: str,
350 file_name: str,
351 *,
351 - repo_type: Optional[str] = None,
352 - revision: Optional[str] = None,
353 - token: Union[str, bool, None] = None,
352 + repo_type: str | None = None,
353 + revision: str | None = None,
354 + token: str | bool | None = None,
355 ) -> bool:
356 file_list = list_repo_files(
357 repo_id, repo_type=repo_type, revision=revision, token=token
@@ -360,7 +361,7 @@ def file_exists(
361
362 # In offline mode the result can be a false negative
363 def file_or_path_exists(
363 - model: Union[str, Path], config_name: str, revision: Optional[str]
364 + model: str | Path, config_name: str, revision: str | None
365 ) -> bool:
366 if (local_path := Path(model)).exists():
367 return (local_path / config_name).is_file()
@@ -493,10 +494,10 @@ def maybe_override_with_speculators(
494 model: str,
495 tokenizer: str,
496 trust_remote_code: bool,
496 - revision: Optional[str] = None,
497 - vllm_speculative_config: Optional[dict[str, Any]] = None,
497 + revision: str | None = None,
498 + vllm_speculative_config: dict[str, Any] | None = None,
499 **kwargs,
499 -) -> tuple[str, str, Optional[dict[str, Any]]]:
500 +) -> tuple[str, str, dict[str, Any] | None]:
501 """
502 Resolve model configuration when speculators are detected.
503
@@ -551,13 +552,13 @@ def maybe_override_with_speculators(
552
553
554 def get_config(
554 - model: Union[str, Path],
555 + model: str | Path,
556 trust_remote_code: bool,
556 - revision: Optional[str] = None,
557 - code_revision: Optional[str] = None,
558 - config_format: Union[str, ConfigFormat] = "auto",
559 - hf_overrides_kw: Optional[dict[str, Any]] = None,
560 - hf_overrides_fn: Optional[Callable[[PretrainedConfig], PretrainedConfig]] = None,
557 + revision: str | None = None,
558 + code_revision: str | None = None,
559 + config_format: str | ConfigFormat = "auto",
560 + hf_overrides_kw: dict[str, Any] | None = None,
561 + hf_overrides_fn: Callable[[PretrainedConfig], PretrainedConfig] | None = None,
562 **kwargs,
563 ) -> PretrainedConfig:
564 # Separate model folder from file path for GGUF models
@@ -669,8 +670,8 @@ def get_config(
670
671
672 def try_get_local_file(
672 - model: Union[str, Path], file_name: str, revision: Optional[str] = "main"
673 -) -> Optional[Path]:
673 + model: str | Path, file_name: str, revision: str | None = "main"
674 +) -> Path | None:
675 file_path = Path(model) / file_name
676 if file_path.is_file():
677 return file_path
@@ -687,7 +688,7 @@ def try_get_local_file(
688
689
690 def get_hf_file_to_dict(
690 - file_name: str, model: Union[str, Path], revision: Optional[str] = "main"
691 + file_name: str, model: str | Path, revision: str | None = "main"
692 ):
693 """
694 Downloads a file from the Hugging Face Hub and returns
@@ -735,7 +736,7 @@ def get_hf_file_to_dict(
736
737
738 @cache
738 -def get_pooling_config(model: str, revision: Optional[str] = "main") -> Optional[dict]:
739 +def get_pooling_config(model: str, revision: str | None = "main") -> dict | None:
740 """
741 This function gets the pooling and normalize
742 config from the model - only applies to
@@ -799,7 +800,7 @@ def get_pooling_config(model: str, revision: Optional[str] = "main") -> Optional
800 return None
801
802
802 -def get_pooling_config_name(pooling_name: str) -> Union[str, None]:
803 +def get_pooling_config_name(pooling_name: str) -> str | None:
804 if "pooling_mode_" in pooling_name:
805 pooling_name = pooling_name.replace("pooling_mode_", "")
806
@@ -820,7 +821,7 @@ def get_pooling_config_name(pooling_name: str) -> Union[str, None]:
821
822 @cache
823 def get_sentence_transformer_tokenizer_config(
823 - model: Union[str, Path], revision: Optional[str] = "main"
824 + model: str | Path, revision: str | None = "main"
825 ):
826 """
827 Returns the tokenization configuration dictionary for a
@@ -958,9 +959,9 @@ def maybe_register_config_serialize_by_value() -> None:
959
960
961 def get_hf_image_processor_config(
961 - model: Union[str, Path],
962 - hf_token: Optional[Union[bool, str]] = None,
963 - revision: Optional[str] = None,
962 + model: str | Path,
963 + hf_token: bool | str | None = None,
964 + revision: str | None = None,
965 **kwargs,
966 ) -> dict[str, Any]:
967 # ModelScope does not provide an interface for image_processor
@@ -992,9 +993,9 @@ def get_hf_text_config(config: PretrainedConfig):
993 def try_get_generation_config(
994 model: str,
995 trust_remote_code: bool,
995 - revision: Optional[str] = None,
996 - config_format: Union[str, ConfigFormat] = "auto",
997 -) -> Optional[GenerationConfig]:
996 + revision: str | None = None,
997 + config_format: str | ConfigFormat = "auto",
998 +) -> GenerationConfig | None:
999 try:
1000 return GenerationConfig.from_pretrained(
1001 model,
@@ -1016,7 +1017,7 @@ def try_get_generation_config(
1017 def try_get_safetensors_metadata(
1018 model: str,
1019 *,
1019 - revision: Optional[str] = None,
1020 + revision: str | None = None,
1021 ):
1022 get_safetensors_metadata_partial = partial(
1023 get_safetensors_metadata,
@@ -1034,10 +1035,10 @@ def try_get_safetensors_metadata(
1035
1036
1037 def try_get_tokenizer_config(
1037 - pretrained_model_name_or_path: Union[str, os.PathLike],
1038 + pretrained_model_name_or_path: str | os.PathLike,
1039 trust_remote_code: bool,
1039 - revision: Optional[str] = None,
1040 -) -> Optional[dict[str, Any]]:
1040 + revision: str | None = None,
1041 +) -> dict[str, Any] | None:
1042 try:
1043 return get_tokenizer_config(
1044 pretrained_model_name_or_path,
@@ -1051,7 +1052,7 @@ def try_get_tokenizer_config(
1052 def get_safetensors_params_metadata(
1053 model: str,
1054 *,
1054 - revision: Optional[str] = None,
1055 + revision: str | None = None,
1056 ) -> dict[str, Any]:
1057 """
1058 Get the safetensors metadata for remote model repository.
@@ -1112,7 +1113,7 @@ def _maybe_retrieve_max_pos_from_hf(model, revision, **kwargs) -> int:
1113 return max_position_embeddings
1114
1115
1115 -def get_model_path(model: Union[str, Path], revision: Optional[str] = None):
1116 +def get_model_path(model: str | Path, revision: str | None = None):
1117 if os.path.exists(model):
1118 return model
1119 assert huggingface_hub.constants.HF_HUB_OFFLINE
@@ -1132,8 +1133,8 @@ def get_model_path(model: Union[str, Path], revision: Optional[str] = None):
1133
1134
1135 def get_hf_file_bytes(
1135 - file_name: str, model: Union[str, Path], revision: Optional[str] = "main"
1136 -) -> Optional[bytes]:
1136 + file_name: str, model: str | Path, revision: str | None = "main"
1137 +) -> bytes | None:
1138 """Get file contents from HuggingFace repository as bytes."""
1139 file_path = try_get_local_file(model=model, file_name=file_name, revision=revision)
1140
vllm/transformers_utils/config_parser_base.py
+3 -4
@@ -3,7 +3,6 @@
3
4 from abc import ABC, abstractmethod
5 from pathlib import Path
6 -from typing import Optional, Union
6
7 from transformers import PretrainedConfig
8
@@ -12,10 +11,10 @@ class ConfigParserBase(ABC):
11 @abstractmethod
12 def parse(
13 self,
15 - model: Union[str, Path],
14 + model: str | Path,
15 trust_remote_code: bool,
17 - revision: Optional[str] = None,
18 - code_revision: Optional[str] = None,
16 + revision: str | None = None,
17 + code_revision: str | None = None,
18 **kwargs,
19 ) -> tuple[dict, PretrainedConfig]:
20 raise NotImplementedError
vllm/transformers_utils/configs/dotsocr.py
+2 -2
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, Optional
3 +from typing import Any
4
5 from transformers.configuration_utils import PretrainedConfig
6 from transformers.models.qwen2 import Qwen2Config
@@ -57,7 +57,7 @@ class DotsOCRConfig(Qwen2Config):
57 self,
58 image_token_id=151665,
59 video_token_id=151656,
60 - vision_config: Optional[dict] = None,
60 + vision_config: dict | None = None,
61 *args,
62 **kwargs,
63 ):
vllm/transformers_utils/configs/eagle.py
+5 -6
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import os
5 -from typing import Optional, Union
5
6 from transformers import AutoConfig, PretrainedConfig
7
@@ -14,12 +13,12 @@ class EAGLEConfig(PretrainedConfig):
13
14 def __init__(
15 self,
17 - model: Union[PretrainedConfig, dict, None] = None,
18 - truncated_vocab_size: Optional[int] = None,
19 - method: Optional[str] = "eagle",
16 + model: PretrainedConfig | dict | None = None,
17 + truncated_vocab_size: int | None = None,
18 + method: str | None = "eagle",
19 **kwargs,
20 ):
22 - model_config: Union[PretrainedConfig, DeepseekV2Config, None]
21 + model_config: PretrainedConfig | DeepseekV2Config | None
22 if isinstance(model, dict):
23 archs = model.get("architectures", [])
24 target_archs = ["DeepseekV2ForCausalLM", "DeepseekV3ForCausalLM"]
@@ -84,7 +83,7 @@ class EAGLEConfig(PretrainedConfig):
83 @classmethod
84 def from_pretrained(
85 cls,
87 - pretrained_model_name_or_path: Union[str, os.PathLike],
86 + pretrained_model_name_or_path: str | os.PathLike,
87 **kwargs,
88 ) -> "EAGLEConfig":
89 config_dict, kwargs = cls.get_config_dict(
vllm/transformers_utils/configs/kimi_vl.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 # Adapted from https://huggingface.co/moonshotai/Kimi-VL-A3B-Instruct/blob/main/configuration_kimi_vl.py
4 -from typing import Optional, Union
4
5 from transformers.configuration_utils import PretrainedConfig
6
@@ -14,8 +13,8 @@ class KimiVLConfig(PretrainedConfig):
13
14 def __init__(
15 self,
17 - vision_config: Optional[Union[dict, MoonViTConfig]] = None,
18 - text_config: Optional[Union[dict, DeepseekV2Config]] = None,
16 + vision_config: dict | MoonViTConfig | None = None,
17 + text_config: dict | DeepseekV2Config | None = None,
18 ignore_index: int = -100,
19 media_placeholder_token_id: int = 163605,
20 pad_token_id: int = 0,
vllm/transformers_utils/configs/lfm2_moe.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 from transformers.configuration_utils import PretrainedConfig
5
@@ -115,7 +114,7 @@ class Lfm2MoeConfig(PretrainedConfig):
114 use_expert_bias: bool = True,
115 routed_scaling_factor: float = 1.0,
116 norm_topk_prob: bool = True,
118 - layer_types: Optional[list[str]] = None,
117 + layer_types: list[str] | None = None,
118 **kwargs,
119 ):
120 self.vocab_size = vocab_size
vllm/transformers_utils/configs/medusa.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import os
5 -from typing import Optional, Union
5
6 from transformers import PretrainedConfig
7
@@ -18,7 +17,7 @@ class MedusaConfig(PretrainedConfig):
17 num_hidden_layers: int = 1,
18 max_paths: int = 64,
19 topk: int = 10,
21 - truncated_vocab_size: Optional[int] = None,
20 + truncated_vocab_size: int | None = None,
21 **kwargs,
22 ):
23 self.hidden_size = hidden_size
@@ -39,7 +38,7 @@ class MedusaConfig(PretrainedConfig):
38 @classmethod
39 def from_pretrained(
40 cls,
42 - pretrained_model_name_or_path: Union[str, os.PathLike],
41 + pretrained_model_name_or_path: str | os.PathLike,
42 **kwargs,
43 ) -> "MedusaConfig":
44 config_dict, kwargs = cls.get_config_dict(
vllm/transformers_utils/configs/midashenglm.py
+6 -7
@@ -21,7 +21,6 @@
21 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 # See the License for the specific language governing permissions and
23 # limitations under the License.
24 -from typing import Optional, Union
24
25 from transformers import PretrainedConfig
26 from transformers.models.qwen2_5_omni.configuration_qwen2_5_omni import (
@@ -36,15 +35,15 @@ class DashengConfig(PretrainedConfig):
35 self,
36 embed_dim: int = 768,
37 outputdim: int = 527,
39 - patch_size: Union[int, tuple[int, int]] = 16,
40 - patch_stride: Union[int, tuple[int, int]] = 16,
38 + patch_size: int | tuple[int, int] = 16,
39 + patch_stride: int | tuple[int, int] = 16,
40 input_channels: int = 1,
41 target_length: int = 1012,
42 depth: int = 12,
43 num_heads: int = 12,
44 mlp_ratio: float = 4.0,
45 qkv_bias: bool = True,
47 - init_values: Optional[float] = None,
46 + init_values: float | None = None,
47 drop_rate: float = 0.0,
48 attn_drop_rate: float = 0.0,
49 f_min: float = 0.0,
@@ -86,10 +85,10 @@ class MiDashengLMConfig(PretrainedConfig):
85
86 def __init__(
87 self,
89 - audio_encoder_config: Optional[dict] = None,
88 + audio_encoder_config: dict | None = None,
89 subsample_factor: int = 5,
91 - text_config: Optional[dict] = None,
92 - audio_token_id: Optional[int] = None,
90 + text_config: dict | None = None,
91 + audio_token_id: int | None = None,
92 **kwargs,
93 ):
94 self.audio_encoder_config = DashengConfig(**(audio_encoder_config or {}))
vllm/transformers_utils/configs/mlp_speculator.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 from transformers import PretrainedConfig
6
@@ -19,7 +18,7 @@ class MLPSpeculatorConfig(PretrainedConfig):
18 emb_dim: int = 4096,
19 inner_dim: int = 0,
20 n_predict: int = 3,
22 - top_k_tokens_per_head: Optional[list[int]] = None,
21 + top_k_tokens_per_head: list[int] | None = None,
22 n_candidates: int = 5,
23 tie_weights: bool = False,
24 scale_input: bool = False,
vllm/transformers_utils/configs/ovis.py
+4 -4
@@ -5,7 +5,7 @@
5 # adapted from https://huggingface.co/AIDC-AI/Ovis2-1B/blob/main/configuration_aimv2.py
6 # and https://huggingface.co/AIDC-AI/Ovis2-1B/blob/main/configuration_ovis.py
7 # Ovis Config with AimV2 config registration removed for Transformers compatibility
8 -from typing import Any, Optional, Union
8 +from typing import Any
9
10 from transformers import AutoConfig, PretrainedConfig
11
@@ -76,7 +76,7 @@ class BaseVisualTokenizerConfig(PretrainedConfig):
76 tau=1.0,
77 depths=None,
78 drop_cls_token=False,
79 - backbone_config: Optional[Union[PretrainedConfig, dict]] = None,
79 + backbone_config: PretrainedConfig | dict | None = None,
80 hidden_stride: int = 1,
81 **kwargs,
82 ):
@@ -142,8 +142,8 @@ class OvisConfig(PretrainedConfig):
142
143 def __init__(
144 self,
145 - llm_config: Optional[Union[PretrainedConfig, dict]] = None,
146 - visual_tokenizer_config: Optional[Union[PretrainedConfig, dict]] = None,
145 + llm_config: PretrainedConfig | dict | None = None,
146 + visual_tokenizer_config: PretrainedConfig | dict | None = None,
147 multimodal_max_length=8192,
148 hidden_size=None,
149 conversation_formatter_class=None,
vllm/transformers_utils/configs/radio.py
+3 -5
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Radio vision model configuration"""
4
5 -from typing import Optional, Union
6 -
5 from transformers.configuration_utils import PretrainedConfig
6 from transformers.utils import logging
7
@@ -60,9 +58,9 @@ class RadioConfig(PretrainedConfig):
58 initializer_factor: float = 1.0,
59 hidden_act: str = "gelu",
60 max_img_size: int = 2048,
63 - norm_mean: Union[tuple[float, float, float], list] = OPENAI_CLIP_MEAN,
64 - norm_std: Union[tuple[float, float, float], list] = OPENAI_CLIP_STD,
65 - reg_tokens: Optional[int] = None,
61 + norm_mean: tuple[float, float, float] | list = OPENAI_CLIP_MEAN,
62 + norm_std: tuple[float, float, float] | list = OPENAI_CLIP_STD,
63 + reg_tokens: int | None = None,
64 **kwargs,
65 ):
66 self.model_name = model_name
vllm/transformers_utils/configs/speculators/base.py
+2 -2
@@ -1,7 +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, Union
4 +from typing import Any
5
6 from transformers import PretrainedConfig
7
@@ -18,7 +18,7 @@ class SpeculatorsConfig(PretrainedConfig):
18 @classmethod
19 def from_pretrained(
20 cls,
21 - pretrained_model_name_or_path: Union[str, os.PathLike],
21 + pretrained_model_name_or_path: str | os.PathLike,
22 **kwargs,
23 ) -> "SpeculatorsConfig":
24 """Load speculators Eagle config and convert to vLLM format."""
vllm/transformers_utils/configs/step3_vl.py
+4 -4
@@ -1,6 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, Optional, Union
3 +from typing import Any
4
5 from transformers.configuration_utils import PretrainedConfig
6
@@ -53,7 +53,7 @@ class Step3TextConfig(PretrainedConfig):
53 moe_num_experts: int = 48,
54 moe_top_k: int = 3,
55 rope_theta: float = 500000,
56 - rope_scaling: Optional[dict[str, Any]] = None,
56 + rope_scaling: dict[str, Any] | None = None,
57 max_position_embedding: int = 65536,
58 share_expert_dim: int = 5120,
59 share_q_dim: int = 2048,
@@ -147,8 +147,8 @@ class Step3VLConfig(PretrainedConfig):
147
148 def __init__(
149 self,
150 - vision_config: Optional[Union[dict, Step3VisionEncoderConfig]] = None,
151 - text_config: Optional[Union[dict, Step3TextConfig]] = None,
150 + vision_config: dict | Step3VisionEncoderConfig | None = None,
151 + text_config: dict | Step3TextConfig | None = None,
152 understand_projector_stride: int = 1,
153 projector_bias: bool = True,
154 image_token_id: int = 128001,
vllm/transformers_utils/configs/ultravox.py
+5 -5
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 # Adapted from https://github.com/fixie-ai/ultravox/blob/ecd58c4041030bae2ad15aa6bcf04ab43199ea02/ultravox/model/ultravox_config.py
5 -from typing import Any, Optional
5 +from typing import Any
6
7 import transformers
8
@@ -50,10 +50,10 @@ class UltravoxConfig(transformers.PretrainedConfig):
50
51 def __init__(
52 self,
53 - audio_config: Optional[dict[str, Any]] = None,
54 - text_config: Optional[dict[str, Any]] = None,
55 - audio_model_id: Optional[str] = None,
56 - text_model_id: Optional[str] = None,
53 + audio_config: dict[str, Any] | None = None,
54 + text_config: dict[str, Any] | None = None,
55 + audio_model_id: str | None = None,
56 + text_model_id: str | None = None,
57 ignore_index: int = -100,
58 audio_token_index: int = 32000,
59 hidden_size: int = 4096,
vllm/transformers_utils/detokenizer_utils.py
+2 -3
@@ -1,12 +1,11 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 from .tokenizer import AnyTokenizer
6
7
9 -def _replace_none_with_empty(tokens: list[Optional[str]]):
8 +def _replace_none_with_empty(tokens: list[str | None]):
9 for i, token in enumerate(tokens):
10 if token is None:
11 tokens[i] = ""
@@ -111,7 +110,7 @@ def convert_ids_list_to_tokens(
110 def detokenize_incrementally(
111 tokenizer: AnyTokenizer,
112 all_input_ids: list[int],
114 - prev_tokens: Optional[list[str]],
113 + prev_tokens: list[str] | None,
114 prefix_offset: int,
115 read_offset: int,
116 skip_special_tokens: bool = False,
vllm/transformers_utils/dynamic_module.py
+8 -9
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import os
4 -from typing import Optional, Union
4
5 from transformers.dynamic_module_utils import get_class_from_dynamic_module
6
@@ -14,18 +13,18 @@ logger = init_logger(__name__)
13 def try_get_class_from_dynamic_module(
14 class_reference: str,
15 pretrained_model_name_or_path: str,
17 - cache_dir: Optional[Union[str, os.PathLike]] = None,
16 + cache_dir: str | os.PathLike | None = None,
17 force_download: bool = False,
19 - resume_download: Optional[bool] = None,
20 - proxies: Optional[dict[str, str]] = None,
21 - token: Optional[Union[bool, str]] = None,
22 - revision: Optional[str] = None,
18 + resume_download: bool | None = None,
19 + proxies: dict[str, str] | None = None,
20 + token: bool | str | None = None,
21 + revision: str | None = None,
22 local_files_only: bool = False,
24 - repo_type: Optional[str] = None,
25 - code_revision: Optional[str] = None,
23 + repo_type: str | None = None,
24 + code_revision: str | None = None,
25 warn_on_fail: bool = True,
26 **kwargs,
28 -) -> Optional[type]:
27 +) -> type | None:
28 """
29 As `transformers.dynamic_module_utils.get_class_from_dynamic_module`,
30 but ignoring any errors.
vllm/transformers_utils/processor.py
+11 -11
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from functools import lru_cache
5 -from typing import TYPE_CHECKING, Any, Optional, Union, cast
5 +from typing import TYPE_CHECKING, Any, cast
6
7 from transformers import (
8 AutoFeatureExtractor,
@@ -45,7 +45,7 @@ class HashableList(list):
45 return hash(tuple(self))
46
47
48 -def _get_processor_factory_fn(processor_cls: Union[type, tuple[type, ...]]):
48 +def _get_processor_factory_fn(processor_cls: type | tuple[type, ...]):
49 if isinstance(processor_cls, tuple) or processor_cls == ProcessorMixin:
50 return AutoProcessor.from_pretrained
51 if hasattr(processor_cls, "from_pretrained"):
@@ -56,7 +56,7 @@ def _get_processor_factory_fn(processor_cls: Union[type, tuple[type, ...]]):
56
57 def _merge_mm_kwargs(
58 model_config: "ModelConfig",
59 - processor_cls: Union[type, tuple[type, ...]],
59 + processor_cls: type | tuple[type, ...],
60 /,
61 **kwargs,
62 ):
@@ -86,9 +86,9 @@ def _merge_mm_kwargs(
86 def get_processor(
87 processor_name: str,
88 *args: Any,
89 - revision: Optional[str] = None,
89 + revision: str | None = None,
90 trust_remote_code: bool = False,
91 - processor_cls: Union[type[_P], tuple[type[_P], ...]] = ProcessorMixin,
91 + processor_cls: type[_P] | tuple[type[_P], ...] = ProcessorMixin,
92 **kwargs: Any,
93 ) -> _P:
94 """Load a processor for the given model name via HuggingFace."""
@@ -146,7 +146,7 @@ cached_get_processor = lru_cache(get_processor)
146
147 def cached_processor_from_config(
148 model_config: "ModelConfig",
149 - processor_cls: Union[type[_P], tuple[type[_P], ...]] = ProcessorMixin,
149 + processor_cls: type[_P] | tuple[type[_P], ...] = ProcessorMixin,
150 **kwargs: Any,
151 ) -> _P:
152 return cached_get_processor(
@@ -161,7 +161,7 @@ def cached_processor_from_config(
161 def get_feature_extractor(
162 processor_name: str,
163 *args: Any,
164 - revision: Optional[str] = None,
164 + revision: str | None = None,
165 trust_remote_code: bool = False,
166 **kwargs: Any,
167 ):
@@ -211,7 +211,7 @@ def cached_feature_extractor_from_config(
211 def get_image_processor(
212 processor_name: str,
213 *args: Any,
214 - revision: Optional[str] = None,
214 + revision: str | None = None,
215 trust_remote_code: bool = False,
216 **kwargs: Any,
217 ):
@@ -261,9 +261,9 @@ def cached_image_processor_from_config(
261 def get_video_processor(
262 processor_name: str,
263 *args: Any,
264 - revision: Optional[str] = None,
264 + revision: str | None = None,
265 trust_remote_code: bool = False,
266 - processor_cls_overrides: Optional[type[_V]] = None,
266 + processor_cls_overrides: type[_V] | None = None,
267 **kwargs: Any,
268 ):
269 """Load a video processor for the given model name via HuggingFace."""
@@ -300,7 +300,7 @@ cached_get_video_processor = lru_cache(get_video_processor)
300
301 def cached_video_processor_from_config(
302 model_config: "ModelConfig",
303 - processor_cls: Optional[type[_V]] = None,
303 + processor_cls: type[_V] | None = None,
304 **kwargs: Any,
305 ):
306 return cached_get_video_processor(
vllm/transformers_utils/processors/ovis.py
+4 -4
@@ -23,7 +23,6 @@
23 # See the License for the specific language governing permissions and
24 # limitations under the License.
25 from functools import cached_property
26 -from typing import Union
26
27 import PIL
28 import torch
@@ -104,9 +103,10 @@ class OvisProcessor(ProcessorMixin):
103 def __call__(
104 self,
105 images: ImageInput = None,
107 - text: Union[
108 - TextInput, PreTokenizedInput, list[TextInput], list[PreTokenizedInput]
109 - ] = None,
106 + text: TextInput
107 + | PreTokenizedInput
108 + | list[TextInput]
109 + | list[PreTokenizedInput] = None,
110 **kwargs: Unpack[OvisProcessorKwargs],
111 ) -> BatchFeature:
112 """
vllm/transformers_utils/processors/ovis2_5.py
+9 -9
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import math
4 from functools import cached_property
5 -from typing import Optional, Union
5
6 import numpy as np
7 import PIL
@@ -99,10 +98,11 @@ class Ovis2_5Processor(ProcessorMixin):
98 def __call__(
99 self,
100 images: ImageInput = None,
102 - videos: Union[np.ndarray, list[ImageInput]] = None,
103 - text: Union[
104 - TextInput, PreTokenizedInput, list[TextInput], list[PreTokenizedInput]
105 - ] = None,
101 + videos: np.ndarray | list[ImageInput] = None,
102 + text: TextInput
103 + | PreTokenizedInput
104 + | list[TextInput]
105 + | list[PreTokenizedInput] = None,
106 **kwargs: Unpack[Ovis2_5ProcessorKwargs],
107 ) -> BatchFeature:
108 """
@@ -376,12 +376,12 @@ class Ovis2_5Processor(ProcessorMixin):
376
377 def preprocess_multidata(
378 self,
379 - images: Optional[Union[PIL.Image.Image, list[PIL.Image.Image]]] = None,
380 - video: Optional[Union[list[PIL.Image.Image], np.ndarray]] = None,
381 - convert_to_rgb: Optional[bool] = True,
379 + images: PIL.Image.Image | list[PIL.Image.Image] | None = None,
380 + video: list[PIL.Image.Image] | np.ndarray | None = None,
381 + convert_to_rgb: bool | None = True,
382 min_pixels: int = MIN_PIXELS,
383 max_pixels: int = MAX_PIXELS,
384 - return_tensors: Optional[str] = "pt",
384 + return_tensors: str | None = "pt",
385 ):
386 is_video = False
387 if images is not None:
vllm/transformers_utils/runai_utils.py
+2 -3
@@ -5,7 +5,6 @@ import hashlib
5 import os
6 import shutil
7 import signal
8 -from typing import Optional
8
9 from vllm import envs
10 from vllm.assets.base import get_cache_dir
@@ -88,8 +87,8 @@ class ObjectStorageModel:
87 def pull_files(
88 self,
89 model_path: str = "",
91 - allow_pattern: Optional[list[str]] = None,
92 - ignore_pattern: Optional[list[str]] = None,
90 + allow_pattern: list[str] | None = None,
91 + ignore_pattern: list[str] | None = None,
92 ) -> None:
93 """
94 Pull files from object storage into the temporary directory.
vllm/transformers_utils/s3_utils.py
+3 -3
@@ -34,7 +34,7 @@ def _filter_ignore(paths: list[str], patterns: list[str]) -> list[str]:
34 def glob(
35 s3: Optional["BaseClient"] = None,
36 path: str = "",
37 - allow_pattern: Optional[list[str]] = None,
37 + allow_pattern: list[str] | None = None,
38 ) -> list[str]:
39 """
40 List full file names from S3 path and filter by allow pattern.
@@ -58,8 +58,8 @@ def glob(
58 def list_files(
59 s3: "BaseClient",
60 path: str,
61 - allow_pattern: Optional[list[str]] = None,
62 - ignore_pattern: Optional[list[str]] = None,
61 + allow_pattern: list[str] | None = None,
62 + ignore_pattern: list[str] | None = None,
63 ) -> tuple[str, str, list[str]]:
64 """
65 List files from S3 path and filter by pattern.
vllm/transformers_utils/tokenizer.py
+9 -9
@@ -7,7 +7,7 @@ import os
7 import warnings
8 from functools import lru_cache
9 from pathlib import Path
10 -from typing import TYPE_CHECKING, Any, Optional, Union
10 +from typing import TYPE_CHECKING, Any, TypeAlias
11
12 import huggingface_hub
13 from transformers import AutoTokenizer, PreTrainedTokenizer, PreTrainedTokenizerFast
@@ -30,14 +30,14 @@ else:
30
31 logger = init_logger(__name__)
32
33 -AnyTokenizer = Union[PreTrainedTokenizer, PreTrainedTokenizerFast, TokenizerBase]
33 +AnyTokenizer: TypeAlias = PreTrainedTokenizer | PreTrainedTokenizerFast | TokenizerBase
34
35
36 def decode_tokens(
37 tokenizer: AnyTokenizer,
38 token_ids: list[int],
39 *,
40 - skip_special_tokens: Optional[bool] = None,
40 + skip_special_tokens: bool | None = None,
41 ) -> str:
42 """
43 Backend-agnostic equivalent of HF's
@@ -56,9 +56,9 @@ def encode_tokens(
56 tokenizer: AnyTokenizer,
57 text: str,
58 *,
59 - truncation: Optional[bool] = None,
60 - max_length: Optional[int] = None,
61 - add_special_tokens: Optional[bool] = None,
59 + truncation: bool | None = None,
60 + max_length: int | None = None,
61 + add_special_tokens: bool | None = None,
62 ) -> list[int]:
63 """
64 Backend-agnostic equivalent of HF's
@@ -137,12 +137,12 @@ def get_cached_tokenizer(tokenizer: AnyTokenizer) -> AnyTokenizer:
137
138
139 def get_tokenizer(
140 - tokenizer_name: Union[str, Path],
140 + tokenizer_name: str | Path,
141 *args,
142 tokenizer_mode: str = "auto",
143 trust_remote_code: bool = False,
144 - revision: Optional[str] = None,
145 - download_dir: Optional[str] = None,
144 + revision: str | None = None,
145 + download_dir: str | None = None,
146 **kwargs,
147 ) -> AnyTokenizer:
148 """Gets a tokenizer for the given model name via HuggingFace or ModelScope."""
vllm/transformers_utils/tokenizer_base.py
+10 -12
@@ -3,7 +3,7 @@
3
4 import importlib
5 from abc import ABC, abstractmethod
6 -from typing import TYPE_CHECKING, Any, Optional, Union
6 +from typing import TYPE_CHECKING, Any
7
8 if TYPE_CHECKING:
9 from vllm.entrypoints.chat_utils import ChatCompletionMessageParam
@@ -71,11 +71,11 @@ class TokenizerBase(ABC):
71 @abstractmethod
72 def __call__(
73 self,
74 - text: Union[str, list[str], list[int]],
75 - text_pair: Optional[str] = None,
74 + text: str | list[str] | list[int],
75 + text_pair: str | None = None,
76 add_special_tokens: bool = False,
77 truncation: bool = False,
78 - max_length: Optional[int] = None,
78 + max_length: int | None = None,
79 ):
80 raise NotImplementedError()
81
@@ -92,7 +92,7 @@ class TokenizerBase(ABC):
92 self,
93 text: str,
94 truncation: bool = False,
95 - max_length: Optional[int] = None,
95 + max_length: int | None = None,
96 ) -> list[int]:
97 raise NotImplementedError()
98
@@ -100,9 +100,9 @@ class TokenizerBase(ABC):
100 def encode(
101 self,
102 text: str,
103 - truncation: Optional[bool] = None,
104 - max_length: Optional[int] = None,
105 - add_special_tokens: Optional[bool] = None,
103 + truncation: bool | None = None,
104 + max_length: int | None = None,
105 + add_special_tokens: bool | None = None,
106 ) -> list[int]:
107 raise NotImplementedError()
108
@@ -110,7 +110,7 @@ class TokenizerBase(ABC):
110 def apply_chat_template(
111 self,
112 messages: list["ChatCompletionMessageParam"],
113 - tools: Optional[list[dict[str, Any]]] = None,
113 + tools: list[dict[str, Any]] | None = None,
114 **kwargs,
115 ) -> list[int]:
116 raise NotImplementedError()
@@ -120,9 +120,7 @@ class TokenizerBase(ABC):
120 raise NotImplementedError()
121
122 @abstractmethod
123 - def decode(
124 - self, ids: Union[list[int], int], skip_special_tokens: bool = True
125 - ) -> str:
123 + def decode(self, ids: list[int] | int, skip_special_tokens: bool = True) -> str:
124 raise NotImplementedError()
125
126 @abstractmethod
vllm/transformers_utils/tokenizers/mistral.py
+14 -16
@@ -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, Any, Optional, Union, cast
4 +from typing import TYPE_CHECKING, Any, cast
5
6 from vllm.logger import init_logger
7 from vllm.transformers_utils.tokenizer_base import TokenizerBase
@@ -90,10 +90,10 @@ def truncate_tool_call_ids(request: "MistralChatCompletionRequest"):
90
91 def _prepare_apply_chat_template_tools_and_messages(
92 messages: list["ChatCompletionMessageParam"],
93 - tools: Optional[list[dict[str, Any]]] = None,
93 + tools: list[dict[str, Any]] | None = None,
94 continue_final_message: bool = False,
95 add_generation_prompt: bool = False,
96 -) -> tuple[list["ChatCompletionMessageParam"], Optional[list[dict[str, Any]]]]:
96 +) -> tuple[list["ChatCompletionMessageParam"], list[dict[str, Any]] | None]:
97 if add_generation_prompt and continue_final_message:
98 raise ValueError(
99 "Cannot set both `add_generation_prompt` and "
@@ -144,7 +144,7 @@ def validate_request_params(request: "ChatCompletionRequest"):
144 raise ValueError("chat_template is not supported for Mistral tokenizers.")
145
146
147 -def _tekken_token_to_id(tokenizer: "Tekkenizer", t: Union[str, bytes]) -> int:
147 +def _tekken_token_to_id(tokenizer: "Tekkenizer", t: str | bytes) -> int:
148 from mistral_common.tokens.tokenizers.tekken import Tekkenizer
149
150 assert isinstance(tokenizer, Tekkenizer), type(tokenizer)
@@ -197,7 +197,7 @@ class MistralTokenizer(TokenizerBase):
197
198 @classmethod
199 def from_pretrained(
200 - cls, path_or_repo_id: str, *, revision: Optional[str] = None
200 + cls, path_or_repo_id: str, *, revision: str | None = None
201 ) -> "MistralTokenizer":
202 from transformers.tokenization_mistral_common import (
203 MistralCommonTokenizer as TransformersMistralTokenizer,
@@ -298,11 +298,11 @@ class MistralTokenizer(TokenizerBase):
298
299 def __call__(
300 self,
301 - text: Union[str, list[str], list[int]],
302 - text_pair: Optional[str] = None,
301 + text: str | list[str] | list[int],
302 + text_pair: str | None = None,
303 add_special_tokens: bool = False,
304 truncation: bool = False,
305 - max_length: Optional[int] = None,
305 + max_length: int | None = None,
306 ):
307 return self.transformers_tokenizer(
308 text=text,
@@ -327,7 +327,7 @@ class MistralTokenizer(TokenizerBase):
327 self,
328 text: str,
329 truncation: bool = False,
330 - max_length: Optional[int] = None,
330 + max_length: int | None = None,
331 ) -> list[int]:
332 # Mistral Tokenizers should not add special tokens
333 return self.transformers_tokenizer.encode(
@@ -337,9 +337,9 @@ class MistralTokenizer(TokenizerBase):
337 def encode(
338 self,
339 text: str,
340 - truncation: Optional[bool] = None,
341 - max_length: Optional[int] = None,
342 - add_special_tokens: Optional[bool] = None,
340 + truncation: bool | None = None,
341 + max_length: int | None = None,
342 + add_special_tokens: bool | None = None,
343 ) -> list[int]:
344 if add_special_tokens is not None:
345 return self.transformers_tokenizer.encode(
@@ -359,7 +359,7 @@ class MistralTokenizer(TokenizerBase):
359 def apply_chat_template(
360 self,
361 messages: list["ChatCompletionMessageParam"],
362 - tools: Optional[list[dict[str, Any]]] = None,
362 + tools: list[dict[str, Any]] | None = None,
363 **kwargs,
364 ) -> list[int]:
365 add_generation_prompt = kwargs.pop("add_generation_prompt", False)
@@ -384,9 +384,7 @@ class MistralTokenizer(TokenizerBase):
384 return_dict=False,
385 )
386
387 - def decode(
388 - self, ids: Union[list[int], int], skip_special_tokens: bool = True
389 - ) -> str:
387 + def decode(self, ids: list[int] | int, skip_special_tokens: bool = True) -> str:
388 return self.transformers_tokenizer.decode(
389 ids, skip_special_tokens=skip_special_tokens
390 )
vllm/transformers_utils/utils.py
+7 -7
@@ -6,7 +6,7 @@ import struct
6 from functools import cache
7 from os import PathLike
8 from pathlib import Path
9 -from typing import Any, Optional, Union
9 +from typing import Any
10
11 from vllm.envs import VLLM_MODEL_REDIRECT_PATH
12 from vllm.logger import init_logger
@@ -18,7 +18,7 @@ def is_s3(model_or_path: str) -> bool:
18 return model_or_path.lower().startswith("s3://")
19
20
21 -def check_gguf_file(model: Union[str, PathLike]) -> bool:
21 +def check_gguf_file(model: str | PathLike) -> bool:
22 """Check if the file is a GGUF model."""
23 model = Path(model)
24 if not model.is_file():
@@ -38,8 +38,8 @@ def check_gguf_file(model: Union[str, PathLike]) -> bool:
38
39 def modelscope_list_repo_files(
40 repo_id: str,
41 - revision: Optional[str] = None,
42 - token: Union[str, bool, None] = None,
41 + revision: str | None = None,
42 + token: str | bool | None = None,
43 ) -> list[str]:
44 """List files in a modelscope repo."""
45 from modelscope.hub.api import HubApi
@@ -57,7 +57,7 @@ def modelscope_list_repo_files(
57 return files
58
59
60 -def _maybe_json_dict(path: Union[str, PathLike]) -> dict[str, str]:
60 +def _maybe_json_dict(path: str | PathLike) -> dict[str, str]:
61 with open(path) as f:
62 try:
63 return json.loads(f.read())
@@ -65,7 +65,7 @@ def _maybe_json_dict(path: Union[str, PathLike]) -> dict[str, str]:
65 return dict[str, str]()
66
67
68 -def _maybe_space_split_dict(path: Union[str, PathLike]) -> dict[str, str]:
68 +def _maybe_space_split_dict(path: str | PathLike) -> dict[str, str]:
69 parsed_dict = dict[str, str]()
70 with open(path) as f:
71 for line in f.readlines():
@@ -104,7 +104,7 @@ def maybe_model_redirect(model: str) -> str:
104 return model
105
106
107 -def parse_safetensors_file_metadata(path: Union[str, PathLike]) -> dict[str, Any]:
107 +def parse_safetensors_file_metadata(path: str | PathLike) -> dict[str, Any]:
108 with open(path, "rb") as f:
109 length_of_metadata = struct.unpack("<Q", f.read(8))[0]
110 metadata = json.loads(f.read(length_of_metadata).decode("utf-8"))
vllm/usage/usage_lib.py
+21 -21
@@ -10,7 +10,7 @@ import time
10 from enum import Enum
11 from pathlib import Path
12 from threading import Thread
13 -from typing import Any, Optional, Union
13 +from typing import Any
14 from uuid import uuid4
15
16 import cpuinfo
@@ -32,7 +32,7 @@ _USAGE_STATS_DO_NOT_TRACK_PATH = os.path.join(_config_home, "do_not_track")
32 _USAGE_STATS_ENABLED = None
33 _USAGE_STATS_SERVER = envs.VLLM_USAGE_STATS_SERVER
34
35 -_GLOBAL_RUNTIME_DATA = dict[str, Union[str, int, bool]]()
35 +_GLOBAL_RUNTIME_DATA = dict[str, str | int | bool]()
36
37 _USAGE_ENV_VARS_TO_COLLECT = [
38 "VLLM_USE_MODELSCOPE",
@@ -46,7 +46,7 @@ _USAGE_ENV_VARS_TO_COLLECT = [
46 ]
47
48
49 -def set_runtime_usage_data(key: str, value: Union[str, int, bool]) -> None:
49 +def set_runtime_usage_data(key: str, value: str | int | bool) -> None:
50 """Set global usage data that will be sent with every usage heartbeat."""
51 _GLOBAL_RUNTIME_DATA[key] = value
52
@@ -131,33 +131,33 @@ class UsageMessage:
131 self.uuid = str(uuid4())
132
133 # Environment Information
134 - self.provider: Optional[str] = None
135 - self.num_cpu: Optional[int] = None
136 - self.cpu_type: Optional[str] = None
137 - self.cpu_family_model_stepping: Optional[str] = None
138 - self.total_memory: Optional[int] = None
139 - self.architecture: Optional[str] = None
140 - self.platform: Optional[str] = None
141 - self.cuda_runtime: Optional[str] = None
142 - self.gpu_count: Optional[int] = None
143 - self.gpu_type: Optional[str] = None
144 - self.gpu_memory_per_device: Optional[int] = None
145 - self.env_var_json: Optional[str] = None
134 + self.provider: str | None = None
135 + self.num_cpu: int | None = None
136 + self.cpu_type: str | None = None
137 + self.cpu_family_model_stepping: str | None = None
138 + self.total_memory: int | None = None
139 + self.architecture: str | None = None
140 + self.platform: str | None = None
141 + self.cuda_runtime: str | None = None
142 + self.gpu_count: int | None = None
143 + self.gpu_type: str | None = None
144 + self.gpu_memory_per_device: int | None = None
145 + self.env_var_json: str | None = None
146
147 # vLLM Information
148 - self.model_architecture: Optional[str] = None
149 - self.vllm_version: Optional[str] = None
150 - self.context: Optional[str] = None
148 + self.model_architecture: str | None = None
149 + self.vllm_version: str | None = None
150 + self.context: str | None = None
151
152 # Metadata
153 - self.log_time: Optional[int] = None
154 - self.source: Optional[str] = None
153 + self.log_time: int | None = None
154 + self.source: str | None = None
155
156 def report_usage(
157 self,
158 model_architecture: str,
159 usage_context: UsageContext,
160 - extra_kvs: Optional[dict[str, Any]] = None,
160 + extra_kvs: dict[str, Any] | None = None,
161 ) -> None:
162 t = Thread(
163 target=self._report_usage_worker,
vllm/utils/__init__.py
+33 -31
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import asyncio
5 import concurrent
6 import contextlib
@@ -46,6 +44,7 @@ from collections import UserDict, defaultdict
44 from collections.abc import (
45 AsyncGenerator,
46 Awaitable,
47 + Callable,
48 Collection,
49 Generator,
50 Hashable,
@@ -62,12 +61,10 @@ from pathlib import Path
61 from typing import (
62 TYPE_CHECKING,
63 Any,
65 - Callable,
64 Generic,
65 Literal,
66 TextIO,
67 TypeVar,
70 - Union,
68 )
69 from urllib.parse import urlparse
70 from uuid import uuid4
@@ -99,6 +96,12 @@ if TYPE_CHECKING:
96
97 from vllm.config import ModelConfig, VllmConfig
98 from vllm.sequence import IntermediateTensors
99 +else:
100 + Namespace = object
101 +
102 + ModelConfig = object
103 + VllmConfig = object
104 + IntermediateTensors = object
105
106 logger = init_logger(__name__)
107
@@ -245,9 +248,7 @@ class AsyncMicrobatchTokenizer:
248 self._queues: dict[
249 tuple,
250 asyncio.Queue[
248 - Union[
249 - tuple[str, dict, asyncio.Future], tuple[list[int], asyncio.Future]
250 - ]
251 + tuple[str, dict, asyncio.Future] | tuple[list[int], asyncio.Future]
252 ],
253 ] = {}
254 self._batcher_tasks: list[asyncio.Task] = []
@@ -274,7 +275,7 @@ class AsyncMicrobatchTokenizer:
275 def _get_queue(
276 self, loop: asyncio.AbstractEventLoop, key: tuple
277 ) -> asyncio.Queue[
277 - Union[tuple[str, dict, asyncio.Future], tuple[list[int], asyncio.Future]]
278 + tuple[str, dict, asyncio.Future] | tuple[list[int], asyncio.Future]
279 ]:
280 """Get the request queue for the given operation key, creating a new
281 queue and batcher task if needed."""
@@ -431,7 +432,7 @@ def cancel_task_threadsafe(task: Task):
432 run_in_loop(task.get_loop(), task.cancel)
433
434
434 -def close_sockets(sockets: Sequence[Union[zmq.Socket, zmq.asyncio.Socket]]):
435 +def close_sockets(sockets: Sequence[zmq.Socket | zmq.asyncio.Socket]):
436 for sock in sockets:
437 if sock is not None:
438 sock.close(linger=0)
@@ -767,8 +768,8 @@ def _generate_random_fp8(
768
769
770 def get_kv_cache_torch_dtype(
770 - cache_dtype: Union[str, torch.dtype] | None,
771 - model_dtype: Union[str, torch.dtype] | None = None,
771 + cache_dtype: str | torch.dtype | None,
772 + model_dtype: str | torch.dtype | None = None,
773 ) -> torch.dtype:
774 if isinstance(cache_dtype, str):
775 if cache_dtype == "auto":
@@ -795,8 +796,8 @@ def create_kv_caches_with_random_flash(
796 num_layers: int,
797 num_heads: int,
798 head_size: int,
798 - cache_dtype: Union[str, torch.dtype] | None,
799 - model_dtype: Union[str, torch.dtype] | None = None,
799 + cache_dtype: str | torch.dtype | None,
800 + model_dtype: str | torch.dtype | None = None,
801 seed: int | None = None,
802 device: str | None = "cuda",
803 cache_layout: str | None = "NHD",
@@ -837,8 +838,8 @@ def create_kv_caches_with_random(
838 num_layers: int,
839 num_heads: int,
840 head_size: int,
840 - cache_dtype: Union[str, torch.dtype] | None,
841 - model_dtype: Union[str, torch.dtype] | None = None,
841 + cache_dtype: str | torch.dtype | None,
842 + model_dtype: str | torch.dtype | None = None,
843 seed: int | None = None,
844 device: str | None = "cuda",
845 ) -> tuple[list[torch.Tensor], list[torch.Tensor]]:
@@ -952,7 +953,7 @@ def make_tensor_with_pad(
953 dtype: torch.dtype,
954 *,
955 max_len: int | None = None,
955 - device: Union[str, torch.device] | None = None,
956 + device: str | torch.device | None = None,
957 pin_memory: bool = False,
958 ) -> torch.Tensor:
959 """
@@ -974,7 +975,7 @@ def make_tensor_with_pad(
975 def async_tensor_h2d(
976 data: list,
977 dtype: torch.dtype,
977 - target_device: Union[str, torch.device],
978 + target_device: str | torch.device,
979 pin_memory: bool,
980 ) -> torch.Tensor:
981 """Asynchronously create a tensor and copy it from host to device."""
@@ -1041,7 +1042,7 @@ def as_list(maybe_list: Iterable[T]) -> list[T]:
1042 return maybe_list if isinstance(maybe_list, list) else list(maybe_list)
1043
1044
1044 -def as_iter(obj: Union[T, Iterable[T]]) -> Iterable[T]:
1045 +def as_iter(obj: T | Iterable[T]) -> Iterable[T]:
1046 if isinstance(obj, str) or not isinstance(obj, Iterable):
1047 return [obj] # type: ignore[list-item]
1048 return obj
@@ -1050,7 +1051,7 @@ def as_iter(obj: Union[T, Iterable[T]]) -> Iterable[T]:
1051 # `collections` helpers
1052 def is_list_of(
1053 value: object,
1053 - typ: Union[type[T], tuple[type[T], ...]],
1054 + typ: type[T] | tuple[type[T], ...],
1055 *,
1056 check: Literal["first", "all"] = "first",
1057 ) -> TypeIs[list[T]]:
@@ -1266,7 +1267,7 @@ F = TypeVar("F", bound=Callable[..., Any])
1267
1268 def deprecate_args(
1269 start_index: int,
1269 - is_deprecated: Union[bool, Callable[[], bool]] = True,
1270 + is_deprecated: bool | Callable[[], bool] = True,
1271 additional_message: str | None = None,
1272 ) -> Callable[[F], F]:
1273 if not callable(is_deprecated):
@@ -1306,7 +1307,7 @@ def deprecate_args(
1307
1308 def deprecate_kwargs(
1309 *kws: str,
1309 - is_deprecated: Union[bool, Callable[[], bool]] = True,
1310 + is_deprecated: bool | Callable[[], bool] = True,
1311 additional_message: str | None = None,
1312 ) -> Callable[[F], F]:
1313 deprecated_kws = set(kws)
@@ -1892,7 +1893,7 @@ class FlexibleArgumentParser(ArgumentParser):
1893 # only expecting a flat dictionary of atomic types
1894 processed_args: list[str] = []
1895
1895 - config: dict[str, Union[int, str]] = {}
1896 + config: dict[str, int | str] = {}
1897 try:
1898 with open(file_path) as config_file:
1899 config = yaml.safe_load(config_file)
@@ -2149,10 +2150,11 @@ def weak_ref_tensor(tensor: Any) -> Any:
2150
2151
2152 def weak_ref_tensors(
2152 - tensors: Union[
2153 - torch.Tensor, list[torch.Tensor], tuple[torch.Tensor], IntermediateTensors
2154 - ],
2155 -) -> Union[torch.Tensor, list[Any], tuple[Any], Any]:
2153 + tensors: torch.Tensor
2154 + | list[torch.Tensor]
2155 + | tuple[torch.Tensor]
2156 + | IntermediateTensors,
2157 +) -> torch.Tensor | list[Any] | tuple[Any] | Any:
2158 """
2159 Convenience function to create weak references to tensors,
2160 for single tensor, list of tensors or tuple of tensors.
@@ -2183,7 +2185,7 @@ def get_cuda_view_from_cpu_tensor(cpu_tensor: torch.Tensor) -> torch.Tensor:
2185 return torch.ops._C.get_cuda_view_from_cpu_tensor(cpu_tensor)
2186
2187
2186 -def import_from_path(module_name: str, file_path: Union[str, os.PathLike]):
2188 +def import_from_path(module_name: str, file_path: str | os.PathLike):
2189 """
2190 Import a Python file according to its file path.
2191
@@ -2584,7 +2586,7 @@ class MemorySnapshot:
2586 self.non_torch_memory = self.cuda_memory - self.torch_memory
2587 self.timestamp = time.time()
2588
2587 - def __sub__(self, other: MemorySnapshot) -> MemorySnapshot:
2589 + def __sub__(self, other: "MemorySnapshot") -> "MemorySnapshot":
2590 return MemorySnapshot(
2591 torch_peak=self.torch_peak - other.torch_peak,
2592 free_memory=self.free_memory - other.free_memory,
@@ -2778,13 +2780,13 @@ def make_zmq_path(scheme: str, host: str, port: int | None = None) -> str:
2780
2781 # Adapted from: https://github.com/sgl-project/sglang/blob/v0.4.1/python/sglang/srt/utils.py#L783 # noqa: E501
2782 def make_zmq_socket(
2781 - ctx: Union[zmq.asyncio.Context, zmq.Context], # type: ignore[name-defined]
2783 + ctx: zmq.asyncio.Context | zmq.Context, # type: ignore[name-defined]
2784 path: str,
2785 socket_type: Any,
2786 bind: bool | None = None,
2787 identity: bytes | None = None,
2788 linger: int | None = None,
2787 -) -> Union[zmq.Socket, zmq.asyncio.Socket]: # type: ignore[name-defined]
2789 +) -> zmq.Socket | zmq.asyncio.Socket: # type: ignore[name-defined]
2790 """Make a ZMQ socket with the proper bind/connect semantics."""
2791
2792 mem = psutil.virtual_memory()
@@ -2950,7 +2952,7 @@ def bind_kv_cache(
2952
2953 def run_method(
2954 obj: Any,
2953 - method: Union[str, bytes, Callable],
2955 + method: str | bytes | Callable,
2956 args: tuple[Any],
2957 kwargs: dict[str, Any],
2958 ) -> Any:
vllm/utils/cache.py
+9 -15
@@ -1,11 +1,9 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 from collections import UserDict
6 -from collections.abc import Hashable, Iterator, KeysView, Mapping
4 +from collections.abc import Callable, Hashable, Iterator, KeysView, Mapping
5 from types import MappingProxyType
8 -from typing import Callable, Generic, NamedTuple, TypeVar, Union, cast, overload
6 +from typing import Generic, NamedTuple, TypeVar, cast, overload
7
8 import cachetools
9
@@ -43,7 +41,7 @@ class CacheInfo(NamedTuple):
41
42 return self.hits / self.total
43
46 - def __sub__(self, other: CacheInfo):
44 + def __sub__(self, other: "CacheInfo"):
45 return CacheInfo(
46 hits=self.hits - other.hits,
47 total=self.total - other.total,
@@ -129,12 +127,10 @@ class LRUCache(cachetools.LRUCache[_K, _V], Generic[_K, _V]):
127 def get(self, key: _K, /) -> _V | None: ...
128
129 @overload
132 - def get(self, key: _K, /, default: Union[_V, _T]) -> Union[_V, _T]: ...
130 + def get(self, key: _K, /, default: _V | _T) -> _V | _T: ...
131
134 - def get(
135 - self, key: _K, /, default: Union[_V, _T] | None = None
136 - ) -> Union[_V, _T] | None:
137 - value: Union[_V, _T] | None
132 + def get(self, key: _K, /, default: _V | _T | None = None) -> _V | _T | None:
133 + value: _V | _T | None
134 if key in self:
135 value = self.__getitem__(key, update_info=False) # type: ignore[call-arg]
136
@@ -149,12 +145,10 @@ class LRUCache(cachetools.LRUCache[_K, _V], Generic[_K, _V]):
145 def pop(self, key: _K) -> _V: ...
146
147 @overload
152 - def pop(self, key: _K, default: Union[_V, _T]) -> Union[_V, _T]: ...
148 + def pop(self, key: _K, default: _V | _T) -> _V | _T: ...
149
154 - def pop(
155 - self, key: _K, default: Union[_V, _T] | None = None
156 - ) -> Union[_V, _T] | None:
157 - value: Union[_V, _T] | None
150 + def pop(self, key: _K, default: _V | _T | None = None) -> _V | _T | None:
151 + value: _V | _T | None
152 if key not in self:
153 return default
154
vllm/utils/deep_gemm.py
+2 -3
@@ -5,12 +5,11 @@
5 Users of vLLM should always import **only** these wrappers.
6 """
7
8 -from __future__ import annotations
9 -
8 import functools
9 import importlib
10 import os
13 -from typing import Any, Callable, NoReturn
11 +from collections.abc import Callable
12 +from typing import Any, NoReturn
13
14 import torch
15
vllm/utils/flashinfer.py
+2 -3
@@ -5,15 +5,14 @@
5 Users of vLLM should always import **only** these wrappers.
6 """
7
8 -from __future__ import annotations
9 -
8 import contextlib
9 import functools
10 import importlib
11 import importlib.util
12 import os
13 import shutil
16 -from typing import Any, Callable, NoReturn
14 +from collections.abc import Callable
15 +from typing import Any, NoReturn
16
17 import requests
18 import torch
vllm/utils/gc_utils.py
+2 -2
@@ -5,7 +5,7 @@ import json
5 import time
6 from collections import Counter
7 from contextlib import suppress
8 -from typing import Any, Optional
8 +from typing import Any
9
10 from vllm.envs import VLLM_GC_DEBUG
11 from vllm.logger import init_logger
@@ -21,7 +21,7 @@ class GCDebugConfig:
21 - '{"top_objects":5}': enable GC debugger with top 5 collected objects
22 """
23
24 - def __init__(self, gc_debug_conf: Optional[str] = None) -> None:
24 + def __init__(self, gc_debug_conf: str | None = None) -> None:
25 self.enabled: bool = False
26 self.top_objects: int = -1
27
vllm/utils/jsontree.py
+27 -30
@@ -2,9 +2,9 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Helper functions to work with nested JSON structures."""
4
5 -from collections.abc import Iterable
5 +from collections.abc import Callable, Iterable
6 from functools import reduce
7 -from typing import TYPE_CHECKING, Callable, TypeVar, Union, cast, overload
7 +from typing import TYPE_CHECKING, TypeAlias, TypeVar, cast, overload
8
9 if TYPE_CHECKING:
10 import torch
@@ -14,23 +14,20 @@ if TYPE_CHECKING:
14 _T = TypeVar("_T")
15 _U = TypeVar("_U")
16
17 -JSONTree = Union[
18 - dict[str, "JSONTree[_T]"],
19 - list["JSONTree[_T]"],
20 - tuple["JSONTree[_T]", ...],
21 - _T,
22 -]
17 +JSONTree: TypeAlias = (
18 + dict[str, "JSONTree[_T]"] | list["JSONTree[_T]"] | tuple["JSONTree[_T]", ...] | _T
19 +)
20 """A nested JSON structure where the leaves need not be JSON-serializable."""
21
25 -_JSONTree = Union[
26 - dict[str, "JSONTree[_T]"],
27 - list["JSONTree[_T]"],
28 - tuple["JSONTree[_T]", ...],
29 - dict[str, _T],
30 - list[_T],
31 - tuple[_T, ...],
32 - _T,
33 -]
22 +_JSONTree: TypeAlias = (
23 + dict[str, "JSONTree[_T]"]
24 + | list["JSONTree[_T]"]
25 + | tuple["JSONTree[_T]", ...]
26 + | dict[str, _T]
27 + | list[_T]
28 + | tuple[_T, ...]
29 + | _T
30 +)
31 """
32 Same as `JSONTree` but with additional `Union` members to satisfy overloads.
33 """
@@ -58,22 +55,22 @@ def json_map_leaves(
55 @overload
56 def json_map_leaves(
57 func: Callable[[_T], _U],
61 - value: Union[_T, dict[str, _T]],
62 -) -> Union[_U, dict[str, _U]]: ...
58 + value: _T | dict[str, _T],
59 +) -> _U | dict[str, _U]: ...
60
61
62 @overload
63 def json_map_leaves(
64 func: Callable[[_T], _U],
68 - value: Union[_T, list[_T]],
69 -) -> Union[_U, list[_U]]: ...
65 + value: _T | list[_T],
66 +) -> _U | list[_U]: ...
67
68
69 @overload
70 def json_map_leaves(
71 func: Callable[[_T], _U],
75 - value: Union[_T, tuple[_T, ...]],
76 -) -> Union[_U, tuple[_U, ...]]: ...
72 + value: _T | tuple[_T, ...],
73 +) -> _U | tuple[_U, ...]: ...
74
75
76 @overload
@@ -85,8 +82,8 @@ def json_map_leaves(
82
83 def json_map_leaves(
84 func: Callable[[_T], _U],
88 - value: Union["BatchedTensorInputs", _JSONTree[_T]],
89 -) -> Union["BatchedTensorInputs", _JSONTree[_U]]:
85 + value: "BatchedTensorInputs" | _JSONTree[_T],
86 +) -> "BatchedTensorInputs" | _JSONTree[_U]:
87 """Apply a function to each leaf in a nested JSON structure."""
88 if isinstance(value, dict):
89 return {
@@ -104,7 +101,7 @@ def json_map_leaves(
101 @overload
102 def json_reduce_leaves(
103 func: Callable[[_T, _T], _T],
107 - value: Union[_T, dict[str, _T]],
104 + value: _T | dict[str, _T],
105 /,
106 ) -> _T: ...
107
@@ -112,7 +109,7 @@ def json_reduce_leaves(
109 @overload
110 def json_reduce_leaves(
111 func: Callable[[_T, _T], _T],
115 - value: Union[_T, list[_T]],
112 + value: _T | list[_T],
113 /,
114 ) -> _T: ...
115
@@ -120,7 +117,7 @@ def json_reduce_leaves(
117 @overload
118 def json_reduce_leaves(
119 func: Callable[[_T, _T], _T],
123 - value: Union[_T, tuple[_T, ...]],
120 + value: _T | tuple[_T, ...],
121 /,
122 ) -> _T: ...
123
@@ -143,11 +140,11 @@ def json_reduce_leaves(
140
141
142 def json_reduce_leaves(
146 - func: Callable[..., Union[_T, _U]],
143 + func: Callable[..., _T | _U],
144 value: _JSONTree[_T],
145 initial: _U = cast(_U, ...), # noqa: B008
146 /,
150 -) -> Union[_T, _U]:
147 +) -> _T | _U:
148 """
149 Apply a function of two arguments cumulatively to each leaf in a
150 nested JSON structure, from left to right, so as to reduce the
vllm/utils/tensor_schema.py
+12 -10
@@ -1,6 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Annotated, Any, Optional, Union, get_args, get_origin, get_type_hints
3 +from types import UnionType
4 +from typing import Annotated, Any, Union, get_args, get_origin, get_type_hints
5
6 import torch
7
@@ -12,16 +13,16 @@ logger = init_logger(__name__)
13 class TensorShape:
14 def __init__(
15 self,
15 - *dims: Union[int, str],
16 - dynamic_dims: Optional[set[str]] = None,
16 + *dims: int | str,
17 + dynamic_dims: set[str] | None = None,
18 ) -> None:
19 super().__init__()
20
21 self.dims = dims
22 self.dynamic_dims = dynamic_dims if dynamic_dims else set()
23
23 - def resolve(self, **bindings: int) -> tuple[Union[int, str], ...]:
24 - resolved = list[Union[int, str]]()
24 + def resolve(self, **bindings: int) -> tuple[int | str, ...]:
25 + resolved = list[int | str]()
26 for dim in self.dims:
27 if isinstance(dim, str) and dim in bindings:
28 resolved.append(bindings[dim])
@@ -48,7 +49,7 @@ class TensorSchema:
49 self,
50 *,
51 validate: bool = True,
51 - resolve_bindings: Optional[dict[str, int]] = None,
52 + resolve_bindings: dict[str, int] | None = None,
53 **kwargs: Any,
54 ) -> None:
55 super().__init__()
@@ -71,7 +72,7 @@ class TensorSchema:
72 self,
73 actual: tuple[int, ...],
74 reference: tuple[int, ...],
74 - expected_shape: tuple[Union[int, str], ...],
75 + expected_shape: tuple[int | str, ...],
76 dynamic_dims: set[str],
77 ) -> bool:
78 if len(actual) != len(reference) or len(actual) > len(expected_shape):
@@ -100,7 +101,7 @@ class TensorSchema:
101 self,
102 value: object,
103 field_name: str,
103 - expected_shape: tuple[Union[int, str], ...],
104 + expected_shape: tuple[int | str, ...],
105 dynamic_dims: set[str],
106 leading_idxs: tuple[int, ...] = (),
107 ) -> tuple[int, ...]:
@@ -154,7 +155,7 @@ class TensorSchema:
155 def _validate_tensor_shape_expected(
156 self,
157 actual_shape: tuple[int, ...],
157 - expected_shape: tuple[Union[int, str], ...],
158 + expected_shape: tuple[int | str, ...],
159 field_name: str,
160 shape_env: dict[str, int],
161 dynamic_dims: set[str],
@@ -209,7 +210,8 @@ class TensorSchema:
210 actual_type = args[0]
211
212 # Check arg was provided as Union
212 - if get_origin(actual_type) is Union:
213 + if get_origin(actual_type) in {Union, UnionType}:
214 + # Union for Union[X, Y] and UnionType for X | Y
215 args = get_args(actual_type)
216 # Skip validation when Union contains None
217 if type(None) in args:
vllm/v1/attention/backends/cpu_attn.py
+29 -29
@@ -110,7 +110,7 @@ class TorchSDPAMetadata(AttentionMetadata):
110 """Metadata for PagedAttention."""
111 # (batch_size,). The length of sequences (entire tokens seen so far) per
112 # sequence.
113 - decode_seq_lens_tensor: Optional[torch.Tensor]
113 + decode_seq_lens_tensor: torch.Tensor | None
114 # Maximum sequence length in the batch. 0 if it is prefill-only batch.
115 decode_max_seq_len: int
116 # (batch_size, max_blocks_per_seq).
@@ -119,39 +119,39 @@ class TorchSDPAMetadata(AttentionMetadata):
119 # in the kv cache. Each block can contain up to block_size tokens.
120 # 2nd dimensions are padded up to max_blocks_per_seq if it is cuda-graph
121 # captured.
122 - decode_block_tables: Optional[torch.Tensor]
122 + decode_block_tables: torch.Tensor | None
123 """Metadata for TorchSDPABackend.
124 """
125 # Currently, input sequences can only contain all prompts
126 # or all decoding. True if all sequences are prompts.
127 chunked_prefill: bool
128 - seq_lens: Optional[list[int]] = None # For non-chunked prefill
128 + seq_lens: list[int] | None = None # For non-chunked prefill
129
130 # For chunked prefill only
131 - max_query_len: Optional[int] = None
132 - prefill_max_seq_len: Optional[int] = None
133 - prefill_query_start_loc: Optional[torch.Tensor] = None
134 - prefill_seq_start_loc: Optional[torch.Tensor] = None
135 - prefill_block_tables: Optional[torch.Tensor] = None
131 + max_query_len: int | None = None
132 + prefill_max_seq_len: int | None = None
133 + prefill_query_start_loc: torch.Tensor | None = None
134 + prefill_seq_start_loc: torch.Tensor | None = None
135 + prefill_block_tables: torch.Tensor | None = None
136
137 # For V1 logits index only
138 - query_start_loc: Optional[torch.Tensor] = None
138 + query_start_loc: torch.Tensor | None = None
139
140 # Begin encoder attn & enc/dec cross-attn fields...
141 # Encoder sequence lengths representation
142 - encoder_seq_lens: Optional[list[int]] = None
143 - encoder_seq_lens_tensor: Optional[torch.Tensor] = None
142 + encoder_seq_lens: list[int] | None = None
143 + encoder_seq_lens_tensor: torch.Tensor | None = None
144
145 # Maximum sequence length among encoder sequences
146 - max_encoder_seq_len: Optional[int] = None
146 + max_encoder_seq_len: int | None = None
147
148 # Number of tokens input to encoder
149 - num_encoder_tokens: Optional[int] = None
149 + num_encoder_tokens: int | None = None
150
151 # Cross-attention memory-mapping data structures: slot mapping
152 # and block tables
153 - cross_slot_mapping: Optional[torch.Tensor] = None
154 - cross_block_tables: Optional[torch.Tensor] = None
153 + cross_slot_mapping: torch.Tensor | None = None
154 + cross_block_tables: torch.Tensor | None = None
155
156 def __post_init__(self):
157 # Set during the execution of the first attention op.
@@ -159,9 +159,9 @@ class TorchSDPAMetadata(AttentionMetadata):
159 # when alibi slopes is used. It is because of the limitation
160 # from xformer API.
161 # will not appear in the __repr__ and __init__
162 - self.attn_bias: Optional[list[torch.Tensor]] = None
163 - self.encoder_attn_bias: Optional[list[torch.Tensor]] = None
164 - self.cross_attn_bias: Optional[list[torch.Tensor]] = None
162 + self.attn_bias: list[torch.Tensor] | None = None
163 + self.encoder_attn_bias: list[torch.Tensor] | None = None
164 + self.cross_attn_bias: list[torch.Tensor] | None = None
165
166 @property
167 def is_all_encoder_attn_metadata_set(self):
@@ -237,7 +237,7 @@ class TorchSDPAMetadata(AttentionMetadata):
237 def get_attn_bias(
238 self,
239 attn_type: str,
240 - ) -> Optional[list[torch.Tensor]]:
240 + ) -> list[torch.Tensor] | None:
241 """
242 Extract appropriate attention bias from attention metadata
243 according to attention type.
@@ -439,12 +439,12 @@ class TorchSDPABackendImpl(AttentionImpl[TorchSDPAMetadata]):
439 head_size: int,
440 scale: float,
441 num_kv_heads: int,
442 - alibi_slopes: Optional[list[float]],
443 - sliding_window: Optional[int],
442 + alibi_slopes: list[float] | None,
443 + sliding_window: int | None,
444 kv_cache_dtype: str,
445 - logits_soft_cap: Optional[float] = None,
445 + logits_soft_cap: float | None = None,
446 attn_type: str = AttentionType.DECODER,
447 - kv_sharing_target_layer_name: Optional[str] = None,
447 + kv_sharing_target_layer_name: str | None = None,
448 ) -> None:
449 if kv_sharing_target_layer_name is not None:
450 raise NotImplementedError("KV sharing is not supported in V0.")
@@ -484,9 +484,9 @@ class TorchSDPABackendImpl(AttentionImpl[TorchSDPAMetadata]):
484 value: torch.Tensor,
485 kv_cache: torch.Tensor,
486 attn_metadata: TorchSDPAMetadata, # type: ignore
487 - output: Optional[torch.Tensor] = None,
488 - output_scale: Optional[torch.Tensor] = None,
489 - output_block_scale: Optional[torch.Tensor] = None,
487 + output: torch.Tensor | None = None,
488 + output_scale: torch.Tensor | None = None,
489 + output_block_scale: torch.Tensor | None = None,
490 ) -> torch.Tensor:
491 """Forward pass with torch SDPA and PagedAttention.
492
@@ -737,7 +737,7 @@ def _make_alibi_bias(
737
738 def _make_sliding_window_bias(
739 seq_lens: list[int],
740 - window_size: Optional[int],
740 + window_size: int | None,
741 dtype: torch.dtype,
742 ) -> list[torch.Tensor]:
743 attn_biases: list[torch.Tensor] = []
@@ -824,7 +824,7 @@ class _PagedAttention:
824 kv_cache_dtype: str,
825 num_kv_heads: int,
826 scale: float,
827 - alibi_slopes: Optional[torch.Tensor],
827 + alibi_slopes: torch.Tensor | None,
828 k_scale: torch.Tensor,
829 v_scale: torch.Tensor,
830 *args,
@@ -907,7 +907,7 @@ class _IPEXPagedAttention(_PagedAttention):
907 kv_cache_dtype: str,
908 num_kv_heads: int,
909 scale: float,
910 - alibi_slopes: Optional[torch.Tensor],
910 + alibi_slopes: torch.Tensor | None,
911 k_scale: torch.Tensor,
912 v_scale: torch.Tensor,
913 *args,
vllm/v1/attention/backends/flash_attn.py
+24 -25
@@ -3,7 +3,6 @@
3 """Attention layer with FlashAttention."""
4
5 from dataclasses import dataclass
6 -from typing import Optional, Union
6
7 import numpy as np
8 import torch
@@ -59,7 +58,7 @@ class FlashAttentionBackend(AttentionBackend):
58 return [32, 64, 96, 128, 160, 192, 224, 256]
59
60 @staticmethod
62 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
61 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
62 return [MultipleOf(16)]
63
64 @classmethod
@@ -144,13 +143,13 @@ class FlashAttentionMetadata:
143 # For cascade attention.
144 use_cascade: bool
145 common_prefix_len: int
147 - cu_prefix_query_lens: Optional[torch.Tensor]
148 - prefix_kv_lens: Optional[torch.Tensor]
149 - suffix_kv_lens: Optional[torch.Tensor]
146 + cu_prefix_query_lens: torch.Tensor | None
147 + prefix_kv_lens: torch.Tensor | None
148 + suffix_kv_lens: torch.Tensor | None
149
150 # Optional aot scheduling
152 - scheduler_metadata: Optional[torch.Tensor] = None
153 - prefix_scheduler_metadata: Optional[torch.Tensor] = None
151 + scheduler_metadata: torch.Tensor | None = None
152 + prefix_scheduler_metadata: torch.Tensor | None = None
153 max_num_splits: int = 0
154
155 causal: bool = True
@@ -158,9 +157,9 @@ class FlashAttentionMetadata:
157
158 def _get_sliding_window_configs(
159 vllm_config: VllmConfig,
161 -) -> set[Optional[tuple[int, int]]]:
160 +) -> set[tuple[int, int] | None]:
161 """Get the set of all sliding window configs used in the model."""
163 - sliding_window_configs: set[Optional[tuple[int, int]]] = set()
162 + sliding_window_configs: set[tuple[int, int] | None] = set()
163 layers = get_layers_from_vllm_config(vllm_config, Attention)
164 for layer in layers.values():
165 assert isinstance(layer.impl, FlashAttentionImpl)
@@ -242,7 +241,7 @@ class FlashAttentionMetadataBuilder(AttentionMetadataBuilder[FlashAttentionMetad
241
242 # Sliding window size to be used with the AOT scheduler will be
243 # populated on first build() call.
245 - self.aot_sliding_window: Optional[tuple[int, int]] = None
244 + self.aot_sliding_window: tuple[int, int] | None = None
245
246 def build(
247 self,
@@ -403,13 +402,13 @@ class FlashAttentionImpl(AttentionImpl):
402 head_size: int,
403 scale: float,
404 num_kv_heads: int,
406 - alibi_slopes: Optional[list[float]],
407 - sliding_window: Optional[int],
405 + alibi_slopes: list[float] | None,
406 + sliding_window: int | None,
407 kv_cache_dtype: str,
409 - logits_soft_cap: Optional[float] = None,
408 + logits_soft_cap: float | None = None,
409 attn_type: AttentionType = AttentionType.DECODER,
411 - kv_sharing_target_layer_name: Optional[str] = None,
412 - sinks: Optional[torch.Tensor] = None,
410 + kv_sharing_target_layer_name: str | None = None,
411 + sinks: torch.Tensor | None = None,
412 ) -> None:
413 self.num_heads = num_heads
414 self.head_size = head_size
@@ -460,9 +459,9 @@ class FlashAttentionImpl(AttentionImpl):
459 value: torch.Tensor,
460 kv_cache: torch.Tensor,
461 attn_metadata: FlashAttentionMetadata,
463 - output: Optional[torch.Tensor] = None,
464 - output_scale: Optional[torch.Tensor] = None,
465 - output_block_scale: Optional[torch.Tensor] = None,
462 + output: torch.Tensor | None = None,
463 + output_scale: torch.Tensor | None = None,
464 + output_block_scale: torch.Tensor | None = None,
465 ) -> torch.Tensor:
466 """Forward pass with FlashAttention.
467
@@ -762,18 +761,18 @@ def cascade_attention(
761 suffix_kv_lens: torch.Tensor,
762 max_kv_len: int,
763 softmax_scale: float,
765 - alibi_slopes: Optional[torch.Tensor],
764 + alibi_slopes: torch.Tensor | None,
765 sliding_window: tuple[int, int],
766 logits_soft_cap: float,
767 block_table: torch.Tensor,
768 common_prefix_len: int,
769 fa_version: int,
771 - prefix_scheduler_metadata: Optional[torch.Tensor] = None,
772 - suffix_scheduler_metadata: Optional[torch.Tensor] = None,
773 - q_descale: Optional[torch.Tensor] = None,
774 - k_descale: Optional[torch.Tensor] = None,
775 - v_descale: Optional[torch.Tensor] = None,
776 - s_aux: Optional[torch.Tensor] = None,
770 + prefix_scheduler_metadata: torch.Tensor | None = None,
771 + suffix_scheduler_metadata: torch.Tensor | None = None,
772 + q_descale: torch.Tensor | None = None,
773 + k_descale: torch.Tensor | None = None,
774 + v_descale: torch.Tensor | None = None,
775 + s_aux: torch.Tensor | None = None,
776 ) -> torch.Tensor:
777 assert alibi_slopes is None, "Cascade attention does not support ALiBi."
778 # TODO: Support sliding window.
vllm/v1/attention/backends/flashinfer.py
+8 -10
@@ -2,10 +2,8 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Attention layer with FlashInfer."""
4
5 -from __future__ import annotations
6 -
5 from dataclasses import dataclass
8 -from typing import ClassVar, Union
6 +from typing import ClassVar
7
8 import numpy as np
9 import torch
@@ -167,7 +165,7 @@ class FlashInferBackend(AttentionBackend):
165 return [64, 128, 256]
166
167 @staticmethod
170 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
168 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
169 # Note: Not sure for all platforms,
170 # but on Blackwell, only support a page size of
171 # 16, 32, 64
@@ -190,15 +188,15 @@ class FlashInferBackend(AttentionBackend):
188 return "FLASHINFER"
189
190 @staticmethod
193 - def get_impl_cls() -> type[FlashInferImpl]:
191 + def get_impl_cls() -> type["FlashInferImpl"]:
192 return FlashInferImpl
193
194 @staticmethod
197 - def get_metadata_cls() -> type[FlashInferMetadata]:
195 + def get_metadata_cls() -> type["FlashInferMetadata"]:
196 return FlashInferMetadata
197
198 @staticmethod
201 - def get_builder_cls() -> type[FlashInferMetadataBuilder]:
199 + def get_builder_cls() -> type["FlashInferMetadataBuilder"]:
200 return FlashInferMetadataBuilder
201
202 @staticmethod
@@ -1116,9 +1114,9 @@ def fast_plan_decode(
1114 pos_encoding_mode: str = "NONE",
1115 window_left: int = -1,
1116 logits_soft_cap: float | None = None,
1119 - q_data_type: Union[str, torch.dtype] | None = "float16",
1120 - kv_data_type: Union[str, torch.dtype] | None = None,
1121 - data_type: Union[str, torch.dtype] | None = None,
1117 + q_data_type: str | torch.dtype | None = "float16",
1118 + kv_data_type: str | torch.dtype | None = None,
1119 + data_type: str | torch.dtype | None = None,
1120 sm_scale: float | None = None,
1121 rope_scale: float | None = None,
1122 rope_theta: float | None = None,
vllm/v1/attention/backends/flex_attention.py
+21 -22
@@ -3,7 +3,6 @@
3 """Attention layer with FlexAttention."""
4
5 from dataclasses import dataclass
6 -from typing import Optional, Union
6
7 import torch
8 import torch._dynamo.decorators
@@ -282,9 +281,9 @@ class FlexAttentionMetadata:
281
282 use_cascade: bool
283 common_prefix_len: int
285 - cu_prefix_query_lens: Optional[torch.Tensor]
286 - prefix_kv_lens: Optional[torch.Tensor]
287 - suffix_kv_lens: Optional[torch.Tensor]
284 + cu_prefix_query_lens: torch.Tensor | None
285 + prefix_kv_lens: torch.Tensor | None
286 + suffix_kv_lens: torch.Tensor | None
287
288 # Block info
289 total_cache_tokens: int
@@ -300,15 +299,15 @@ class FlexAttentionMetadata:
299
300 # Flex Metadata
301 num_blocks = 0
303 - block_mask: Optional[BlockMask] = None
304 - score_mod: Optional[_score_mod_signature] = None
302 + block_mask: BlockMask | None = None
303 + score_mod: _score_mod_signature | None = None
304 logical_mask_mod: _mask_mod_signature = causal_mask_mod
306 - doc_ids: Optional[torch.Tensor] = None
305 + doc_ids: torch.Tensor | None = None
306 direct_build: bool = True
307 q_block_size: int = 16
308 kv_block_size: int = 16
310 - transformed_score_mod: Optional[_score_mod_signature] = None
311 - sliding_window: Optional[int] = None
309 + transformed_score_mod: _score_mod_signature | None = None
310 + sliding_window: int | None = None
311
312 def _convert_physical_to_logical(
313 self,
@@ -443,7 +442,7 @@ class FlexAttentionMetadata:
442 mask_mod = and_masks(mask_mod, sliding_window_mask_mod)
443 return mask_mod
444
446 - def get_transformed_score_mod(self) -> Optional[_score_mod_signature]:
445 + def get_transformed_score_mod(self) -> _score_mod_signature | None:
446 """Creates the transformed score_mod function for FlexAttention.
447
448 This function wraps the user's score_mod to handle physical-to-logical
@@ -669,9 +668,9 @@ class FlexAttentionMetadataBuilder(AttentionMetadataBuilder[FlexAttentionMetadat
668
669
670 class FlexAttentionImpl(AttentionImpl):
672 - sliding_window: Optional[int]
673 - alibi_slopes: Optional[torch.Tensor]
674 - logits_soft_cap: Optional[float]
671 + sliding_window: int | None
672 + alibi_slopes: torch.Tensor | None
673 + logits_soft_cap: float | None
674
675 def __init__(
676 self,
@@ -679,12 +678,12 @@ class FlexAttentionImpl(AttentionImpl):
678 head_size: int,
679 scale: float,
680 num_kv_heads: int,
682 - alibi_slopes: Optional[list[float]],
683 - sliding_window: Optional[int],
681 + alibi_slopes: list[float] | None,
682 + sliding_window: int | None,
683 kv_cache_dtype: str,
685 - logits_soft_cap: Optional[float] = None,
684 + logits_soft_cap: float | None = None,
685 attn_type: AttentionType = AttentionType.DECODER,
687 - kv_sharing_target_layer_name: Optional[str] = None,
686 + kv_sharing_target_layer_name: str | None = None,
687 **kwargs,
688 ) -> None:
689 self.num_heads = num_heads
@@ -742,9 +741,9 @@ class FlexAttentionImpl(AttentionImpl):
741 value: torch.Tensor,
742 kv_cache: torch.Tensor,
743 attn_metadata: FlexAttentionMetadata,
745 - output: Optional[torch.Tensor] = None,
746 - output_scale: Optional[torch.Tensor] = None,
747 - output_block_scale: Optional[torch.Tensor] = None,
744 + output: torch.Tensor | None = None,
745 + output_scale: torch.Tensor | None = None,
746 + output_block_scale: torch.Tensor | None = None,
747 ) -> torch.Tensor:
748 """Forward pass with FLexAttention.
749
@@ -860,8 +859,8 @@ class FlexAttentionImpl(AttentionImpl):
859
860 def get_kernel_options(
861 query, block_m, block_n, use_direct_build: bool
863 -) -> dict[str, Union[int, bool]]:
864 - kernel_options: dict[str, Union[int, bool]] = {
862 +) -> dict[str, int | bool]:
863 + kernel_options: dict[str, int | bool] = {
864 "FORCE_USE_FLEX_ATTENTION": True,
865 }
866 if vllm_kernel_override_batch_invariant():
vllm/v1/attention/backends/gdn_attn.py
+13 -16
@@ -3,7 +3,6 @@
3 """Backend for GatedDeltaNet attention."""
4
5 from dataclasses import dataclass
6 -from typing import Optional
6
7 import torch
8
@@ -36,29 +35,27 @@ class GDNAttentionMetadata:
35 num_spec_decode_tokens: int
36 num_actual_tokens: int
37
39 - has_initial_state: Optional[torch.Tensor] = None
38 + has_initial_state: torch.Tensor | None = None
39
41 - spec_query_start_loc: Optional[torch.Tensor] = (
42 - None # shape: [num_spec_decodes + 1,]
43 - )
44 - non_spec_query_start_loc: Optional[torch.Tensor] = (
40 + spec_query_start_loc: torch.Tensor | None = None # shape: [num_spec_decodes + 1,]
41 + non_spec_query_start_loc: torch.Tensor | None = (
42 None # shape: [batch - num_spec_decodes + 1,]
43 )
44
48 - spec_state_indices_tensor: Optional[torch.Tensor] = None # shape: [batch, num_spec]
49 - non_spec_state_indices_tensor: Optional[torch.Tensor] = (
45 + spec_state_indices_tensor: torch.Tensor | None = None # shape: [batch, num_spec]
46 + non_spec_state_indices_tensor: torch.Tensor | None = (
47 None # shape: [batch - num_spec_decodes,]
48 )
52 - spec_sequence_masks: Optional[torch.Tensor] = None # shape: [batch,]
53 - spec_token_masks: Optional[torch.Tensor] = (
49 + spec_sequence_masks: torch.Tensor | None = None # shape: [batch,]
50 + spec_token_masks: torch.Tensor | None = (
51 None # shape: [num_prefill_tokens + num_decode_tokens,]
52 )
56 - num_accepted_tokens: Optional[torch.Tensor] = None # shape: [batch,]
53 + num_accepted_tokens: torch.Tensor | None = None # shape: [batch,]
54
55 # The following attributes are for triton implementation of causal_conv1d
59 - nums_dict: Optional[dict] = None
60 - batch_ptr: Optional[torch.Tensor] = None
61 - token_chunk_offset_ptr: Optional[torch.Tensor] = None
56 + nums_dict: dict | None = None
57 + batch_ptr: torch.Tensor | None = None
58 + token_chunk_offset_ptr: torch.Tensor | None = None
59
60
61 class GDNAttentionMetadataBuilder(AttentionMetadataBuilder[GDNAttentionMetadata]):
@@ -133,8 +130,8 @@ class GDNAttentionMetadataBuilder(AttentionMetadataBuilder[GDNAttentionMetadata]
130 self,
131 common_prefix_len: int,
132 common_attn_metadata: CommonAttentionMetadata,
136 - num_accepted_tokens: Optional[torch.Tensor] = None,
137 - num_decode_draft_tokens_cpu: Optional[torch.Tensor] = None,
133 + num_accepted_tokens: torch.Tensor | None = None,
134 + num_decode_draft_tokens_cpu: torch.Tensor | None = None,
135 fast_build: bool = False,
136 ) -> GDNAttentionMetadata:
137 m = common_attn_metadata
vllm/v1/attention/backends/mamba1_attn.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 import torch
7
@@ -26,7 +25,7 @@ class Mamba1AttentionMetadata:
25 query_start_loc: torch.Tensor
26 context_lens_tensor: torch.Tensor
27 state_indices_tensor: torch.Tensor
29 - has_initial_states: Optional[torch.Tensor]
28 + has_initial_states: torch.Tensor | None
29 num_prefills: int
30 num_prefill_tokens: int
31 num_decodes: int
vllm/v1/attention/backends/mamba2_attn.py
+7 -8
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import itertools
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 import torch
7
@@ -108,18 +107,18 @@ class Mamba2AttentionMetadata:
107
108 # The following tensors only contain prefill requests and will be None if
109 # the batch has no prefill request.
111 - has_initial_states_p: Optional[torch.Tensor]
112 - seq_idx_p: Optional[torch.Tensor]
110 + has_initial_states_p: torch.Tensor | None
111 + seq_idx_p: torch.Tensor | None
112
113 # cu_chunk_seqlen_p is a tensor of shape (nchunks+1,) that contains, for
114 # each chunk, its offests into the varlen sequence dimension. It is defined
115 # such that the i-th chunk contains tokens from cu_chunk_seqlen_p[i] to
116 # cu_chunk_seqlen_p[i+1].
118 - cu_chunk_seqlen_p: Optional[torch.Tensor]
117 + cu_chunk_seqlen_p: torch.Tensor | None
118
119 # last_chunk_indices_p is a tensor of shape (batch,) that contains the
120 # index of the last chunk for every sequence in the (prefill) batch.
122 - last_chunk_indices_p: Optional[torch.Tensor]
121 + last_chunk_indices_p: torch.Tensor | None
122
123 state_indices_tensor: torch.Tensor # shape: [batch,]
124 block_idx_last_scheduled_token: torch.Tensor # shape: [batch,]
@@ -128,9 +127,9 @@ class Mamba2AttentionMetadata:
127 num_computed_tokens_p: torch.Tensor # shape: [batch,]
128
129 # The following attributes are for triton implementation of causal_conv1d
131 - nums_dict: Optional[dict] = None
132 - batch_ptr: Optional[torch.Tensor] = None
133 - token_chunk_offset_ptr: Optional[torch.Tensor] = None
130 + nums_dict: dict | None = None
131 + batch_ptr: torch.Tensor | None = None
132 + token_chunk_offset_ptr: torch.Tensor | None = None
133
134
135 class Mamba2AttentionMetadataBuilder(
vllm/v1/attention/backends/mla/common.py
+37 -32
@@ -190,7 +190,7 @@ return curr_o @ W_O
190 import functools
191 from abc import abstractmethod
192 from dataclasses import dataclass, field
193 -from typing import ClassVar, Generic, Optional, TypeVar, Union
193 +from typing import ClassVar, Generic, TypeVar
194
195 import torch
196 from tqdm import tqdm
@@ -243,6 +243,8 @@ try:
243
244 flashinfer_available = True
245 except ImportError:
246 + BatchPrefillWithRaggedKVCacheWrapper = object
247 +
248 flashinfer_available = False
249
250
@@ -337,22 +339,22 @@ class MLACommonPrefillMetadata:
339 workspace: torch.Tensor
340
341 # for mla DCP
340 - cp_chunk_seq_lens: Optional[list[list[int]]] = None
341 - origin_context_lens: Optional[list[int]] = None
342 - cp_cu_seq_lens: Optional[torch.Tensor] = None
343 - chunk_size: Optional[int] = None
344 - cu_seq_lens_lst: Optional[list[list[int]]] = None
342 + cp_chunk_seq_lens: list[list[int]] | None = None
343 + origin_context_lens: list[int] | None = None
344 + cp_cu_seq_lens: torch.Tensor | None = None
345 + chunk_size: int | None = None
346 + cu_seq_lens_lst: list[list[int]] | None = None
347
348 block_table: torch.Tensor
349 query_start_loc: torch.Tensor
350 max_query_len: int
349 - chunked_context: Optional[ChunkedContextMetadata] = None
351 + chunked_context: ChunkedContextMetadata | None = None
352
353
354 @dataclass
355 class FlashInferPrefillMetadata(MLACommonPrefillMetadata):
354 - prefill_main: Optional["BatchPrefillWithRaggedKVCacheWrapper"] = None
355 - prefill_chunks: list["BatchPrefillWithRaggedKVCacheWrapper"] = field(
356 + prefill_main: BatchPrefillWithRaggedKVCacheWrapper | None = None
357 + prefill_chunks: list[BatchPrefillWithRaggedKVCacheWrapper] = field(
358 default_factory=list
359 )
360
@@ -362,15 +364,15 @@ class CudnnPrefillMetadata(MLACommonPrefillMetadata):
364 class ChunkedContextMetadata(MLACommonPrefillMetadata.ChunkedContextMetadata):
365 seq_lens: torch.Tensor
366
365 - query_seq_lens: Optional[torch.Tensor] = None
366 - cudnn_workspace: Optional[torch.Tensor] = None
367 + query_seq_lens: torch.Tensor | None = None
368 + cudnn_workspace: torch.Tensor | None = None
369
370
371 @dataclass
372 class MLACommonDecodeMetadata:
373 block_table: torch.Tensor
374 seq_lens: torch.Tensor
373 - dcp_tot_seq_lens: Optional[torch.Tensor]
375 + dcp_tot_seq_lens: torch.Tensor | None
376
377
378 D = TypeVar("D", bound=MLACommonDecodeMetadata)
@@ -407,12 +409,15 @@ class MLACommonMetadata(Generic[D]):
409 num_prefills: int
410
411 # The dimension of the attention heads
410 - head_dim: Optional[int] = None
412 + head_dim: int | None = None
413
412 - decode: Optional[D] = None
413 - prefill: Optional[
414 - Union[MLACommonPrefillMetadata, FlashInferPrefillMetadata, CudnnPrefillMetadata]
415 - ] = None
414 + decode: D | None = None
415 + prefill: (
416 + MLACommonPrefillMetadata
417 + | FlashInferPrefillMetadata
418 + | CudnnPrefillMetadata
419 + | None
420 + ) = None
421
422 def __post_init__(self):
423 if self.head_dim is not None:
@@ -508,7 +513,7 @@ class MLACommonMetadataBuilder(AttentionMetadataBuilder[M]):
513 layer_names: list[str],
514 vllm_config: VllmConfig,
515 device: torch.device,
511 - metadata_cls: Optional[type[M]] = None,
516 + metadata_cls: type[M] | None = None,
517 ):
518 self.metadata_cls = (
519 metadata_cls if metadata_cls is not None else MLACommonMetadata
@@ -580,7 +585,7 @@ class MLACommonMetadataBuilder(AttentionMetadataBuilder[M]):
585 FLASHINFER_WORKSPACE_BUFFER_SIZE, dtype=torch.uint8, device=device
586 )
587
583 - self._fi_prefill_main: Optional[BatchPrefillWithRaggedKVCacheWrapper] = None
588 + self._fi_prefill_main: BatchPrefillWithRaggedKVCacheWrapper | None = None
589 self._fi_prefill_chunks: list[BatchPrefillWithRaggedKVCacheWrapper] = []
590
591 self._global_hyperparameters = infer_global_hyperparameters(
@@ -683,7 +688,7 @@ class MLACommonMetadataBuilder(AttentionMetadataBuilder[M]):
688 query_start_loc_cpu: torch.Tensor,
689 query_start_loc_device: torch.Tensor,
690 num_decode_tokens: int,
686 - dcp_tot_seq_lens_device: Optional[torch.Tensor],
691 + dcp_tot_seq_lens_device: torch.Tensor | None,
692 ) -> MLACommonDecodeMetadata:
693 return MLACommonDecodeMetadata(
694 block_table=block_table_tensor,
@@ -1023,14 +1028,14 @@ class MLACommonBaseImpl(MLAAttentionImpl[A], Generic[A]):
1028 head_size: int,
1029 scale: float,
1030 num_kv_heads: int,
1026 - alibi_slopes: Optional[list[float]],
1027 - sliding_window: Optional[int],
1031 + alibi_slopes: list[float] | None,
1032 + sliding_window: int | None,
1033 kv_cache_dtype: str,
1029 - logits_soft_cap: Optional[float],
1034 + logits_soft_cap: float | None,
1035 attn_type: str,
1031 - kv_sharing_target_layer_name: Optional[str],
1036 + kv_sharing_target_layer_name: str | None,
1037 # MLA Specific Arguments
1033 - q_lora_rank: Optional[int],
1038 + q_lora_rank: int | None,
1039 kv_lora_rank: int,
1040 qk_nope_head_dim: int,
1041 qk_rope_head_dim: int,
@@ -1038,7 +1043,7 @@ class MLACommonBaseImpl(MLAAttentionImpl[A], Generic[A]):
1043 v_head_dim: int,
1044 kv_b_proj: ColumnParallelLinear,
1045 indexer=None,
1041 - q_pad_num_heads: Optional[int] = None,
1046 + q_pad_num_heads: int | None = None,
1047 ) -> None:
1048 if kv_sharing_target_layer_name is not None:
1049 raise NotImplementedError("KV sharing is not supported for MLA")
@@ -1226,7 +1231,7 @@ class MLACommonImpl(MLACommonBaseImpl[M], Generic[M]):
1231 and current_platform.get_device_capability()[0] == 9
1232 )
1233
1229 - self.dcp_world_size: Optional[int] = None
1234 + self.dcp_world_size: int | None = None
1235
1236 self.chunked_prefill_workspace_size = (
1237 MLACommonMetadataBuilder.determine_chunked_prefill_workspace_size(
@@ -1710,11 +1715,11 @@ class MLACommonImpl(MLACommonBaseImpl[M], Generic[M]):
1715 @abstractmethod
1716 def _forward_decode(
1717 self,
1713 - q: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
1718 + q: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
1719 kv_c_and_k_pe_cache: torch.Tensor,
1720 attn_metadata: M,
1721 layer: AttentionLayer,
1717 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
1722 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
1723 raise NotImplementedError
1724
1725 def forward(
@@ -1725,9 +1730,9 @@ class MLACommonImpl(MLACommonBaseImpl[M], Generic[M]):
1730 k_pe: torch.Tensor, # value in unified attn
1731 kv_cache: torch.Tensor,
1732 attn_metadata: M,
1728 - output: Optional[torch.Tensor] = None,
1729 - output_scale: Optional[torch.Tensor] = None,
1730 - output_block_scale: Optional[torch.Tensor] = None,
1733 + output: torch.Tensor | None = None,
1734 + output_scale: torch.Tensor | None = None,
1735 + output_block_scale: torch.Tensor | None = None,
1736 ) -> torch.Tensor:
1737 assert output is not None, "Output tensor must be provided."
1738
vllm/v1/attention/backends/mla/cutlass_mla.py
+8 -8
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import os
5 -from typing import ClassVar, Optional, Union
5 +from typing import ClassVar
6
7 import torch
8
@@ -46,7 +46,7 @@ class CutlassMLABackend(MLACommonBackend):
46 return CutlassMLAMetadataBuilder
47
48 @staticmethod
49 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
49 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
50 return [128]
51
52
@@ -95,12 +95,12 @@ class CutlassMLAImpl(MLACommonImpl[MLACommonMetadata]):
95 head_size: int,
96 scale: float,
97 num_kv_heads: int,
98 - alibi_slopes: Optional[list[float]],
99 - sliding_window: Optional[int],
98 + alibi_slopes: list[float] | None,
99 + sliding_window: int | None,
100 kv_cache_dtype: str,
101 - logits_soft_cap: Optional[float],
101 + logits_soft_cap: float | None,
102 attn_type: str,
103 - kv_sharing_target_layer_name: Optional[str],
103 + kv_sharing_target_layer_name: str | None,
104 # MLA Specific Arguments
105 **mla_args,
106 ) -> None:
@@ -232,11 +232,11 @@ class CutlassMLAImpl(MLACommonImpl[MLACommonMetadata]):
232
233 def _forward_decode(
234 self,
235 - q: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
235 + q: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
236 kv_c_and_k_pe_cache: torch.Tensor,
237 attn_metadata: MLACommonMetadata,
238 layer: AttentionLayer,
239 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
239 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
240 assert kv_c_and_k_pe_cache.numel() > 0
241 assert attn_metadata.decode is not None
242
vllm/v1/attention/backends/mla/flashattn_mla.py
+9 -9
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import ClassVar, Optional, Union
5 +from typing import ClassVar
6
7 import torch
8
@@ -55,7 +55,7 @@ class FlashAttnMLADecodeMetadata(MLACommonDecodeMetadata):
55 query_start_loc: torch.Tensor
56 max_query_len: int
57 max_seq_len: int
58 - scheduler_metadata: Optional[torch.Tensor] = None
58 + scheduler_metadata: torch.Tensor | None = None
59 max_num_splits: int = 0
60
61
@@ -135,7 +135,7 @@ class FlashAttnMLAMetadataBuilder(MLACommonMetadataBuilder[FlashAttnMLAMetadata]
135 query_start_loc_cpu: torch.Tensor,
136 query_start_loc_device: torch.Tensor,
137 num_decode_tokens: int,
138 - dcp_tot_seq_lens_device: Optional[torch.Tensor],
138 + dcp_tot_seq_lens_device: torch.Tensor | None,
139 ) -> FlashAttnMLADecodeMetadata:
140 query_lens_cpu = query_start_loc_cpu[1:] - query_start_loc_cpu[:-1]
141 max_query_len = query_lens_cpu.max().item()
@@ -195,12 +195,12 @@ class FlashAttnMLAImpl(MLACommonImpl[FlashAttnMLAMetadata]):
195 head_size: int,
196 scale: float,
197 num_kv_heads: int,
198 - alibi_slopes: Optional[list[float]],
199 - sliding_window: Optional[int],
198 + alibi_slopes: list[float] | None,
199 + sliding_window: int | None,
200 kv_cache_dtype: str,
201 - logits_soft_cap: Optional[float],
201 + logits_soft_cap: float | None,
202 attn_type: str,
203 - kv_sharing_target_layer_name: Optional[str],
203 + kv_sharing_target_layer_name: str | None,
204 # MLA Specific Arguments
205 **mla_args,
206 ) -> None:
@@ -242,11 +242,11 @@ class FlashAttnMLAImpl(MLACommonImpl[FlashAttnMLAMetadata]):
242
243 def _forward_decode(
244 self,
245 - q: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
245 + q: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
246 kv_c_and_k_pe_cache: torch.Tensor,
247 attn_metadata: FlashAttnMLAMetadata,
248 layer: AttentionLayer,
249 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
249 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
250 assert kv_c_and_k_pe_cache.numel() > 0
251 assert attn_metadata.decode is not None
252
vllm/v1/attention/backends/mla/flashinfer_mla.py
+9 -9
@@ -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 ClassVar, Optional, Union
4 +from typing import ClassVar
5
6 import torch
7 from flashinfer.decode import trtllm_batch_decode_with_kv_cache_mla
@@ -57,12 +57,12 @@ class FlashInferMLAImpl(MLACommonImpl[MLACommonMetadata]):
57 head_size: int,
58 scale: float,
59 num_kv_heads: int,
60 - alibi_slopes: Optional[list[float]],
61 - sliding_window: Optional[int],
60 + alibi_slopes: list[float] | None,
61 + sliding_window: int | None,
62 kv_cache_dtype: str,
63 - logits_soft_cap: Optional[float],
63 + logits_soft_cap: float | None,
64 attn_type: str,
65 - kv_sharing_target_layer_name: Optional[str],
65 + kv_sharing_target_layer_name: str | None,
66 # MLA Specific Arguments
67 **mla_args,
68 ) -> None:
@@ -96,16 +96,16 @@ class FlashInferMLAImpl(MLACommonImpl[MLACommonMetadata]):
96 )
97
98 self._workspace_buffer = g_fi_workspace
99 - self.bmm1_scale: Optional[float] = None
100 - self.bmm2_scale: Optional[float] = None
99 + self.bmm1_scale: float | None = None
100 + self.bmm2_scale: float | None = None
101
102 def _forward_decode(
103 self,
104 - q: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
104 + q: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
105 kv_c_and_k_pe_cache: torch.Tensor,
106 attn_metadata: MLACommonMetadata,
107 layer: AttentionLayer,
108 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
108 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
109 assert kv_c_and_k_pe_cache.numel() > 0
110 assert attn_metadata.decode is not None
111
vllm/v1/attention/backends/mla/flashmla.py
+9 -9
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import ClassVar, Optional, Union
5 +from typing import ClassVar
6
7 import torch
8
@@ -45,7 +45,7 @@ class FlashMLABackend(MLACommonBackend):
45 return FlashMLAImpl
46
47 @staticmethod
48 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
48 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
49 return [64]
50
51
@@ -106,7 +106,7 @@ class FlashMLAMetadataBuilder(MLACommonMetadataBuilder[FlashMLAMetadata]):
106 query_start_loc_cpu: torch.Tensor,
107 query_start_loc_device: torch.Tensor,
108 num_decode_tokens: int,
109 - dcp_tot_seq_lens_device: Optional[torch.Tensor],
109 + dcp_tot_seq_lens_device: torch.Tensor | None,
110 ) -> FlashMLADecodeMetadata:
111 tile_scheduler_metadata, num_splits = get_mla_metadata(
112 seq_lens_device,
@@ -160,12 +160,12 @@ class FlashMLAImpl(MLACommonImpl[FlashMLAMetadata]):
160 head_size: int,
161 scale: float,
162 num_kv_heads: int,
163 - alibi_slopes: Optional[list[float]],
164 - sliding_window: Optional[int],
163 + alibi_slopes: list[float] | None,
164 + sliding_window: int | None,
165 kv_cache_dtype: str,
166 - logits_soft_cap: Optional[float],
166 + logits_soft_cap: float | None,
167 attn_type: str,
168 - kv_sharing_target_layer_name: Optional[str],
168 + kv_sharing_target_layer_name: str | None,
169 # MLA Specific Arguments
170 **mla_args,
171 ) -> None:
@@ -203,11 +203,11 @@ class FlashMLAImpl(MLACommonImpl[FlashMLAMetadata]):
203
204 def _forward_decode(
205 self,
206 - q: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
206 + q: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
207 kv_c_and_k_pe_cache: torch.Tensor,
208 attn_metadata: FlashMLAMetadata,
209 layer: AttentionLayer,
210 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
210 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
211 # TODO: (zyongye) decode function for mla here
212 assert kv_c_and_k_pe_cache.numel() > 0
213 assert attn_metadata.decode is not None
vllm/v1/attention/backends/mla/flashmla_sparse.py
+10 -10
@@ -110,12 +110,12 @@ class FlashMLASparseMetadata:
110
111 @dataclass
112 class FP8KernelMetadata:
113 - scheduler_metadata: Optional[torch.Tensor]
113 + scheduler_metadata: torch.Tensor | None
114 num_splits: torch.Tensor
115 dummy_block_table: torch.Tensor
116 cache_lens: torch.Tensor
117
118 - fp8_extra_metadata: Optional[FP8KernelMetadata] = None
118 + fp8_extra_metadata: FP8KernelMetadata | None = None
119
120
121 @triton.jit
@@ -373,14 +373,14 @@ class FlashMLASparseImpl(MLACommonBaseImpl[FlashMLASparseMetadata]):
373 head_size: int,
374 scale: float,
375 num_kv_heads: int,
376 - alibi_slopes: Optional[list[float]],
377 - sliding_window: Optional[int],
376 + alibi_slopes: list[float] | None,
377 + sliding_window: int | None,
378 kv_cache_dtype: str,
379 - logits_soft_cap: Optional[float],
379 + logits_soft_cap: float | None,
380 attn_type: str,
381 - kv_sharing_target_layer_name: Optional[str],
381 + kv_sharing_target_layer_name: str | None,
382 # MLA Specific Arguments
383 - topk_indice_buffer: Optional[torch.Tensor] = None,
383 + topk_indice_buffer: torch.Tensor | None = None,
384 indexer: Optional["Indexer"] = None,
385 **mla_args,
386 ) -> None:
@@ -466,9 +466,9 @@ class FlashMLASparseImpl(MLACommonBaseImpl[FlashMLASparseMetadata]):
466 k_pe: torch.Tensor, # value in unified attn
467 kv_cache: torch.Tensor,
468 attn_metadata: FlashMLASparseMetadata,
469 - output: Optional[torch.Tensor] = None,
470 - output_scale: Optional[torch.Tensor] = None,
471 - output_block_scale: Optional[torch.Tensor] = None,
469 + output: torch.Tensor | None = None,
470 + output_scale: torch.Tensor | None = None,
471 + output_block_scale: torch.Tensor | None = None,
472 ) -> torch.Tensor:
473 # NOTE(lucas): for the sparse FlashMLA kernels the kernels want to use
474 # MQA 576/512 approach for both prefill and decode
vllm/v1/attention/backends/mla/indexer.py
+4 -4
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import ClassVar, Optional, Union
4 +from typing import ClassVar
5
6 import torch
7
@@ -52,7 +52,7 @@ class DeepseekV32IndexerBackend(AttentionBackend):
52 return (0, 1, 2)
53
54 @classmethod
55 - def get_supported_kernel_block_size(cls) -> list[Union[int, MultipleOf]]:
55 + def get_supported_kernel_block_size(cls) -> list[int | MultipleOf]:
56 return [64]
57
58
@@ -105,8 +105,8 @@ class DeepseekV32IndexerMetadata:
105 num_prefills: int
106 num_prefill_tokens: int
107
108 - decode: Optional[DeepSeekV32IndexerDecodeMetadata] = None
109 - prefill: Optional[DeepseekV32IndexerPrefillMetadata] = None
108 + decode: DeepSeekV32IndexerDecodeMetadata | None = None
109 + prefill: DeepseekV32IndexerPrefillMetadata | None = None
110
111
112 # TODO (zyongye) optimize this, this is now vibe coded
vllm/v1/attention/backends/mla/rocm_aiter_mla.py
+12 -12
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import ClassVar, Optional, Union
5 +from typing import ClassVar
6
7 import torch
8
@@ -47,14 +47,14 @@ class AiterMLABackend(MLACommonBackend):
47 @dataclass
48 class AiterMLADecodeMetadata(MLACommonDecodeMetadata):
49 # The indptr of the paged kv cache, shape: [batch_size + 1]
50 - paged_kv_indptr: Optional[torch.Tensor] = None
50 + paged_kv_indptr: torch.Tensor | None = None
51 # The page indices of the paged kv cache
52 - paged_kv_indices: Optional[torch.Tensor] = None
52 + paged_kv_indices: torch.Tensor | None = None
53 # The number of entries in the last page of each request in
54 # the paged kv cache, shape: [batch_size]
55 - paged_kv_last_page_len: Optional[torch.Tensor] = None
55 + paged_kv_last_page_len: torch.Tensor | None = None
56 # The query indptr, shape : [num_decode + 1]
57 - qo_indptr: Optional[torch.Tensor] = None
57 + qo_indptr: torch.Tensor | None = None
58
59
60 class AiterMLAMetadata(MLACommonMetadata[AiterMLADecodeMetadata]):
@@ -116,7 +116,7 @@ class AiterMLAMetadataBuilder(MLACommonMetadataBuilder[AiterMLAMetadata]):
116 query_start_loc_cpu: torch.Tensor,
117 query_start_loc_device: torch.Tensor,
118 num_decode_tokens: int,
119 - dcp_tot_seq_lens_device: Optional[torch.Tensor],
119 + dcp_tot_seq_lens_device: torch.Tensor | None,
120 ) -> AiterMLADecodeMetadata:
121 page_size = self.kv_cache_spec.block_size
122 block_table_bounds = (seq_lens_device + page_size - 1) // page_size
@@ -188,12 +188,12 @@ class AiterMLAImpl(MLACommonImpl[AiterMLAMetadata]):
188 head_size: int,
189 scale: float,
190 num_kv_heads: int,
191 - alibi_slopes: Optional[list[float]],
192 - sliding_window: Optional[int],
191 + alibi_slopes: list[float] | None,
192 + sliding_window: int | None,
193 kv_cache_dtype: str,
194 - logits_soft_cap: Optional[float],
194 + logits_soft_cap: float | None,
195 attn_type: str,
196 - kv_sharing_target_layer_name: Optional[str],
196 + kv_sharing_target_layer_name: str | None,
197 # MLA Specific Arguments
198 **mla_args,
199 ) -> None:
@@ -242,11 +242,11 @@ class AiterMLAImpl(MLACommonImpl[AiterMLAMetadata]):
242
243 def _forward_decode(
244 self,
245 - q: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
245 + q: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
246 kv_c_and_k_pe_cache: torch.Tensor,
247 attn_metadata: AiterMLAMetadata,
248 layer: AttentionLayer,
249 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
249 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
250 assert kv_c_and_k_pe_cache.numel() > 0
251 assert attn_metadata.decode is not None
252
vllm/v1/attention/backends/mla/triton_mla.py
+6 -7
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional, Union
4
5 import torch
6
@@ -44,12 +43,12 @@ class TritonMLAImpl(MLACommonImpl[MLACommonMetadata]):
43 head_size: int,
44 scale: float,
45 num_kv_heads: int,
47 - alibi_slopes: Optional[list[float]],
48 - sliding_window: Optional[int],
46 + alibi_slopes: list[float] | None,
47 + sliding_window: int | None,
48 kv_cache_dtype: str,
50 - logits_soft_cap: Optional[float],
49 + logits_soft_cap: float | None,
50 attn_type: str,
52 - kv_sharing_target_layer_name: Optional[str],
51 + kv_sharing_target_layer_name: str | None,
52 # MLA Specific Arguments
53 **mla_args,
54 ) -> None:
@@ -138,11 +137,11 @@ class TritonMLAImpl(MLACommonImpl[MLACommonMetadata]):
137
138 def _forward_decode(
139 self,
141 - q: Union[torch.Tensor, tuple[torch.Tensor, torch.Tensor]],
140 + q: torch.Tensor | tuple[torch.Tensor, torch.Tensor],
141 kv_c_and_k_pe_cache: torch.Tensor,
142 attn_metadata: MLACommonMetadata,
143 layer: AttentionLayer,
145 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
144 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
145 assert kv_c_and_k_pe_cache.numel() > 0
146 assert attn_metadata.decode is not None
147
vllm/v1/attention/backends/pallas.py
+8 -9
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 import torch
7
@@ -201,12 +200,12 @@ class PallasAttentionBackendImpl(AttentionImpl):
200 head_size: int,
201 scale: float,
202 num_kv_heads: int,
204 - alibi_slopes: Optional[list[float]],
205 - sliding_window: Optional[int],
203 + alibi_slopes: list[float] | None,
204 + sliding_window: int | None,
205 kv_cache_dtype: str,
207 - logits_soft_cap: Optional[float] = None,
206 + logits_soft_cap: float | None = None,
207 attn_type: str = AttentionType.DECODER,
209 - kv_sharing_target_layer_name: Optional[int] = None,
208 + kv_sharing_target_layer_name: int | None = None,
209 ) -> None:
210 self.num_heads = num_heads
211 self.head_size = head_size
@@ -242,9 +241,9 @@ class PallasAttentionBackendImpl(AttentionImpl):
241 value: torch.Tensor,
242 kv_cache: torch.Tensor,
243 attn_metadata: PallasMetadata,
245 - output: Optional[torch.Tensor] = None,
246 - output_scale: Optional[torch.Tensor] = None,
247 - output_block_scale: Optional[torch.Tensor] = None,
244 + output: torch.Tensor | None = None,
245 + output_scale: torch.Tensor | None = None,
246 + output_block_scale: torch.Tensor | None = None,
247 ) -> torch.Tensor:
248 """Forward pass with Pallas attention.
249
@@ -342,7 +341,7 @@ def write_to_kv_cache(
341 slot_mapping: torch.Tensor,
342 num_slices_per_kv_cache_update_block: int,
343 num_kv_update_slices: torch.Tensor,
345 - kv_cache_quantized_dtype: Optional[torch.dtype] = None,
344 + kv_cache_quantized_dtype: torch.dtype | None = None,
345 k_scale: float = 1.0,
346 v_scale: float = 1.0,
347 ) -> None:
vllm/v1/attention/backends/rocm_aiter_fa.py
+14 -15
@@ -3,7 +3,6 @@
3 """Attention layer with AiterFlashAttention."""
4
5 from dataclasses import dataclass
6 -from typing import Optional, Union
6
7 import torch
8
@@ -160,8 +159,8 @@ if current_platform.is_rocm():
159 max_seqlen_q: int,
160 max_seqlen_k: int,
161 softmax_scale: float,
163 - window_size: Optional[list[int]], # -1 means infinite context window
164 - alibi_slopes: Optional[list[float]],
162 + window_size: list[int] | None, # -1 means infinite context window
163 + alibi_slopes: list[float] | None,
164 block_table: torch.Tensor,
165 k_scale: torch.Tensor,
166 v_scale: torch.Tensor,
@@ -209,8 +208,8 @@ if current_platform.is_rocm():
208 max_seqlen_q: int,
209 max_seqlen_k: int,
210 softmax_scale: float,
212 - window_size: Optional[list[int]], # -1 means infinite context window
213 - alibi_slopes: Optional[list[float]],
211 + window_size: list[int] | None, # -1 means infinite context window
212 + alibi_slopes: list[float] | None,
213 block_table: torch.Tensor,
214 k_scale: torch.Tensor,
215 v_scale: torch.Tensor,
@@ -249,7 +248,7 @@ class AiterFlashAttentionMetadata:
248 seq_lens: torch.Tensor
249 slot_mapping: torch.Tensor
250 block_table: torch.Tensor
252 - cu_seq_lens: Optional[torch.Tensor]
251 + cu_seq_lens: torch.Tensor | None
252
253 # For cascade attention.
254 use_cascade: bool
@@ -283,7 +282,7 @@ class AiterFlashAttentionMetadataBuilder(
282 self.block_size = kv_cache_spec.block_size
283 # Sliding window size to be used with the AOT scheduler will be
284 # populated on first build() call.
286 - self.aot_sliding_window: Optional[tuple[int, int]] = None
285 + self.aot_sliding_window: tuple[int, int] | None = None
286 self.total_tokens: int = 0
287
288 def build_for_cudagraph_capture(
@@ -361,7 +360,7 @@ class AiterFlashAttentionBackend(AttentionBackend):
360 return [64, 128, 256]
361
362 @staticmethod
364 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
363 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
364 return [MultipleOf(16)]
365
366 @classmethod
@@ -412,12 +411,12 @@ class AiterFlashAttentionImpl(AttentionImpl):
411 head_size: int,
412 scale: float,
413 num_kv_heads: int,
415 - alibi_slopes: Optional[list[float]],
416 - sliding_window: Optional[int],
414 + alibi_slopes: list[float] | None,
415 + sliding_window: int | None,
416 kv_cache_dtype: str,
418 - logits_soft_cap: Optional[float] = None,
417 + logits_soft_cap: float | None = None,
418 attn_type: AttentionType = AttentionType.DECODER,
420 - kv_sharing_target_layer_name: Optional[int] = None,
419 + kv_sharing_target_layer_name: int | None = None,
420 ) -> None:
421 self.num_heads = num_heads
422 self.head_size = head_size
@@ -458,9 +457,9 @@ class AiterFlashAttentionImpl(AttentionImpl):
457 value: torch.Tensor,
458 kv_cache: torch.Tensor,
459 attn_metadata: AiterFlashAttentionMetadata,
461 - output: Optional[torch.Tensor] = None,
462 - output_scale: Optional[torch.Tensor] = None,
463 - output_block_scale: Optional[torch.Tensor] = None,
460 + output: torch.Tensor | None = None,
461 + output_scale: torch.Tensor | None = None,
462 + output_block_scale: torch.Tensor | None = None,
463 ) -> torch.Tensor:
464 """Forward pass with AiterFlashAttention.
465
vllm/v1/attention/backends/rocm_aiter_unified_attn.py
+8 -10
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Attention layer with PagedAttention and Triton prefix prefill."""
4
5 -from typing import Optional
6 -
5 import torch
6
7 from vllm import _custom_ops as ops
@@ -70,13 +68,13 @@ class RocmAiterUnifiedAttentionImpl(RocmAttentionImpl):
68 head_size: int,
69 scale: float,
70 num_kv_heads: int,
73 - alibi_slopes: Optional[list[float]],
74 - sliding_window: Optional[int],
71 + alibi_slopes: list[float] | None,
72 + sliding_window: int | None,
73 kv_cache_dtype: str,
76 - logits_soft_cap: Optional[float] = None,
74 + logits_soft_cap: float | None = None,
75 attn_type: AttentionType = AttentionType.DECODER,
78 - kv_sharing_target_layer_name: Optional[int] = None,
79 - sinks: Optional[torch.Tensor] = None,
76 + kv_sharing_target_layer_name: int | None = None,
77 + sinks: torch.Tensor | None = None,
78 ) -> None:
79 super().__init__(
80 num_heads,
@@ -106,9 +104,9 @@ class RocmAiterUnifiedAttentionImpl(RocmAttentionImpl):
104 value: torch.Tensor,
105 kv_cache: torch.Tensor,
106 attn_metadata: FlashAttentionMetadata,
109 - output: Optional[torch.Tensor] = None,
110 - output_scale: Optional[torch.Tensor] = None,
111 - output_block_scale: Optional[torch.Tensor] = None,
107 + output: torch.Tensor | None = None,
108 + output_scale: torch.Tensor | None = None,
109 + output_block_scale: torch.Tensor | None = None,
110 ) -> torch.Tensor:
111 """Forward pass with FlashAttention.
112
vllm/v1/attention/backends/rocm_attn.py
+14 -14
@@ -3,7 +3,7 @@
3 """Attention layer with PagedAttention and Triton prefix prefill."""
4
5 from dataclasses import dataclass
6 -from typing import ClassVar, Optional
6 +from typing import ClassVar
7
8 import torch
9
@@ -54,13 +54,13 @@ class RocmAttentionMetadata:
54 # For cascade attention.
55 use_cascade: bool
56 common_prefix_len: int
57 - cu_prefix_query_lens: Optional[torch.Tensor]
58 - prefix_kv_lens: Optional[torch.Tensor]
59 - suffix_kv_lens: Optional[torch.Tensor]
57 + cu_prefix_query_lens: torch.Tensor | None
58 + prefix_kv_lens: torch.Tensor | None
59 + suffix_kv_lens: torch.Tensor | None
60
61 # Optional aot scheduling
62 - scheduler_metadata: Optional[torch.Tensor] = None
63 - prefix_scheduler_metadata: Optional[torch.Tensor] = None
62 + scheduler_metadata: torch.Tensor | None = None
63 + prefix_scheduler_metadata: torch.Tensor | None = None
64
65
66 class RocmAttentionMetadataBuilder(AttentionMetadataBuilder[RocmAttentionMetadata]):
@@ -217,13 +217,13 @@ class RocmAttentionImpl(AttentionImpl):
217 head_size: int,
218 scale: float,
219 num_kv_heads: int,
220 - alibi_slopes: Optional[list[float]],
221 - sliding_window: Optional[int],
220 + alibi_slopes: list[float] | None,
221 + sliding_window: int | None,
222 kv_cache_dtype: str,
223 - logits_soft_cap: Optional[float] = None,
223 + logits_soft_cap: float | None = None,
224 attn_type: AttentionType = AttentionType.DECODER,
225 - kv_sharing_target_layer_name: Optional[int] = None,
226 - sinks: Optional[torch.Tensor] = None,
225 + kv_sharing_target_layer_name: int | None = None,
226 + sinks: torch.Tensor | None = None,
227 ) -> None:
228 self.num_heads = num_heads
229 self.head_size = head_size
@@ -273,9 +273,9 @@ class RocmAttentionImpl(AttentionImpl):
273 value: torch.Tensor,
274 kv_cache: torch.Tensor,
275 attn_metadata: FlashAttentionMetadata,
276 - output: Optional[torch.Tensor] = None,
277 - output_scale: Optional[torch.Tensor] = None,
278 - output_block_scale: Optional[torch.Tensor] = None,
276 + output: torch.Tensor | None = None,
277 + output_scale: torch.Tensor | None = None,
278 + output_block_scale: torch.Tensor | None = None,
279 ) -> torch.Tensor:
280 """Forward pass with FlashAttention.
281
vllm/v1/attention/backends/short_conv_attn.py
+4 -5
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import Optional
4
5 import torch
6
@@ -30,12 +29,12 @@ class ShortConvAttentionMetadata:
29
30 query_start_loc: torch.Tensor
31 state_indices_tensor: torch.Tensor
33 - has_initial_states_p: Optional[torch.Tensor]
32 + has_initial_states_p: torch.Tensor | None
33
34 # For causal_conv1d
36 - nums_dict: Optional[dict] = None
37 - batch_ptr: Optional[torch.Tensor] = None
38 - token_chunk_offset_ptr: Optional[torch.Tensor] = None
35 + nums_dict: dict | None = None
36 + batch_ptr: torch.Tensor | None = None
37 + token_chunk_offset_ptr: torch.Tensor | None = None
38
39
40 class ShortConvAttentionMetadataBuilder(
vllm/v1/attention/backends/tree_attn.py
+12 -12
@@ -4,7 +4,7 @@
4
5 import ast
6 from dataclasses import dataclass
7 -from typing import Optional, Union
7 +from typing import Optional
8
9 import torch
10
@@ -41,7 +41,7 @@ class TreeAttentionBackend(AttentionBackend):
41 return [32, 64, 96, 128, 160, 192, 224, 256]
42
43 @staticmethod
44 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
44 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
45 return [MultipleOf(16)]
46
47 @classmethod
@@ -104,7 +104,7 @@ class TreeAttentionMetadata:
104 num_prefills: int = 0
105 num_decodes: int = 0
106
107 - tree_attn_bias: Optional[torch.Tensor] = None
107 + tree_attn_bias: torch.Tensor | None = None
108
109 # Cached Prefill/decode metadata.
110 _cached_prefill_metadata: Optional["TreeAttentionMetadata"] = None
@@ -267,8 +267,8 @@ def _get_depth_counts(sorted_tree_choices: list[tuple[int, ...]]) -> list[int]:
267 def _prepare_tree_attn_bias(
268 sorted_tree_choices: list[tuple[int, ...]],
269 depth_counts: list[int],
270 - dtype: Optional[torch.dtype],
271 - device: Optional[torch.device],
270 + dtype: torch.dtype | None,
271 + device: torch.device | None,
272 ) -> torch.Tensor:
273 # +1 comes from the additional root node.
274 tree_len = len(sorted_tree_choices) + 1
@@ -310,12 +310,12 @@ class TreeAttentionImpl(AttentionImpl):
310 head_size: int,
311 scale: float,
312 num_kv_heads: int,
313 - alibi_slopes: Optional[list[float]],
314 - sliding_window: Optional[int],
313 + alibi_slopes: list[float] | None,
314 + sliding_window: int | None,
315 kv_cache_dtype: str,
316 - logits_soft_cap: Optional[float] = None,
316 + logits_soft_cap: float | None = None,
317 attn_type: AttentionType = AttentionType.DECODER,
318 - kv_sharing_target_layer_name: Optional[str] = None,
318 + kv_sharing_target_layer_name: str | None = None,
319 ) -> None:
320 self.num_heads = num_heads
321 self.head_size = head_size
@@ -354,9 +354,9 @@ class TreeAttentionImpl(AttentionImpl):
354 value: torch.Tensor,
355 kv_cache: torch.Tensor,
356 attn_metadata: TreeAttentionMetadata,
357 - output: Optional[torch.Tensor] = None,
358 - output_scale: Optional[torch.Tensor] = None,
359 - output_block_scale: Optional[torch.Tensor] = None,
357 + output: torch.Tensor | None = None,
358 + output_scale: torch.Tensor | None = None,
359 + output_block_scale: torch.Tensor | None = None,
360 ) -> torch.Tensor:
361 """Forward pass with TreeAttention.
362
vllm/v1/attention/backends/triton_attn.py
+15 -15
@@ -3,7 +3,7 @@
3 """High-Performance Triton-only Attention layer."""
4
5 from dataclasses import dataclass
6 -from typing import ClassVar, Optional, Union
6 +from typing import ClassVar
7
8 import torch
9
@@ -61,13 +61,13 @@ class TritonAttentionMetadata:
61 # For cascade attention.
62 use_cascade: bool
63 common_prefix_len: int
64 - cu_prefix_query_lens: Optional[torch.Tensor]
65 - prefix_kv_lens: Optional[torch.Tensor]
66 - suffix_kv_lens: Optional[torch.Tensor]
64 + cu_prefix_query_lens: torch.Tensor | None
65 + prefix_kv_lens: torch.Tensor | None
66 + suffix_kv_lens: torch.Tensor | None
67
68 # Optional aot scheduling
69 - scheduler_metadata: Optional[torch.Tensor] = None
70 - prefix_scheduler_metadata: Optional[torch.Tensor] = None
69 + scheduler_metadata: torch.Tensor | None = None
70 + prefix_scheduler_metadata: torch.Tensor | None = None
71
72
73 class TritonAttentionMetadataBuilder(AttentionMetadataBuilder[TritonAttentionMetadata]):
@@ -159,7 +159,7 @@ class TritonAttentionBackend(AttentionBackend):
159 return [torch.float16, torch.bfloat16, torch.float32]
160
161 @staticmethod
162 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
162 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
163 return [MultipleOf(16)]
164
165 @classmethod
@@ -216,13 +216,13 @@ class TritonAttentionImpl(AttentionImpl):
216 head_size: int,
217 scale: float,
218 num_kv_heads: int,
219 - alibi_slopes: Optional[list[float]],
220 - sliding_window: Optional[int],
219 + alibi_slopes: list[float] | None,
220 + sliding_window: int | None,
221 kv_cache_dtype: str,
222 - logits_soft_cap: Optional[float] = None,
222 + logits_soft_cap: float | None = None,
223 attn_type: AttentionType = AttentionType.DECODER,
224 - kv_sharing_target_layer_name: Optional[int] = None,
225 - sinks: Optional[torch.Tensor] = None,
224 + kv_sharing_target_layer_name: int | None = None,
225 + sinks: torch.Tensor | None = None,
226 ) -> None:
227 self.num_heads = num_heads
228 self.head_size = head_size
@@ -272,9 +272,9 @@ class TritonAttentionImpl(AttentionImpl):
272 value: torch.Tensor,
273 kv_cache: torch.Tensor,
274 attn_metadata: TritonAttentionMetadata,
275 - output: Optional[torch.Tensor] = None,
276 - output_scale: Optional[torch.Tensor] = None,
277 - output_block_scale: Optional[torch.Tensor] = None,
275 + output: torch.Tensor | None = None,
276 + output_scale: torch.Tensor | None = None,
277 + output_block_scale: torch.Tensor | None = None,
278 ) -> torch.Tensor:
279 """Forward pass with Paged Attention impl. in Triton.
280
vllm/v1/attention/backends/utils.py
+10 -12
@@ -11,10 +11,8 @@ from typing import (
11 ClassVar,
12 Generic,
13 Literal,
14 - Optional,
14 Protocol,
15 TypeVar,
17 - Union,
16 get_args,
17 )
18
@@ -42,7 +40,7 @@ from vllm.v1.worker.ubatch_utils import UBatchSlice
40
41 logger = init_logger(__name__)
42 KVCacheLayoutType = Literal["NHD", "HND"]
45 -_KV_CACHE_LAYOUT_OVERRIDE: Union[KVCacheLayoutType, None] = None
43 +_KV_CACHE_LAYOUT_OVERRIDE: KVCacheLayoutType | None = None
44
45 PAD_SLOT_ID = -1
46
@@ -87,13 +85,13 @@ class CommonAttentionMetadata:
85 causal: bool = True
86
87 # Needed by FastPrefillAttentionBuilder
90 - logits_indices_padded: Optional[torch.Tensor] = None
91 - num_logits_indices: Optional[int] = None
88 + logits_indices_padded: torch.Tensor | None = None
89 + num_logits_indices: int | None = None
90
91 # Needed by CrossAttentionBuilder
94 - encoder_seq_lens: Optional[np.ndarray] = None
92 + encoder_seq_lens: np.ndarray | None = None
93
96 - dcp_local_seq_lens: Optional[torch.Tensor] = None
94 + dcp_local_seq_lens: torch.Tensor | None = None
95 """Sequence lengths of the local rank in decode context parallelism world"""
96
97
@@ -250,7 +248,7 @@ class AttentionMetadataBuilder(abc.ABC, Generic[M]):
248 # Does this backend/builder reorder the batch?
249 # If not, set this to None. Otherwise set it to the query
250 # length that will be pulled into the front of the batch.
253 - reorder_batch_threshold: Optional[int] = None
251 + reorder_batch_threshold: int | None = None
252
253 @abstractmethod
254 def __init__(
@@ -395,12 +393,12 @@ class PerLayerParameters:
393 """
394
395 window_left: int
398 - logits_soft_cap: Optional[float]
396 + logits_soft_cap: float | None
397 sm_scale: float
398 has_sinks: bool = False
399 # has same params for all layers
402 - has_same_window_lefts: Optional[bool] = field(default=None, compare=False)
403 - has_same_all_params: Optional[bool] = field(default=None, compare=False)
400 + has_same_window_lefts: bool | None = field(default=None, compare=False)
401 + has_same_all_params: bool | None = field(default=None, compare=False)
402
403
404 def get_per_layer_parameters(
@@ -873,7 +871,7 @@ def reshape_attn_output_for_spec_decode(attn_output: torch.Tensor) -> torch.Tens
871
872
873 KV_SHARING_FAST_PREFILL_METADATA_FIELDS = [
876 - ("logits_indices_padded", Optional[torch.Tensor], None),
874 + ("logits_indices_padded", torch.Tensor | None, None),
875 ("num_logits_indices", int, 0),
876 ]
877
vllm/v1/attention/backends/xformers.py
+9 -9
@@ -3,7 +3,7 @@
3 """Attention layer with XFormersAttention."""
4
5 from dataclasses import dataclass
6 -from typing import Optional, Union
6 +from typing import Optional
7
8 import torch
9
@@ -82,7 +82,7 @@ class XFormersAttentionBackend(AttentionBackend):
82 ]
83
84 @staticmethod
85 - def get_supported_kernel_block_size() -> list[Union[int, MultipleOf]]:
85 + def get_supported_kernel_block_size() -> list[int | MultipleOf]:
86 return [MultipleOf(16)]
87
88 @classmethod
@@ -280,12 +280,12 @@ class XFormersAttentionImpl(AttentionImpl):
280 head_size: int,
281 scale: float,
282 num_kv_heads: int,
283 - alibi_slopes: Optional[list[float]],
284 - sliding_window: Optional[int],
283 + alibi_slopes: list[float] | None,
284 + sliding_window: int | None,
285 kv_cache_dtype: str,
286 - logits_soft_cap: Optional[float] = None,
286 + logits_soft_cap: float | None = None,
287 attn_type: AttentionType = AttentionType.DECODER,
288 - kv_sharing_target_layer_name: Optional[str] = None,
288 + kv_sharing_target_layer_name: str | None = None,
289 ) -> None:
290 if kv_sharing_target_layer_name is not None:
291 raise NotImplementedError("KV sharing is not supported in V0.")
@@ -328,9 +328,9 @@ class XFormersAttentionImpl(AttentionImpl):
328 value: torch.Tensor,
329 kv_cache: torch.Tensor,
330 attn_metadata: XFormersAttentionMetadata,
331 - output: Optional[torch.Tensor] = None,
332 - output_scale: Optional[torch.Tensor] = None,
333 - output_block_scale: Optional[torch.Tensor] = None,
331 + output: torch.Tensor | None = None,
332 + output_scale: torch.Tensor | None = None,
333 + output_block_scale: torch.Tensor | None = None,
334 ) -> torch.Tensor:
335 """Forward pass with XFormers.
336
vllm/v1/core/block_pool.py
+7 -7
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterable
4 -from typing import Any, Optional, Union
4 +from typing import Any
5
6 from vllm.distributed.kv_events import (
7 MEDIUM_GPU,
@@ -51,10 +51,10 @@ class BlockHashToBlockMap:
51
52 def __init__(self):
53 self._cache: dict[
54 - BlockHashWithGroupId, Union[KVCacheBlock, dict[int, KVCacheBlock]]
54 + BlockHashWithGroupId, KVCacheBlock | dict[int, KVCacheBlock]
55 ] = {}
56
57 - def get_one_block(self, key: BlockHashWithGroupId) -> Optional[KVCacheBlock]:
57 + def get_one_block(self, key: BlockHashWithGroupId) -> KVCacheBlock | None:
58 """
59 Gets any block with the given block hash key.
60 """
@@ -85,7 +85,7 @@ class BlockHashToBlockMap:
85 else:
86 self._unexpected_blocks_type(blocks)
87
88 - def pop(self, key: BlockHashWithGroupId, block_id: int) -> Optional[KVCacheBlock]:
88 + def pop(self, key: BlockHashWithGroupId, block_id: int) -> KVCacheBlock | None:
89 """
90 Checks if block_hash exists and pop block_id from the cache
91 """
@@ -168,7 +168,7 @@ class BlockPool:
168
169 def get_cached_block(
170 self, block_hash: BlockHash, kv_cache_group_ids: list[int]
171 - ) -> Optional[list[KVCacheBlock]]:
171 + ) -> list[KVCacheBlock] | None:
172 """Get the cached block by the block hash for each group in
173 `kv_cache_group_ids`, or None if cache miss for any group.
174 If there are duplicated blocks, we return the first block in the cache.
@@ -225,7 +225,7 @@ class BlockPool:
225 assert len(request.block_hashes) >= num_full_blocks
226 new_block_hashes = request.block_hashes[num_cached_blocks:]
227
228 - new_hashes: Optional[list[ExternalBlockHash]] = (
228 + new_hashes: list[ExternalBlockHash] | None = (
229 [] if self.enable_kv_cache_events else None
230 )
231 for i, blk in enumerate(new_full_blocks):
@@ -243,7 +243,7 @@ class BlockPool:
243
244 if self.enable_kv_cache_events:
245 if num_cached_blocks == 0:
246 - parent_block_hash: Optional[ExternalBlockHash] = None
246 + parent_block_hash: ExternalBlockHash | None = None
247 else:
248 parent_block = blocks[num_cached_blocks - 1]
249 assert parent_block.block_hash is not None
vllm/v1/core/kv_cache_coordinator.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from abc import ABC, abstractmethod
4 -from typing import Optional
4
5 from vllm.v1.core.block_pool import BlockPool
6 from vllm.v1.core.kv_cache_utils import BlockHash, KVCacheBlock
@@ -320,8 +319,8 @@ class HybridKVCacheCoordinator(KVCacheCoordinator):
319 one of them is full attention. Then, split the kv cache groups into full
320 attention groups and other groups.
321 """
323 - full_attention_spec: Optional[FullAttentionSpec] = None
324 - other_spec: Optional[KVCacheSpec] = None
322 + full_attention_spec: FullAttentionSpec | None = None
323 + other_spec: KVCacheSpec | None = None
324 self.full_attention_group_ids: list[int] = []
325 self.other_group_ids: list[int] = []
326 for i, g in enumerate(self.kv_cache_config.kv_cache_groups):
vllm/v1/core/kv_cache_manager.py
+7 -7
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import Literal, Optional, overload
5 +from typing import Literal, overload
6
7 from vllm.distributed.kv_events import KVCacheEvent
8 from vllm.logger import init_logger
@@ -49,12 +49,12 @@ class KVCacheBlocks:
49 def get_block_ids(
50 self,
51 allow_none: Literal[True] = True,
52 - ) -> Optional[tuple[list[int], ...]]: ...
52 + ) -> tuple[list[int], ...] | None: ...
53
54 def get_block_ids(
55 self,
56 allow_none: bool = False,
57 - ) -> Optional[tuple[list[int], ...]]:
57 + ) -> tuple[list[int], ...] | None:
58 """
59 Converts the KVCacheBlocks instance to block_ids.
60
@@ -97,7 +97,7 @@ class KVCacheManager:
97 # FIXME: make prefix cache stats conditional on log_stats
98 self.prefix_cache_stats = PrefixCacheStats() if log_stats else None
99
100 - self.block_size: Optional[int] = None
100 + self.block_size: int | None = None
101 if self.enable_caching:
102 assert (
103 len(
@@ -140,7 +140,7 @@ class KVCacheManager:
140 """
141 return self.block_pool.get_usage()
142
143 - def make_prefix_cache_stats(self) -> Optional[PrefixCacheStats]:
143 + def make_prefix_cache_stats(self) -> PrefixCacheStats | None:
144 """Get (and reset) the prefix cache stats.
145
146 Returns:
@@ -205,11 +205,11 @@ class KVCacheManager:
205 request: Request,
206 num_new_tokens: int,
207 num_new_computed_tokens: int = 0,
208 - new_computed_blocks: Optional[KVCacheBlocks] = None,
208 + new_computed_blocks: KVCacheBlocks | None = None,
209 num_lookahead_tokens: int = 0,
210 delay_cache_blocks: bool = False,
211 num_encoder_tokens: int = 0,
212 - ) -> Optional[KVCacheBlocks]:
212 + ) -> KVCacheBlocks | None:
213 """Add slots for a request with new tokens to append.
214
215 Args:
vllm/v1/core/kv_cache_utils.py
+10 -10
@@ -5,9 +5,9 @@
5 import copy
6 import os
7 from collections import defaultdict
8 -from collections.abc import Iterable, Sequence
8 +from collections.abc import Callable, Iterable, Sequence
9 from dataclasses import dataclass
10 -from typing import Any, Callable, NewType, Optional, Union
10 +from typing import Any, NewType, TypeAlias
11
12 from vllm import envs
13 from vllm.config import VllmConfig
@@ -38,7 +38,7 @@ BlockHashWithGroupId = NewType("BlockHashWithGroupId", bytes)
38 # ExternalBlockHash is used for reproducible prefix-cache block hashing.
39 # It's a union of ``bytes`` and ``int`` to keep backward compatibility
40 # after we default block hashing to use sha256 bytes.
41 -ExternalBlockHash = Union[bytes, int]
41 +ExternalBlockHash: TypeAlias = bytes | int
42
43
44 def make_block_hash_with_group_id(
@@ -110,18 +110,18 @@ class KVCacheBlock:
110 ref_cnt: int = 0
111 # The hash key (block hash + group id) of the block, only available
112 # when the block is full and cached.
113 - _block_hash: Optional[BlockHashWithGroupId] = None
113 + _block_hash: BlockHashWithGroupId | None = None
114
115 # Used to construct a doubly linked list for free blocks.
116 # These two attributes should only be manipulated by FreeKVCacheBlockQueue.
117 - prev_free_block: Optional["KVCacheBlock"] = None
118 - next_free_block: Optional["KVCacheBlock"] = None
117 + prev_free_block: "KVCacheBlock | None" = None
118 + next_free_block: "KVCacheBlock | None" = None
119
120 # Whether the block is a null block that should never be cached.
121 is_null: bool = False
122
123 @property
124 - def block_hash(self) -> Optional[BlockHashWithGroupId]:
124 + def block_hash(self) -> BlockHashWithGroupId | None:
125 return self._block_hash
126
127 @block_hash.setter
@@ -461,7 +461,7 @@ def _gen_lora_extra_hash_keys(request: Request) -> list[int]:
461
462 def generate_block_hash_extra_keys(
463 request: Request, start_token_idx: int, end_token_idx: int, start_mm_idx: int
464 -) -> tuple[Optional[tuple[Any, ...]], int]:
464 +) -> tuple[tuple[Any, ...] | None, int]:
465 """Generate extra keys for the block hash. The extra keys can come from
466 the multi-modal inputs and request specific metadata (e.g., LoRA ID).
467
@@ -493,9 +493,9 @@ def generate_block_hash_extra_keys(
493
494 def hash_block_tokens(
495 hash_function: Callable[[Any], bytes],
496 - parent_block_hash: Optional[BlockHash],
496 + parent_block_hash: BlockHash | None,
497 curr_block_token_ids: Sequence[int],
498 - extra_keys: Optional[tuple[Any, ...]] = None,
498 + extra_keys: tuple[Any, ...] | None = None,
499 ) -> BlockHash:
500 """Computes a hash value corresponding to the contents of a block and
501 the contents of the preceding block(s). The hash value is used for
vllm/v1/core/sched/async_scheduler.py
-2
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 from vllm.logger import init_logger
5 from vllm.v1.core.sched.output import SchedulerOutput
6 from vllm.v1.core.sched.scheduler import Scheduler
vllm/v1/core/sched/interface.py
+2 -2
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from abc import ABC, abstractmethod
4 from collections.abc import Iterable
5 -from typing import TYPE_CHECKING, Optional, Union
5 +from typing import TYPE_CHECKING, Optional
6
7 if TYPE_CHECKING:
8 from vllm.distributed.kv_transfer.kv_connector.v1 import KVConnectorBase_V1
@@ -80,7 +80,7 @@ class SchedulerInterface(ABC):
80 @abstractmethod
81 def finish_requests(
82 self,
83 - request_ids: Union[str, Iterable[str]],
83 + request_ids: str | Iterable[str],
84 finished_status: "RequestStatus",
85 ) -> None:
86 """Finish the requests in the scheduler's internal queue. If the request
vllm/v1/core/sched/output.py
+11 -6
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 from dataclasses import dataclass
5 from typing import TYPE_CHECKING
6
@@ -19,6 +17,13 @@ if TYPE_CHECKING:
17 from vllm.pooling_params import PoolingParams
18 from vllm.sampling_params import SamplingParams
19 from vllm.v1.request import Request
20 +else:
21 + KVConnectorMetadata = object
22 + LoRARequest = object
23 + MultiModalFeatureSpec = object
24 + PoolingParams = object
25 + SamplingParams = object
26 + Request = object
27
28
29 @bc_linter_include
@@ -32,14 +37,14 @@ class NewRequestData:
37 block_ids: tuple[list[int], ...]
38 num_computed_tokens: int
39 lora_request: LoRARequest | None
35 - prompt_embeds: torch.Tensor | None = None
40 + prompt_embeds: "torch.Tensor | None" = None
41
42 @classmethod
43 def from_request(
44 cls,
45 request: Request,
46 block_ids: tuple[list[int], ...],
42 - ) -> NewRequestData:
47 + ) -> "NewRequestData":
48 return cls(
49 req_id=request.request_id,
50 prompt_token_ids=request.prompt_token_ids,
@@ -110,7 +115,7 @@ class CachedRequestData:
115 return len(self.req_ids)
116
117 @classmethod
113 - def make_empty(cls) -> CachedRequestData:
118 + def make_empty(cls) -> "CachedRequestData":
119 return cls(
120 req_ids=[],
121 resumed_from_preemption=[],
@@ -164,7 +169,7 @@ class SchedulerOutput:
169 # for filling the next token bitmask
170 structured_output_request_ids: dict[str, int]
171 # the bitmask for the whole batch
167 - grammar_bitmask: npt.NDArray[np.int32] | None
172 + grammar_bitmask: "npt.NDArray[np.int32] | None"
173
174 # KV Cache Connector metadata.
175 kv_connector_metadata: KVConnectorMetadata | None = None
vllm/v1/core/sched/request_queue.py
+1 -3
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import heapq
5 from abc import ABC, abstractmethod
6 from collections import deque
@@ -43,7 +41,7 @@ class RequestQueue(ABC):
41 pass
42
43 @abstractmethod
46 - def prepend_requests(self, requests: RequestQueue) -> None:
44 + def prepend_requests(self, requests: "RequestQueue") -> None:
45 """Prepend all requests from another queue to the front of this
46 queue."""
47 pass
vllm/v1/core/sched/scheduler.py
+2 -4
@@ -1,13 +1,11 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import itertools
5 import time
6 from collections import defaultdict
7 from collections.abc import Iterable
10 -from typing import Any, Union
8 +from typing import Any
9
10 from vllm.config import VllmConfig
11 from vllm.distributed.kv_events import EventPublisherFactory, KVEventBatch
@@ -1168,7 +1166,7 @@ class Scheduler(SchedulerInterface):
1166
1167 def finish_requests(
1168 self,
1171 - request_ids: Union[str, Iterable[str]],
1169 + request_ids: str | Iterable[str],
1170 finished_status: RequestStatus,
1171 ) -> None:
1172 """Handles the finish signal from outside the scheduler.
vllm/v1/core/sched/utils.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import contextlib
4 -from typing import Optional
4
5 import torch
6
@@ -41,7 +40,7 @@ def remove_all(lst: list, items_to_remove: set) -> list:
40
41
42 def check_stop(
44 - request: Request, max_model_len: int, pooler_output: Optional[torch.Tensor] = None
43 + request: Request, max_model_len: int, pooler_output: torch.Tensor | None = None
44 ) -> bool:
45 if (
46 request.num_tokens >= max_model_len
vllm/v1/cudagraph_dispatcher.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 from vllm.config import CUDAGraphMode, VllmConfig
5 from vllm.forward_context import BatchDescriptor
@@ -102,7 +101,7 @@ class CudagraphDispatcher:
101
102 def dispatch(
103 self, batch_descriptor: BatchDescriptor, use_cascade_attn: bool = False
105 - ) -> tuple[CUDAGraphMode, Optional[BatchDescriptor]]:
104 + ) -> tuple[CUDAGraphMode, BatchDescriptor | None]:
105 """
106 Given conditions(e.g.,batch descriptor and if using cascade attention),
107 dispatch to a cudagraph runtime mode and the valid batch descriptor.
vllm/v1/engine/__init__.py
+27 -27
@@ -4,7 +4,7 @@
4 import enum
5 import time
6 from collections.abc import Mapping
7 -from typing import Any, Optional, Union
7 +from typing import Any
8
9 import msgspec
10 import torch
@@ -48,16 +48,16 @@ class EngineCoreRequest(
48 gc=False,
49 ): # type: ignore[call-arg]
50 request_id: str
51 - prompt_token_ids: Optional[list[int]]
52 - mm_features: Optional[list[MultiModalFeatureSpec]]
53 - sampling_params: Optional[SamplingParams]
54 - pooling_params: Optional[PoolingParams]
55 - eos_token_id: Optional[int]
51 + prompt_token_ids: list[int] | None
52 + mm_features: list[MultiModalFeatureSpec] | None
53 + sampling_params: SamplingParams | None
54 + pooling_params: PoolingParams | None
55 + eos_token_id: int | None
56 arrival_time: float
57 - lora_request: Optional[LoRARequest]
58 - cache_salt: Optional[str]
59 - data_parallel_rank: Optional[int]
60 - prompt_embeds: Optional[torch.Tensor] = None
57 + lora_request: LoRARequest | None
58 + cache_salt: str | None
59 + data_parallel_rank: int | None
60 + prompt_embeds: torch.Tensor | None = None
61
62 # Index of the client, used to ensure outputs are sent back to the same
63 # client for this request when scaling out the front-end.
@@ -69,7 +69,7 @@ class EngineCoreRequest(
69 current_wave: int = 0
70 priority: int = 0
71
72 - trace_headers: Optional[Mapping[str, str]] = None
72 + trace_headers: Mapping[str, str] | None = None
73
74
75 class EngineCoreEventType(enum.IntEnum):
@@ -93,7 +93,7 @@ class EngineCoreEvent(msgspec.Struct):
93
94 @classmethod
95 def new_event(
96 - cls, event_type: EngineCoreEventType, timestamp: Optional[float] = None
96 + cls, event_type: EngineCoreEventType, timestamp: float | None = None
97 ) -> "EngineCoreEvent":
98 timestamp = time.monotonic() if timestamp is None else timestamp
99 return cls(event_type, timestamp)
@@ -108,17 +108,17 @@ class EngineCoreOutput(
108 request_id: str
109 new_token_ids: list[int]
110
111 - new_logprobs: Optional[LogprobsLists] = None
112 - new_prompt_logprobs_tensors: Optional[LogprobsTensors] = None
111 + new_logprobs: LogprobsLists | None = None
112 + new_prompt_logprobs_tensors: LogprobsTensors | None = None
113
114 - pooling_output: Optional[torch.Tensor] = None
114 + pooling_output: torch.Tensor | None = None
115
116 - finish_reason: Optional[FinishReason] = None
117 - stop_reason: Union[int, str, None] = None
118 - events: Optional[list[EngineCoreEvent]] = None
119 - kv_transfer_params: Optional[dict[str, Any]] = None
116 + finish_reason: FinishReason | None = None
117 + stop_reason: int | str | None = None
118 + events: list[EngineCoreEvent] | None = None
119 + kv_transfer_params: dict[str, Any] | None = None
120
121 - trace_headers: Optional[Mapping[str, str]] = None
121 + trace_headers: Mapping[str, str] | None = None
122 # The number of tokens with prefix cache hits.
123 num_cached_tokens: int = 0
124
@@ -142,8 +142,8 @@ class UtilityOutput(
142 call_id: int
143
144 # Non-None implies the call failed, result should be None.
145 - failure_message: Optional[str] = None
146 - result: Optional[UtilityResult] = None
145 + failure_message: str | None = None
146 + result: UtilityResult | None = None
147
148
149 class EngineCoreOutputs(
@@ -159,18 +159,18 @@ class EngineCoreOutputs(
159
160 # [num_reqs]
161 outputs: list[EngineCoreOutput] = []
162 - scheduler_stats: Optional[SchedulerStats] = None
162 + scheduler_stats: SchedulerStats | None = None
163 timestamp: float = 0.0
164
165 - utility_output: Optional[UtilityOutput] = None
166 - finished_requests: Optional[set[str]] = None
165 + utility_output: UtilityOutput | None = None
166 + finished_requests: set[str] | None = None
167
168 # In DP case, used to signal that the current wave of requests
169 # has finished and the engines are paused.
170 - wave_complete: Optional[int] = None
170 + wave_complete: int | None = None
171 # In DP case, used to signal that a request was received for an
172 # "old" wave, so the next wave needs to be started in other engines.
173 - start_wave: Optional[int] = None
173 + start_wave: int | None = None
174
175 def __post_init__(self):
176 if self.timestamp == 0.0:
vllm/v1/engine/async_llm.py
+35 -35
@@ -6,7 +6,7 @@ import socket
6 import time
7 from collections.abc import AsyncGenerator, Iterable, Mapping
8 from copy import copy
9 -from typing import Any, Optional, Union
9 +from typing import Any
10
11 import numpy as np
12 import torch
@@ -56,8 +56,8 @@ class AsyncLLM(EngineClient):
56 use_cached_outputs: bool = False,
57 log_requests: bool = True,
58 start_engine_loop: bool = True,
59 - stat_loggers: Optional[list[StatLoggerFactory]] = None,
60 - client_addresses: Optional[dict[str, str]] = None,
59 + stat_loggers: list[StatLoggerFactory] | None = None,
60 + client_addresses: dict[str, str] | None = None,
61 client_count: int = 1,
62 client_index: int = 0,
63 ) -> None:
@@ -136,7 +136,7 @@ class AsyncLLM(EngineClient):
136 )
137
138 # Loggers.
139 - self.logger_manager: Optional[StatLoggerManager] = None
139 + self.logger_manager: StatLoggerManager | None = None
140 if self.log_stats:
141 self.logger_manager = StatLoggerManager(
142 vllm_config=vllm_config,
@@ -147,7 +147,7 @@ class AsyncLLM(EngineClient):
147 )
148 self.logger_manager.log_engine_initialized()
149
150 - self.output_handler: Optional[asyncio.Task] = None
150 + self.output_handler: asyncio.Task | None = None
151 try:
152 # Start output handler eagerly if we are in the asyncio eventloop.
153 asyncio.get_running_loop()
@@ -185,10 +185,10 @@ class AsyncLLM(EngineClient):
185 vllm_config: VllmConfig,
186 start_engine_loop: bool = True,
187 usage_context: UsageContext = UsageContext.ENGINE_CONTEXT,
188 - stat_loggers: Optional[list[StatLoggerFactory]] = None,
188 + stat_loggers: list[StatLoggerFactory] | None = None,
189 enable_log_requests: bool = False,
190 disable_log_stats: bool = False,
191 - client_addresses: Optional[dict[str, str]] = None,
191 + client_addresses: dict[str, str] | None = None,
192 client_count: int = 1,
193 client_index: int = 0,
194 disable_log_requests: bool = True, # Deprecated, will be removed
@@ -221,7 +221,7 @@ class AsyncLLM(EngineClient):
221 engine_args: AsyncEngineArgs,
222 start_engine_loop: bool = True,
223 usage_context: UsageContext = UsageContext.ENGINE_CONTEXT,
224 - stat_loggers: Optional[list[StatLoggerFactory]] = None,
224 + stat_loggers: list[StatLoggerFactory] | None = None,
225 ) -> "AsyncLLM":
226 """Create an AsyncLLM from the EngineArgs."""
227
@@ -259,15 +259,15 @@ class AsyncLLM(EngineClient):
259 async def add_request(
260 self,
261 request_id: str,
262 - prompt: Union[EngineCoreRequest, PromptType],
263 - params: Union[SamplingParams, PoolingParams],
264 - arrival_time: Optional[float] = None,
265 - lora_request: Optional[LoRARequest] = None,
266 - tokenization_kwargs: Optional[dict[str, Any]] = None,
267 - trace_headers: Optional[Mapping[str, str]] = None,
262 + prompt: EngineCoreRequest | PromptType,
263 + params: SamplingParams | PoolingParams,
264 + arrival_time: float | None = None,
265 + lora_request: LoRARequest | None = None,
266 + tokenization_kwargs: dict[str, Any] | None = None,
267 + trace_headers: Mapping[str, str] | None = None,
268 priority: int = 0,
269 - data_parallel_rank: Optional[int] = None,
270 - prompt_text: Optional[str] = None,
269 + data_parallel_rank: int | None = None,
270 + prompt_text: str | None = None,
271 ) -> RequestOutputCollector:
272 """Add new request to the AsyncLLM."""
273
@@ -325,8 +325,8 @@ class AsyncLLM(EngineClient):
325 async def _add_request(
326 self,
327 request: EngineCoreRequest,
328 - prompt: Optional[str],
329 - parent_req: Optional[ParentRequest],
328 + prompt: str | None,
329 + parent_req: ParentRequest | None,
330 index: int,
331 queue: RequestOutputCollector,
332 ):
@@ -346,16 +346,16 @@ class AsyncLLM(EngineClient):
346 # re-multiplexed in the API server anyhow.
347 async def generate(
348 self,
349 - prompt: Union[EngineCoreRequest, PromptType],
349 + prompt: EngineCoreRequest | PromptType,
350 sampling_params: SamplingParams,
351 request_id: str,
352 *,
353 - prompt_text: Optional[str] = None,
354 - lora_request: Optional[LoRARequest] = None,
355 - tokenization_kwargs: Optional[dict[str, Any]] = None,
356 - trace_headers: Optional[Mapping[str, str]] = None,
353 + prompt_text: str | None = None,
354 + lora_request: LoRARequest | None = None,
355 + tokenization_kwargs: dict[str, Any] | None = None,
356 + trace_headers: Mapping[str, str] | None = None,
357 priority: int = 0,
358 - data_parallel_rank: Optional[int] = None,
358 + data_parallel_rank: int | None = None,
359 ) -> AsyncGenerator[RequestOutput, None]:
360 """
361 Main function called by the API server to kick off a request
@@ -520,7 +520,7 @@ class AsyncLLM(EngineClient):
520
521 self.output_handler = asyncio.create_task(output_handler())
522
523 - async def abort(self, request_id: Union[str, Iterable[str]]) -> None:
523 + async def abort(self, request_id: str | Iterable[str]) -> None:
524 """Abort RequestId in OutputProcessor and EngineCore."""
525
526 request_ids = (
@@ -537,11 +537,11 @@ class AsyncLLM(EngineClient):
537 prompt: PromptType,
538 pooling_params: PoolingParams,
539 request_id: str,
540 - lora_request: Optional[LoRARequest] = None,
541 - trace_headers: Optional[Mapping[str, str]] = None,
540 + lora_request: LoRARequest | None = None,
541 + trace_headers: Mapping[str, str] | None = None,
542 priority: int = 0,
543 - truncate_prompt_tokens: Optional[int] = None,
544 - tokenization_kwargs: Optional[dict[str, Any]] = None,
543 + truncate_prompt_tokens: int | None = None,
544 + tokenization_kwargs: dict[str, Any] | None = None,
545 ) -> AsyncGenerator[PoolingRequestOutput, None]:
546 """
547 Main function called by the API server to kick off a request
@@ -622,11 +622,11 @@ class AsyncLLM(EngineClient):
622 raise EngineGenerateError() from e
623
624 @property
625 - def tokenizer(self) -> Optional[AnyTokenizer]:
625 + def tokenizer(self) -> AnyTokenizer | None:
626 return self.processor.tokenizer
627
628 @tokenizer.setter
629 - def tokenizer(self, tokenizer: Optional[AnyTokenizer]) -> None:
629 + def tokenizer(self, tokenizer: AnyTokenizer | None) -> None:
630 self.processor.tokenizer = tokenizer
631
632 async def get_tokenizer(self) -> AnyTokenizer:
@@ -665,7 +665,7 @@ class AsyncLLM(EngineClient):
665 self.processor.clear_mm_cache()
666 await self.engine_core.reset_mm_cache_async()
667
668 - async def reset_prefix_cache(self, device: Optional[Device] = None) -> None:
668 + async def reset_prefix_cache(self, device: Device | None = None) -> None:
669 if device == Device.CPU:
670 raise ValueError("Not supported on CPU.")
671 await self.engine_core.reset_prefix_cache_async()
@@ -674,7 +674,7 @@ class AsyncLLM(EngineClient):
674 await self.reset_prefix_cache()
675 await self.engine_core.sleep_async(level)
676
677 - async def wake_up(self, tags: Optional[list[str]] = None) -> None:
677 + async def wake_up(self, tags: list[str] | None = None) -> None:
678 await self.engine_core.wake_up_async(tags)
679
680 async def is_sleeping(self) -> bool:
@@ -699,9 +699,9 @@ class AsyncLLM(EngineClient):
699 async def collective_rpc(
700 self,
701 method: str,
702 - timeout: Optional[float] = None,
702 + timeout: float | None = None,
703 args: tuple = (),
704 - kwargs: Optional[dict] = None,
704 + kwargs: dict | None = None,
705 ):
706 """
707 Perform a collective RPC call to the given path.
vllm/v1/engine/coordinator.py
+2 -3
@@ -4,7 +4,6 @@ import copy
4 import multiprocessing
5 import time
6 import weakref
7 -from typing import Optional
7
8 import msgspec.msgpack
9 import zmq
@@ -155,7 +154,7 @@ class DPCoordinatorProc:
154 stats_changed = False
155 last_stats_step = -1
156 last_stats_wave = -1
158 - last_step_counts: Optional[list[list[int]]] = None
157 + last_step_counts: list[list[int]] | None = None
158
159 with (
160 make_zmq_socket(
@@ -360,7 +359,7 @@ class DPCoordinatorProc:
359
360 @staticmethod
361 def _send_start_wave(
363 - socket: zmq.Socket, wave: int, exclude_engine_index: Optional[int]
362 + socket: zmq.Socket, wave: int, exclude_engine_index: int | None
363 ):
364 """Broadcast the START_DP_WAVE message to all the engines.
365 It includes the current wave number and index of engine which
vllm/v1/engine/core.py
+24 -24
@@ -7,12 +7,12 @@ import signal
7 import threading
8 import time
9 from collections import deque
10 -from collections.abc import Generator
10 +from collections.abc import Callable, Generator
11 from concurrent.futures import Future
12 from contextlib import ExitStack, contextmanager
13 from inspect import isclass, signature
14 from logging import DEBUG
15 -from typing import Any, Callable, Optional, TypeVar, Union
15 +from typing import Any, TypeVar
16
17 import msgspec
18 import zmq
@@ -83,7 +83,7 @@ class EngineCore:
83 vllm_config: VllmConfig,
84 executor_class: type[Executor],
85 log_stats: bool,
86 - executor_fail_callback: Optional[Callable] = None,
86 + executor_fail_callback: Callable | None = None,
87 ):
88 # plugins need to be loaded at the engine/scheduler level too
89 from vllm.plugins import load_general_plugins
@@ -171,14 +171,14 @@ class EngineCore:
171 # schedule and execute batches, and is required by pipeline parallelism
172 # to eliminate pipeline bubbles.
173 self.batch_queue_size = self.model_executor.max_concurrent_batches
174 - self.batch_queue: Optional[
175 - deque[tuple[Future[ModelRunnerOutput], SchedulerOutput]]
176 - ] = None
174 + self.batch_queue: (
175 + deque[tuple[Future[ModelRunnerOutput], SchedulerOutput]] | None
176 + ) = None
177 if self.batch_queue_size > 1:
178 logger.info("Batch queue is enabled with size %d", self.batch_queue_size)
179 self.batch_queue = deque(maxlen=self.batch_queue_size)
180
181 - self.request_block_hasher: Optional[Callable[[Request], list[BlockHash]]] = None
181 + self.request_block_hasher: Callable[[Request], list[BlockHash]] | None = None
182 if (
183 self.vllm_config.cache_config.enable_prefix_caching
184 or self.scheduler.get_kv_connector() is not None
@@ -337,7 +337,7 @@ class EngineCore:
337
338 def step_with_batch_queue(
339 self,
340 - ) -> tuple[Optional[dict[int, EngineCoreOutputs]], bool]:
340 + ) -> tuple[dict[int, EngineCoreOutputs] | None, bool]:
341 """Schedule and execute batches with the batch queue.
342 Note that if nothing to output in this step, None is returned.
343
@@ -424,7 +424,7 @@ class EngineCore:
424 def sleep(self, level: int = 1):
425 self.model_executor.sleep(level)
426
427 - def wake_up(self, tags: Optional[list[str]] = None):
427 + def wake_up(self, tags: list[str] | None = None):
428 self.model_executor.wake_up(tags)
429
430 def is_sleeping(self) -> bool:
@@ -448,8 +448,8 @@ class EngineCore:
448 def save_sharded_state(
449 self,
450 path: str,
451 - pattern: Optional[str] = None,
452 - max_size: Optional[int] = None,
451 + pattern: str | None = None,
452 + max_size: int | None = None,
453 ) -> None:
454 self.model_executor.save_sharded_state(
455 path=path, pattern=pattern, max_size=max_size
@@ -457,10 +457,10 @@ class EngineCore:
457
458 def collective_rpc(
459 self,
460 - method: Union[str, Callable[..., _R]],
461 - timeout: Optional[float] = None,
460 + method: str | Callable[..., _R],
461 + timeout: float | None = None,
462 args: tuple = (),
463 - kwargs: Optional[dict[str, Any]] = None,
463 + kwargs: dict[str, Any] | None = None,
464 ) -> list[_R]:
465 return self.model_executor.collective_rpc(method, timeout, args, kwargs)
466
@@ -509,11 +509,11 @@ class EngineCoreProc(EngineCore):
509 handshake_address: str,
510 executor_class: type[Executor],
511 log_stats: bool,
512 - client_handshake_address: Optional[str] = None,
512 + client_handshake_address: str | None = None,
513 engine_index: int = 0,
514 ):
515 self.input_queue = queue.Queue[tuple[EngineCoreRequestType, Any]]()
516 - self.output_queue = queue.Queue[Union[tuple[int, EngineCoreOutputs], bytes]]()
516 + self.output_queue = queue.Queue[tuple[int, EngineCoreOutputs] | bytes]()
517 executor_fail_callback = lambda: self.input_queue.put_nowait(
518 (EngineCoreRequestType.EXECUTOR_FAILED, b"")
519 )
@@ -606,7 +606,7 @@ class EngineCoreProc(EngineCore):
606 identity: bytes,
607 local_client: bool,
608 vllm_config: VllmConfig,
609 - client_handshake_address: Optional[str],
609 + client_handshake_address: str | None,
610 ) -> Generator[EngineZmqAddresses, None, None]:
611 """
612 Perform startup handshakes.
@@ -667,7 +667,7 @@ class EngineCoreProc(EngineCore):
667 local_client: bool,
668 headless: bool,
669 vllm_config: VllmConfig,
670 - parallel_config_to_update: Optional[ParallelConfig] = None,
670 + parallel_config_to_update: ParallelConfig | None = None,
671 ) -> Generator[EngineZmqAddresses, None, None]:
672 with make_zmq_socket(
673 ctx,
@@ -710,7 +710,7 @@ class EngineCoreProc(EngineCore):
710 handshake_socket: zmq.Socket,
711 local_client: bool,
712 headless: bool,
713 - parallel_config: Optional[ParallelConfig] = None,
713 + parallel_config: ParallelConfig | None = None,
714 ) -> EngineZmqAddresses:
715 # Send registration message.
716 handshake_socket.send(
@@ -765,7 +765,7 @@ class EngineCoreProc(EngineCore):
765 signal.signal(signal.SIGTERM, signal_handler)
766 signal.signal(signal.SIGINT, signal_handler)
767
768 - engine_core: Optional[EngineCoreProc] = None
768 + engine_core: EngineCoreProc | None = None
769 try:
770 parallel_config: ParallelConfig = kwargs["vllm_config"].parallel_config
771 if parallel_config.data_parallel_size > 1 or dp_rank > 0:
@@ -911,7 +911,7 @@ class EngineCoreProc(EngineCore):
911 def process_input_sockets(
912 self,
913 input_addresses: list[str],
914 - coord_input_address: Optional[str],
914 + coord_input_address: str | None,
915 identity: bytes,
916 ready_event: threading.Event,
917 ):
@@ -980,7 +980,7 @@ class EngineCoreProc(EngineCore):
980 def process_output_sockets(
981 self,
982 output_paths: list[str],
983 - coord_output_path: Optional[str],
983 + coord_output_path: str | None,
984 engine_index: int,
985 ):
986 """Output socket IO thread."""
@@ -1059,7 +1059,7 @@ class DPEngineCoreProc(EngineCoreProc):
1059 handshake_address: str,
1060 executor_class: type[Executor],
1061 log_stats: bool,
1062 - client_handshake_address: Optional[str] = None,
1062 + client_handshake_address: str | None = None,
1063 ):
1064 # Counts forward-passes of the model so that we can synchronize
1065 # finished with DP peers every N steps.
@@ -1332,7 +1332,7 @@ class DPEngineCoreActor(DPEngineCoreProc):
1332 identity: bytes,
1333 local_client: bool,
1334 vllm_config: VllmConfig,
1335 - client_handshake_address: Optional[str],
1335 + client_handshake_address: str | None,
1336 ):
1337 """
1338 For Ray, we don't need to actually perform handshake.
vllm/v1/engine/core_client.py
+50 -52
@@ -9,11 +9,11 @@ import uuid
9 import weakref
10 from abc import ABC, abstractmethod
11 from collections import defaultdict, deque
12 -from collections.abc import Awaitable, Sequence
12 +from collections.abc import Awaitable, Callable, Sequence
13 from concurrent.futures import Future
14 from dataclasses import dataclass
15 from threading import Thread
16 -from typing import Any, Callable, Optional, TypeVar, Union
16 +from typing import Any, TypeAlias, TypeVar
17
18 import msgspec.msgpack
19 import zmq
@@ -51,7 +51,7 @@ from vllm.v1.serial_utils import MsgpackDecoder, MsgpackEncoder, bytestr
51
52 logger = init_logger(__name__)
53
54 -AnyFuture = Union[asyncio.Future[Any], Future[Any]]
54 +AnyFuture: TypeAlias = asyncio.Future[Any] | Future[Any]
55
56 _R = TypeVar("_R") # Return type for collective_rpc
57
@@ -99,7 +99,7 @@ class EngineCoreClient(ABC):
99 vllm_config: VllmConfig,
100 executor_class: type[Executor],
101 log_stats: bool,
102 - client_addresses: Optional[dict[str, str]] = None,
102 + client_addresses: dict[str, str] | None = None,
103 client_count: int = 1,
104 client_index: int = 0,
105 ) -> "MPClient":
@@ -144,7 +144,7 @@ class EngineCoreClient(ABC):
144 def sleep(self, level: int = 1) -> None:
145 raise NotImplementedError
146
147 - def wake_up(self, tags: Optional[list[str]] = None) -> None:
147 + def wake_up(self, tags: list[str] | None = None) -> None:
148 raise NotImplementedError
149
150 def is_sleeping(self) -> bool:
@@ -172,16 +172,16 @@ class EngineCoreClient(ABC):
172 raise NotImplementedError
173
174 def save_sharded_state(
175 - self, path: str, pattern: Optional[str] = None, max_size: Optional[int] = None
175 + self, path: str, pattern: str | None = None, max_size: int | None = None
176 ) -> None:
177 raise NotImplementedError
178
179 def collective_rpc(
180 self,
181 - method: Union[str, Callable[..., _R]],
182 - timeout: Optional[float] = None,
181 + method: str | Callable[..., _R],
182 + timeout: float | None = None,
183 args: tuple = (),
184 - kwargs: Optional[dict[str, Any]] = None,
184 + kwargs: dict[str, Any] | None = None,
185 ) -> list[_R]:
186 raise NotImplementedError
187
@@ -214,7 +214,7 @@ class EngineCoreClient(ABC):
214 async def sleep_async(self, level: int = 1) -> None:
215 raise NotImplementedError
216
217 - async def wake_up_async(self, tags: Optional[list[str]] = None) -> None:
217 + async def wake_up_async(self, tags: list[str] | None = None) -> None:
218 raise NotImplementedError
219
220 async def is_sleeping_async(self) -> bool:
@@ -236,16 +236,16 @@ class EngineCoreClient(ABC):
236 raise NotImplementedError
237
238 async def save_sharded_state_async(
239 - self, path: str, pattern: Optional[str] = None, max_size: Optional[int] = None
239 + self, path: str, pattern: str | None = None, max_size: int | None = None
240 ) -> None:
241 raise NotImplementedError
242
243 async def collective_rpc_async(
244 self,
245 - method: Union[str, Callable[..., _R]],
246 - timeout: Optional[float] = None,
245 + method: str | Callable[..., _R],
246 + timeout: float | None = None,
247 args: tuple = (),
248 - kwargs: Optional[dict[str, Any]] = None,
248 + kwargs: dict[str, Any] | None = None,
249 ) -> list[_R]:
250 raise NotImplementedError
251
@@ -293,7 +293,7 @@ class InprocClient(EngineCoreClient):
293 def sleep(self, level: int = 1) -> None:
294 self.engine_core.sleep(level)
295
296 - def wake_up(self, tags: Optional[list[str]] = None) -> None:
296 + def wake_up(self, tags: list[str] | None = None) -> None:
297 self.engine_core.wake_up(tags)
298
299 def is_sleeping(self) -> bool:
@@ -315,16 +315,16 @@ class InprocClient(EngineCoreClient):
315 return self.engine_core.pin_lora(lora_id)
316
317 def save_sharded_state(
318 - self, path: str, pattern: Optional[str] = None, max_size: Optional[int] = None
318 + self, path: str, pattern: str | None = None, max_size: int | None = None
319 ) -> None:
320 self.engine_core.save_sharded_state(path, pattern, max_size)
321
322 def collective_rpc(
323 self,
324 - method: Union[str, Callable[..., _R]],
325 - timeout: Optional[float] = None,
324 + method: str | Callable[..., _R],
325 + timeout: float | None = None,
326 args: tuple = (),
327 - kwargs: Optional[dict[str, Any]] = None,
327 + kwargs: dict[str, Any] | None = None,
328 ) -> list[_R]:
329 return self.engine_core.collective_rpc(method, timeout, args, kwargs)
330
@@ -340,18 +340,16 @@ class BackgroundResources:
340 ctx: zmq.Context
341 # If CoreEngineProcManager, it manages local engines;
342 # if CoreEngineActorManager, it manages all engines.
343 - engine_manager: Optional[Union[CoreEngineProcManager, CoreEngineActorManager]] = (
344 - None
345 - )
346 - coordinator: Optional[DPCoordinator] = None
347 - output_socket: Optional[Union[zmq.Socket, zmq.asyncio.Socket]] = None
348 - input_socket: Optional[Union[zmq.Socket, zmq.asyncio.Socket]] = None
349 - first_req_send_socket: Optional[zmq.asyncio.Socket] = None
350 - first_req_rcv_socket: Optional[zmq.asyncio.Socket] = None
351 - stats_update_socket: Optional[zmq.asyncio.Socket] = None
352 - output_queue_task: Optional[asyncio.Task] = None
353 - stats_update_task: Optional[asyncio.Task] = None
354 - shutdown_path: Optional[str] = None
343 + engine_manager: CoreEngineProcManager | CoreEngineActorManager | None = None
344 + coordinator: DPCoordinator | None = None
345 + output_socket: zmq.Socket | zmq.asyncio.Socket | None = None
346 + input_socket: zmq.Socket | zmq.asyncio.Socket | None = None
347 + first_req_send_socket: zmq.asyncio.Socket | None = None
348 + first_req_rcv_socket: zmq.asyncio.Socket | None = None
349 + stats_update_socket: zmq.asyncio.Socket | None = None
350 + output_queue_task: asyncio.Task | None = None
351 + stats_update_task: asyncio.Task | None = None
352 + shutdown_path: str | None = None
353
354 # Set if any of the engines are dead. Here so that the output
355 # processing threads can access it without holding a ref to the client.
@@ -438,7 +436,7 @@ class MPClient(EngineCoreClient):
436 vllm_config: VllmConfig,
437 executor_class: type[Executor],
438 log_stats: bool,
441 - client_addresses: Optional[dict[str, str]] = None,
439 + client_addresses: dict[str, str] | None = None,
440 ):
441 self.vllm_config = vllm_config
442 # Serialization setup.
@@ -459,7 +457,7 @@ class MPClient(EngineCoreClient):
457 # State used for data parallel.
458 self.engines_running = False
459
462 - self.stats_update_address: Optional[str] = None
460 + self.stats_update_address: str | None = None
461 if client_addresses:
462 # Engines are managed externally to this client.
463 input_address = client_addresses["input_address"]
@@ -646,7 +644,7 @@ class SyncMPClient(MPClient):
644 )
645
646 self.is_dp = self.vllm_config.parallel_config.data_parallel_size > 1
649 - self.outputs_queue = queue.Queue[Union[EngineCoreOutputs, Exception]]()
647 + self.outputs_queue = queue.Queue[EngineCoreOutputs | Exception]()
648
649 # Ensure that the outputs socket processing thread does not have
650 # a ref to the client which prevents gc.
@@ -770,7 +768,7 @@ class SyncMPClient(MPClient):
768 def sleep(self, level: int = 1) -> None:
769 self.call_utility("sleep", level)
770
773 - def wake_up(self, tags: Optional[list[str]] = None) -> None:
771 + def wake_up(self, tags: list[str] | None = None) -> None:
772 self.call_utility("wake_up", tags)
773
774 def is_sleeping(self) -> bool:
@@ -781,15 +779,15 @@ class SyncMPClient(MPClient):
779
780 def collective_rpc(
781 self,
784 - method: Union[str, Callable[..., _R]],
785 - timeout: Optional[float] = None,
782 + method: str | Callable[..., _R],
783 + timeout: float | None = None,
784 args: tuple = (),
787 - kwargs: Optional[dict[str, Any]] = None,
785 + kwargs: dict[str, Any] | None = None,
786 ) -> list[_R]:
787 return self.call_utility("collective_rpc", method, timeout, args, kwargs)
788
789 def save_sharded_state(
792 - self, path: str, pattern: Optional[str] = None, max_size: Optional[int] = None
790 + self, path: str, pattern: str | None = None, max_size: int | None = None
791 ) -> None:
792 self.call_utility("save_sharded_state", path, pattern, max_size)
793
@@ -802,7 +800,7 @@ class AsyncMPClient(MPClient):
800 vllm_config: VllmConfig,
801 executor_class: type[Executor],
802 log_stats: bool,
805 - client_addresses: Optional[dict[str, str]] = None,
803 + client_addresses: dict[str, str] | None = None,
804 client_count: int = 1,
805 client_index: int = 0,
806 ):
@@ -816,7 +814,7 @@ class AsyncMPClient(MPClient):
814
815 self.client_count = client_count
816 self.client_index = client_index
819 - self.outputs_queue = asyncio.Queue[Union[EngineCoreOutputs, Exception]]()
817 + self.outputs_queue = asyncio.Queue[EngineCoreOutputs | Exception]()
818 try:
819 # If we are running in an asyncio event loop, start the queue task.
820 # Otherwise, it will be started lazily. If it is not started here,
@@ -837,9 +835,9 @@ class AsyncMPClient(MPClient):
835 decoder = self.decoder
836 utility_results = self.utility_results
837 outputs_queue = self.outputs_queue
840 - output_handler: Optional[
841 - Callable[[AsyncMPClient, EngineCoreOutputs], Awaitable[None]]
842 - ] = getattr(self.__class__, "process_engine_outputs", None)
838 + output_handler: (
839 + Callable[[AsyncMPClient, EngineCoreOutputs], Awaitable[None]] | None
840 + ) = getattr(self.__class__, "process_engine_outputs", None)
841 _self_ref = weakref.ref(self) if output_handler else None
842 output_socket = resources.output_socket
843 assert output_socket is not None
@@ -888,7 +886,7 @@ class AsyncMPClient(MPClient):
886 self,
887 request_type: EngineCoreRequestType,
888 request: Any,
891 - engine: Optional[EngineIdentity] = None,
889 + engine: EngineIdentity | None = None,
890 ) -> Awaitable[Any]:
891 if engine is None:
892 engine = self.core_engine
@@ -962,7 +960,7 @@ class AsyncMPClient(MPClient):
960 async def sleep_async(self, level: int = 1) -> None:
961 await self.call_utility_async("sleep", level)
962
965 - async def wake_up_async(self, tags: Optional[list[str]] = None) -> None:
963 + async def wake_up_async(self, tags: list[str] | None = None) -> None:
964 await self.call_utility_async("wake_up", tags)
965
966 async def is_sleeping_async(self) -> bool:
@@ -984,16 +982,16 @@ class AsyncMPClient(MPClient):
982 return await self.call_utility_async("pin_lora", lora_id)
983
984 async def save_sharded_state_async(
987 - self, path: str, pattern: Optional[str] = None, max_size: Optional[int] = None
985 + self, path: str, pattern: str | None = None, max_size: int | None = None
986 ) -> None:
987 await self.call_utility_async("save_sharded_state", path, pattern, max_size)
988
989 async def collective_rpc_async(
990 self,
993 - method: Union[str, Callable[..., _R]],
994 - timeout: Optional[float] = None,
991 + method: str | Callable[..., _R],
992 + timeout: float | None = None,
993 args: tuple = (),
996 - kwargs: Optional[dict[str, Any]] = None,
994 + kwargs: dict[str, Any] | None = None,
995 ) -> list[_R]:
996 return await self.call_utility_async(
997 "collective_rpc", method, timeout, args, kwargs
@@ -1009,7 +1007,7 @@ class DPAsyncMPClient(AsyncMPClient):
1007 vllm_config: VllmConfig,
1008 executor_class: type[Executor],
1009 log_stats: bool,
1012 - client_addresses: Optional[dict[str, str]] = None,
1010 + client_addresses: dict[str, str] | None = None,
1011 client_count: int = 1,
1012 client_index: int = 0,
1013 ):
@@ -1166,7 +1164,7 @@ class DPLBAsyncMPClient(DPAsyncMPClient):
1164 vllm_config: VllmConfig,
1165 executor_class: type[Executor],
1166 log_stats: bool,
1169 - client_addresses: Optional[dict[str, str]] = None,
1167 + client_addresses: dict[str, str] | None = None,
1168 client_count: int = 1,
1169 client_index: int = 0,
1170 ):
vllm/v1/engine/detokenizer.py
+5 -6
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from abc import ABC, abstractmethod
4 -from typing import Optional
4
5 import tokenizers
6 from packaging import version
@@ -36,7 +35,7 @@ class IncrementalDetokenizer:
35 def output_token_ids(self) -> list[int]:
36 return self.token_ids
37
39 - def update(self, new_token_ids: list[int], stop_terminated: bool) -> Optional[str]:
38 + def update(self, new_token_ids: list[int], stop_terminated: bool) -> str | None:
39 self.token_ids.extend(new_token_ids)
40 return None
41
@@ -46,7 +45,7 @@ class IncrementalDetokenizer:
45 @classmethod
46 def from_new_request(
47 cls,
49 - tokenizer: Optional[AnyTokenizer],
48 + tokenizer: AnyTokenizer | None,
49 request: EngineCoreRequest,
50 ) -> "IncrementalDetokenizer":
51 assert request.sampling_params is not None
@@ -85,7 +84,7 @@ class BaseIncrementalDetokenizer(IncrementalDetokenizer, ABC):
84 # Generation data
85 self.output_text = ""
86
88 - def update(self, new_token_ids: list[int], stop_terminated: bool) -> Optional[str]:
87 + def update(self, new_token_ids: list[int], stop_terminated: bool) -> str | None:
88 """
89 Update RequestState for the request_id by:
90 1) Detokenize the new token ids incrementally.
@@ -224,7 +223,7 @@ class FastIncrementalDetokenizer(BaseIncrementalDetokenizer):
223
224 return token or ""
225
227 - def _protected_step(self, next_token_id: int) -> Optional[str]:
226 + def _protected_step(self, next_token_id: int) -> str | None:
227 try:
228 token = self.stream.step(self.tokenizer, next_token_id)
229 except (OverflowError, TypeError):
@@ -312,7 +311,7 @@ def check_stop_strings(
311 new_char_count: int,
312 stop: list[str],
313 include_in_output: bool,
315 -) -> Optional[tuple[str, int]]:
314 +) -> tuple[str, int] | None:
315 """Check if any stop strings are matched and truncate sequence
316 output text accordingly.
317
vllm/v1/engine/llm_engine.py
+21 -21
@@ -2,9 +2,9 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import time
5 -from collections.abc import Mapping
5 +from collections.abc import Callable, Mapping
6 from copy import copy
7 -from typing import Any, Callable, Optional, Union
7 +from typing import Any
8
9 import torch.nn as nn
10 from typing_extensions import TypeVar
@@ -52,7 +52,7 @@ class LLMEngine:
52 executor_class: type[Executor],
53 log_stats: bool,
54 usage_context: UsageContext = UsageContext.ENGINE_CONTEXT,
55 - stat_loggers: Optional[list[StatLoggerFactory]] = None,
55 + stat_loggers: list[StatLoggerFactory] | None = None,
56 mm_registry: MultiModalRegistry = MULTIMODAL_REGISTRY,
57 use_cached_outputs: bool = False,
58 multiprocess_mode: bool = False,
@@ -126,7 +126,7 @@ class LLMEngine:
126 log_stats=self.log_stats,
127 )
128
129 - self.logger_manager: Optional[StatLoggerManager] = None
129 + self.logger_manager: StatLoggerManager | None = None
130 if self.log_stats:
131 self.logger_manager = StatLoggerManager(
132 vllm_config=vllm_config,
@@ -152,7 +152,7 @@ class LLMEngine:
152 cls,
153 vllm_config: VllmConfig,
154 usage_context: UsageContext = UsageContext.ENGINE_CONTEXT,
155 - stat_loggers: Optional[list[StatLoggerFactory]] = None,
155 + stat_loggers: list[StatLoggerFactory] | None = None,
156 disable_log_stats: bool = False,
157 ) -> "LLMEngine":
158 return cls(
@@ -169,7 +169,7 @@ class LLMEngine:
169 cls,
170 engine_args: EngineArgs,
171 usage_context: UsageContext = UsageContext.ENGINE_CONTEXT,
172 - stat_loggers: Optional[list[StatLoggerFactory]] = None,
172 + stat_loggers: list[StatLoggerFactory] | None = None,
173 enable_multiprocessing: bool = False,
174 ) -> "LLMEngine":
175 """Creates an LLM engine from the engine arguments."""
@@ -225,14 +225,14 @@ class LLMEngine:
225 def add_request(
226 self,
227 request_id: str,
228 - prompt: Union[EngineCoreRequest, PromptType],
229 - params: Union[SamplingParams, PoolingParams],
230 - arrival_time: Optional[float] = None,
231 - lora_request: Optional[LoRARequest] = None,
232 - tokenization_kwargs: Optional[dict[str, Any]] = None,
233 - trace_headers: Optional[Mapping[str, str]] = None,
228 + prompt: EngineCoreRequest | PromptType,
229 + params: SamplingParams | PoolingParams,
230 + arrival_time: float | None = None,
231 + lora_request: LoRARequest | None = None,
232 + tokenization_kwargs: dict[str, Any] | None = None,
233 + trace_headers: Mapping[str, str] | None = None,
234 priority: int = 0,
235 - prompt_text: Optional[str] = None,
235 + prompt_text: str | None = None,
236 ) -> None:
237 # Validate the request_id type.
238 if not isinstance(request_id, str):
@@ -283,7 +283,7 @@ class LLMEngine:
283 # Add the request to EngineCore.
284 self.engine_core.add_request(child_request)
285
286 - def step(self) -> Union[list[RequestOutput], list[PoolingRequestOutput]]:
286 + def step(self) -> list[RequestOutput] | list[PoolingRequestOutput]:
287 if self.should_execute_dummy_batch:
288 self.should_execute_dummy_batch = False
289 self.engine_core.execute_dummy_batch()
@@ -326,13 +326,13 @@ class LLMEngine:
326 self.processor.clear_mm_cache()
327 self.engine_core.reset_mm_cache()
328
329 - def reset_prefix_cache(self, device: Optional[Device] = None):
329 + def reset_prefix_cache(self, device: Device | None = None):
330 self.engine_core.reset_prefix_cache()
331
332 def sleep(self, level: int = 1):
333 self.engine_core.sleep(level)
334
335 - def wake_up(self, tags: Optional[list[str]] = None):
335 + def wake_up(self, tags: list[str] | None = None):
336 self.engine_core.wake_up(tags)
337
338 def is_sleeping(self) -> bool:
@@ -343,11 +343,11 @@ class LLMEngine:
343 return get_metrics_snapshot()
344
345 @property
346 - def tokenizer(self) -> Optional[AnyTokenizer]:
346 + def tokenizer(self) -> AnyTokenizer | None:
347 return self.processor.tokenizer
348
349 @tokenizer.setter
350 - def tokenizer(self, tokenizer: Optional[AnyTokenizer]) -> None:
350 + def tokenizer(self, tokenizer: AnyTokenizer | None) -> None:
351 self.processor.tokenizer = tokenizer
352
353 def get_tokenizer(self) -> AnyTokenizer:
@@ -390,10 +390,10 @@ class LLMEngine:
390
391 def collective_rpc(
392 self,
393 - method: Union[str, Callable[[WorkerBase], _R]],
394 - timeout: Optional[float] = None,
393 + method: str | Callable[[WorkerBase], _R],
394 + timeout: float | None = None,
395 args: tuple = (),
396 - kwargs: Optional[dict[str, Any]] = None,
396 + kwargs: dict[str, Any] | None = None,
397 ) -> list[_R]:
398 return self.engine_core.collective_rpc(method, timeout, args, kwargs)
399
vllm/v1/engine/logprobs.py
+9 -10
@@ -4,7 +4,6 @@
4 import itertools
5 from collections.abc import Iterable
6 from dataclasses import dataclass
7 -from typing import Optional
7
8 from vllm.logger import init_logger
9 from vllm.logprobs import Logprob, PromptLogprobs, SampleLogprobs
@@ -24,19 +23,19 @@ NONES = itertools.repeat(None)
23 class LogprobsProcessor:
24 # Tokenizer for this request,
25 # None if detokenization is disabled.
27 - tokenizer: Optional[AnyTokenizer]
26 + tokenizer: AnyTokenizer | None
27
28 # Logprobs for this request
30 - logprobs: Optional[SampleLogprobs]
31 - prompt_logprobs: Optional[PromptLogprobs]
32 - cumulative_logprob: Optional[float]
33 - num_logprobs: Optional[int]
34 - num_prompt_logprobs: Optional[int]
29 + logprobs: SampleLogprobs | None
30 + prompt_logprobs: PromptLogprobs | None
31 + cumulative_logprob: float | None
32 + num_logprobs: int | None
33 + num_prompt_logprobs: int | None
34
35 @classmethod
36 def from_new_request(
37 cls,
39 - tokenizer: Optional[AnyTokenizer],
38 + tokenizer: AnyTokenizer | None,
39 request: EngineCoreRequest,
40 ) -> "LogprobsProcessor":
41 assert request.sampling_params is not None
@@ -148,7 +147,7 @@ class LogprobsProcessor:
147 )
148 )
149
151 - def pop_prompt_logprobs(self) -> Optional[PromptLogprobs]:
150 + def pop_prompt_logprobs(self) -> PromptLogprobs | None:
151 """Pop and return all request prompt logprobs
152
153 The logprobs processor aggregates prompt chunk logprobs
@@ -171,7 +170,7 @@ class LogprobsProcessor:
170 def _make_logprob_dict(
171 logprobs: list[float],
172 logprob_token_ids: list[int],
174 - decoded_tokens: Iterable[Optional[str]],
173 + decoded_tokens: Iterable[str | None],
174 rank: int,
175 num_logprobs: int,
176 ) -> dict[int, Logprob]:
vllm/v1/engine/output_processor.py
+43 -47
@@ -4,7 +4,7 @@
4 import asyncio
5 from collections.abc import Iterable
6 from dataclasses import dataclass
7 -from typing import Any, Optional, Union, cast
7 +from typing import Any, cast
8
9 import torch
10
@@ -36,14 +36,10 @@ class RequestOutputCollector:
36
37 def __init__(self, output_kind: RequestOutputKind):
38 self.aggregate = output_kind == RequestOutputKind.DELTA
39 - self.output: Optional[Union[RequestOutput, PoolingRequestOutput, Exception]] = (
40 - None
41 - )
39 + self.output: RequestOutput | PoolingRequestOutput | Exception | None = None
40 self.ready = asyncio.Event()
41
44 - def put(
45 - self, output: Union[RequestOutput, PoolingRequestOutput, Exception]
46 - ) -> None:
42 + def put(self, output: RequestOutput | PoolingRequestOutput | Exception) -> None:
43 """Non-blocking put operation."""
44 if self.output is None or isinstance(output, Exception):
45 self.output = output
@@ -53,7 +49,7 @@ class RequestOutputCollector:
49 # (if n > 1) do not override each other.
50 self.output.add(output, aggregate=self.aggregate)
51
56 - async def get(self) -> Union[RequestOutput, PoolingRequestOutput]:
52 + async def get(self) -> RequestOutput | PoolingRequestOutput:
53 """Get operation blocks on put event."""
54 while (output := self.output) is None:
55 await self.ready.wait()
@@ -63,7 +59,7 @@ class RequestOutputCollector:
59 raise output
60 return output
61
66 - def get_nowait(self) -> Optional[Union[RequestOutput, PoolingRequestOutput]]:
62 + def get_nowait(self) -> RequestOutput | PoolingRequestOutput | None:
63 """Non-blocking get operation."""
64 output = self.output
65 if output is not None:
@@ -76,7 +72,7 @@ class RequestOutputCollector:
72
73 @dataclass
74 class OutputProcessorOutput:
79 - request_outputs: list[Union[RequestOutput, PoolingRequestOutput]]
75 + request_outputs: list[RequestOutput | PoolingRequestOutput]
76 reqs_to_abort: list[str]
77
78
@@ -84,22 +80,22 @@ class RequestState:
80 def __init__(
81 self,
82 request_id: str,
87 - parent_req: Optional[ParentRequest],
83 + parent_req: ParentRequest | None,
84 request_index: int,
89 - lora_name: Optional[str],
85 + lora_name: str | None,
86 output_kind: RequestOutputKind,
91 - prompt: Optional[str],
92 - prompt_token_ids: Optional[list[int]],
93 - prompt_embeds: Optional[torch.Tensor],
94 - logprobs_processor: Optional[LogprobsProcessor],
95 - detokenizer: Optional[IncrementalDetokenizer],
96 - max_tokens_param: Optional[int],
87 + prompt: str | None,
88 + prompt_token_ids: list[int] | None,
89 + prompt_embeds: torch.Tensor | None,
90 + logprobs_processor: LogprobsProcessor | None,
91 + detokenizer: IncrementalDetokenizer | None,
92 + max_tokens_param: int | None,
93 arrival_time: float,
98 - queue: Optional[RequestOutputCollector],
94 + queue: RequestOutputCollector | None,
95 log_stats: bool,
100 - top_p: Optional[float] = None,
101 - n: Optional[int] = None,
102 - temperature: Optional[float] = None,
96 + top_p: float | None = None,
97 + n: int | None = None,
98 + temperature: float | None = None,
99 ):
100 self.request_id = request_id
101 self.parent_req = parent_req
@@ -129,10 +125,10 @@ class RequestState:
125 cls,
126 tokenizer: AnyTokenizer,
127 request: EngineCoreRequest,
132 - prompt: Optional[str],
133 - parent_req: Optional[ParentRequest],
128 + prompt: str | None,
129 + parent_req: ParentRequest | None,
130 request_index: int,
135 - queue: Optional[RequestOutputCollector],
131 + queue: RequestOutputCollector | None,
132 log_stats: bool,
133 ) -> "RequestState":
134 if sampling_params := request.sampling_params:
@@ -186,11 +182,11 @@ class RequestState:
182 def make_request_output(
183 self,
184 new_token_ids: list[int],
189 - pooling_output: Optional[torch.Tensor],
190 - finish_reason: Optional[FinishReason],
191 - stop_reason: Union[int, str, None],
192 - kv_transfer_params: Optional[dict[str, Any]] = None,
193 - ) -> Optional[Union[RequestOutput, PoolingRequestOutput]]:
185 + pooling_output: torch.Tensor | None,
186 + finish_reason: FinishReason | None,
187 + stop_reason: int | str | None,
188 + kv_transfer_params: dict[str, Any] | None = None,
189 + ) -> RequestOutput | PoolingRequestOutput | None:
190 finished = finish_reason is not None
191 final_only = self.output_kind == RequestOutputKind.FINAL_ONLY
192
@@ -222,10 +218,10 @@ class RequestState:
218 def _new_request_output(
219 self,
220 request_id: str,
225 - outputs: Union[list[CompletionOutput], list[PoolingOutput]],
221 + outputs: list[CompletionOutput] | list[PoolingOutput],
222 finished: bool,
227 - kv_transfer_params: Optional[dict[str, Any]] = None,
228 - ) -> Union[RequestOutput, PoolingRequestOutput]:
223 + kv_transfer_params: dict[str, Any] | None = None,
224 + ) -> RequestOutput | PoolingRequestOutput:
225 first_output = outputs[0]
226 if isinstance(first_output, PoolingOutput):
227 assert len(outputs) == 1
@@ -264,8 +260,8 @@ class RequestState:
260 def _new_completion_output(
261 self,
262 token_ids: list[int],
267 - finish_reason: Optional[FinishReason],
268 - stop_reason: Union[int, str, None],
263 + finish_reason: FinishReason | None,
264 + stop_reason: int | str | None,
265 ) -> CompletionOutput:
266 assert self.detokenizer is not None
267 assert self.logprobs_processor is not None
@@ -308,7 +304,7 @@ class OutputProcessor:
304 self.request_states: dict[str, RequestState] = {}
305 self.parent_requests: dict[str, ParentRequest] = {}
306 self.lora_states = LoRARequestStates()
311 - self.tracer: Optional[Tracer] = None
307 + self.tracer: Tracer | None = None
308
309 def get_num_unfinished_requests(self):
310 return len(self.request_states)
@@ -360,10 +356,10 @@ class OutputProcessor:
356 def add_request(
357 self,
358 request: EngineCoreRequest,
363 - prompt: Optional[str],
364 - parent_req: Optional[ParentRequest] = None,
359 + prompt: str | None,
360 + parent_req: ParentRequest | None = None,
361 request_index: int = 0,
366 - queue: Optional[RequestOutputCollector] = None,
362 + queue: RequestOutputCollector | None = None,
363 ) -> None:
364 request_id = request.request_id
365 if request_id in self.request_states:
@@ -386,8 +382,8 @@ class OutputProcessor:
382 def process_outputs(
383 self,
384 engine_core_outputs: list[EngineCoreOutput],
389 - engine_core_timestamp: Optional[float] = None,
390 - iteration_stats: Optional[IterationStats] = None,
385 + engine_core_timestamp: float | None = None,
386 + iteration_stats: IterationStats | None = None,
387 ) -> OutputProcessorOutput:
388 """
389 Process the EngineCoreOutputs:
@@ -411,7 +407,7 @@ class OutputProcessor:
407 within the loop below.
408 """
409
414 - request_outputs: Union[list[RequestOutput], list[PoolingRequestOutput]] = []
410 + request_outputs: list[RequestOutput] | list[PoolingRequestOutput] = []
411 reqs_to_abort: list[str] = []
412 for engine_core_output in engine_core_outputs:
413 req_id = engine_core_output.request_id
@@ -492,7 +488,7 @@ class OutputProcessor:
488 self,
489 engine_core_output: EngineCoreOutput,
490 req_state: RequestState,
495 - iteration_stats: Optional[IterationStats],
491 + iteration_stats: IterationStats | None,
492 ) -> None:
493 assert req_state.stats is not None
494 assert iteration_stats is not None
@@ -555,8 +551,8 @@ class OutputProcessor:
551 self,
552 req_state: RequestState,
553 engine_core_output: EngineCoreOutput,
558 - engine_core_timestamp: Optional[float],
559 - iteration_stats: Optional[IterationStats],
554 + engine_core_timestamp: float | None,
555 + iteration_stats: IterationStats | None,
556 ):
557 if iteration_stats is None:
558 return
@@ -577,8 +573,8 @@ class OutputProcessor:
573 def _update_stats_from_finished(
574 self,
575 req_state: RequestState,
580 - finish_reason: Optional[FinishReason],
581 - iteration_stats: Optional[IterationStats],
576 + finish_reason: FinishReason | None,
577 + iteration_stats: IterationStats | None,
578 ):
579 if iteration_stats is None:
580 return
vllm/v1/engine/parallel_sampling.py
+1 -1
@@ -29,7 +29,7 @@ class ParentRequest:
29 max_num_generation_tokens: int
30
31 # To efficiently obtain child sampling params
32 - cached_child_sampling_params: Optional[SamplingParams]
32 + cached_child_sampling_params: SamplingParams | None
33
34 def __init__(self, request_id: str, sampling_params: SamplingParams) -> None:
35 self.request_id = request_id
vllm/v1/engine/processor.py
+17 -17
@@ -3,7 +3,7 @@
3
4 import time
5 from collections.abc import Mapping
6 -from typing import Any, Literal, Optional, Union
6 +from typing import Any, Literal
7
8 from vllm.config import VllmConfig
9 from vllm.inputs import ProcessorInputs, PromptType, SingletonInputs
@@ -38,7 +38,7 @@ class Processor:
38 def __init__(
39 self,
40 vllm_config: VllmConfig,
41 - tokenizer: Optional[AnyTokenizer],
41 + tokenizer: AnyTokenizer | None,
42 mm_registry: MultiModalRegistry = MULTIMODAL_REGISTRY,
43 ) -> None:
44 self.vllm_config = vllm_config
@@ -60,11 +60,11 @@ class Processor:
60 )
61
62 @property
63 - def tokenizer(self) -> Optional[AnyTokenizer]:
63 + def tokenizer(self) -> AnyTokenizer | None:
64 return self.input_preprocessor.tokenizer
65
66 @tokenizer.setter
67 - def tokenizer(self, tokenizer: Optional[AnyTokenizer]) -> None:
67 + def tokenizer(self, tokenizer: AnyTokenizer | None) -> None:
68 self.input_preprocessor.tokenizer = tokenizer
69
70 def _validate_logprobs(
@@ -152,7 +152,7 @@ class Processor:
152
153 def _validate_params(
154 self,
155 - params: Union[SamplingParams, PoolingParams],
155 + params: SamplingParams | PoolingParams,
156 ):
157 """
158 Validate supported SamplingParam.
@@ -174,7 +174,7 @@ class Processor:
174 auto-hashed downstream.
175 """
176
177 - def _validate_single_prompt(single_prompt: Union[dict, str]) -> None:
177 + def _validate_single_prompt(single_prompt: dict | str) -> None:
178 if not isinstance(single_prompt, dict):
179 return
180 mm_data = single_prompt.get("multi_modal_data")
@@ -214,7 +214,7 @@ class Processor:
214 else:
215 _validate_single_prompt(prompt) # type: ignore[arg-type]
216
217 - def _validate_lora(self, lora_request: Optional[LoRARequest]) -> None:
217 + def _validate_lora(self, lora_request: LoRARequest | None) -> None:
218 if lora_request is None:
219 return
220
@@ -309,7 +309,7 @@ class Processor:
309 self,
310 request_id: str,
311 prompt: PromptType,
312 - ) -> Optional[MultiModalUUIDDict]:
312 + ) -> MultiModalUUIDDict | None:
313 """Build per-item multimodal hash overrides when enabled. In this case,
314 multimodal data items are identified by their request id, modality and
315 index rather than their content.
@@ -342,13 +342,13 @@ class Processor:
342 self,
343 request_id: str,
344 prompt: PromptType,
345 - params: Union[SamplingParams, PoolingParams],
346 - arrival_time: Optional[float] = None,
347 - lora_request: Optional[LoRARequest] = None,
348 - tokenization_kwargs: Optional[dict[str, Any]] = None,
349 - trace_headers: Optional[Mapping[str, str]] = None,
345 + params: SamplingParams | PoolingParams,
346 + arrival_time: float | None = None,
347 + lora_request: LoRARequest | None = None,
348 + tokenization_kwargs: dict[str, Any] | None = None,
349 + trace_headers: Mapping[str, str] | None = None,
350 priority: int = 0,
351 - data_parallel_rank: Optional[int] = None,
351 + data_parallel_rank: int | None = None,
352 ) -> EngineCoreRequest:
353 self._validate_lora(lora_request)
354 self._validate_params(params)
@@ -445,7 +445,7 @@ class Processor:
445 pooling_params = params.clone()
446
447 # Multimodal related.
448 - mm_features: Optional[list[MultiModalFeatureSpec]] = None
448 + mm_features: list[MultiModalFeatureSpec] | None = None
449
450 if decoder_inputs["type"] == "multimodal":
451 decoder_mm_inputs = decoder_inputs["mm_kwargs"]
@@ -485,7 +485,7 @@ class Processor:
485 )
486
487 def _validate_model_inputs(
488 - self, encoder_inputs: Optional[SingletonInputs], decoder_inputs: SingletonInputs
488 + self, encoder_inputs: SingletonInputs | None, decoder_inputs: SingletonInputs
489 ):
490 if encoder_inputs is not None:
491 self._validate_model_input(encoder_inputs, prompt_type="encoder")
@@ -574,7 +574,7 @@ class Processor:
574 # check that chunked prefill does not truncate them
575 # max_batch_len = self.scheduler_config.max_num_batched_tokens
576
577 - def stat_mm_cache(self) -> Optional[MultiModalCacheStats]:
577 + def stat_mm_cache(self) -> MultiModalCacheStats | None:
578 return self.input_preprocessor.stat_mm_cache()
579
580 def clear_mm_cache(self) -> None:
vllm/v1/engine/utils.py
+14 -14
@@ -4,12 +4,12 @@
4 import contextlib
5 import os
6 import weakref
7 -from collections.abc import Iterator
7 +from collections.abc import Callable, Iterator
8 from dataclasses import dataclass
9 from enum import Enum, auto
10 from multiprocessing import Process, connection
11 from multiprocessing.process import BaseProcess
12 -from typing import TYPE_CHECKING, Callable, Optional, Union
12 +from typing import TYPE_CHECKING
13 from unittest.mock import patch
14
15 import msgspec
@@ -56,13 +56,13 @@ class EngineZmqAddresses:
56 # ZMQ output socket addresses for each front-end client (responses)
57 outputs: list[str]
58 # ZMQ input socket address of DP coordinator if applicable
59 - coordinator_input: Optional[str] = None
59 + coordinator_input: str | None = None
60 # ZMQ output socket address of DP coordinator if applicable
61 - coordinator_output: Optional[str] = None
61 + coordinator_output: str | None = None
62 # ZMQ socket for front-end to connect to DP coordinator.
63 # Not used by engine, just relayed to front-end in handshake response.
64 # Only required for external DP LB case.
65 - frontend_stats_publish_address: Optional[str] = None
65 + frontend_stats_publish_address: str | None = None
66
67
68 @dataclass
@@ -73,8 +73,8 @@ class EngineHandshakeMetadata:
73 """
74
75 addresses: EngineZmqAddresses
76 - parallel_config: dict[str, Union[int, str, list[int]]]
77 - parallel_config_hash: Optional[str] = None
76 + parallel_config: dict[str, int | str | list[int]]
77 + parallel_config_hash: str | None = None
78
79
80 class CoreEngineProcManager:
@@ -94,7 +94,7 @@ class CoreEngineProcManager:
94 handshake_address: str,
95 executor_class: type[Executor],
96 log_stats: bool,
97 - client_handshake_address: Optional[str] = None,
97 + client_handshake_address: str | None = None,
98 ):
99 context = get_mp_context()
100 common_kwargs = {
@@ -221,8 +221,8 @@ class CoreEngineActorManager:
221 addresses: EngineZmqAddresses,
222 executor_class: type[Executor],
223 log_stats: bool,
224 - placement_groups: Optional[list["PlacementGroup"]] = None,
225 - local_dp_ranks: Optional[list[int]] = None,
224 + placement_groups: list["PlacementGroup"] | None = None,
225 + local_dp_ranks: list[int] | None = None,
226 ):
227 import copy
228
@@ -675,8 +675,8 @@ def launch_core_engines(
675 num_api_servers: int = 1,
676 ) -> Iterator[
677 tuple[
678 - Optional[Union[CoreEngineProcManager, CoreEngineActorManager]],
679 - Optional[DPCoordinator],
678 + CoreEngineProcManager | CoreEngineActorManager | None,
679 + DPCoordinator | None,
680 EngineZmqAddresses,
681 ]
682 ]:
@@ -829,8 +829,8 @@ def wait_for_engine_startup(
829 core_engines: list[CoreEngine],
830 parallel_config: ParallelConfig,
831 cache_config: CacheConfig,
832 - proc_manager: Optional[CoreEngineProcManager],
833 - coord_process: Optional[Process],
832 + proc_manager: CoreEngineProcManager | None,
833 + coord_process: Process | None,
834 ):
835 # Wait for engine core process(es) to send ready messages.
836 local_count = parallel_config.data_parallel_size_local
vllm/v1/executor/abstract.py
+7 -6
@@ -1,8 +1,9 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 +from collections.abc import Callable
5 from concurrent.futures import Future
5 -from typing import Any, Callable, Optional, Union
6 +from typing import Any
7
8 import torch
9 import torch.distributed as dist
@@ -91,10 +92,10 @@ class Executor(ExecutorBase):
92
93 def collective_rpc(
94 self,
94 - method: Union[str, Callable],
95 - timeout: Optional[float] = None,
95 + method: str | Callable,
96 + timeout: float | None = None,
97 args: tuple = (),
97 - kwargs: Optional[dict] = None,
98 + kwargs: dict | None = None,
99 non_block: bool = False,
100 ) -> list[Any]:
101 raise NotImplementedError
@@ -103,7 +104,7 @@ class Executor(ExecutorBase):
104 self,
105 scheduler_output: SchedulerOutput,
106 non_block: bool = False,
106 - ) -> Union[ModelRunnerOutput, Future[ModelRunnerOutput]]:
107 + ) -> ModelRunnerOutput | Future[ModelRunnerOutput]:
108 output = self.collective_rpc(
109 "execute_model", args=(scheduler_output,), non_block=non_block
110 )
@@ -112,7 +113,7 @@ class Executor(ExecutorBase):
113 def execute_dummy_batch(self) -> None:
114 self.collective_rpc("execute_dummy_batch")
115
115 - def take_draft_token_ids(self) -> Optional[DraftTokenIds]:
116 + def take_draft_token_ids(self) -> DraftTokenIds | None:
117 output = self.collective_rpc("take_draft_token_ids")
118 return output[0]
119
vllm/v1/executor/multiproc_executor.py
+16 -15
@@ -9,6 +9,7 @@ import threading
9 import time
10 import traceback
11 import weakref
12 +from collections.abc import Callable
13 from concurrent.futures import Future, ThreadPoolExecutor
14 from dataclasses import dataclass
15 from enum import Enum, auto
@@ -17,7 +18,7 @@ from multiprocessing.connection import Connection
18 from multiprocessing.process import BaseProcess
19 from multiprocessing.synchronize import Lock as LockType
20 from threading import Thread
20 -from typing import Any, Callable, Optional, Union, cast
21 +from typing import Any, cast
22
23 import cloudpickle
24 import torch
@@ -59,8 +60,8 @@ class MultiprocExecutor(Executor):
60 self._finalizer = weakref.finalize(self, self.shutdown)
61 self.is_failed = False
62 self.shutdown_event = threading.Event()
62 - self.failure_callback: Optional[FailureCallback] = None
63 - self.io_thread_pool: Optional[ThreadPoolExecutor] = None
63 + self.failure_callback: FailureCallback | None = None
64 + self.io_thread_pool: ThreadPoolExecutor | None = None
65
66 self.world_size = self.parallel_config.world_size
67 tensor_parallel_size = self.parallel_config.tensor_parallel_size
@@ -179,7 +180,7 @@ class MultiprocExecutor(Executor):
180 self,
181 scheduler_output: SchedulerOutput,
182 non_block: bool = False,
182 - ) -> Union[ModelRunnerOutput, Future[ModelRunnerOutput]]:
183 + ) -> ModelRunnerOutput | Future[ModelRunnerOutput]:
184 if not self.has_connector:
185 # get output only from a single worker (output_rank)
186 (output,) = self.collective_rpc(
@@ -207,7 +208,7 @@ class MultiprocExecutor(Executor):
208 def execute_dummy_batch(self) -> None:
209 self.collective_rpc("execute_dummy_batch", unique_reply_rank=self.output_rank)
210
210 - def take_draft_token_ids(self) -> Optional[DraftTokenIds]:
211 + def take_draft_token_ids(self) -> DraftTokenIds | None:
212 # OPTIMIZATION: Get output only from a single worker (output_rank)
213 outputs = self.collective_rpc(
214 "take_draft_token_ids", unique_reply_rank=self.output_rank
@@ -216,12 +217,12 @@ class MultiprocExecutor(Executor):
217
218 def collective_rpc(
219 self,
219 - method: Union[str, Callable],
220 - timeout: Optional[float] = None,
220 + method: str | Callable,
221 + timeout: float | None = None,
222 args: tuple = (),
222 - kwargs: Optional[dict] = None,
223 + kwargs: dict | None = None,
224 non_block: bool = False,
224 - unique_reply_rank: Optional[int] = None,
225 + unique_reply_rank: int | None = None,
226 ) -> list[Any]:
227 if self.is_failed:
228 raise RuntimeError("Executor failed.")
@@ -252,8 +253,8 @@ class MultiprocExecutor(Executor):
253
254 def get_response(
255 w: WorkerProcHandle,
255 - dequeue_timeout: Optional[float] = None,
256 - cancel_event: Optional[threading.Event] = None,
256 + dequeue_timeout: float | None = None,
257 + cancel_event: threading.Event | None = None,
258 ):
259 status, result = w.worker_response_mq.dequeue(
260 timeout=dequeue_timeout, cancel=cancel_event
@@ -370,7 +371,7 @@ class UnreadyWorkerProcHandle:
371 proc: BaseProcess
372 rank: int
373 ready_pipe: Connection
373 - death_writer: Optional[Connection] = None
374 + death_writer: Connection | None = None
375
376
377 @dataclass
@@ -378,7 +379,7 @@ class WorkerProcHandle:
379 proc: BaseProcess
380 rank: int
381 worker_response_mq: MessageQueue # The worker process writes to this MQ
381 - death_writer: Optional[Connection] = None
382 + death_writer: Connection | None = None
383
384 @classmethod
385 def from_unready_handle(
@@ -505,7 +506,7 @@ class WorkerProc:
506 )
507
508 pipes = {handle.ready_pipe: handle for handle in unready_proc_handles}
508 - ready_proc_handles: list[Optional[WorkerProcHandle]] = [None] * len(
509 + ready_proc_handles: list[WorkerProcHandle | None] = [None] * len(
510 unready_proc_handles
511 )
512 while pipes:
@@ -674,7 +675,7 @@ class WorkerProc:
675 output = self.async_output_queue.get()
676 self.enqueue_output(output)
677
677 - def worker_busy_loop(self, cancel: Optional[threading.Event] = None):
678 + def worker_busy_loop(self, cancel: threading.Event | None = None):
679 """Main busy loop for Multiprocessing Workers"""
680 while True:
681 method, args, kwargs, output_rank = self.rpc_broadcast_mq.dequeue(
vllm/v1/executor/ray_distributed_executor.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from concurrent.futures import Future
5 -from typing import Optional, Union
5
6 from vllm.distributed.kv_transfer.kv_connector.utils import KVOutputAggregator
7 from vllm.executor.ray_distributed_executor import ( # noqa
@@ -26,7 +25,7 @@ class FutureWrapper(Future):
25 the result() call. If not only the first worker's output is returned.
26 """
27
29 - def __init__(self, refs, aggregator: Optional[KVOutputAggregator] = None):
28 + def __init__(self, refs, aggregator: KVOutputAggregator | None = None):
29 super().__init__()
30 self.refs = refs
31 self.aggregator = aggregator
@@ -66,7 +65,7 @@ class RayDistributedExecutor(RayDistributedExecutorV0, Executor):
65 self,
66 scheduler_output: SchedulerOutput,
67 non_block: bool = False,
69 - ) -> Union[ModelRunnerOutput, Future[ModelRunnerOutput]]:
68 + ) -> ModelRunnerOutput | Future[ModelRunnerOutput]:
69 """Execute the model on the Ray workers.
70
71 Args:
vllm/v1/kv_cache_interface.py
+6 -7
@@ -4,7 +4,6 @@
4 import copy
5 from dataclasses import dataclass, fields
6 from math import prod
7 -from typing import Optional
7
8 import torch
9 from typing_extensions import Self
@@ -74,8 +73,8 @@ class AttentionSpec(KVCacheSpec):
73
74 @dataclass(frozen=True)
75 class FullAttentionSpec(AttentionSpec):
77 - sliding_window: Optional[int] = None
78 - attention_chunk_size: Optional[int] = None
76 + sliding_window: int | None = None
77 + attention_chunk_size: int | None = None
78 """
79 When hybrid allocator is disabled and the model contains both full
80 attention layers and sliding window attention layers, sliding
@@ -96,7 +95,7 @@ class FullAttentionSpec(AttentionSpec):
95 return cdiv(max_model_len, self.block_size) * self.page_size_bytes
96
97 @classmethod
99 - def merge_window_sizes(cls, window_sizes: set[int]) -> Optional[int]:
98 + def merge_window_sizes(cls, window_sizes: set[int]) -> int | None:
99 if len(window_sizes) == 0:
100 return None
101 elif len(window_sizes) == 1:
@@ -154,7 +153,7 @@ class FullAttentionSpec(AttentionSpec):
153 @dataclass(frozen=True)
154 class MLAAttentionSpec(FullAttentionSpec):
155 # TODO(Lucas/Chen): less hacky way to do this
157 - cache_dtype_str: Optional[str] = None
156 + cache_dtype_str: str | None = None
157
158 @property
159 def page_size_bytes(self) -> int:
@@ -237,7 +236,7 @@ class SlidingWindowSpec(AttentionSpec):
236 class MambaSpec(KVCacheSpec):
237 shapes: tuple[tuple[int, ...], ...]
238 dtypes: tuple[torch.dtype]
240 - page_size_padded: Optional[int] = None
239 + page_size_padded: int | None = None
240 mamba_type: str = "mamba2"
241 num_speculative_blocks: int = 0
242
@@ -342,7 +341,7 @@ class UniformTypeKVCacheSpecs(KVCacheSpec):
341 )
342
343 @classmethod
345 - def from_specs(cls, kv_cache_specs: dict[str, KVCacheSpec]) -> Optional[Self]:
344 + def from_specs(cls, kv_cache_specs: dict[str, KVCacheSpec]) -> Self | None:
345 """
346 Return a SameTypeKVCacheSpecs object if all layers have the same type
347 of KV cache spec. Return None if not.
vllm/v1/kv_offload/abstract.py
+1 -2
@@ -30,7 +30,6 @@ The class provides the following primitives:
30 from abc import ABC, abstractmethod
31 from collections.abc import Iterable
32 from dataclasses import dataclass
33 -from typing import Optional
33
34 from vllm.v1.core.kv_cache_utils import BlockHash
35
@@ -122,7 +121,7 @@ class OffloadingManager(ABC):
121 @abstractmethod
122 def prepare_store(
123 self, block_hashes: Iterable[BlockHash]
125 - ) -> Optional[PrepareStoreOutput]:
124 + ) -> PrepareStoreOutput | None:
125 """
126 Prepare the given blocks to be offloaded.
127 The given blocks will be protected from eviction until
vllm/v1/kv_offload/cpu.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterator
4 -from typing import Optional
4
5 import torch
6
@@ -29,10 +28,10 @@ class CPUOffloadingSpec(OffloadingSpec):
28 self.num_cpu_blocks: int = num_cpu_blocks
29
30 # scheduler-side
32 - self._manager: Optional[OffloadingManager] = None
31 + self._manager: OffloadingManager | None = None
32
33 # worker-side
35 - self._handler: Optional[OffloadingHandler] = None
34 + self._handler: OffloadingHandler | None = None
35
36 def get_manager(self) -> OffloadingManager:
37 if not self._manager:
vllm/v1/kv_offload/factory.py
+2 -1
@@ -1,7 +1,8 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import importlib
4 -from typing import TYPE_CHECKING, Callable
4 +from collections.abc import Callable
5 +from typing import TYPE_CHECKING
6
7 from vllm.logger import init_logger
8 from vllm.v1.kv_offload.spec import OffloadingSpec
vllm/v1/kv_offload/lru_manager.py
+2 -3
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections import OrderedDict
4 from collections.abc import Iterable
5 -from typing import Optional
5
6 from vllm.v1.core.kv_cache_utils import BlockHash
7 from vllm.v1.kv_offload.abstract import (
@@ -23,7 +22,7 @@ class LRUOffloadingManager(OffloadingManager):
22 self.backend: Backend = backend
23 # block_hash -> BlockStatus
24 self.blocks: OrderedDict[BlockHash, BlockStatus] = OrderedDict()
26 - self.events: Optional[list[OffloadingEvent]] = [] if enable_events else None
25 + self.events: list[OffloadingEvent] | None = [] if enable_events else None
26
27 def lookup(self, block_hashes: Iterable[BlockHash]) -> int:
28 hit_count = 0
@@ -57,7 +56,7 @@ class LRUOffloadingManager(OffloadingManager):
56
57 def prepare_store(
58 self, block_hashes: Iterable[BlockHash]
60 - ) -> Optional[PrepareStoreOutput]:
59 + ) -> PrepareStoreOutput | None:
60 # filter out blocks that are already stored
61 block_hashes_to_store = [
62 block_hash for block_hash in block_hashes if block_hash not in self.blocks
vllm/v1/metrics/loggers.py
+25 -30
@@ -4,9 +4,10 @@
4 import logging
5 import time
6 from abc import ABC, abstractmethod
7 -from typing import Callable, Optional, Union
7 +from collections.abc import Callable
8 +from typing import TypeAlias
9
9 -import prometheus_client
10 +from prometheus_client import Counter, Gauge, Histogram
11
12 from vllm.config import SupportsMetricsInfo, VllmConfig
13 from vllm.distributed.kv_transfer.kv_connector.v1.metrics import KVConnectorLogging
@@ -40,9 +41,9 @@ class StatLoggerBase(ABC):
41 @abstractmethod
42 def record(
43 self,
43 - scheduler_stats: Optional[SchedulerStats],
44 - iteration_stats: Optional[IterationStats],
45 - mm_cache_stats: Optional[MultiModalCacheStats] = None,
44 + scheduler_stats: SchedulerStats | None,
45 + iteration_stats: IterationStats | None,
46 + mm_cache_stats: MultiModalCacheStats | None = None,
47 engine_idx: int = 0,
48 ): ...
49
@@ -93,9 +94,9 @@ class LoggingStatLogger(StatLoggerBase):
94
95 def record(
96 self,
96 - scheduler_stats: Optional[SchedulerStats],
97 - iteration_stats: Optional[IterationStats],
98 - mm_cache_stats: Optional[MultiModalCacheStats] = None,
97 + scheduler_stats: SchedulerStats | None,
98 + iteration_stats: IterationStats | None,
99 + mm_cache_stats: MultiModalCacheStats | None = None,
100 engine_idx: int = 0,
101 ):
102 """Log Stats to standard output."""
@@ -178,13 +179,13 @@ class LoggingStatLogger(StatLoggerBase):
179
180
181 class PrometheusStatLogger(StatLoggerBase):
181 - _gauge_cls = prometheus_client.Gauge
182 - _counter_cls = prometheus_client.Counter
183 - _histogram_cls = prometheus_client.Histogram
182 + _gauge_cls = Gauge
183 + _counter_cls = Counter
184 + _histogram_cls = Histogram
185 _spec_decoding_cls = SpecDecodingProm
186
187 def __init__(
187 - self, vllm_config: VllmConfig, engine_indexes: Optional[list[int]] = None
188 + self, vllm_config: VllmConfig, engine_indexes: list[int] | None = None
189 ):
190 if engine_indexes is None:
191 engine_indexes = [0]
@@ -368,9 +369,7 @@ class PrometheusStatLogger(StatLoggerBase):
369 counter_generation_tokens, engine_indexes, model_name
370 )
371
371 - self.counter_request_success: dict[
372 - FinishReason, dict[int, prometheus_client.Counter]
373 - ] = {}
372 + self.counter_request_success: dict[FinishReason, dict[int, Counter]] = {}
373 counter_request_success_base = self._counter_cls(
374 name="vllm:request_success",
375 documentation="Count of successfully processed requests.",
@@ -660,7 +659,7 @@ class PrometheusStatLogger(StatLoggerBase):
659
660 # TODO: This metric might be incorrect in case of using multiple
661 # api_server counts which uses prometheus mp.
663 - self.gauge_lora_info: Optional[prometheus_client.Gauge] = None
662 + self.gauge_lora_info: Gauge | None = None
663 if vllm_config.lora_config is not None:
664 if len(self.engine_indexes) > 1:
665 raise NotImplementedError("LoRA in DP mode is not supported yet.")
@@ -705,9 +704,9 @@ class PrometheusStatLogger(StatLoggerBase):
704
705 def record(
706 self,
708 - scheduler_stats: Optional[SchedulerStats],
709 - iteration_stats: Optional[IterationStats],
710 - mm_cache_stats: Optional[MultiModalCacheStats] = None,
707 + scheduler_stats: SchedulerStats | None,
708 + iteration_stats: IterationStats | None,
709 + mm_cache_stats: MultiModalCacheStats | None = None,
710 engine_idx: int = 0,
711 ):
712 """Log to prometheus."""
@@ -826,11 +825,7 @@ class PrometheusStatLogger(StatLoggerBase):
825 self.log_metrics_info("cache_config", self.vllm_config.cache_config)
826
827
829 -PromMetric = Union[
830 - prometheus_client.Gauge,
831 - prometheus_client.Counter,
832 - prometheus_client.Histogram,
833 -]
828 +PromMetric: TypeAlias = Gauge | Counter | Histogram
829
830
831 def make_per_engine(
@@ -882,8 +877,8 @@ class StatLoggerManager:
877 def __init__(
878 self,
879 vllm_config: VllmConfig,
885 - engine_idxs: Optional[list[int]] = None,
886 - custom_stat_loggers: Optional[list[StatLoggerFactory]] = None,
880 + engine_idxs: list[int] | None = None,
881 + custom_stat_loggers: list[StatLoggerFactory] | None = None,
882 enable_default_loggers: bool = True,
883 client_count: int = 1,
884 ):
@@ -924,10 +919,10 @@ class StatLoggerManager:
919
920 def record(
921 self,
927 - scheduler_stats: Optional[SchedulerStats],
928 - iteration_stats: Optional[IterationStats],
929 - mm_cache_stats: Optional[MultiModalCacheStats] = None,
930 - engine_idx: Optional[int] = None,
922 + scheduler_stats: SchedulerStats | None,
923 + iteration_stats: IterationStats | None,
924 + mm_cache_stats: MultiModalCacheStats | None = None,
925 + engine_idx: int | None = None,
926 ):
927 if engine_idx is None:
928 engine_idx = 0
vllm/v1/metrics/prometheus.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import os
5 import tempfile
6 -from typing import Optional
6
7 from prometheus_client import REGISTRY, CollectorRegistry, multiprocess
8
@@ -12,7 +11,7 @@ from vllm.logger import init_logger
11 logger = init_logger(__name__)
12
13 # Global temporary directory for prometheus multiprocessing
15 -_prometheus_multiproc_dir: Optional[tempfile.TemporaryDirectory] = None
14 +_prometheus_multiproc_dir: tempfile.TemporaryDirectory | None = None
15
16
17 def setup_multiprocess_prometheus():
vllm/v1/metrics/ray_wrappers.py
+11 -12
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import time
4 -from typing import Optional, Union
4
5 from vllm.v1.metrics.loggers import PrometheusStatLogger
6 from vllm.v1.spec_decode.metrics import SpecDecodingProm
@@ -63,9 +62,9 @@ class RayGaugeWrapper(RayPrometheusMetric):
62 def __init__(
63 self,
64 name: str,
66 - documentation: Optional[str] = "",
67 - labelnames: Optional[list[str]] = None,
68 - multiprocess_mode: Optional[str] = "",
65 + documentation: str | None = "",
66 + labelnames: list[str] | None = None,
67 + multiprocess_mode: str | None = "",
68 ):
69 # All Ray metrics are keyed by WorkerId, so multiprocess modes like
70 # "mostrecent", "all", "sum" do not apply. This logic can be manually
@@ -77,7 +76,7 @@ class RayGaugeWrapper(RayPrometheusMetric):
76 name=name, description=documentation, tag_keys=labelnames_tuple
77 )
78
80 - def set(self, value: Union[int, float]):
79 + def set(self, value: int | float):
80 return self.metric.set(value)
81
82 def set_to_current_time(self):
@@ -92,8 +91,8 @@ class RayCounterWrapper(RayPrometheusMetric):
91 def __init__(
92 self,
93 name: str,
95 - documentation: Optional[str] = "",
96 - labelnames: Optional[list[str]] = None,
94 + documentation: str | None = "",
95 + labelnames: list[str] | None = None,
96 ):
97 labelnames_tuple = tuple(labelnames) if labelnames else None
98 name = self._get_sanitized_opentelemetry_name(name)
@@ -101,7 +100,7 @@ class RayCounterWrapper(RayPrometheusMetric):
100 name=name, description=documentation, tag_keys=labelnames_tuple
101 )
102
104 - def inc(self, value: Union[int, float] = 1.0):
103 + def inc(self, value: int | float = 1.0):
104 if value == 0:
105 return
106 return self.metric.inc(value)
@@ -114,9 +113,9 @@ class RayHistogramWrapper(RayPrometheusMetric):
113 def __init__(
114 self,
115 name: str,
117 - documentation: Optional[str] = "",
118 - labelnames: Optional[list[str]] = None,
119 - buckets: Optional[list[float]] = None,
116 + documentation: str | None = "",
117 + labelnames: list[str] | None = None,
118 + buckets: list[float] | None = None,
119 ):
120 labelnames_tuple = tuple(labelnames) if labelnames else None
121 name = self._get_sanitized_opentelemetry_name(name)
@@ -128,7 +127,7 @@ class RayHistogramWrapper(RayPrometheusMetric):
127 boundaries=boundaries,
128 )
129
131 - def observe(self, value: Union[int, float]):
130 + def observe(self, value: int | float):
131 return self.metric.observe(value)
132
133
vllm/v1/metrics/reader.py
+1 -2
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 from prometheus_client import REGISTRY
7 from prometheus_client import Metric as PromMetric
@@ -144,7 +143,7 @@ def get_metrics_snapshot() -> list[Metric]:
143 return collected
144
145
147 -def _get_samples(metric: PromMetric, suffix: Optional[str] = None) -> list[Sample]:
146 +def _get_samples(metric: PromMetric, suffix: str | None = None) -> list[Sample]:
147 name = (metric.name + suffix) if suffix is not None else metric.name
148 return [s for s in metric.samples if s.name == name]
149
vllm/v1/metrics/stats.py
+11 -11
@@ -4,7 +4,7 @@
4 import time
5 from collections import deque
6 from dataclasses import dataclass, field
7 -from typing import TYPE_CHECKING, Any, Optional
7 +from typing import TYPE_CHECKING, Any
8
9 from vllm.v1.spec_decode.metrics import SpecDecodingStats
10
@@ -152,8 +152,8 @@ class SchedulerStats:
152
153 prefix_cache_stats: PrefixCacheStats = field(default_factory=PrefixCacheStats)
154
155 - spec_decoding_stats: Optional[SpecDecodingStats] = None
156 - kv_connector_stats: Optional[dict[str, Any]] = None
155 + spec_decoding_stats: SpecDecodingStats | None = None
156 + kv_connector_stats: dict[str, Any] | None = None
157
158 num_corrupted_reqs: int = 0
159
@@ -191,7 +191,7 @@ class FinishedRequestStats:
191 e2e_latency: float = 0.0
192 num_prompt_tokens: int = 0
193 num_generation_tokens: int = 0
194 - max_tokens_param: Optional[int] = None
194 + max_tokens_param: int | None = None
195 queued_time: float = 0.0
196 prefill_time: float = 0.0
197 inference_time: float = 0.0
@@ -230,7 +230,7 @@ class IterationStats:
230 is_prefilling: bool,
231 prompt_len: int,
232 req_stats: RequestStateStats,
233 - lora_stats: Optional[LoRAStats],
233 + lora_stats: LoRAStats | None,
234 ):
235 num_new_generation_tokens = len(output.new_token_ids)
236
@@ -265,7 +265,7 @@ class IterationStats:
265 events: list["EngineCoreEvent"],
266 is_prefilling: bool,
267 req_stats: RequestStateStats,
268 - lora_stats: Optional[LoRAStats],
268 + lora_stats: LoRAStats | None,
269 ):
270 # Avoid circular dependency
271 from vllm.v1.engine import EngineCoreEventType
@@ -287,7 +287,7 @@ class IterationStats:
287 self,
288 finish_reason: "FinishReason",
289 num_prompt_tokens: int,
290 - max_tokens_param: Optional[int],
290 + max_tokens_param: int | None,
291 req_stats: RequestStateStats,
292 ):
293 e2e_latency = self._time_since(req_stats.arrival_time)
@@ -335,7 +335,7 @@ class LoRARequestStates:
335 def __init__(self):
336 self.lora_name_to_stats: dict[str, LoRAStats] = {}
337
338 - def get_stats(self, req_state: "RequestState") -> Optional[LoRAStats]:
338 + def get_stats(self, req_state: "RequestState") -> LoRAStats | None:
339 if req_state.lora_name is None:
340 return None
341 if req_state.lora_name not in self.lora_name_to_stats:
@@ -362,20 +362,20 @@ class LoRARequestStates:
362 # Break the pattern for this lifecycle methods so we can
363 # call this from IterationStats.update_from_events()
364 @staticmethod
365 - def scheduled_request(lora_stats: Optional[LoRAStats], request_id: str):
365 + def scheduled_request(lora_stats: LoRAStats | None, request_id: str):
366 if lora_stats is None:
367 return
368 lora_stats.waiting_requests.remove(request_id)
369 lora_stats.running_requests.add(request_id)
370
371 @staticmethod
372 - def preempted_request(lora_stats: Optional[LoRAStats], request_id: str):
372 + def preempted_request(lora_stats: LoRAStats | None, request_id: str):
373 if lora_stats is None:
374 return
375 lora_stats.running_requests.remove(request_id)
376 lora_stats.waiting_requests.add(request_id)
377
378 - def update_iteration_stats(self, iteration_stats: Optional[IterationStats]):
378 + def update_iteration_stats(self, iteration_stats: IterationStats | None):
379 if iteration_stats is None:
380 return
381 for lora_name, stats in self.lora_name_to_stats.items():
vllm/v1/outputs.py
+13 -11
@@ -3,12 +3,14 @@
3
4 from abc import ABC, abstractmethod
5 from dataclasses import dataclass, field
6 -from typing import TYPE_CHECKING, NamedTuple, Optional, Union
6 +from typing import TYPE_CHECKING, NamedTuple
7
8 import torch
9
10 if TYPE_CHECKING:
11 from vllm.distributed.kv_transfer.kv_connector.v1.metrics import KVConnectorStats
12 +else:
13 + KVConnectorStats = object
14
15
16 class LogprobsLists(NamedTuple):
@@ -64,7 +66,7 @@ class LogprobsTensors(NamedTuple):
66
67 # [num_reqs, <dynamic>]
68 # The shape of each element depends on the pooler used
67 -PoolerOutput = Union[torch.Tensor, list[torch.Tensor]]
69 +PoolerOutput = torch.Tensor | list[torch.Tensor]
70
71
72 @dataclass
@@ -74,15 +76,15 @@ class SamplerOutput:
76 # All requests are padded to max_num_generated_tokens.
77 # PLACEHOLDER_TOKEN_ID (-1 by default) is used for padding.
78 sampled_token_ids: torch.Tensor
77 - logprobs_tensors: Optional[LogprobsTensors]
79 + logprobs_tensors: LogprobsTensors | None
80
81
82 @dataclass
83 class KVConnectorOutput:
84 # [req_ids]
83 - finished_sending: Optional[set[str]] = None
84 - finished_recving: Optional[set[str]] = None
85 - kv_connector_stats: Optional["KVConnectorStats"] = None
85 + finished_sending: set[str] | None = None
86 + finished_recving: set[str] | None = None
87 + kv_connector_stats: KVConnectorStats | None = None
88 # IDs of externally computed KV blocks that failed to load.
89 # Requests referencing these blocks should be rescheduled to recompute them.
90 invalid_block_ids: set[int] = field(default_factory=set)
@@ -114,21 +116,21 @@ class ModelRunnerOutput:
116 # [num_reqs, max_num_logprobs + 1]
117 # [num_reqs, max_num_logprobs + 1]
118 # [num_reqs]
117 - logprobs: Optional[LogprobsLists]
119 + logprobs: LogprobsLists | None
120
121 # req_id -> (token_ids, logprobs, ranks)
122 # [prompt_len, num_prompt_logprobs]
123 # [prompt_len, num_prompt_logprobs]
124 # [prompt_len]
123 - prompt_logprobs_dict: dict[str, Optional[LogprobsTensors]]
125 + prompt_logprobs_dict: dict[str, LogprobsTensors | None]
126
127 # [num_reqs, hidden_size]
126 - pooler_output: list[Optional[torch.Tensor]]
128 + pooler_output: list[torch.Tensor | None]
129
128 - kv_connector_output: Optional[KVConnectorOutput] = None
130 + kv_connector_output: KVConnectorOutput | None = None
131
132 # req_id -> num_nans_in_logits
131 - num_nans_in_logits: Optional[dict[str, int]] = None
133 + num_nans_in_logits: dict[str, int] | None = None
134
135
136 # ModelRunnerOutput wrapper for async scheduling.
vllm/v1/pool/metadata.py
+2 -3
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 -from typing import Optional
4
5 import torch
6
@@ -37,9 +36,9 @@ class PoolingMetadata:
36 """Tensors for pooling."""
37
38 prompt_lens: torch.Tensor # CPU Tensor
40 - prompt_token_ids: Optional[torch.Tensor]
39 + prompt_token_ids: torch.Tensor | None
40 pooling_params: list[PoolingParams]
42 - pooling_cursor: Optional[PoolingCursor] = None
41 + pooling_cursor: PoolingCursor | None = None
42
43 def __getitem__(self, indices: slice):
44 return PoolingMetadata(
vllm/v1/request.py
+22 -22
@@ -3,9 +3,9 @@
3
4 import enum
5 import time
6 -from collections.abc import Mapping
6 +from collections.abc import Callable, Mapping
7 from functools import partial
8 -from typing import TYPE_CHECKING, Any, Callable, Optional, Union
8 +from typing import TYPE_CHECKING, Any, Optional
9
10 import torch
11
@@ -31,20 +31,20 @@ class Request:
31 def __init__(
32 self,
33 request_id: str,
34 - prompt_token_ids: Optional[list[int]],
35 - sampling_params: Optional[SamplingParams],
36 - pooling_params: Optional[PoolingParams],
37 - eos_token_id: Optional[int],
34 + prompt_token_ids: list[int] | None,
35 + sampling_params: SamplingParams | None,
36 + pooling_params: PoolingParams | None,
37 + eos_token_id: int | None,
38 client_index: int = 0,
39 - arrival_time: Optional[float] = None,
40 - prompt_embeds: Optional[torch.Tensor] = None,
41 - mm_features: Optional[list[MultiModalFeatureSpec]] = None,
39 + arrival_time: float | None = None,
40 + prompt_embeds: torch.Tensor | None = None,
41 + mm_features: list[MultiModalFeatureSpec] | None = None,
42 lora_request: Optional["LoRARequest"] = None,
43 structured_output_request: Optional["StructuredOutputRequest"] = None,
44 - cache_salt: Optional[str] = None,
44 + cache_salt: str | None = None,
45 priority: int = 0,
46 - trace_headers: Optional[Mapping[str, str]] = None,
47 - block_hasher: Optional[Callable[["Request"], list["BlockHash"]]] = None,
46 + trace_headers: Mapping[str, str] | None = None,
47 + block_hasher: Callable[["Request"], list["BlockHash"]] | None = None,
48 ) -> None:
49 self.request_id = request_id
50 self.client_index = client_index
@@ -60,10 +60,10 @@ class Request:
60 self.status = RequestStatus.WAITING
61 self.use_structured_output = False
62 self.events: list[EngineCoreEvent] = []
63 - self.stop_reason: Union[int, str, None] = None
63 + self.stop_reason: int | str | None = None
64
65 # P/D: Connector-specific KV transfer parameters.
66 - self.kv_transfer_params: Optional[dict[str, Any]] = None
66 + self.kv_transfer_params: dict[str, Any] | None = None
67
68 if pooling_params is not None:
69 # Pooling models.
@@ -97,7 +97,7 @@ class Request:
97 self.num_output_placeholders = 0 # Used in async scheduling.
98 self.spec_token_ids: list[int] = []
99 self.num_computed_tokens = 0
100 - self.cache_salt: Optional[str] = cache_salt
100 + self.cache_salt: str | None = cache_salt
101
102 # Multi-modal related
103 self.mm_features = mm_features or []
@@ -123,7 +123,7 @@ class Request:
123 self.num_preemptions = 0
124
125 self.block_hashes: list[BlockHash] = []
126 - self.get_hash_new_full_blocks: Optional[Callable[[], list[BlockHash]]] = None
126 + self.get_hash_new_full_blocks: Callable[[], list[BlockHash]] | None = None
127 if block_hasher is not None:
128 self.get_hash_new_full_blocks = partial(block_hasher, self)
129 self.block_hashes = self.get_hash_new_full_blocks()
@@ -132,7 +132,7 @@ class Request:
132 def from_engine_core_request(
133 cls,
134 request: EngineCoreRequest,
135 - block_hasher: Optional[Callable[["Request"], list["BlockHash"]]],
135 + block_hasher: Callable[["Request"], list["BlockHash"]] | None,
136 ) -> "Request":
137 return cls(
138 request_id=request.request_id,
@@ -158,7 +158,7 @@ class Request:
158
159 def append_output_token_ids(
160 self,
161 - token_ids: Union[int, list[int]],
161 + token_ids: int | list[int],
162 ) -> None:
163 if isinstance(token_ids, int):
164 self._output_token_ids.append(token_ids)
@@ -189,7 +189,7 @@ class Request:
189 def is_finished(self) -> bool:
190 return RequestStatus.is_finished(self.status)
191
192 - def get_finished_reason(self) -> Union[FinishReason, None]:
192 + def get_finished_reason(self) -> FinishReason | None:
193 return RequestStatus.get_finished_reason(self.status)
194
195 def get_num_encoder_tokens(self, input_id: int) -> int:
@@ -200,11 +200,11 @@ class Request:
200 def record_event(
201 self,
202 event_type: EngineCoreEventType,
203 - timestamp: Optional[float] = None,
203 + timestamp: float | None = None,
204 ) -> None:
205 self.events.append(EngineCoreEvent.new_event(event_type, timestamp))
206
207 - def take_events(self) -> Optional[list[EngineCoreEvent]]:
207 + def take_events(self) -> list[EngineCoreEvent] | None:
208 if not self.events:
209 return None
210 events, self.events = self.events, []
@@ -234,7 +234,7 @@ class RequestStatus(enum.IntEnum):
234 return status > RequestStatus.PREEMPTED
235
236 @staticmethod
237 - def get_finished_reason(status: "RequestStatus") -> Union[FinishReason, None]:
237 + def get_finished_reason(status: "RequestStatus") -> FinishReason | None:
238 return _FINISHED_REASON_MAP.get(status)
239
240
vllm/v1/sample/logits_processor/__init__.py
+8 -8
@@ -6,7 +6,7 @@ import itertools
6 from abc import abstractmethod
7 from collections.abc import Sequence
8 from functools import partial
9 -from typing import TYPE_CHECKING, Optional, Union
9 +from typing import TYPE_CHECKING
10
11 import torch
12
@@ -81,7 +81,7 @@ def _load_logitsprocs_plugins() -> list[type[LogitsProcessor]]:
81
82
83 def _load_logitsprocs_by_fqcns(
84 - logits_processors: Optional[Sequence[Union[str, type[LogitsProcessor]]]],
84 + logits_processors: Sequence[str | type[LogitsProcessor]] | None,
85 ) -> list[type[LogitsProcessor]]:
86 """Load logit processor types, identifying them by fully-qualified class
87 names (FQCNs).
@@ -146,7 +146,7 @@ def _load_logitsprocs_by_fqcns(
146
147
148 def _load_custom_logitsprocs(
149 - logits_processors: Optional[Sequence[Union[str, type[LogitsProcessor]]]],
149 + logits_processors: Sequence[str | type[LogitsProcessor]] | None,
150 ) -> list[type[LogitsProcessor]]:
151 """Load all custom logits processors.
152
@@ -176,7 +176,7 @@ def build_logitsprocs(
176 device: torch.device,
177 is_pin_memory: bool,
178 is_pooling_model: bool,
179 - custom_logitsprocs: Sequence[Union[str, type[LogitsProcessor]]] = (),
179 + custom_logitsprocs: Sequence[str | type[LogitsProcessor]] = (),
180 ) -> LogitsProcessors:
181 if is_pooling_model:
182 if custom_logitsprocs:
@@ -249,7 +249,7 @@ class AdapterLogitsProcessor(LogitsProcessor):
249 def new_req_logits_processor(
250 self,
251 params: SamplingParams,
252 - ) -> Optional[RequestLogitsProcessor]:
252 + ) -> RequestLogitsProcessor | None:
253 """Consume request info; return a per-request logits processor.
254
255 Return None if logits processor does not need to be applied to request
@@ -267,9 +267,9 @@ class AdapterLogitsProcessor(LogitsProcessor):
267 def _new_state(
268 self,
269 params: SamplingParams,
270 - prompt_ids: Optional[list[int]],
270 + prompt_ids: list[int] | None,
271 output_ids: list[int],
272 - ) -> Optional[partial[torch.Tensor]]:
272 + ) -> partial[torch.Tensor] | None:
273 """Return state representation for new request
274
275 Returns None if logits processor is not applicable to request
@@ -292,7 +292,7 @@ class AdapterLogitsProcessor(LogitsProcessor):
292 return partial(req_lp, *args)
293 return None
294
295 - def update_state(self, batch_update: Optional[BatchUpdate]):
295 + def update_state(self, batch_update: BatchUpdate | None):
296 process_dict_updates(
297 self.req_info,
298 batch_update,
vllm/v1/sample/logits_processor/builtin.py
+9 -9
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from collections.abc import Sequence
4 -from typing import TYPE_CHECKING, Callable, Optional, TypeVar
3 +from collections.abc import Callable, Sequence
4 +from typing import TYPE_CHECKING, TypeVar
5
6 import torch
7
@@ -49,7 +49,7 @@ class MinPLogitsProcessor(LogitsProcessor):
49 def get_min_p_by_index(self, index: int) -> float:
50 return float(self.min_p_cpu[index])
51
52 - def update_state(self, batch_update: Optional[BatchUpdate]):
52 + def update_state(self, batch_update: BatchUpdate | None):
53 if not batch_update:
54 return
55
@@ -131,7 +131,7 @@ class LogitBiasLogitsProcessor(LogitsProcessor):
131 outcome of argmax in greedy sampling."""
132 return False
133
134 - def update_state(self, batch_update: Optional[BatchUpdate]):
134 + def update_state(self, batch_update: BatchUpdate | None):
135 needs_update = process_dict_updates(
136 self.biases, batch_update, lambda params, _, __: params.logit_bias or None
137 )
@@ -185,14 +185,14 @@ class MinTokensLogitsProcessor(LogitsProcessor):
185
186 @staticmethod
187 def add_request(
188 - params: SamplingParams, _: Optional[list[int]], output_tok_ids: list[int]
189 - ) -> Optional[tuple[int, Sequence[int], set[int]]]:
188 + params: SamplingParams, _: list[int] | None, output_tok_ids: list[int]
189 + ) -> tuple[int, Sequence[int], set[int]] | None:
190 min_tokens = params.min_tokens
191 if not min_tokens or len(output_tok_ids) >= min_tokens:
192 return None
193 return min_tokens, output_tok_ids, params.all_stop_token_ids
194
195 - def update_state(self, batch_update: Optional[BatchUpdate]):
195 + def update_state(self, batch_update: BatchUpdate | None):
196 needs_update = process_dict_updates(
197 self.min_toks, batch_update, self.add_request
198 )
@@ -235,8 +235,8 @@ class MinTokensLogitsProcessor(LogitsProcessor):
235
236 def process_dict_updates(
237 req_entries: dict[int, T],
238 - batch_update: Optional[BatchUpdate],
239 - new_state: Callable[[SamplingParams, Optional[list[int]], list[int]], Optional[T]],
238 + batch_update: BatchUpdate | None,
239 + new_state: Callable[[SamplingParams, list[int] | None, list[int]], T | None],
240 ) -> bool:
241 """Utility function to update dict state for sparse LogitsProcessors."""
242
vllm/v1/sample/logits_processor/interface.py
+1 -1
@@ -26,7 +26,7 @@ RemovedRequest = int
26
27 # (index, params, prompt_tok_ids, output_tok_ids) tuples for new
28 # requests added to the batch.
29 -AddedRequest = tuple[int, SamplingParams, Optional[list[int]], list[int]]
29 +AddedRequest = tuple[int, SamplingParams, list[int] | None, list[int]]
30
31 # (index 1, index 2, directionality) tuples representing
32 # one-way moves or two-way swaps of requests in batch
vllm/v1/sample/logits_processor/state.py
+8 -10
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Iterator
4 from itertools import chain
5 -from typing import TYPE_CHECKING, Optional
5 +from typing import TYPE_CHECKING
6
7 from vllm.v1.sample.logits_processor.interface import (
8 AddedRequest,
@@ -43,9 +43,9 @@ class BatchUpdateBuilder:
43
44 def __init__(
45 self,
46 - removed: Optional[list[RemovedRequest]] = None,
47 - added: Optional[list[AddedRequest]] = None,
48 - moved: Optional[list[MovedRequest]] = None,
46 + removed: list[RemovedRequest] | None = None,
47 + added: list[AddedRequest] | None = None,
48 + moved: list[MovedRequest] | None = None,
49 ) -> None:
50 self._removed = removed or []
51 self.added = added or []
@@ -92,14 +92,14 @@ class BatchUpdateBuilder:
92 def has_removed(self) -> bool:
93 return bool(self._removed)
94
95 - def peek_removed(self) -> Optional[int]:
95 + def peek_removed(self) -> int | None:
96 """Return lowest removed request index"""
97 if self.has_removed():
98 self._ensure_removed_sorted()
99 return self._removed[-1]
100 return None
101
102 - def pop_removed(self) -> Optional[int]:
102 + def pop_removed(self) -> int | None:
103 """Pop lowest removed request index"""
104 if self.has_removed():
105 self._ensure_removed_sorted()
@@ -116,7 +116,7 @@ class BatchUpdateBuilder:
116 self.batch_changed = False
117 return batch_changed
118
119 - def get_and_reset(self, batch_size: int) -> Optional[BatchUpdate]:
119 + def get_and_reset(self, batch_size: int) -> BatchUpdate | None:
120 """Generate a logitsprocs batch update data structure and reset
121 internal batch update builder state.
122
@@ -148,9 +148,7 @@ class BatchUpdateBuilder:
148 class LogitsProcessors:
149 """Encapsulates initialized logitsproc objects."""
150
151 - def __init__(
152 - self, logitsprocs: Optional[Iterator["LogitsProcessor"]] = None
153 - ) -> None:
151 + def __init__(self, logitsprocs: Iterator["LogitsProcessor"] | None = None) -> None:
152 self.argmax_invariant: list[LogitsProcessor] = []
153 self.non_argmax_invariant: list[LogitsProcessor] = []
154 if logitsprocs:
vllm/v1/sample/metadata.py
+7 -8
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from dataclasses import dataclass
5 -from typing import Optional
5
6 import torch
7
@@ -11,20 +10,20 @@ from vllm.v1.sample.logits_processor import LogitsProcessors
10
11 @dataclass
12 class SamplingMetadata:
14 - temperature: Optional[torch.Tensor]
13 + temperature: torch.Tensor | None
14 all_greedy: bool
15 all_random: bool
16
18 - top_p: Optional[torch.Tensor]
19 - top_k: Optional[torch.Tensor]
17 + top_p: torch.Tensor | None
18 + top_k: torch.Tensor | None
19
20 generators: dict[int, torch.Generator]
21
22 # None means no logprobs, 0 means sampled token logprobs only
24 - max_num_logprobs: Optional[int]
23 + max_num_logprobs: int | None
24
25 no_penalties: bool
27 - prompt_token_ids: Optional[torch.Tensor]
26 + prompt_token_ids: torch.Tensor | None
27 frequency_penalties: torch.Tensor
28 presence_penalties: torch.Tensor
29 repetition_penalties: torch.Tensor
@@ -33,7 +32,7 @@ class SamplingMetadata:
32
33 # `allowed_token_ids_mask` is a 2D bool tensor of shape (max batch size,
34 # vocab size).
36 - allowed_token_ids_mask: Optional[torch.Tensor]
35 + allowed_token_ids_mask: torch.Tensor | None
36
37 # req_index -> bad_words_token_ids
38 bad_words_token_ids: dict[int, list[list[int]]]
@@ -42,4 +41,4 @@ class SamplingMetadata:
41 logitsprocs: LogitsProcessors
42
43 # Speculative token ids
45 - spec_token_ids: Optional[list[list[int]]] = None
44 + spec_token_ids: list[list[int]] | None = None
vllm/v1/sample/ops/topk_topp_sampler.py
+13 -14
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from typing import Optional
4
5 import torch
6 import torch.nn as nn
@@ -84,9 +83,9 @@ class TopKTopPSampler(nn.Module):
83 self,
84 logits: torch.Tensor,
85 generators: dict[int, torch.Generator],
87 - k: Optional[torch.Tensor],
88 - p: Optional[torch.Tensor],
89 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
86 + k: torch.Tensor | None,
87 + p: torch.Tensor | None,
88 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
89 """
90 PyTorch-native implementation of top-k and top-p sampling.
91
@@ -105,9 +104,9 @@ class TopKTopPSampler(nn.Module):
104 self,
105 logits: torch.Tensor,
106 generators: dict[int, torch.Generator],
108 - k: Optional[torch.Tensor],
109 - p: Optional[torch.Tensor],
110 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
107 + k: torch.Tensor | None,
108 + p: torch.Tensor | None,
109 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
110 """More optimized implementation for top-k and top-p sampling."""
111 # We prefer `random_sample` over `flashinfer_sample` when sorting is
112 # not needed. This is because `random_sample` does not require
@@ -132,9 +131,9 @@ class TopKTopPSampler(nn.Module):
131 self,
132 logits: torch.Tensor,
133 generators: dict[int, torch.Generator],
135 - k: Optional[torch.Tensor],
136 - p: Optional[torch.Tensor],
137 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
134 + k: torch.Tensor | None,
135 + p: torch.Tensor | None,
136 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
137 """
138 PyTorch-native implementation of top-k and top-p sampling for CPU.
139
@@ -170,8 +169,8 @@ class TopKTopPSampler(nn.Module):
169
170 def apply_top_k_top_p(
171 logits: torch.Tensor,
173 - k: Optional[torch.Tensor],
174 - p: Optional[torch.Tensor],
172 + k: torch.Tensor | None,
173 + p: torch.Tensor | None,
174 ) -> torch.Tensor:
175 """Apply top-k and top-p masks to the logits.
176
@@ -262,8 +261,8 @@ def random_sample(
261
262 def flashinfer_sample(
263 logits: torch.Tensor,
265 - k: Optional[torch.Tensor],
266 - p: Optional[torch.Tensor],
264 + k: torch.Tensor | None,
265 + p: torch.Tensor | None,
266 generators: dict[int, torch.Generator],
267 ) -> torch.Tensor:
268 """Sample from the logits using FlashInfer.
vllm/v1/sample/rejection_sampler.py
+4 -5
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import torch
5 import torch.nn as nn
@@ -49,7 +48,7 @@ class RejectionSampler(nn.Module):
48 self,
49 metadata: SpecDecodeMetadata,
50 # [num_tokens, vocab_size]
52 - draft_probs: Optional[torch.Tensor],
51 + draft_probs: torch.Tensor | None,
52 # [num_tokens, vocab_size]
53 target_logits: torch.Tensor,
54 # [batch_size, 1]
@@ -216,7 +215,7 @@ class RejectionSampler(nn.Module):
215 @staticmethod
216 def _combine_outputs_with_spec_tokens(
217 output_token_ids: list[list[int]],
219 - spec_token_ids: Optional[list[list[int]]] = None,
218 + spec_token_ids: list[list[int]] | None = None,
219 ) -> list[list[int]]:
220 if spec_token_ids is None:
221 return output_token_ids
@@ -240,7 +239,7 @@ def rejection_sample(
239 # [batch_size]
240 cu_num_draft_tokens: torch.Tensor,
241 # [num_tokens, vocab_size]
243 - draft_probs: Optional[torch.Tensor],
242 + draft_probs: torch.Tensor | None,
243 # [num_tokens, vocab_size]
244 target_probs: torch.Tensor,
245 # [batch_size, 1]
@@ -493,7 +492,7 @@ def sample_recovered_tokens(
492 # [num_tokens]
493 draft_token_ids: torch.Tensor,
494 # [num_tokens, vocab_size]
496 - draft_probs: Optional[torch.Tensor],
495 + draft_probs: torch.Tensor | None,
496 # [num_tokens, vocab_size]
497 target_probs: torch.Tensor,
498 sampling_metadata: SamplingMetadata,
vllm/v1/sample/sampler.py
+2 -4
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """A layer that samples the next tokens from the model's outputs."""
4
5 -from typing import Optional
6 -
5 import torch
6 import torch.nn as nn
7
@@ -140,7 +138,7 @@ class Sampler(nn.Module):
138 self,
139 logits: torch.Tensor,
140 sampling_metadata: SamplingMetadata,
143 - ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
141 + ) -> tuple[torch.Tensor, torch.Tensor | None]:
142 """Sample logits based on sampling metadata.
143
144 The various logits processing functions called in this method
@@ -243,7 +241,7 @@ class Sampler(nn.Module):
241 @staticmethod
242 def _combine_outputs_with_spec_tokens(
243 output_token_ids: list[list[int]],
246 - spec_token_ids: Optional[list[list[int]]] = None,
244 + spec_token_ids: list[list[int]] | None = None,
245 ) -> list[list[int]]:
246 if spec_token_ids is None:
247 return output_token_ids
vllm/v1/sample/tpu/metadata.py
+1 -2
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass, field
4 -from typing import Optional
4
5 import torch
6
@@ -48,7 +47,7 @@ class TPUSupportedSamplingMetadata:
47
48 min_tokens = None # impl is not vectorized
49
51 - logit_bias: list[Optional[dict[int, float]]] = field(default_factory=lambda: list())
50 + logit_bias: list[dict[int, float] | None] = field(default_factory=lambda: list())
51
52 allowed_token_ids_mask = None
53 bad_words_token_ids = None
vllm/v1/sample/tpu/sampler.py
+2 -4
@@ -2,8 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Sampler layer implementing TPU supported operations."""
4
5 -from typing import Optional
6 -
5 import torch
6 import torch.nn as nn
7
@@ -166,8 +164,8 @@ class Sampler(nn.Module):
164
165 def apply_top_k_top_p(
166 logits: torch.Tensor,
169 - k: Optional[torch.Tensor],
170 - p: Optional[torch.Tensor],
167 + k: torch.Tensor | None,
168 + p: torch.Tensor | None,
169 ) -> torch.Tensor:
170 """
171 Apply top-k and top-p optimized for TPU.
vllm/v1/serial_utils.py
+10 -10
@@ -4,10 +4,10 @@
4 import dataclasses
5 import importlib
6 import pickle
7 -from collections.abc import Sequence
7 +from collections.abc import Callable, Sequence
8 from inspect import isclass
9 from types import FunctionType
10 -from typing import Any, Callable, Optional, Union
10 +from typing import Any, TypeAlias
11
12 import cloudpickle
13 import msgspec
@@ -47,7 +47,7 @@ MMF_CLASS_TO_FACTORY: dict[type[BaseMultiModalField], str] = {
47 MultiModalBatchedField: "batched",
48 }
49
50 -bytestr = Union[bytes, bytearray, memoryview, zmq.Frame]
50 +bytestr: TypeAlias = bytes | bytearray | memoryview | zmq.Frame
51
52
53 def _log_insecure_serialization_warning():
@@ -57,7 +57,7 @@ def _log_insecure_serialization_warning():
57 )
58
59
60 -def _typestr(val: Any) -> Optional[tuple[str, str]]:
60 +def _typestr(val: Any) -> tuple[str, str] | None:
61 if val is None:
62 return None
63 t = type(val)
@@ -111,14 +111,14 @@ class MsgpackEncoder:
111 via dedicated messages. Note that this is a per-tensor limit.
112 """
113
114 - def __init__(self, size_threshold: Optional[int] = None):
114 + def __init__(self, size_threshold: int | None = None):
115 if size_threshold is None:
116 size_threshold = envs.VLLM_MSGPACK_ZERO_COPY_THRESHOLD
117 self.encoder = msgpack.Encoder(enc_hook=self.enc_hook)
118 # This is used as a local stash of buffers that we can then access from
119 # our custom `msgspec` hook, `enc_hook`. We don't have a way to
120 # pass custom data to the hook otherwise.
121 - self.aux_buffers: Optional[list[bytestr]] = None
121 + self.aux_buffers: list[bytestr] | None = None
122 self.size_threshold = size_threshold
123 if envs.VLLM_ALLOW_INSECURE_SERIALIZATION:
124 _log_insecure_serialization_warning()
@@ -195,7 +195,7 @@ class MsgpackEncoder:
195
196 def _encode_ndarray(
197 self, obj: np.ndarray
198 - ) -> tuple[str, tuple[int, ...], Union[int, memoryview]]:
198 + ) -> tuple[str, tuple[int, ...], int | memoryview]:
199 assert self.aux_buffers is not None
200 # If the array is non-contiguous, we need to copy it first
201 arr_data = obj.data if obj.flags.c_contiguous else obj.tobytes()
@@ -215,7 +215,7 @@ class MsgpackEncoder:
215
216 def _encode_tensor(
217 self, obj: torch.Tensor
218 - ) -> tuple[str, tuple[int, ...], Union[int, memoryview]]:
218 + ) -> tuple[str, tuple[int, ...], int | memoryview]:
219 assert self.aux_buffers is not None
220 # view the tensor as a contiguous 1D array of bytes
221 arr = obj.flatten().contiguous().view(torch.uint8).numpy()
@@ -280,7 +280,7 @@ class MsgpackDecoder:
280 not thread-safe when encoding tensors / numpy arrays.
281 """
282
283 - def __init__(self, t: Optional[Any] = None):
283 + def __init__(self, t: Any | None = None):
284 args = () if t is None else (t,)
285 self.decoder = msgpack.Decoder(
286 *args, ext_hook=self.ext_hook, dec_hook=self.dec_hook
@@ -289,7 +289,7 @@ class MsgpackDecoder:
289 if envs.VLLM_ALLOW_INSECURE_SERIALIZATION:
290 _log_insecure_serialization_warning()
291
292 - def decode(self, bufs: Union[bytestr, Sequence[bytestr]]) -> Any:
292 + def decode(self, bufs: bytestr | Sequence[bytestr]) -> Any:
293 if isinstance(bufs, bytestr): # type: ignore
294 return self.decoder.decode(bufs)
295
vllm/v1/spec_decode/eagle.py
+5 -6
@@ -3,7 +3,6 @@
3 import ast
4 from dataclasses import replace
5 from importlib.util import find_spec
6 -from typing import Optional
6
7 import numpy as np
8 import torch
@@ -79,8 +78,8 @@ class EagleProposer:
78 vllm_config.model_config
79 )
80
82 - self.attn_metadata_builder: Optional[AttentionMetadataBuilder] = None
83 - self.draft_indexer_metadata_builder: Optional[AttentionMetadataBuilder] = None
81 + self.attn_metadata_builder: AttentionMetadataBuilder | None = None
82 + self.draft_indexer_metadata_builder: AttentionMetadataBuilder | None = None
83 self.attn_layer_names: list[str] = []
84 self.indexer_layer_names: list[str] = []
85
@@ -149,7 +148,7 @@ class EagleProposer:
148 )
149
150 # Determine allowed attention backends once during initialization.
152 - self.allowed_attn_types: Optional[tuple] = None
151 + self.allowed_attn_types: tuple | None = None
152 if current_platform.is_rocm():
153 rocm_types = [TritonAttentionMetadata, FlashAttentionMetadata]
154 # vllm.v1.attention.backends.rocm_aiter_fa is an optional backend
@@ -207,10 +206,10 @@ class EagleProposer:
206 target_hidden_states: torch.Tensor,
207 # [batch_size]
208 next_token_ids: torch.Tensor,
210 - last_token_indices: Optional[torch.Tensor],
209 + last_token_indices: torch.Tensor | None,
210 common_attn_metadata: CommonAttentionMetadata,
211 sampling_metadata: SamplingMetadata,
213 - mm_embed_inputs: Optional[tuple[list[torch.Tensor], torch.Tensor]] = None,
212 + mm_embed_inputs: tuple[list[torch.Tensor], torch.Tensor] | None = None,
213 ) -> torch.Tensor:
214 num_tokens = target_token_ids.shape[0]
215 batch_size = next_token_ids.shape[0]
vllm/v1/spec_decode/metrics.py
+1 -2
@@ -3,7 +3,6 @@
3
4 import time
5 from dataclasses import dataclass, field
6 -from typing import Optional
6
7 import numpy as np
8 import prometheus_client
@@ -143,7 +142,7 @@ class SpecDecodingProm:
142
143 def __init__(
144 self,
146 - speculative_config: Optional[SpeculativeConfig],
145 + speculative_config: SpeculativeConfig | None,
146 labelnames: list[str],
147 per_engine_labelvalues: dict[int, list[str]],
148 ):
vllm/v1/structured_output/__init__.py
+4 -3
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import multiprocessing
4 from concurrent.futures import Future, ThreadPoolExecutor
5 from typing import TYPE_CHECKING
@@ -28,6 +26,9 @@ if TYPE_CHECKING:
26 else:
27 torch = LazyLoader("torch", globals(), "torch")
28
29 + ReasoningParser = object
30 + Request = object
31 +
32 logger = init_logger(__name__)
33
34
@@ -168,7 +169,7 @@ class StructuredOutputManager:
169 requests: dict[str, Request],
170 structured_output_request_ids: dict[str, int],
171 scheduled_spec_decode_tokens: dict[str, list[int]],
171 - ) -> npt.NDArray[np.int32] | None:
172 + ) -> "npt.NDArray[np.int32] | None":
173 # Prepare the structured output bitmask for this batch.
174 if not structured_output_request_ids:
175 return None
vllm/v1/structured_output/backend_guidance.py
+4 -6
@@ -1,13 +1,11 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import copy
5 import json
6 import os
7 from dataclasses import dataclass
10 -from typing import TYPE_CHECKING, Any, Union
8 +from typing import TYPE_CHECKING, Any
9
10 import torch
11
@@ -47,7 +45,7 @@ def _walk_json_for_additional_properties(data: object):
45
46
47 def process_for_additional_properties(
50 - guide_json: Union[str, dict[str, Any]],
48 + guide_json: str | dict[str, Any],
49 ) -> dict[str, Any]:
50 if isinstance(guide_json, str):
51 guide_json_obj = json.loads(guide_json)
@@ -184,12 +182,12 @@ class GuidanceGrammar(StructuredOutputGrammar):
182
183 def serialize_guidance_grammar(
184 request_type: StructuredOutputOptions,
187 - grammar_spec: Union[str, dict[str, Any]],
185 + grammar_spec: str | dict[str, Any],
186 disable_any_whitespace: bool = False,
187 disable_additional_properties: bool = False,
188 ) -> str:
189 def _process_schema(
192 - grammar_spec: Union[str, dict[str, Any]],
190 + grammar_spec: str | dict[str, Any],
191 ) -> str:
192 if disable_additional_properties:
193 grammar_spec = process_for_additional_properties(grammar_spec)
vllm/v1/structured_output/backend_lm_format_enforcer.py
+1 -3
@@ -1,7 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import ast
4 import json
5 from dataclasses import dataclass, field
@@ -34,7 +32,7 @@ else:
32 @lru_cache
33 def _cached_build_vllm_token_enforcer_tokenizer_data(
34 tokenizer: PreTrainedTokenizerBase, vocab_size: int
37 -) -> lmfe_vllm.TokenEnforcerTokenizerData:
35 +) -> "lmfe_vllm.TokenEnforcerTokenizerData":
36 return lmfe_vllm.build_vllm_token_enforcer_tokenizer_data(
37 tokenizer, use_bitmask=True, vocab_size=vocab_size
38 )
vllm/v1/structured_output/backend_outlines.py
-2
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright 2025-present the Outlines developers
3 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4 -from __future__ import annotations
5 -
4 import ast
5 import importlib
6 import json
vllm/v1/structured_output/backend_types.py
+5 -4
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import enum
5 from abc import ABC, abstractmethod
6 from dataclasses import dataclass
@@ -13,6 +11,9 @@ if TYPE_CHECKING:
11
12 from vllm.config import VllmConfig
13 from vllm.transformers_utils.tokenizer import AnyTokenizer
14 +else:
15 + VllmConfig = object
16 + AnyTokenizer = object
17
18
19 class StructuredOutputOptions(enum.Enum):
@@ -69,7 +70,7 @@ class StructuredOutputGrammar(ABC):
70 """
71
72 @abstractmethod
72 - def fill_bitmask(self, bitmask: torch.Tensor, batch_index: int) -> None:
73 + def fill_bitmask(self, bitmask: "torch.Tensor", batch_index: int) -> None:
74 """
75 Fills the bitmask for a specific batch index.
76
@@ -119,7 +120,7 @@ class StructuredOutputBackend(ABC):
120 """
121
122 @abstractmethod
122 - def allocate_token_bitmask(self, max_num_seqs: int) -> torch.Tensor:
123 + def allocate_token_bitmask(self, max_num_seqs: int) -> "torch.Tensor":
124 """
125 Allocates a token bitmask for the specified maximum number of sequences.
126
vllm/v1/structured_output/backend_xgrammar.py
-2
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import json
5 from dataclasses import dataclass, field
6 from typing import TYPE_CHECKING, Any
vllm/v1/structured_output/request.py
+4 -10
@@ -1,13 +1,11 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from __future__ import annotations
4 -
3 import dataclasses
4 import functools
5 import json
6 from concurrent.futures import Future
7 from concurrent.futures._base import TimeoutError
10 -from typing import Optional, Union, cast
8 +from typing import cast
9
10 from vllm.sampling_params import SamplingParams
11 from vllm.v1.structured_output.backend_types import (
@@ -20,9 +18,7 @@ from vllm.v1.structured_output.backend_types import (
18 @dataclasses.dataclass
19 class StructuredOutputRequest:
20 sampling_params: SamplingParams
23 - _grammar: Union[Future[StructuredOutputGrammar], StructuredOutputGrammar] | None = (
24 - None
25 - )
21 + _grammar: Future[StructuredOutputGrammar] | StructuredOutputGrammar | None = None
22 reasoning_ended: bool | None = None
23
24 def _check_grammar_completion(self) -> bool:
@@ -46,14 +42,12 @@ class StructuredOutputRequest:
42 def grammar(self) -> StructuredOutputGrammar | None:
43 completed = self._check_grammar_completion()
44 return (
49 - cast(Optional[StructuredOutputGrammar], self._grammar)
50 - if completed
51 - else None
45 + cast(StructuredOutputGrammar | None, self._grammar) if completed else None
46 )
47
48 @grammar.setter
49 def grammar(
56 - self, grammar: Union[StructuredOutputGrammar, Future[StructuredOutputGrammar]]
50 + self, grammar: StructuredOutputGrammar | Future[StructuredOutputGrammar]
51 ) -> None:
52 self._grammar = grammar
53
vllm/v1/structured_output/utils.py
+4 -3
@@ -1,8 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -
4 -from __future__ import annotations
5 -
3 import hashlib
4 import importlib.metadata
5 import os
@@ -37,6 +34,10 @@ else:
34 "transformers.models.gpt2.tokenization_gpt2",
35 )
36
37 + AnyTokenizer = object
38 + SchedulerOutput = object
39 + InputBatch = object
40 +
41 logger = init_logger(__name__)
42
43 CACHE = None
vllm/v1/utils.py
+10 -12
@@ -5,14 +5,13 @@ import contextlib
5 import multiprocessing
6 import time
7 import weakref
8 -from collections.abc import Sequence
8 +from collections.abc import Callable, Sequence
9 from contextlib import AbstractContextManager
10 from multiprocessing import connection
11 from multiprocessing.process import BaseProcess
12 from typing import (
13 TYPE_CHECKING,
14 Any,
15 - Callable,
15 Generic,
16 Optional,
17 TypeVar,
@@ -66,7 +65,7 @@ class ConstantList(Generic[T], Sequence):
65 def clear(self):
66 raise TypeError("Cannot clear a constant list")
67
69 - def index(self, item: T, start: int = 0, stop: Optional[int] = None) -> int:
68 + def index(self, item: T, start: int = 0, stop: int | None = None) -> int:
69 return self._x.index(item, start, stop if stop is not None else len(self._x))
70
71 @overload
@@ -75,7 +74,7 @@ class ConstantList(Generic[T], Sequence):
74 @overload
75 def __getitem__(self, s: slice, /) -> list[T]: ...
76
78 - def __getitem__(self, item: Union[int, slice]) -> Union[T, list[T]]:
77 + def __getitem__(self, item: int | slice) -> T | list[T]:
78 return self._x[item]
79
80 @overload
@@ -84,7 +83,7 @@ class ConstantList(Generic[T], Sequence):
83 @overload
84 def __setitem__(self, s: slice, value: T, /): ...
85
87 - def __setitem__(self, item: Union[int, slice], value: Union[T, list[T]]):
86 + def __setitem__(self, item: int | slice, value: T | list[T]):
87 raise TypeError("Cannot set item in a constant list")
88
89 def __delitem__(self, item):
@@ -108,7 +107,7 @@ class CpuGpuBuffer:
107
108 def __init__(
109 self,
111 - *size: Union[int, torch.SymInt],
110 + *size: int | torch.SymInt,
111 dtype: torch.dtype,
112 device: torch.device,
113 pin_memory: bool,
@@ -128,12 +127,12 @@ class CpuGpuBuffer:
127 )
128 self.np = self.cpu.numpy()
129
131 - def copy_to_gpu(self, n: Optional[int] = None) -> torch.Tensor:
130 + def copy_to_gpu(self, n: int | None = None) -> torch.Tensor:
131 if n is None:
132 return self.gpu.copy_(self.cpu, non_blocking=True)
133 return self.gpu[:n].copy_(self.cpu[:n], non_blocking=True)
134
136 - def copy_to_cpu(self, n: Optional[int] = None) -> torch.Tensor:
135 + def copy_to_cpu(self, n: int | None = None) -> torch.Tensor:
136 """NOTE: Because this method is non-blocking, explicit synchronization
137 is needed to ensure the data is copied to CPU."""
138 if n is None:
@@ -173,7 +172,7 @@ class APIServerProcessManager:
172 num_servers: int,
173 input_addresses: list[str],
174 output_addresses: list[str],
176 - stats_update_address: Optional[str] = None,
175 + stats_update_address: str | None = None,
176 ):
177 """Initialize and start API server worker processes.
178
@@ -227,9 +226,8 @@ class APIServerProcessManager:
226
227 def wait_for_completion_or_failure(
228 api_server_manager: APIServerProcessManager,
230 - engine_manager: Optional[
231 - Union["CoreEngineProcManager", "CoreEngineActorManager"]
232 - ] = None,
229 + engine_manager: Union["CoreEngineProcManager", "CoreEngineActorManager"]
230 + | None = None,
231 coordinator: Optional["DPCoordinator"] = None,
232 ) -> None:
233 """Wait for all processes to complete or detect if any fail.
vllm/v1/worker/block_table.py
+1 -2
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Union
3
4 import numpy as np
5 import torch
@@ -215,7 +214,7 @@ class BlockTable:
214 return self.block_table.np
215
216 def _make_buffer(
218 - self, *size: Union[int, torch.SymInt], dtype: torch.dtype
217 + self, *size: int | torch.SymInt, dtype: torch.dtype
218 ) -> CpuGpuBuffer:
219 return CpuGpuBuffer(
220 *size, dtype=dtype, device=self.device, pin_memory=self.pin_memory
vllm/v1/worker/cpu_model_runner.py
+2 -2
@@ -1,7 +1,7 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from contextlib import contextmanager
4 -from typing import TYPE_CHECKING, Any, Optional
4 +from typing import TYPE_CHECKING, Any
5
6 import torch
7 import torch.nn as nn
@@ -95,7 +95,7 @@ class CPUModelRunner(GPUModelRunner):
95 def _to_list(self, sampled_token_ids: torch.Tensor) -> list[list[int]]:
96 return sampled_token_ids.tolist()
97
98 - def get_dp_padding(self, num_tokens: int) -> tuple[int, Optional[torch.Tensor]]:
98 + def get_dp_padding(self, num_tokens: int) -> tuple[int, torch.Tensor | None]:
99 # Note: For CPU backend, dp padding is not required for now.
100 return 0, None
101
vllm/v1/worker/cpu_worker.py
+2 -2
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import os
4 import platform
5 -from typing import Callable, Optional
5 +from collections.abc import Callable
6
7 import torch
8
@@ -91,7 +91,7 @@ class CPUWorker(Worker):
91 logger.warning("sleep mode is not supported on CPU, ignore it.")
92 pass
93
94 - def wake_up(self, tags: Optional[list[str]] = None) -> None:
94 + def wake_up(self, tags: list[str] | None = None) -> None:
95 logger.warning("sleep mode is not supported on CPU, ignore it.")
96 pass
97
vllm/v1/worker/dp_utils.py
+5 -6
@@ -1,6 +1,5 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Optional
3
4 import numpy as np
5 import torch
@@ -95,7 +94,7 @@ def _synchronize_dp_ranks(
94 should_attempt_ubatching: bool,
95 should_attempt_dp_padding: bool,
96 parallel_config: ParallelConfig,
98 -) -> tuple[bool, Optional[torch.Tensor]]:
97 +) -> tuple[bool, torch.Tensor | None]:
98 """
99 1. Decides if each DP rank is going to microbatch. Either all ranks
100 run with microbatching or none of them do.
@@ -156,10 +155,10 @@ def coordinate_batch_across_dp(
155 allow_microbatching: bool,
156 allow_dp_padding: bool,
157 parallel_config: ParallelConfig,
159 - num_tokens_padded: Optional[int] = None,
160 - uniform_decode: Optional[bool] = None,
161 - num_scheduled_tokens_per_request: Optional[np.ndarray] = None,
162 -) -> tuple[Optional[UBatchSlices], Optional[torch.Tensor]]:
158 + num_tokens_padded: int | None = None,
159 + uniform_decode: bool | None = None,
160 + num_scheduled_tokens_per_request: np.ndarray | None = None,
161 +) -> tuple[UBatchSlices | None, torch.Tensor | None]:
162 """
163 Coordinates amongst all DP ranks to determine if and how the full batch
164 should be split into microbatches.
vllm/v1/worker/gpu_input_batch.py
+22 -22
@@ -3,7 +3,7 @@
3 # Datastructures defining a GPU input batch
4
5 from dataclasses import dataclass
6 -from typing import Optional, cast
6 +from typing import cast
7
8 import numpy as np
9 import torch
@@ -29,21 +29,21 @@ from vllm.v1.worker.block_table import MultiGroupBlockTable
29 @dataclass
30 class CachedRequestState:
31 req_id: str
32 - prompt_token_ids: Optional[list[int]]
32 + prompt_token_ids: list[int] | None
33 mm_features: list[MultiModalFeatureSpec]
34 - sampling_params: Optional[SamplingParams]
35 - pooling_params: Optional[PoolingParams]
36 - generator: Optional[torch.Generator]
34 + sampling_params: SamplingParams | None
35 + pooling_params: PoolingParams | None
36 + generator: torch.Generator | None
37
38 block_ids: tuple[list[int], ...]
39 num_computed_tokens: int
40 output_token_ids: list[int]
41
42 - mrope_positions: Optional[torch.Tensor] = None
43 - mrope_position_delta: Optional[int] = None
42 + mrope_positions: torch.Tensor | None = None
43 + mrope_position_delta: int | None = None
44
45 - lora_request: Optional[LoRARequest] = None
46 - prompt_embeds: Optional[torch.Tensor] = None
45 + lora_request: LoRARequest | None = None
46 + prompt_embeds: torch.Tensor | None = None
47
48 def __post_init__(self):
49 self.num_prompt_tokens = length_from_prompt_token_ids_or_embeds(
@@ -78,7 +78,7 @@ class InputBatch:
78 vocab_size: int,
79 block_sizes: list[int], # The block_size of each kv cache group
80 kernel_block_sizes: list[int],
81 - logitsprocs: Optional[LogitsProcessors] = None,
81 + logitsprocs: LogitsProcessors | None = None,
82 logitsprocs_need_output_token_ids: bool = False,
83 is_spec_decode: bool = False,
84 is_pooling_model: bool = False,
@@ -93,7 +93,7 @@ class InputBatch:
93 self.pin_memory = pin_memory
94 self.vocab_size = vocab_size
95
96 - self._req_ids: list[Optional[str]] = []
96 + self._req_ids: list[str | None] = []
97 self.req_id_to_index: dict[str, int] = {}
98
99 # TODO(woosuk): This buffer could be too large if max_model_len is big.
@@ -228,15 +228,15 @@ class InputBatch:
228 self.has_allowed_token_ids: set[str] = set()
229 # NOTE(lufang): In the mask tensor, if the corresponding token allowed,
230 # the value is False. Since we use masked_fill_ to set -inf.
231 - self.allowed_token_ids_mask: Optional[torch.Tensor] = None
232 - self.allowed_token_ids_mask_cpu_tensor: Optional[torch.Tensor] = None
231 + self.allowed_token_ids_mask: torch.Tensor | None = None
232 + self.allowed_token_ids_mask_cpu_tensor: torch.Tensor | None = None
233
234 # req_index -> bad_words_token_ids
235 self.bad_words_token_ids: dict[int, list[list[int]]] = {}
236
237 self.logits_processing_needs_token_ids = np.zeros(max_num_reqs, dtype=bool)
238
239 - self.req_output_token_ids: list[Optional[list[int]]] = []
239 + self.req_output_token_ids: list[list[int] | None] = []
240
241 # Store provided logitsprocs. If none are provided, initialize empty
242 # data structure
@@ -244,7 +244,7 @@ class InputBatch:
244 self.logitsprocs_need_output_token_ids = logitsprocs_need_output_token_ids
245
246 # Store last speculative tokens for sampler.
247 - self.spec_token_ids: list[Optional[list[int]]] = []
247 + self.spec_token_ids: list[list[int] | None] = []
248
249 # This is updated each time the batch constituents change.
250 self.sampling_metadata = self._make_sampling_metadata()
@@ -252,13 +252,13 @@ class InputBatch:
252 self.pooling_params: dict[str, PoolingParams] = {}
253
254 # Cached reference to the GPU tensor of previously sampled tokens
255 - self.prev_sampled_token_ids: Optional[torch.Tensor] = None
256 - self.prev_req_id_to_index: Optional[dict[str, int]] = None
255 + self.prev_sampled_token_ids: torch.Tensor | None = None
256 + self.prev_req_id_to_index: dict[str, int] | None = None
257 # These are used to update output_token_ids with real sampled
258 # ids from prior step, if required by current sampling params
259 # (e.g. penalties).
260 - self.sampled_token_ids_cpu: Optional[torch.Tensor] = None
261 - self.async_copy_ready_event: Optional[torch.cuda.Event] = None
260 + self.sampled_token_ids_cpu: torch.Tensor | None = None
261 + self.async_copy_ready_event: torch.cuda.Event | None = None
262
263 @property
264 def req_ids(self) -> list[str]:
@@ -438,7 +438,7 @@ class InputBatch:
438
439 return req_index
440
441 - def remove_request(self, req_id: str) -> Optional[int]:
441 + def remove_request(self, req_id: str) -> int | None:
442 """This method must always be followed by a call to condense().
443
444 Args:
@@ -796,7 +796,7 @@ class InputBatch:
796 else []
797 )
798
799 - allowed_token_ids_mask: Optional[torch.Tensor] = None
799 + allowed_token_ids_mask: torch.Tensor | None = None
800 if not self.no_allowed_token_ids:
801 assert self.allowed_token_ids_mask is not None
802 copy_slice(
@@ -954,7 +954,7 @@ class InputBatch:
954 )
955
956 @property
957 - def max_num_logprobs(self) -> Optional[int]:
957 + def max_num_logprobs(self) -> int | None:
958 return max(self.num_logprobs.values()) if self.num_logprobs else None
959
960 @property
vllm/v1/worker/gpu_model_runner.py
+41 -42
@@ -8,14 +8,13 @@ from collections import defaultdict
8 from collections.abc import Iterator
9 from contextlib import contextmanager
10 from copy import deepcopy
11 -from typing import TYPE_CHECKING, Any, NamedTuple, Optional, Union, cast
11 +from typing import TYPE_CHECKING, Any, NamedTuple, TypeAlias, cast
12
13 import numpy as np
14 import torch
15 import torch.distributed
16 import torch.nn as nn
17 from tqdm import tqdm
18 -from typing_extensions import TypeAlias
18
19 import vllm.envs as envs
20 from vllm.attention import Attention, AttentionType
@@ -162,7 +161,7 @@ logger = init_logger(__name__)
161
162 AttnMetadataDict: TypeAlias = dict[str, AttentionMetadata]
163 # list when ubatching is enabled
165 -PerLayerAttnMetadata: TypeAlias = Union[list[AttnMetadataDict], AttnMetadataDict]
164 +PerLayerAttnMetadata: TypeAlias = list[AttnMetadataDict] | AttnMetadataDict
165
166
167 # Wrapper for ModelRunnerOutput to support overlapped execution.
@@ -295,7 +294,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
294 # Sampler
295 self.sampler = Sampler(logprobs_mode=self.model_config.logprobs_mode)
296
298 - self.eplb_state: Optional[EplbState] = None
297 + self.eplb_state: EplbState | None = None
298 """
299 State of the expert parallelism load balancer.
300
@@ -447,14 +446,14 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
446
447 # CUDA event to synchronize use of reused CPU tensors between steps
448 # when async scheduling is enabled.
450 - self.prepare_inputs_event: Optional[torch.cuda.Event] = None
449 + self.prepare_inputs_event: torch.cuda.Event | None = None
450 if self.use_async_scheduling:
451 self.prepare_inputs_event = torch.cuda.Event()
452 # Start in a completed state.
453 self.prepare_inputs_event.record(torch.cuda.default_stream())
454
455 # None in the first PP rank. The rest are set after load_model.
457 - self.intermediate_tensors: Optional[IntermediateTensors] = None
456 + self.intermediate_tensors: IntermediateTensors | None = None
457
458 # OPTIMIZATION: Cache the tensors rather than creating them every step.
459 # Keep in int64 to avoid overflow with long context
@@ -495,7 +494,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
494 else None
495 )
496
498 - self.reorder_batch_threshold: Optional[int] = None
497 + self.reorder_batch_threshold: int | None = None
498
499 # Attention layers that are only in the KVCacheConfig of the runner
500 # (e.g., KV sharing, encoder-only attention), but not in the
@@ -503,7 +502,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
502 self.runner_only_attn_layers: set[str] = set()
503
504 # Cached outputs.
506 - self._draft_token_ids: Optional[Union[list[list[int]], torch.Tensor]] = None
505 + self._draft_token_ids: list[list[int]] | torch.Tensor | None = None
506 self.transfer_event = torch.cuda.Event()
507 self.sampled_token_ids_pinned_cpu = torch.empty(
508 (self.max_model_len, 1),
@@ -527,7 +526,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
526 return self.positions.gpu[num_tokens]
527
528 def _make_buffer(
530 - self, *size: Union[int, torch.SymInt], dtype: torch.dtype, numpy: bool = True
529 + self, *size: int | torch.SymInt, dtype: torch.dtype, numpy: bool = True
530 ) -> CpuGpuBuffer:
531 return CpuGpuBuffer(
532 *size,
@@ -928,7 +927,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
927 def _get_cumsum_and_arange(
928 self,
929 num_tokens: np.ndarray,
931 - cumsum_dtype: Optional[np.dtype] = None,
930 + cumsum_dtype: np.dtype | None = None,
931 ) -> tuple[np.ndarray, np.ndarray]:
932 """Get the cumulative sum and batched arange of the given array.
933 # E.g., [2, 5, 3] -> ([2, 7, 10], [0, 1, 0, 1, 2, 3, 4, 0, 1, 2])
@@ -1024,7 +1023,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
1023 scheduler_output: "SchedulerOutput",
1024 kv_cache_spec: KVCacheSpec,
1025 num_reqs: int,
1027 - ) -> Optional[np.ndarray]:
1026 + ) -> np.ndarray | None:
1027 if not isinstance(kv_cache_spec, CrossAttentionSpec):
1028 return None
1029
@@ -1042,12 +1041,12 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
1041 ) -> tuple[
1042 PerLayerAttnMetadata,
1043 torch.Tensor,
1045 - Optional[SpecDecodeMetadata],
1044 + SpecDecodeMetadata | None,
1045 np.ndarray,
1047 - Optional[CommonAttentionMetadata],
1046 + CommonAttentionMetadata | None,
1047 int,
1049 - Optional[UBatchSlices],
1050 - Optional[torch.Tensor],
1048 + UBatchSlices | None,
1049 + torch.Tensor | None,
1050 bool,
1051 ]:
1052 """
@@ -2048,7 +2047,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2047 )
2048 self._sync_device()
2049
2051 - pooler_output: list[Optional[torch.Tensor]] = []
2050 + pooler_output: list[torch.Tensor | None] = []
2051 for raw_output, seq_len, prompt_len in zip(
2052 raw_pooler_output, seq_lens_cpu, pooling_metadata.prompt_lens
2053 ):
@@ -2091,13 +2090,13 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2090 self,
2091 scheduler_output: "SchedulerOutput",
2092 num_input_tokens: int, # Padded
2094 - intermediate_tensors: Optional[IntermediateTensors] = None,
2093 + intermediate_tensors: IntermediateTensors | None = None,
2094 ) -> tuple[
2095 int,
2097 - Optional[torch.Tensor],
2098 - Optional[torch.Tensor],
2096 + torch.Tensor | None,
2097 + torch.Tensor | None,
2098 torch.Tensor,
2100 - Optional[IntermediateTensors],
2099 + IntermediateTensors | None,
2100 dict[str, Any],
2101 ]:
2102 num_scheduled_tokens = scheduler_output.total_num_scheduled_tokens
@@ -2197,8 +2196,8 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2196
2197 def _sample(
2198 self,
2200 - logits: Optional[torch.Tensor],
2201 - spec_decode_metadata: Optional[SpecDecodeMetadata],
2199 + logits: torch.Tensor | None,
2200 + spec_decode_metadata: SpecDecodeMetadata | None,
2201 ) -> SamplerOutput:
2202 # Sample the next token and get logprobs if needed.
2203 sampling_metadata = self.input_batch.sampling_metadata
@@ -2243,14 +2242,14 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2242 self,
2243 scheduler_output: "SchedulerOutput",
2244 sampler_output: SamplerOutput,
2246 - logits: Optional[torch.Tensor],
2245 + logits: torch.Tensor | None,
2246 hidden_states: torch.Tensor,
2247 num_scheduled_tokens: int,
2248 ) -> tuple[
2249 dict[str, int],
2251 - Optional[LogprobsLists],
2250 + LogprobsLists | None,
2251 list[list[int]],
2253 - dict[str, Optional[LogprobsTensors]],
2252 + dict[str, LogprobsTensors | None],
2253 list[str],
2254 dict[str, int],
2255 list[int],
@@ -2377,10 +2376,10 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2376
2377 def _model_forward(
2378 self,
2380 - input_ids: Optional[torch.Tensor] = None,
2381 - positions: Optional[torch.Tensor] = None,
2382 - intermediate_tensors: Optional[IntermediateTensors] = None,
2383 - inputs_embeds: Optional[torch.Tensor] = None,
2379 + input_ids: torch.Tensor | None = None,
2380 + positions: torch.Tensor | None = None,
2381 + intermediate_tensors: IntermediateTensors | None = None,
2382 + inputs_embeds: torch.Tensor | None = None,
2383 **model_kwargs: dict[str, Any],
2384 ) -> Any:
2385 """Helper method to call the model forward pass.
@@ -2411,8 +2410,8 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2410 def execute_model(
2411 self,
2412 scheduler_output: "SchedulerOutput",
2414 - intermediate_tensors: Optional[IntermediateTensors] = None,
2415 - ) -> Union[ModelRunnerOutput, AsyncModelRunnerOutput, IntermediateTensors]:
2413 + intermediate_tensors: IntermediateTensors | None = None,
2414 + ) -> ModelRunnerOutput | AsyncModelRunnerOutput | IntermediateTensors:
2415 with record_function_or_nullcontext("Preprocess"):
2416 with self.synchronize_input_prep():
2417 # Update persistent batch states.
@@ -2678,7 +2677,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2677
2678 return async_output
2679
2681 - def take_draft_token_ids(self) -> Optional[DraftTokenIds]:
2680 + def take_draft_token_ids(self) -> DraftTokenIds | None:
2681 if self._draft_token_ids is None:
2682 return None
2683 req_ids = self.input_batch.req_ids
@@ -2692,14 +2691,14 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2691 def propose_draft_token_ids(
2692 self,
2693 scheduler_output: "SchedulerOutput",
2695 - sampled_token_ids: Union[torch.Tensor, list[list[int]]],
2694 + sampled_token_ids: torch.Tensor | list[list[int]],
2695 sampling_metadata: SamplingMetadata,
2696 hidden_states: torch.Tensor,
2697 sample_hidden_states: torch.Tensor,
2699 - aux_hidden_states: Optional[list[torch.Tensor]],
2700 - spec_decode_metadata: Optional[SpecDecodeMetadata],
2698 + aux_hidden_states: list[torch.Tensor] | None,
2699 + spec_decode_metadata: SpecDecodeMetadata | None,
2700 common_attn_metadata: CommonAttentionMetadata,
2702 - ) -> Union[list[list[int]], torch.Tensor]:
2701 + ) -> list[list[int]] | torch.Tensor:
2702 num_scheduled_tokens = scheduler_output.total_num_scheduled_tokens
2703 if self.speculative_config.method == "ngram":
2704 assert isinstance(sampled_token_ids, list)
@@ -2961,7 +2960,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
2960 self.model, self.vllm_config, CUDAGraphMode.NONE, self.device
2961 )
2962
2964 - def _get_eagle3_aux_layers_from_config(self) -> Optional[tuple[int, ...]]:
2963 + def _get_eagle3_aux_layers_from_config(self) -> tuple[int, ...] | None:
2964 """Extract Eagle3 auxiliary layer indices from speculative config.
2965
2966 These indices specify which hidden states from the base model should
@@ -3007,13 +3006,13 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
3006 self,
3007 hidden_states: torch.Tensor,
3008 num_scheduled_tokens: dict[str, int],
3010 - ) -> dict[str, Optional[LogprobsTensors]]:
3009 + ) -> dict[str, LogprobsTensors | None]:
3010 num_prompt_logprobs_dict = self.input_batch.num_prompt_logprobs
3011 if not num_prompt_logprobs_dict:
3012 return {}
3013
3014 in_progress_dict = self.input_batch.in_progress_prompt_logprobs_cpu
3016 - prompt_logprobs_dict: dict[str, Optional[LogprobsTensors]] = {}
3015 + prompt_logprobs_dict: dict[str, LogprobsTensors | None] = {}
3016
3017 # Since prompt logprobs are a rare feature, prioritize simple,
3018 # maintainable loop over optimal performance.
@@ -3107,7 +3106,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
3106
3107 def _get_nans_in_logits(
3108 self,
3110 - logits: Optional[torch.Tensor],
3109 + logits: torch.Tensor | None,
3110 ) -> dict[str, int]:
3111 try:
3112 if logits is None:
@@ -3190,7 +3189,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
3189 def _dummy_run(
3190 self,
3191 num_tokens: int,
3193 - cudagraph_runtime_mode: Optional[CUDAGraphMode] = None,
3192 + cudagraph_runtime_mode: CUDAGraphMode | None = None,
3193 force_attention: bool = False,
3194 uniform_decode: bool = False,
3195 allow_microbatching: bool = True,
@@ -3294,7 +3293,7 @@ class GPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
3293 dp_rank = self.parallel_config.data_parallel_rank
3294 num_tokens_after_padding = int(num_tokens_across_dp[dp_rank])
3295
3297 - attn_metadata: Optional[PerLayerAttnMetadata] = None
3296 + attn_metadata: PerLayerAttnMetadata | None = None
3297
3298 # If force_attention is True, we always capture attention. Otherwise,
3299 # it only happens for cudagraph_runtime_mode=FULL.
vllm/v1/worker/gpu_ubatch_wrapper.py
+5 -4
@@ -2,8 +2,9 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import threading
5 +from collections.abc import Callable
6 from dataclasses import dataclass
6 -from typing import Any, Callable, Optional
7 +from typing import Any
8
9 import torch
10
@@ -32,8 +33,8 @@ class UbatchMetadata:
33 context: UBatchContext
34 input_ids: torch.Tensor
35 positions: torch.Tensor
35 - inputs_embeds: Optional[torch.Tensor]
36 - intermediate_tensors: Optional[IntermediateTensors]
36 + inputs_embeds: torch.Tensor | None
37 + intermediate_tensors: IntermediateTensors | None
38 num_tokens: int
39
40
@@ -41,7 +42,7 @@ class UbatchMetadata:
42 class CUDAGraphMetaData:
43 cudagraph: torch.cuda.CUDAGraph
44 ubatch_metadata: UbatchMetadata
44 - outputs: Optional[Any] = None
45 + outputs: Any | None = None
46
47
48 class SMControlContextManager:
vllm/v1/worker/gpu_worker.py
+9 -9
@@ -6,7 +6,7 @@ import copy
6 import gc
7 import os
8 from contextlib import AbstractContextManager, nullcontext
9 -from typing import TYPE_CHECKING, Any, Optional, Union
9 +from typing import TYPE_CHECKING, Any
10
11 import torch
12 import torch.distributed
@@ -132,7 +132,7 @@ class Worker(WorkerBase):
132 used_bytes / GiB_bytes,
133 )
134
135 - def wake_up(self, tags: Optional[list[str]] = None) -> None:
135 + def wake_up(self, tags: list[str] | None = None) -> None:
136 from vllm.device_allocator.cumem import CuMemAllocator
137
138 allocator = CuMemAllocator.get_instance()
@@ -456,7 +456,7 @@ class Worker(WorkerBase):
456 def execute_model(
457 self,
458 scheduler_output: "SchedulerOutput",
459 - ) -> Optional[Union[ModelRunnerOutput, AsyncModelRunnerOutput]]:
459 + ) -> ModelRunnerOutput | AsyncModelRunnerOutput | None:
460 intermediate_tensors = None
461 forward_pass = scheduler_output.total_num_scheduled_tokens > 0
462 num_scheduled_tokens = scheduler_output.total_num_scheduled_tokens
@@ -504,7 +504,7 @@ class Worker(WorkerBase):
504 output.kv_connector_output = kv_connector_output
505 return output
506
507 - def take_draft_token_ids(self) -> Optional[DraftTokenIds]:
507 + def take_draft_token_ids(self) -> DraftTokenIds | None:
508 return self.model_runner.take_draft_token_ids()
509
510 def profile(self, is_start: bool = True):
@@ -565,7 +565,7 @@ class Worker(WorkerBase):
565 self,
566 old_ep_size: int,
567 new_ep_size: int,
568 - global_expert_load: Optional[torch.Tensor],
568 + global_expert_load: torch.Tensor | None,
569 ) -> None:
570 from vllm.distributed.parallel_state import get_ep_group
571
@@ -611,7 +611,7 @@ class Worker(WorkerBase):
611
612 def _reconfigure_moe(
613 self, old_ep_size: int, new_ep_size: int
614 - ) -> Optional[torch.Tensor]:
614 + ) -> torch.Tensor | None:
615 """
616 Reconfigure MoE modules with provided reconfig_request
617
@@ -730,8 +730,8 @@ class Worker(WorkerBase):
730 def save_sharded_state(
731 self,
732 path: str,
733 - pattern: Optional[str] = None,
734 - max_size: Optional[int] = None,
733 + pattern: str | None = None,
734 + max_size: int | None = None,
735 ) -> None:
736 from vllm.model_executor.model_loader import ShardedStateLoader
737
@@ -758,7 +758,7 @@ class Worker(WorkerBase):
758 def init_worker_distributed_environment(
759 vllm_config: VllmConfig,
760 rank: int,
761 - distributed_init_method: Optional[str] = None,
761 + distributed_init_method: str | None = None,
762 local_rank: int = -1,
763 backend: str = "nccl",
764 ) -> None:
vllm/v1/worker/kv_connector_model_runner_mixin.py
+3 -4
@@ -9,7 +9,6 @@ from collections.abc import Generator
9 from contextlib import AbstractContextManager, contextmanager, nullcontext
10 from typing import (
11 TYPE_CHECKING, # noqa: UP035
12 - Optional,
12 )
13
14 from vllm.config import VllmConfig
@@ -65,7 +64,7 @@ class KVConnectorModelRunnerMixin:
64 @staticmethod
65 def get_finished_kv_transfers(
66 scheduler_output: "SchedulerOutput",
68 - ) -> tuple[Optional[set[str]], Optional[set[str]]]:
67 + ) -> tuple[set[str] | None, set[str] | None]:
68 if has_kv_transfer_group():
69 return get_kv_transfer_group().get_finished(
70 scheduler_output.finished_req_ids
@@ -95,7 +94,7 @@ class KVConnectorModelRunnerMixin:
94 @staticmethod
95 def maybe_get_kv_connector_output(
96 scheduler_output: "SchedulerOutput",
98 - ) -> AbstractContextManager[Optional[KVConnectorOutput]]:
97 + ) -> AbstractContextManager[KVConnectorOutput | None]:
98 return (
99 KVConnectorModelRunnerMixin._get_kv_connector_output(scheduler_output)
100 if has_kv_transfer_group()
@@ -139,7 +138,7 @@ class KVConnectorModelRunnerMixin:
138 kv_connector.clear_connector_metadata()
139
140 @staticmethod
142 - def get_kv_connector_stats() -> Optional[KVConnectorStats]:
141 + def get_kv_connector_stats() -> KVConnectorStats | None:
142 if has_kv_transfer_group():
143 return get_kv_transfer_group().get_kv_connector_stats()
144 return None
vllm/v1/worker/lora_model_runner_mixin.py
+5 -6
@@ -5,7 +5,6 @@ Define LoRA functionality mixin for model runners.
5 """
6
7 from contextlib import contextmanager
8 -from typing import Optional, Union
8
9 import numpy as np
10 import torch
@@ -21,7 +20,7 @@ from vllm.model_executor.models import supports_lora, supports_multimodal
20 from vllm.v1.worker.gpu_input_batch import InputBatch as GPUInputBatch
21 from vllm.v1.worker.tpu_input_batch import InputBatch as TPUInputBatch
22
24 -InputBatch = Union[TPUInputBatch, GPUInputBatch]
23 +InputBatch = TPUInputBatch | GPUInputBatch
24
25 logger = init_logger(__name__)
26
@@ -85,7 +84,7 @@ class LoRAModelRunnerMixin:
84
85 @contextmanager
86 def maybe_setup_dummy_loras(
88 - self, lora_config: Optional[LoRAConfig], remove_lora: bool = True
87 + self, lora_config: LoRAConfig | None, remove_lora: bool = True
88 ):
89 if lora_config is None:
90 yield
@@ -121,7 +120,7 @@ class LoRAModelRunnerMixin:
120
121 @contextmanager
122 def maybe_select_dummy_loras(
124 - self, lora_config: Optional[LoRAConfig], num_scheduled_tokens: np.ndarray
123 + self, lora_config: LoRAConfig | None, num_scheduled_tokens: np.ndarray
124 ):
125 if lora_config is None:
126 yield
@@ -158,7 +157,7 @@ class LoRAModelRunnerMixin:
157 @contextmanager
158 def maybe_dummy_run_with_lora(
159 self,
161 - lora_config: Optional[LoRAConfig],
160 + lora_config: LoRAConfig | None,
161 num_scheduled_tokens: np.ndarray,
162 remove_lora: bool = True,
163 ):
@@ -168,7 +167,7 @@ class LoRAModelRunnerMixin:
167 ):
168 yield
169
171 - def maybe_remove_all_loras(self, lora_config: Optional[LoRAConfig]):
170 + def maybe_remove_all_loras(self, lora_config: LoRAConfig | None):
171 if lora_config is None:
172 return
173 self.lora_manager.remove_all_adapters()
vllm/v1/worker/tpu_input_batch.py
+9 -9
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 # Datastructures defining a TPU input batch
4
5 -from typing import Optional, cast
5 +from typing import cast
6
7 import numpy as np
8 import torch
@@ -36,7 +36,7 @@ class InputBatch:
36 self.pin_memory = pin_memory
37 self.vocab_size = vocab_size
38
39 - self._req_ids: list[Optional[str]] = []
39 + self._req_ids: list[str | None] = []
40 self.req_id_to_index: dict[str, int] = {}
41
42 # TODO(woosuk): This buffer could be too large if max_model_len is big.
@@ -155,17 +155,17 @@ class InputBatch:
155 # To accumulate prompt logprobs tensor chunks across prefill steps.
156 self.in_progress_prompt_logprobs_cpu: dict[str, LogprobsTensors] = {}
157
158 - self.logit_bias: list[Optional[dict[int, float]]] = [None] * max_num_reqs
158 + self.logit_bias: list[dict[int, float] | None] = [None] * max_num_reqs
159 self.has_allowed_token_ids: set[str] = set()
160 # NOTE(lufang): In the mask tensor, if the corresponding token allowed,
161 # the value is False. Since we use masked_fill_ to set -inf.
162 - self.allowed_token_ids_mask: Optional[torch.Tensor] = None
163 - self.allowed_token_ids_mask_cpu_tensor: Optional[torch.Tensor] = None
162 + self.allowed_token_ids_mask: torch.Tensor | None = None
163 + self.allowed_token_ids_mask_cpu_tensor: torch.Tensor | None = None
164
165 # req_index -> bad_words_token_ids
166 self.bad_words_token_ids: dict[int, list[list[int]]] = {}
167
168 - self.req_output_token_ids: list[Optional[list[int]]] = []
168 + self.req_output_token_ids: list[list[int] | None] = []
169
170 @property
171 def req_ids(self) -> list[str]:
@@ -176,7 +176,7 @@ class InputBatch:
176 def add_request(
177 self,
178 request: "CachedRequestState",
179 - req_index: Optional[int] = None,
179 + req_index: int | None = None,
180 ) -> None:
181 if req_index is None:
182 req_index = self.num_reqs
@@ -296,7 +296,7 @@ class InputBatch:
296 # No LoRA
297 self.request_lora_mapping[req_index] = 0
298
299 - def remove_request(self, req_id: str) -> Optional[int]:
299 + def remove_request(self, req_id: str) -> int | None:
300 """This method must always be followed by a call to condense()."""
301
302 req_index = self.req_id_to_index.pop(req_id, None)
@@ -580,7 +580,7 @@ class InputBatch:
580 )
581
582 @property
583 - def max_num_logprobs(self) -> Optional[int]:
583 + def max_num_logprobs(self) -> int | None:
584 return max(self.num_logprobs.values()) if self.num_logprobs else None
585
586 @property
vllm/v1/worker/tpu_model_runner.py
+7 -7
@@ -3,7 +3,7 @@
3 import bisect
4 import gc
5 import time
6 -from typing import TYPE_CHECKING, Any, Optional, cast
6 +from typing import TYPE_CHECKING, Any, cast
7 from unittest.mock import patch
8
9 import numpy as np
@@ -140,7 +140,7 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
140 self,
141 vllm_config: VllmConfig,
142 device: torch.device,
143 - original_parallel_config: Optional[ParallelConfig] = None,
143 + original_parallel_config: ParallelConfig | None = None,
144 ):
145 self.vllm_config = vllm_config
146 self.model_config = vllm_config.model_config
@@ -1050,7 +1050,7 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
1050 def _get_model_inputs(
1051 self,
1052 input_ids: torch.Tensor,
1053 - mm_embed_inputs: Optional[tuple[list[torch.Tensor], torch.Tensor]],
1053 + mm_embed_inputs: tuple[list[torch.Tensor], torch.Tensor] | None,
1054 ):
1055 if self.supports_mm_inputs:
1056 mm_embeds, is_mm_embed = mm_embed_inputs or (None, None)
@@ -1076,7 +1076,7 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
1076 def execute_model(
1077 self,
1078 scheduler_output: "SchedulerOutput",
1079 - intermediate_tensors: Optional[IntermediateTensors] = None,
1079 + intermediate_tensors: IntermediateTensors | None = None,
1080 ) -> ModelRunnerOutput:
1081 # Update cached state
1082 self._update_states(scheduler_output)
@@ -1220,7 +1220,7 @@ class TPUModelRunner(LoRAModelRunnerMixin, KVConnectorModelRunnerMixin):
1220 ), "req_ids contains None"
1221 req_ids = cast(list[str], self.input_batch.req_ids[:num_reqs])
1222
1223 - prompt_logprobs_dict: dict[str, Optional[LogprobsTensors]] = {}
1223 + prompt_logprobs_dict: dict[str, LogprobsTensors | None] = {}
1224 for req_id in self.input_batch.req_ids[:num_reqs]:
1225 prompt_logprobs_dict[req_id] = None
1226
@@ -2127,8 +2127,8 @@ def replace_set_lora(model):
2127 index: int,
2128 lora_a: torch.Tensor,
2129 lora_b: torch.Tensor,
2130 - embeddings_tensor: Optional[torch.Tensor],
2131 - bias: Optional[torch.Tensor] = None,
2130 + embeddings_tensor: torch.Tensor | None,
2131 + bias: torch.Tensor | None = None,
2132 ):
2133 # TODO: The integer index leads to a recompilation, but converting it
2134 # to a tensor doesn't seem to work anymore. This might be fixed with a
vllm/v1/worker/tpu_worker.py
+4 -3
@@ -3,7 +3,8 @@
3 """A TPU worker class."""
4
5 import os
6 -from typing import Any, Callable, Optional, TypeVar
6 +from collections.abc import Callable
7 +from typing import Any, TypeVar
8
9 import torch
10 import torch.distributed
@@ -257,7 +258,7 @@ class TPUWorker:
258 def execute_model(
259 self,
260 scheduler_output: "SchedulerOutput",
260 - ) -> Optional[ModelRunnerOutput]:
261 + ) -> ModelRunnerOutput | None:
262 output = self.model_runner.execute_model(scheduler_output)
263 # every worker's output is needed when kv_transfer_group is set up
264 return output if self.is_driver_worker or has_kv_transfer_group() else None
@@ -317,7 +318,7 @@ class TPUWorker:
318 self,
319 vllm_config: VllmConfig,
320 rank: int,
320 - distributed_init_method: Optional[str] = None,
321 + distributed_init_method: str | None = None,
322 local_rank: int = -1,
323 ) -> None:
324 """Initialize the distributed environment."""
vllm/v1/worker/ubatch_utils.py
+1 -1
@@ -1,9 +1,9 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass
4 +from typing import TypeAlias
5
6 import numpy as np
6 -from typing_extensions import TypeAlias
7
8 from vllm.config import ParallelConfig
9
vllm/v1/worker/utils.py
+5 -5
@@ -2,7 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections import defaultdict
4 from dataclasses import dataclass
5 -from typing import TYPE_CHECKING, Optional
5 +from typing import TYPE_CHECKING
6
7 import torch
8
@@ -193,7 +193,7 @@ def sanity_check_mm_encoder_outputs(
193
194 def scatter_mm_placeholders(
195 embeds: torch.Tensor,
196 - is_embed: Optional[torch.Tensor],
196 + is_embed: torch.Tensor | None,
197 ) -> torch.Tensor:
198 """
199 Scatter the multimodal embeddings into a contiguous tensor that represents
@@ -221,7 +221,7 @@ def scatter_mm_placeholders(
221
222 def gather_mm_placeholders(
223 placeholders: torch.Tensor,
224 - is_embed: Optional[torch.Tensor],
224 + is_embed: torch.Tensor | None,
225 ) -> torch.Tensor:
226 """
227 Reconstructs the embeddings from the placeholder tokens.
@@ -238,7 +238,7 @@ def gather_mm_placeholders(
238 def add_kv_sharing_layers_to_kv_cache_groups(
239 shared_kv_cache_layers: dict[str, str],
240 kv_cache_groups: list[KVCacheGroupSpec],
241 - runner_only_attn_layers: Optional[set[str]] = None,
241 + runner_only_attn_layers: set[str] | None = None,
242 ) -> None:
243 """
244 Sets up KV cache sharing by reusing the allocated KV caches in `kv_caches`
@@ -270,7 +270,7 @@ def bind_kv_cache(
270 kv_caches: dict[str, torch.Tensor],
271 forward_context: dict[str, "Attention"],
272 runner_kv_caches: list[torch.Tensor],
273 - num_attn_module: Optional[int] = 1,
273 + num_attn_module: int | None = 1,
274 ) -> None:
275 """
276 Bind the allocated KV cache to both ModelRunner and forward context so
vllm/v1/worker/worker_base.py
+6 -4
@@ -1,10 +1,9 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 -from __future__ import annotations
5 -
4 import os
7 -from typing import TYPE_CHECKING, Any, Callable, TypeVar, Union
5 +from collections.abc import Callable
6 +from typing import TYPE_CHECKING, Any, TypeVar
7
8 import torch
9 import torch.nn as nn
@@ -26,6 +25,9 @@ from vllm.v1.kv_cache_interface import KVCacheSpec
25 if TYPE_CHECKING:
26 from vllm.v1.core.sched.output import SchedulerOutput
27 from vllm.v1.outputs import ModelRunnerOutput
28 +else:
29 + SchedulerOutput = object
30 + ModelRunnerOutput = object
31
32 logger = init_logger(__name__)
33
@@ -329,7 +331,7 @@ class WorkerWrapperBase:
331 # To make vLLM config available during device initialization
332 self.worker.init_device() # type: ignore
333
332 - def execute_method(self, method: Union[str, bytes], *args, **kwargs):
334 + def execute_method(self, method: str | bytes, *args, **kwargs):
335 try:
336 # method resolution order:
337 # if a method is defined in this class, it will be called directly.