Enable flashinfer TRTLLM for FP8 EAGLE MoE

This commit is contained in:
wxiwnd
2026-06-30 00:05:16 +08:00
committed by wxiwnd
parent 2de822661c
commit 6f96a1c269
2 changed files with 43 additions and 17 deletions

View File

@@ -622,6 +622,25 @@ def nextn_moe_is_fp4_quantized_in_checkpoint(
)
def nextn_moe_is_fp8_quantized_in_checkpoint(
model_dir: Optional[str],
revision: Optional[str],
num_hidden_layers: Optional[int],
) -> Optional[bool]:
"""True/False if the checkpoint's NextN/MTP MoE experts ship fp8 scales."""
if not model_dir or num_hidden_layers is None:
return None
weight_map = load_safetensors_index_weight_map(model_dir, revision)
if weight_map is None:
return None
expert_prefix = f"model.layers.{num_hidden_layers}.mlp.experts."
return any(
name.startswith(expert_prefix)
and (name.endswith(".weight_scale_inv") or name.endswith(".weight_scale"))
for name in weight_map
)
# For models like Mistral-7B-v0.3, there are both sharded
# safetensors files and a consolidated safetensors file.
# Passing both of these to the weight loader functionality breaks.

View File

@@ -3303,17 +3303,12 @@ class ServerArgs:
from sglang.srt.layers.moe.utils import MoeRunnerBackend
from sglang.srt.model_loader.weight_utils import (
nextn_moe_is_fp4_quantized_in_checkpoint,
nextn_moe_is_fp8_quantized_in_checkpoint,
)
# An fp4 NextN/MTP layer (e.g. GLM-5.2-NVFP4) is a genuine DeepSeek-V3 fp4 MoE,
# identical in kind to the main model's MoE — and the fp4 trtllm kernel supports
# the DeepSeek routing it carries. So the EAGLE draft can run the SAME
# flashinfer_trtllm path as the main model (consistent, well-tested, correct EP
# scale handling). The trtllm restriction below is real only for a *bf16* MTP
# (DeepSeek-R1/V3-FP4): the bf16 trtllm MoE requires RenormalizeNaive routing,
# and the draft routing is hard to guarantee there. We distinguish the two from
# the checkpoint's safetensors index (ground truth: do the MTP experts ship fp4
# scales), the same signal used to keep/drop modelopt_fp4 for the NextN module.
# Quantized NextN/MTP MoE can run the same non-routed flashinfer_trtllm
# path as the main model. A bf16 MTP still cannot: bf16 trtllm MoE needs
# RenormalizeNaive routing, which the draft path does not guarantee.
_main_is_trtllm = self.moe_runner_backend in [
"flashinfer_trtllm",
"flashinfer_trtllm_routed",
@@ -3324,20 +3319,32 @@ class ServerArgs:
if self.speculative_draft_model_path
else self.revision
)
_num_hidden_layers = getattr(
self.get_model_config().hf_config, "num_hidden_layers", None
)
_nextn_is_fp4 = _main_is_trtllm and (
nextn_moe_is_fp4_quantized_in_checkpoint(
_spec_model_dir,
_spec_revision,
getattr(self.get_model_config().hf_config, "num_hidden_layers", None),
_num_hidden_layers,
)
is True
)
_nextn_is_fp8 = _main_is_trtllm and (
nextn_moe_is_fp8_quantized_in_checkpoint(
_spec_model_dir,
_spec_revision,
_num_hidden_layers,
)
is True
)
_nextn_can_use_trtllm = _nextn_is_fp4 or _nextn_is_fp8
if self.speculative_moe_runner_backend is None:
if _nextn_is_fp4:
# fp4 NextN -> the draft runs the same fp4 trtllm MoE path as main.
# Always the NON-routed kernel: the draft's FlashInferFP4MoE only
# implements trtllm_fp4_block_scale_moe, not the _routed variant.
if _nextn_can_use_trtllm:
# Quantized NextN -> the draft runs the same trtllm MoE path as main.
# Always the NON-routed kernel; speculative MoE does not support the
# _routed variant.
self.speculative_moe_runner_backend = "flashinfer_trtllm"
elif _main_is_trtllm:
self.speculative_moe_runner_backend = "auto"
@@ -3346,10 +3353,10 @@ class ServerArgs:
elif MoeRunnerBackend(
self.speculative_moe_runner_backend
).is_flashinfer_trtllm():
assert _nextn_is_fp4, (
assert _nextn_can_use_trtllm, (
"Speculative MoE runner backend flashinfer_trtllm is only supported for "
"an fp4 NextN/MTP layer (the bf16 trtllm MoE requires RenormalizeNaive "
"routing); use triton or auto for a bf16 MTP."
"a quantized fp4/fp8 NextN/MTP layer (the bf16 trtllm MoE requires "
"RenormalizeNaive routing); use triton or auto for a bf16 MTP."
)
elif MoeRunnerBackend(
self.speculative_moe_runner_backend