main
py 134 lines 3.81 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Accessors for the optional ``b12x`` package."""
4
5 import importlib
6 import importlib.util
7 from collections.abc import Callable, Hashable, Iterable
8 from dataclasses import dataclass, fields, is_dataclass
9 from types import ModuleType
10 from typing import Any
11
12 import torch
13
14
15 @dataclass(frozen=True)
16 class B12xWarmupUnit:
17 name: str
18 key: Hashable
19 compile: Callable[[], None]
20
21
22 _HAS_B12X = importlib.util.find_spec("b12x") is not None
23
24
25 def _import_submodule(module_name: str) -> ModuleType | None:
26 if not _HAS_B12X:
27 return None
28 try:
29 return importlib.import_module(module_name)
30 except (ImportError, ModuleNotFoundError):
31 return None
32
33
34 _B12X_SUBMODULES = {
35 module_name: _import_submodule(module_name)
36 for module_name in (
37 "b12x.attention.paged",
38 "b12x.gemm.blockscaled",
39 # TODO: Remove once B12X exposes the scale-swizzle API publicly.
40 "b12x._lib.intrinsics",
41 "b12x.gemm.mxfp8_linear",
42 "b12x.gemm.tensor_fp8_linear",
43 "b12x.moe.fused_moe",
44 )
45 }
46
47
48 def has_b12x() -> bool:
49 """Return whether the B12X package is installed."""
50 return _HAS_B12X
51
52
53 def _get_submodule(module_name: str) -> ModuleType | None:
54 return _B12X_SUBMODULES.get(module_name)
55
56
57 def get_b12x_blockscaled() -> ModuleType | None:
58 return _get_submodule("b12x.gemm.blockscaled")
59
60
61 def get_b12x_intrinsics() -> ModuleType | None:
62 return _get_submodule("b12x._lib.intrinsics")
63
64
65 def get_b12x_mxfp8_linear() -> ModuleType | None:
66 return _get_submodule("b12x.gemm.mxfp8_linear")
67
68
69 def get_b12x_tensor_fp8_linear() -> ModuleType | None:
70 return _get_submodule("b12x.gemm.tensor_fp8_linear")
71
72
73 def get_b12x_fused_moe() -> ModuleType | None:
74 return _get_submodule("b12x.moe.fused_moe")
75
76
77 def get_b12x_paged_attention() -> ModuleType | None:
78 return _get_submodule("b12x.attention.paged")
79
80
81 def b12x_warmup_token_counts(
82 *,
83 max_tokens: int,
84 cudagraph_capture_sizes: Iterable[int] = (),
85 ) -> tuple[int, ...]:
86 # B12X deduplicates shapes that select the same internal kernel policy.
87 # Keep the complete serving shape set here rather than duplicating its
88 # policy-selection heuristics in vLLM.
89 counts = {1}
90 counts.update(int(size) for size in cudagraph_capture_sizes if int(size) > 0)
91 if int(max_tokens) > 0:
92 counts.add(int(max_tokens))
93 return tuple(sorted(counts))
94
95
96 def _same_packed_layout(current: Any, replacement: Any) -> bool:
97 if type(current) is not type(replacement):
98 return False
99 if isinstance(current, torch.Tensor):
100 return (
101 current.shape == replacement.shape
102 and current.stride() == replacement.stride()
103 and current.dtype == replacement.dtype
104 and current.device == replacement.device
105 )
106 if is_dataclass(current):
107 return all(
108 _same_packed_layout(
109 getattr(current, field.name),
110 getattr(replacement, field.name),
111 )
112 for field in fields(current)
113 )
114 return bool(current == replacement)
115
116
117 def _copy_packed_tensors(current: Any, replacement: Any) -> None:
118 if isinstance(current, torch.Tensor):
119 current.copy_(replacement)
120 elif is_dataclass(current):
121 for field in fields(current):
122 _copy_packed_tensors(
123 getattr(current, field.name),
124 getattr(replacement, field.name),
125 )
126
127
128 @torch.no_grad()
129 def reuse_packed_weight_storage(current: Any, replacement: Any) -> Any:
130 """Reuse packed tensor addresses when a compatible weight is reloaded."""
131 if current is None or not _same_packed_layout(current, replacement):
132 return replacement
133 _copy_packed_tensors(current, replacement)
134 return current