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 10, 15:15 UTC
[Misc][BE] Type coverage for vllm/compilation [1/3] (#31554)
Signed-off-by: Lucas Kabela <lucaskabela@meta.com>
Lucas Kabela committed
Jan 6, 2026 at 17:37 UTC
873480d133f3e32743a0e187b03da1e67635bdc2
12 files changed
+103
-85
vllm/compilation/backends.py
+13
-13
@@ -9,7 +9,7 @@ import operator
9
import os
10
import pprint
11
import time
12
-from collections.abc import Callable, Sequence
12
+from collections.abc import Callable, Generator, Sequence
13
from contextlib import contextmanager
14
from copy import deepcopy
15
from functools import partial
@@ -90,7 +90,7 @@ class CompilerManager:
90
support int as key.
91
"""
92
93
- def __init__(self, compilation_config: CompilationConfig):
93
+ def __init__(self, compilation_config: CompilationConfig) -> None:
94
self.cache: dict[tuple[Range, int, str], Any] = dict()
95
self.is_cache_updated = False
96
self.compilation_config = compilation_config
@@ -100,7 +100,7 @@ class CompilerManager:
100
return self.compiler.compute_hash(vllm_config)
101
102
@contextmanager
103
- def compile_context(self, compile_range: Range):
103
+ def compile_context(self, compile_range: Range) -> Generator[None, None, None]:
104
"""Provide compilation context for the duration of compilation to set
105
any torch global properties we want to scope to a single Inductor
106
compilation (e.g. partition rules, pass context)."""
@@ -115,7 +115,7 @@ class CompilerManager:
115
116
def initialize_cache(
117
self, cache_dir: str, disable_cache: bool = False, prefix: str = ""
118
- ):
118
+ ) -> None:
119
"""
120
Initialize the cache directory for the compiler.
121
@@ -143,7 +143,7 @@ class CompilerManager:
143
# do not use eval(), it is unsafe.
144
cache = ast.literal_eval(f.read())
145
146
- def check_type(value, ty):
146
+ def check_type(value: Any, ty: type) -> None:
147
if not isinstance(value, ty):
148
raise TypeError(f"Expected {ty} but got {type(value)} for {value}")
149
@@ -165,7 +165,7 @@ class CompilerManager:
165
cache_dir=cache_dir, disable_cache=disable_cache, prefix=prefix
166
)
167
168
- def save_to_file(self):
168
+ def save_to_file(self) -> None:
169
if self.disable_cache or not self.is_cache_updated:
170
return
171
printer = pprint.PrettyPrinter(indent=4)
@@ -198,7 +198,7 @@ class CompilerManager:
198
def compile(
199
self,
200
graph: fx.GraphModule,
201
- example_inputs,
201
+ example_inputs: list[Any],
202
additional_inductor_config,
203
compilation_config: CompilationConfig,
204
compile_range: Range,
@@ -373,7 +373,7 @@ class PiecewiseCompileInterpreter(torch.fx.Interpreter):
373
compile_submod_names: list[str],
374
vllm_config: VllmConfig,
375
vllm_backend: "VllmBackend",
376
- ):
376
+ ) -> None:
377
super().__init__(module)
378
from torch._guards import detect_fake_mode
379
@@ -385,7 +385,7 @@ class PiecewiseCompileInterpreter(torch.fx.Interpreter):
385
# When True, it annoyingly dumps the torch.fx.Graph on errors.
386
self.extra_traceback = False
387
388
- def run(self, *args):
388
+ def run(self, *args: Any) -> Any:
389
# maybe instead just assert inputs are fake?
390
fake_args = [
391
self.fake_mode.from_tensor(t) if isinstance(t, torch.Tensor) else t
@@ -467,7 +467,7 @@ model_is_encoder: bool = False
467
468
469
@contextmanager
470
-def set_model_tag(tag: str, is_encoder: bool = False):
470
+def set_model_tag(tag: str, is_encoder: bool = False) -> Generator[None, None, None]:
471
"""Context manager to set the model tag."""
472
global model_tag
473
global model_is_encoder
@@ -521,7 +521,7 @@ class VllmBackend:
521
vllm_config: VllmConfig,
522
prefix: str = "",
523
is_encoder: bool = False,
524
- ):
524
+ ) -> None:
525
# if the model is initialized with a non-empty prefix,
526
# then usually it's enough to use that prefix,
527
# e.g. language_model, vision_model, etc.
@@ -558,7 +558,7 @@ class VllmBackend:
558
# `torch.compile` is JIT compiled, so we don't need to
559
# do anything here
560
561
- def configure_post_pass(self):
561
+ def configure_post_pass(self) -> None:
562
self.pass_manager.configure(self.vllm_config)
563
564
# Post-grad custom passes are run using the post_grad_custom_post_pass
@@ -580,7 +580,7 @@ class VllmBackend:
580
self.inductor_config[self.pass_key] = self.pass_manager
581
582
def __call__(
583
- self, graph: fx.GraphModule, example_inputs
583
+ self, graph: fx.GraphModule, example_inputs: Sequence[Any]
584
) -> VllmSerializableFunction:
585
vllm_config = self.vllm_config
586
# Minimal hashing here with existing utilities, reused below.
vllm/compilation/collective_fusion.py
+7
-7
@@ -50,7 +50,7 @@ if hasattr(torch.ops._C, "scaled_fp4_quant"):
50
51
52
class BasePattern:
53
- def __init__(self, dtype: torch.dtype, device: str):
53
+ def __init__(self, dtype: torch.dtype, device: str | None) -> None:
54
self.dtype = dtype
55
self.device = device
56
self.tp = get_tp_group()
@@ -637,7 +637,7 @@ class AllReduceRMSNormPattern(BasePattern):
637
self,
638
epsilon: float,
639
dtype: torch.dtype,
640
- device: str,
640
+ device: str | None,
641
allreduce_params: FlashInferFusedAllReduceParams,
642
):
643
super().__init__(dtype, device)
@@ -692,7 +692,7 @@ class AllReduceFusedAddRMSNormPattern(BasePattern):
692
self,
693
epsilon: float,
694
dtype: torch.dtype,
695
- device: str,
695
+ device: str | None,
696
allreduce_params: FlashInferFusedAllReduceParams,
697
):
698
super().__init__(dtype, device)
@@ -759,7 +759,7 @@ class AllReduceFusedRMSNormStaticQuantFP8Pattern(BasePattern):
759
self,
760
epsilon: float,
761
dtype: torch.dtype,
762
- device: str,
762
+ device: str | None,
763
allreduce_params: FlashInferFusedAllReduceParams,
764
):
765
super().__init__(dtype, device)
@@ -828,7 +828,7 @@ class AllReduceFusedAddRMSNormStaticQuantFP8Pattern(BasePattern):
828
self,
829
epsilon: float,
830
dtype: torch.dtype,
831
- device: str,
831
+ device: str | None,
832
allreduce_params: FlashInferFusedAllReduceParams,
833
):
834
super().__init__(dtype, device)
@@ -902,7 +902,7 @@ class AllReduceFusedRMSNormStaticQuantNVFP4Pattern(BasePattern):
902
self,
903
epsilon: float,
904
dtype: torch.dtype,
905
- device: str,
905
+ device: str | None,
906
allreduce_params: FlashInferFusedAllReduceParams,
907
):
908
super().__init__(dtype, device)
@@ -988,7 +988,7 @@ class AllReduceFusedAddRMSNormStaticQuantNVFP4Pattern(BasePattern):
988
self,
989
epsilon: float,
990
dtype: torch.dtype,
991
- device: str,
991
+ device: str | None,
992
allreduce_params: FlashInferFusedAllReduceParams,
993
):
994
super().__init__(dtype, device)
vllm/compilation/compiler_interface.py
+24
-24
@@ -31,7 +31,7 @@ class CompilerInterface:
31
32
def initialize_cache(
33
self, cache_dir: str, disable_cache: bool = False, prefix: str = ""
34
- ):
34
+ ) -> None:
35
"""
36
when the vLLM process uses `cache_dir` as the cache directory,
37
the compiler should initialize itself with the cache directory,
@@ -66,7 +66,7 @@ class CompilerInterface:
66
compiler_config: dict[str, Any],
67
compile_range: Range,
68
key: str | None = None,
69
- ) -> tuple[Callable | None, Any | None]:
69
+ ) -> tuple[Callable[..., Any] | None, Any | None]:
70
"""
71
Compile the graph with the given example inputs and compiler config,
72
with a range. The `compile_range` specifies the range of the inputs,
@@ -100,7 +100,7 @@ class CompilerInterface:
100
example_inputs: list[Any],
101
graph_index: int,
102
compile_range: Range,
103
- ) -> Callable:
103
+ ) -> Callable[..., Any]:
104
"""
105
Load the compiled function from the handle.
106
Raises an error if the handle is invalid.
@@ -138,13 +138,13 @@ class AlwaysHitShapeEnv:
138
def __init__(self) -> None:
139
self.guards: list[Any] = []
140
141
- def evaluate_guards_expression(self, *args, **kwargs):
141
+ def evaluate_guards_expression(self, *args: Any, **kwargs: Any) -> Literal[True]:
142
return True
143
144
- def get_pruned_guards(self, *args, **kwargs):
144
+ def get_pruned_guards(self, *args: Any, **kwargs: Any) -> list[Any]:
145
return []
146
147
- def produce_guards_expression(self, *args, **kwargs):
147
+ def produce_guards_expression(self, *args: Any, **kwargs: Any) -> Literal[""]:
148
return ""
149
150
@@ -193,7 +193,7 @@ class InductorStandaloneAdaptor(CompilerInterface):
193
194
name = "inductor_standalone"
195
196
- def __init__(self, save_format: Literal["binary", "unpacked"]):
196
+ def __init__(self, save_format: Literal["binary", "unpacked"]) -> None:
197
self.save_format = save_format
198
199
def compute_hash(self, vllm_config: VllmConfig) -> str:
@@ -205,7 +205,7 @@ class InductorStandaloneAdaptor(CompilerInterface):
205
206
def initialize_cache(
207
self, cache_dir: str, disable_cache: bool = False, prefix: str = ""
208
- ):
208
+ ) -> None:
209
self.cache_dir = cache_dir
210
211
def compile(
@@ -215,7 +215,7 @@ class InductorStandaloneAdaptor(CompilerInterface):
215
compiler_config: dict[str, Any],
216
compile_range: Range,
217
key: str | None = None,
218
- ) -> tuple[Callable | None, Any | None]:
218
+ ) -> tuple[Callable[..., Any] | None, Any | None]:
219
compilation_counter.num_inductor_compiles += 1
220
current_config = {}
221
if compiler_config is not None:
@@ -252,7 +252,7 @@ class InductorStandaloneAdaptor(CompilerInterface):
252
example_inputs: list[Any],
253
graph_index: int,
254
compile_range: Range,
255
- ) -> Callable:
255
+ ) -> Callable[..., Any]:
256
assert isinstance(handle, tuple)
257
assert isinstance(handle[0], str)
258
assert isinstance(handle[1], str)
@@ -264,7 +264,7 @@ class InductorStandaloneAdaptor(CompilerInterface):
264
265
returns_tuple = graph_returns_tuple(graph)
266
267
- def compiled_graph_wrapper(*args):
267
+ def compiled_graph_wrapper(*args: Any) -> tuple[Any, ...] | Any:
268
graph_output = inductor_compiled_graph(*args)
269
# unpack the tuple if needed
270
# TODO(rzou): the implication is that we're not
@@ -293,7 +293,7 @@ class InductorAdaptor(CompilerInterface):
293
294
def initialize_cache(
295
self, cache_dir: str, disable_cache: bool = False, prefix: str = ""
296
- ):
296
+ ) -> None:
297
self.cache_dir = cache_dir
298
self.prefix = prefix
299
self.base_cache_dir = cache_dir[: -len(prefix)] if prefix else cache_dir
@@ -317,7 +317,7 @@ class InductorAdaptor(CompilerInterface):
317
compiler_config: dict[str, Any],
318
compile_range: Range,
319
key: str | None = None,
320
- ) -> tuple[Callable | None, Any | None]:
320
+ ) -> tuple[Callable[..., Any] | None, Any | None]:
321
compilation_counter.num_inductor_compiles += 1
322
from torch._inductor.compile_fx import compile_fx
323
@@ -348,7 +348,7 @@ class InductorAdaptor(CompilerInterface):
348
original_load = FxGraphCache.load
349
original_load_name = "torch._inductor.codecache.FxGraphCache.load"
350
351
- def hijack_load(*args, **kwargs):
351
+ def hijack_load(*args: Any, **kwargs: Any) -> Any:
352
inductor_compiled_graph = original_load(*args, **kwargs)
353
nonlocal file_path
354
compiled_fn = inductor_compiled_graph.current_callable
@@ -375,7 +375,7 @@ class InductorAdaptor(CompilerInterface):
375
# function renamed in 2.6
376
original_load_name = None
377
378
- def hijacked_compile_fx_inner(*args, **kwargs):
378
+ def hijacked_compile_fx_inner(*args: Any, **kwargs: Any) -> Any:
379
output = torch._inductor.compile_fx.compile_fx_inner(*args, **kwargs)
380
nonlocal hash_str
381
inductor_compiled_graph = output
@@ -401,13 +401,13 @@ class InductorAdaptor(CompilerInterface):
401
hash_str = inductor_compiled_graph._fx_graph_cache_key
402
return output
403
404
- def hijack_compiled_fx_graph_hash(*args, **kwargs):
404
+ def hijack_compiled_fx_graph_hash(*args: Any, **kwargs: Any) -> Any:
405
out = compiled_fx_graph_hash(*args, **kwargs)
406
nonlocal hash_str
407
hash_str = out[0]
408
return out
409
410
- def _check_can_cache(*args, **kwargs):
410
+ def _check_can_cache(*args: Any, **kwargs: Any) -> None:
411
# no error means it can be cached.
412
# Inductor refuses to cache the graph outside of Dynamo
413
# tracing context, and also disables caching for graphs
@@ -513,7 +513,7 @@ class InductorAdaptor(CompilerInterface):
513
example_inputs: list[Any],
514
graph_index: int,
515
compile_range: Range,
516
- ) -> Callable:
516
+ ) -> Callable[..., Any]:
517
assert isinstance(handle, tuple)
518
assert isinstance(handle[0], str)
519
assert isinstance(handle[1], str)
@@ -572,7 +572,7 @@ class InductorAdaptor(CompilerInterface):
572
returns_tuple = graph_returns_tuple(graph)
573
574
# this is the callable we return to Dynamo to run
575
- def compiled_graph(*args):
575
+ def compiled_graph(*args: Any) -> tuple[Any, ...] | Any:
576
# convert args to list
577
list_args = list(args)
578
graph_output = inductor_compiled_graph(list_args)
@@ -584,7 +584,7 @@ class InductorAdaptor(CompilerInterface):
584
585
return compiled_graph
586
587
- def metrics_context(self) -> contextlib.AbstractContextManager:
587
+ def metrics_context(self) -> contextlib.AbstractContextManager[Any]:
588
"""
589
This method returns the Dynamo metrics context (if it exists,
590
otherwise a null context). It is used by various compile components.
@@ -603,12 +603,12 @@ class InductorAdaptor(CompilerInterface):
603
if is_torch_equal_or_newer("2.6"):
604
import torch._dynamo.utils
605
606
- return torch._dynamo.utils.get_metrics_context()
606
+ return torch._dynamo.utils.get_metrics_context() # type: ignore[no-any-return]
607
else:
608
return contextlib.nullcontext()
609
610
611
-def set_inductor_config(config, compile_range: Range):
611
+def set_inductor_config(config: dict[str, Any], compile_range: Range) -> None:
612
if compile_range.is_single_size():
613
# for a specific batch size, tuning triton kernel parameters
614
# can be beneficial
@@ -618,7 +618,7 @@ def set_inductor_config(config, compile_range: Range):
618
)
619
620
621
-def set_functorch_config():
621
+def set_functorch_config() -> None:
622
torch._functorch.config.bundled_autograd_cache = False
623
624
@@ -632,7 +632,7 @@ class EagerAdaptor(CompilerInterface):
632
compiler_config: dict[str, Any],
633
compile_range: Range,
634
key: str | None = None,
635
- ) -> tuple[Callable | None, Any | None]:
635
+ ) -> tuple[Callable[..., Any] | None, Any | None]:
636
compilation_counter.num_eager_compiles += 1
637
# we don't need to compile the graph, just return the graph itself.
638
# It does not support caching, return None for the handle.
vllm/compilation/counter.py
+3
-1
@@ -3,7 +3,9 @@
3
4
import copy
5
import dataclasses
6
+from collections.abc import Generator
7
from contextlib import contextmanager
8
+from typing import Any
9
10
11
@dataclasses.dataclass
@@ -34,7 +36,7 @@ class CompilationCounter:
36
return copy.deepcopy(self)
37
38
@contextmanager
37
- def expect(self, **kwargs):
39
+ def expect(self, **kwargs: Any) -> Generator[None, None, None]:
40
old = self.clone()
41
yield
42
for k, v in kwargs.items():
vllm/compilation/cuda_graph.py
+1
@@ -219,6 +219,7 @@ class CUDAGraphWrapper:
219
# runtime modes.
220
return self.runnable(*args, **kwargs)
221
222
+ assert batch_descriptor is not None
223
if batch_descriptor not in self.concrete_cudagraph_entries:
224
# create a new entry for this batch descriptor
225
self.concrete_cudagraph_entries[batch_descriptor] = CUDAGraphEntry(
vllm/compilation/fx_utils.py
+3
-2
@@ -7,10 +7,11 @@ from collections.abc import Iterable, Iterator
7
from torch import fx
8
from torch._higher_order_ops.auto_functionalize import auto_functionalized
9
from torch._ops import OpOverload, OpOverloadPacket
10
+from torch.fx.node import Target
11
12
12
-def is_func(node: fx.Node, target) -> bool:
13
- return node.op == "call_function" and node.target == target
13
+def is_func(node: fx.Node, target: Target) -> bool:
14
+ return bool(node.op == "call_function" and node.target == target)
15
16
17
def is_auto_func(node: fx.Node, op: OpOverload) -> bool:
vllm/compilation/inductor_pass.py
+15
-11
@@ -8,9 +8,9 @@ import hashlib
8
import inspect
9
import json
10
import types
11
-from collections.abc import Callable
11
+from collections.abc import Callable, Generator
12
from contextlib import contextmanager
13
-from typing import TYPE_CHECKING, Any
13
+from typing import TYPE_CHECKING, Any, ParamSpec, TypeVar
14
15
import torch
16
from torch import fx
@@ -30,6 +30,8 @@ else:
30
)
31
32
_pass_context = None
33
+P = ParamSpec("P")
34
+R = TypeVar("R")
35
36
37
class PassContext:
@@ -44,7 +46,7 @@ def get_pass_context() -> PassContext:
46
47
48
@contextmanager
47
-def pass_context(compile_range: Range):
49
+def pass_context(compile_range: Range) -> Generator[None, None, None]:
50
"""A context manager that stores the current pass context,
51
usually it is a list of sizes to specialize.
52
"""
@@ -57,7 +59,7 @@ def pass_context(compile_range: Range):
59
_pass_context = prev_context
60
61
60
-class InductorPass(CustomGraphPass):
62
+class InductorPass(CustomGraphPass): # type: ignore[misc]
63
"""
64
A custom graph pass that uses a hash of its source as the UUID.
65
This is defined as a convenience and should work in most cases.
@@ -73,7 +75,7 @@ class InductorPass(CustomGraphPass):
75
return InductorPass.hash_source(self)
76
77
@staticmethod
76
- def hash_source(*srcs: str | Any):
78
+ def hash_source(*srcs: str | Any) -> str:
79
"""
80
Utility method to hash the sources of functions or objects.
81
:param srcs: strings or objects to add to the hash.
@@ -93,7 +95,7 @@ class InductorPass(CustomGraphPass):
95
return hasher.hexdigest()
96
97
@staticmethod
96
- def hash_dict(dict_: dict[Any, Any]):
98
+ def hash_dict(dict_: dict[Any, Any]) -> str:
99
"""
100
Utility method to hash a dictionary, can alternatively be used for uuid.
101
:return: A sha256 hash of the json rep of the dictionary.
@@ -101,7 +103,7 @@ class InductorPass(CustomGraphPass):
103
encoded = json.dumps(dict_, sort_keys=True).encode("utf-8")
104
return hashlib.sha256(encoded).hexdigest()
105
104
- def is_applicable_for_range(self, compile_range: Range):
106
+ def is_applicable_for_range(self, compile_range: Range) -> bool:
107
return True
108
109
@@ -111,25 +113,27 @@ class CallableInductorPass(InductorPass):
113
implementation of the UUID.
114
"""
115
114
- def __init__(self, callable: Callable[[fx.Graph], None], uuid: Any | None = None):
116
+ def __init__(
117
+ self, callable: Callable[[fx.Graph], None], uuid: Any | None = None
118
+ ) -> None:
119
self.callable = callable
120
self._uuid = self.hash_source(callable) if uuid is None else uuid
121
118
- def __call__(self, graph: torch.fx.Graph):
122
+ def __call__(self, graph: torch.fx.Graph) -> None:
123
self.callable(graph)
124
125
def uuid(self) -> Any:
126
return self._uuid
127
128
125
-def enable_fake_mode(fn: Callable[..., Any]) -> Callable[..., Any]:
129
+def enable_fake_mode(fn: Callable[P, R]) -> Callable[P, R]:
130
"""
131
Applies a FakeTensorMode context. This is useful when you don't want to
132
create or run things with real tensors.
133
"""
134
135
@functools.wraps(fn)
132
- def fn_new(*args, **kwargs) -> Any:
136
+ def fn_new(*args: P.args, **kwargs: P.kwargs) -> R:
137
with torch._guards.tracing(None), unset_fake_temporarily(), FakeTensorMode():
138
result = fn(*args, **kwargs)
139
vllm/compilation/monitor.py
+4
-4
@@ -12,7 +12,7 @@ context_manager = None
12
torch_compile_start_time: float = 0.0
13
14
15
-def start_monitoring_torch_compile(vllm_config: VllmConfig):
15
+def start_monitoring_torch_compile(vllm_config: VllmConfig) -> None:
16
global torch_compile_start_time
17
torch_compile_start_time = time.time()
18
@@ -28,7 +28,7 @@ def start_monitoring_torch_compile(vllm_config: VllmConfig):
28
context_manager.__enter__()
29
30
31
-def end_monitoring_torch_compile(vllm_config: VllmConfig):
31
+def end_monitoring_torch_compile(vllm_config: VllmConfig) -> None:
32
compilation_config: CompilationConfig = vllm_config.compilation_config
33
if compilation_config.mode == CompilationMode.VLLM_COMPILE:
34
logger.info_once(
@@ -45,7 +45,7 @@ def end_monitoring_torch_compile(vllm_config: VllmConfig):
45
cudagraph_capturing_enabled: bool = True
46
47
48
-def validate_cudagraph_capturing_enabled():
48
+def validate_cudagraph_capturing_enabled() -> None:
49
# used to monitor whether a cudagraph capturing is legal at runtime.
50
# should be called before any cudagraph capturing.
51
# if an illegal cudagraph capturing happens, raise an error.
@@ -57,6 +57,6 @@ def validate_cudagraph_capturing_enabled():
57
)
58
59
60
-def set_cudagraph_capturing_enabled(enabled: bool):
60
+def set_cudagraph_capturing_enabled(enabled: bool) -> None:
61
global cudagraph_capturing_enabled
62
cudagraph_capturing_enabled = enabled
vllm/compilation/partition_rules.py
+4
-1
@@ -2,6 +2,7 @@
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
import contextlib
5
+from collections.abc import Generator
6
7
import torch
8
@@ -38,7 +39,9 @@ def should_split(node: torch.fx.Node, splitting_ops: list[str]) -> bool:
39
40
41
@contextlib.contextmanager
41
-def inductor_partition_rule_context(splitting_ops: list[str]):
42
+def inductor_partition_rule_context(
43
+ splitting_ops: list[str] | None,
44
+) -> Generator[None, None, None]:
45
"""Context manager to temporarily register Inductor partition rules.
46
47
Registers custom partition rules for specified operators, forcing the
vllm/compilation/sequence_parallelism.py
+7
-7
@@ -41,8 +41,8 @@ class _SequenceParallelPatternHelper:
41
self,
42
epsilon: float,
43
dtype: torch.dtype,
44
- device: str,
45
- ):
44
+ device: str | None,
45
+ ) -> None:
46
self.epsilon = epsilon
47
self.dtype = dtype
48
self.device = device
@@ -64,7 +64,7 @@ class _SequenceParallelPatternHelper:
64
65
66
class FirstAllReduceRMSNormPattern(_SequenceParallelPatternHelper):
67
- def __init__(self, epsilon: float, dtype: torch.dtype, device: str):
67
+ def __init__(self, epsilon: float, dtype: torch.dtype, device: str | None) -> None:
68
super().__init__(epsilon, dtype, device)
69
self.rmsnorm_matcher = MatcherRMSNorm(epsilon)
70
@@ -74,7 +74,7 @@ class FirstAllReduceRMSNormPattern(_SequenceParallelPatternHelper):
74
75
return [input, arg3_1]
76
77
- def register(self, pm_pass: PatternMatcherPass):
77
+ def register(self, pm_pass: PatternMatcherPass) -> None:
78
def pattern(
79
input: torch.Tensor,
80
arg3_1: torch.Tensor,
@@ -100,7 +100,7 @@ class FirstAllReduceRMSNormPattern(_SequenceParallelPatternHelper):
100
101
102
class MiddleAllReduceRMSNormPattern(_SequenceParallelPatternHelper):
103
- def __init__(self, epsilon: float, dtype: torch.dtype, device: str):
103
+ def __init__(self, epsilon: float, dtype: torch.dtype, device: str | None):
104
super().__init__(epsilon, dtype, device)
105
self.rmsnorm_matcher = MatcherFusedAddRMSNorm(epsilon)
106
@@ -162,7 +162,7 @@ class FirstAllReduceRMSNormStaticFP8Pattern(_SequenceParallelPatternHelper):
162
self,
163
epsilon: float,
164
dtype: torch.dtype,
165
- device: str,
165
+ device: str | None,
166
):
167
super().__init__(epsilon, dtype, device)
168
self.rmsnorm_matcher = MatcherRMSNorm(epsilon)
@@ -203,7 +203,7 @@ class FirstAllReduceRMSNormStaticFP8Pattern(_SequenceParallelPatternHelper):
203
204
205
class MiddleAllReduceRMSNormStaticFP8Pattern(_SequenceParallelPatternHelper):
206
- def __init__(self, epsilon: float, dtype: torch.dtype, device: str):
206
+ def __init__(self, epsilon: float, dtype: torch.dtype, device: str | None):
207
super().__init__(epsilon, dtype, device)
208
self.rmsnorm_matcher = MatcherFusedAddRMSNorm(epsilon)
209
self.quant_matcher = MatcherQuantFP8(kFp8StaticTensorSym)
vllm/compilation/torch25_custom_graph_pass.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 abc import ABC, abstractmethod
4
-from typing import Any
4
+from typing import Any, NoReturn
5
6
import torch
7
@@ -29,14 +29,14 @@ class Torch25CustomGraphPass(ABC): # noqa (redefinition)
29
Return None to skip inductor code caching entirely.
30
"""
31
32
- def __getstate__(self):
32
+ def __getstate__(self) -> Any | None:
33
"""
34
Pickling is used instead of uuid() in torch<2.6. Just return uuid()
35
to enable subclasses to only have to implement uuid.
36
"""
37
return self.uuid()
38
39
- def __setstate__(self, state):
39
+ def __setstate__(self, state: Any) -> NoReturn:
40
raise ValueError(
41
"Cannot unpickle CustomGraphPass because pickling"
42
" is used for cache key uuid. Use torch>=2.6 with"
vllm/compilation/vllm_inductor_pass.py
+19
-12
@@ -3,6 +3,7 @@
3
import functools
4
import operator
5
import time
6
+from collections.abc import Callable
7
from dataclasses import dataclass
8
from typing import ClassVar
9
@@ -43,13 +44,17 @@ class VllmInductorPass(InductorPass):
44
)
45
self.pass_config = config.compilation_config.pass_config
46
self.model_dtype = config.model_config.dtype if config.model_config else None
46
- self.device = config.device_config.device if config.device_config else None
47
+ self.device: str | None = (
48
+ config.device_config.device if config.device_config else None
49
+ )
50
self.pass_name = self.__class__.__name__
51
52
@staticmethod
50
- def time_and_log(call_fn):
53
+ def time_and_log(
54
+ call_fn: Callable[["VllmInductorPass", torch.fx.Graph], None],
55
+ ) -> Callable[["VllmInductorPass", torch.fx.Graph], None]:
56
@functools.wraps(call_fn)
52
- def wrapped(self: VllmInductorPass, graph: torch.fx.Graph):
57
+ def wrapped(self: VllmInductorPass, graph: torch.fx.Graph) -> None:
58
self.begin()
59
self.dump_graph(graph, "before")
60
call_fn(self, graph)
@@ -58,17 +63,17 @@ class VllmInductorPass(InductorPass):
63
64
return wrapped
65
61
- def dump_graph(self, graph: torch.fx.Graph, stage: str):
66
+ def dump_graph(self, graph: torch.fx.Graph, stage: str) -> None:
67
i = VllmInductorPass.dump_prefix
68
i_str = "" if i is None else f".{i}"
69
lazy_format_graph_code(
70
f"post_grad{i_str}.{self.pass_name}.{stage}", graph.owning_module
71
)
72
68
- def begin(self):
73
+ def begin(self) -> None:
74
self._start_time = time.perf_counter_ns()
75
71
- def end_and_log(self):
76
+ def end_and_log(self) -> None:
77
self._end_time = time.perf_counter_ns()
78
duration_ms = float(self._end_time - self._start_time) / 1.0e6
79
logger.debug("%s completed in %.1f ms", self.pass_name, duration_ms)
@@ -92,12 +97,14 @@ class VllmPatternMatcherPass(VllmInductorPass):
97
98
def _replace_op_overloads(self, string: str) -> str:
99
"""Replace <OpOverload(..., ...)> with nicer formulations"""
95
- return self._OP_OVERLOAD_PATTERN.sub(
96
- lambda m: f"torch.ops.{m.group(1)}.{m.group(2)}",
97
- string,
100
+ return str(
101
+ self._OP_OVERLOAD_PATTERN.sub(
102
+ lambda m: f"torch.ops.{m.group(1)}.{m.group(2)}",
103
+ string,
104
+ )
105
)
106
100
- def dump_patterns(self, config: VllmConfig, pm_pass: PatternMatcherPass):
107
+ def dump_patterns(self, config: VllmConfig, pm_pass: PatternMatcherPass) -> None:
108
"""
109
If debug dumping is enabled, dump the Inductor pattern-matcher patterns
110
into the debug_dump_path folder next to the dumped fx graphs.
@@ -165,9 +172,9 @@ class VllmPatternMatcherPass(VllmInductorPass):
172
173
174
class PrinterInductorPass(VllmInductorPass):
168
- def __init__(self, name: str, config: VllmConfig):
175
+ def __init__(self, name: str, config: VllmConfig) -> None:
176
super().__init__(config)
177
self.name = name
178
172
- def __call__(self, graph: torch.fx.Graph):
179
+ def __call__(self, graph: torch.fx.Graph) -> None:
180
self.dump_graph(graph, self.name)