№ 0030GitHub
MLX runtime for Muse Glimmer 30B
muse-glimmer-mlx is an MLX port of Muse Glimmer 30B for Apple Silicon that supplies the missing runtime so the many unloadable MLX conversions published on Hugging Face can actually be run.
# muse-glimmer-mlx
MLX (Apple Silicon) port of [**meta-models/Muse-Glimmer-30B**](https://huggingface.co/meta-models/Muse-Glimmer-30B) —
a 30B image-text-to-text VLM: a 52-layer text stack with interleaved sliding/full attention, and a
50-layer vision tower behind a bilinear-resampled position grid.
## Why this exists
`muse_glimmer` is carried by **neither mlx-lm nor mlx-vlm** — not in released mlx-vlm 0.6.10, and
not on either project's `main`. Fourteen MLX conversions of this model were nonetheless published to
the Hub within hours of its release, and none of them can be loaded:
```python
>>> import importlib; importlib.import_module("mlx_vlm.models.muse_glimmer")
ModuleNotFoundError: No module named 'mlx_vlm.models.muse_glimmer'
```
`load()` resolves `mlx_vlm.models.<model_type>`, so every published build is weights without a
runtime. **This repository is that runtime**, and it reads those checkpoints unmodified — see
[Loading existing conversions](#loading-existing-conversions).
## Architecture
What makes this model non-generic, and what a port has to get right:
| feature | detail |
|---|---|
| attention scale | `qk_scale_factor` **3.87** applied to the *query only*, on top of the usual `head_dim ** -0.5` |
| QK norm | weightless RMS norm on Q and K before the extra scale |
| output gating | attention result multiplied by `sigmoid(gate_proj(x))`, computed from the **layer input** |
| RoPE | θ=500000 on the 39 sliding layers; **θ=0 on the 13 full-attention layers, meaning no rotary at all** |
| layers | 52, interleaved 3 sliding (window 2048) : 1 full |
| GQA | 32 query heads : **2** KV heads |
| norms | three variants, two epsilons — see below |
| logits | `logits * output_multiplier`, then a Gemma-style `T * tanh(x / T)` softcap at **T = 20** |
| vision | 50 layers, 37 windowed (448 px) + 13 full, variable-length by `cu_seqlens` |
| projector | `pixel_shuffle` folds 2x2 blocks into channels, so the projector takes **6144**, not 1536 |
### Three norms, two epsilons
| form | math | used by |
|---|---|---|
| `RMSNorm(with_scale=True)` | `x/rms · w` | the final norm, and nothing else |
| `RMSNorm(with_scale=False)` | `x/rms` | the QK norm and the embedding norm — **no parameter at all** |
| `CenteredRMSNorm` | `x/rms · (1 + w)` | all four per-layer norms |
The pre-norms use `rms_norm_eps` (1e-5) and the post-norms `post_norm_eps` (**1e-8**). Subs


ChatForm
Tgmlabs