feat(muse-glimmer): trace Meta's Muse Glimmer in vLLM and land the W0 scaffold - #279
Merged
Conversation
Meta released Muse Glimmer (30B, Apache-2.0, agentic multimodal) on 2026-08-08. This commit is records and spec only: no source file changes, no forward, no gate. The model does not exist at the parity pin 555967922, and it is not on vLLM main either. Its only upstream implementation is vllm#51655, which is OPEN and approved but unmerged with 3 of 20 CI checks red. Porting from that branch head instead of the pin is a deliberate exception taken on explicit developer direction, recorded as porting-inventory §9 deviation 16 rather than as a waivers.csv entry, because no checker enforces the anchor rule and a waiver naming a checker that does not exist would be a false record. Because the pinned oracle cannot load muse_glimmer at all, there is no honest denominator: every performance axis for this model is an OPEN GAP by construction, not a waived one, until #51655 merges and the pin advances. Correctness gates against the HF reference instead, with per-mechanism RED-first mutation carrying the weight the missing oracle would have. Traced from muse_glimmer.py @ 075d645af. The text tower is a Gemma2-style sandwich-norm stack (fp32, baked +1 weight offset, split pre/post eps) with Llama-4-style iRoPE (no_rope_layers==0 gives NoPE plus full attention, ==1 gives RoPE plus sliding window), weightless pre-RoPE QK-norm, a post-QK-norm query pre-scale, and a Qwen3.5-style attention output gate whose gate reads the layer input rather than the attention output. Two named correctness traps get their own RED-first tests: the query pre-scale ships under two config schemas disambiguated by magnitude, and use_qk_norm / use_attn_output_gate read as None rather than True so a naive getattr default silently drops both mechanisms while still emitting plausible text. The 50-layer perception encoder (linear patchify, bilinear pos-emb interpolation, width-first 2D RoPE, block-windowed attention, pixel-shuffle merge) reuses the Qwen3-VL vision seam. DFlash needs no new drafter, only architecture recognition and is_neox_style threading. iRoPE is the one mechanism with no local analogue. Issue: #268 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
… map Additive only: no forward, no checkpoint, no GPU, no download. The forward REFUSES-by-name so a call LOUDLY reports the pending brick instead of returning a silent wrong answer. Both architecture strings register onto one factory, mirroring upstream. The config parse handles the canonical nested layout and normalizes the older flat one; without that normalization a flat config deserializes to an all-default text config, ignoring every checkpoint value with no error. The weight-name mapper ports hf_to_vllm_mapper for both checkpoint conventions. The structural enumeration deliberately omits the three weightless modules (embed_norm, the per-head qk_norm, perception_emb_norm) that ship no tensor: enumerating them would make the loader demand tensors no checkpoint contains. Gate tests/vllm/models/test_muse_glimmer_scaffold.cpp: 11/11 cases, 73/73 assertions, clean CPU -Werror build. Full CPU ctest 367/367. RED-first mutation evidence, each mutated in tree and then restored byte-for-byte (verified by an empty git diff): native raw qk_scale_factor treated as pre-folded -> 3 assertions RED absent use_qk_norm / use_attn_output_gate -> false -> 4 assertions RED iRoPE mask counted forward, not backward -> 5 assertions RED legacy sandwich-norm renames in the wrong order -> 1 assertion RED The last one is the subtle one: legacy guac exports name the PRE-feedforward norm post_attention_layernorm and the true post-attention norm post_attn_norm, so renaming in the wrong order silently swaps them. Registering two architectures extends the registry-coverage ledgers exactly as they are designed to be extended: the registration/SupportedArchs counts 35 -> 37, the two sorted architecture arrays, the golden raise-message lists (also in test_model_loader_gguf), and the non-hybrid multimodal branch, which Muse Glimmer joins because its iRoPE split is sliding-vs-full attention and not a recurrent lane. No assertion was deleted or widened. What this does NOT establish: no forward runs, so nothing here says the model produces correct tokens. The KV-cache spec is a documented placeholder; the real sliding/full split rides the Gemma-4 per-layer seam at W1. And no speed axis is measurable at all while the pin lacks muse_glimmer. Anchored to the OPEN vllm#51655 head 075d645af, not the parity pin. See porting-inventory §9 deviation 16. Issue: #268 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Model checkpoints belong on shared or network storage, not on each box's system disk. A 30B bf16 checkpoint is ~60 GB; this box's system disk was already at 80% before fetching one, and a full disk surfaces as unrelated test failures rather than an obvious disk error. Configuration, not policy: CHECKPOINT_ROOT is documented in the tracked .env.example and set in each developer's untracked .env. Model operations respect it when it is set and fall back to the tool default (usually the HF cache under $HOME) when it is empty, so nothing breaks for a setup that has no shared mount. It authorizes nothing on its own -- large asset fetches still need explicit authority. Also documents the reproducibility rule that goes with it: pin an explicit revision when fetching, because publishers re-quantize in place under an unchanged repo name. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
localai-bot
force-pushed
the
row/MODEL-MUSE-GLIMMER
branch
from
August 10, 2026 15:49
8975f56 to
050596f
Compare
Surveys what the text tower forward needs against what the tree already has. Result: every primitive exists, so W1 is a mechanical port against gemma2.cpp (whose sandwich-norm decoder layer is structurally identical) rather than new kernel work. Notably vt::kSigmoidGateBf16 already implements attn * sigmoid(gate), the attention output gate, and is already used by Qwen3.5; and RmsNormArgs' gemma=true flag IS the baked +1 weight offset. Records the six deltas from the gemma2 template that are places to get it wrong -- the weightless embed_norm standing in for Gemma's sqrt(hidden) scale, the split pre/post eps, the plain head_dim**-0.5 attention scale, iRoPE tying RoPE and sliding-window together per layer, the gate reading the normed layer input rather than the attention output, and the untied lm_head with its output multiplier. No code. This is the survey that keeps W1 from re-deriving it. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
FOLLOWING_AGENTS_PROTOCOL
Ports Muse Glimmer's two serving-surface parsers from vLLM PR #51655 head
075d645af (NOT the parity pin - Muse Glimmer does not exist at 555967922; the
branch-head anchor is spec §0 / porting-inventory §9 deviation 16):
vllm/reasoning/muse_glimmer_reasoning_parser.py -> reasoning_parsers/muse_glimmer.{h,cpp}
vllm/tool_parsers/muse_glimmer_tool_parser.py -> tool_parsers/muse_glimmer.{h,cpp}
Muse Glimmer frames a turn as channel-scoped messages - to=self reasoning, a
to=<tool>.<fn> ATEM tool channel, a to=user answer - so the whole job is channel
SELECTION, not regex subtraction: an <atem:invoke> echoed inside the CoT or in a
final answer must never become a tool call, and a truncated turn must not lose a
real one.
All five upstream parser test modules are ported in this change with their
fixtures and failure cases preserved: test_muse_glimmer_tool_parser.py (5),
test_muse_glimmer_toolname_normalize.py (6), test_muse_glimmer_reasoning_handoff.py
(4), test_muse_glimmer_streaming.py (6) and test_muse_glimmer_parse_delta.py (5),
plus 8 cases guarding invariants the upstream files claim but never exercise.
Harness adaptations are documented at the head of each test file; the two that
matter are that upstream builds its parsers with cls.__new__ (which makes the
reasoning parser raise AttributeError before its streaming module can assert
anything) and that the streaming cases drive ShapeChatDelta, this seam's
analogue of DelegatingParser.parse_delta, rather than the parsers in isolation.
Seam deviations are listed in the two headers. The load-bearing one: our
ShapeChatDelta consults the reasoning parser on EVERY delta and re-derives the
tool parser's previous_text from extract_reasoning(), so the reasoning->tool
handoff forwards incrementally, and the tool parser gains the unframed-content
fallback its non-streaming path already had. Both are mutation-proven.
Upstream disagreement, reported not silently mirrored: _normalize_name and
test_trailing_segment_unambiguous contradict each other. The leaf rule here
binds only onto a registered BARE name, and only when the leaf identifies one
tool, which satisfies every ported assertion AND upstream's stated safety
invariant that an emitted weather.get must not dispatch a registered
calendar.get.
NO model claim: the Muse Glimmer forward is not implemented, so nothing serves
tool calls end to end. No speed claim of any kind. Full-suite regression is
deferred to the orchestrator's central sweep.
Gate (CPU-only, Release, -DVLLM_CPP_CUDA=OFF): the two new suites green
(15 cases / 35 assertions, 19 cases / 216 assertions) after a captured RED
against stubs (15 of 17 cases failing); all 44 built tool/reasoning/parser
suites green run serially; 7/7 mutations red with the tree restored
byte-for-byte.
Issue: #268
Row: MODEL-MUSE-GLIMMER-W7
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Meta released Muse Glimmer (30B, Apache-2.0, agentic multimodal) on 2026-08-08. This commit is records and spec only: no source file changes, no forward, no gate. The model does not exist at the parity pin 555967922, and it is not on vLLM main either. Its only upstream implementation is vllm#51655, which is OPEN and approved but unmerged with 3 of 20 CI checks red. Porting from that branch head instead of the pin is a deliberate exception taken on explicit developer direction, recorded as porting-inventory §9 deviation 16 rather than as a waivers.csv entry, because no checker enforces the anchor rule and a waiver naming a checker that does not exist would be a false record. Because the pinned oracle cannot load muse_glimmer at all, there is no honest denominator: every performance axis for this model is an OPEN GAP by construction, not a waived one, until #51655 merges and the pin advances. Correctness gates against the HF reference instead, with per-mechanism RED-first mutation carrying the weight the missing oracle would have. Traced from muse_glimmer.py @ 075d645af. The text tower is a Gemma2-style sandwich-norm stack (fp32, baked +1 weight offset, split pre/post eps) with Llama-4-style iRoPE (no_rope_layers==0 gives NoPE plus full attention, ==1 gives RoPE plus sliding window), weightless pre-RoPE QK-norm, a post-QK-norm query pre-scale, and a Qwen3.5-style attention output gate whose gate reads the layer input rather than the attention output. Two named correctness traps get their own RED-first tests: the query pre-scale ships under two config schemas disambiguated by magnitude, and use_qk_norm / use_attn_output_gate read as None rather than True so a naive getattr default silently drops both mechanisms while still emitting plausible text. The 50-layer perception encoder (linear patchify, bilinear pos-emb interpolation, width-first 2D RoPE, block-windowed attention, pixel-shuffle merge) reuses the Qwen3-VL vision seam. DFlash needs no new drafter, only architecture recognition and is_neox_style threading. iRoPE is the one mechanism with no local analogue. Issue: #268 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
… map Additive only: no forward, no checkpoint, no GPU, no download. The forward REFUSES-by-name so a call LOUDLY reports the pending brick instead of returning a silent wrong answer. Both architecture strings register onto one factory, mirroring upstream. The config parse handles the canonical nested layout and normalizes the older flat one; without that normalization a flat config deserializes to an all-default text config, ignoring every checkpoint value with no error. The weight-name mapper ports hf_to_vllm_mapper for both checkpoint conventions. The structural enumeration deliberately omits the three weightless modules (embed_norm, the per-head qk_norm, perception_emb_norm) that ship no tensor: enumerating them would make the loader demand tensors no checkpoint contains. Gate tests/vllm/models/test_muse_glimmer_scaffold.cpp: 11/11 cases, 73/73 assertions, clean CPU -Werror build. Full CPU ctest 367/367. RED-first mutation evidence, each mutated in tree and then restored byte-for-byte (verified by an empty git diff): native raw qk_scale_factor treated as pre-folded -> 3 assertions RED absent use_qk_norm / use_attn_output_gate -> false -> 4 assertions RED iRoPE mask counted forward, not backward -> 5 assertions RED legacy sandwich-norm renames in the wrong order -> 1 assertion RED The last one is the subtle one: legacy guac exports name the PRE-feedforward norm post_attention_layernorm and the true post-attention norm post_attn_norm, so renaming in the wrong order silently swaps them. Registering two architectures extends the registry-coverage ledgers exactly as they are designed to be extended: the registration/SupportedArchs counts 35 -> 37, the two sorted architecture arrays, the golden raise-message lists (also in test_model_loader_gguf), and the non-hybrid multimodal branch, which Muse Glimmer joins because its iRoPE split is sliding-vs-full attention and not a recurrent lane. No assertion was deleted or widened. What this does NOT establish: no forward runs, so nothing here says the model produces correct tokens. The KV-cache spec is a documented placeholder; the real sliding/full split rides the Gemma-4 per-layer seam at W1. And no speed axis is measurable at all while the pin lacks muse_glimmer. Anchored to the OPEN vllm#51655 head 075d645af, not the parity pin. See porting-inventory §9 deviation 16. Issue: #268 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Model checkpoints belong on shared or network storage, not on each box's system disk. A 30B bf16 checkpoint is ~60 GB; this box's system disk was already at 80% before fetching one, and a full disk surfaces as unrelated test failures rather than an obvious disk error. Configuration, not policy: CHECKPOINT_ROOT is documented in the tracked .env.example and set in each developer's untracked .env. Model operations respect it when it is set and fall back to the tool default (usually the HF cache under $HOME) when it is empty, so nothing breaks for a setup that has no shared mount. It authorizes nothing on its own -- large asset fetches still need explicit authority. Also documents the reproducibility rule that goes with it: pin an explicit revision when fetching, because publishers re-quantize in place under an unchanged repo name. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Surveys what the text tower forward needs against what the tree already has. Result: every primitive exists, so W1 is a mechanical port against gemma2.cpp (whose sandwich-norm decoder layer is structurally identical) rather than new kernel work. Notably vt::kSigmoidGateBf16 already implements attn * sigmoid(gate), the attention output gate, and is already used by Qwen3.5; and RmsNormArgs' gemma=true flag IS the baked +1 weight offset. Records the six deltas from the gemma2 template that are places to get it wrong -- the weightless embed_norm standing in for Gemma's sqrt(hidden) scale, the split pre/post eps, the plain head_dim**-0.5 attention scale, iRoPE tying RoPE and sliding-window together per layer, the gate reading the normed layer input rather than the attention output, and the untied lm_head with its output multiplier. No code. This is the survey that keeps W1 from re-deriving it. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
docs/USAGE.md is for people USING vllm.cpp; where our checkpoints live is development setup, so it belongs with the environment registry rather than in the user-facing guide. Moves the CHECKPOINT_ROOT guidance into .agents/environment.md as a registration step alongside .env and developer-preferences.md, and keeps the two rules that travel with it: pin an explicit revision when fetching (publishers re-quantize in place under an unchanged repo name), and the variable authorizes nothing on its own. The .env.example entry added in the previous commit stays -- that file is where the value comes from. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…eption lives main retired the waiver registry in a4f72f8: an exception now argues for itself in the commit that needs it, attached to the diff it excuses, with git log --grep as the record. This row's off-pin anchor exception already worked that way -- it was recorded in porting-inventory §9 and argued in its own commit, precisely because a waiver naming a checker that does not exist would have been a false record. Only the wording referred to a file that no longer exists. Updates both references so a reader is not sent to a deleted registry. Also re-anchors the coordination claim row onto main's current version of that keyed record, reapplying only this row's scoped edit so every unrelated claim survives byte-for-byte. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
FOLLOWING_AGENTS_PROTOCOL
Adds the Muse Glimmer vision tower as an additive TU, ported from the row's
declared off-pin anchor vllm PR #51655 head `075d645af`
(vllm/model_executor/models/muse_glimmer.py:555-1044; spec §0,
porting-inventory §9 deviation 16):
_patchify :902-935 -> MuseGlimmerVisionPatchify
_get_pos_emb :761-820 -> MuseGlimmerVisionPosEmbedInterpolate
_make_2d_rope :741-759 -> MuseGlimmerVisionRopeCosSin
_get_sparse_permutation :844-867 -> MuseGlimmerVisionSparsePermutation
_pixel_shuffle_downsample :822-842 -> MuseGlimmerVisionPixelShuffle
Encoder.forward :937-1034 -> MuseGlimmerVisionForward
VisionAdapter.forward :1036-1044 -> MuseGlimmerVisionAdapterForward
Routed through the existing seams — vt::{MatmulBT,Add,LayerNorm,GeluErf,
RopeFromCache,Attention,IndexSelect} and the shared merged-QKV fold
vllm::models::FusedMergedQkvBiasSplit. No parallel path was hand-rolled.
GATE (CPU, Release, VLLM_CPP_CUDA=OFF), run serially:
tests/vllm/models/test_muse_glimmer_vision.cpp, 7 cases / 98 assertions GREEN.
Every stage is compared against a torch reference derived from the upstream
formulas by scripts/mm/muse_glimmer_vision_ref.py (regenerating it reproduces
the committed goldens byte-for-byte):
patchify (3ch and 6ch) exact
pos-emb bilinear interp exact
pixel shuffle exact
2D RoPE cos|sin max_abs 5.96e-08
ln_pre / block0 / tower f32 rel_l2 1.18e-07 / 1.20e-07 / 1.43e-07
adapter f32 rel_l2 2.98e-07
tower, production bf16 rel_l2 5.95e-03
MUTATION-PROVEN, 15/15 red, tree restored byte-for-byte (md5) after each, and
green again on the restored tree: the width-first 2D RoPE order, 1-based RoPE
positions, the +0.5/-0.5 half-pixel positional convention, per-corner validity
masking, the pixel-shuffle channel transpose, the pixel-shuffle group
permutation, block walk order, within-block token order, patch channel order,
GELU erf-vs-tanh, the LayerNorm bias, window-vs-full layer selection, the
adapter output GELU, the inverse permutation before ln_post, and permuting the
RoPE table alongside the hidden states. Each of these is silent when wrong.
NOT ESTABLISHED, and not claimed. No speed number of any kind: the pinned
oracle cannot load `muse_glimmer`, so there is no denominator. No image or
video end-to-end correctness — that is W4/W5 and needs the checkpoint plus a
reference run. The tower is not wired into ModelRegistry and has no loader;
MuseGlimmerModel::Forward still refuses by name.
Issue: #268
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Ports both parsers from the unmerged vllm#51655 @ 075d645af, with all five upstream test modules ported (26 cases) plus 8 added guards. Gates: test_tool_parser_muse_glimmer 15 cases/35 assertions, test_reasoning_muse_glimmer 19 cases/216 assertions, and all 44 built tool/reasoning/parser suites pass run SERIALLY. RED captured first (15 of 17 cases failed against stubs). 7/7 mutations red with the tree restored byte-for-byte each time. Two mutations SURVIVED the first pass -- real coverage gaps, not passing mutants -- and were fixed by splitting normalize_name's two guards so each is independently mutable and adding the header-less channel-switch case, rather than by accepting them. Two upstream defects found and recorded rather than mirrored: _normalize_name contradicts its own test_trailing_segment_unambiguous, and test_muse_glimmer_streaming.py builds the parser with cls.__new__ so every case raises AttributeError before asserting anything. This does NOT make the model serve tool calls: the forward is still refuse-by-name. Only parser behaviour against upstream's own tests is established. No speed claim on any axis. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] # Conflicts: # .agents/coordination.md # .agents/porting-inventory.md # .agents/roadmap_v1.md # .agents/specs/muse-glimmer.md
FOLLOWING_AGENTS_PROTOCOL
Ports the Muse Glimmer TEXT tower from vllm#51655 head `075d645af`
(models/muse_glimmer.py:1046-1345, :1615-1621), replacing the W0
refuse-by-name forward. Structurally mirrors gemma2.cpp with the six
deltas spec §9 names, each a place a wrong port stays coherent:
1. WEIGHTLESS `embed_norm` (:1286) in the slot where Gemma multiplies
by sqrt(hidden). Realized as vt::RmsNorm against a ones weight.
2. SPLIT eps: pre-norms `rms_norm_eps`, post-norms `post_norm_eps`
(:1236-1247). The two post-norms stay STANDALONE (no residual add),
so kFusedAddRmsNorm would be an incorrect fold. The FINAL norm has
NO `+1` offset unlike the four sandwich norms, so it runs the
gemma=false recipe (kFusedAddRmsNormStd).
3. Softmax scale is plain head_dim**-0.5 (:1112), never folded with
the query pre-scale.
4. iRoPE (:1114-1116, :1167-1168): `no_rope_layers[l]==1` gets RoPE
AND the sliding window; `==0` gets NoPE AND full attention. The
window rides the same flag.
5. The attention output gate (:1202-1206) reads the NORMED LAYER
INPUT, not the attention output, via vt::SigmoidGateBf16.
6. SwiGLU via layers::UnquantizedMlpGateUpMethod, untied lm_head,
`output_multiplier` BEFORE the final soft-cap.
The loader now materializes the text tower through the same
`NormalizeMuseGlimmerWeightName` the W0 accounting uses, in both
checkpoint conventions. The perception encoder is still W3, so a Muse
Glimmer forward is text-only. The KV-cache spec's W0 "placeholder" note
is resolved: both layer classes share one KV geometry and differ only in
window, which is applied at the attention-kernel level exactly as
Gemma-2 does, so one full-attention group is correct.
GATE (CPU-only, no checkpoint, RED captured first against the W0
refuse-by-name forward: 12/13 cases red):
test_muse_glimmer_text 16/16 cases, 324/324 assertions
test_muse_glimmer_scaffold 11/11 cases, 73/73 assertions (unchanged)
The gate compares the whole text forward against an fp32 reference
transcribed independently from the upstream python (max|diff| 1.21e-4 on
logits of max 4.88e-2; 5.28e-6 on a biting-soft-cap variant that pins the
multiplier/cap order), plus a property test per mechanism and a synthetic
safetensors loader round-trip in both naming conventions.
18 mutations were applied in tree, each confirmed RED, then restored
byte-for-byte: 13 on the forward (embed_norm, split eps, the +1 offset on
the sandwich norms, an offset on the final norm, inverted iRoPE, the
window on NoPE layers, QK-norm, the query pre-scale, a gemma2-style
folded softmax scale, the gate source, GeGLU-for-SwiGLU, multiplier/cap
order, and folding a post-norm onto the residual) and 5 on the loader
(legacy norm rename order, the attention-gate rename, the lm_head
transpose, and both merged-shard orders).
NOT ESTABLISHED. No checkpoint was run, so there is no token-exact or e2e
claim; that is W2. NO speed claim of any kind is possible: the parity pin
`555967922` contains no `muse_glimmer`, so the oracle cannot load the
model and there is no denominator (spec §0). The full CPU suite was not
run here (three agents shared the box); the orchestrator runs it centrally.
Issue: #268
Spec: .agents/specs/muse-glimmer.md
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Ports the 50-layer vision tower from the unmerged vllm#51655 @ 075d645af: linear patchify, bilinear positional-embedding interpolation with per-corner validity masking, width-first 2D RoPE, block-windowed attention, pixel-shuffle merge, and the adapter. Gate: test_muse_glimmer_vision 7 cases / 98 assertions, serial, clean -Werror. RED captured first. Per-stage numerics against a torch reference derived from the upstream formulas: patchify, positional interpolation and pixel shuffle are EXACT (0 rel_l2); RoPE 2.0e-08; ln_pre 1.2e-07; block 0 1.2e-07; tower 1.4e-07; adapter 3.0e-07. f32 gates assert < 1e-6, tightened after measuring rather than loosened. Production bf16 tower 5.95e-03. 15/15 mutations RED with the tree restored byte-for-byte each time, covering every trap the spec names: the width/height RoPE swap, the half-pixel convention, per-corner validity masking, both pixel-shuffle permutations, and window ordering. The mutation battery also exposed a real defect in the implementation: the seq_lens coverage check ran AFTER the slicing loop, so an out-of-bounds mutant hung rather than failing. Moved before the loop and all 15 re-run against the final tree. The tower is NOT wired into ModelRegistry and has no loader; the model forward still refuses. This establishes per-stage numerics against a computed reference, NOT image or video e2e correctness, and no speed axis. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…rs landed W3 flagged this as stale and it was: the vision tower and both parsers are implemented and gated, so "spec only, no code" understated what shipped while the neighbouring rows already described them. The replacement stays narrow on purpose. It says the towers and parsers are gated in isolation and that the text forward is absent so nothing runs end to end, which is exactly what the evidence supports -- verified here by re-running all four gates myself on the merged tree: scaffold 73, vision 98, tool parser 35, reasoning parser 216, all passing. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
… the checkpoint
FOLLOWING_AGENTS_PROTOCOL
Three config defects, each verified against the RELEASED
meta-models/Muse-Glimmer-30B `config.json` rather than against the
upstream python, and each of the silent kind: the parse produced a
plausible model and no error.
1. iRoPE. The released config ships NO `no_rope_layers` at all. It
encodes the split twice instead: `text_config.layer_rope_theta[i] == 0`
marks a NoPE layer, and `text_config.layer_types[i] ==
"full_attention"` marks the same one. W0 ignored both and used the
backward-counted default, which AGREES at L=52 purely by arithmetic
coincidence. Now derived from the checkpoint, with the counted default
kept only as the fallback. When both encodings are present they must
agree, and a per-layer theta that disagrees with
`rope_parameters.rope_theta` is rejected rather than applied with the
wrong base (we thread one theta into the forward).
2. Vision field spellings. The vision block ships `merge_size`, not
`merge_kernel_size`, and ships NEITHER `output_dim` NOR `adapter_dim` —
those are top-level `out_hidden_size` (6144) and
`projector_hidden_size` (4096). W0 read only the old names and fell
back to defaults that coincidentally equal the real values, so the
`output_dim == hidden * merge^2` assertion was passing by luck. Both
spellings are now accepted, checkpoint-first.
3. Vision `layer_types`. The checkpoint spells the non-full class
"window_attention"; the default generator emitted "sliding_attention".
Every consumer compares against "full_attention" as upstream does, so
the default now emits the checkpoint's spelling and either reads the
same.
Gated by a hardcoded fixture of the released config (no NAS dependency,
runs in CI), asserting the real geometry, the 1e-5/1e-8 split eps, the
pre-folded 3.87 query pre-scale at head_dim 128, both absent flags
reading ON, the derived iRoPE mask, and the vision spellings.
test_muse_glimmer_text 19/19 cases, 423/423 assertions
test_muse_glimmer_scaffold 11/11 cases, 73/73 assertions (unchanged)
Six mutations applied in tree, each confirmed RED, then restored
byte-for-byte: the derivation dropped, the two-encoding agreement check
dropped, the per-layer theta check dropped, and each of the three field
spellings left unread. The `adapter_dim` assertion initially survived its
mutation (4096 is also the default), so a control was added that changes
`projector_hidden_size` and requires the parse to follow.
NOT FIXED HERE, and handed back: the vision attention biases are missing
from `EnumerateMuseGlimmerTensors`, and the checkpoint ships SEPARATE
`attn.{q,k,v}_proj` where the enumeration expects a merged `attn.qkv_proj`,
so vision layers under-count. Both need the enumeration changed, which
`test_muse_glimmer_scaffold` pins (`attn.qkv_proj.weight`) and which this
lane must not edit. They belong with the W3 vision tower, which has to
decide merged-vs-separate anyway.
Issue: #268
Spec: .agents/specs/muse-glimmer.md
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Replaces the refuse-by-name forward with the real 52-layer text tower ported from the unmerged vllm#51655 @ 075d645af: sandwich norms with the baked +1 and split pre/post eps, iRoPE, weightless pre-RoPE QK-norm, the query pre-scale, and the attention output gate. Gate: test_muse_glimmer_text 19 cases / 423 assertions, scaffold 73 unchanged. RED captured first (12 of 13 cases red against the refuse-by-name forward). The whole forward is compared against an fp32 reference transcribed independently from muse_glimmer.py: max|diff| 1.21e-4 on logits of max 4.88e-2. 24 mutations all RED with the tree restored byte-for-byte: 13 on the forward, 5 on the loader, 6 on config. Two initially SURVIVED and exposed real test defects rather than passing mutants -- qkv shard order was unchecked, and the adapter_dim assertion could not distinguish a read from a fallback because 4096 is also the default. Both fixed. Also fixes three defects in the W0 config parse, verified against the released checkpoint and pinned by a hardcoded fixture: the checkpoint does not ship no_rope_layers at all but encodes iRoPE as layer_types plus layer_rope_theta (0 marks a NoPE layer), and vision uses merge_size with out_hidden_size / projector_hidden_size at top level. W0's derived default agreed by luck. Upstream detail mirrored and gated: the final norm has NO +1 offset while all four sandwich norms do. No checkpoint was run -- evidence is unit-level. No token-exact or e2e claim, and no speed axis. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] # Conflicts: # docs/FEATURES.md # docs/USAGE.md # tests/CMakeLists.txt
Brings in 17 commits of main and resolves one conflict in docs/USAGE.md. The resolution matters: the three W1/W3/W7 helper branches were cut from 9ade113, which predates the commit that moved the model-path guidance out of docs/USAGE.md and into .agents/environment.md. Merging them silently restored the removed section. This merge drops it again and keeps main's operator-role text, so the rule lives in setup material and .env.example only, as intended -- docs/USAGE.md is for people using vllm.cpp, not for how we provision a dev box. Verified after resolution: 0 occurrences in docs/USAGE.md, present in .agents/environment.md and .env.example. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
An image or video prompt no longer refuses. The perception encoder now loads
off the checkpoint, its output is projected into the text hidden space, and the
soft tokens are masked-scattered onto the image (200092) and video (200091)
placeholder rows, consumed by a new registered mm forward branch.
Ported from vllm#51655 head 075d645af (muse_glimmer.py:1440-1613: __init__,
_encode_pixel_groups, _process_{image,video}_input, embed_multimodal, forward,
plus the inputs_embeds branch at :1311-1315). That is an OPEN, CI-red upstream
PR, NOT the parity pin 555967922, which contains no muse_glimmer at all:
porting-inventory section 9 deviation 16, specs/muse-glimmer.md section 0.
THE BUG THIS FIXES
EnumerateMuseGlimmerTensors declared one MERGED
`vision_encoder.transformer.N.attn.qkv_proj.weight` per vision layer and no
vision attention bias at all. It was mirroring upstream's QKVParallelLinear
MODULE name rather than the checkpoint's on-disk names: the released
meta-models/Muse-Glimmer-30B ships SEPARATE attn.{q,k,v}_proj and attn.proj,
each WITH a bias, and upstream fuses the three shards at LOAD time through
packed_modules_mapping (:1427-1430). The enumeration is the checkpoint's
contract, so it now names what the file ships; the q|k|v merge moved into the
loader, where upstream does it too. Left as it was, the loader would have
demanded a tensor no checkpoint contains and the structural accounting pass
would have reported the tower as partly missing instead of saying so.
THE REAL-CHECKPOINT STRUCTURAL GATE
tests/vllm/models/test_muse_glimmer_wiring.cpp asserts that every name the
enumeration produces exists in the released 1436-tensor index at the shape the
resolved config predicts, and that NOTHING in the checkpoint is unaccounted.
Result: 1436 of 1436, zero unaccounted, zero dropped. It runs off a committed
HEADER-ONLY fixture (tests/vllm/models/fixtures/muse_glimmer_30b/) so CI never
needs the NAS; a second case re-reads the live safetensors headers when
VLLM_MUSE_CKPT points at the checkpoint and requires the fixture to match it
tensor for tensor. No tensor bytes are read on either path.
WHAT IS AND IS NOT ESTABLISHED
Established: the enumeration matches the real checkpoint; the tower loads with
the q|k|v merge order and every bias; the soft tokens land on the placeholder
rows and nowhere else; the registered mm forward runs an image prompt; and the
text path through the mm seam is BIT-IDENTICAL to the text path (0 of 704
logit words differ).
NOT established: image or video end-to-end correctness. The pinned oracle
cannot load muse_glimmer, so there is no reference decode to compare against.
Reachability is not an answer. NO SPEED AXIS IS CLAIMABLE for this model on any
arm, and none is claimed here.
The text path is unchanged: the mm pointer only gates which of two ways the
hidden stream is filled, and test_muse_glimmer_text (19/19),
test_muse_glimmer_vision (7/7) and both parser gates pass unchanged.
MUTATION EVIDENCE (each applied in tree, rebuilt, run, restored byte-for-byte)
recorded in the session report; the four the gate must catch are the q|k|v
shard order, a dropped vision attention bias, a scatter mask that ignores the
video placeholder, and the projector order.
Named residual: the W3 tower owns host-f32 weight structs, so the loader widens
the checkpoint's bf16 vision bytes to f32 (about 3.7 GiB to 7.4 GiB at the 30B
scale). Collapsing it means teaching the tower a bf16 weight struct, which is a
change to the sibling-owned tower gate.
Issue: #268
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…cks us against it Establishes the first evidence for this model that comes from the actual released checkpoint rather than a synthetic fixture. scripts/mm/muse_glimmer_text_ref.py is a standalone torch transcription of vllm#51655 head 075d645af. It needs no transformers support for model_type muse_glimmer, which matters because nothing on either box can load this model: released transformers does not register the type (the checkpoint declares 5.15.0.dev0), it ships no remote-code modelling file, and the parity pin has no muse_glimmer at all. The script streams ONE decoder layer at a time, so a 55.7 GB tower runs in about 7 GB. Full-depth 52-layer reference on the real weights, prompt "The capital of France is": argmax [" key", " of", " the", " is", " Paris"], last-position top-2 17.086 vs 13.445, |logit| max 18.66 under the 20.0 soft cap. A coherent and correct continuation is good evidence the transcription is faithful to the checkpoint. It also independently confirms two things W0/W1 had to infer: scale_query_by resolves to 3.87, and the derived iRoPE mask agrees with the checkpoint's own layer_types/layer_rope_theta encoding. test_muse_glimmer_real_weights.cpp checks our loader and text forward against that reference: config agreement, tensor accounting, finite logits bounded by the soft cap, argmax equality, and a logit max-abs and cosine comparison. Every case SKIPs cleanly when its env var is unset, so CI never depends on a 60 GB asset; only the small JSON summary is committed. What this is NOT: not token-exact against the model's own runtime, because no such runtime exists here to be exact against -- it is agreement with an independent transcription of the same upstream source. And not a speed result on any axis; no denominator exists. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Fixes the enumeration to match the real checkpoint (separate vision
attn.{q,k,v}_proj WITH biases, not a merged qkv_proj), loads the vision
weights, and wires the tower into the registered mm forward so an image
prompt no longer refuses.
NOTE: the agent committed this and was cut off by an API session limit
before running its mutation battery, so the mutation proofs for this
commit are OWED, not done. The orchestrator re-runs the gates directly.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
A standalone torch transcription of vllm#51655 head 075d645af, streaming one decoder layer at a time so the 55.7 GB tower runs in ~7 GB, plus the test that checks our loader and forward against it. Full-depth 52-layer reference on the released checkpoint, prompt "The capital of France is": argmax [" key", " of", " the", " is", " Paris"], last-position top-2 17.086 vs 13.445, |logit| max 18.66 under the 20.0 soft cap. It also independently confirms scale_query_by 3.87 and that the derived iRoPE mask agrees with the checkpoint's own layer_types/layer_rope_theta. Env-gated so CI never needs the 60 GB asset; only the small JSON summary is committed. NOT token-exact against the model's own runtime -- none exists on either box to be exact against. Agreement with an independent transcription of the same upstream source is a weaker claim than a true oracle gate, and is stated as such. No speed axis. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] # Conflicts: # tests/CMakeLists.txt
An image or video prompt no longer refuses. The perception encoder now loads
off the checkpoint, its output is projected into the text hidden space, and the
soft tokens are masked-scattered onto the image (200092) and video (200091)
placeholder rows, consumed by a new registered mm forward branch.
Ported from vllm#51655 head 075d645af (muse_glimmer.py:1440-1613: __init__,
_encode_pixel_groups, _process_{image,video}_input, embed_multimodal, forward,
plus the inputs_embeds branch at :1311-1315). That is an OPEN, CI-red upstream
PR, NOT the parity pin 555967922, which contains no muse_glimmer at all:
porting-inventory section 9 deviation 16, specs/muse-glimmer.md section 0.
THE BUG THIS FIXES
EnumerateMuseGlimmerTensors declared one MERGED
`vision_encoder.transformer.N.attn.qkv_proj.weight` per vision layer and no
vision attention bias at all. It was mirroring upstream's QKVParallelLinear
MODULE name rather than the checkpoint's on-disk names: the released
meta-models/Muse-Glimmer-30B ships SEPARATE attn.{q,k,v}_proj and attn.proj,
each WITH a bias, and upstream fuses the three shards at LOAD time through
packed_modules_mapping (:1427-1430). The enumeration is the checkpoint's
contract, so it now names what the file ships; the q|k|v merge moved into the
loader, where upstream does it too. Left as it was, the loader would have
demanded a tensor no checkpoint contains and the structural accounting pass
would have reported the tower as partly missing instead of saying so.
THE REAL-CHECKPOINT STRUCTURAL GATE
tests/vllm/models/test_muse_glimmer_wiring.cpp asserts that every name the
enumeration produces exists in the released 1436-tensor index at the shape the
resolved config predicts, and that NOTHING in the checkpoint is unaccounted.
Result: 1436 of 1436, zero unaccounted, zero dropped. It runs off a committed
HEADER-ONLY fixture (tests/vllm/models/fixtures/muse_glimmer_30b/) so CI never
needs the NAS; a second case re-reads the live safetensors headers when
VLLM_MUSE_CKPT points at the checkpoint and requires the fixture to match it
tensor for tensor. No tensor bytes are read on either path.
WHAT IS AND IS NOT ESTABLISHED
Established: the enumeration matches the real checkpoint; the tower loads with
the q|k|v merge order and every bias; the soft tokens land on the placeholder
rows and nowhere else; the registered mm forward runs an image prompt; and the
text path through the mm seam is BIT-IDENTICAL to the text path (0 of 704
logit words differ).
NOT established: image or video end-to-end correctness. The pinned oracle
cannot load muse_glimmer, so there is no reference decode to compare against.
Reachability is not an answer. NO SPEED AXIS IS CLAIMABLE for this model on any
arm, and none is claimed here.
The text path is unchanged: the mm pointer only gates which of two ways the
hidden stream is filled, and test_muse_glimmer_text (19/19),
test_muse_glimmer_vision (7/7) and both parser gates pass unchanged.
MUTATION EVIDENCE (each applied in tree, rebuilt, run, restored byte-for-byte)
recorded in the session report; the four the gate must catch are the q|k|v
shard order, a dropped vision attention bias, a scatter mask that ignores the
video placeholder, and the projector order.
Named residual: the W3 tower owns host-f32 weight structs, so the loader widens
the checkpoint's bf16 vision bytes to f32 (about 3.7 GiB to 7.4 GiB at the 30B
scale). Collapsing it means teaching the tower a bf16 weight struct, which is a
change to the sibling-owned tower gate.
Issue: #268
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Our text tower agrees with an independent torch transcription on the released checkpoint at reduced depth: argmax identical, max abs logit difference 0.0889745, cosine 0.999981, 1010282 assertions. Also records the verification trap this exposed: with the env gates unset the same binary reports 3 cases passed / 15 assertions and looks green while comparing nothing, because the heavy cases return early and doctest counts them passed rather than skipped. The assertion count is the tell. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…ward
Brings in the wiring agent's completed work: the enumeration now names the
tensors the checkpoint actually ships (separate vision attn.{q,k,v}_proj WITH
biases, not a merged qkv_proj, with the q|k|v fold moved into the loader), the
vision tower loads, and the registered mm forward scatters projected soft
tokens onto the image/video rows.
Enumeration accounts for 1436 of 1436 real-checkpoint tensors, zero
unaccounted, verified against both a committed header-only fixture and the live
safetensors headers. Six mutations RED with byte-for-byte restore; one
initially escaped and drove a new bf16-exact scale probe before going RED.
Text path proven bit-identical through the mm seam: 0 of 704 logit words
differ between Forward and ForwardMm.
Establishes reachability, NOT image or video correctness: no reference decode
exists because the pinned oracle cannot load muse_glimmer. No speed axis.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…ting gap
Two things learned after the real-weights harness landed, both belonging in
the record rather than in a report that scrolls away.
The full 52-layer reference was rerun on a GB10 with --device cuda, same
checkpoint and same prompt, and produced the identical argmax stream with a
per-layer |x| trace matching the x86 CPU run to four decimals. So the
" Paris" continuation is not an artifact of one accumulation path: x86 torch,
GB10 torch and our C++ CPU forward all land on the same five ids. The golden
now says so, and says in the same breath that all three are still ports of
the SAME upstream source, so they cannot rule out a shared misreading of
vllm#51655. Only Meta's runtime or the merged upstream can.
The full multimodal checkpoint also does NOT close its tensor accounting:
1086 accounted against 1136 enumerated, short by exactly 50, one per
perception-encoder layer. EnumerateMuseGlimmerTensors declares a merged
vision attn.qkv_proj.weight, but the checkpoint ships separate
attn.{q,k,v}_proj.weight and NormalizeMuseGlimmerWeightName does not fuse
them -- upstream's orig_to_new_stacked is a load-time stacking, not a name
rewrite. Separately the enumeration declares no vision attention biases while
upstream builds qkv_proj and o_proj with bias=True (muse_glimmer.py:573-588)
and the checkpoint ships 200 of them. Neither touches the text tower, which
loads and forwards correctly, and both live in a file this branch does not
own, so the test reports them and asserts the text-tower names directly
instead of pinning a shortfall that would go red the moment someone fixes it.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Full 52-layer tower on the released checkpoint, prompt "The capital of France is": our C++ argmax is IDENTICAL to the torch transcription at every position -- " key" / " of" / " the" / " is" / " Paris". max|ours-torch| 0.236, cosine 0.9999, all logits finite and under the 20.0 soft cap. 9m13s wall, peak RSS 52.0 GB. Last-position top-1 leads by 3.64 logits, so this is not a near-tie. Rerunning the reference on the GB10 with --device cuda gives the identical argmax and a per-layer trace matching to 4 decimals. The gate is mutation-proven to have teeth, and one of those mutations is the reason the numeric bound exists rather than a tokens-only check: dropping the weightless QK-norm moves max|diff| to 1.49 and cosine to 0.9953 while leaving the ARGMAX UNCHANGED. A tokens-only gate would have passed a model missing one of the mechanisms this port exists to get right. The vision accounting gap this agent reported (1086 of 1136) was fixed in parallel by the wiring branch, which now accounts 1436 of 1436 real-checkpoint tensors. Still NOT token-exact against Muse Glimmer's own runtime: none exists on any machine we have. Our C++, the CPU reference and the GPU reference are three paths over the SAME upstream source, so their agreement rules out a large class of porting defects but cannot rule out a shared misreading of #51655. No speed axis. Untested: the perception encoder end to end, multi-step decode, and the sliding window (the prompt is 5 tokens against a 2048 window). FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Two conflicts, both resolved by taking main's content and reapplying only this row's scoped edit. .agents/roadmap_v1.md is a keyed record: main's version taken wholesale and the #268 issue row reapplied, verified to delete none of main's rows. docs/USAGE.md was a false conflict between two adjacent, unrelated sections; both are kept. The Muse paragraph was also corrected in place: it still said no output of this model had been checked against a reference, which stopped being true when the full-depth real-weights comparison landed. It now says what is actually established -- the text tower matches a torch transcription of the upstream source token for token on the released checkpoint, that this is not the model's own runtime, and that the perception encoder has no such check. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
The spec said no gateable reference existed. That was wrong, and this
corrects it.
HF's Muse Glimmer implementation is on the `exportable-muse` branch of
huggingface/transformers (a9e337e8, 5.16.0.dev0) -- NOT the
`new-model-addition-onyx` name vllm#51655's comment gives, which exists
neither as a branch nor as a repo. The branch carries the full
models/muse_glimmer set plus muse_glimmer_assistant.
Installed on dgx at $HOME/venvs/muse-onyx, isolated: the pinned oracle venv
is untouched and the new venv reuses its torch through a .pth fallback
rather than pulling a second CUDA build. muse_glimmer registers and
AutoConfig resolves the released 52-layer config. It registers under the
MULTIMODAL AutoModel classes, so AutoModelForCausalLM rejects it.
At reduced depth (4/52) on the real weights, prompt "The capital of France
is", three independent implementations agree on
[27389, 110709, 32485, 122967, 152652]:
HF reference vs our transcription : argmax identical, max 0.117212, cos 0.99997157
our C++ vs our transcription : argmax identical, max 0.0889745, cos 0.999981
That is stronger than the previous evidence, which was agreement between two
things we wrote from the same upstream source. This adds a third-party oracle.
The full 52-layer HF run is OWED: dgx had a live vllm serve holding most of
the 119 GB unified pool, leaving ~37 GB against a 60 GB load, and a GB10 OOM
can reboot the box. That job did not hold ${GPU_LOCK}, so the mutex protected
nothing; the bounded run was chosen deliberately over risking someone else's
work.
No speed axis is claimable on any dimension, and the perception encoder still
has no reference check.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Routine sync, no conflicts. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Routine sync. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
This row bumped the MODEL count 361 -> 362 for Muse Glimmer, which is a checker semantic change, and the size gate correctly refused it without mutation evidence. Mirrors the existing ENGINE ratchet test, and for a sharper reason: MODEL is the count that actually moves, since every new architecture re-pins it by hand. Without a test, bumping the number to silence a failure looks exactly like bumping it because a row really landed. Asserts BOTH directions -- a pin one below the tree and one above it must each be an error -- so a count can never be inflated ahead of the rows that justify it. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Routine sync. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
`LoadMuseGlimmer` threw "does not support GGUF weights". That was never a
decision -- the quantized arm simply was not on any list, while a 30B bf16
checkpoint is ~60 GB against a ~17 GB k-quant, so for this model the k-quant is
the arm most users can run at all. The porting checklist's §2 now makes it a
rule; this closes it for Muse Glimmer.
GGUF gets its OWN translation unit, mirroring qwen3_5_gguf_weights.cpp, and
targets the same MuseGlimmerWeights the safetensors loader produces, so the
shared forward is untouched. `LoadMuseGlimmer` gains one branch and the
entrypoint's GGUF architecture dispatch gains one arm.
THREE CONVERT-TIME TRANSFORMS, each verified byte-for-byte against the released
bf16 safetensors rather than inferred from names:
1. The sandwich norms are stored PRE-OFFSET. GGUF blk.0.attn_norm.weight[0] is
1.09619141; safetensors layers.0.input_layernorm.weight[0] is 0.09619141.
Exactly w_hf + 1, for all four sandwich norms. Our forward adds the +1 via
RmsNormArgs{gemma=true}, so the loader subtracts one. output_norm takes no
offset in the model, is stored raw, and must NOT be un-shifted.
2. The query pre-scale is FOLDED INTO attn_q_norm. ggml has no weightless
RMSNorm, so the converter materializes attn_k_norm as ones and attn_q_norm
as the constant 3.87, which is exactly text_config.qk_scale_factor. No
metadata key carries it, so scale_query_by is recovered from that tensor,
checked constant on all 52 layers; a non-constant q-norm or a non-ones
k-norm is refused rather than averaged into a plausible wrong model.
3. The iRoPE mask rides attention.sliding_window_pattern: true = RoPE plus
sliding, false = NoPE plus full attention, agreeing with the safetensors
config's layer_types and layer_rope_theta (NoPE at 3, 7, ... 51).
RESIDENCY, stated rather than assumed. Kept quantized: o_proj, the attention
output gate, down_proj, and the merged gate_up as a block concat when ffn_gate
and ffn_up share a ggml type (a k-quant row is a whole number of superblocks, so
the merge is a byte concatenation). Dequantized, each for a structural reason:
the merged QKV, because the file's attn_v is Q6_K while attn_q/attn_k are Q4_K
and two block encodings cannot share one tensor; lm_head, because the forward
consumes it via vt::Matmul in [H, vocab] and a block encoding cannot be
transposed without requantizing; the embedding table, because it is a gather;
the norms, because of the -1 value transform.
EVIDENCE. The released muse-glimmer-30B-kquant-17gb.gguf loads: 731/731 tensors
accounted with zero unaccounted in BOTH directions, all 52 layers materialized
at the right shapes, layer-0 input_layernorm min = -1.0 (matching the
safetensors' own min, so the un-shift demonstrably fired), scale_query_by 3.87
recovered on every layer. The 19.65 GB mixed-type dynamic file accounts
identically. tests/vllm/models/test_muse_glimmer_gguf.cpp: 12/12 cases, 362
assertions with no asset, 428 with VLLM_MUSE_GGUF, 636 on the full-load case,
against committed header-only manifests of the real 731/809/58-tensor files so
CI never needs the 16.76 GB payload. RED-first: the same gate was 3 passed /
8 failed against a throwing stub. 11 mutations each proven RED with the tree
restored byte-for-byte (norm un-shift, blanket un-shift onto the final norm,
pre/post-ffn name swap, output-gate/MLP-gate collision, non-constant q-norm
accepted, non-ones k-norm accepted, dropped GGUF-only enumeration, inverted
iRoPE polarity, swapped QKV row order, mislabelled lm_head orientation,
inverted tied-head decision).
REFUSED AND OWED, not quietly skipped. The released mmproj-kquant.gguf maps
cleanly for every tower tensor except one: v.patch_embd.weight is ne
[14, 14, 3, 1536] = torch [1536, 588], while conv1_linear needs
patch_temporal * 3 * patch^2 = 1176 input features and the safetensors ships
exactly [1536, 1176]. The patch_temporal axis is absent from the file, so the
perception encoder refuses BY NAME and image/video keep using safetensors; the
fix is upstream in the llama.cpp converter. The dflash drafter needs NO new
seam: all 58 of its tensors are covered by the already-landed qwen3_dflash_gguf
name map, and it ships neither token_embd nor output because it shares the
target's, which the text GGUF provides. That is reachability only; an
acceptance-rate run is owed.
NAMED RESIDUAL. The GGUF carries no post_norm_eps key, so the post-norms fall
back to rms_norm_eps (1e-5 vs the safetensors' 1e-8). Inside
1/sqrt(mean_square + eps) that is ~5e-6 relative, two orders of magnitude below
bf16's spacing, so it is not representable in the activation dtype. Recorded
rather than hidden.
NOT ESTABLISHED. No forward was run on GGUF weights: no e2e, no token-exactness,
and no numeric comparison against the bf16 arm (owed). No speed axis of any kind
exists for this model in either weight format, because the pinned oracle cannot
load muse_glimmer at all, so there is no denominator and none is claimed.
Tracked under #268. Inertness: test_muse_glimmer_{scaffold,text,vision,wiring,
real_weights}, both parser gates, test_model_registry, test_model_loader_gguf,
test_gguf and test_gguf_keep_quant all unchanged and green.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…top a header claiming a gap does not exist PR #279 review findings, worked from reviewed head 774c44d. Three of them were COVERAGE HOLES: a mutation that stayed GREEN, which means a shipped guarantee had no test at all. Those are the substance here; the rest is telling the truth in records that had drifted. 1. `perception_emb_norm` was entirely untested. No config in the tree set `normalize_tok_embeddings`, so muse_glimmer_mm.cpp:217 never ran, and the scatter case compared merged rows against the same `soft` vector it had just computed -- structurally blind to what EncodePixelGroups did to it. Inverting the condition, or deleting the call, left the wiring gate GREEN. The new case runs the IDENTICAL tower twice, flag off and flag on, so the norm is the only difference, and requires the soft tokens to stand in the exact relation the weightless RMSNorm defines, with a control proving the norm is not a no-op at this geometry. INVERT -> 18 assertions RED; DROP -> 17 RED; 8 of 9 cases still pass either way, which is the hole itself. 2. The whole non-FusedChain fallback arm was dead. FusedChainAdoptEnabled() defaults ON and is read once per process into a function-local static, so the three `else vt::RmsNorm(...)` branches never executed under test, and a same-process env flip cannot reach them either. tests/CMakeLists.txt now registers the text binary a SECOND time as test_muse_glimmer_text_fallback with VT_FUSED_CHAIN_ADOPT=0, so the whole gate -- fp32 reference comparison included -- runs on both arms; a case inside the binary asserts which arm it took, so the second registration cannot silently repeat the first. Wrong eps on the input-layernorm fallback: default arm 21/21 GREEN, fallback 1 RED. `gemma=true` on the final-norm fallback: default arm 21/21 GREEN, fallback 59 RED. 3. RoPE theta was ungated at a realistic magnitude. Every case ran at positions 0..4 with head_dim 4, where 5e5 and 1e4 differ by milliradians -- under the reference band -- so the exact "forgot to read the config" bug passed and only an absurd base (2.0) went red. The new case moves to positions 0..4096 and pins the base three ways: it matches its own reference, does NOT match a 1e4 reference, and the two configs cannot produce the same logits. Base 10000 -> 4 assertions RED, and it is the only failing case. Every mutation was applied in-tree, built, run, then restored from an in-memory snapshot with `git diff` on src/ verified empty before re-running green. No src/ file is modified by this commit. Also closed: * The real-weights gate had demoted CHECK(accounted == enumerated) to a MESSAGE whenever vision.present, over a 50-tensor shortfall the W4 enumeration correction already fixed. A conditional assertion is a disarmed one; re-armed. The same guarantee runs without the NAS in test_muse_glimmer_wiring, which asserts it on a multimodal checkpoint. * Both parser headers justified dropping upstream's `adjust_request` by claiming the seam has no `skip_special_tokens`. That is FALSE: protocol.h:240 and :461 declare it true and detokenizer.cpp:68 honours it, and the checkpoint marks <|start|> 200022, <|message|> 200023, <|eom|> 200007 and <|eot|> 200008 special. So at server defaults the ATEM framing is stripped before either parser runs and channel scoping cannot work. The seam has no `adjust_request` dispatch site at all, so this is a pre-existing seam gap, NOT built here -- recorded as an OPEN GAP in spec 6.7, FEATURES and USAGE instead of papered over. This is visible debt and owes its own issue and row. * USAGE said the text tower "matches it token for token" on the released checkpoint while FEATURES said "no checkpoint run". Both were wrong. What ran is reduced depth 4 of 52, five prefill argmax positions, not generated tokens, against transcriptions rather than the model's own runtime. Both documents now say that, and USAGE's new section no longer splits the modelopt_mixed paragraph off from the quantization section it belongs to. * model-matrix and coordination described a branch with "no forward, no weights" while it ships two towers, mm wiring and two parsers. Corrected, without advancing the lifecycle token -- see below. * .env.example and environment.md asserted CHECKPOINT_ROOT behaviour that has zero consumers in the tree. Softened to the intent they actually carry. * The scaffold test gained its 075d645af anchor and names the two upstream config-test modules it ports, plus the one harness adaptation. LEFT OPEN, deliberately and on the record: the `adjust_request` seam (6.7); the docs/STATUS.md and .agents/NOW.md rows, because STATUS sits byte-exactly on its shrink-only ratchet (243451 of 243451) and NOW at 5986 of 6000, so either can only take a Muse row by rewriting another row's binding narrative, which a review-findings fix will not do as a side effect; the lifecycle-token advance, which owes those two rows; and the compact-vs-spaced `arguments` JSON, which is the whole parser family's convention and is documented rather than changed in one parser. NO SPEED CLAIM IS MADE OR IMPLIED ON ANY AXIS. The pinned oracle 555967922 carries no muse_glimmer, so no denominator exists; the axis is an open gap by construction. Nothing here claims e2e, token-exactness against the model's own runtime, image or video correctness, or multi-step decode. Gates, CPU-only Release, run serially: test_muse_glimmer_scaffold 11/11 cases, 81 assertions test_muse_glimmer_vision 7/7 cases, 98 assertions test_muse_glimmer_text 21/21 cases, 487 assertions test_muse_glimmer_text_fallback 21/21 cases, 487 assertions (ADOPT=0) test_muse_glimmer_wiring 9/9 cases, 10,316 assertions test_muse_glimmer_real_weights 3/3 cases, 15 assertions (fixtures absent -- the no-op count; the re-armed assertion is NOT runtime-verified here) test_tool_parser_muse_glimmer 15/15 cases, 35 assertions test_reasoning_muse_glimmer 19/19 cases, 216 assertions test_model_registry 24/24 cases, 871 assertions ctest -R "muse_glimmer|model_registry": 9/9 passed Record checkers green: model-checklist, agent-record, public-doc-tables, supported-models, doc-checkpoint, now-current, env-doc, test-registration. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
The GGUF k-quant work was tracked only under the parent row; #329 now carries it, including the mmproj blocker (the converter drops the patch_temporal axis, so v.patch_embd is [1536,588] where the model needs [1536,1176]) and the owed numeric comparison against the bf16 arm. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Three of these were COVERAGE HOLES the reviewer found by mutation -- a guarantee with no test at all, where breaking it left every gate green: perception_emb_norm / normalize_tok_embeddings was entirely untested the whole non-FusedChain fallback arm was dead in every test RoPE theta was ungated at realistic magnitude (10000 vs 500000 passed) Each is now RED-first proven: inverting perception_emb_norm turns 18 assertions red where the wiring gate was green; the config-bug theta turns 4 red where text was green; and the fallback arm is registered as a SECOND ctest entry under VT_FUSED_CHAIN_ADOPT=0, with an in-binary assertion on which arm it took so the second registration cannot silently repeat the first (an in-process flip is impossible -- the flag is a function-local static). Also corrects a FALSE justification in shipped headers: they claimed the seam has no skip_special_tokens. It does (protocol.h:240/:461, honoured at detokenizer.cpp:68), and the checkpoint marks the ATEM channel tokens special, so at server defaults the framing is stripped before the parser sees it. The seam gap is real and pre-existing -- no dispatch site exists anywhere -- so it is recorded as visible debt rather than papered over. docs/USAGE.md no longer contradicts docs/FEATURES.md: both now say reduced depth 4/52, 5 prefill argmax positions rather than generated tokens, and against transcriptions rather than the model's own runtime. No src/ file changed. No speed claim anywhere. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Implements the quantized-arm rule added to AGENTS.md today (#318, #329). Muse Glimmer previously refused GGUF outright, which was never a decision. A dedicated muse_glimmer_gguf_weights.cpp -- the shape porting-a-model.md calls for, where GGUF is its own TU rather than an afterthought. Structural accounting: 731 enumerated / 731 present, zero missing, zero unaccounted, BOTH directions, on the live 16.76 GB kquant-17gb file and the 19.65 GB mixed-type kquant-dynamic file. A full load materializes all 52 layers at 29.9 GiB RSS. Three convert-time transforms, each recovered from the data rather than assumed. The four sandwich norms are stored PRE-OFFSET: GGUF attn_norm[0] is 1.09619141 against safetensors 0.09619141, exactly w_hf + 1, so the loader subtracts one -- while output_norm carries no offset and is deliberately NOT un-shifted, a blanket un-shift being a mutation-proven failure. The query pre-scale is folded into attn_q_norm (k-norm all 1.0, q-norm the constant 3.87 = qk_scale_factor) with no metadata key, so it is recovered from the tensor and checked constant across all 52 layers. iRoPE comes from attention.sliding_window_pattern, agreeing with layer_types. 11/11 mutations RED, tree restored byte-for-byte. REFUSED and recorded, not faked: the mmproj perception encoder cannot load because v.patch_embd is [1536,588] where the model needs [1536,1176] -- the patch_temporal axis is absent from the file, which looks like an upstream llama.cpp converter bug rather than a naming problem. Image and video keep using safetensors. No forward on GGUF weights yet, so no e2e and no numeric comparison against the bf16 arm. No speed claim on any axis. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] # Conflicts: # docs/FEATURES.md
Routine sync before landing. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] # Conflicts: # .agents/roadmap_v1.md
main grew the page while this row was in flight, so the Muse entry pushed BENCHMARKS.md to 45014 of its 45000-char budget. Trimmed this row rather than anyone else's: the detail belongs in the spec and #333 anyway, and the scoreboard only needs to say that every axis is an OPEN GAP with no denominator. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…one non-binding leg, and the tokenizer gap that blocks the quant-matched cell FOLLOWING_AGENTS_PROTOCOL Issue #333 asked for whatever speed number could be produced honestly for Muse Glimmer 30B. The answer is: none is binding today, and the reason the llama.cpp cell cannot be filled is now located rather than assumed. * vLLM stays an OPEN GAP by construction (the pin carries no `muse_glimmer`). Nothing was substituted for it and nothing was waived. * llama.cpp master `030ebb5` DOES load and run the released k-quant (pp32 9.79 t/s, tg8 0.79 t/s, `-r 1 -t 4`, CPU). Recorded as NON-BINDING: one repetition is no noise band, and the box carried four other agents' builds at load average 39 to 123 with the root filesystem twice at 100%. `.agents/benchmarking.md` requires the band first and an idle box; neither was available, so this is an artifact of the attempt, not a measurement. * Our GGUF arm cannot generate at all, and the blocker is the TOKENIZER, not the forward: the file declares `tokenizer.ggml.pre = llama4` and `Tokenizer::FromGguf` refuses it (tokenizer.cpp:749). llama.cpp maps that name to `LLAMA_VOCAB_PRE_TYPE_GPT4O` with its own regex pair, so it is a missing pre-tokenizer, not a missing alias -- aliasing it onto kLlama3 or kQwen2 would mistokenize silently. Filed as #347. Consequence: the GGUF is the only artifact both engines can hold, so a quant-matched llama.cpp comparison is NOT possible today. Our bf16 against a 4-bit GGUF would report quantization as speed, so that cell is recorded not-comparable rather than published with a caveat. * Both bf16 cells (HF `exportable-muse` vs ours) are blocked on host availability: dgx's GPU lock was correctly held for the whole window by another session's 27B online-serving gate. It was not interfered with, and no CUDA build was started there either, because a parallel build on the same 20-core host would have perturbed a live serving measurement. No ratio appears anywhere in this change, because no cell has two quant-matched sides. No ceiling is claimed. docs/STATUS.md is a byte-tight ratchet, so the line it owes about the GGUF arm was paid for OUT of the page: the Qwen3.5-4B `Performance detail` paragraph restated percentages and OPEN ratios that already live BOTH in .agents/benchmark-record.md and in the evidence file that paragraph itself links. Each dropped figure was verified present in both surfaces before the duplicate collapsed to its binding result plus the pointer, and the ratchet constant moves DOWN with it (243287 -> 243283), which is the gate closing, not widening. .agents/NOW.md is at its 6,000-char budget, so the closed `Invocation-parity` row -- CLOSED with next step "--", i.e. not a live position -- makes room for the Muse row. Its closure is NOT lost: the `kGemvHeuristicAlgos CUDA build-verify CLOSED` section of .agents/benchmark-record.md names that NOW.md row explicitly, records why it was stale, and carries the `812de8ca` re-verification, and the closed-gaps table in the same file carries the guard's CLOSED line. The row's own table text is not reproduced verbatim anywhere, and does not need to be -- the evidence it pointed at is what had to survive, and it did. Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…binding leg The honest answer to #333 is that no binding speed number exists on any axis, and this records why rather than manufacturing one. vLLM stays an OPEN GAP by construction: the pin carries no muse_glimmer, so there is no denominator, and nothing was substituted for it. llama.cpp master runs the released k-quant on CPU (pp32 9.79 t/s, tg8 0.79 t/s) but at -r 1 on a box at load 39-123, so it is recorded NON-BINDING, with no ratio anywhere. The finding that reshapes the scope: OUR GGUF ARM CANNOT GENERATE, and the blocker is the tokenizer rather than the forward -- tokenizer.ggml.pre is llama4 (GPT-4o family), which we do not implement. llama.cpp maps it to its own regex pair, so aliasing onto kLlama3/kQwen2 would MISTOKENIZE SILENTLY. Filed as #347. Since the GGUF is the only artifact both engines can hold, the quant-matched llama.cpp cell is impossible until that lands; our bf16 against a 4-bit GGUF would report quantization as speed, so that cell is recorded not-comparable instead. Both bf16 cells were blocked by dgx being legitimately busy with another session's serving gate, which correctly held the GPU lock and was not disturbed. No ceiling is claimed anywhere. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
The Muse Glimmer speed entry moved the STATUS char ratchet 243287 -> 243283, which is a checker semantic change, and the size gate correctly refused it without mutation evidence. The shape of that re-pin is the only legitimate one: the page shrank by collapsing a duplicated Qwen3.5-4B paragraph to pay for its own line, so the number shrank with it. The failure worth guarding is the opposite move -- raising the constant to make room -- which turns a shrink-only ratchet into a growth budget and silently stops measuring anything. Proven in both directions: a ratchet below the live page must be an error, and an inflated one must exceed the slack bound that catches it. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Final sync before landing. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
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.
Traces Meta's Muse Glimmer (released 2026-08-08, 30B, Apache-2.0, agentic
multimodal) in vLLM and lands the W0 scaffold: registry, config parse, and weight
name map. No forward, no checkpoint, no GPU, no download.
Closes #268.
Read this part first
The upstream anchor is not the pin. There is no
muse_glimmercode at ourparity pin
555967922—grep -ril 'muse\|glimmer' vllm/model_executor/models/returns nothing — and none on vLLM
maineither. The only implementationanywhere is vllm#51655: OPEN,
approved, 3 of 20 CI checks red, at head
075d645af. Everyfile:linethisPR cites points at that branch head.
This is a deliberate exception to "port from the pinned oracle", taken on
explicit developer direction (2026-08-10), and recorded as deviation 16 in
porting-inventory.md§9 rather than as awaivers.csventry — no checkerenforces the anchor rule, and a waiver naming a checker that does not exist would
be a false record. It owes a re-anchor and a pin advance when #51655 merges.
No speed axis is claimable for this model. The pinned oracle cannot load
muse_glimmerat all (and the checkpoint wants transformers 5.15.0.dev0 vs thepin's 5.14.1), so there is no honest denominator. Every performance axis is an
OPEN GAP by construction, not a waived one. Correctness will gate against the HF
reference instead.
llama.cpp is a secondary reference only. Its support is merged
(#26841) and is useful for
C++ cross-checking, but vLLM stays the baseline and the cited anchor.
What the trace found
Architecturally Muse Glimmer recombines mechanisms we already ship — Gemma-style
sandwich norms, Qwen3 QK-norm, Qwen3.5 gated attention, a Qwen3-VL-shaped vision
tower, and our existing DFlash drafter. iRoPE is the only genuinely new
mechanism (we have no Llama-4). DFlash needs no new drafter at all: upstream
only adds architecture recognition and threads the target's
is_neox_styleintothe draft.
Four traps, all of which produce plausible-but-wrong output rather than an error:
qk_scale_factorships raw (~43.784) or pre-folded (~3.87), disambiguated by magnitudeuse_qk_norm/use_attn_output_gateread as absent, notfalsegetattr(..., False)silently drops both mechanismsguacexports name the PRE-feedforward normpost_attention_layernormFull architecture trace, W0-W7 plan, gates and stop conditions:
.agents/specs/muse-glimmer.md.What W0 implements
Additive TUs only, plus the ledger updates that registering an architecture is
designed to make.
ParseMuseGlimmerParamsdescends the canonical nested layout andnormalizes the older flat one. That normalization is load-bearing: without
it a flat config deserializes to an all-default text config, ignoring every
checkpoint value with no error.
NormalizeMuseGlimmerWeightNameportshf_to_vllm_mapperfor bothcheckpoint conventions.
EnumerateMuseGlimmerTensorsdeliberately omits the three weightlessmodules (
embed_norm, the per-headqk_norm,perception_emb_norm) that shipno tensor; enumerating them would make the loader demand tensors no checkpoint
contains.
instead of returning a silent wrong answer.
Evidence
test_muse_glimmer_scaffold: 11/11 cases, 73/73 assertionsctest: 367/367, zero failures-Werrorbuild;agent-preflight.shgreen; trailer contract OKRED-first mutation proof. Each trap was mutated in tree, rebuilt, confirmed
to turn the gate red, then restored byte-for-byte (verified by an empty
git diff) and re-run green:qk_scale_factortreated as pre-foldeduse_qk_norm/use_attn_output_gatedefaultedfalseLedger changes (no assertion deleted or widened)
Registering two architectures extends the registry-coverage ledgers exactly as
they are built to be extended: registration/
SupportedArchscounts 35 -> 37, thetwo sorted architecture arrays, the golden raise-message lists (also in
test_model_loader_gguf), and the non-hybrid multimodal branch — which MuseGlimmer joins because its iRoPE split is sliding-vs-full attention, not a
recurrent lane.
What this does NOT establish
rides the Gemma-4 per-layer seam and lands with W1.
need a quantized arm.
AGENTS.mdrequires a reviewer who did notwrite the code; this was implemented directly in the coordinating session, so
that step is outstanding.
Records
Row
MODEL-MM-muse-glimmer-muse-glimmer-for-conditional-generationstaysSPIKE— config, name map and registry only. Updated in the same change:model-matrix.md(row + checklist + rollup),roadmap_v1.mdissue table,coordination.mdclaim,porting-inventory.md§9,docs/FEATURES.md(supported-arch rows + "not supported yet"),
docs/USAGE.md(architectures thatresolve but refuse to run).
🤖 Generated with Claude Code