Repository navigation
bloomery 0.3.3
bloomery 0.3.3 adds two models: Nemotron 3 Nano 4B (bloomery-serve --model nemotron) and MiniCPM-V 4.7 images (#147). It also lays the groundwork for the Qwen3.6 in-file MTP draft and fixes two Qwen3.8 items from 0.3.2's known limits. The release pass on this candidate is the RC tape under "Checked before the tag".
Install
Linux x86-64 with AVX2 (glibc 2.34+), an NVIDIA GPU of compute capability 8.6+ and driver R580 or newer (CUDA 13).
On Windows, run inside WSL2.
curl -fsSL https://raw.githubusercontent.com/midagedev/bloomery/main/tools/release/install.sh | sh
bloomery-serve --hf unsloth/Qwen3-30B-A3B-Instruct-2507-GGUF:Q4_K_M --port 8080Docker and Homebrew as in the README.
New models
| Model | File tested | Serves |
|---|---|---|
| Nemotron 3 Nano 4B | NVIDIA-Nemotron3-Nano-4B-Q4_K_M.gguf |
Text, one slot, the whole model on one card. A prompt runs one decode step per token (see known limits) |
| MiniCPM-V 4.7 35B-A3B, images | MiniCPM-V-4_7-35B-A3B-Q4_K_M.gguf with --mmproj |
Text and images end to end. A tile is capped at 70 tokens |
- Nemotron 3 Nano 4B (#259) is built over #179 (header reader), #185 (pixtral pre-tokenizer), #191 (host Mamba-2
step), #195 (fixture), #209 (Mamba-2 decode step on the card, one fused kernel per layer), #235 (the common pieces a
Nemotron-H body attaches to: group-5 flash entry, Q5_0 embed rows, the recurrent store) and #236 (the mainline
reference set).- The body is written on the common owners: site gemvs, the recurrent store, the shared per-head K/V append and the
common head. It owns only the layer kinds and the residual order. - The Mamba-2 state cannot step back. A request keeps what the slot holds only when its prompt extends the whole
held sequence; any other prompt resets the slot and is read again.
- The body is written on the common owners: site gemvs, the recurrent store, the shared per-head K/V append and the
Changed
- Context is one owner for every seat (#157, #158, #178, #208).
- A load serves the context it computes from the user's slots and
--ctx. - A
--ctxpast the model's trained limit stops the load by name. - The old per-seat context searches are gone.
- A load serves the context it computes from the user's slots and
- DeepSeek V4.1:
/propsreports the qwen3 seat's placement (#230).- Plans count the rope table they stage. The Qwen loads (#232) and MiMo (#217) hold their scratch to the plan.
- MiMo-V2.6-Flash: the window store is a ring, with a k192 flash and neox append for ring rows (#129).
- CPU tier (by @juliankang4):
- Unified-memory machines and DGX Spark (by @juliankang4):
- A machine's host and unified pool live in one node list (#94).
- A model is planned over several unified nodes, on one to four Sparks (#95, #166).
- A plan the NVMe tier's floor refuses is planned again under a card budget (#100).
- On an integrated device the NVMe arena is one write-combined pinned allocation (#120).
- The tier page's counters cross a link (#96, #172).
- Qwen3.6 in-file MTP draft, groundwork (#30):
Fixed
- Two Qwen3.8 items from 0.3.2's known limits:
- A paged plan serves the slot count it was asked (#188). With no arena, the paged draft keeps the draft and its
reason as asked (#138, by @juliankang4). - A one-card plan asked for a draft is refused by name (#142).
- The Qwen3.6 head-256 out gate writes rows of its own, so the queries are kept (#250). Model output is unchanged.
- Qwen3.6 unjoined files (Q8_0 attention and delta projections): the e2e gate is green (#250, #257). Its forced
attention taps read the queries rather than the gated rows. Its layer-0 band follows the activation rule of the delta
projections. Model output is unchanged. ggufrefuses malformed files by name (by @juliankang4):bloomery-serve's draft pick names every place it looked when the line resolves to off (#114).- A GLM or Qwen3.8
--planrun no longer probes the GPU lane; a load still probes before it reads the room (#223,
closes #204). - On an integrated device, a small pinned arena no longer starts off a 4 KiB boundary (#120, closes #109).
Tools and contributors' checks (developer-facing)
just pre-reviewruns the Shingler reviewer locally before a push (#199) and refuses a base behind origin/main
(#231). Shingler ranks correctness first, then duplication, and re-reviews only new commits (#161, #253). It can run
on Codex (#107, #244, by @juliankang4).- Box queue and runners:
- queued jobs no longer resync each other; INT and TERM cancel only queued jobs; an attach rides out a daemon blip
(#181, #196, #197, #198, #205, #225); - a one-card gate asked of another card is refused by name (#211, #222);
- a red gate is rechecked on origin/main (#215);
- the queue's self-test counts every follow before it waits on them (#266).
- queued jobs no longer resync each other; INT and TERM cancel only queued jobs; an attach rides out a daemon blip
just canon-check BASEproves a kernel move bit-identical (#245).gate-ptx-spillreads per-arch tables, with cc
12.1 tables for sm_121 (#170, by @juliankang4).tools/gate-paths-merge.pyis a merge driver fortools/gate-paths.tsv(#182).recipes.py check --filladds the
gates a row lacks (#183).- The v3 release check reads each instruction's encoding, so AVX-512 on ymm and xmm is caught (#150, by
@juliankang4). - Native AMD: contributor-owned HIP operator checks under
lab/(#248, by @Burntgogi). This is not a shipped backend. - The dead feature-off stub
mainis gone from the 112 bins that declarerequired-features(#99, by @avlp12). - Groundwork for later models, with no serve path yet, all by @juliankang4:
- gemma-embedding2's header reader (#238) and the gemma4 tokenizer (#241);
- EmbeddingGemma 2's and EmbeddingGemma (v1)'s mainline oracle sets and their families (#260, #267);
geglu_tanh, the GELU-gated unit over f32 rows on the card (#237);- the head-512 rope append and prefill flash of EmbeddingGemma 2's global layers (#233).
Off cells and known limits
- Nemotron 3 Nano 4B reads a prompt at its decode rate: the body has no prompt batch, so a prompt runs one decode
step per token. - Nemotron 3 Nano 4B serves one slot on one card:
--parallelabove 1, a placement of more than one card or with a
tier card, and a draft lever are each refused by name. It runs no prompt cache, and a snapshot or resume is refused
by name. - Qwen3.6 real-tier e2e gate,
splitresidency clause: it can fail on one run and pass on the next at the same
commit (on an RTX 3090, logits distance from the off run up to 4.879e-1 against its 0.26 band, then 1.6–1.8e-1 on a
rerun). The experts it streams follow the lane rate measured at runtime, so the clause's distance moves from run to
run. This is a developer gate, not a change in what a load serves. - The Qwen3.6 in-file MTP draft is not served in 0.3.3 (groundwork only, above).
- EmbeddingGemma and EmbeddingGemma 2 have no embeddings endpoint in 0.3.3 (#190): their groundwork is in this
release, and the endpoint comes in the next one. - On Qwen3.8 loads that page experts through the NVMe tier,
gate-gpu-qwen38-serve's real tier was 70/72 on 0.3.2's
baseline (f382b474), two preexisting paged failures. It was not re-run on its own for this release. - Carried over from 0.3.2:
- Qwen3.6-35B-A3B has no DSpark draft;
BLOOMERY_DRAFT=dsparkon it is refused by name. - DSpark (V4.1) serves one slot:
--parallelabove 1 with it is refused by name. - An image request under DSpark (V4.1) is refused by name.
- V4.1 DSpark on one card under
--place a: the draft shares the target's card with no reserve, so a load past its
free bytes stops with a CUDA allocation error.
- Qwen3.6-35B-A3B has no DSpark draft;
Checked before the tag
- Release head:
5626a096. - The release-candidate pass, its rows and their conditions:
https://tape.midagedev.com/r/tz7hzsysnd9u85cpf8mf. - Nemotron 3 Nano 4B on the release head:
https://tape.midagedev.com/r/tz7hzsysnd9u85cpf8mf.
Thanks
- @juliankang4: 38 merged PRs in this release, among them:
- the AVX-512 VNNI Q4_K bodies (#86) and the Q4_K/Q5_K f16 read (#111);
- the unified-node and DGX Spark planner (#94, #95, #100, #120, #166, #172);
- the gguf refusals (#149, #153) and the v3 release check (#150);
- Shingler on Codex (#107, #244);
- the EmbeddingGemma and gemma4 groundwork (#233, #237, #238, #241, #260, #267);
- many tool fixes (#113, #130, #148, #163, #167–#170, #173, #174, #177, #186, #187, #194, #234);
- and the report in #109, which #120 fixes.
- @Burntgogi: #248, native HIP operator checks for AMD (lab, contributor-owned).
- @avlp12: #99, the feature-off stub
mainremoved from 112 bins.