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+
223243logger = 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