llama.cpp 0.4.1 adds three new model architectures
A point release: three new architectures land, the JSON schema layer is refactored, and the server now supervises its child processes in one thread.
In short
llama.cpp 0.4.1 is a patch on top of 0.4.0 that adds three model architectures - Maple 20B-A1B, Tencent Hy 4 and Spark2.5 - and moves ggml from v0.23.0 to v0.24.0.
At a glance
- Patch release on v0.4.0, dated September 14 on the release page; no year is given there.
- New: Maple 20B-A1B (ternary MoE, CPU), Tencent Hy 4 as a preview (hy_v4), Spark2.5.
- The ggml compute library moves from v0.23.0 to v0.24.0.
- API change: llama_sampler_chain_n() now returns int32_t instead of int (PR #28631).
- Removed: the deprecated --mmap, --mlock and --direct-io arguments (PR #28334).
llama.cpp 0.4.1 is a maintenance patch on 0.4.0. It adds three model architectures, reorganizes how JSON schemas are handled, and pulls the ggml compute library up from v0.23.0 to v0.24.0.
Three architectures join the list
The release adds Maple 20B-A1B, a ternary MoE architecture running on CPU first (PR #27000), the Tencent Hy 4 preview architecture under the tag hy_v4 (#28127), and Spark2.5 (#27868). A --fuse-qkv flag was added to the HF-to-GGUF conversion path (#22780).
Existing families get repairs rather than features. Kimi-K3 can now roll back recurrent state (#28466), MTP context KV cache allocation was fixed for DeepSeek2 and GLM-MoE (#28630), and GDN normalization for Qwen, Kimi and GLM models switched from max to rsqrt (#28068). Granite and Granite3 MoE report their parameter counts correctly again (#28643, #28632).
Plumbing: schemas, parsers, logs
JSON schema handling moved onto a shared representation called common_schema (#28736), and the specialized chat parsers were split out into common/parsers (#27764). For anyone running constrained decoding or tool calls in production, that plumbing is arguably the more consequential half of this release.
Structured logging arrives as JSONL through --log-jsonl and the LOG_JSON environment variable (#28437, #28586). The long-deprecated --mmap, --mlock and --direct-io arguments are gone (#28334), so launch scripts that still pass them need editing before the upgrade.
Server and web UI
Router child processes are now watched by a single monitor thread (#28555), backed by new server_subproc and waiter types in server-common.h. A hang in LRU handling when several requests hit the same model is fixed (#28539), and model downloads are allowed even once --models-max is reached (#28530).
Context checkpoints are no longer evicted on prompts shorter than checkpoint_min_step (#28302), and --reasoning-preserve is enabled by default (#28437). On the UI side, chat messages mount lazily (#28460), assets get a cache (#28802) and are embedded directly via CMake (#28445), plus a fix for MCP image attachments inside tool blocks (#28089).
Exactly one C API signature changes: llama_sampler_chain_n() returns int32_t rather than int (#28631).
What the release page does not say
The notes give September 14 as the date but no year. The page's assets block failed to load when we fetched it, so binary file names, platforms and sizes could not be checked. There is no contributor count either; the page only notes that five commits have landed on the branch since this tag.
This story rests on the release page alone - a single source. It carries no benchmarks, no speed comparisons and no claim about how mature the three new architectures are, so neither does this article.
FAQ
Which new models does llama.cpp 0.4.1 support?
Maple 20B-A1B as a ternary MoE architecture on CPU, Tencent Hy 4 as a preview under the hy_v4 tag, and Spark2.5. Kimi-K3, DeepSeek2, GLM-MoE, Qwen and Granite models get correctness fixes.
Will my existing command line still work after upgrading?
Not necessarily: --mmap, --mlock and --direct-io were removed (#28334). New flags include --log-jsonl for JSONL logs and --fuse-qkv for GGUF conversion.
What changed in the llama.cpp server?
Child-process monitoring moved into a single thread, an LRU hang on concurrent requests for the same model is fixed, model downloads work at --models-max, and --reasoning-preserve is on by default.