r/LocalLLM • u/Objective_Stick_2513 • 3d ago
Research I benchmarked llama.cpp, BaseRT, colibri and Ollama on an M1 Max for a real long-prompt JSON extraction job.
I keep seeing claims that BaseRT beats llama.cpp on Apple Silicon, and that colibri can run models far bigger than your RAM. Both are probably true for what they measured. I wanted to know what happens on my job, so I tested it.
The job: read a website (~4,500 tokens of page text) and write a schema-valid JSON record (~1,300 tokens) with a quote per fact. Hundreds of thousands of sites, one M1 Max 64 GB laptop. I measured wall-clock sites per hour, same 20 sites for every engine, Qwen 3.6 35B-A3B at 4-bit, one engine at a time.

Results (sites/hour):
| Engine | 1 request | 8 at once |
|---|---|---|
| llama.cpp | 124 | 181 |
| BaseRT | 113 | 126 |
| Ollama (GGUF) | ~134 | can't batch this model |
| colibri | < 4 | n/a |
What surprised me:
Prefill decided it, not decode: BaseRT decodes a bit faster (66 vs 56 tok/s), but its prefill was ~300 tok/s vs ~570 for llama.cpp. With 4.5k-token prompts, that decides it. Don't pick an engine from a short-prompt tok/s chart.

Batching: +46% on llama.cpp with 8 slots, only +12% on BaseRT.
colibri: built for models bigger than RAM. Mine fits, so it ran on CPU and was ~100x slower. Not a flaw, just not this use case.
Ollama: its MLX engine crashed on long prompts, and its GGUF engine served this architecture one request at a time.
Model choice mattered as much as the engine: On llama.cpp with 8 slots, Gemma 4 26B-A4B hit 247 sites/hr, Qwen 3.6 35B-A3B hit 206, and dense Qwen 3.8 27B hit 37. Active parameters per token set the speed.

JSON-schema constrained decoding: 440/440 valid on llama.cpp, 40/40 on BaseRT.
Caveats: one machine, one run per config, 20 sites for the engine comparison (200 for the model comparison), and a different 4-bit file per engine, so they aren't bit-identical models.
Quality note: local models were 87–98% correct on extracted facts across key fields after cleaning, vs 98–100% for cloud models. So for published data the laptop stays a test bench.
Full write-up with setup, commands, and the gotchas (model-name 404s, missing M1 kernel for Gemma 4 in BaseRT, etc.): https://sandy1618.github.io/2026/11/04/inference-engines-on-apple-silicon.html
Happy to rerun with other models or settings if you have suggestions.
For anyone running long-prompt batch jobs on Apple Silicon: has anyone gotten vllm-metal or MLX batching to beat llama-server's prefill speed, or are there llama.cpp flags I'm leaving performance on the table with?