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 15, 08:30 UTC
Add ability to use CUDAGraphs with use_inductor=False (#17345)
Signed-off-by: rzou <zou3519@gmail.com>
Richard Zou committed
May 28, 2025 at 22:16 UTC
26b4fa45bead5d65d4e15bfaffaa52ac71bea270
5 files changed
+51
-13
tests/compile/piecewise/test_simple.py
+10
-1
@@ -74,11 +74,12 @@ class SillyModel(nn.Module):
74
return x
75
76
77
-def test_simple_piecewise_compile():
77
+def _test_simple_piecewise_compile(*, use_inductor):
78
79
vllm_config = VllmConfig(compilation_config=CompilationConfig(
80
level=CompilationLevel.PIECEWISE,
81
use_cudagraph=True,
82
+ use_inductor=use_inductor,
83
splitting_ops=["silly.attention"],
84
cudagraph_copy_inputs=True,
85
cudagraph_capture_sizes=[1, 2],
@@ -108,3 +109,11 @@ def test_simple_piecewise_compile():
109
output = model(input)
110
assert global_counter == 2
111
assert torch.allclose(output.cpu(), torch.tensor([3., 1.]))
112
+
113
+
114
+def test_simple_piecewise_compile_inductor():
115
+ _test_simple_piecewise_compile(use_inductor=True)
116
+
117
+
118
+def test_simple_piecewise_compile_no_inductor():
119
+ _test_simple_piecewise_compile(use_inductor=False)
tests/compile/piecewise/test_toy_llama.py
+33
-7
@@ -261,12 +261,14 @@ def tractable_computation(input_ids: torch.Tensor,
261
@torch.inference_mode
262
def run_model(llama_config,
263
use_compile: bool,
264
+ use_inductor: bool,
265
split_attn: bool = False) -> torch.Tensor:
266
267
if use_compile:
268
compilation_config = CompilationConfig(
269
level=CompilationLevel.PIECEWISE,
270
use_cudagraph=True,
271
+ use_inductor=use_inductor,
272
cudagraph_capture_sizes=[1, 2],
273
)
274
if split_attn:
@@ -304,7 +306,7 @@ def run_model(llama_config,
306
return output.cpu()
307
308
307
-def test_toy_llama():
309
+def _test_toy_llama(*, use_inductor):
310
# compare output with and without piecewise compilation
311
312
llama_config = LlamaConfig(hidden_size=128,
@@ -326,8 +328,14 @@ def test_toy_llama():
328
num_backend_compilations=0,
329
num_cudagraph_caputured=0,
330
):
329
- outputs.append(run_model(llama_config, use_compile=False))
330
- run_model(tractable_config, use_compile=False)
331
+ outputs.append(
332
+ run_model(llama_config, use_inductor=False, use_compile=False))
333
+ run_model(tractable_config, use_inductor=False, use_compile=False)
334
+
335
+ if use_inductor:
336
+ kwargs = {"num_inductor_compiles": 1, "num_eager_compiles": 0}
337
+ else:
338
+ kwargs = {"num_eager_compiles": 1, "num_inductor_compiles": 0}
339
340
with compilation_counter.expect(
341
num_graphs_seen=1, # one graph for the model
@@ -336,9 +344,13 @@ def test_toy_llama():
344
num_backend_compilations=1, # num_piecewise_capturable_graphs_seen
345
num_cudagraph_caputured=
346
2, # num_cudagraph_sizes * num_piecewise_capturable_graphs_seen
347
+ **kwargs,
348
):
340
- outputs.append(run_model(llama_config, use_compile=True))
341
- run_model(tractable_config, use_compile=True)
349
+ outputs.append(
350
+ run_model(llama_config,
351
+ use_inductor=use_inductor,
352
+ use_compile=True))
353
+ run_model(tractable_config, use_inductor=use_inductor, use_compile=True)
354
355
with compilation_counter.expect(
356
num_graphs_seen=1, # one graph for the model
@@ -353,13 +365,27 @@ def test_toy_llama():
365
), # num_cudagraph_sizes * num_piecewise_capturable_graphs_seen
366
):
367
outputs.append(
356
- run_model(llama_config, use_compile=True, split_attn=True))
357
- run_model(tractable_config, use_compile=True, split_attn=True)
368
+ run_model(llama_config,
369
+ use_inductor=use_inductor,
370
+ use_compile=True,
371
+ split_attn=True))
372
+ run_model(tractable_config,
373
+ use_inductor=use_inductor,
374
+ use_compile=True,
375
+ split_attn=True)
376
377
for i in range(1, len(outputs)):
378
assert torch.allclose(outputs[0], outputs[i])
379
380
381
+def test_toy_llama_inductor():
382
+ _test_toy_llama(use_inductor=True)
383
+
384
+
385
+def test_toy_no_inductor():
386
+ _test_toy_llama(use_inductor=False)
387
+
388
+
389
@torch.inference_mode
390
def benchmark():
391
from triton.testing import do_bench
vllm/compilation/compiler_interface.py
+4
@@ -12,6 +12,7 @@ import torch._inductor.compile_fx
12
import torch.fx as fx
13
14
import vllm.envs as envs
15
+from vllm.compilation.counter import compilation_counter
16
from vllm.config import VllmConfig
17
from vllm.utils import is_torch_equal_or_newer
18
@@ -175,6 +176,7 @@ class InductorStandaloneAdaptor(CompilerInterface):
176
runtime_shape: Optional[int] = None,
177
key: Optional[str] = None,
178
) -> tuple[Optional[Callable], Optional[Any]]:
179
+ compilation_counter.num_inductor_compiles += 1
180
current_config = {}
181
if compiler_config is not None:
182
current_config.update(compiler_config)
@@ -262,6 +264,7 @@ class InductorAdaptor(CompilerInterface):
264
runtime_shape: Optional[int] = None,
265
key: Optional[str] = None,
266
) -> tuple[Optional[Callable], Optional[Any]]:
267
+ compilation_counter.num_inductor_compiles += 1
268
from torch._inductor.compile_fx import compile_fx
269
current_config = {}
270
if compiler_config is not None:
@@ -528,6 +531,7 @@ class EagerAdaptor(CompilerInterface):
531
runtime_shape: Optional[int] = None,
532
key: Optional[str] = None,
533
) -> tuple[Optional[Callable], Optional[Any]]:
534
+ compilation_counter.num_eager_compiles += 1
535
# we don't need to compile the graph, just return the graph itself.
536
# It does not support caching, return None for the handle.
537
return graph, None
vllm/compilation/counter.py
+4
@@ -15,6 +15,10 @@ class CompilationCounter:
15
num_piecewise_capturable_graphs_seen: int = 0
16
num_backend_compilations: int = 0
17
num_cudagraph_caputured: int = 0
18
+ # InductorAdapter.compile calls
19
+ num_inductor_compiles: int = 0
20
+ # EagerAdapter.compile calls
21
+ num_eager_compiles: int = 0
22
23
def clone(self) -> "CompilationCounter":
24
return copy.deepcopy(self)
vllm/config.py
-5
@@ -4315,15 +4315,10 @@ class VllmConfig:
4315
self.compilation_config.custom_ops.append("+rms_norm")
4316
if envs.VLLM_USE_V1 and self.model_config is not None and \
4317
not self.model_config.enforce_eager:
4318
- # NOTE(woosuk): Currently, we use inductor because the piecewise
4319
- # CUDA graphs do not work properly with the custom CUDA kernels.
4320
- # FIXME(woosuk): Disable inductor to reduce the compilation time
4321
- # and avoid any potential issues with the inductor.
4318
# FIXME(rob): Add function to set all of these.
4319
if not self.compilation_config.custom_ops:
4320
self.compilation_config.custom_ops = ["none"]
4321
self.compilation_config.use_cudagraph = True
4326
- self.compilation_config.use_inductor = True
4322
self.compilation_config.cudagraph_num_of_warmups = 1
4323
self.compilation_config.pass_config.enable_fusion = False
4324
self.compilation_config.pass_config.enable_noop = False