Repository navigation
[Perf][MoE] Enable SM90 block-FP8 MegaMoE via FlashInfer MoE-EP - #62603
qianlihuang wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
--moe-backend flashinfer_moe_ep_cutedsl now also takes block-FP8 (128x128) checkpoints on Hopper. They run on FlashInfer's SM90 FP8 pull-style CuTeDSL megakernel, which fuses token dispatch, both expert GEMMs and the combine, through the existing FlashInfer MoE-EP adapter. - The FP8 oracle reorders w13 into the kernel's FC1 layout: gate and up rows interleaved by 8 under shared 128x128 scales. Power-of-two checkpoint scales survive this as exponent shifts. - The kernel always runs its whole token buffer, with a launch geometry picked for that size. The adapter therefore adds 64/256/1024-token workspaces and picks the smallest one that fits every EP rank's batch. - Fp8MoEMethod calls the experts' process_weights_after_loading hook, as the NVFP4 and MXFP4 methods do. It is a no-op for the other FP8 experts. GLM-5.3-Flash on 8x H200, DP8/EP8, 128K/512 decode with MTP3, A/B/A: output throughput +11% to +18% at concurrency 8-192, TPOT p50 -6% to -14%. EP8 MoE layer microbenchmark: -7% at 8 tokens/rank to -48% at 8192. GSM8K (1319, 5-shot): 0.919 vs 0.917. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
- Passthrough experts own the EP collective, so FusedMoEKernel no longer skips them on a rank without tokens (the same change is in vllm-project#62073). - The SM90 FP8 kernel weights the activation before fc2, so layers that weight the expert input (apply_router_weight_on_input) are rejected. - The compressed-tensors, online FP8 and Quark FP8 MoE methods call the experts' weight hook as well, so they also build the megakernel. - The SM90 path is chosen from the quant config rather than the weight dtype, and block-FP8 kernel weights stay FP8 on the layer. Rebuilding the kernel from preprocessed weights selects the same path. Tests: input-side router weights are rejected; a rebuild keeps the SM90 config; an empty rank and a CUDA graph replay through FusedMoEKernel stay bit-exact (without the idle-rank change the empty-rank case hangs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
- Every EP rank must launch on the same workspace. Without the DP-wide token counts in the forward context, the adapter now uses the default workspace instead of sizing it from the local batch. - The rebuild test passes the kernel weights by name and checks that the rebuilt layer reads the same storage. - The GPU test runs the modular kernel under inference mode and a forward context with DP-wide token counts, as serving does. It now covers the GLM-5.3-Flash, DeepSeek-V4.1-Flash, Kimi-K3 and Qwen3.8-Flash-Next expert shapes. - The weight-layout and router-weight tests move next to the other kernel tests. Stale comments are fixed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
9299748 to
7558a8c
Compare
|
We are tracking this from an offline DeepInfer Hopper tree, not a vLLM serving stack. On SM90 we already run DeepEP V2 + humming MXFP4 (float8e4m3-gs32, humming-kernels==0.1.13) and explicitly reject mega-MoE / NVFP4 backend names. We will not vendor FlashInfer moe_ep / CuTeDSL CUDA. After this PR merges we can re-test on H200 against that humming baseline, but only if FlashInfer is an importable dependency and the checkpoint under test is actually block-FP8 (stock DeepSeek-V4.1-Flash here is MXFP4 experts). Question: does the Hopper moe_ep path still require block-FP8 weights, or is there a planned MXFP4-resident entry that would apply to an unmodified DeepSeek-V4.1-Flash checkpoint? |
|
@kabishou11 This PR focuses on the SM90 block-FP8 path, and FP8 achieved better serving throughput than NVFP4 in my H200 benchmarks. For DeepSeek MXFP4 checkpoints, I think you could try FlashInfer's SM90 FP4 MegaMoE implementation and SM90 FP4 MoE-EP implementation. |
|
Thanks @qianlihuang — that clarifies it. We'll keep treating this PR as the SM90 block-FP8 path, and park stock MXFP4 DeepSeek-V4.1-Flash against FlashInfer #6343 as a watch item rather than expecting an MXFP4-resident entry here. Appreciate the H200 FP8 vs NVFP4 pointer. |
|
This pull request has merge conflicts that must be resolved before it can be |
Overview
vLLM has no MegaMoE that runs on Hopper today:
deep_gemm_mega_moe) requires SM100;flashinfer_moe_ep_cutedsl,flashinfer_moe_ep_mega_deep_gemm) require SM100This PR runs block-FP8 MoE checkpoints on Hopper with FlashInfer's SM90 FP8 MegaMoE, which ships in FlashInfer 0.7.2. The kernel fuses dispatch, both expert GEMMs and combine. It goes through the existing
--moe-backend flashinfer_moe_ep_cutedslpath with no model code, so any block-FP8 MoE can use it.Related:
Claims
Validation
Setup.
vllm-rs bench serve(0.32.0rc1.dev284) with token-ID prompts.Decode.
Prefill.
The base saturates at 21.4 req/s. At 23 and 25 req/s its TTFT p50 is 3.8 and 4.5 s, while this PR serves 22.7 and 24.7 req/s at 610 and 831 ms. At 11 req/s the median TTFT is 10% higher (base arms 351 and 389 ms).
MoE layer, EP8. GLM-5.3-Flash expert shapes, milliseconds per layer:
GSM8K. 1319 questions, 5-shot, natural MTP3:
Tests.
pytest tests/models/test_deepseek_v4_fi_moe_ep.py tests/kernels/moe/test_flashinfer_moe_ep.py # CPU: 29 passed. SM90 GPU: 8 passed (4 expert shapes x EP2/EP4).The SM90 GPU tests need at least two Hopper GPUs and
nvshmem4py, so CI does not run them.Commands
--moe-backend flashinfer_moe_ep_cutedslis omitted for the baseline. Both servers run withVLLM_USE_V2_MODEL_RUNNER=1.Details
Sm90PullFp8MegaMoeConfig, with FP32 128x128 weight scales and a SwiGLU clamp.swiglu_limitmodels.[pair, {gate, up}, 8]under one 128x128 scale. Each scale block therefore covers rows from two checkpoint blocks, and both usemax(s_gate, s_up).max_num_batched_tokens, decode is slower than the baseline.process_weights_after_loading. It is a no-op for other experts.nvshmem4py.apply_router_weight_on_input.FlashInfer upstream
Sm90PullFp8MegaMoeConfig) used by this PR through FlashInfer'sMoEEpLayerAPI.Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.