Skip to content

feat(muse_glimmer): serve image input on Muse-Glimmer-30B - #481

Merged
jason-fxz merged 1 commit into
mainfrom
feat/muse-glimmer-mm
Sep 15, 2026
Merged

jason-fxz merged 1 commit into
mainfrom
feat/muse-glimmer-mm

Conversation

@jason-fxz

Copy link
Copy Markdown
Collaborator

Image input for Muse-Glimmer-30B (MuseGlimmerForConditionalGeneration) through the checkpoint's own ViT tower, on the multimodal path and the block weight streamer from #454, following the per-family tower layout of #467 (Gemma-4) and #479 (GLM-5.3).

What

  • Processor. The chat template renders one <|patch|> per image and the checkpoint's processor wraps the expansion itself, so the replacement is <|image_start|> + one content pad id per 28x28 pixels of the resized image (a 2x2 pixel shuffle of 14-pixel patches) + <|image_end|>, 1-D rope. The image processor's only budget is a token maximum (default 4096, aspect ratio kept), so --image-max-tokens passes through as its max_image_tokens; --image-min-tokens has no knob. The wrapper ids live only in the tokenizer, so they are module constants pinned by the tokenizer test.
  • Tower. The 1.85B Perception-Encoder-style ViT: linear patch embedding plus a bilinearly resampled 32x32 position table, 50 LayerNorm blocks with biased q/k/v and 2-D rope (fp32 tables, the NeoX rope kernel) that attend inside 32x32-patch windows except every fourth block and the last one (full attention), a 2x2 pixel shuffle, the GELU adapter, the projection into the 6656 text width and the weightless perception norm, so the soft tokens scatter into the embeddings as the reference's get_image_features. The text side norms its token embeddings before the image rows scatter in, like the reference's NormedEmbedding. Blocks stream from pinned host banks under the default --mm-encoder-weights host: 289 MiB resident instead of 3666 (the tower alone is 3.45 GiB bf16 in both releases, 16% of the NVFP4 checkpoint).
  • Attention. Nothing: the reference keeps 1-D positions and causal attention over image tokens, so the SWA/NoPE layers, the scheduler and the chunking are untouched.
  • Reader. model.vision_tower.*, model.vision_adapter.* and model.vision_projection.* load under vision_tower.* (q/k/v fused into attn.qkv) when an encoder is built and are skipped under --text-model-only, on both the bf16 and the compressed-tensors NVFP4 paths. No new flags; docs/models.md gains the Muse-Glimmer row of the image-input table.

Verification

  • Tower parity against the reference on meta-models/Muse-Glimmer-30B (bf16, a textured 896x616 image so the windows are ragged): mean cosine 0.9925 to the fp32 reference, error 0.98x the reference's own bf16 noise. A tiny random tower matches a reference tower built on the same weights exactly (rope layout, window permutation, pixel shuffle, adapter, norm), without a checkpoint.
  • RedHatAI/Muse-Glimmer-30B-NVFP4 on an RTX PRO 6000 (96 GB), started with ft serve --model-path RedHatAI/Muse-Glimmer-30B-NVFP4 (defaults); /v1/stats reports input_modalities: ["text", "image"] and an image request through the chat API describes the image correctly ("a blue flag with a yellow circle above a red horizontal bar", 256 image tokens for 448x448).
  • Activations: 178 KiB per image token, linear; 710 MiB transient at the 4096-token cap (block MLP fc1 + GELU), 286 ms per max-size image.

Not in this PR

  • Video input (<|video|> groups with timestamps).

@jason-fxz jason-fxz mentioned this pull request Sep 15, 2026
23 tasks
@jason-fxz jason-fxz added multimodal feature New feature or request labels Sep 15, 2026
@jason-fxz
jason-fxz merged commit 63d6471 into main Sep 15, 2026
nomanoma121 pushed a commit to nomanoma121/My-FreeToken that referenced this pull request Sep 16, 2026
…limmer and MiniMax-M3

Upstream serves images on three more families (FlashML-org#479, FlashML-org#481, FlashML-org#480) on the multimodal stack Kai
already runs, resolves --moe-strategy auto to fused on unified-memory GPUs (FlashML-org#445) and pins
transformers to 5.16 (FlashML-org#479). No conflicts.

How Kai's additions reach the new towers:
- --pp-size: they sit under vision_config like Qwen VL's, so only the first rank builds them.
- --mm-encoder-weights cpu stays Qwen VL only; the other families refuse it at start-up.
- --mm-encoder-dtype and the pin budget count only the Qwen VL tower (model.visual); the new
  towers follow the model dtype and are not counted.
- --dense-quant fp8 keeps modules named visual in bf16; Muse-Glimmer's and MiniMax-M3's
  vision_tower is not in that list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request multimodal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant