Skip to content

[HIP] [CK] [MoE] Fix missing SwiGLU non-split no-bias CK-Tile MXFP4 dispatch (follow-up to #6376 revert) - #6478

Merged
yifehuan merged 53 commits into
ROCm:mainfrom
shantipriya-amd:feature/relu2-moe-gemm-tier2
Oct 16, 2026
Merged

yifehuan merged 53 commits into
ROCm:mainfrom
shantipriya-amd:feature/relu2-moe-gemm-tier2

Conversation

@shantipriya-amd

@shantipriya-amd shantipriya-amd commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

[MoE] Fix missing SwiGLU non-split no-bias CK-Tile MXFP4 dispatch (follow-up to #6376 revert)

Summary

Follow-up to #6376 (Relu2 Tier 1+2 MoE GEMM support), which was reverted via #6460/#6463 due to a regression in the amd/MiniMax-M3-MXFP4 TP4 production job: moe_dispatch: unsupported (activation=2, has_bias=0, split_k=1) combination.

Root cause

Two independent gaps combined to produce this failure:

  1. Codegen gap (the real root cause). csrc/ck_tile_gemm_moe_2stages/gen_instances.py derived has_bias as a single value per (act_type, is_split_k) pair instead of sweeping it independently. For SwiGLU non-split (split_k<=1), this meant only the has_bias=True kernel instance was ever generated. The C++ dispatch branch in moe_dispatch() for (SwiGLU, no-bias, split_k<=1) already existed and was correct — it called moe_gemm2_heuristic_dispatcher<...,2,false,false>::dispatch() — but with no generated specialization behind it, the call fell through to the empty primary (unspecialized) template, which is undefined behavior (confirmed: a literal empty-bodied function with a non-void return type). This was silent UB before [HIP] [CK] Re-submit Relu2 Tier 2 MoE GEMM support (clean CK pin) #6376 added a fail-loud TORCH_CHECK guard — the guard didn't introduce the bug, it correctly surfaced a pre-existing one.

  2. Caller/metadata mismatch. get_2stage_cfgs() hardcoded has_bias=True, stage2_has_bias=True for every CK-Tile SwiGLU MXFP4 branch, regardless of the caller's real has_stage1_bias/has_stage2_bias. vLLM passes bias1=None, bias2=None for MiniMax-M3 (a4w4, not use_mxfp4_w4a16), so even after closing the codegen gap this mismatch would have resurfaced the same failure class on a future shape.

Fix

  • gen_instances.py: the outer codegen loop now sweeps has_bias in [True, False] for SwiGLU in both split_k modes (previously derived a single value from is_split_k). Also fixed a related bug this exposed: gen_heuristic_dispatch()'s has_bias template substitution was computing an iteration-invariant value that would have mislabeled the new no-bias instances as bias instances — now derives it from the actual sampled kernel instance.
  • fused_moe.py: get_2stage_cfgs()'s two CK-Tile SwiGLU MXFP4 branches now report the caller's real has_stage1_bias/has_stage2_bias instead of a hardcoded True.
  • test_moe_2stage.py: added test_swiglu_mxfp4_nonsplit_nobias_dispatch(), which asserts correct CK-Tile routing (has_bias=False, stage2_has_bias=False, ksplit<=1) and runs a passing end-to-end dispatch (no TORCH_CHECK/crash).

Verification

  • Targeted test (test_swiglu_mxfp4_nonsplit_nobias_dispatch) passes: correct dispatch-family/metadata assertions, end-to-end kernel call completes without raising.
  • Broader sweep on the real MiniMax-M3 shape (model_dim=6144, inter_dim=1536, E=129, topk=5) across token counts {1, 3, 5, 32, 128} x bias {on, off}: all 10 cases complete with no crashes; accuracy (logits_diff) is nearly identical between bias-on and bias-off at every token count, confirming the fix removes bias as a point of failure without changing kernel numerics.
  • Note: this specific CK-Tile SwiGLU-MXFP4 shape has an independent, pre-existing logits_diff≈0.07-0.075 accuracy characteristic in both the old (bias) and new (no-bias) configurations — reproduced identically either way, so it predates and is unrelated to this fix. Worth a separate investigation; not a blocker here.

Checklist (per revert-PR follow-up requirements)

  • Cover the required non-split/no-bias SwiGLU dispatch path
  • Remove the empty primary-dispatcher undefined behavior
  • Add a targeted test for (SwiGLU, has_bias=false, split_k=1)
  • Pass MiniMax-M3-MXFP4 TP4/TP8 validation through ci:vllm (existing coverage, label applied)

Signed-off-by: Shantipriya Parida <shantipriya.parida@amd.com>
… output_dtype

Signed-off-by: Shantipriya Parida <shantipriya.parida@amd.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved weight-layout and bias-forwarding regressions can change MoE results, and test coverage needs correction.

18 open findings
Previously missed (1)

In code that hasn't changed since last review

Medium severity Add unaligned lengths covering partial vectors and scalar remainders

op_tests/​test_activation.py:661

Every nonempty length here selects vec_size=1 on wave32 and wave64. These cases check the missing second load, but never exercise a partial vector or either scalar remainder loop in activation_kernel_vec_safe. Add unaligned lengths above the vectorization thresholds. On wave64, 129/131, 257/261, and 513/521 cover partial first and second vectors at widths 2, 4, and 8.

🧠 Review effort: Balanced

Comment thread aiter/fused_moe.py Resolved
Comment thread aiter/fused_moe.py Resolved
Comment thread op_tests/test_moe_2stage.py Resolved
Copilot AI balanced review requested due to automatic review settings October 15, 2026 08:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Comment thread op_tests/test_moe_2stage.py Resolved
Copilot AI balanced review requested due to automatic review settings October 15, 2026 13:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread aiter/fused_moe.py Resolved
Comment thread aiter/fused_moe.py Resolved
Comment thread op_tests/test_moe_2stage.py Resolved
…m-tier2

# Conflicts:
#	op_tests/test_moe_2stage.py
Copilot AI balanced review requested due to automatic review settings October 15, 2026 13:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Copilot AI balanced review requested due to automatic review settings October 15, 2026 14:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved layout-routing regressions select incompatible weight interpretations, and the expanded test sweep includes an unsupported Relu2 combination.

21 open findings

And 1 more that still need to be addressed.

1 resolved since last review
Previously missed (1)

In code that hasn't changed since last review

Medium severity Preserve dtype fallback for untagged weight layouts

aiter/​fused_moe.py:4135

Preserve the bf16/fp16 fallback when layout metadata is absent. The generic shuffle_weight(..., layout=(16, 16)) path sets is_shuffled but not gate_up_interleave. An untuned, separated SwiGLU call with bf16 activations and GGUU weights therefore loses the standard-layout split-K path. The later CK-Tile fallback uses post_activation_layout="auto", which treats PyTorch FP4 weights as interleaved: it pairs the wrong gate/up groups, or raises if stage1 bias is present. Keep the previous dtype-based inference for untagged weights while honoring explicit layout metadata.

🧠 Review effort: Balanced

Comment thread aiter/fused_moe.py Resolved
Comment thread op_tests/test_moe_2stage.py Resolved

@yifehuan yifehuan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@yifehuan
yifehuan merged commit 88d7db6 into ROCm:main Oct 16, 2026
valarLip pushed a commit that referenced this pull request Oct 16, 2026
…ave gate_up_interleave unset (MiniMax-M3 TP8 regression from #6478) (#6620)

* [MoE] Keep the CK-Tile split-k route for SwiGLU MXFP4 callers that leave gate_up_interleave unset

#6478 made the CK-Tile split-k route (swiglu_mxfp4_bf16_cktile) require
w1.gate_up_interleave is False. Callers that never set the attribute pass None,
and with bf16/fp16 activations they now fall through to the "unshuffled weights"
CK-Tile fallback, which runs with post_activation_layout="auto" instead of
"standard". ATOM's MiniMax-M3-MXFP4 at TP8 (per-rank inter_dim 384 padded to 512)
hits exactly this on every decode step: the MoE output is uncorrelated with the
reference and generation runs to max tokens.

Treat an untagged layout (None) with bf16/fp16 activations as before #6478.
Tagged callers (True/False) are unchanged. Add a dispatch regression test for the
untagged case on the MiniMax-M3 TP8 shape.

* Use the MiniMax-M3 TP8 MoE call shape ATOM actually issues in the untagged-layout test

A server-side trace of get_2stage_cfgs shows inter_dim=512 with intermediate_pad=0
for this call, not intermediate_pad=128.
zhiding512 added a commit that referenced this pull request Oct 19, 2026
Since #6478 hands a caller's stage-1 bias to the CK-Tile split-k route,
MXFP4 callers with gate/up-interleaved weights and a bias reach its
interleaved epilogue, which cannot apply one. That is a missing feature,
not a bad argument, so raise NotImplementedError like fused_moe's other
unsupported combinations; the MoE replay records such caller-side
variants as unsupported rather than failing on them.

Signed-off-by: zhimding <zhimding@amd.com>
josh-schell-amd added a commit to josh-schell-amd/vllm that referenced this pull request Oct 20, 2026
…curacy test

The test runs rocm_aiter_fused_experts with SWIGLUOAI and no bias but
scored it against a silu(gate) * up reference. It only passed because
AITER <= v0.1.25 had no CK-Tile instance for SwiGLU without bias and
dispatched to a SiLU kernel instead. AITER v0.1.26 (ROCm/aiter#6478)
adds the missing instance, so the kernel now computes gpt-oss SwiGLU and
the silu reference no longer matches.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: josh schell <josh.schell@amd.com>
josh-schell-amd added a commit to josh-schell-amd/vllm that referenced this pull request Oct 20, 2026
…curacy test

The test runs rocm_aiter_fused_experts with SWIGLUOAI and no bias but
scored it against a silu(gate) * up reference. It only passed because
AITER <= v0.1.25 had no CK-Tile instance for SwiGLU without bias and
dispatched to a SiLU kernel instead. AITER v0.1.26 (ROCm/aiter#6478)
adds the missing instance, so the kernel now computes gpt-oss SwiGLU and
the silu reference no longer matches.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: josh schell <josh.schell@amd.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.

4 participants