Skip to content

fix(moe): support Llama4 NVFP4 router input weights on SM120 - #35504

Merged
kpham-sgl merged 12 commits into
sgl-project:mainfrom
janbernloehr:jbernloehr/support-llama4-nvfp4-rout
Sep 22, 2026
Merged

kpham-sgl merged 12 commits into
sgl-project:mainfrom
janbernloehr:jbernloehr/support-llama4-nvfp4-rout

Conversation

@janbernloehr

@janbernloehr janbernloehr commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Fixes #34192.

Llama 4 constructs its MoE layers with apply_router_weight_on_input=True. For ModelOpt NVFP4 on SM120/SM121, SGLang selects the FlashInfer CUTLASS MoE runner, which previously rejected this configuration during server warmup.

For top-1 routing, the required semantics can be implemented exactly by multiplying each token's hidden states by its router weight before activation quantization and passing unit final scales to CUTLASS. This follows the existing pattern in the AITER MoE runner.

The fix remains intentionally restricted to top-1 routing. With top-k greater than one, each selected expert would require a differently scaled copy of the input.

Modifications

  • Add top-1 router-weight pre-scaling to the common FlashInfer CUTLASS MoE execution path.
  • Replace the kernel's output-side router scaling with float32 unit token_final_scales when pre-scaling is active.
  • Normalize all token_final_scales passed through this CUTLASS path to float32, as required by the binding.
  • Remove the ModelOpt NVFP4 and FlashInfer CUTLASS assertions that rejected apply_router_weight_on_input=True.
  • Preserve explicit rejection for:
    • top-k greater than one;
    • activations already quantized before dispatch, including the FlashInfer CUTLASS FP4 all-gather path.
  • Add focused CPU unit tests covering:
    • top-1 activation pre-scaling;
    • float32 unit final scales;
    • preservation of expert IDs;
    • top-k greater than one rejection;
    • pre-quantized dispatch rejection.

The normal apply_router_weight_on_input=False path is unchanged apart from enforcing the CUTLASS binding's float32 scale requirement.

Accuracy Tests

Added:

test/registered/unit/layers/moe/test_flashinfer_cutlass_router_weight.py

The tests compare the transformed hidden states and final scales against the expected top-1 formulation and verify that unsupported configurations fail explicitly.

Local validation:

python -m py_compile \
  python/sglang/srt/layers/moe/moe_runner/flashinfer_cutlass.py \
  python/sglang/srt/layers/quantization/modelopt_quant.py \
  test/registered/unit/layers/moe/test_flashinfer_cutlass_router_weight.py

Result: passed.

All commit-time pre-commit checks passed, including Python AST validation, isort, Ruff, Black, codespell, and registered-test validation.

The focused pytest test could not be executed in the local development environment because PyTorch is not installed. No real-checkpoint accuracy test was run for this checkout.

The equivalent patch and its SM120/SM121 validation evidence are documented in #34192. That validation used dummy weights for end-to-end liveness, so it is not claimed as a model-accuracy result.

Speed Tests and Profiling

No speed test or profiling was run for this checkout.

The equivalent patch validation documented in #34192 completed both SM120 scenarios without errors and did not show a decode throughput regression. Those results used dummy weights and a separate validated build, so they are included only as prior evidence, not as performance results for this commit.

Checklist

Review and Merge Process

  1. Ping Merge Oncalls to start the process. See the PR Merge Process.
  2. Get approvals from CODEOWNERS and other reviewers.
  3. Trigger CI tests with comments or contact authorized users to do so.
    • Common commands include /tag-and-rerun-ci, /tag-run-ci-label, /rerun-failed-ci
  4. After green CI and required approvals, ask Merge Oncalls or people with Write permission to merge the PR.

CI States

Latest PR Test (Base): ✅ Run #35553178662
Latest PR Test (Extra): ❌ Run #35553178439
Latest PR Test (AMD ROCm 10): ❌ Run #35553178589

@github-actions github-actions Bot added the quant LLM Quantization label Aug 19, 2026
@janbernloehr
janbernloehr force-pushed the jbernloehr/support-llama4-nvfp4-rout branch from 11dc473 to 47b6b56 Compare August 20, 2026 07:22
@nvpohanh nvpohanh added the bug Something isn't working label Aug 31, 2026

@nvpohanh nvpohanh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[by Codex] One inline review finding.


# Activations are already quantized and all-gathered before the runner on
# this path, so the multiply is no longer expressible here.
if getattr(dispatch_output, "hidden_states_scale", None) is not None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[by Codex] Severity: style | Confidence: High

Please avoid getattr here. Both StandardDispatchOutput and FlashinferDispatchOutput define hidden_states_scale; annotate this helper with their explicit union (or a small protocol) and read dispatch_output.hidden_states_scale directly so the supported structure is type-checked.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@nvpohanh

nvpohanh commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

/tag-and-rerun-ci

@github-actions github-actions Bot added the run-ci CI: run the baseline test suite on this PR label Sep 1, 2026
@nvpohanh

nvpohanh commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

@janbernloehr could you fix the conflicts?

@janbernloehr
janbernloehr force-pushed the jbernloehr/support-llama4-nvfp4-rout branch from bb02d04 to cecbbd4 Compare September 4, 2026 09:31

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just delete it

Comment thread python/sglang/srt/layers/moe/moe_runner/flashinfer_cutlass.py
@janbernloehr
janbernloehr force-pushed the jbernloehr/support-llama4-nvfp4-rout branch from cecbbd4 to 24f643b Compare September 4, 2026 12:23
@b8zhong
b8zhong enabled auto-merge (squash) September 4, 2026 12:31
@nvpohanh

nvpohanh commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@nvpohanh

nvpohanh commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

2 similar comments
@nvpohanh

nvpohanh commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@nvpohanh

nvpohanh commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@nvpohanh

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

1 similar comment
@nvpohanh

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@nvpohanh

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@nvpohanh

Copy link
Copy Markdown
Collaborator

All NV pipelines have passed. @b8zhong @ch-wan could we merge this? Thanks!

@kpham-sgl
kpham-sgl disabled auto-merge September 22, 2026 03:18
@kpham-sgl
kpham-sgl merged commit 56fee88 into sgl-project:main Sep 22, 2026
161 of 181 checks passed
detain added a commit to detain/sglang that referenced this pull request Sep 28, 2026
…input

Upstream sgl-project#35504 made _run_flashinfer_cutlass read
runner_config.apply_router_weight_on_input via
_prescale_router_weight_on_input. The TestSmallmRuntimeFallback
SimpleNamespace stub (from the SM120 small-row NVFP4 kernel pick)
predates that field, so all four fallback cases raised AttributeError
after the upstream merge. Add it with MoeRunnerConfig's default (False).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working quant LLM Quantization run-ci CI: run the baseline test suite on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Llama4 NVFP4 MoE crashes on SM120/SM121: apply_router_weight_on_input is not supported for Flashinfer

5 participants