Local LLM benchmark results

Setup and models

M1 Max: 21 GPU cores, 8 performance CPU cores, 2 efficiency CPU cores. The chip has a theoretical memory bandwidth of 400 GB/s.

LM Studio is used for everything. OMLX on occasion just to see if did better on the MTP variant of Qwen.

Which models do I test?

  • Qwen 3.6 is the gold standard for coding, which produces good results but is also slow because it’s a dense model.
  • Gemma 4 26B A4B QAT is interesting because it’s one of the first out there using Quantization-Aware Training.
  • Ornith is allegedly a “benchmaxed” refinement of Qwen, which has some positive reviews on Reddit.

Bounded read-only benchmark

Each model is run with this same prompt:

pi   --provider lmstudio  --model $MODELNAME  \
--thinking low  --tools read,grep,find,ls  \
--name "benchmark-$MODELNAME-bounded"  \
 "Inspect this repository for one real bug or fragile area. \
Make at most 8 tool calls total. Never call the same tool \
with the same arguments twice. Never read the same file twice. \
After finding one credible issue, stop using tools immediately \
and give the final answer. If no issue is confirmed after 8 \
tool calls, stop and report the strongest candidate. Your final \
answer must be under 500 words and contain exactly these\
 headings: Location, Evidence, Failure scenario, Root cause, \
Minimal patch. Do not edit files. Do not discuss your search \
process. Do not output internal reasoning."

And here are the results:

ModelRuntimeTTFTTPSOutputDecode timeOutcome
Ornith 35BLM Studio4.46s43.93,27374.6sCompleted, verbose
Qwen 3.6 27B non-MTPLM Studio37.85s11.01,01292.3sCompleted, most restrained
Gemma 4 26B A4B QAT, tunedLM Studio4.56s41.79,919237.9sCompleted, very verbose
Qwen 3.6 27B oQ8 MTPoMLX25.13s11.12,811252.1sCompleted
Qwen 3.6 27B MTP Q8_0LM Studio15.64s11.93,554297.6sCompleted, inefficient
Qwen 3.6 27B MLX 8-bitoMLX23.81s10.24,245416.1sCompleted, poor overall
Gemma, original settingsLM Studio15.09s35.316,070453.6sFailed to terminate
Ornith, original promptLM Studio18.51s40.119,566487.5sHit output limit

Current conclusion: Surprisingly, Ornith 1.0 35B through LM Studio is the best fit so far. Gemma is correct but inefficient. Ordinary Qwen is restrained in token use, but the objective benchmark exposed a concurrency bug, so it does not technicall qualify as a correct solution.

Objective coding benchmark

The objective benchmark is a deliberately broken Python repository designed to test whether a coding agent can produce a functionally correct patch.

The repository contains a function called get_or_load(key, loader). The method should return a cached value when one exists. On a cache miss, the method calls loader(), caches the result, and returns it. It is deliberately broken under concurrency.

Each model gets the same prompt:

You must preserve the existing API while meeting these requirements:

Concurrent requests for the same missing key invoke the loader exactly once.
All callers waiting for that load receive the same value.
If the loader raises, every waiting caller receives that exception.
A loader failure is not cached, so a later request can retry.
None is a valid value and must be cached.
Different keys can load concurrently.
No external dependencies are added.
The patch should be reasonably small.
Existing tests must be run.
Existing tests must not be weakened just to obtain a pass.

Aside from the included test suite, there is an extra test suite that the model does not have access to. This checks for quality of implementation. For example, it checks if two loaders can execute at the same time for different keys, and whether the key was loaded multiple times even though there was no expiry. It also checks if TTL expiry causes correct behaviour.

Here are the results

ModelResultTTFTTPSOutputDecode timeInput
Ornith 1.0 35B 8-bit5/5 PASS21.02s47.37,921167.3s78k
Gemma 4 26B A4B QAT 4-bit5/5 PASS16.79s31.530,883981.1s363k
Qwen 3.6 27B 8-bit4/5 FAIL46.02s7.23,872540.0s59k

Findings

  • Ornith 5/5 hidden checks. Fastest correct result and current winner.
  • Gemma: 5/5 hidden checks, but generated 30,883 tokens and repeatedly reconsidered a correct approach.
  • Qwen: 4/5 hidden checks. The patch coalesced successful same-key loads but failed to distribute one loader exception to all concurrent waiters. The failing loader ran six times instead of once.

Conclusions

Tokens/second is important. But also is the time to first token (TTFT). Keeping both of these down is essential for iterative agentic coding.

Qwen remains the best philosopher and still excels with output brevity. It did not fully pass the test and i suspect more bespoke tests will be needed to get a better feel about how it interprets vague prompts. More interestingly, MTP only made a difference of 1 tok/sec on this machine. I have seen MTP make a bigger difference in the past but was not able to reproduce that here.

While Gemma QAT looked good at face value, it really struggled to stay focused and kept introducing doubt. Temperature reduction did not improve this. It still may be reasonable as a general purpose agent but I will not be using it for any coding. There is a bigger version (31b qat) but I could not get it to run properly with pi or opencode.

Written on July 26, 2026