Vol. III · Essays on work after AI
Saturday, October 3, 2026
evolving.work
Local AI · Essay № 072

The Best Local Models for a 64 GB MacBook Pro

The page I keep updated with the local model I would actually run on a 64 GB MacBook Pro today, why I picked it, and what else I tried.

Tested 17 September 2026 · Updated 19 September 2026 · one M5 Pro MacBook Pro, 64 GB unified memory · 12 prompts · sources

This is the page I keep updated with the model I would actually put on a MacBook Pro today, and it is the one page in this series I expect to rewrite. I have an M5 Pro with 64 GB of memory, I wanted to get work done on it without sending anything to a provider, and I wanted to know which of the packages I could fit was worth the disk space. So I wrote a set of prompts with answers I could check, ran a pile of model builds against them over the weeks up to 17 September 2026, and kept everything, including the runs that went badly. The evidence on this page is frozen at that date.

It works. A 27-billion-parameter Qwen model stored at 8 bits answered every one of the structured prompts correctly, took about twelve and a half minutes for the whole set, and wrote four pieces of prose I was willing to read. That is enough for real work with nothing leaving the machine: pulling structured records out of messy text, small SQL and Python jobs, a briefing from source material I supply, a rewrite of my own draft. It is not fast the way a hosted API is fast, and it cannot keep a whole codebase in mind at once.

A pruned, 4-bit build of Qwen’s sparse Flash-Next model, which I converted myself, is about a quarter faster on the six structured tasks both it and the 27B finished. It never finished two of the others, spending more than an hour between them in loops that produced nothing usable. I kept the 27B installed.

Best on this page means the model I would pick today, among the packages, workflows and tasks I have actually tested, on this one Mac. It does not mean any of these is best at every job, and it does not carry over to a different machine. The recommendation is followed by the per-test comparison table, the other model families and the testing method. The field guide, the 27B builds, the head-to-head and the custom build all link here for current recommendations.

Look at the results for yourself: choose models and compare each test by time, token speed and generated tokens.

What I run today

The model I have installed today is Qwen 3.8 27B in Youssofal’s 8-bit packaging, the one they call Optimized-Quality. It is what I would tell a friend to start with. It finished everything I asked of it, and on a machine where the main failure mode is a model that never stops talking, finishing is the thing I care about most. A longer SEO-audit comparison with another 27B build, Splash, is in Splash! A Test of Real Work. Swift’s build of the same model is its equal, and you would not be wrong to run that instead. My custom Flash build is the one to reach for when you want speed on work you already know it can do.

Two labels appear on the cards below and it is worth knowing what they mean. Q8 means each number in the model is stored in eight bits rather than the sixteen it was trained in, which roughly halves the file and the memory it needs. MTPLX is the program that actually runs the model on this Mac; the settings each run used are spelled out in the specification at the end.

Each card below names the exact run it rests on and links to that row in the module further down. There is no combined score, because completion, correctness, time and writing quality moved separately in the runs, so they stay separate.

Conservative local default

Qwen 3.8 27B Q8

Youssofal Q8 MTPLX, the Optimized-Quality package — the one I have installed
Structured work
Answered every prompt correctly
Writing
Finished all four, and I was willing to read them
Pace
About twelve and a half minutes for the whole structured set

Caveat. It does not win every writing score. Its knowledge article was its weakest answer, with two moderate factual errors in it, and Swift’s briefing was marked higher than its own — one reviewer, one attempt each.

Evidence: matrix-16 →
Close alternative

Swift Qwen 3.8 27B Q8

The same model packaged by KrossKinetic, run the same way
Structured work
Answered every prompt correctly as well
Writing
Finished all four, and scored very close to the package above
Pace
Finished the whole set in about the same time

Caveat. A near tie, from one trial each, so the small difference in total time is not a speed ranking. It was quicker on most of the individual tasks and took about twice as long as the package above on the SQL question.

Evidence: matrix-15 →
Custom Flash option

My custom Flash-Next build

Qwen’s sparse Flash-Next, pruned and stored at 4 bits by me, run under MTPLX
Structured work
Got most of the prompts right and stuck on two
Writing
Finished all but the knowledge article
Pace
Quicker than the 27B on most of the work they both finished

Caveat. The two structured prompts it failed ran until they exhausted their output allowance and produced no answer, and the knowledge article did the same. Its data memo ended on a cause the numbers do not support. Its writing average covers only the answers it finished, so it does not sit beside the other two as it stands.

Evidence: matrix-03 →
The rest of the field

Gemma 4 and the earlier builds

Gemma run on Apple’s own MLX, plus the older builds I screened along the way
Gemma
Got nearly everything right; one prompt ran out of room before it answered
Published REAP-288 Q4g64
About half the structured prompts, across four runs
Flash-Next 3.3 bpw
About half again, in both of its runs

Caveat. Different budgets, runtimes and fresh-process timing, so none of these rows is directly comparable to the three above, and they belong to an older cohort. Earlier writing runs of the published REAP-288 Q4g64 build exist in a different cohort, in historical-writing-reviews.json; Gemma and the 3.3 bpw build have no writing run at all.

Evidence: matrix-11 →

Both 27B packages finished everything, within seconds of each other. My Flash build finished six of the eight structured prompts and burned more than an hour on the two it did not.

For these runs I deliberately let Flash continue up to the full output allowance, without an earlier reasoning cutoff or a corrective prompt: I wanted to see whether it would eventually return an answer. A harness could limit reasoning, detect repetition and tell the model it is looping before asking it to try again. It might self-correct, but these runs do not test that. I plan to test this next week, measuring completion and total time including retries.

Day to day that means I stop reaching for a hosted model on the small jobs. The wait is real — a minute or two on a structured answer, four to eleven minutes on a piece of writing — but I can start it and go and do something else, and nothing I paste into it goes anywhere. What I still send elsewhere is anything that needs a model to hold a large project in mind at once, and anything where somebody is waiting on the answer.

What this recommendation does not cover
  • Agent work with tools, repository access or a repair loop. The harness sends one prompt, saves the answer and grades it.
  • Long documents, multi-turn dialogue, other languages, images. None was tested.
  • Any other Mac. This is one M5 Pro whose 64 GB is shared by CPU, GPU and macOS, not 64 GB of dedicated VRAM.
  • A writing quality ranking. The scores are one assistant’s rubric review of single attempts, and the custom reviews were unblinded.

Compare the eight tests

Open the Models dropdown to select the runs you want to compare. Your selection is saved in this browser. Each test lists models in rows, with a horizontal time bar followed by decode speed, generated tokens and memory where recorded. Use Test to view one task or all eight. These are coding and structured tasks with answers checked by a script; the four writing tasks are assessed separately below.

Elapsed time and generation metrics · three current local runs
Model / runResultTask time · secondsDecode · tokens/sGenerated tokensPeak memory · GiB
invoice
Youssofal Q8matrix-16✓ Passed93.3 s20.36 tok/s1,857Not recorded
Swift Q8matrix-15✓ Passed76.5 s21.73 tok/s1,634Not recorded
Custom Flashmatrix-03✓ Passed130.3 s24.88 tok/s3,205Not recorded
schedule
Youssofal Q8matrix-16✓ Passed113.3 s16.04 tok/s1,795Not recorded
Swift Q8matrix-15✓ Passed107.1 s16.24 tok/s1,724Not recorded
Custom Flashmatrix-03✓ Passed79.2 s20.11 tok/s1,569Not recorded
intervals
Youssofal Q8matrix-16✓ Passed72.0 s17.36 tok/s1,236Not recorded
Swift Q8matrix-15✓ Passed49.9 s20.38 tok/s1,003Not recorded
Custom Flashmatrix-03✗ Failed2,336.5 s27.41 tok/s64,000Not recorded
batches
Youssofal Q8matrix-16✓ Passed96.1 s17.79 tok/s1,693Not recorded
Swift Q8matrix-15✓ Passed57.6 s22.34 tok/s1,272Not recorded
Custom Flashmatrix-03✗ Failed2,166.6 s29.56 tok/s64,000Not recorded
sql
Youssofal Q8matrix-16✓ Passed68.1 s17.97 tok/s1,202Not recorded
Swift Q8matrix-15✓ Passed140.0 s19.63 tok/s2,727Not recorded
Custom Flashmatrix-03✓ Passed62.7 s30.64 tok/s1,902Not recorded
cache
Youssofal Q8matrix-16✓ Passed151.3 s20.37 tok/s3,037Not recorded
Swift Q8matrix-15✓ Passed174.8 s17.48 tok/s3,022Not recorded
Custom Flashmatrix-03✓ Passed102.1 s31.73 tok/s3,206Not recorded
extract
Youssofal Q8matrix-16✓ Passed89.5 s19.04 tok/s1,676Not recorded
Swift Q8matrix-15✓ Passed69.2 s18.16 tok/s1,214Not recorded
Custom Flashmatrix-03✓ Passed88.1 s31.05 tok/s2,706Not recorded
policy
Youssofal Q8matrix-16✓ Passed59.6 s20.06 tok/s1,165Not recorded
Swift Q8matrix-15✓ Passed49.0 s19.52 tok/s920Not recorded
Custom Flashmatrix-03✓ Passed25.5 s39.33 tok/s963Not recorded

Time includes failed attempts; hatched bars mark failures. Bars share a scale within each test. These runs use different runtimes and cohorts. The interactive version adds model selection and earlier screening packages. Per-test memory was not recorded.

Every family I tried, and what each is good for

I tested nine locally run model families on the same prompts. The hosted Qwen 3.8 Flash and Qwen 3.8 27B endpoints ran them too, and they appear further down as comparators rather than as things to install. The summaries below cover the selected variant from each family, best by a rule I state in the next section rather than by reputation. Which family you pick matters more than which variant of it you run, so the variant-level detail waits until further down.

Qwen 3.8 27B

A dense 27-billion-parameter model from Qwen, and the one I actually use. My recommended variant is the Youssofal Optimized-Quality Q8 package on MTPLX, matrix-16: all eight objective tasks correct, all four writing tasks finished. The completion-and-time selection rule gives a different result. Inside the current cohort the rule picks Swift, matrix-15, and across all cohorts it picks the historical command-line run matrix-14; I show both below. I name Youssofal Q8 here because it is the recommendation and because it is the reference every other number on this page is measured against, and because Swift’s 2.55% edge in a single trial is not a speed ranking. It remains my default for these coding and structured tasks.

Qwen 3.8 Flash-Next

Qwen’s sparse sibling. It carries 512 routed experts in each layer and runs only ten of them for any given token, so a very large model does a small amount of arithmetic per word. The best variant I tested in this family is my own REAP-288 build in plain one-token-at-a-time mode, matrix-02, which completed seven of the eight objective tasks. The multi-token version of the same build, matrix-03, is the faster one and the one the other articles in this series feature, and it completed six. I cut the model down to 288 of those 512 experts and stored it at 4 bits, which is what made it fit on the machine; the set of experts I kept is sh0wie’s published selection, reused unchanged, and what I did was the conversion. The build article has the whole story, and the exact recipe is in the specification at the end of this page. Its summary and rewrite results were promising, but some requests exhausted the output allowance without an answer. It is an option for tasks it has already completed successfully, with a timeout and another model available if it fails.

Gemma 4

Google’s Gemma line, tested here as the 26B-A4B package. The best variant I tested in this family is the native MLX run, matrix-11: seven of eight correct, losing only cache, where it hit its 8,192-token budget with nothing to show. It produced words about two and a half times faster than the 27B on this machine, but under a much smaller output budget, so that speed is not a like-for-like win. It has no current writing run at all. A comparison under the same settings as the Qwen builds is still needed. I would rerun it under matched settings before recommending it over the 27B.

Laguna

Laguna-XS-2.1, screened in an 8-bit package. On its first pass it got two of the eight right; across later attempts at larger budgets the selected-latest rows show seven. The selected-latest result combines several tries under varying budgets and stopping rules; it is not a single fresh suite. It had the strongest result among the screening-only families and would be my next candidate for a matched run.

Qwen 3.6

The previous Qwen generation, in a 35B-A3B Balance package at 6 bits. One of eight on the first pass, six on the selected-latest rows. Its weighted decode of 69.84 tok/s is the fastest figure anywhere in my data, and it still passed fewer tasks than the Qwen 3.8 27B builds. These results give me no reason to choose it over Qwen 3.8 today.

MiniCPM5

MiniCPM5-2B at full 16-bit precision, the smallest model I tried. Four of eight on the first pass, six on the selected-latest rows, and quick: on the tasks it and the baseline both passed it took about 70% of the baseline’s time. Its output budgets were much smaller than the 27B’s, so the timings need a matched comparison. It completed much of the suite despite its size, but I would not replace the 27B with it.

Ornith

Ornith-1.5 in a 35B-A3B 8-bit package. Five of eight on the first pass and five again on the selected-latest rows, the only one of the six single-screening families whose retries did not move. It was also the fastest local row in the comparison on the tasks it and the baseline both passed; three hosted rows were quicker still. Its speed was useful on the five tasks it passed; retries did not improve completion.

Ternary Bonsai

A 27B model stored at about 2 bits per weight — a large model squeezed onto a small amount of disk, not a small model. Two of eight on the first pass, six on the selected-latest rows, and slow with it: on the tasks it and the baseline both passed it took about three and a half times as long. I had hoped for 27B behaviour at a fraction of the footprint, but the task times fell short. A different runtime or setting might do better; this artifact did not.

Spark

Spark-X2.5, a 4-billion-parameter package at full 16-bit precision. It passed nothing at all on the first pass and four of eight after retries, and it shares too few passing tasks with the baseline to sit on the charts below; on the four it does share it took about 4.7 times the baseline’s time. I would not choose it from these results, though it needs a rerun with a larger output budget before drawing a broader conclusion.

How I picked

Best variant I tested in a family means the variant that completed the most objective tasks. Where two tie, the lower total time wins. I apply this rule within each family. Differences in settings limit comparisons across families.

There are two qualifications to this selection rule.

Qwen 3.8 27B. Four separate runs completed all eight tasks. The two quickest are historical command-line runs: matrix-14, the Youssofal Optimized-Speed Q4 package, at 575.82 s, and matrix-08, the Youssofal Optimized-Quality Q8 package, at 576.33 s, half a second apart. Both ran with a 4,096-token output allowance, while the current runs matrix-16 and matrix-15 ran with 64,000, and each historical answer started a fresh process whose wall time includes loading the model. Those timings cannot be compared directly with the current runs. Inside the current cohort the rule picks Swift, matrix-15, at 724.15 s over Youssofal Q8’s 743.10 s — a 2.55% difference in a single trial, which is not a speed ranking. I name Youssofal Q8 as the family’s recommendation because it is the reference the rest of this page is measured against, and Swift as its equal rather than its runner-up.

Qwen 3.8 Flash-Next. The custom build’s plain autoregressive run, matrix-02, completed seven of eight. The multi-token run of the same build, matrix-03, completed six and is the faster of the two. The rule picks the AR run. The other articles focus on the MTP run to examine its faster decoding and incomplete tasks.

For each test, I send one prompt and a small Python script saves and grades the answer. No tools, no repository, no test feedback, no second attempt, no chance to notice a mistake and fix it. Eight of the prompts have exact answers I can check by running or comparing them; four ask for prose and are scored against a written rubric. One trial each, on 17 September 2026. That is a narrow test, and a good score on it is evidence about one-shot structured answering, not about a model’s ability to work through a task the way a person would.

Nobody in this comparison ran Qwen’s own upstream full-precision weights on this Mac. The baseline is the Youssofal Optimized-Quality Q8 package because that is the artifact I tested, and everything else on this page is measured against it.

If a friend asked me which of these to install, I would not start from the table. A dense model like the 27B does the same amount of work for every word it writes, so it is slow in a predictable way: you can watch the clock and know roughly when it will finish. A sparse model like Flash-Next wakes only a small part of itself for each word, which is why a model that large runs on a laptop at all and why it can be quicker. What I did not expect was how differently they fail. When the 27B gave me a wrong answer it gave it to me quickly, and I could see it was wrong. When my Flash build went wrong it did not stop: it kept producing text until it ran out of room, twice, and those two attempts cost me more time than the whole rest of the suite. So when I choose, I weigh the time saved on a good run against the time lost on a bad one, and for everyday work I would rather have the model that always stops.

How much to trust any of this depends on what you want it for. Twelve prompts run once each is a small test, and I know these twelve well enough by now that a model doing well on them is not the same as a model doing well on yours. What the test is good at is catching the thing I care about most: whether a model returns a complete, checkable answer without help. What it cannot tell you is how a model behaves when it can run code, read a repository and try again after a failure, because nothing here lets it do any of that.

The runs themselves

The explorer below includes every recorded run and the two conditions I prepared but never ran. Those are marked “not run”, with no result.

The hosted version of the same model did not simply run the same work faster. The hosted 27B at a 64k reasoning budget passed 6 of 8, failing schedule and sql where both local 27B packages passed, and its four writing answers received a model-judge mean of 86.5/100 with factual flags on three of them. Hosted Flash passed 7 of 8 at a 32k reasoning budget and 8 of 8 at 64k, two independent trials that do not show the larger budget caused the difference.

ConditionIDObjective correctFailed tasksWriting finished
Qwen 3.8 27B Q8 · MTPLX HTTP · medium · MTPmatrix-168/8none4/4
Swift Qwen 3.8 27B Q8 · MTPLX HTTP · medium · MTPmatrix-158/8none4/4
Custom Flash Q4g32 + Q8 · MTPLX native · MTPmatrix-036/8intervals, batches: both hit the 64,000-token ceiling with no final answer3/4

One trial per task, evidence frozen 17 September 2026. Hosted comparators and older runs are in the downloadable data at the end of this page.

What it cost in time

The comparison table above shows the per-test numbers. The charts and calculations below give the aggregate comparisons and time spent on failures.

Detailed timing charts and calculations

The measure I care about is seconds to a passing final answer, not the token counter. An attempt that failed gets no bar and keeps its elapsed seconds; a condition that was never run reads not run.

The two 27B packages both passed all eight objective tasks and finished all four writing tasks; the 2.55% gap between their totals comes from one trial and does not establish a speed ranking. Custom Flash passed six of eight and spent 4,503.09 s on the two it did not finish; its three finished writing answers received model-judge ratings of 93/100, 80/100 and 92/100. Gemma passed seven of eight under an 8,192-token budget, one fresh process per task, a different cohort.

Here are the rows behind the four cards, with the exact figures and the settings each one ran under.

RowHow it ranObjectiveWriting
Youssofal Q8 MTPLX, matrix-16HTTP server, medium effort, MTP, 64,000-token budget8 of 8 correct in 743.10 s4 of 4 finished, mean 86.75 /100 over 4; 90.67 on the three tasks custom Flash finished
Swift Q8, matrix-15MTPLX HTTP, medium effort, MTP, 64,000-token budget8 of 8 correct in 724.15 s4 of 4 finished, mean 87.50 /100 over 4; 91.67 on those same three
Custom Flash Q4g32 + Q8, matrix-03MTPLX native, medium effort, MTP with draft depth 3, 64,000-token budget6 of 8 correct; 487.85 s on those six, 4,503.09 s on the two that failed3 of 4 finished, mean 88.33 /100 over 3
Gemma 4 26B-A4B Q8, matrix-11native MLX, AR, sampled, 8,192-token budget7 of 8 correct; cache hit its budget; 880.89 s for all eight attemptsNo current writing run
Published REAP-288 Q4g64, matrix-00, matrix-01, matrix-04, matrix-05MLX-Serve and MTPLX HTTP, AR and MTP5, 4, 4 and 5 of 8Earlier runs only, in a different cohort
Flash-Next 3.3 bpw, matrix-09 and matrix-10MLX-Serve, AR and MTP requested5 of 8 in bothNone

One trial per task for the matrix rows, 17 September 2026. The settings column uses the labels the runs were recorded with: AR means ordinary decoding one token at a time, MTP means multi-token decoding, medium is the reasoning effort the run asked for, and sampled means the run drew each token at random rather than always taking the most likely one. The glossary at the end has the longer versions. The recorded memory-pressure caveat applies to custom Flash’s four writing timings only; the last three rows belong to an older cohort with different budgets and fresh-process timing, so they are not directly comparable with the first three.

The two charts below put one model per family against the Youssofal Q8 package, matrix-16, at 100%, using the geometric mean of the per-task time ratios on the tasks that row and the baseline both passed. They are split in two for a reason. Only Swift and my custom Flash build ran with the same 64,000-token output allowance as the baseline; every other row ran with somewhere between 4,096 and 32,768 tokens, and a smaller allowance cuts a model off sooner, which can make it look quicker than it is. Read the second chart as context for what each family did on this machine, not as a race result.

One thing about the Flash-Next row in the first chart: it is matrix-03, the multi-token run, not matrix-02, the run my selection rule picks. matrix-02 completed one more task and was slower — a geometric mean of 112.68% of the baseline’s time on the seven tasks it and the baseline both passed.

Normalised time, matched 64,000-token output budget
Shorter is faster. Bar length runs from 0 to 400%. N is the number of tasks the row and the baseline both passed.
  • Geometric mean of per-task time ratios, matched budget
  • Youssofal Q8 MTPLX, matrix-16 = 100%
Qwen 3.8 Flash-Next · custom REAP-288, MTP · matrix-03 · N = 679.64%
Qwen 3.8 27B · Swift Q8 · matrix-15 · N = 891.41%
Geometric mean of per-task wall-time ratios against matrix-16, on the tasks each row and matrix-16 both passed. One trial per task, 17 September 2026. Both rows ran at a 64,000-token total output budget, as matrix-16 did, but matrix-15 ran on the resident MTPLX HTTP server in the current cohort while matrix-03 ran on a native MTPLX request path in a different cohort, so the Flash figure is a workflow observation rather than a matched comparison. The Flash-Next row is the multi-token variant matrix-03, not the matrix-02 run the selection rule picks.
Normalised time, lighter screening budgets
Same scale and same baseline as the chart above: 0 to 400%, matrix-16 = 100%. Each row prints the output budget it ran under.
  • Geometric mean of per-task time ratios, smaller output budget
  • Youssofal Q8 MTPLX, matrix-16 = 100%
Ornith · 1.5 35B-A3B 8-bit · N = 5 · 4,096–8,19257.63%
MiniCPM5 · 2B BF16 · N = 6 · 4,096–8,19270.44%
Laguna · XS-2.1 8-bit · N = 7 · 4,096–8,19293.87%
Gemma 4 · 26B-A4B Q8 native · matrix-11 · N = 7 · 8,192117.24%
Qwen 3.6 · 35B-A3B Balance Q6 · N = 6 · 4,096–32,768119.15%
Ternary Bonsai · 27B 2-bit · N = 6 · 4,096–16,384357.62%
Geometric mean of per-task wall-time ratios against matrix-16, on the tasks each row and matrix-16 both passed. Snapshot 17 September 2026. matrix-11 is one trial per task; the five screening rows are selected-latest results from earlier-models.json, meaning the best of several attempts under varying budgets and stopping rules, not a single fresh suite and not a pass-first-time number. Every row here ran a fresh process per answer, so its wall time includes loading the model. Spark-X2.5 4B BF16 is not shown: it shares only four passing tasks with matrix-16, where its geometric mean is 472.81%.

Between the three conditions I actually recommend from, the comparison is tighter. On the All tasks tab they share six passing tasks with the baseline: invoice, schedule, sql, cache, extract and policy. On those six, custom Flash took a geometric mean of 79.64% of the baseline’s time, arithmetic mean 85.06%, which is about 1.26× faster on the six tasks both models finished; it was quicker on five of them and slower on invoice. Swift took 102.69% of the baseline time on the same six (109.56% arithmetic, 0.97×), because its sql answer took 139.99 s against 68.07 s. Across all eight tasks, which both passed, Swift took a geometric mean of 91.41% of the baseline time (98.34% arithmetic, 1.09× paired speed) and was faster on six of the eight. The two 27B packages ran on a resident HTTP server and custom Flash on a native request path, in different cohorts, one trial each, so the gap cannot be put down to the model weights alone.

The totals below separate time spent on passing and failed attempts.

Objective suite: time on tasks that passed and time on attempts that did not
Bar length runs from 0 to 5,000 s. The hatched segment produced no passing answer.
  • Time on tasks that passed
  • Time on attempts that did not pass
Qwen 3.8 27B, Youssofal Q88 of 8 passed
743.1 s passed0 s not passedTotal 743.1 s
Qwen 3.8 27B, Swift Q88 of 8 passed
724.2 s passed0 s not passedTotal 724.2 s
Custom Flash, MTP6 of 8 passed
487.9 s passed4,503.1 s not passed (2 attempts)Total 4,990.9 s
Conditions matrix-16, matrix-15 and matrix-03, one trial per task, all eight attempts each, 17 September 2026. The two 27B packages ran on a resident MTPLX HTTP server in the current cohort; custom Flash ran on a native MTPLX request path in a different test cohort, so the rows are workflow observations, not a matched comparison. Custom Flash’s two failed attempts are intervals (2,336.5 s) and batches (2,166.6 s), both at 64,000 of 64,000 tokens.

Token rate is the number people quote and the one that misled me first. Weighted decode was 18.67 tok/s for Youssofal Q8, 18.95 for Swift and 28.42 for custom Flash, and the higher rate did not produce a faster suite: during its two loops custom Flash generated 64,000 tokens each at 27 to 30 tok/s and nothing passed. Gemma’s native MLX run decoded at 47.48 tok/s weighted, the highest local rate among the main conditions, under a much smaller output budget. Hosted rows have no GPU decode figure; the rate a client sees includes queueing and transfer, and the module never prints it as decode.

TaskBase Q8 matrix-16Swift Q8 matrix-15Custom Flash matrix-03
invoice93.3 s76.5 s130.3 s
schedule113.3 s107.1 s79.2 s
intervals72.0 s49.9 sfailed after 2,336.5 s
batches96.1 s57.6 sfailed after 2,166.6 s
sql68.1 s140.0 s62.7 s
cache151.3 s174.8 s102.1 s
extract89.5 s69.2 s88.1 s
policy59.6 s49.0 s25.5 s

Wall seconds to a passing final answer, one trial per task, 17 September 2026. On the six tasks all three passed (invoice, schedule, sql, cache, extract, policy), custom Flash took a geometric mean of 79.64% of the base time (arithmetic mean 85.06%, 1.26× paired speed). Its two failed attempts cost 4,503.1 s against 487.9 s on the six it passed. Base and Swift ran on a resident HTTP server, custom Flash on a native request; the runtimes and cohorts differ.

How the writing went

Four of the twelve prompts ask for prose: a briefing built from source material I supply, a short knowledge article, a memo written from a table of numbers, and a rewrite of a customer email. Each answer is scored out of 100 against a written rubric by one assistant. That is a judgement, not a measurement, and it is not a human blind test; the four custom Flash answers were reviewed with the model’s identity known, which introduces another potential source of bias. The scores are useful for examining individual answers, but do not establish a ranking.

Both 27B packages finished all four. Custom Flash finished three and never produced a final answer for the knowledge article. On the three all of them completed, the model judge rated the baseline 90.67/100, Swift 91.67/100 and custom Flash 88.33/100 — and custom Flash’s own four-task figure does not exist, because one of its four is unscored rather than zero. A difference of a point or two here means nothing: the baseline’s 88/100 on the email against Swift’s 87/100, or Swift’s four-task mean of 87.50/100 against the baseline’s 86.75/100, are noise.

The individual factual errors are more useful than small score differences. Custom Flash’s data memo got the arithmetic right and still received 80/100 from the model judge, because it ended on a causal claim the numbers cannot support. The baseline’s weakest answer was its knowledge article, at 75/100 with two moderate errors; Swift’s knowledge article also scored 75/100. The rubric penalizes factual errors even when the prose reads well.

Custom Flash’s knowledge article attempt stopped at 64,000 tokens after 2,009.93 s with an empty final text, and its raw output ended in repetition. The data does not show whether pruning, quantization or multi-token decoding was responsible. I had rebooted before that writing run and still observed elevated memory pressure, swap reads and compression, so all four custom writing timings carry the recorded caveat that the size of any slowdown was not isolated.

ConditionFinishedsource_summaryknowledge_explainerdata_to_reporteditorial_rewriteMean of scored tasksSame three tasks
Base Q8 matrix-164/48875968886.75 over 490.67
Swift Q8 matrix-154/49375958787.5 over 491.67
Custom Flash matrix-033/493No final answer, unscored809288.33 over 388.33

Assistant rubric scores out of 100 from single attempts, 17 September 2026. Not human blind tests; the custom reviews were unblinded. The same three tasks are source_summary, data_to_report and editorial_rewrite.

What exactly is in the test

Eight objective prompts and four writing prompts, sent one at a time by a small Python harness that saves the response and grades it afterwards; the model gets no tools and no second attempt. A correct answer inside a JSON or code fence is accepted. The objective suite leans toward structured reasoning: 37.5% of the eight prompts is executed code and another 25% is strongly algorithmic. Eight prompts are eight even though each has several internal checks, which is why one pass moves the objective rate by 12.5 points. An 8/8 says the model returned exact, checkable answers in one shot, not that it can do agent work, which needs tools and a repair loop this harness does not have. The same twelve prompts have been run against many builds, so they are development exposure, not a clean held-out test.

TaskOutputWhat it probesHow it is graded
invoiceJSONTotals; discount, tax and shipping order; monetary roundingExact structure and expected values
scheduleJSONDependencies, two machines, optimal schedule, tie-breakingExact optimal schedule
intervalsPython functionUnion of half-open intervals by user; validation; non-mutationNine executable cases plus non-mutation check
batchesPython functionDependency layers, implicit nodes, duplicate edges, cyclesNine executable cases plus non-mutation check
sqlSQLite queryJoins and aggregates, refunds, empty and zero-order casesFour database fixtures and a column-name check
cacheJSONTTL and LRU state, equal-time orderingExact expected state and counts
extractJSONCorrections, estimates versus actuals, timezone conversion, evidenceExact records and values with documented normalization
policyJSONRule precedence, strict boundaries, unknownsExact expected eligibility and credit
source_summary220–280-word briefingFaithful compression of supplied evidenceWeighted writing rubric against the source facts
knowledge_explainer450–600-word articleExisting knowledge, explanation, accuracy, natural proseWeighted rubric and an evaluator-only factual guide
data_to_report220–280-word memoArithmetic, a Simpson’s-paradox-style composition shift, causal cautionNumerical and factual review plus the writing rubric
editorial_rewrite160–220-word customer emailKeeping facts and uncertainty while improving tone and usefulnessFact preservation and the prose rubric

Full prompts, expected answers for the JSON tasks and the rubric are in the downloadable files at the end of this page.

The full specification

The selection rule, and its working

The rule is: most objective tasks completed, ties broken by lower total time, applied inside each family. Here is what it picks in the three families that have recorded condition IDs. The Qwen 3.8 27B row appears twice because the historical command-line runs and the current runs are not comparable, and the rule would otherwise hand the family to a 4,096-token run that includes model-loading time in its wall clock.

FamilyBest variant under the ruleCorrect /8All-attempt wall sOutput budget
Qwen 3.8 27B, all cohortsYoussofal Optimized-Speed Q4, matrix-148575.824,096
Qwen 3.8 27B, current cohortSwift Q8, matrix-158724.1564,000
Qwen 3.8 Flash-NextCustom REAP-288, AR, matrix-0273,581.9964,000
Gemma 426B-A4B Q8, native MLX, matrix-117880.898,192

Runs considered, by family: Qwen 3.8 27B has matrix-08 (Youssofal Optimized-Quality Q8 on the command line, 8 of 8 in 576.33 s), matrix-14, matrix-15, matrix-16 and the hosted matrix-19, plus four screening packages — Cold Fusion 8-bit at 8 of 8 in 729.53 s, Cold Fusion 4-bit at 7 of 8 in 792.63 s, and the Youssofal 8-bit and 4-bit packages, which are the same runs as matrix-08 and matrix-14. Flash-Next has matrix-00 through matrix-05, matrix-09 and matrix-10, with matrix-06 and matrix-07 prepared and never run, plus the Flash-Next 3.3 bpw screening package at 5 of 8 on its first pass and 6 on its selected-latest rows. Gemma 4 has matrix-11 (7 of 8), matrix-12 and matrix-13 (6 of 8 each) plus a Gemma 4 31B Q4 + Q6 assistant screening package at 3 of 8 rising to 5.

The other six families were screened once each, so the rule has nothing to choose between. Their numbers are here, and the two columns are different claims: the first pass is what the package did the first time, and selected latest is the best of several attempts under varying budgets and stopping rules, which is neither a fresh suite nor a pass-first-time figure. The wall seconds are for the selected-latest attempts and do not include time lost on earlier ones.

FamilyPackageFirst pass /8Selected latest /8Selected-latest wall s
LagunaLaguna-XS-2.1 8-bit27742.06
Qwen 3.635B-A3B Balance Q616868.11
MiniCPM5MiniCPM5-2B BF1646732.52
Ternary BonsaiTernary Bonsai 27B 2-bit263,106.45
OrnithOrnith-1.5 35B-A3B 8-bit55515.73
SparkSpark-X2.5 4B BF16043,857.84

Weighted decode on the selected-latest rows: Qwen 3.6 69.84, Laguna 56.51, Ornith 55.63, MiniCPM5 46.14, Spark 27.21 and Ternary Bonsai 20.16 tok/s.

What the module shows, and what it cannot filter

The three current local conditions are checked to start. The hosted comparators and the other local candidates are listed unchecked, and a collapsed group, “Diagnostics and older runs”, holds custom Flash without multi-token decoding (matrix-02), the two conditions planned and never run (matrix-06 and matrix-07) and the historical command-line runs of the 27B (matrix-08 and matrix-14). Context length, primary versus retry and memory pressure are not filters, because the data has no field for them.

The tabs sort the twelve prompts that exist in this test — Python / SQL is three prompts and Knowledge writing is one — so no tab is a representative sample of that kind of work. Every aggregate I quote in this article is the All tasks figure unless I name a tab: on Structured work the three default conditions share five passing tasks, of which custom Flash was quicker than the baseline on four; on Python / SQL only sql; and on Knowledge writing none was scored for all three.

How I measured time

The aggregates are means of the per-task time ratios against the Youssofal Q8 baseline, matrix-16. Two means are printed because they answer different questions: the geometric mean, where a task at half the time and one at double cancel out, and the arithmetic mean, which does not. Paired speed is 100 divided by the geometric mean, so a geometric mean of 79.64% is 1.26× faster over the six tasks both models finished, and over no other set. Every ratio needs both conditions to have passed the task and both wall times to have been captured, which is why N changes from row to row.

Timing scope is not uniform across the data and cannot be made so. The current conditions ran as requests against a resident server, so their wall time excludes loading the model. The historical command-line runs and every screening package started a fresh process per answer, so their wall time includes it. Hosted rows include network and queue time and have no GPU decode figure at all. Those three kinds of number are never pooled into one ranking here, and where they appear in the same chart the chart says so.

How the writing is scored

Each answer is scored on five or six weighted dimensions out of 100, with the heaviest weight on what the task is for: factual faithfulness in the summary (35), accuracy in the knowledge article (30), causal caution in the data memo (30) and factual preservation in the email (35). Brief compliance is worth 5 everywhere, so a short answer is not rewarded for being short. Only the final prose is scored; an answer that ran out of tokens with no final text is not finished and unscored, never zero.

The reviewer is one assistant, not a panel and not a human blind test. The twenty answers from the two 27B packages and the three hosted conditions were reviewed with shuffled identity labels after prior exposure to the outputs; the four custom Flash answers were reviewed with the identity known. Custom Flash’s model-judge mean of 88.33/100 covers three tasks and the baseline’s 86.75/100 covers four; on the same three, the baseline scored 90.67/100 and Swift 91.67/100.

The factual corrections in full. Custom Flash’s data memo got the arithmetic right (numerical accuracy 5 of 5) and received 80/100 from the model judge: the reviewer marked one clause of its closing sentence, “The safer operational conclusion is that the checkout change did not improve conversion on either device and may have harmed it”, as a causal claim the nonrandomized before-and-after data cannot support — causal caution 3 of 5, 12 of the 20 points lost, with two other dimensions at 4. The baseline’s knowledge article scored 75/100 with two moderate errors, one of them “it happens every summer evening in virtually every city”; Swift’s article also scored 75/100, with “their roots release moisture that cools the air” flagged as the wrong mechanism, a moderate error.

The words I use

Q8, Q4, bpw
How many bits each weight is stored in: Q8 is 8 bits, Q4 is 4, and bpw is bits per weight for builds that mix the two. Fewer bits means a smaller file and less memory, with no guarantee either way about output quality.
27B, 35B-A3B
Parameter counts, unrelated to the bit depth. A name like 35B-A3B describes a sparse model: a large bank of parameters of which only a small share runs for any one token.
AR and MTP
AR is ordinary decoding, one token at a time. MTP is multi-token prediction: a small extra head proposes several tokens at once and the main model verifies them.
MLX and MTPLX
MLX is Apple's array framework for Apple Silicon. MTPLX is the runtime built on it that I use for the Qwen runs; it provides the multi-token decoding and the n-gram lookup table.
medium, sampled
Medium is the reasoning effort a run requested from the model. Sampled means the run drew each token at random from the distribution rather than always taking the most likely one.
REAP-288, saliency
REAP is the pruning method that drops routed experts from a sparse model; 288 is how many of the original 512 per layer this build keeps. It ranks experts by a stored saliency score — the method's own importance number, accumulated router-weighted output magnitude divided by selection count, not how often the router picked an expert.
original
In this series it means Qwen's own upstream release of the weights, at full precision, before anyone quantized or pruned them. Nobody in this comparison ran those on the Mac. The 27B baseline here is Youssofal's Optimized-Quality Q8 package, and the Q4g64 Flash build my custom one derives from is the published REAP-288 build.

What the evidence cannot carry

Attribution and licence

The checkpoint and the multi-token prediction head are Qwen’s. The set of 288 retained experts is sh0wie’s published REAP-288 selection, reused unchanged and pinned to a revision. Native multi-token decoding and the SSD-backed n-gram lookup were already MTPLX features, and the Q8 and Q4 27B packages are Youssofal’s and KrossKinetic’s work. What I contributed is the conversion and the loading change that let a 288-expert trunk load with a 512-expert head. That is integration and conversion work. I did not invent the pruning method or the runtime features, and I did not fine-tune the model: no training of any kind took place. The recipe itself: the routed experts are stored at 4 bits in groups of 32, and a selected set of projections the conversion marks as sensitive is kept at 8 bits in groups of 64 instead of being dropped to 4. Smaller groups and those selected 8-bit matrices hold more precision in those components than a uniform 4-bit conversion would; they do not make the model higher quality overall and they do not put back the experts that were removed. The published repository’s licence metadata is other, with the Qwen Community License 1.0 named in the model card and an upstream licence link; anyone redistributing it should check the upstream obligations rather than rely on this summary.

What changed in this edition

Runs, corrected grades and recommendation changes are logged by date. A retry is added as a new row; a failed attempt is never rewritten as a success.

17 September 2026. Custom Flash’s four writing tasks were run and reviewed; three of the four finished: summary 93/100 from the model judge, knowledge article no final answer at the 64,000-token ceiling after 2,009.93 s, data memo 80/100 with a causal-language correction, editorial rewrite 92/100. Memory pressure during that run is attached as a timing caveat on all four rows. I verified the public repository through the unauthenticated Hugging Face metadata API: revision 05858670, 121 files, public. Recommendation unchanged.

16 September 2026. A methodology audit of the harness set the language used here. The REAP-288 audit found the retained set is exactly the top 288 experts per layer by the published saliency score, not by how often the router used it.

14 September 2026. Historical command-line cohort at a 4,096-token total output allowance, one fresh process per answer: the Youssofal Optimized-Quality Q8 and Optimized-Speed Q4 packages are matrix-08 and matrix-14; the Cold Fusion Q8 and Q4 packages are in earlier-models.json, under Historical candidates. All stay a separate cohort.

Not run. Custom Flash on MLX-Serve (matrix-06 and 07); guarded retries of the two custom loops with a 64k reasoning and 8k answer split, prepared and paused; a Cold Fusion Q6 quality suite; a four-task writing suite for the Youssofal Optimized-Speed Q4 package. These conditions have no results.

Reproduce and challenge the result

Everything the module draws comes from the JSON files below, exported with local paths, request headers and credentials removed. The prompts, the expected answers for the JSON tasks and the full rubric are included, so a disagreement with a grade can be argued from the same inputs. The evaluator’s hidden cases for the three executed tasks are not: they are grader inputs the model never saw.

Condition IDs are stable: a new run gets a new ID, no existing row is overwritten even when a later retry does better, and a corrected score keeps the old one visible. Each condition records its artifact revision, runtime version, decoding mode, budgets, timing scope, date, memory-pressure state and trial count where known; an unknown value stays unknown. The cards change only after I have reviewed new evidence, and a change in grading policy is logged separately from a new model result. Any future tuning on these twelve tasks will need validation on a separate test set. Two checks would change this page more than any new model: repeated timing of the same conditions under normal memory pressure, and a held-out set of prompts with a fixed, documented repair loop. Both are proposals; neither has been run.

Public sources

  1. khuasar/Qwen3.8-Flash-Next-REAP-288-Q4g32-Q8-MTPLX, the custom build’s model page, revision 05858670, checked through the public metadata API on 17 September 2026.
  2. reap_kept_experts.json in sh0wie/Qwen3.8-Flash-Next-REAP-288-MLX-4bit, the pinned expert-selection manifest the custom build reuses, revision 668f31bc.
  3. Qwen 3.8 27B on OpenRouter, the hosted 27B endpoint (matrix-19, DeepInfra, provider-advertised BF16). Live provider figures there are not this benchmark.
  4. Qwen 3.8 Flash on OpenRouter, the hosted Flash endpoint (matrix-17 and 18, Alibaba); its weight precision was not independently verified.
About the author
Héctor Reinoso writes about how organizations should be designed when intelligence becomes abundant. He works on enterprise AI adoption inside a large industrial organization, after 25 years as a strategy consultant and transformation executive across four continents. Harvard MBA, industrial engineer, and still writes the code he writes about. More →