Qwen3.8-27B came out on 14 August. This release runs it the way the model card says it should be run, with three MTPLX builds tuned for it, FP16 versions of all three for M1 and M2 Macs, and a longer compiled verify window that helps every model. It also fixes a CPU drain in the SSD session cache and a crash on macOS 27.
Every speed number below was measured on one M5 Max with fans verified at maximum, die temperature gated before each run, one request at a time, generation running to the model's own stop. Other Macs will land elsewhere. Nothing here was measured on M1 or M2.
There is a new qwen3_8 model family in the engine and the app. It carries
Qwen's official inference contract instead of the Qwen 3.6 coding defaults:
xhigh, medium and low. Coding sessions
default to medium: on the same uncapped agent task, medium finished
correct in 51.5 s where xhigh took 314.9 s. You can pick xhigh per
request, on the CLI (--reasoning-effort xhigh) or in the app before you
start the model.chat_template_kwargs: {"enable_thinking": ...} request field is
honored, so client code copied from the model card works unchanged.The 3.8 trunk keeps the 3.6 hybrid attention layout, so the whole kernel stack transfers as is: compiled verify graphs, the custom verify kernels and the GQA fast paths engage identically, with the same load-time self-check on your own chip.
Each build states its measured calibration in its own runtime metadata: recommended draft sampler (Bare Speed 0.6, the Optimized pair 1.0), tuned MTP depth (3 for all three), and peak memory measured on that build. The runtime reads that metadata ahead of profile fallbacks, so a build launches at its own tuned depth even when the serving profile disagrees, and the app and the CLI launch every 3.8 build identically because neither pins a draft sampler of its own any more.
Sizes shown in the app and CLI are the exact byte sums of the published Hub files, and the peak memory numbers are measured, not inherited from a 3.6 sibling.
mtplx quickstart, mtplx start and the app's first-run picker offer the
whole 3.8 line-up in the same order with the same one-line descriptions:
Optimized Speed as the recommended default, then Bare Speed, then Optimized
Quality (Quality is hidden on 32 GB Macs because its measured 33 GB peak
does not fit there). Qwen 3.6 Optimized Speed V2 stays directly below them
and keeps its turbo profile.
If you already use MTPLX and your last run used the recommended default,
mtplx start says once that the default moved and from which model, instead
of quietly relabeling. The app keeps whatever model you had; it does not
switch you.
M1 and M2 have no native bf16, so every 3.8 build has an FP16 sibling on the
Hub (Youssofal/Qwen3.8-27B-MTPLX-...-FP16). They are the identical model:
every quantized pack is byte for byte the parent's (498 of 498 per build),
and every 16-bit tensor is the bf16 value cast to fp16 (99.992% of elements
exact; the remaining 0.008% are magnitudes below 7.6e-6 rounded on the fp16
subnormal grid, largest error 3.0e-8, none overflow). No bf16 tensor is left
in any of them.
The M1/M2 tier of the CLI and the app routes to the FP16 siblings
automatically: same three picks, same order, same descriptions, and the
OpenCode config names the id the server actually advertises
(mtplx-qwen38-27b-...-fp16). All three launch on turbo like their parents
and pass the fp16 kernel self-check at boot; if a chip ever disagrees, the
affected lane falls back to the stock path on its own.
Since July the compiled verify graph stopped at 12,288 tokens of context,
because a KV copy tax at the time made longer compiled windows a regression.
That tax is gone, so turbo now compiles verify to 32,768 tokens. Interleaved
A/B on Qwen 3.8 Bare Speed under die-temperature gates: the compiled path
beat the eager fallback in every paired epoch (48.5 against 45.4 tok/s at 20k
context, +6.9%), with flat peak memory at 20k and lower at 30k (25.4 GB
against 28.5 GB; the eager path is the one that spikes). Past the fence the
same custom kernels run eagerly, exactly as before. MTPLX_COMPILED_VERIFY
can now be set by hand for parity and exactness runs against the shipped
profile.
xhigh available and medium as the
coding default, Tune from AR to D3, and catalog rows with exact sizes and
measured peaks.1...1 for models without draft
control, and the context-window slider could hit 4096...4096. Both are
now built only when there is something to slide. Reported and fixed by
@joshlacal./health poll. On a long-lived bank (816,220 files, 89.9 GB) each walk
took 41.7 s. The cap check forced one per write, and the app's health
poller kept another running back to back: most of a CPU core, all the
time, heating the die under live decode. Reconciliation is now
maintenance. It runs only when the store changed and at most 5% of the
time, off the writer lock, yielding to live traffic, and the cap gate
prices orphan bytes from the last snapshot instead of walking again.
Measured on that bank: idle CPU with a health poller 35% down to 0.2%,
per-write cap gate 71 to 159 s down to 3 to 6 s, cache-hit restores
unchanged.mtplx pull names the mirror knob when a download fails for a network
reason and no HF_ENDPOINT is set (#259): HF_ENDPOINT=https://hf-mirror.com
on the CLI, Settings, Advanced, HF download mirror in the app. Both were
already supported and neither was documented; the troubleshooting docs now
cover them.mtplx doctor judges memory against the model this Mac would actually
default to (9B under 32 GB, FP16 on M1/M2) instead of pricing a 27B
against 80% of RAM and failing every Mac under about 45 GB. M5 Max is
listed in the support matrix./usr/sbin/sysctl and /usr/sbin/system_profiler
by absolute path, so it works from the app's sanitized environment on any
Mac. mtplx doctor and mtplx tune no longer run git outside a
repository, which on a Mac without the Command Line Tools used to pop the
Xcode install dialog during onboarding.mtplx tune validates depths against what the
model actually supports and takes its sampler from the same family
contract as mtplx serve.MTPLX_REQUEST_LOG_JSONL=1 means "log to the default file", not a file
literally named 1.mtplx tune
gained --require-max-fans for the same reason.module_overrides: per-module quantization overrides
applied in one conversion pass (suffix match, optional layer list, bits,
group size, mode). This is the lane that built Optimized Speed.xhigh in the app's Inference settings while the model is
already running is rejected by the server in this build, and
mtplx config set reasoning_effort xhigh is rejected the same way. Set it
before starting the model, or pass --reasoning-effort xhigh on the CLI.@joshlacal for the macOS 27 crash report and fix (#256, #257), and everyone who filed the download and mirror reports behind #259.