[AMD][Fix] Restore aiter-padded MoE weight dims for serialized checkpoints - #33090
Merged
HaiShaw merged 1 commit intoAug 1, 2026
Merged
Conversation
yichiche
requested review from
1am9trash,
hubertlu-tw and
kkHuang-amd
as code owners
July 31, 2026 15:59
Contributor
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
Collaborator
Author
|
@fxmarty-amd Please help review if this PR fix the issue properly. We observe the accuracy loss only at TP8, and the reason is as below.
|
fxmarty-amd
approved these changes
Jul 31, 2026
mqhc2020
approved these changes
Jul 31, 2026
BowenBao
approved these changes
Jul 31, 2026
Collaborator
Author
|
@amd-bot ci-status |
HaiShaw
approved these changes
Aug 1, 2026
Collaborator
|
@BowenBao @fxmarty-amd would you please add more UTs to cover ongoing change validations, using following-up PR? |
saturn-acc
pushed a commit
to saturn-acc/sglang
that referenced
this pull request
Aug 16, 2026
…oints (sgl-project#33090) AMD only change
jakki-amd
pushed a commit
to jakki-amd/sglang
that referenced
this pull request
Sep 9, 2026
…oints (sgl-project#33090) AMD only change
Atituiset
pushed a commit
to Atituiset/sglang
that referenced
this pull request
Sep 10, 2026
…oints (sgl-project#33090) AMD only change
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.
Motivation
dcd9014f15("[AMD][MXFP4] Reland Online MXFP4 quantization 2/N - FP8 to MXFP4 requantization on AMD GPUs", #28291) silently broke accuracy for serialized MXFP4 Quark MoE checkpoints on ROCm whenever the per-rank MoE intermediate size needs aiter padding.On Qwen3.5-397B-A17B-MXFP4 at TP8 on MI355 this drops GSM8K from 0.99 to 0.54. The failure is not obvious garbage — output stays fluent English, but the model loses knowledge and frequently fails to terminate (runs to
max_tokens), so a single smoke prompt does not reliably catch it.Bisected over the 422 commits between the
v0.5.16branch point (8905cbd42f, good) and current main (fd28242b6, bad);git bisectnamesdcd9014f15as the first bad commit, and its parent696e8f80d1is good.Root cause
In
QuarkW4A4MXFp4MoE.create_weights, #28291 changed the weight allocation from the aiter-aligned dims returned byget_moe_weight_sizes()to raw dims:but the corresponding scales in the very same function were left on the padded dims:
get_moe_weight_sizes()is still called and itsweight_paddedflag is still advertised throughextra_weight_attrs(drivingFusedMoE.use_padded_loading), so the layer claims padding it no longer has. The weights and their block scales therefore describe different intermediate sizes.Why only TP >= 8
get_moe_weight_sizes()only pads whenw2_down_dim = (moe_intermediate_size / TP) / 2is not already a multiple ofAITER_PADDING_SIZE(128). Below that threshold the new raw expressions happen to equal the padded ones, so the commit is a no-op; at and above it they diverge. For Qwen3.5 (moe_intermediate_size = 1024):inter_dimSo the trigger condition is
moe_intermediate_size / TP < 256. This is not specific to Qwen3.5 or to TP8 — any serialized MXFP4 Quark MoE whose per-rank intermediate is not already 128-aligned is affected.There is a secondary, silent performance cost: the wrong
inter_dimalso drops the model off its tuned aiter FlyDSL MoE configs. Before the fix the server logs[fused_moe] no tuned FlyDSL config for (...), using 2stage defaultfor every token bucket; after the fix it resolves tuned kernels again (using 2stage (kernelName1='flydsl_moe1_afp4_wfp4_bf16_...')).Modifications
python/sglang/srt/layers/quantization/quark/schemes/quark_w4a4_mxfp4_moe.py— inQuarkW4A4MXFp4MoE.create_weights, usew13_up_dim/w2_down_dimfromget_moe_weight_sizes()for theis_checkpoint_mxfp4_serializedbranch so the weights match the scales again. The online-quantization branch (else) is untouched and keeps the shapes introduced by #28291.Two lines of real change plus a comment explaining why the serialized branch must stay on the padded dims.
Accuracy Tests
Qwen3.5-397B-A17B-MXFP4, 8x MI355 (gfx950), TP8,
--attention-backend aiter,SGLANG_USE_AITER=1 SGLANG_USE_AITER_UNIFIED_ATTN=1, identical aiter / sgl-kernel / flags across all rows — only the sglang Python tree differs.GSM8K, 5-shot,
--thinking-mode qwen-3,--max-tokens 32768, temperature 0.6, top-p 0.95.inter_dimv0.5.16696e8f80d1(parent of the bad commit)dcd9014f15(first bad commit)fd28242b6Qualitative check on the same builds, prompt "What do you know about Kalevipoeg?" (
max_tokens10000):v0.5.16finish_reason=stopfd28242b6finish_reason=lengthfinish_reason=stopFull bisect ledger (GSM8K n=40 per point, same harness):
8905cbd42f0.975 /66ea79dc2e0.975 /696e8f80d10.975 — allinter_dim256;dcd9014f150.525 /f369a820d40.525 /1a53f231d60.575 /6f55de04680.525 /d708969f680.500 /eb242b6c030.525 — allinter_dim128.Speed Tests and Profiling
No dedicated speed run; this is an accuracy fix. It does restore the tuned aiter FlyDSL MoE kernel selection that the regression disabled, so it should recover MoE throughput lost since #28291 as well. Counting kernel-selection log lines on an identical TP8 startup:
no tuned FlyDSL configfallbacksv0.5.16fd28242b6Happy to add a throughput sweep if reviewers want it.
Checklist
Note on unit tests: this regression was invisible to the existing suite because the weight and scale shapes are each individually self-consistent — only their relationship is wrong, and only at TP >= 8. A cheap guard would be a shape assertion in
create_weightstying the weight dims to the scale dims (deliberately left out of this PR to keep it minimal, happy to add it here or in a follow-up).test/registered/quant/test_quark_mxfp4.pyadded by #28291 does not cover the serialized + aiter-padded path.Review and Merge Process
CI States
Latest PR Test (Base): ❌ Run #30645224321
Latest PR Test (Extra): ❌ Run #30645408755