Port fused SiLU+clamp+FP8 quant from DSV4 dev branch (#24897)

Co-authored-by: Cheng Wan <chwan@rice.edu>
Co-authored-by: fzyzcjy <ch271828n@outlook.com>
Co-authored-by: zcnrex <zcnrex@gmail.com>
This commit is contained in:
Yuhao Yang
2026-05-13 22:36:44 +08:00
committed by GitHub
co-authored by Cheng Wan fzyzcjy zcnrex
parent 9e00b7ca95
commit d0913fca8d
+51 -6
View File
@@ -27,6 +27,10 @@ import torch.nn.functional as F
from torch import nn
from transformers import PretrainedConfig
from sglang.jit_kernel.deepseek_v4 import (
silu_and_mul_clamp,
silu_and_mul_contig_post_quant,
)
from sglang.srt.batch_overlap.single_batch_overlap import SboFlags, compute_overlap_args
from sglang.srt.batch_overlap.two_batch_overlap import (
MaybeTboDeepEPDispatcher,
@@ -107,6 +111,9 @@ from sglang.srt.layers.moe.utils import (
)
from sglang.srt.layers.quantization.base_config import QuantizationConfig
from sglang.srt.layers.quantization.fp8 import Fp8Config
from sglang.srt.layers.quantization.fp8_kernel import (
create_per_token_group_quant_fp8_output_scale,
)
from sglang.srt.layers.quantization.mxfp4_flashinfer_trtllm_moe import (
maybe_fuse_routed_scale_and_shared_add,
)
@@ -269,13 +276,51 @@ class DeepseekV2MLP(nn.Module):
x = (x, None, y)
gate_up, _ = self.gate_up_proj(x)
if self.swiglu_limit is not None:
_g, _u = gate_up.chunk(2, dim=-1)
_lim = float(self.swiglu_limit)
gate_up = torch.cat(
[_g.clamp(max=_lim), _u.clamp(min=-_lim, max=_lim)], dim=-1
# Fast path: fused silu+clamp+fp8_quant+deepgemm when conditions met.
# Only valid when down_proj does NOT need an all-reduce and its weights
# are fp8 (uint8 storage with weight_scale_inv).
if (
self.swiglu_limit is not None
and not self.down_proj.reduce_results
and self.down_proj.weight.dtype == torch.uint8
and hasattr(self.down_proj, "weight_scale_inv")
):
M, N = gate_up.shape
down_input_fp8 = gate_up.new_empty((M, N // 2), dtype=torch.float8_e4m3fn)
scale_block_size = 128
down_input_scale = create_per_token_group_quant_fp8_output_scale(
x_shape=(M, N // 2),
device=gate_up.device,
group_size=scale_block_size,
column_major_scales=deep_gemm_wrapper.DEEPGEMM_SCALE_UE8M0,
scale_tma_aligned=deep_gemm_wrapper.DEEPGEMM_SCALE_UE8M0,
scale_ue8m0=deep_gemm_wrapper.DEEPGEMM_SCALE_UE8M0,
)
x = self.act_fn(gate_up)
silu_and_mul_contig_post_quant(
input=gate_up,
output=down_input_fp8,
output_scale=down_input_scale,
quant_group_size=scale_block_size,
scale_ue8m0=deep_gemm_wrapper.DEEPGEMM_SCALE_UE8M0,
transposed=deep_gemm_wrapper.DEEPGEMM_SCALE_UE8M0,
swiglu_limit=float(self.swiglu_limit),
)
down_output = gate_up.new_empty(
(M, self.down_proj.output_size), dtype=torch.bfloat16
)
deep_gemm_wrapper.gemm_nt_f8f8bf16(
(down_input_fp8, down_input_scale),
(self.down_proj.weight, self.down_proj.weight_scale_inv),
down_output,
)
return down_output
# Fallback: fused silu+clamp kernel (still faster than unfused)
if self.swiglu_limit is not None:
M, N = gate_up.shape
x = gate_up.new_empty((M, N // 2))
silu_and_mul_clamp(gate_up, x, float(self.swiglu_limit))
else:
x = self.act_fn(gate_up)
x, _ = self.down_proj(
x,
skip_all_reduce=should_allreduce_fusion or use_reduce_scatter,