Skip to content

fix(muse_glimmer)!: keep the attention gate out of the qkv fusion - #741

Merged
jason-fxz merged 1 commit into
mainfrom
fix/muse-attn-gate-split
Oct 19, 2026
Merged

jason-fxz merged 1 commit into
mainfrom
fix/muse-attn-gate-split

Conversation

@jason-fxz

Copy link
Copy Markdown
Collaborator

Muse-Glimmer fused its per-head attention output gate into the q/k/v projection (qkvg_proj). The gate is now its own linear next to qkv_proj, as vLLM builds it (qkv_proj + output_gate_proj), in every format the family loads (bf16, compressed-tensors NVFP4, GGUF).

The reason is the NVFP4 release: Muse-Glimmer-30B-NVFP4 quantizes the gate with a different weight global scale than q/k/v in all 52 layers (the gate's global is down to 0.40x of q/k/v's), while q/k/v share one. main's Triton W4A16 linear keeps one global per output row, so the fused weight is exact there, but GEMMs that take one global per weight (cuBLASLt scaled_mm, FlashInfer mm_fp4, used by #737) cannot run a fused weight whose parts differ without scaling one part wrongly. Across the local NVFP4 checkpoints (Qwen3.6-27B, Qwen3.8-27B, Gemma-4-31B, Muse-Glimmer-30B, GLM-4.7) this was the only fused weight with differing per-part globals. Merge before #737.

Changes

  • models/muse_glimmer/attention.py: qkv_proj (q, k, v) and gate_proj (the gate) instead of qkvg_proj.
  • Loaders: the bf16 and compressed-tensors NVFP4 readers fuse only q/k/v (.self_attn.gate_proj loads on its own; the full suffix keeps it out of the MLP's gate/up fusion), the GGUF reader writes qkv_proj and gate_proj; the family uses the shared qkv_proj / gate_up_proj packed mapping.
  • Tests and docs/models.md.

Breaking: an FTW checkpoint converted with qkvg_proj no longer loads; reconvert it with ft checkpoint.

Results

On RTX PRO 6000, main's W4A16 linears:

  • Muse-Glimmer-30B-NVFP4, greedy 96 tokens on a three-sentence prompt: the same text as main.
  • bs=1 decode, 256 greedy tokens, two server runs x 3 requests each: 72.0 -> 71.0 tok/s (-1.4%), from one more GEMM per layer.
  • GGUF: synthetic 2-layer muse-glimmer GGUFs (q / k Q8_0 + v Q4_0 + gate F16; all Q8_0; a fused attn_qkv + Q4_0 gate) give qkv_proj and gate_proj outputs equal to the old qkvg_proj output bitwise at T = 1 / 7 / 64 (an F16 gate now runs as a plain bf16 linear, the same bf16 values). There is no real Muse-Glimmer GGUF on this box.

Tests

pytest tests/models/test_muse_glimmer.py tests/models/test_muse_glimmer_vision.py tests/server/test_muse_glimmer_parsers.py tests/models/test_quant_config.py tests/models/test_models_registry.py tests/checkpoint: 235 passed, 12 skipped, 5 failed; the 5 failures (test_quant_config.py, from the local HF cache) also fail on main. The test_quant_config.py Muse-Glimmer cases that build the model on the bf16, FP8 block and NVFP4 checkpoints on disk pass with the separate gate.

The NVFP4 release quantizes the attention gate with a different weight global scale than q/k/v, so
one fused weight cannot carry a single global for all four parts.

BREAKING CHANGE: an FTW checkpoint converted with the fused qkvg_proj no longer loads; reconvert it
with `ft checkpoint`.
@jason-fxz
jason-fxz merged commit 30dd715 into main Oct 19, 2026
1 check passed
pretor pushed a commit to pretor/FreeToken that referenced this pull request Oct 19, 2026
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.

1 participant