Skip to content
AB
EuclidPRO.ai

Evaluation · completed 2026-10-28

Hardware evaluation: small open models on one CPU server

18 open models, 444 timed requests at 1 to 5 parallel slots on a 12-vCPU server with no GPU: throughput, latency, decode speed and memory.

Problem

Clients that keep data on their own servers often have no GPU. An AI agent is only useful if it answers fast enough on the hardware they already own.

Hypothesis

A small open model (under 5B parameters) can triage an email in seconds on CPU, and parallel slots raise throughput.

Success metric

Emails per minute and time to first token at 1 to 5 parallel requests, with peak memory, on identical settings.

Result

qwen3:0.6b leads: 13.9 emails/min alone, 31.9/min at 5 in parallel. 4 models cannot serve in parallel at all.

Decision

Fine-tune the smallest fast model for the task instead of serving a larger general one; test accuracy next on the full benchmark.

Setup

One server, identical settings for every model

12 vCPU

AMD EPYC 9645

AVX-512, no GPU

31 GB

RAM

Ollama 0.40.12

llama.cpp runner, every model in Q4_K_M

444

timed requests

3 runs

Method

  • For each model and N = 1 to 5, Ollama is restarted with N parallel slots and the runner must report exactly N.
  • 2N copies of the same email arrive at once and N channels take the next waiting job as they finish.
  • Every prompt starts with a unique tag, so no request reuses another's cached prompt.
  • Temperature 0, seed 42, context 8,192, 12 threads, 180s timeout; the same JSON schema is enforced for all.
  • 76 measurements per request: queue wait, time to first token, decode speed, latency, memory and CPU of the runner and of the rest of the machine.
  • The test email is 425 characters (about 589 prompt tokens with the system prompt).

Single request

Emails per minute, one request at a time

The baseline a single user sees: one email in, one answer out. Hover or focus a bar for latency, time to first token and memory.

  • qwen3:0.6b13.9
  • OLMoE-1B-7B-0125-Instruct10.6
  • qwen3.5:2b8.7
  • qwen3:1.7b8.6
  • granite4:tiny-h7.8
  • ministral-3:3b7.5
  • granite4.1:3b6.0
  • SmolLM3-3B6.0
  • gemma3n:e2b5.4
  • gemma3:4b5.2
  • qwen3:4b4.7
  • granite4:micro4.3
  • qwen3.5:4b4.2
  • phi4-mini:3.8b4.1
  • llama3.2:3b1.6
  • LFM2.5-8B-A1B1.4
  • gemma4:e2b1.4
  • LFM2.5-2.6B1.3

Highlighted: qwen3:0.6b, the base model later fine-tuned for triage.

Parallel requests

Throughput as parallel slots increase

Emails per minute with 1 to 5 requests served at once. Darker cells are faster; a dash means the runner could not provide that many slots.

Throughput in emails per minute by number of parallel slots
Model×1×2×3×4×5Peak RAM at max
qwen3:0.6b13.919.023.825.931.95.5 GiB
OLMoE-1B-7B-0125-Instruct10.610.713.814.414.36.6 GiB
qwen3.5:2b8.7––––2.3 GiB
qwen3:1.7b8.614.113.915.018.96.4 GiB
granite4:tiny-h7.89.010.110.611.35.8 GiB
ministral-3:3b7.56.610.011.511.77.6 GiB
granite4.1:3b6.07.59.310.312.45.7 GiB
SmolLM3-3B6.07.08.82.7*10.45.2 GiB
gemma3n:e2b5.46.68.89.29.77.7 GiB
gemma3:4b5.25.77.89.28.16.2 GiB
qwen3:4b4.77.66.69.59.89.0 GiB
granite4:micro4.36.98.511.511.35.0 GiB
qwen3.5:4b4.2––––4.0 GiB
phi4-mini:3.8b4.19.010.111.411.47.0 GiB
llama3.2:3b1.610.811.013.213.47.0 GiB
LFM2.5-8B-A1B1.4––––5.2 GiB
gemma4:e2b1.42.43.54.55.35.8 GiB
LFM2.5-2.6B1.3––––1.9 GiB

* One request in that mode hit the 180 s timeout, which holds the whole mode open and explains the drop.

Findings

What the numbers say

Small and dense wins on CPU

qwen3:0.6b answers in 4.3 s alone (first token in 0.55 s) and reaches 31.9 emails/min with 5 parallel slots in 5.5 GiB of RAM.

Parallel slots trade latency for throughput

Models that support 5 slots gain 1.4× to 8.1× throughput, while each request takes longer. Sizing is a product decision: queue length versus answer time.

Not every model can be served in parallel

qwen3.5:4b, qwen3.5:2b, LFM2.5-2.6B, LFM2.5-8B-A1B ran with a single slot only in this Ollama version, which rules them out for shared use on one server.

Parameter count is not speed

gemma4:e2b decodes at only 6.2 tokens/s, while mixture-of-experts models with about 1B active parameters decode as fast as the 0.6B dense model but need several times its memory.

Full results

Every model, single request

Hardware evaluation: per-model details at one request
ModelFamilyParams (active)QuantSizeLatency p50First tokenDecodeRAMMax slots
qwen3:0.6bQwen3 · dense0.6BQ4_K_M0.5 GB4.3 s0.55 s67.1 tok/s1.6 GiB5
OLMoE-1B-7B-0125-InstructOLMoE · moe6.9B (1.3B)Q4_K_M4.2 GB5.7 s1.60 s62.6 tok/s4.7 GiB5
qwen3.5:2bQwen3.5 · dense1.9BQ4_K_M1.9 GB6.9 s1.34 s42.5 tok/s2.3 GiB1
qwen3:1.7bQwen3 · dense2.0BQ4_K_M1.4 GB7.0 s1.26 s40.8 tok/s2.5 GiB5
granite4:tiny-hGranite 4 · moe6.9B (1B)Q4_K_M4.2 GB7.7 s2.11 s44.0 tok/s4.5 GiB5
ministral-3:3bMinistral 3 · dense3.8BQ4_K_M3.0 GB8.0 s2.21 s40.2 tok/s3.9 GiB5
granite4.1:3bGranite 4.1 · dense3.4BQ4_K_M2.1 GB9.9 s2.39 s24.9 tok/s2.8 GiB5
SmolLM3-3BSmolLM3 · dense3.1BQ4_K_M1.9 GB10.0 s2.07 s30.0 tok/s2.6 GiB5
gemma3n:e2bGemma 3n · dense4.5B (2B eff)Q4_K_M7.8 GB11.2 s2.13 s27.5 tok/s6.7 GiB5
gemma3:4bGemma 3 · dense3.9BQ4_K_M3.4 GB11.6 s2.45 s27.8 tok/s4.1 GiB5
qwen3:4bQwen3 · dense4.0BQ4_K_M2.5 GB12.7 s2.77 s22.8 tok/s3.8 GiB5
granite4:microGranite 4 · dense3.4BQ4_K_M2.1 GB13.8 s2.20 s19.1 tok/s2.8 GiB5
qwen3.5:4bQwen3.5 · dense4.2BQ4_K_M3.3 GB14.3 s3.19 s21.9 tok/s4.0 GiB1
phi4-mini:3.8bPhi-4 · dense3.8BQ4_K_M2.5 GB14.8 s2.15 s15.5 tok/s3.7 GiB5
llama3.2:3bLlama 3.2 · dense3.2BQ4_K_M2.0 GB36.4 s1.96 s16.1 tok/s3.1 GiB5
LFM2.5-8B-A1BLFM2.5 · moe8.3B (1.5B)Q4_K_M5.2 GB43.0 s38.99 s53.9 tok/s5.2 GiB1
gemma4:e2bGemma 4 · dense4.6B (2.3B eff)Q4_K_M4.6 GB44.3 s1.49 s6.2 tok/s5.2 GiB5
LFM2.5-2.6BLFM2.5 · dense2.6BQ4_K_M1.7 GB46.3 s39.41 s34.5 tok/s1.9 GiB1

Limits

What this evaluation does not show

  • It measures speed and memory, not accuracy: every request used the same email. Accuracy is measured separately on 100 held-out emails.
  • One virtual server, so neighbours on the host can add noise; CPU used by other processes was recorded for every request (median 0.7%; above 1% for 14 of 444).
  • Results are for one Ollama version (0.40.12) and its default runner settings; another runtime (vLLM, llama.cpp server flags) can change the parallel numbers.