-
Notifications
You must be signed in to change notification settings - Fork 2
Changelog
The project was called NVMAI until 2026-09-14, when it was renamed to TinyTitan. Entries below keep the name each release shipped under, and their links still resolve (GitHub redirects the old repository name).
Compact user-facing release history. Follow the linked GitHub releases for complete source changes and assets.
Released 2026-10-03. The prebuilt binaries, the library archive and their checksums are on the release page.
-
TinyTitanLibis a supported Swift package you embed in your own program: anEngineand aSessionover the same kernels, format reader and sampler the engine uses — streaming, cancellation,unload()and tools, with no subprocess and no HTTP.examples/embeddedis a consumer you can read. -
Every release now ships the library as binaries too:
libTinyTitanLib.a,libTinyTitanLib.dylib, the module set and its module maps, the Metal shader sources, and two demo apps — one per link form — for a consumer that cannot or will not build from source. -
Tools work in both directions: offer them with
respond(tools:), read the model's calls as events, and close the loop by replaying the turn that asked plus the tool's result. - Building needs Xcode 27 with Swift 6.4 — exactly. Nothing else is tested, and the installer now says so rather than accepting a newer Swift silently.
-
CLI fixes: dense Qwen 3.5 prefills in 4,096-token chunks again (which also
puts it back on the ANE), a fifth
--stopstring works again, and--quietsilences the library's own lines as well. - No engine output changed: the seven installed golden baselines are byte-identical, and the CLI matches its pre-5.16 output byte for byte.
Released 2026-10-02. The prebuilt binaries and their checksum are on the release page.
-
The install format is
.ssdai(it was.gturbo): the manifest magic, the Swift vocabulary, the CLI, the tools and the docs all carry the new name. -
Your existing installs keep working, untouched. Reads accept the legacy
GTURBOmagic for one release, and no manifest is rewritten in place — the receipt binds the manifest's digest and the directory path, so an install moves to the new magic only when it is next rebuilt. -
--input-ssdaiis the flag;--input-gturbois still accepted as a deprecated alias. The directory suffix is a convention, so a folder still namedsomething.gturboworks exactly as before. - No engine behaviour changed — the seven installed golden baselines are byte-identical, and each of them loads a manifest that still carries the legacy magic.
Released 2026-10-01. The prebuilt binaries and their checksum are on the release page.
-
The browser chat window runs on DeepSeek Harness 0.2.0-rc.2.
tools/dsh_local.shinstalls that release andtools/server_launcher.sh --webopens it with the TinyTitan route already in place. The route now goes through the harness's own settings service and the agent preset is registered with its preset registry — 0.2.0 removed thesettings.yamland preset files the bundle used to write. The preset keeps its id, so sessions already on it keep working; it becomes the default only while nothing else is selected. - Installing a model while the window is open reaches the model picker without restarting the harness — the watcher had been refreshing through the old file path, which 0.2.0 cannot satisfy.
-
compactionHeadroomTokenslets you place the compaction trigger: leave it unset for the harness's policy,0to let the 0.8 ratio govern, or a token count for a guard. The stock 65,536-token headroom holds the trigger near 62% of a 262,144-token window, and on a narrow declared window it stops compaction altogether. -
tools/dsh_local.sh statusnow says which harness version is installed, not just which one is pinned, and the bundle's README and wiki page describe what it actually writes after the 0.2.0 move. - No engine behaviour changed; the seven installed golden baselines are byte-identical. The internal-speed record is optional from this release on (a machine under load moves the numbers further than the 10% threshold), so no timing record accompanies 5.14.
Released 2026-09-29. The prebuilt binaries and their checksum are on the release page.
-
A
--modelpath that does not exist now says so. Any typo used to fail withinstalled tokenizer is missing chat_template.jinja; reinstall the model, which sent you to reinstall a model that was simply not at that path. It now saysmodel directory not found: <absolute path>— at the CLI, the server and the token-counting endpoint alike. - The wiki is a user guide. Every page now explains how to use TinyTitan: a new Installation and Configuration page (every model key, the launcher's flags, all the environment variables in one place), a rewritten Runtime Controls (every CLI, server and API parameter with its default), Local Server and API (endpoints, examples, structured output, function tools, client wiring), a larger Cookbook, and Benchmarks reduced to what to expect on an M3. The engineering record and the closed audit findings left the wiki.
-
The README is a verified quickstart — what TinyTitan is and who it is for,
prerequisites, install, a complete worked example and troubleshooting, with a
Last verifiedline naming the commands that were actually run. - No engine behaviour changed. 50 source files were split under the 500-line rule as pure code motion, each moved block verified byte-for-byte with the full suite green after every split; sampling, kernels, defaults and the API are untouched.
Released 2026-09-25. The prebuilt binaries and their checksum are on the release page.
-
A bad state reports itself instead of killing the process. Every force
unwrap is gone — 171 sites in the engine and 139 in tests and benchmarks — so
the engine returns a typed error where it used to trap. Chunked prefill against
a producer that cannot run it now returns the existing
chunkedUnsupportederror rather than crashing. - The project verifies itself with eleven pinned gates — SwiftLint and swift-format, strict C99, Ruff, eslint/prettier per plugin package, shellcheck, and the size/architecture/scanner checks — run by the same command locally and in CI. Each fails when its tool is missing or is a different version, so none can pass by skipping.
- Swift code scanning works again. CodeQL had failed before compiling a single file since the toolchain moved; it now scans 249 of 464 Swift files, including the memory, validation and Fleet modules, with no alerts.
-
The DeepSeek-V4.1-Flash port reference (
docs/deepseek-v41-flash-port.md,docs/deepseek-v41-flash-reference.md) documents what that checkpoint is, its byte and quantization layout, and the two conversion paths available here. - No model, kernel or API behaviour was retargeted. This is a hardening release: 4,479 SwiftLint findings and 442 files of formatting drift went to zero, and the audit that found them is closed, with its evidence and deliberate decisions live in the closing commits of that work.
5.11 — a browser chat window that installs without a registry, and an installer that refuses what cannot finish
Released 2026-09-25. The prebuilt binaries and their checksum are on the release page.
-
The chat window is
dsh-tinytitan, a local DeepSeek Harness bundle. The Mac app is gone; this points the harness at the TinyTitan server, keeps the route current as models are installed, and stops the harness's own compaction calls from thinking on a local reasoning model. It is configuration only — the harness's own adapter serves the models, nothing is patched, and it composes with a harness you already run. Install: run the installer and accept the chat window (a model must be installed), then start it with~/.local/bin/tinytitan-web. Harness and bundle both come from the release's source archive, so no npm account is needed on either side. Benefits: one command sets up engine, models, window and route; the harness is private and pinned under~/.tinytitan/dsh, so yours is never read, written or stopped, caches included. Limits: exactly one harness release (0.1.6-alpha.2) and it refuses any other; loopback only; session titles are not covered by the compaction row; macOS Apple Silicon only; binaries not notarized. More: TinyTitan Plugin. -
The model installer refuses a download that cannot finish, before fetching a
byte. It prints what each volume needs, the two ways out (free space, or
TINYTITAN_WORK_DIRon another volume) andTINYTITAN_SKIP_DISK_CHECK=1. -
Staging stays inside the install root and is reclaimed as widths complete. It
used to be a relative
.build/…— for a factory-new install,~/.buildin the user's home;install_models.sh cleanreclaims what is left. - An EOF at the model menu installs nothing, where Ctrl-D used to fall through to the recommended 36.9 GB download.
- Memory keeps one address per fact. Two sessions in one project could distil at once, so the later read a store the earlier had not written and invented a parallel key; distillations are now chained per project.
-
--ramhelp now says what it accepts: any whole GB from 4 up, not only the interactive menu's 4/8/16/32. No behaviour change.
Released 2026-09-24. The prebuilt binaries and their checksum are on the release page.
-
--ramis a target for the whole process, not just the expert cache. The flag used to bound the cache alone, so--ram 8produced a process using 11.63 GiB. It now budgets the process — the cache gets the target minus the weight file and a measured 512 MiB reserve — steps down to the largest slot rung that fits, refuses anything below a 4 GB floor, and printsram target=… cache=… slots=… resident_floor=… estimate=…at every start. This changes an existing flag:--ram 8now gives 32 slots where it gave 64, so it is slower than it was on 5.9;--ram 12reproduces the old 64-slot cache. Peak RSS is now within 0.2 GiB of the printed estimate. -
Qwen3.8's instruct row is real. The engine refused every non-zero presence
penalty; it now applies one in the same pre-softmax window as the repetition
penalty, ships two explicit Qwen3.8 rows (thinking 1.0/0.95/20; instruct
0.7/0.80/20 with presence 1.5), picks the row from the request's thinking mode,
and exposes
--presence-penaltyon the CLI.min_pis accepted but must be zero — the filter does not exist, and refusing beats ignoring. -
The C kernels compile at
-O2. The CPU int8 GEMV runs 1.21× faster (2.35 → 1.94 ms, identical checksum); the internal-speed re-record reads decode +2.5%, prefill +6.5%, first token −6.1%. - The expert-cache ceiling is a third of physical memory, not a half, which is what stopped a 24 GiB machine from swapping (855 → 1,610 MB before; flat swap and 7.29 tok/s after, against 5.58 tok/s at the old cap).
-
Twelve decode switches that measured a wash or a loss are gone — including
TINYTITAN_PREFETCH_PER_EXPERT,…_AHEAD,…_TOP_M,…_MIN_MARGIN,…_IO_TIER,…_EXPERT_CACHE_POLICY,…_EXPERT_CACHE_LAYOUT,…_EARLY_HITS,…_KEEP_WIRED,…_PARALLEL_IOand…_PREFILL_LAYER_MAJOR. Setting one is now inert; the winning default is what runs. -
Converting Qwen3.8 resumes and works through mirrors. An interrupted
conversion keeps the output shards it finished and fetches only what is
missing;
HF_ENDPOINT(or--endpoint) points the whole fetch at a mirror on the Hub's URL layout; a truncated shard is never adopted; the finished 102 GB n-gram table is reused in place or copied across filesystems; downloads retry with a real timeout and restart a file when a mirror refuses ranges; and a directory left between the shard rename and the index write is refused rather than duplicated. Thirty-six fault-injection cases back it and run in CI. - Prefetch depth 1 is the Qwen3.8 profile default (+15.7% decode at a short prompt, +14.6% at ~500 tokens, responses byte-identical).
Released 2026-09-20. The prebuilt binaries and their checksum are on the release page.
-
An install whose manifest names the GDN pair explicitly serves again. A
manifest that carries
linear_attn.in_proj_a/in_proj_bat the attention slot's own width was refused on load as if it were corrupt, which broke aqwen38flash4-bit install completely (issue #16). The validator now honours the slot's width and bf16, and names the width it accepts when it still refuses another. - The ten master prompts are runnable end to end. Long-session worlds as data, with foundation and carryable key sets derived from the truth rather than authored beside it, a scorer over the stored answers, and a driver that runs all ten. The result that matters is the baseline: a client's own 200-word summary wins or ties on three of the first four scenarios, so memory is argued against that, not against memory-off. Where the fact set is dense, arbitrary and revised, memory carries 20 of 20 against the summary's 14.
-
Which model judges the side-engine's tasks is a measurement.
benchmark/side_engine_judges.pyruns the same cases through the resident 4B on the CPU and the model already on the engine: the 35B is better at the reply check the 4B cannot do (100% against 62%) and worse at duplication (75% against 100%), and the pair beats either alone. - A T7 retrieval hint is queued before the search returns. The background caller's registration was fire-and-forget, so a caller that observed the hint immediately after a search could arrive before the question was queued — the race the thread-sanitizer gate caught. Nothing on the request path waits on a judgement either way.
-
The plugin is catalogued.
dsh-tinytitanis listed inawesome-dsh-plugin; the npm publish remains the operator's step.
Released 2026-09-19. The prebuilt binaries and their checksum are on the release page.
-
Agent memory has a resident side-engine. A 4B runs on the CPU and answers
one closed question at a time — keep this fact, do these two say the same
thing, do they disagree, which kind of change is this — while the main model
keeps the GPU. Durability, duplication, contradiction and supersession are
wired into consolidation under a budget of six questions;
nilmeans no decision, so an absent engine leaves the old path alone. The 4B is the default, the 9B optional, the 2B unused. -
A stored rule can hold a write back.
rules/eyesnow stopscharacters/marcus/eyesfrom changing, found by key with no model call; only model-derived facts are checked, so the person always overrules a rule. - Retrieval ranks by rarity. Weighting each term by inverse document frequency takes the authored paraphrase set from recall@1 1 of 4 to 3 of 4, and T7 — the one scorer that reaches the semantic miss — now works in the background during idle windows instead of on the request path.
- The 102 GB n-gram table is shared between builds, not copied per quantization, with a gate that refuses a table whose constants do not match.
- Per-tensor bit widths resolve in the resident index, the enabler for a ~10 MB precision promotion. Its quality case was measured twice and is absent (18/20 against 18/20; 0.0097 ± 0.0067 nats, inside the instrument's floor), so the converter policy is deliberately not built.
-
A LAN manager for a DeepSeek Harness fleet.
dsh-lan-manageradds a LAN-scoped API for workspaces, sessions and prompts, andttlanmanageris a terminal dashboard over it; reaching it from another machine is blocked until the harness allows a non-loopback bind. -
Both DSH plugins pin exactly
0.1.6-alpha.2and refuse to run on any other release rather than write into a harness home they cannot identify.
Released 2026-09-17. The prebuilt binaries and their checksum are on the release page.
-
The install builds nothing.
tools/install_tinytitan.shdownloads the published arm64 executables, verifies their sha256, unpacks them under~/.tinytitanand asks one question — which model. No Xcode, Homebrew, Python or Node is needed, and--version TAGpins a release while--from-sourcekeeps the clone-and-build path. See Getting Started. -
The model is a menu. All 16 builds are listed with their installed size and
what each is for; Enter takes the default,
--model NAMEskips the menu, and through a pipe the installer takes the default and says so rather than hanging. -
Every script runs on the shell a factory Mac actually has.
/bin/bashthere is 3.2.57, and these scripts had only ever run under Homebrew's 5.x. Three classes were closed: a heredoc apostrophe that stopped 3.2 parsing the launcher at all,${v^^}/mapfilethat died mid-menu, and"${a[@]}"on an empty array (unbound variableunderset -u), which broke the default--webpath.tools/lint.sh shellnow fails on all three. -
An optional browser chat window, isolated from any DeepSeek Harness you
run: its own home, npm prefix, pnpm store and port, under
~/.tinytitan. The launcher's--webopens it already pointed at your model, with a chat preset that cuts a nine-word question from 4222 to 124 prompt tokens and a warm expert cache, so the first answer lands in 8.3 s instead of 161 s on the 35B. -
The Mac app is removed. The engine and its loopback server are the product;
the supported clients are the ones you already have, plus the browser window as
a client of the loopback server. This also leaves
ServerVersion.currentas the tree's single version literal, whichrelease.shenforces. -
POST /v1/responses/compactreturns one opaque state item standing in for a conversation, preserving the system prompt and the core reasoning. The note is metered with the server's own tokenizer and compressed rather than truncated when it is over budget. Verified on the 4B and 9B. - The concurrent width is any power of two up to 256 (the default stays 1), with the per-load memory budget doing the clamping and saying so in the log.
- Repository cleanup: the forum article series is gone with the forum, and adding a model is eight wiring points now that the app descriptor is not one.
Released 2026-09-17. The prebuilt binaries and their checksum are on the release page.
- The app can change models. Model → Change Model now lists every selectable build and records the choice; a banner says to reopen, because the model directory, its settings file and the decode-service process are bound at launch. Previously the app read a model preference it had no way to write.
-
The model installer finds its own binary.
tools/install_models.shused a target-triple build path that exists only when SwiftPM's triple matches the toolchain, and can point at a stale tree when it does. It uses the stable product path now, and a lint gate fails any build path that hardcodes a triple. -
A sidecar the Neural Engine refused can no longer be written or run. The
exporter checks the compile markers, loads every function it records, and asks
the compute plan which device each operation is assigned to — the refused
Qwen 3.8
h12288measures 0 of 173 operations on the ANE. The runtime declines a sidecar that lacksaneCompileVerified, so an old sidecar costs a GPU prefill instead of a ~38× slower CPU one. - Qwen 3.8's sparse attention is correct on the ANE, and still stays on the GPU. The runtime folds the indexer's key selection into the mask the sidecar already takes — 0.47% against an independent reference, where a causal-only mask is off by 7.6%. Measured, the ANE is 0.72× the GPU at 4-bit and 0.87× at 8-bit, so no sidecar is installed for it; the gather-graph variant that would have removed the extra arithmetic was sized and rejected.
- Building from source needs Swift 6.4 (Xcode 27). The manifest floor now matches the toolchain the project is built and tested on.
- The dense Qwen 3.5 installs reach the ANE. They were on the 128-token default prefill chunk, which never matches the sidecar's fixed 4,096-token program; at 4,096 the 2B prefill measured 1.30× faster at ~2,500 tokens.
-
The server has per-session KV and GDN state and admits up to four sessions,
but serves them one at a time: width > 1 produced degenerate output on the
real 2B and 4B, so the batched width is held at 1 until multi-session output is
verified correct. The Responses API now echoes the sampling the server used
instead of
null. -
The wiki is a user guide. New: a Cookbook of copy-paste recipes
with the output to expect; the engineering write-ups it used to index live under
docs/in the repository. - Repository cleanup: the processed deep-audit register was removed, the project tracker no longer carries a closure log, and three oversized source files were split as pure code motion with the build and 1,566 tests verified.
- Internal speeds are a release gate with a committed baseline, so a kernel or bandwidth regression fails a release instead of being noticed later.
Released 2026-09-14. The prebuilt binaries and their checksum are on the release page.
-
The project is TinyTitan everywhere — package, targets, executables,
environment variables, repository and app. The binaries are
TinyTitanServer,TinyTitanMac,TinyTitanCLI,TinyTitanRepack,TinyTitanDecodeServiceandTinyTitanBench; the environment variables areTINYTITAN_*; the app installs asTinyTitan.app; and the archive istinytitan-5.5-macos-arm64.tar.gz. The old repository URL redirects, and releases before this one keep the name they shipped under. -
JSON output is enforced, not requested.
response_formaton Chat Completions,text.formaton the Responses API andoutput_config.formaton Messages compile into a byte-level grammar that masks the sampler, so the model can only emit a document the schema allows. The supported subset is small and explicit, and everything outside it is refused by name. -
Thinking is the request's own on every surface. On
/v1/messages,thinking.disabledreally turns it off,adaptivestill means "you decide", and anenabledbudget maps onto the levels the served model renders. Chat Completions gained the same per-request control, and reasoning tokens are reported in usage. -
A
developermessage no longer fails with HTTP 500. It renders as the system turn it stands for — what a harness that switches to that role once a model reasons needs. -
The launcher lists only installed models, and warns in red above 40% of
this Mac's physical memory before using a larger
--ramanyway. -
One client list for the launcher and the coder harness — Codex, Claude
Code, Qwen Code, OpenCode and the Zed editor — with
--round clientschecking every client's wiring without loading a model. -
DeepSeek Harness support.
tools/dsh_route.shgenerates the harness'sllm-pi-airoute from the installed models, andplugins/dsh-tinytitan/keeps it current at boot and mounts a compaction backend that does not think. - The six dense Qwen 3.5 installs have golden baselines, so a release now re-checks 2B/4B/9B at both widths instead of declaring them exceptions.
- The README is one benchmark table with a reproducible GPU-versus-CPU column for the dense models and no per-release callout — this page is the announcement.
Released 2026-09-14. The prebuilt binaries and their checksum are on the release page. This release first ships the 5.3 work to users (see the note below), together with the release-verification policy and a native app icon.
- KAT-Coder-V2.5-Dev 35B-A3B is supported at 4-bit and 8-bit — Kwaipilot's agentic-coding fine-tune of Qwen 3.6, with its own temperature (1.0) rather than the series' 0.6. 17.86 tok/s at 4-bit, 6.91 at 8-bit, with the three verified continuations and a golden baseline per width.
-
Routed experts are filed by index, not by arrival order. KAT is the first
converted checkpoint whose experts ship one tensor per expert; fusing them in
arrival order silently paired each routing decision with a different expert's
weights. The install loaded, matched the checkpoint byte for byte, passed
every structural check, and answered nonsense. A
tools/lint.shgate now fails if the order regresses. -
Both widths install from one download:
tools/install_models.sh <model> bothconverts 4-bit and 8-bit in a single pass over one ~70 GB checkpoint, and a later second width reuses the snapshot instead of re-fetching it. -
Three size caps that refused legitimate files are fixed — the snapshot
index (4 MiB against KAT's 9.7 MB, copied into both install paths), the
resident index (a 1 MB staging budget applied to a ~28 MB output), and the
runtime's manifest cap (4 MiB against the 6.25 MB file
--verify-installhad just accepted). - The downloader survives a truncating link: length-verified 64 MiB ranges, a small connection pool, HTTP/1.1, stall detection, and no resume that could append to a truncated prefix.
- The tools resolve their own Python by capability rather than a pinned version.
-
Release verification uses only the models already installed. The golden
gate reports every target it could not check instead of skipping it silently,
an installed model that no gate covers is an error, and the gate fails if it
changes
models/at all — so a release is never made to pass by downloading, converting or re-installing a model. -
A native NVMAI app icon, replacing the upstream fork's bird: the wordmark's
own palette, and reproducible with
tools/make_app_icon.py. -
The binary archive carries
NOTICEalongsideLICENSEandTHIRD_PARTY_NOTICES.md.
5.3 was prepared and tagged (v5.3) but never published, because the golden
gate could not complete on the machine it was cut from: a storage provider had
left most installs online-only and reading them failed. Nothing was missing from
the release itself, so its content first shipped to users in
5.4. The tag is kept as
the history it records.
-
One server serves every installed model.
--models-dirserves the whole catalogue on one port with one model resident at a time;/v1/modelslists them and a request naming another switches to it. One launcher replaces the eight per-model start scripts and the separate client launcher: it starts the API alone or with Codex, Claude Code, Qwen Code, OpenCode or Zed, and asks what to launch, the answer style, the model, the thinking level and — only where a model has an expert cache — the RAM limit. -
The dense Qwen 3.5 2B / 4B / 9B run on the GPU as well as the CPU, and
the engine is a per-request choice for them: the bare id is the GPU spelling
and
<id>@cpu/<id>@gpuname an engine explicitly. The refusal was lifted only after the GPU's logits matched the CPU engine's on the real install, layer by layer — which is the gate that caughtk_proj/v_projbeing read at the attention slot's 4-bit width while the install stores them at 8, a plausible wrong answer rather than an error. -
Optional agent memory:
NVMAI_MEMORY=1gives a model durable facts scoped to the repository a client is working in, inside the server process, with no database to install. The extraction marks whether the person asserted a fact or the model inferred it, and the guard (on by default where memory is on) stops an inferred fact from silently superseding an asserted one: unguarded the store answered 61% of a recorded session's questions, guarded 98%. -
Thinking is not the answer. Reasoning reaches clients as
reasoning_content, apart fromcontent, on every surface, and each model offers only the levels its template renders. A thought the model opens while thinking is off is now split out too — Qwen-AgentWorld 8-bit does exactly that, and its scaffold used to arrive as the answer — and the server logs it. - The APIs coding agents speak: the OpenAI Responses API in full and the Anthropic Messages API, both exercised against the real Codex and Claude Code CLIs rather than only against test doubles.
- A deep audit of the whole tree: 89 code findings and 8 documentation defects, 0 open. The worst were silent rather than loud — an out-of-bounds router write on Qwen3.8-Flash-Next, a prompt-cache restore that left the sparse indexer holding the previous conversation's keys, and a fused kernel that could never be built, so every measurement of that path had measured the unfused one.
-
Watchdogs, off by default:
NVMAI_WATCHDOGS=1watches for a repetition loop, a stall, a stub answer and a ping-pong turn, and names which of them may stop a generation rather than only report it. - Structure and language baseline: the 2,599-line HTTP server is eight files, the test tree mirrors the source tree, the compiler warning count is zero, and the three upcoming Swift features the tree was already clean under are now enforced (the three with a real migration cost are recorded as deliberate, with what they would cost).
- This release's own measurements — every model, both engines, three repeats,
every reply quoted verbatim, including the install that thinks with the
switch off — are in
benchmark/benchmark-results/capital-of-paris-20260911T1935/in the repository. The 512-token story table under Benchmarks was measured at 5.1 and has not been re-run.
- The expert prefetch ring was clogged and is now repaired. A reclaim rule introduced in 5.0.2 freed a speculative slot only once its layer index had passed, so a prediction made for the last layer of a token was never freed and the ring ran with almost no free slots. Every prefetch measurement since compared variants of a mechanism that was not running.
- Prefetch is on again for the 35B models, one read deep, measured per install: Qwen 3.6 +1.8% at 4-bit and +11.3% at 8-bit, Ornith 1.5 +1.8% / +12.6%, Qwen-AgentWorld +1.4% / +11.4%. Qwen3.8-Flash-Next keeps it off, where the repaired ring loses at every setting: its experts are larger and arrive after the layer that would have used them.
- The expert cache stays wired through prefill. It used to be released at prefill, swapped out under memory pressure, and faulted back in by the first decode token, costing 1.6-4.7 s per request. Short answers gain 5-7%; long ones about 1%; prefill is unaffected.
- A start script per model and quantization, eight in all, each on its own port so two can run at once. The interactive launchers and the start scripts now share one catalogue of models, paths and ports, and both read the served model id from the running server rather than assuming it.
- The Mac app recognizes the models you have installed. Its catalogue listed only MLX repacks, so after 5.0.1 moved installs to bf16-sourced builds it treated all of them as foreign checkpoints. It now fingerprints each of the eight, and where it cannot download a build itself it prints the installer command instead of a Download button.
- New decode diagnostics, and three levers measured and left off by default: early expert hits, a probe-weight prefetch gate, and a decayed-frequency cache policy.
- Story benchmark, base M3 24 GB: AgentWorld 21.74 / 12.28 tok/s (4 / 8-bit), Ornith 21.65 / 11.93, Qwen 3.6 21.41 / 12.37, Qwen 3.8 5.46 / 2.10.
-
Every installed model and width has its own tuning row (expert-cache
budget, prefetch depth and disk I/O tier, prefill chunk, sampling defaults,
kernel switches), resolved family default, then row, then environment.
Editing one install never moves another;
NVMAI_*variables still override. -
The 35B-A3B models get bigger expert caches. A per-role split showed a
fifth of the 4-bit token and over a third of the 8-bit token waiting on
expert reads at the old 128 / 64 slots per layer. Qwen 3.6, Ornith 1.5 and
Qwen-AgentWorld now ship 160 slots at 4-bit (10 GiB) and 96 at 8-bit
(12 GiB), measured on each install with swap sampled: +9% at 4-bit and +15%
at 8-bit, output byte-identical. 192 slots at 4-bit measured +4% more but
starts paging on a 24 GB machine;
--ram-budget 12Gselects it. - Qwen3.8-Flash-Next: 4-bit prefetch runs two deep on the utility disk I/O tier (+3%); 8-bit takes 40 slots (+8%). Two-layer-ahead prefetch and the fused hyper-connection gates measured washes and stay opt-in.
- Ornith 1.5 is rebuilt from its bf16 release through the shared converter; no third-party quantization remains in the installer.
- Story benchmark, base M3 24 GB: AgentWorld 21.28 / 11.16 tok/s (4 / 8-bit), Ornith 20.99 / 10.89, Qwen 3.6 20.95 / 11.23, Qwen 3.8 5.40 / 2.06.
- Fixed a 5.0 decode regression on the 35B models: per-kernel environment reads (about 800 per token) cost most of a 45 ms token. Qwen 3.6 4-bit went from 6.67 back to 19.21 tok/s; output unchanged on every golden.
- Added Qwen-AgentWorld 35B-A3B (4-bit and 8-bit), installed straight from Qwen's bf16 release: one download quantized a shard at a time into both widths, router, shared-expert gate, DeltaNet gating projections and every norm kept at bf16.
- Every install now comes from its own bf16 release through one converter;
the embedding and head stay 8-bit for quality (
--head-bits 4exists and is worth about 20% on 35B 4-bit builds). - Top-8 routing uses the one-simdgroup selector (byte-identical, a few percent on the 35B family).
- Added Qwen3.8-Flash-Next 125B-A6B in 4-bit: 48 layers of gated DeltaNet with sparse-indexed attention, 512 experts at top-10, hyper-connection residual streams, a QSA key indexer, and hashed n-gram embeddings at layer 1. Text-only; the checkpoint's vision tower is not repacked. An install is about 161 GB on SSD, of which the n-gram table alone is 95 GB, and it runs on a 24 GiB machine because only a bounded slice of its experts is resident.
-
The expert-cache budget and expert prefetch are now tuned per family and
quantization rather than being one number for the catalogue. Both are
governed by how much of the token is expert I/O, and that varies by nearly 3x
across the shipped models. Qwen3.8-Flash-Next takes a 12 GiB budget (96 slots)
and depth-1 prefetch, worth +21.3% together (5.735 to 6.957 tok/s); Qwen 3.6
and Ornith take depth-1 prefetch at 8-bit (+5.5% / +5.9%) and no prefetch at
4-bit, where it measured -4.2% / -3.9%. The tuned budget is clamped to half of
physical memory, so a 16 GiB Mac is not handed a budget measured on a 24 GiB
one.
--ram-budgetandNVMAI_PREDICTIVE_PREFETCHoverride both, in either direction. - Speculative prefetch now filters the predicted experts by residency before capping the ring rather than after, so the budget is aimed at experts that would otherwise miss instead of being spent on ones already cached. Ring depth is a bandwidth decision and is sharply peaked at one read in flight: depth 1 measured +12.2% where depth 4 measured -9.8%.
-
ANE prefill is now the default (
NVMAI_PREFILL_ANE=offopts out). Models without an exported sidecar fall back to the GPU automatically. -
Breaking: API model ids now always end in the routed-expert width, for
example
ornith-1.5-35b-a3b_8-Bit. The width comes from the manifest rather than the name, so two quantizations of the same weights are distinguishable in/v1/models. The bare id is no longer accepted. -
NVMAICLInow derives its expert-cache slots the way the server does instead of defaulting to a flat 64 for every model, so the two front ends agree.
- Production sampling (Top-K 1...64, which includes the default Top-K 20) now
runs through the tiled three-stage GPU reduction instead of a
single-threadgroup kernel that re-scanned the full vocabulary once per
kept candidate. Sampled output at a fixed seed is unchanged
token-for-token; the per-token sampling cost fell from 15.5 ms to 1.4 ms.
NVMAI_SAMPLER_PATH=generickeeps the old kernel as a measured control. - Added the experimental opt-in ANE prefill path (
NVMAI_PREFILL_ANE=on): full-attention prefill blocks run on the Neural Engine from a Core ML sidecar exported once per model withtools/export_ane_prefill.py. A 6,103-token prompt measured 2.31x faster prefill (132.90 s to 57.52 s) with decode unchanged. Off by default because its fp16 attention is not byte-identical to the GPU path; the greedy golden baseline runs with it off. Short prompts, prompt-cache resumes, and MTP chunks stay on the GPU automatically. - The MTP verify pass now plans both rows' experts as one union, overlaps one
parallel miss fetch with the shared expert, and reads the lm_head once per
pass. Faster than the old width-4096 tile scheduler at width 2 with
byte-identical output;
NVMAI_MTP_VERIFY=tileretains the old schedule. MTP itself remains off: re-qualification still failed promotion at both quantizations even at 84-86% draft acceptance. - Sampling is now visible to
NVMAI_KERNEL_STATSas its own role, and MTP runs report per-pass phase attribution underNVMAI_RUNNER_STATS. - Retained the v4.2 control-plane and v4.3 predictive-prefetch experiments as documented, non-default controls; production decode scheduling is unchanged from v4.1.
- On the release M3/24 GB benchmark, median Ornith decode improved from 16.45 to 22.53 tok/s at 4-bit and from 8.75 to 9.40 tok/s at 8-bit.
- Decode now executes phase 1 for already-cached routed experts while missing experts are read from SSD, then runs a bounded fixup for those misses. Shared expert work remains overlapped with routing and I/O.
- Cache-slot leases prevent in-flight expert buffers from being evicted or overwritten. The default pread path still bypasses the macOS page cache and preserves the configured RAM bound.
- Added per-run hit/miss, reload, read-latency, hidden-I/O, and hit/fixup-layer telemetry plus a deterministic barrier-versus-hit/fixup benchmark.
- Kept the Metal expert-I/O backend experimental; production continues to use bounded pread because Metal I/O is not yet a complete faster replacement.
- Fixed command-buffer completion tracking found during release benchmarking. Golden output remained identical after the scheduling change.
- On the release M3/24 GB benchmark, median Ornith decode improved from 15.31 to 16.45 tok/s at 4-bit and from 8.31 to 8.75 tok/s at 8-bit.
- Added an eight-cell Ornith coding/tooling matrix for 4-bit and 8-bit weights, Concise on/off, and Thinking on/off. Four isolated Swift, Python, TensorFlow, and PyTorch repairs receive up to 25 turns and must pass both public execution and chained hidden validation.
- Exposed Ornith/Qwen thinking consistently as the models' official binary
off|onswitch in the server, CLI, Mac app, launchers, and benchmark profile. Low/Medium/High modes are not offered because the model templates define no effort levels or thinking-token budgets. - Made Ornith 1.5 35B-A3B 8-bit with Concise off and Thinking off the default installer, Mac app, launcher, benchmark, release gate, and real-inference golden baseline. Qwen 3.6 and Ornith 4-bit remain explicit options.
- Added pinned, text-only Ornith 1.5 35B-A3B installers for 4-bit and 8-bit. Ornith reuses the existing bounded Qwen3.5-MoE runtime and SSD expert streaming; its tokenizer and chat template remain model-specific. Vision is deferred.
- Added reproducible preparation and local import of Ornith's official native one-layer MTP draft. It shares the matching target embedding and head while keeping draft experts SSD-streamed and bounded. Cross-model Qwen/Ornith pairings are rejected. MTP remains experimental and off by default because the first M3 benchmarks found no repeatable speedup.
- Standardized Mac app, CLI, Chat Completions, Responses API, decode-service,
and benchmark defaults across Qwen and Ornith quantizations: temperature
0.6, Top-P0.95, Top-K20, and presence penalty0.0. Nonzero presence penalties remain unsupported; greedy correctness and MTP measurements still override temperature to0explicitly. - Added 16-, 8-, and 4-bit KV-cache storage with 8-bit as the default. The cache remains bounded and grows on demand independently of model weight precision.
- Added optional YaRN context scaling for 512K and 1M contexts. Native RoPE is still the default; YaRN defaults to 1M when enabled and currently excludes MTP.
- KV state now grows on demand, bounded expert I/O is the default, and the server accepts a RAM budget that derives the expert-cache size.
- Six-bit support was withdrawn; current supported installations are 4-bit and 8-bit.
- Reduced transition idle time and improved decode throughput while preserving deterministic output.
- Added clearer GPU occupancy, routing, and runtime timing instrumentation.
- Fixed sampler, moved-install, unload, and concurrency defects found in a production audit.
- Added lint, ThreadSanitizer, and real-inference golden-output gates.
- Added lazy loading, idle unload, and manual model unload.
- Improved receipt recovery and prompt-cache consistency for fast-alias turns.
- Hardened streaming tool calls, cancellation, UTF-8 detokenization, installer durability, and server queue behavior.
- Aligned server sampling defaults with the Mac app and CLI.
- Added the unified server and coding-CLI launchers.
- Added optional reasoning mode and removed the artificial default response cap when clients omit one.
- Added
qwen3.6-35b-a3b-fastfor chat-only coding-CLI requests with much less prompt prefill.
- Corrected expert-cache and prefill defaults and improved API compatibility.
- Added native
POST /v1/responsessupport and direct Codex connectivity.
- Added per-model concise prompts and standardized model-directory names.
- Added parallel expert fills, larger expert caches, read advice, larger prefill chunks, and the kernel benchmark suite.
- Released Qwen 3.6 inference with the installer, CLI, Mac app, bounded expert streaming, and local OpenAI-compatible server.
Start
Use TinyTitan
DeepSeek Harness
Reference
Project