main
py 114 lines 3.75 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Enablement gate for the HPC fused gated-MLA GEMM.
4
5 ``hpc.gated_mla_gemm`` fuses the MLA output gating -- the gate projection, the
6 sigmoid and the elementwise product -- into a single kernel launch, replacing
7 the eager ``attn_out * sigmoid(hidden_states @ weight.T)`` sequence.
8
9 Kernel constraints:
10 - Requires VLLM_ENABLE_HPC_OPS=1
11 - Requires the hpc package (.so) built for the current arch
12 - Only sm100 / sm103 (compute capability 100, 103)
13 - All three operands must be bfloat16 and contiguous
14 - The gate width must be a multiple of 256
15 - Only elementwise gating (headwise has no fused form)
16 """
17
18 import torch
19
20 from vllm import envs
21 from vllm.logger import init_logger
22 from vllm.utils.hpc import has_hpc
23
24 logger = init_logger(__name__)
25
26 # hpc.gated_mla_gemm fuses `attn_out * sigmoid(x @ weight.T)` into one launch.
27 # It is built for sm100/sm103 and needs all three operands bf16 + contiguous,
28 # with the gate width a multiple of 256.
29 _HPC_GATED_GEMM_N_ALIGN = 256
30 _HPC_GATED_GEMM_CAPABILITIES: frozenset[int] = frozenset({100, 103})
31
32
33 def hpc_gated_mla_supported(
34 gating_type: str | None, attn_output_gate: torch.nn.Module | None
35 ) -> bool:
36 """Gate for running the MLA output gating through hpc.gated_mla_gemm."""
37 if not envs.VLLM_ENABLE_HPC_OPS:
38 return False
39
40 if attn_output_gate is None:
41 return False
42
43 if not has_hpc():
44 logger.warning_once(
45 "HPC gated MLA disabled: 'hpc' package is not installed. "
46 "Please install the HPC library (.so) to enable the fused kernel."
47 )
48 return False
49
50 from vllm.platforms import current_platform
51
52 if not current_platform.is_cuda():
53 logger.warning_once("HPC gated MLA disabled: only CUDA is supported.")
54 return False
55
56 capability = current_platform.get_device_capability()
57 if capability is None or capability.to_int() not in _HPC_GATED_GEMM_CAPABILITIES:
58 logger.warning_once(
59 "HPC gated MLA disabled: compute capability %s not in %s.",
60 capability,
61 _HPC_GATED_GEMM_CAPABILITIES,
62 )
63 return False
64
65 # Headwise gating broadcasts one scalar per head over v_head_dim; the
66 # kernel only implements the elementwise product.
67 if gating_type != "elementwise":
68 logger.warning_once(
69 "HPC gated MLA disabled: gating_type '%s' has no fused form.",
70 gating_type,
71 )
72 return False
73
74 weight = getattr(attn_output_gate, "weight", None)
75 if weight is None or weight.dtype != torch.bfloat16:
76 logger.warning_once(
77 "HPC gated MLA disabled: gate weight dtype is %s, the kernel needs "
78 "bfloat16 (keep the layer out of quantization).",
79 None if weight is None else weight.dtype,
80 )
81 return False
82
83 if weight.shape[0] % _HPC_GATED_GEMM_N_ALIGN != 0:
84 logger.warning_once(
85 "HPC gated MLA disabled: gate width %d is not a multiple of %d.",
86 weight.shape[0],
87 _HPC_GATED_GEMM_N_ALIGN,
88 )
89 return False
90
91 logger.info_once("HPC gated MLA enabled by set VLLM_ENABLE_HPC_OPS.")
92 return True
93
94
95 def hpc_gated_mla_gemm(
96 x: torch.Tensor,
97 weight: torch.Tensor,
98 atten_output: torch.Tensor,
99 ) -> torch.Tensor:
100 """Fused ``atten_output * sigmoid(x @ weight.T)``.
101
102 Args:
103 x: ``[m, k]`` bfloat16, contiguous.
104 weight: ``[n, k]`` bfloat16, contiguous and row-major (the kernel
105 transposes it). ``n`` must be a multiple of 256.
106 atten_output: ``[m, n]`` bfloat16, contiguous.
107
108 Returns:
109 ``[m, n]`` bfloat16.
110
111 """
112 from hpc.gemm import gated_mla_gemm
113
114 return gated_mla_gemm(x, weight, atten_output)