Repository navigation
[Perf][MoE] Enable SM90 MXFP4 MegaMoE via FlashInfer MoE-EP - #64289
Draft
qianlihuang wants to merge 4 commits into
Draft
qianlihuang wants to merge 4 commits into
qianlihuang wants to merge 4 commits into
Conversation
--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>
--moe-backend flashinfer_moe_ep_cutedsl now also takes MXFP4 checkpoints on Hopper, such as DeepSeek-V4.1-Flash. They run on FlashInfer's SM90 MXFP4 x FP8 pull-style CuTeDSL megakernel (flashinfer-ai/flashinfer#4843), which fuses token dispatch, both expert GEMMs and the combine. - The MXFP4 weights stay packed: the checkpoint's E2M1 bytes and E8M0 scales go to FlashInfer as PrequantizedMoEWeights, and FlashInfer folds the scales into its kernel layout instead of requantizing from bf16. - The 64/256/1024-token workspaces of the block-FP8 path are reused, now together with the DeepSeek-V4 output view. - The kernel takes int64 expert ids, so the adapter converts the top-k ids to the kernel's index dtype. - EPLB is rejected, because FlashInfer keeps a per-expert scale of these weights outside the layer parameters. Input-side router weights are rejected as for block FP8. DeepSeek-V4.1-Flash on H200 against main's default MXFP4 backend (HUMMING): DP8/EP8 128K/512 decode with DSpark3 synthetic acceptance, +2% to +18% output throughput at concurrency 8-192; DP4/EP4 2048/1 prefill at the full 1M context, +3.5% saturated throughput. GSM8K (1319, 5-shot): 90.4% and 91.1% vs 89.8% and 90.5%. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
|
Thanks for stacking MXFP4 on the FlashInfer MoE-EP adapter (#62603 / flashinfer#4843). From an offline DeepInfer Hopper fork (kabishou11/deepinfer-hopper) we are watching this as the FlashInfer SM90 MXFP4 MegaMoE path next to the DeepGEMM route in #64061 + vllm-project/DeepGEMM#44. No GPU on our side yet — docs only, no copied tok/s — so this is just a port-note interest, not a serving claim. Happy to re-test once FlashInfer ships #4843 in a release (same pin gap you called out vs 0.7.2.post1). |
This was referenced Oct 29, 2026
Contributor
|
This pull request has merge conflicts that must be resolved before it can be |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
--moe-backend flashinfer_moe_ep_cutedslnow runs MXFP4 MoE checkpoints, such as DeepSeek-V4.1-Flash, on Hopper. It uses FlashInfer's SM90 MXFP4 x FP8 MegaMoE (flashinfer-ai/flashinfer#4843) through the existing FlashInfer MoE-EP adapter. The packed MXFP4 weights go to the kernel as loaded, without a bf16 round trip.Related:
Claims
All results are DeepSeek-V4.1-Flash on 8x H200, compared against main's default MXFP4 backend (HUMMING with block-FP8 activations and
allgather_reducescatter):Validation
Setup.
--moe-backend deep_gemm_mega_moe.--moe-backend flashinfer_moe_ep_cutedsl.vllm-rs bench servewith token-ID prompts.Decode. DP8/EP8, DecodeBenchConnector, ISL 128K / OSL 512, DSpark with 3 draft tokens and synthetic acceptance [0.8, 0.6, 0.5], N = 2C prompts. Each arm runs a warm-up pass, then three passes; cells are three-pass medians.
The two main arms differ by -5.8% at C=8 and by at most 3.3% elsewhere. The +2.4% at C=8 is inside that spread.
Decode output tok/s, median [min, max] of the three passes per arm
Prefill.
At 44.5 req/s, main serves 40.5 req/s, #64061 serves 36.7 req/s and this PR serves 41.7 req/s.
GSM8K. 1319 questions, 5-shot,
tests/evals/gsm8k/gsm8k_eval.pyagainst the prefill servers with natural DSpark3.One standard error is about 0.8 points, so no difference is resolved.
Tests. On H200 with FlashInfer 0.7.2.dev20261027:
nvshmem4py, and a FlashInfer build with #4843; without one they skip.Commands
Every server runs with
VLLM_USE_V2_MODEL_RUNNER=1. The main arm omits--moe-backend; the #64061 arm passes--moe-backend deep_gemm_mega_moe.The loader is
safetensorswith prefetch for all arms.fastsafetensorsOOMs here: it allocates a 94.6 GiB transient device buffer on top of 51.8 GiB of parameters.Details
PrequantizedMoEWeights.FlashInferMoeEptakes the Hopper weight format ("fp8_block"or"mxfp4") instead of a block-FP8 flag.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.
🤖 Generated with Claude Code