Skip to content

[AMD] [GLM-5.3-Flash Day 0] Honor fused and per-expert names in quark exclude - #37673

Closed
Arist12 wants to merge 1 commit into
sgl-project:xinyuan/glm-5.3-flash-supportfrom
Arist12:amd-glm53flash-quark-fused-excludes
Closed

Arist12 wants to merge 1 commit into
sgl-project:xinyuan/glm-5.3-flash-supportfrom
Arist12:amd-glm53flash-quark-fused-excludes

Conversation

@Arist12

@Arist12 Arist12 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Problem

OneNexus/GLM-5.3-Flash-MXFP4 cannot be loaded on this branch. Weight loading aborts with

AssertionError: param_data.shape=torch.Size([128, 512]),
                loaded_weight.shape=torch.Size([128, 1024])

in load_qkv_weight. The 2× width is the signature of an MXFP4-packed parameter (two values per byte) meeting an unpacked BF16 weight — i.e. a layer the checkpoint excluded from quantization got quantized anyway.

Root cause

should_ignore_layer() only consults exclude after rewriting a fused module name into its shards. This checkpoint uses two exclusion shapes that never survive that rewrite:

1. Already-fused modules named directly. The vision tower ships visual.blocks.N.attn.qkv_proj as a single tensor, and all 125 such names appear verbatim in quantization_config.exclude. Expanding to q_proj/k_proj/v_proj matches nothing, so the module is quantized while the checkpoint holds it unpacked.

2. Per-expert MoE excludes. The checkpoint lists model.layers.{3,5,6}.mlp.experts.{0..287}.{down,gate,up}_proj1728 entries — but SGLang builds one FusedMoE named model.layers.N.mlp.experts, which matches none of them. Those three layers' routed experts are BF16 in the checkpoint (the model card documents this) and were being loaded as MXFP4.

Measured on the checkpoint, confirming both the exclusion shape and which layers it covers:

exclude entries total                     2552
  ... mentioning "experts"                1860
  ... per-expert (experts.<N>.<proj>)     1728   -> layers 3, 5 and 6 only
  ... mentioning "visual"                  125

and the tensors themselves:

layers.5.mlp.experts.0.down_proj.weight   BF16   (4096, 2048)     no weight_scale
layers.7.mlp.experts.0.down_proj.weight   U8     (4096, 1024)     + weight_scale

At TP8 that is 2048/8 = 256 versus 1024/8 = 128 — exactly the assertion above.

Fix

Check exclude for a direct match before expanding packed mappings, and treat a fused ...experts module as excluded when the checkpoint excludes its experts individually. Both run before the existing expansion, so the shard-level path is unchanged.

The per-expert rule is exact for this checkpoint, where exclusion is whole-layer (288 experts × 3 projections). It would not be for a checkpoint that excluded only some experts of a layer — SGLang's fused representation cannot express that at all, so there is no correct behavior to preserve there.

Verification

8× MI355X (gfx950), ROCm 7.2.4, with the six open [AMD] [GLM-5.3-Flash Day 0] PRs applied (#37530, #37563, #37573, #37626, #37629, #37653):

  • without this change: weight loading aborts as above
  • with it: all 120 shards load and the server answers /v1/models

Tests

Added to test/registered/unit/layers/quantization/test_quark_utils.py, in that file's existing bug-catcher style. Proven non-vacuous — run against the unpatched function:

== UNFIXED (branch HEAD)
   directly excluded fused qkv            want=True  got=False FAIL
   per-expert excludes -> fused MoE       want=True  got=False FAIL
   unexcluded fused qkv still expands     want=False got=False PASS
   shard-level excludes still work        want=True  got=True  PASS
   unrelated MoE layer not ignored        want=False got=False PASS
== FIXED (this PR)
   all five PASS

The three guards cover the behavior that must not change: an empty ignore list must not start excluding everything, the original shard-level path must still work, and a per-expert prefix must not match a different layer index.

Note

None of the six Day-0 PRs touch quark/utils.py, so this gap is not covered by them.


CI States

Latest PR Test (Base): ❌ Run #33696764690
Latest PR Test (Extra): ❌ Run #33696764505
Latest PR Test (AMD ROCm 7.2): ❌ Run #33696764681

… `exclude`

OneNexus/GLM-5.3-Flash-MXFP4 cannot be loaded today: weight loading dies with

    AssertionError: param_data.shape=torch.Size([128, 512]),
                    loaded_weight.shape=torch.Size([128, 1024])

in `load_qkv_weight`. The 2x width is an MXFP4-packed parameter (two values per
byte) meeting an unpacked BF16 weight, i.e. a layer the checkpoint excluded from
quantization was quantized anyway.

`should_ignore_layer` only ever consults `exclude` after rewriting a fused
module name into its shards. That misses two shapes this checkpoint uses:

1. Already-fused modules named directly. The vision tower ships
   `visual.blocks.N.attn.qkv_proj` as ONE tensor and all 125 such names appear
   verbatim in `quantization_config.exclude`. Expanding to q/k/v_proj finds
   nothing, so the module is quantized while the checkpoint holds it unpacked.

2. Per-expert MoE excludes. The checkpoint lists
   `model.layers.{3,5,6}.mlp.experts.{0..287}.{down,gate,up}_proj` -- 1728
   entries -- but SGLang builds a single FusedMoE named
   `model.layers.N.mlp.experts`, which matches none of them. Those three layers'
   experts are BF16 in the checkpoint (the model card documents this) and were
   being loaded as MXFP4.

Fix: check `exclude` for a direct match before expanding packed mappings, and
treat a fused `...experts` module as excluded when the checkpoint excludes its
experts individually. Both checks run before the existing expansion, so the
shard-level path is unchanged.

The per-expert rule is exact for this checkpoint, where exclusion is
whole-layer (288 experts x 3 projections). It would not be for a checkpoint
excluding only some experts of a layer -- SGLang's fused representation cannot
express that at all, so there is no correct answer to preserve there.

Verified on 8x MI355X (gfx950) with the six open [AMD][GLM-5.3-Flash Day 0] PRs
(sgl-project#37530, sgl-project#37563, sgl-project#37573, sgl-project#37626, sgl-project#37629, sgl-project#37653) applied: without this change
weight loading aborts as above; with it all 120 shards load and the server
answers `/v1/models`.

Tests are bug-catchers, not vacuous: run against the unpatched function the two
new cases fail and the three regression guards pass; with the fix all five pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants