GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com โ€” GitHub - CryptoJones/MacminiM2Pro_ModelShowdown: Testing Matrix of local models on a Macmini M2 Pro w/ 16 GB UM

BranchesTags
Open more actions menu

Latest commit

 

History

83 Commits
83 Commits

Folders and files

NameName
Last commit message
Last commit date
harness
harness
 
 
results
results
 
 
AGENTS.md
AGENTS.md
 
 
BACKLOG.md
BACKLOG.md
 
 
METHODOLOGY.md
METHODOLOGY.md
 
 
README.md
README.md
 
 
update_readme.py
update_readme.py
 
 

Repository files navigation

Proudly Made in Nebraska. Go Big Red! ๐ŸŒฝ https://xkcd.com/2347/

MacminiM2Pro_ModelShowdown

Local coding-LLM showdown on a Mac mini (Apple M2 Pro, 16 GB unified memory) โ€” every number measured first-hand on this machine, not copied from leaderboards.

Two questions:

  1. Which open-weight coding model is best for software engineering that fits comfortably (โ‰ค ~10 GB peak) on 16 GB?
  2. Which local runtime hosts it best โ€” llama.cpp (Metal, GGUF) vs MLX (4-bit)?

How: quality = EvalPlus HumanEval+ (164 problems, executed, greedy, pass@1); speed = llama-bench (llama.cpp) / mlx_lm (MLX); 4-bit except for the native ternary Q2_0 Bonsai build. See METHODOLOGY.md.

โœ… STATUS: both llama.cpp and MLX measurements are now present in the matrix (โ€” = not measured).

Results โ€” HumanEval+ pass@1 (quality) + generation t/s

โœ… GGUF PASS COMPLETE. MLX results remain unmeasured for models marked โ€”. โ€” = not measured.

Rank Model Vendor / gen Params quant ยท size (lcpp) HE+ (llama.cpp) HE+ (MLX) gen t/s (lcpp) gen t/s (MLX) empty (lcpp) empty (MLX)
๐Ÿฅ‡ Qwen3.5-9B โบ Alibaba 2026 (reasoning/MTP) 9B Q4_K_M ยท 5.74 GiB 90.2 โ€” 25 37 โ€” โ€”
๐Ÿฅˆ ornith-9B โบ DeepReinforce 2026 (Qwen3.5-based) 9B Q4_K_M ยท 5.23 GiB 88.4 84.8 25 37 โ€” โ€”
๐Ÿฅ‰ Qwen2.5-Coder-14B Alibaba 2024 (dedicated coder) 14B Q4_K_M ยท 8.37 GiB 87.2 85.4 17 22 โ€” โ€”
4 gpt-oss-20b โบ OpenAI 20B (MoE) MXFP4 MoE ยท 11.27 GiB 87.2 79.9 52 57 โ€” โ€”
5 Qwen2.5-Coder-7B Alibaba 2024 (dedicated coder) 7B Q4_K_M ยท 4.36 GiB 84.1 83.5 34 43 โ€” โ€”
6 NVIDIA-Nemotron-9B โบ NVIDIA 2026 (reasoning) 9B Q4_K_M ยท 6.07 GiB 82.3 87.8 17 32 โ€” โ€”
7 Phi-4 Microsoft 14B Q4_K_M ยท 8.28 GiB 82.3 80.5 17 22 โ€” โ€”
8 Gemma-4-12B-Coder community finetune of Gemma-4-12B (fable5/composer2.5) 12B Q4_K_M ยท 6.86 GiB 82.3 โ€” 20 โ€” โ€” โ€”
9 Qwen3.8-27B (UD-IQ2_M) โบ Alibaba 2026 (dense, multimodal, reasoning) - 2-bit budget-edge 27B UD-IQ2_M ยท 9.60 GiB 81.1 โ€” 8 โ€” 29 โ€”
10 Qwythos-9B-v2 โบ Empero AI 2026 (Qwen3.5-based reasoning finetune) 9B Q4_K_M ยท 5.33 GiB 78.7 โ€” 25 37 8 26
11 DeepSeek-V2-Lite DeepSeek 2024 (MoE, 2.4B active) 16B Q4_K_M ยท 9.65 GiB 76.8 75.6 69 91 โ€” โ€”
12 Ternary-Bonsai-27B โบ Prism ML 2026 (Qwen3.6-based ternary) 27B Q2_0 ยท 6.66 GiB 72.0 65.9 10 18 33 0
13 Gemma-4-12B Google 2026 12B Q4_K_M ยท 7.12 GiB 68.3 โ€” 18 โ€” โ€” โ€”
14 IBM-Granite-8B IBM / Red Hat 8B Q4_K_M ยท 4.60 GiB 65.2 62.2 30 37 โ€” โ€”
15 CodeGemma-7B Google 2024 7B Q4_K_M ยท 4.96 GiB 50.0 50.0 29 31 โ€” โ€”

โบ = reasoning model โ€” its score is a FLOOR, not a measurement.

These models emit a <think> block before answering. llama.cpp with --jinja splits that into reasoning_content, so a model that does not finish thinking within the token cap returns empty content โ€” and EvalPlus scores an empty response identically to a wrong answer. Confirmed directly against a live server:

HumanEval/10 -> finish_reason=length, content=0 chars, reasoning_content=14451 chars, completion_tokens=4096

The model wrote ~14,500 characters of reasoning and never emitted one character of answer. This is not quantisation damage: it reproduces on a vanilla Q5_K_XL build on different hardware. Read the empty columns as the size of this effect โ€” Qwen3.8-27B lost 29 of 164 tasks (17.7%) to it, capping its achievable score at 82.3% before any code was judged.

The cap was already raised once (768 -> 4096) after it scored Qwen3.5-9B a false 42.7. 4096 is still not enough for the newest reasoning models. See #7.

Reading so far

  • Quality leader: Qwen3.5-9B (90.2 % HE+) โ€” a newest-gen reasoning 9B beating the dedicated Qwen2.5-Coder-14B at 2/3 the size. ornith-9B (also Qwen3.5-based) is right behind at 88.4 %.
  • Speed leader: DeepSeek-V2-Lite MoE โ€” ~69/87 t/s, 3โ€“4ร— the dense models (only ~2.4B params active), but lower quality (76.8 %).
  • Runtime pattern (so far): MLX wins generation throughput on every model measured; llama.cpp wins prefill.
  • Ternary Bonsai 27B: its native ternary Q2_0 GGUF scored 72.0 % HE+ at 9.83 t/s (83.97 t/s prompt processing), while MLX scored 65.9 % HE+ at 17.8 t/s. It fits a full 27B-class model into a 6.66 GiB GGUF, trading speed and benchmark quality for an unusually small footprint.
  • Gotcha worth noting: reasoning models were initially scored falsely low (Qwen3.5-9B showed 42.7 %) because EvalPlus's default 768-token cap truncated their <think> before the code. Raising it to 4096 fixed it โ€” see METHODOLOGY.

The Ternary-Bonsai-27B MLX cell is now filled from this run (65.9 % HE+, 17.8 t/s).

About

Testing Matrix of local models on a Macmini M2 Pro w/ 16 GB UM

Resources

Readme
Activity

Stars

1 star

Watchers

1 watching

Forks

0 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402520 โ€” GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800ร—600. No cookies required.