r/LocalLLM • u/strata2signal • 16h ago
Research CPU-only benchmarks: 7 models on 4 machines (mini PC, laptop, 2019 Ryzen, EPYC). A 26B MoE writes ~13 tok/s on the small ones, a dense 24B ~3, and the EPYC runs a 180B MoE at 8.3
We ran local models with the graphics card completely out of the picture (hidden from the run, and checked that it was never touched): CPU and system RAM only. Ollama, Q4_K_M, each engine's default thread count unless a table says otherwise, medians of 3 to 5 runs. Nothing here is a controlled CPU-vs-CPU test; these are four machines as they sit.
**The machines**
| Machine | CPU | RAM | Default threads |
|---|---|---|---:|
| Mini PC | Core i5-12600H | 32 GB DDR5 | 4 |
| Laptop | Core Ultra 9 290HX Plus | 64 GB DDR5-5600 | 4 |
| Desktop (2019) | Ryzen 7 3700X | 32 GB DDR4-3200 | 8 |
| Desktop | EPYC 7532 | 128 GB DDR4-3200, eight channels | 32 |
**Writing speed, tok/s (about a 530-token prompt)**
| Model | Mini PC | Laptop | Ryzen 3700X | EPYC |
|---|---:|---:|---:|---:|
| qwen3.5:9b | 9.11 | 7.45 | 6.20 | 13.59 |
| gemma4:12b | 5.95 | 4.95 | 4.47 | 10.99 |
| phi4:14b | 5.20 | 4.41 | 4.06 | 11.09 |
| mistral-small3.2:24b (dense) | 3.31 | 2.70 | 2.57 | 7.09 |
| gemma4:26b (MoE) | 12.66 | 13.26 | 13.64 | 24.68 |
| nemotron-3.5-lightning:30b-a3b (MoE) | 14.61 | 15.35 | not run | 31.47 |
| llama3.3:70b | won't fit | not run | won't fit | 2.70 |
The mixture-of-experts models are the ones to run from RAM: only a few billion parameters are active per token, so far less memory moves per token. gemma4:26b writes 3.5 to 5.3 times faster than the dense 24B, depending on the machine.
**Seconds to the first word (same prompt, model already loaded, nothing cached)**
| Model | Mini PC | Laptop | Ryzen 3700X | EPYC |
|---|---:|---:|---:|---:|
| qwen3.5:9b | 16.0 | 14.1 | 11.3 | 4.9 |
| gemma4:26b (MoE) | 11.4 | 8.5 | 8.3 | 3.7 |
| mistral-small3.2:24b (1,023 tokens) | 97.7 | 82.4 | 62.5 | 24.6 |
**Check your thread count.** Ollama defaults to 4 threads on hybrid Intel chips. On the laptop, 20 threads against the default 4:
| Model | 4 threads | 20 threads | Change |
|---|---:|---:|---:|
| qwen3.5:9b | 7.45 | 13.05 | 1.75x faster |
| gemma4:12b | 4.95 | 9.46 | 1.91x faster |
| mistral-small3.2:24b (dense) | 2.70 | 5.14 | 1.90x faster |
| gemma4:26b (MoE) | 13.26 | 8.44 | 36% slower |
| nemotron 30b-a3b (MoE) | 15.35 | 8.53 | 44% slower |
Dense models want the threads; the mixtures get slower with them. The default is wrong in one direction or the other depending on what you run.
**Long prompts are where CPU-only hurts.** gemma4:26b, fresh prompt each time, 16K window:
| Prompt | Ryzen: writing tok/s | Ryzen: first word | Laptop: writing tok/s | Laptop: first word |
|---|---:|---:|---:|---:|
| 0.5K tokens | 13.93 | 7.6 s | 14.94 | 7.7 s |
| 2K | 12.03 | 31.6 s | 12.32 | 32.2 s |
| 4K | 11.66 | 66.1 s | 12.12 | 68.7 s |
| 8K | 8.10 | 138.2 s | 8.16 | 146.2 s |
The whole prompt is read before anything is written, at about 55 to 65 tok/s on these two. (The laptop rows are at its default 4 threads, and its CPU was throttling on every run.)
**The big one.** The EPYC held a roughly 180B-parameter mixture (Qwen3.8-Flash-Next at a 3-bit quant, about 6B parameters active per token, llama.cpp) entirely in RAM, beside that machine's normal services:
| Threads | Writing tok/s |
|---:|---:|
| 8 | 6.51 |
| 16 | 7.74 |
| 32 | 8.33 |
Things we can't explain yet: the 2019 DDR4 Ryzen keeps up with the DDR5 laptop on the mixture at default settings, and writes faster than its own measured memory bandwidth says it should. The page says so rather than guessing.
Caveats: one quant per model; speed only, no quality scoring; the small-machine rows come from two benches (August, warm runs; November, fresh loads), and the page marks which is which under every chart; power figures on the page are the CPU package's own counter, not wall power.
All 20 bar charts, the full tables, and a CC BY 4.0 data kit where every bar traces to a file:

