main
py 89 lines 2.79 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Warm b12x JIT kernels used by a loaded model."""
4
5 from collections import Counter
6 from collections.abc import Iterable
7 from typing import TYPE_CHECKING
8
9 import torch
10
11 from vllm.logger import init_logger
12 from vllm.platforms import current_platform
13 from vllm.utils.b12x import B12xWarmupUnit, b12x_warmup_token_counts
14
15 if TYPE_CHECKING:
16 from vllm.v1.worker.gpu_worker import Worker
17
18 logger = init_logger(__name__)
19
20
21 def _collect_warmup_units(
22 model: torch.nn.Module,
23 token_counts: tuple[int, ...],
24 output_dtype: torch.dtype,
25 ) -> Iterable[B12xWarmupUnit]:
26 units: dict[object, B12xWarmupUnit] = {}
27 for layer in model.modules():
28 provider = getattr(layer, "b12x_warmup_provider", None)
29 get_unit = getattr(provider, "get_b12x_warmup_unit", None)
30 if not callable(get_unit):
31 continue
32 unit = get_unit(layer, token_counts, output_dtype)
33 assert isinstance(unit, B12xWarmupUnit)
34 units.setdefault(unit.key, unit)
35 return units.values()
36
37
38 def _compile_warmup_units(
39 units: Iterable[B12xWarmupUnit],
40 ) -> Counter[str]:
41 warmed: Counter[str] = Counter()
42 with torch.inference_mode():
43 for unit in units:
44 unit.compile()
45 warmed[unit.name] += 1
46 if warmed:
47 torch.accelerator.synchronize()
48 return warmed
49
50
51 def b12x_warmup(worker: "Worker", cudagraph_capture_sizes: list[int]) -> None:
52 if not current_platform.is_cuda():
53 return
54 if not current_platform.is_device_capability_family(120):
55 return
56
57 output_dtype = getattr(
58 getattr(worker, "model_config", None),
59 "dtype",
60 torch.bfloat16,
61 )
62 if output_dtype not in (torch.bfloat16, torch.float16):
63 output_dtype = torch.bfloat16
64 compile_sizes = worker.vllm_config.compilation_config.compile_sizes or []
65 max_num_batched_tokens = worker.scheduler_config.max_num_batched_tokens
66 serving_sizes = [
67 max_num_batched_tokens,
68 *cudagraph_capture_sizes,
69 *(size for size in compile_sizes if isinstance(size, int)),
70 ]
71 max_tokens = max_num_batched_tokens
72 max_num_scheduled_tokens = worker.scheduler_config.max_num_scheduled_tokens
73 if max_num_scheduled_tokens is not None:
74 max_tokens = max(max_tokens, max_num_scheduled_tokens)
75 token_counts = b12x_warmup_token_counts(
76 max_tokens=max_tokens,
77 cudagraph_capture_sizes=serving_sizes,
78 )
79 units = _collect_warmup_units(
80 worker.get_model(),
81 token_counts,
82 output_dtype,
83 )
84 for name, count in _compile_warmup_units(units).items():
85 logger.info_once(
86 "Warmed up %d b12x %s kernel signature(s).",
87 count,
88 name,
89 )