llama.cpp b11003 adds HRM-Text support for DFM Mimir 1B model
The llama.cpp project released version b11003, introducing support for the HRM‑Text architecture used by the DFM Mimir 1B model. The new implementation runs two transformer stacks—low and high—in an alternating cycle over a single token stream, with a learned embedding tensor broadcast across positions. The update adds a fused GQKV writer, a sigmoid‑gated attention loop, SwiGLU feed‑forward, and…
Key points
- llama.cpp b11003 adds HRM‑Text support for DFM Mimir 1B, a dual‑stack transformer architecture
- Decode speed is ~4× a dense model of equal width, ~2.65 t/s on an 8‑thread desktop CPU
- Accuracy matches Hugging Face reference (100 % token‑wise argmax, 95.8 % top‑1 after q80 quantisation)
Performance tests show the HRM‑Text variant incurs roughly four‑times the decode cost of a dense model of equal width, delivering about 2.65 t/s on a BF16‑enabled 8‑thread desktop CPU. Accuracy remains high: the implementation matches the Hugging Face reference on all 334 token positions in a 20‑prompt suite, and a q80 quantisation retains 95.8 % top‑1 accuracy. The changes were co‑authored by Sigbjørn Skjæret with assistance from GLM‑5.3 and Claude Sonnet, and the codebase now includes dedicated GGUF writer methods for HRM‑Text metadata.
The release is experimental, with causal‑only attention and no upstream prefix‑LM mode, but it expands llama.cpp’s ability to run advanced, looped transformer architectures on a variety of platforms, from Apple Silicon to Linux and Windows.
The story so far
2 episodes →- llama.cpp b11003 adds HRM-Text support for DFM Mimir 1B model this story
Release b11003 · ggml-org/llama.cpp
github.com · 16 September 2026b11003
model : add support for HrmTextForCausalLM (DFM Mimir 1B) (#27625)
- model : add support for HrmTextForCausalLM (DFM Mimir 1B)
HRM-Text runs two transformer stacks (low, high) in an alternating cycle over the same token stream. The low-cycle state z_l starts from a learned [n_embd] tensor and is broadcast over positions.
- conversion: new writer for the fused gqkv projection (order gate,q,k,v) remapped to llama.cpp q/k/v plus a separate sigmoid gate tensor
- loader: block_count = lps * h_cycles * (l_cycles + 1) cache slots aliasing 2*lps physical blocks via struct copies
- graph: looped build with sigmoid-gated attention, SwiGLU FFN and parameterless RMS norms; learned embedding_scale applied in build_inp_embd
- saver: pointer-deduplicated layer loop (looped archs alias tensors)
- tests: hrm_text fixture (lps 1, h 2, l 3) in test-llama-archs
Limitations:
causal attention only - the upstream prefix-LM mode is not implemented (the prefix_lm GGUF key round-trips unused).
The KV cache holds one entry per pass: 128 layers for Mimir 1B, i.e. 4x a same-width 32-layer model - about 3072 MiB at ctx 4096 in F16 (halves with q8_0 KV + FA).
Every token runs all 128 block passes, so decode cost is roughly 4x a dense model of equal width (2.65 t/s BF16, 8-thread desktop CPU).
Verified against the HF reference: identical argmax at 334/334 positions across 20 prompts (BF16 GGUF vs FP32 golden).
q8_0 requant: 95.8% top-1, all remaining misses inside the HF top-5 (accumulated error over 128 sequential blocks).
AI usage disclosure: YES
Used GLM-5.3 for the majority of code AI-generated under my direction, all gates verified locally.
All in all I could say that I have written less than 20% of the code and most of the heavy lifting has been done by the model. As such, this should be considered experimental.
- Update conversion/hrm_text.py
Co-authored-by: Sigbjørn Skjæret sigbjorn.skjaeret@huggingface.co
- Update src/llama-arch.cpp
Co-authored-by: Sigbjørn Skjæret sigbjorn.skjaeret@huggingface.co
- convert : add gguf_writer methods for hrm_text metadata
replace raw add_uint32/add_bool calls with dedicated GGUFWriter methods, following the add_embedding_scale pattern
Assisted-by: GLM-5.3
- convert : map regular hrm_text tensors via tensor_mapping
delegate unfused checkpoints to the base tensor mapping; training-style attn. names are renamed to self_attn. so the patterns match
Assisted-by: GLM-5.3
- model : format hrm-text build_* calls as in other models
one argument group per line, matching sibling model files
Assisted-by: GLM-5.3
- llama : move hrm z_l_init table entries out of the nemotron group
place the name and tensor-info entries with the other global input tensors
Assisted-by: GLM-5.3
- convert : slim down hrm_text comments
Assisted-by: GLM-5.3
- convert : build hrm_text block tensor names from the {bid} template
The tensor map holds concrete per-block names, so format the template
with the computed layer index before handing it to super().
- llama : name hrm metadata keys in their own hrm. namespace
The four keys are arch-independent, unlike the arch-substituted
Keys.LLM entries, so group them under Keys.HRM (like Keys.Split) and
rename the llm_kv entries to LLM_KV_HRM_*. Only our own GGUFs carry the old hrm_text.* keys; they are regenerated.
- Update src/llama-model-saver.cpp
Co-authored-by: Sigbjørn Skjæret sigbjorn.skjaeret@huggingface.co
- llama : keep hrm metadata keys arch-substituted
Per review: the GGUF keys stay "{arch}.h_cycles" style, so the Python
members drop the LLM_KV_HRM_ prefix and keep arch templates; C++ keeps
the LLM_KV_HRM_* enums. GGUF output is unchanged - existing files and
HF uploads stay valid.
- Update gguf-py/gguf/constants.py
Co-authored-by: Sigbjørn Skjæret sigbjorn.skjaeret@huggingface.co
- Update src/llama-arch.cpp
Co-authored-by: Sigbjørn Skjæret sigbjorn.skjaeret@huggingface.co
- Update src/llama-arch.cpp
Co-authored-by: Sigbjørn Skjæret sigbjorn.skjaeret@huggingface.co
- convert : rename hrm writer methods to add_hrm_*
Generic names like add_h_cycles/add_prefix_lm are too broad on the
shared GGUFWriter; prefix them with hrm_ like the metadata keys.
- model : fix meta-split lookup for archs with aliased cache slots
Cache tensors of archs that alias physical blocks across looped slots
(hrm_text, nanbeige with num_loops > 1) can reference block indices
without weight tensor names. Take the output projection from the layer
array instead of asserting; all other lookups are unchanged.
- model : replicate hrm_text tensors on meta devices instead of splitting
The aliased cache slots rotate split states differently from their
physical weights, so the meta-split execution invariants (set_rows
requires the cache state to match the token indices) cannot hold for
any device count. Replicate all hrm_text tensors on every meta device
instead; single-device and non-meta paths are unchanged.
Assisted-by: Claude Sonnet
Co-authored-by: Sigbjørn Skjæret sigbjorn.skjaeret@huggingface.co
Website:
Attestations:
macOS/iOS:
- macOS Apple Silicon (arm64)
- macOS Apple Silicon (arm64, KleidiAI enabled) DISABLED
- macOS Intel (x64)
- iOS XCFramework
Linux:
Android:
Windows:
openEuler:
- DISABLED
- openEuler x86 (310p)
- openEuler x86 (910b, ACL Graph)
- openEuler aarch64 (310p)
- openEuler aarch64 (910b, ACL Graph)
This text was published by github.com . It is reproduced here with attribution so you can read it in full; the rights remain with the publisher. Read it at the source ↗
Coverage and discussion
1 source- Reddit discussion reddit.com
The headline, key points and digest above were generated by Digest AI's editorial model from the linked sources. Automated summaries can contain errors: the sources are the record. Spotted a mistake? Tell us.
More in Generative AI & Models
All →- Brin Returns to Google's AI Research · 1 src
- TypeSafe AI unveils Jev, a frontier model up to 400× cheaper and 200× faster · 6 src
- OpenAI's GPT-6 Astra Drives Enterprise Spend Ahead of Anthropic · 3 src
- Prior Labs releases TabPFN-3.5, beating 2015 Kaggle winner with default settings · 1 src
- Nums AI launches Causilo, a tabular foundation model that tops TabArena benchmarks · 1 src
Comments
via GitHub Discussions