Skip to content

fix(moe): prepare MXFP8 MXFP4 profiler inputs - #4308

Merged
bkryu merged 1 commit into
flashinfer-ai:mainfrom
ormandj:fix/sm120-mxfp8-mxfp4-profiler
Aug 11, 2026
Merged

bkryu merged 1 commit into
flashinfer-ai:mainfrom
ormandj:fix/sm120-mxfp8-mxfp4-profiler

Conversation

@ormandj

@ormandj ormandj commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

📌 Description

GemmProfilerBackend::init() receives use_mxfp8_act_scaling but does not retain it, so prepareQuantParams() always constructs QuantParams::FP8MXFP4 on the FP8-activation/MXFP4-weight path. That leaves the mxfp8_mxfp4 weight block-scale pointers null, so the MXFPX scale-factor descriptor setup is skipped during profiling.

VictoriaLogs captured the affected DeepSeek-V4-Flash-0731 TP2 startup reaching fused-MoE profiling and then exiting after this error surfaced:

[AutoTuner]: Tuning trtllm::fused_moe::gemm1
...
torch.AcceleratorError: CUDA error: an illegal instruction was encountered
...
[2026-07-31 15:42:01] Received sigquit from a child process. It usually means the child failed.

This change:

  • stores use_mxfp8_act_scaling in the profiler;
  • sizes the fc1 weight scale-factor workspace for the doubled gated-activation output;
  • initializes the profiler's fc1/fc2 weight block scale-factor workspaces to UE8M0 unity on the MXFP8-activation path;
  • constructs QuantParams::MXFP8MXFP4 for MXFP8-activation/MXFP4-weight profiling; and
  • runs the existing numerical test with autotuning disabled and enabled.

When use_mxfp8_act_scaling is false, the existing QuantParams::FP8MXFP4 branch remains in use. The shared fc1 scale-factor workspace sizing is corrected for the gated output in both branches. PR #4066 skips profiling and selects fallback tactics for MXFP8×MXFP4 on SM120/SM121; this change repairs the profiler inputs and retains tactic profiling. Both changes update the same regression test.

If this change is accepted, PR #4066's SM120/SM121 fallback-tactic override should be removed, or #4066 closed. That override keeps SM120/SM121 on fallback tactics for this mode, which makes this profiler fix inert there.

🔍 Related Issues

Fixes #4049.

🚀 Pull Request Checklist

✅ Pre-commit Checks

  • I used uvx pre-commit.
  • I installed the hooks with pre-commit install. Not used; hooks were run directly with uvx.
  • Focused pre-commit checks pass for all three changed paths: csrc/fused_moe/cutlass_backend/cutlass_fused_moe_kernels.cuh, csrc/nv_internal/tensorrt_llm/kernels/cutlass_kernels/include/moe_kernels.h, and tests/moe/test_trtllm_cutlass_fused_moe.py.

🧪 Tests

  • Tests have been added or updated as needed.
  • The complete repository test suite was not run.
  • uv run --no-project python -m pytest -q tests/moe/test_trtllm_cutlass_fused_moe.py -k mxfp8_mxfp4 on SM120: 12 passed, 6 skipped, 132 deselected.
  • With this change applied, a DeepSeek-V4-Flash-0731 TP2 startup completed all 10 gemm1 and 10 gemm2 profiler candidates on both ranks, completed FlashInfer autotuning, captured the target and draft CUDA graphs, and reached ready state with zero restarts.

Test limitations: the autotuned numerical test exercises this path and checks numerical parity, but it does not directly inspect the fabricated workspace contents. The non-MXFP8 activation branch touched by the shared fc1 scale-factor sizing has no focused autotune regression case in this validation.

Reviewer Notes

The table below compares heuristic fallback tactics with profiler-selected tactics. It is not a direct patched-versus-unpatched throughput comparison; the patch is what allows the profiled-tactic side to start successfully. Both sides used the same SGLang revision, model, TP2 configuration, FP8 KV cache, DSpark width 5, hardware, and workload. The control skipped trtllm::fused_moe::gemm1 and gemm2; the candidate profiled them.

Methodology: each decode cell is one unreplicated 30-second run at C1, C2, C4, C8, C16, and C32. The coding row is the median of five sequential requests with a 2,000-token cap. The prefill rows are the median client-observed throughput from standalone cold-prefill runs at exact 8K, 64K, and 128K prompts with 7, 2, and 1 samples, respectively. All rows are single comparison runs with no variance estimate, and no effect size is claimed from any row.

Cell Fallback tactics Profiled tactics
C1 decode (tok/s) 187.7 240.5
C2 decode (tok/s) 241.4 349.5
C4 decode (tok/s) 347.1 515.2
C8 decode (tok/s) 456.5 662.9
C16 decode (tok/s) 683.8 992.8
C32 decode (tok/s) 1030.7 1413.6
Coding median (tok/s) 218.1 264.8
8K prefill (tok/s) 7444 7638
64K prefill (tok/s) 8557 8351
128K prefill (tok/s) 7922 7744

The pinned 1,319-row GSM8K gate was not counted as passing because each run had one response finish at the 1,024-token cap. Two profiled-tactic runs scored 1,241 and 1,239 correct; the fallback-tactic control scored 1,240 correct. No quality difference is claimed from these runs.

AI was used to assist with implementation.

Summary by CodeRabbit

  • Bug Fixes

    • Improved profiling for fused mixture-of-experts workloads using MXFP8 activations and MXFP4 weights.
    • Corrected workspace sizing and scaling behavior for quantized weight formats.
    • Added validation for unsupported scaling configurations.
  • Tests

    • Expanded coverage to verify both autotuned and default execution paths for quantized MoE workloads.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 77d1531d-1788-4df8-a927-76b41de180ea

📥 Commits

Reviewing files that changed from the base of the PR and between 2e97a60 and 4ec7f23.

📒 Files selected for processing (3)
  • csrc/fused_moe/cutlass_backend/cutlass_fused_moe_kernels.cuh
  • csrc/nv_internal/tensorrt_llm/kernels/cutlass_kernels/include/moe_kernels.h
  • tests/moe/test_trtllm_cutlass_fused_moe.py

📝 Walkthrough

Walkthrough

The profiler now preserves MXFP8 activation-scaling state, sizes gated FC1 scale storage correctly, and selects MXFP8×MXFP4 parameters with initialized scales. Tests cover both default and autotuned fused MoE execution.

Changes

MXFP8/MXFP4 fused MoE profiling

Layer / File(s) Summary
Retain profiler scaling state
csrc/nv_internal/tensorrt_llm/kernels/cutlass_kernels/include/moe_kernels.h
GemmProfilerBackend stores the MXFP8 activation-scaling option for later profiler configuration.
Correct profiler sizing and quantization
csrc/fused_moe/cutlass_backend/cutlass_fused_moe_kernels.cuh
Profiler workspace sizing uses the gated FC1 output width. MXFP8 activation scaling selects MXFP8MXFP4 parameters and initializes weight block scales to E8M0 unity under OSS Cutlass.
Validate autotuned execution
tests/moe/test_trtllm_cutlass_fused_moe.py
The MXFP8×MXFP4 test covers autotuning disabled and enabled while retaining the existing inputs and correctness comparison.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • flashinfer-ai/flashinfer#4003 — Both changes adjust native FP4 profiler workspace allocation for MoE autotuning.
  • flashinfer-ai/flashinfer#3558 — Both changes handle MXFP8 activation scaling during Cutlass fused-MoE profiling and test autotuned execution.

Possibly related PRs

Suggested labels: run-ci

Suggested reviewers: aleozlx, samuellees, zianglih

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary change: preparing MXFP8-activation and MXFP4-weight profiler inputs.
Description check ✅ Passed The description includes the required sections, explains the fix, links issue #4049, documents tests, and notes validation limits.
Linked Issues check ✅ Passed The changes address issue #4049 by repairing MXFP8×MXFP4 profiler inputs and preserving tactic profiling without skipping the affected path.
Out of Scope Changes check ✅ Passed The code and test changes are directly related to the profiler fix and its regression coverage; no unrelated changes are evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ormandj

ormandj commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

@waynehacking8 @nv-yunzheq @jimmyzho, could you review this as the profiler-repair alternative to #4066? This initializes the MXFP8×MXFP4 profiler inputs and retains tactic profiling; #4066 selects fallback tactics for this mode on SM120/SM121.

@bkryu

bkryu commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

/bot run tests/moe

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

GitLab MR !1178 has been created, and the CI pipeline #62008314 is currently running. I'll report back once the pipeline job completes.

@bkryu bkryu added run-ci and removed run-ci labels Aug 10, 2026
@bkryu
bkryu enabled auto-merge (squash) August 10, 2026 23:06
@bkryu
bkryu merged commit e31f4dd into flashinfer-ai:main Aug 11, 2026
43 of 56 checks passed
aleozlx pushed a commit that referenced this pull request Sep 8, 2026
…fc1 SF sizing (#4010)

## 📌 Description

Autotuning a native NVFP4 (FP4 activations x FP4 weights) CUTLASS MoE
crashed with `Assertion failed: quant_1 && quant_2 && quant_3 && quant_4
&& quant_5 && quant_6` (#4003): after #3738, the gemm profiler only
allocated its scratch quant-scale buffers for the FP8-activation FP4
flavor, so native NVFP4 got none. #4080 has since fixed that crash on
main. This PR is rebased on top of it and adds what's still missing:

- Replace the ad-hoc `is_nvfp4_quant` check with an
`isNativeWfp4Afp4Family()` helper used by both the allocation site
(`getProfilerWorkspaces`) and the consumption site
(`prepareQuantParams`), so the two can't drift apart again. This also
drops the `mSM >= 100` guard that the allocation side had but the
consumption side didn't.
- Size the fc1 weight scale-factor buffer (`quant_2`) with
`fc1_out_size` instead of `inter_size`. Gated activations make fc1
output 2x `inter_size`, so the old size under-allocated. #4308 has since
landed this sizing for the wfp4afp8 flavor; this PR applies it to native
NVFP4 and merges the two sizing branches so they cannot diverge.
- Add autotune coverage to `test_moe_nvfp4`, the regression test that
would have caught #4003.

Credit to @eugr for the proposed patch this builds on.

## 🔍 Related Issues

Fixes #4003 (crash itself already fixed on main by #4080). Regressed by
#3738.

## 🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull
request, please make sure the following items are complete.

### ✅ Pre-commit Checks

- [x] I have installed `pre-commit` by running `pip install pre-commit`
(or used your preferred method).
- [x] I have installed the hooks with `pre-commit install`.
- [x] I have run the hooks manually with `pre-commit run --all-files`
and fixed any reported issues.

## 🧪 Tests

- [x] Tests have been added or updated as needed.
- [x] All tests are passing (`unittest`, etc.).

`test_moe_nvfp4` is now parametrized with `use_autotune`, same approach
as #3558. Pre-rebase on a GB10 (SM121): every autotune case died with
the assertion without the fix, and all 48 cases passed with it.
Post-rebase, re-ran gated and non-gated autotune cases plus a
non-autotune case on an RTX 5080 (SM120), all passing. After rebasing
onto current main (post-#4308), all 48 cases pass on an RTX 5080
(SM120).

## Reviewer Notes

The predicate deliberately has no SM version check, unlike its wfp4afp8
sibling: it must exactly match the consuming branch in
`prepareQuantParams`, which checks dtypes only. FP4 x FP4 doesn't exist
below SM100 anyway.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved Native NVFP4 fused Mixture-of-Experts (MoE) execution by
correcting workspace and scaling-factor handling.
* Fixed NVFP4 behavior when autotuning is enabled, preventing related
execution failures.

* **Tests**
* Expanded NVFP4 coverage to validate both autotuned and non-autotuned
execution paths.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] SM120 fused-MoE gemm1 tactic profiling followed by illegal instruction

4 participants