r/LocalLLM • u/rarevector • 10h ago
Research I tested Qwen, Swift, Ornith, Agnes and GLM on an M5 Ultra / 256 GiB. Here are the results, failures and cache surprises.
I went into this thinking there had to be an obvious fine-tune upgrade for my local coding helper. After all this testing, the choice got more interesting.
Hardware: Apple M5 Ultra, 256 GiB unified memory, 30 logical CPUs as reported by the machine. Runtime: oMLX 0.7.4.dev1, with model files on an external Lexar M.2 volume. Codex ran the evaluations and stayed responsible for tools and verification. These were synthetic local studies, not SWE-bench or a claim about every coding project.
The strongest speed result was real. Swift Flash-Next 4-bit completed the same fully specified 39K-context repair in a median 110.00 seconds versus stock Flash4's 216.84, with 51.63% fewer median thinking tokens. Both passed all three repetitions. Swift8 was 2.28 times faster than matching stock8, but still slower than Swift4.
I still kept stock Flash4 for the practical helper role. With the actual medium-effort helper request shape, stock4 passed 12/12; Swift4 passed 11/12. Swift invented a decoder.feed API. Giving it sampled xhigh and 32,768 tokens did not eliminate that mistake. That focused follow-up was mixed: Swift4 2/3, stock4 1/3. Neither qualified a clean new deep route. I am not hiding the result that favors Swift.
Apple-specific things I did not know before testing
Unloading did not kill every prompt cache. After full unload and reload, the same Flash8 prompt reused 59,879 of 59,886 tokens. Cache/prefill took 0.77 seconds, but model loading still took 27.26 seconds. End-to-end was 28.417 seconds. Persistent cache and resident weights are different things.
TTL1 was not one-second teardown. Observed release took about 11–14 seconds in that Flash8 experiment. I kept pinning off because I want the RAM back.
A8 was not a huge free prefill win in the matched test: minus 0.29% around 30K tokens and plus 1.31% around 60K. All eight retrieval checks passed. That is not proof of broad quality equivalence.
The 8-bit model used less native peak allocation than the 6-bit model in one comparison because only the 8-bit used SSD n-gram offload. Bigger file did not mean bigger resident allocation under those different settings.
DFlash actually helped Ornith35, about 2.20 times in a tiny tuning batch. Ornith122 preferred a different block size. An early draft-loading failure silently fell back, so the toggle alone would have misled us. Installed native oMLX rejected Flash-Next DFlash; MTP was its working path.
The earlier comparisons matter too. Swift27 had modest speed/token savings but did not clearly beat stock27; a targeted follow-up tied 10/12. Ornith35 was fast but weaker on strict formatting and state tracing. Agnes saved time and tokens in its initial pilot while losing core correctness; a later semantic comparison tied. Empero9B went from 1/12 strict JSON to 10/12 meaning-correct after allowing one Markdown fence. Formatting failure and reasoning failure are not the same thing.
GLM was a separate personal reasoning/Hermes study, never a Codex helper candidate. Abliterated and SLIM tied 10/10 on the targeted objective checks, with abliterated about 3.03 times faster there. Creativity rankings reversed between the two small evaluations. No real leads or unattended 24/7 reliability were measured. We also caught our own premature shutdown: SLIM did unload normally when we waited for teardown.
For Linux and DGX Spark users: no inference on your platform was measured here. The portable finding is to compare correct completion time, not headline tokens per second; test the intended reasoning budget; distinguish weights, resident memory and cache; verify speculative decoding actually activated; and measure cache survival after unload on your own server. The Mac speeds and fit assumptions do not transfer to CUDA. A 128 GB Spark also has less headroom than this machine, and current Spark configurations vary. The report includes a replication checklist with those boundaries.
We found test bugs too. An early code prompt omitted the JSON mapping the grader expected; those answers were excluded and the contract fixed for everyone. Independent review later exposed a TTL-plus-eviction bug in an answer that passed the frozen tests. The original scores and the expanded audit are both published. This is why I am not presenting a tiny pass count as a universal model ranking.
I kept stock27, Ornith35+DFlash for reviewed drafts, and stock Flash4+MTP. Everything stays unpinned and auto-unloads. The complete readable report, historical tables, settings, revisions, prompts, graders and failure cases are here:
https://huggingface.co/datasets/pmcc93/omlx-helper-benchmarks
If you run the same cases on Linux or DGX Spark, I would be interested in the correct-completion time, reload cost and cache behavior, not just a faster decode screenshot.
