Skip to content

Commit 62db0ae

Browse files
committed
add fused fp8 bmm
1 parent 659880b commit 62db0ae

1 file changed

Lines changed: 35 additions & 7 deletions

File tree

vllm/v1/attention/backends/mla/common.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,26 @@
220220
from vllm.v1.worker.gpu_input_batch import InputBatch
221221
from vllm.v1.worker.gpu_model_runner import GPUModelRunner
222222

223+
224+
def dynamic_per_batched_tensor_quant(
225+
x: torch.Tensor, dtype: torch.dtype = torch.float8_e4m3fn
226+
):
227+
DTYPE_MAX = torch.finfo(dtype).max
228+
min_val, max_val = x.aminmax()
229+
amax = torch.maximum(min_val.abs(), max_val.abs()).clamp(min=1e-10)
230+
scale = DTYPE_MAX / amax
231+
x_scl_sat = (x * scale).clamp(min=-DTYPE_MAX, max=DTYPE_MAX)
232+
return x_scl_sat.to(dtype).contiguous(), scale.float().reciprocal()
233+
234+
from aiter.ops.triton.batched_gemm_a8w8_a_per_token_group_prequant_w_per_batched_tensor_quant import batched_gemm_a8w8_a_per_token_group_prequant_w_per_batched_tensor_quant
235+
@torch.compiler.disable
236+
def aiter_triton_fp8_bmm_wrapper(x, w, w_s, y = None, transpose_bm = False):
237+
if y is not None:
238+
batched_gemm_a8w8_a_per_token_group_prequant_w_per_batched_tensor_quant(x, w, w_s, YQ=y, transpose_bm=transpose_bm)
239+
else:
240+
y = batched_gemm_a8w8_a_per_token_group_prequant_w_per_batched_tensor_quant(x, w, w_s, transpose_bm = transpose_bm)
241+
return y
242+
223243
logger = init_logger(__name__)
224244

225245

@@ -704,7 +724,8 @@ def _v_up_proj_and_o_proj(self, x):
704724
# Convert from (B, N, L) to (N, B, L)
705725
x = x.view(-1, self.num_heads, self.kv_lora_rank).transpose(0, 1)
706726
# Multiply (N, B, L) x (N, L, V) -> (N, B, V)
707-
x = torch.bmm(x, self.W_UV)
727+
x = aiter_triton_fp8_bmm_wrapper(x, self.W_V, self.W_V_scale, transpose_bm = False)
728+
# x = torch.bmm(x, self.W_UV)
708729
# Convert from (N, B, V) to (B, N * V)
709730
x = x.transpose(0, 1).reshape(-1, self.num_heads * self.v_head_dim)
710731
return self.o_proj(x)[0]
@@ -718,7 +739,8 @@ def _q_proj_and_k_up_proj(self, x):
718739
# Convert from (B, N, P) to (N, B, P)
719740
q_nope = q_nope.transpose(0, 1)
720741
# Multiply (N, B, P) x (N, P, L) -> (N, B, L)
721-
ql_nope = torch.bmm(q_nope, self.W_UK_T)
742+
ql_nope = aiter_triton_fp8_bmm_wrapper(q_nope, self.W_K, self.W_K_scale, transpose_bm = False)
743+
# ql_nope = torch.bmm(q_nope, self.W_UK_T)
722744
# Convert from (N, B, L) to (B, N, L)
723745
return ql_nope.transpose(0, 1), q_pe
724746

@@ -751,6 +773,7 @@ def get_and_maybe_dequant_weights(layer: LinearBase):
751773
# `W_UV` and `W_UK_T`, we we just store fp16/bf16 copies and perform
752774
# the bmm's in 16-bit, the extra memory overhead of this is fairly low
753775
kv_b_proj_weight = get_and_maybe_dequant_weights(self.kv_b_proj).T
776+
754777
assert kv_b_proj_weight.shape == (
755778
self.kv_lora_rank,
756779
self.num_heads * (self.qk_nope_head_dim + self.v_head_dim)), (
@@ -767,11 +790,16 @@ def get_and_maybe_dequant_weights(layer: LinearBase):
767790

768791
W_UK, W_UV = kv_b_proj_weight.split(
769792
[self.qk_nope_head_dim, self.v_head_dim], dim=-1)
770-
771-
# Convert from (L, N, V) to (N, L, V)
772-
self.W_UV = W_UV.transpose(0, 1)
773-
# Convert from (L, N, P) to (N, P, L)
774-
self.W_UK_T = W_UK.permute(1, 2, 0)
793+
794+
W_K = W_UK.transpose(0, 1) # 16 512 128
795+
W_V = W_UV.permute(1, 2, 0) # 16 128 512
796+
self.W_K, self.W_K_scale = dynamic_per_batched_tensor_quant(W_K, dtype=torch.float8_e4m3fnuz)
797+
self.W_V, self.W_V_scale = dynamic_per_batched_tensor_quant(W_V, dtype=torch.float8_e4m3fnuz)
798+
799+
# # Convert from (L, N, V) to (N, L, V)
800+
# self.W_UV = W_UV.transpose(0, 1)
801+
# # Convert from (L, N, P) to (N, P, L)
802+
# self.W_UK_T = W_UK.permute(1, 2, 0)
775803

776804
def _compute_prefill_context(
777805
self,

0 commit comments

Comments
 (0)