← TinyGPT · docs · devlog · roadmap · speedup
source: docs/research/mac_decode_baseline_m5pro.md · view on GitHub ↗

Mac inference baseline — M5 Pro / 48GB

Date: 2026-05-31 Hardware: Apple M5 Pro, 48 GB, 18 cores (6 perf + 12 P), macOS 25F71 Harness: tinygpt bench --engine tinygpt (greedy decode, seed=42) Commit: d4a9de6 Question: Where is the actual bottleneck on M5 Pro? Is cider’s W8A8 worth the 4-7 day port?

TL;DR

The Mac is 10-20× faster than the realtime/interaction-model targets across every model size we have. cider’s prefill win is real but immaterial at current scales; defer until there’s a 3B specialist or a model-size-driven slowdown.

ModelParamsTTFT p99ITL p99Decode tok/s
mac-trained (gallery)9.6 M5.83 ms3.75 ms564
flagship-huge-v5221 M4.83 ms4.59 ms385–696*
mega-pilot~960 M5.75 ms4.94 ms293

*decode tok/s varies with how full the context is at start of decode

Realtime targets (from roadmap §realtime):

Raw results

Workload: prompt=64, gen=128, n=25, warm=3

metricmedianp95p99
TTFT (ms)2.434.515.83
ITL (ms)1.533.303.75
decode tok/s564.37761.35767.24
prefill tok/s26380.5738230.5039409.15
peak RSS (MB)206.9207.3207.3

Run 2 — flagship-huge-v5.tinygpt (221 M params)

Workload: prompt=64, gen=128, n=20, warm=3

metricmedianp95p99
TTFT (ms)3.254.794.83
ITL (ms)2.374.034.59
decode tok/s385.49401.68406.78
prefill tok/s19912.8723213.0323827.04
peak RSS (MB)270.8270.8270.8

Run 3 — flagship-huge-v5.tinygpt, prefill-heavy

Workload: prompt=128, gen=128, n=20, warm=3 (context fills to ctx=256 cap)

metricmedianp95p99
TTFT (ms)2.253.473.65
ITL (ms)1.302.312.75
decode tok/s696.99707.33717.32
prefill tok/s56814.7458527.3058687.24
peak RSS (MB)323.7323.7323.7

Run 4 — mega-pilot.tinygpt (~960 M params, 1.1 GB on disk)

Workload: prompt=64, gen=64, n=10, warm=2

metricmedianp95p99
TTFT (ms)4.765.755.75
ITL (ms)3.244.654.94
decode tok/s293.20298.33298.33
prefill tok/s14359.4415048.5215048.52
peak RSS (MB)687.0687.2687.2

Run 5 — google/gemma-3-12b (LM Studio, MLX, 12B params, 8.07 GB on disk)

Workload: prompt≈64 (default system+user template in bench_decode.py), gen=128 max (model stops at ~47 tokens — task is “three sentences”), n=20, warm=1. M5 Pro, macOS 26.5, gemma3 MLX runtime. RSS polled on the LM Studio inference worker (a node process; the lmlink-connector subprocess holds only the IPC bridge, ~38 MB — not the model).

metricmedianp95p99
TTFT (ms)184.0187.7187.9
ITL (ms)28.585.190.9
decode tok/s36.336.736.9
peak RSS (MB)909790979097

Reproduce:

lms load google/gemma-3-12b --identifier google/gemma-3-12b
WORKER=$(ps -axo pid,rss,comm | awk '/lmstudio.*node/ && $2>1000000 {print $1; exit}')
python3 scripts/bench_decode.py \
  --url http://127.0.0.1:1234/v1/chat/completions \
  --model google/gemma-3-12b --rss-pid "$WORKER" \
  --jsonl docs/research/data/gemma-12b-decode.jsonl \
  > docs/research/data/decode-gemma-12b.json

Takeaways (verified against this row, not the from-scratch ones above):

Implications for the cider decision

What cider would buy us

Per docs/research/wave_2_5_kernel_audit.md §2, cider on M5 Pro:

Why it doesn’t help us right now

  1. Model size mismatch. cider’s wins scale with matmul cost. At 221M / 960M params on M5 Pro, the model loads in <700 MB and prefill is 14k-56k tok/s — already saturating GPU compute throughput. Int8 saves nothing material until matmul dominates.

  2. Realtime targets met by 10×. The Mac is already faster than anything the interaction-model demo needs. cider’s 1.8× prefill on an already-fast prefill is “we noticed”, not “now we can ship the demo.”

  3. Decode is what limits agent latency — the agent loop generates tokens one at a time and cider’s W8A8 is slower than W8A16 on decode. We’d actively regress agent UX.

  4. The decode tok/s gap with model size suggests memory bandwidth is the limit at 1B+, not int8 vs fp16 arithmetic. cider doesn’t touch the bandwidth picture.

  5. Effort cost is high. cider is Python+C++ targeting MLX’s C++ primitive interface; tinygpt is MLX-Swift. Port is 4-7 days, not the 1-2 days a Python project would face. See research/wave_2_5_kernel_audit.md for the integration analysis.

When to revisit

Revisit cider adoption when ANY of:

Other Mac-speed levers ranked

Given the baseline, here’s what’s actually worth doing next for “Mac speed”:

LeverEffortExpected impactWhen
Verify Medusa/EAGLE-2 spec decode is engaged0.5 dayup to 2× decode if not activeNow (cheap check)
Cold-start TTFT for 1B+ models1-2 dayslikely already <50ms but unmeasured coldAfter cider decision
Async tool-call dispatch (start exec while args still streaming)3 daysagent loop UX, not raw inferenceWave 2.6
Decode jitter under thermal load1 dayp99 may spike on sustained workloadsOptional
cider W8A8 adoption4-7 daysMarginal at current scalesWhen 3B+ specialist exists
ANE prefill + GPU decode hybrid3-6 weeksOnly when screen-watching specialist shipsWave 2.6

Bench harness limitations to flag

Conclusion

Do NOT spend 4-7 days on cider right now. The Mac is already faster than the product demands. The lever has marginal payoff at current scales and active regression risk on decode.

What to do instead:

  1. Document this baseline (this doc)
  2. Move to the next product-shaped Wave 2.6 work (Continue.dev provider adapter is the highest-leverage per wave_4_landscape.md)
  3. Revisit cider after training the first 3B specialist