[FlashInfer v0.6.11] [RL] Support FlashInfer per-token NVFP4 MoE (#22918)
This commit is contained in:
@@ -127,6 +127,7 @@ SGLang supports various environment variables that can be used to configure its
|
|||||||
| `SGLANG_FORCE_FP8_MARLIN` | Force using FP8 MARLIN kernels even if other FP8 kernels are available | `false` |
|
| `SGLANG_FORCE_FP8_MARLIN` | Force using FP8 MARLIN kernels even if other FP8 kernels are available | `false` |
|
||||||
| `SGLANG_NVFP4_CKPT_FP8_GEMM_IN_ATTN` | Quantize q_b_proj from BF16 to FP8 when launching DeepSeek NVFP4 checkpoint | `false` |
|
| `SGLANG_NVFP4_CKPT_FP8_GEMM_IN_ATTN` | Quantize q_b_proj from BF16 to FP8 when launching DeepSeek NVFP4 checkpoint | `false` |
|
||||||
| `SGLANG_MOE_NVFP4_DISPATCH` | Use nvfp4 for moe dispatch (on flashinfer_cutlass or flashinfer_cutedsl moe runner backend) | `"false"` |
|
| `SGLANG_MOE_NVFP4_DISPATCH` | Use nvfp4 for moe dispatch (on flashinfer_cutlass or flashinfer_cutedsl moe runner backend) | `"false"` |
|
||||||
|
| `SGLANG_FLASHINFER_NVFP4_PER_TOKEN_ACTIVATION` | Enable FlashInfer TRTLLM per-token NVFP4 activation scaling; ignores checkpoint activation FP32 scale by treating it as `1` | `false` |
|
||||||
| `SGLANG_NVFP4_CKPT_FP8_NEXTN_MOE` | Quantize moe of nextn layer from BF16 to FP8 when launching DeepSeek NVFP4 checkpoint | `false` |
|
| `SGLANG_NVFP4_CKPT_FP8_NEXTN_MOE` | Quantize moe of nextn layer from BF16 to FP8 when launching DeepSeek NVFP4 checkpoint | `false` |
|
||||||
| `SGLANG_QUANT_ALLOW_DOWNCASTING` | Allow weight dtype downcasting during loading (e.g., fp32 → fp16). By default, SGLang rejects this kind of downcasting when using quantization. | `false` |
|
| `SGLANG_QUANT_ALLOW_DOWNCASTING` | Allow weight dtype downcasting during loading (e.g., fp32 → fp16). By default, SGLang rejects this kind of downcasting when using quantization. | `false` |
|
||||||
| `SGLANG_FP8_IGNORED_LAYERS` | A comma-separated list of layer names to ignore during FP8 quantization. For example: `model.layers.0,model.layers.1.,qkv_proj`. | `""` |
|
| `SGLANG_FP8_IGNORED_LAYERS` | A comma-separated list of layer names to ignore during FP8 quantization. For example: `model.layers.0,model.layers.1.,qkv_proj`. | `""` |
|
||||||
|
|||||||
@@ -549,6 +549,11 @@ SGLang supports various environment variables that can be used to configure its
|
|||||||
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Use nvfp4 for moe dispatch (on flashinfer_cutlass or flashinfer_cutedsl moe runner backend)</td>
|
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Use nvfp4 for moe dispatch (on flashinfer_cutlass or flashinfer_cutedsl moe runner backend)</td>
|
||||||
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}><code>"false"</code></td>
|
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}><code>"false"</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}><code>SGLANG_FLASHINFER_NVFP4_PER_TOKEN_ACTIVATION</code></td>
|
||||||
|
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Enable FlashInfer TRTLLM per-token NVFP4 activation scaling; ignores checkpoint activation FP32 scale by treating it as <code>1</code></td>
|
||||||
|
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}><code>false</code></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}><code>SGLANG_NVFP4_CKPT_FP8_NEXTN_MOE</code></td>
|
<td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}><code>SGLANG_NVFP4_CKPT_FP8_NEXTN_MOE</code></td>
|
||||||
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Quantize moe of nextn layer from BF16 to FP8 when launching DeepSeek NVFP4 checkpoint</td>
|
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Quantize moe of nextn layer from BF16 to FP8 when launching DeepSeek NVFP4 checkpoint</td>
|
||||||
|
|||||||
@@ -369,6 +369,8 @@ class Envs:
|
|||||||
SGLANG_FLASHINFER_USE_PAGED = EnvBool(False)
|
SGLANG_FLASHINFER_USE_PAGED = EnvBool(False)
|
||||||
# Default to the pick from flashinfer
|
# Default to the pick from flashinfer
|
||||||
SGLANG_FLASHINFER_WORKSPACE_SIZE = EnvInt(384 * 1024 * 1024)
|
SGLANG_FLASHINFER_WORKSPACE_SIZE = EnvInt(384 * 1024 * 1024)
|
||||||
|
# Enable per-token NVFP4 activation scaling path for FlashInfer TRT-LLM MoE.
|
||||||
|
SGLANG_FLASHINFER_NVFP4_PER_TOKEN_ACTIVATION = EnvBool(False)
|
||||||
# Skip-softmax threshold scale factor for TRT-LLM attention (prefill and decode separately).
|
# Skip-softmax threshold scale factor for TRT-LLM attention (prefill and decode separately).
|
||||||
# None = standard attention. See https://arxiv.org/abs/2512.12087
|
# None = standard attention. See https://arxiv.org/abs/2512.12087
|
||||||
SGLANG_SKIP_SOFTMAX_PREFILL_THRESHOLD_SCALE_FACTOR = EnvFloat(None)
|
SGLANG_SKIP_SOFTMAX_PREFILL_THRESHOLD_SCALE_FACTOR = EnvFloat(None)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from sglang.srt.distributed.device_communicators.pynccl_allocator import (
|
|||||||
is_tensor_in_symmetric_mempool,
|
is_tensor_in_symmetric_mempool,
|
||||||
use_symmetric_memory,
|
use_symmetric_memory,
|
||||||
)
|
)
|
||||||
|
from sglang.srt.environ import envs
|
||||||
from sglang.srt.layers.dp_attention import is_allocation_symmetric
|
from sglang.srt.layers.dp_attention import is_allocation_symmetric
|
||||||
from sglang.srt.layers.moe.flashinfer_trtllm_moe import (
|
from sglang.srt.layers.moe.flashinfer_trtllm_moe import (
|
||||||
trtllm_fp8_block_scale_moe_wrapper,
|
trtllm_fp8_block_scale_moe_wrapper,
|
||||||
@@ -872,9 +873,26 @@ def fused_experts_none_to_flashinfer_trtllm_fp4(
|
|||||||
topk_output = dispatch_output.topk_output
|
topk_output = dispatch_output.topk_output
|
||||||
|
|
||||||
# Quantize hidden states to FP4
|
# Quantize hidden states to FP4
|
||||||
hs_fp4, hs_scale_linear = quantize_hidden_states_fp4(
|
if envs.SGLANG_FLASHINFER_NVFP4_PER_TOKEN_ACTIVATION.get():
|
||||||
hidden_states, quant_info.w13_input_scale_quant
|
from flashinfer import SfLayout, nvfp4_quantize
|
||||||
)
|
|
||||||
|
hs_fp4_bytes, hs_sf_bytes, per_token_scale = nvfp4_quantize(
|
||||||
|
hidden_states,
|
||||||
|
1.0 / (448.0 * 6.0),
|
||||||
|
sfLayout=SfLayout.layout_linear,
|
||||||
|
per_token_activation=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
seq_len, hidden_size = hidden_states.shape
|
||||||
|
hs_fp4 = hs_fp4_bytes.reshape(seq_len, hidden_size // 2)
|
||||||
|
hs_scale_linear = hs_sf_bytes.view(torch.float8_e4m3fn).reshape(
|
||||||
|
seq_len, hidden_size // 16
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
per_token_scale = None
|
||||||
|
hs_fp4, hs_scale_linear = quantize_hidden_states_fp4(
|
||||||
|
hidden_states, quant_info.w13_input_scale_quant
|
||||||
|
)
|
||||||
hs_scale = hs_scale_linear.view(torch.float8_e4m3fn).reshape(
|
hs_scale = hs_scale_linear.view(torch.float8_e4m3fn).reshape(
|
||||||
*hs_scale_linear.shape[:-1], -1
|
*hs_scale_linear.shape[:-1], -1
|
||||||
)
|
)
|
||||||
@@ -927,6 +945,7 @@ def fused_experts_none_to_flashinfer_trtllm_fp4(
|
|||||||
output1_scale_scalar=quant_info.g1_scale_c,
|
output1_scale_scalar=quant_info.g1_scale_c,
|
||||||
output1_scale_gate_scalar=quant_info.g1_alphas,
|
output1_scale_gate_scalar=quant_info.g1_alphas,
|
||||||
output2_scale_scalar=quant_info.g2_alphas,
|
output2_scale_scalar=quant_info.g2_alphas,
|
||||||
|
per_token_scale=per_token_scale,
|
||||||
num_experts=quant_info.global_num_experts,
|
num_experts=quant_info.global_num_experts,
|
||||||
top_k=topk_output.topk_ids.shape[1],
|
top_k=topk_output.topk_ids.shape[1],
|
||||||
n_group=0,
|
n_group=0,
|
||||||
@@ -974,6 +993,7 @@ def fused_experts_none_to_flashinfer_trtllm_fp4(
|
|||||||
output1_scale_scalar=quant_info.g1_scale_c,
|
output1_scale_scalar=quant_info.g1_scale_c,
|
||||||
output1_scale_gate_scalar=quant_info.g1_alphas,
|
output1_scale_gate_scalar=quant_info.g1_alphas,
|
||||||
output2_scale_scalar=quant_info.g2_alphas,
|
output2_scale_scalar=quant_info.g2_alphas,
|
||||||
|
per_token_scale=per_token_scale,
|
||||||
num_experts=quant_info.global_num_experts,
|
num_experts=quant_info.global_num_experts,
|
||||||
top_k=topk_config.top_k,
|
top_k=topk_config.top_k,
|
||||||
n_group=topk_config.num_expert_group,
|
n_group=topk_config.num_expert_group,
|
||||||
|
|||||||
@@ -1758,6 +1758,13 @@ class ModelOptNvFp4FusedMoEMethod(FusedMoEMethodBase):
|
|||||||
w13_input_scale = layer.w13_input_scale.max(dim=-1).values.to(torch.float32)
|
w13_input_scale = layer.w13_input_scale.max(dim=-1).values.to(torch.float32)
|
||||||
w2_input_scale = layer.w2_input_scale
|
w2_input_scale = layer.w2_input_scale
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.enable_flashinfer_trtllm_moe
|
||||||
|
and envs.SGLANG_FLASHINFER_NVFP4_PER_TOKEN_ACTIVATION.get()
|
||||||
|
):
|
||||||
|
w13_input_scale = torch.ones_like(w13_input_scale, dtype=torch.float32)
|
||||||
|
w2_input_scale = torch.ones_like(w2_input_scale, dtype=torch.float32)
|
||||||
|
|
||||||
# Create shared parameters
|
# Create shared parameters
|
||||||
copy_or_rebind_param(
|
copy_or_rebind_param(
|
||||||
layer,
|
layer,
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ class FlashinferTrtllmGenMoeBackendMXFP8Base:
|
|||||||
|
|
||||||
class FlashinferTrtllmGenMoeBackendNVFP4Base:
|
class FlashinferTrtllmGenMoeBackendNVFP4Base:
|
||||||
backend = None
|
backend = None
|
||||||
|
extra_env = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
@@ -166,7 +167,7 @@ class FlashinferTrtllmGenMoeBackendNVFP4Base:
|
|||||||
cls.model,
|
cls.model,
|
||||||
cls.base_url,
|
cls.base_url,
|
||||||
timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||||
env={**os.environ, "SGLANG_ENABLE_JIT_DEEPGEMM": "False"},
|
env={**os.environ, **cls.extra_env, "SGLANG_ENABLE_JIT_DEEPGEMM": "False"},
|
||||||
other_args=[
|
other_args=[
|
||||||
"--moe-runner-backend",
|
"--moe-runner-backend",
|
||||||
cls.backend,
|
cls.backend,
|
||||||
@@ -204,30 +205,12 @@ class TestFlashinferTrtllmGenMoeBackendFP8(
|
|||||||
backend = "flashinfer_trtllm"
|
backend = "flashinfer_trtllm"
|
||||||
|
|
||||||
|
|
||||||
class TestFlashinferTrtllmGenMoeBackendMXFP8(
|
|
||||||
FlashinferTrtllmGenMoeBackendMXFP8Base, CustomTestCase
|
|
||||||
):
|
|
||||||
backend = "flashinfer_trtllm"
|
|
||||||
|
|
||||||
|
|
||||||
class TestFlashinferTrtllmGenMoeBackendBF16(
|
|
||||||
FlashinferTrtllmGenMoeBackendBF16Base, CustomTestCase
|
|
||||||
):
|
|
||||||
backend = "flashinfer_trtllm"
|
|
||||||
|
|
||||||
|
|
||||||
class TestFlashinferTrtllmGenMoeBackendNVFP4(
|
class TestFlashinferTrtllmGenMoeBackendNVFP4(
|
||||||
FlashinferTrtllmGenMoeBackendNVFP4Base, CustomTestCase
|
FlashinferTrtllmGenMoeBackendNVFP4Base, CustomTestCase
|
||||||
):
|
):
|
||||||
backend = "flashinfer_trtllm"
|
backend = "flashinfer_trtllm"
|
||||||
|
|
||||||
|
|
||||||
class TestFlashinferTrtllmGenMoeBackendFP8Routed(
|
|
||||||
FlashinferTrtllmGenMoeBackendFP8Base, CustomTestCase
|
|
||||||
):
|
|
||||||
backend = "flashinfer_trtllm_routed"
|
|
||||||
|
|
||||||
|
|
||||||
class TestFlashinferTrtllmGenMoeBackendMXFP8Routed(
|
class TestFlashinferTrtllmGenMoeBackendMXFP8Routed(
|
||||||
FlashinferTrtllmGenMoeBackendMXFP8Base, CustomTestCase
|
FlashinferTrtllmGenMoeBackendMXFP8Base, CustomTestCase
|
||||||
):
|
):
|
||||||
@@ -240,9 +223,10 @@ class TestFlashinferTrtllmGenMoeBackendBF16Routed(
|
|||||||
backend = "flashinfer_trtllm_routed"
|
backend = "flashinfer_trtllm_routed"
|
||||||
|
|
||||||
|
|
||||||
class TestFlashinferTrtllmGenMoeBackendNVFP4Routed(
|
class TestFlashinferTrtllmGenMoeBackendPerTokenNVFP4Routed(
|
||||||
FlashinferTrtllmGenMoeBackendNVFP4Base, CustomTestCase
|
FlashinferTrtllmGenMoeBackendNVFP4Base, CustomTestCase
|
||||||
):
|
):
|
||||||
|
extra_env = {"SGLANG_FLASHINFER_NVFP4_PER_TOKEN_ACTIVATION": "1"}
|
||||||
backend = "flashinfer_trtllm_routed"
|
backend = "flashinfer_trtllm_routed"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user