You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add Muse-Glimmer-30B on a pinned mainline llama.cpp image
Muse-Glimmer-30B-GGUF is a dense 30B VLM whose architecture landed in mainline
llama.cpp on 2026-08-10 (ggml-org/llama.cpp#26841, build b10353). The bonsai image
builds PrismML's `prism` fork, whose branch head is 2026-07-31 — ten days older than
the architecture — so it cannot load this model at all. Hence a second llama.cpp
image rather than a new POOL entry.
The two images are not redundant and neither replaces the other: the fork carries the
Q2_0_g128 ternary kernels Ternary-Bonsai needs and mainline lacks; mainline carries
every architecture merged after the fork diverged. Both share docker/gguf-serve.sh as
their entrypoint, so a model moves between them by changing only `image:`.
Two entries, because KV turned out to be nearly free on this model (52 layers,
num_key_value_heads=2, and a 3:1 sliding/full attention split) — the full native
131072 context costs ~1.82 GiB, so weights, not context, are the constraint:
muse-glimmer one 3090, 17gb+vision, 131072 in 1 slot, f16 KV
Muse-Glimmer-30B-split both 3090s, dynamic+vision+draft, 131072 in 1 slot, f16 KV
Both are ungrouped (new UNGROUPED_GGUF list), so neither generates pairNN co-load
pairs: the standby model is not a co-load partner. config.yaml is purely additive —
104 -> 106 models with all pre-existing entries byte-identical and groups unchanged
at 45.
muse-glimmer is also the on-call standby: ttl 0 (never idle-unload) plus a poller that
wakes it once both 3090s have been quiet for an hour. It deliberately does NOT use
`persistent: true` — llama-swap defines that as "other groups can never unload this
group's members", which would pin the cards and starve every other model. Eviction is
already free via the existing exclusive groups, and the wakeup request itself displaces
whatever is squatting, so nothing calls the unload API.
Also fixes a pre-existing gap: bonsai-image.yml did not trigger on docker/gguf-serve.sh
even though Dockerfile.bonsai COPYs it, so a change there would have rebuilt only the
mainline image and left the bonsai one silently stale.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+68Lines changed: 68 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,6 +23,10 @@ static GPU layout** — which is more reliable than dynamic VRAM packing for thi
23
23
|`Dockerfile.bonsai` + `docker/bonsai-serve.sh`| PrismML llama.cpp fork image for Ternary-Bonsai-27B (built by CI → GHCR) |
24
24
|`.github/workflows/build-and-push.yml`| CI: builds the Dockerfile and pushes the image to GHCR (Portainer can't build from a repo) |
25
25
|`.github/workflows/bonsai-image.yml`| CI: builds the PrismML fork image → `ghcr.io/<owner>/bonsai-llama`|
26
+
|`Dockerfile.llamacpp`|**Mainline** llama.cpp at a pinned build (`b10362`) — for models the PrismML fork is too old to load (built by CI → GHCR) |
27
+
|`.github/workflows/llamacpp-image.yml`| CI: builds the mainline image → `ghcr.io/<owner>/llamacpp-mainline`|
28
+
|`docker/gguf-serve.sh`| Shared GGUF entrypoint for **both** llama.cpp images (download-then-serve; vision / drafter / multi-GPU via `GGUF_*` env vars) |
29
+
|`scripts/oncall-wakeup.sh`| On-call standby poller — keeps one model warm when the box is idle (see below) |
26
30
|`docker-compose.yml`| Portainer stack definition (pulls the pre-built image) |
27
31
|`config.yaml`| llama-swap model definitions — GENERATED by `gen_pairs_config.py` (do not hand-edit): standalone models + co-load pairs + solo big models |
28
32
|`gen_pairs_config.py`| Generates `config.yaml`: `pairNN.<model>` co-load pairs (one model per 3090) + standalone `<model>` entries. Edit the `POOL`, run `python3 gen_pairs_config.py > config.yaml`|
@@ -198,6 +202,70 @@ repo builds the fork into its own image and points the model at it:
198
202
`llama-server`with vision + DSpark speculative + tool calling, on one 3090. It speaks
199
203
OpenAI `/v1` + `/health`, so llama-swap proxies it like any other model.
200
204
205
+
## Muse-Glimmer-30B (mainline llama.cpp backend)
206
+
207
+
A dense 30B vision-language model (Apache-2.0). It needs **mainline** llama.cpp `b10353+`
208
+
— support landed 2026-08-10 — so it **cannot** use the bonsai image, whose `prism` fork
209
+
branch is from 2026-07-31, ten days older than the architecture. That's why there are two
210
+
llama.cpp images; see ARCHITECTURE → "Backend matrix".
211
+
212
+
It's cheap on KV: 52 layers, `num_key_value_heads: 2`, and a 3:1 sliding/full attention
213
+
split (39 sliding layers windowed at 2048, 13 full). The full layers cost 13 KiB/token and
214
+
the sliding ones a flat 78 MiB, so the **entire native 131072 context costs under 2 GiB**.
215
+
Weights, not context, are the constraint — which is why two entries exist:
216
+
217
+
| Model ID | GPUs | Quant | Context | Notes |
218
+
|---|---|---|---|---|
219
+
| `muse-glimmer` | one 3090 | `17gb` + vision | 131072, 1 slot | the **on-call** model |
220
+
| `Muse-Glimmer-30B-split` | both 3090s | `dynamic` + vision + drafter | 131072, 1 slot | best quality; owns both cards |
221
+
222
+
Both run `-np 1` — the full native context in a single slot, with unquantized f16 KV. Neither
223
+
is in `POOL`, so **neither generates `pairNN` co-load pairs**: the standby model is not a
224
+
co-load partner, and pairing it would have added 10 pairs nothing would request. They live in
225
+
`UNGROUPED_GGUF`in `gen_pairs_config.py`, and the pair count stays at 45.
226
+
227
+
1. **Build the image** — the `llamacpp-image` workflow (`Dockerfile.llamacpp`) compiles
228
+
mainline at the pinned `LLAMACPP_TAG` and pushes `ghcr.io/<owner>/llamacpp-mainline:latest`.
229
+
Then **make that GHCR package public** (same as the other images).
230
+
2. **Download the weights** on the host (~38 GB, so don't let the first cold start do it):
0 commit comments