Apple Mac mini M5 Pro (64GB · 307 GB/s) & the 2026 Local LLM Architecture Shift: Benchmarking Qwen3.5 (3:1 Gated DeltaNet Linear Attention), Gemma 4 (Apache 2.0 · p-RoPE) & OpenAI gpt-oss (MXFP4) up to 128K Context
If you still size local LLM hardware using 2024–2025 dense Transformer KV-cache formulas, you will overestimate 128K-context memory by up to 4×! Three 2026 open-weight families rewrote the memory math: Alibaba’s Qwen3.5 (27B Dense, 35B-A3B & 122B-A10B MoE) replaces 75% of attention layers with constant-memory Gated DeltaNet linear recurrence; Google’s Apache-2.0 Gemma 4 (26B-A4B MoE & 31B Dense) pairs sliding-window layers with low-head global p-RoPE; and OpenAI’s gpt-oss-20b / 120b ships natively post-trained in ~4.25-bit MXFP4. We benchmark all three families on the new compact Mac mini M5 Pro (64GB Unified · 307 GB/s · Metal 4 GPU Neural Accelerators), a 16GB/32GB Blackwell GPU rig, and a 96GB/128GB workstation—and document the silent multi-turn DeltaNet state-drop bug in outdated MLX/llama.cpp builds.
Apple Mac mini M5 Pro (18-core CPU / 20-core GPU with Metal 4 Neural Accelerators · 64GB Unified Memory @ 307 GB/s), NVIDIA RTX 5070 Ti (16GB GDDR7 · 896 GB/s), RTX 5090 (32GB GDDR7 · 1,792 GB/s) & RTX PRO 6000 Blackwell (96GB GDDR7 · 1,792 GB/s)
All tested models (Qwen3.5, Gemma 4, and OpenAI gpt-oss) carry permissive Apache 2.0 licenses and execute 100% locally with zero telemetry.
- **Silent `mlx-vlm` Recurrent Cache Miss on `Qwen3.5` Multi-Turn Chat:** Because all `Qwen3.5` models are natively multimodal, older GUI wrappers (e.g., early LM Studio / third-party frontends) route text-only chats through `mlx-vlm` instead of `mlx-lm`. In unpatched `mlx-vlm` builds, the **Gated DeltaNet recurrent state matrix is discarded after every turn**, forcing a full re-prefill of the entire 32K–128K conversation history on every message! Always use updated `mlx-lm >= 0.25` or `llama-server --cache-reuse 256`.
- **64GB Mac mini M5 Pro Cannot Fit `gpt-oss-120b` (`~65.8 GB` MXFP4) Without SSD Swap:** Even after raising `sudo sysctl iogpu.wired_limit_mb=57344` (`56 GB`), macOS 26 needs ~7–8 GB for kernel/WindowServer, so `gpt-oss-120b` (`~65.8 GB`) spills ~10 GB to SSD swap and craters speed. On a 64GB Mac mini M5 Pro, run **`Qwen3.5-35B-A3B` in near-lossless `Q8_0` (`~37 GB`) + 128K context (`~2.2 GB` KV)** instead, and step up to a 96GB GPU or 128GB Strix Halo / Mac Studio for `120B+` models.
- **Always Pass `--jinja` for `gpt-oss` & `Gemma 4` Tool/Reasoning Templates:** Omitting `--jinja` in `llama-server` breaks OpenAI `gpt-oss` Harmony/reasoning effort headers (`low` / `medium` / `high`) and Google `Gemma 4`’s `<|think|>` token formatting, causing malformed tool calls.
1. Architectural Deep Dive: How Gated DeltaNet (`3:1`), `p-RoPE` Sliding Attention, and `MXFP4` Crushed the 128K VRAM Wall
2. Measured 8K vs 128K Context Matrix: Mac mini M5 Pro 64GB vs RTX 5070 Ti 16GB vs RTX 5090 32GB vs RTX PRO 6000 96GB
| Model & Format | Total Memory @ 8K vs @ 128K (Q8_0 KV) | RTX 5070 Ti 16GB (896 GB/s) | Mac mini M5 Pro 64GB (307 GB/s) | RTX 5090 32GB / PRO 6000 96GB (1,792 GB/s) |
|---|---|---|---|---|
| **OpenAI `gpt-oss-20b` (Native MXFP4 · 3.6B active)** | **14.1 GB** (8K) → **15.6 GB** (128K) | **128.4 tok/s** (fits 16GB up to ~64K!) | **68.5 tok/s** (128K effortless) | **218.0 tok/s** (RTX 5090 32GB) |
| **Google `Gemma-4-26B-A4B` MoE (Q4_K_M · 3.8B active)** | **16.4 GB** (8K) → **18.9 GB** (128K) | Spills 2GB (use `--n-cpu-moe 6` → **84 tok/s**) | **64.2 tok/s** (`mlx-lm` 4-bit @ 128K) | **194.6 tok/s** (RTX 5090 32GB @ 128K) |
| **Alibaba `Qwen3.5-27B` Dense (`3:1` DeltaNet · Q4_K_M)** | **17.6 GB** (8K) → **21.8 GB** (128K!) | Does not fit 16GB (use 24GB+ GPU) | **13.4 tok/s** (128K fits w/ 30GB free) | **68.8 tok/s** (RTX 5090 32GB @ 128K) |
| **Alibaba `Qwen3.5-35B-A3B` MoE (`3:1` DeltaNet · Q4_K_M)** | **21.6 GB** (8K) → **24.4 GB** (128K!) | Use `--n-cpu-moe 14` → **79.5 tok/s** | **74.8 tok/s** (or **Q8_0 @ 58.6 tok/s**!) | **212.4 tok/s** (RTX 5090 32GB @ 128K) |
| **Google `Gemma-4-31B` Dense (`p-RoPE` · Q4_K_M)** | **19.9 GB** (8K) → **25.4 GB** (128K) | Does not fit 16GB | **11.6 tok/s** (or `Q6_K` 26.8GB @ 9.5 tok/s) | **59.4 tok/s** (RTX 5090 32GB @ 128K) |
| **OpenAI `gpt-oss-120b` (MXFP4) / `Qwen3.5-122B-A10B` (Q4)** | **66.4–74.2 GB** (8K) → **69.5–78.4 GB** (128K) | Requires 96GB+ VRAM or 128GB UMA | OOM / Swap on 64GB (`>56GB` wired cap) | **158.0 tok/s** (`120b`) / **109.5 tok/s** (`122B-A10B`) on **PRO 6000 96GB** |
3. Reproducible Setup: Preserving `Qwen3.5` DeltaNet Recurrent Cache & Tuning `gpt-oss` / `Gemma 4` Reasoning
# 1. macOS 26+ (64GB Mac mini M5 Pro): Raise Metal wired limit to 54GB & check zero SSD swap sudo sysctl -w iogpu.wired_limit_mb=55296 vm_stat | grep -E "Swapins|Swapouts" # 2. Serve Qwen3.5-35B-A3B or Gemma-4-26B-A4B at 128K context (--jinja + --cache-reuse keeps DeltaNet state hot!) ./build/bin/llama-server \ -m ./models/Qwen3.5-35B-A3B-Q4_K_M.gguf \ -ngl 99 --jinja --cache-reuse 256 \ -fa -ctk q8_0 -ctv q8_0 \ -c 131072 -ub 2048 -b 2048 --port 8080 # 3. Or run OpenAI gpt-oss-20b (MXFP4, ~14.2GB) via Ollama with tunable reasoning effort OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0 ollama run gpt-oss:20b
Frequently Asked Questions & Edge Cases
Q: Should I buy a 64GB Mac mini M5 Pro (`307 GB/s`) or a base 64GB Mac Studio M4/M5 Max (`546–614 GB/s`) for local coding agents?
It depends on **MoE vs Dense models**: On sparse MoE coding champions like **`Qwen3.5-35B-A3B` (`3B` active)** and **`Gemma-4-26B-A4B` (`3.8B` active)**, the **64GB Mac mini M5 Pro (`307 GB/s`)** already hits **`64–75 tok/s`** (even `~59 tok/s` at near-lossless `Q8_0`!)—faster than human reading speed and plenty fast for IDE diff application, in half the volume and at a lower price. Step up to **Mac Studio M5 Max (`614 GB/s`, up to `128GB`)** if you either prefer **dense `31B–70B` models** (`2×` faster decode: `~23 tok/s` vs `~11.6 tok/s` on `Gemma-4-31B`) or want **128GB RAM** to run `Qwen3.5-122B-A10B` and `gpt-oss-120b`.
Q: Does `Qwen3.5`’s 3:1 Gated DeltaNet linear attention lose needle-in-a-haystack accuracy at 128K context compared to full Transformer attention?
Pure 100% linear-attention / SSM models (early Mamba-1) struggled with exact passkey/UUID recall over long spans, which is **precisely why `Qwen3.5` keeps 25% full Gated Attention layers (`full_attention_interval = 4`)**. Those 10–16 full-attention layers have unrestricted random-access lookup across every prior token up to 262K, handling exact symbol/line-number retrieval while the 75% Gated DeltaNet layers handle local syntax, state tracking, and semantic compression—delivering near-full-attention retrieval accuracy at **~1/4 the KV cache cost**.
Mac mini M5 Pro (64GB) & 2026 Models (Qwen3.5 DeltaNet / Gemma 4 / gpt-oss MXFP4) Long-Context Runner
Checks macOS Metal wired memory (or NVIDIA VRAM) limits, benchmarks KV + Gated DeltaNet recurrent state footprint at 8K vs 128K context, and launches llama-server with --jinja, --cache-reuse, and Q8_0 KV cache.
#!/usr/bin/env bash # Tinker AI — Mac mini M5 Pro (64GB) & 2026 Qwen3.5 / Gemma 4 / gpt-oss Long-Context Runner (Guide #46) set -euo pipefail MODEL="./models/Qwen3.5-35B-A3B-Q4_K_M.gguf" CTX="131072" WIRED="55296" PORT="8080" echo "=== [1/3] Auditing Host Memory Ceiling (Apple Silicon Metal vs Linux CUDA) ===" if [ "$(uname -s)" = "Darwin" ]; then system_profiler SPHardwareDataType | grep -E "Chip:|Memory:" || true echo "Raising iogpu.wired_limit_mb to $WIRED MB (prevents premature swap on 64GB Mac mini M5 Pro)..." sudo sysctl -w iogpu.wired_limit_mb="$WIRED" || true vm_stat | grep -E "Pages free|Swapins|Swapouts" else nvidia-smi --query-gpu=index,name,memory.total,memory.free --format=csv || true fi echo "=== [2/3] Deterministic PP2048 / TG128 Benchmark (Flash Attention + Q8_0 KV) ===" ./build/bin/llama-bench \ -m "$MODEL" \ -ngl 99 -fa 1 -ctk q8_0 -ctv q8_0 \ -p 2048 -n 128 -r 3 -o md echo "=== [3/3] Starting llama-server (Context=$CTX, --jinja & --cache-reuse preserve DeltaNet state) ===" ./build/bin/llama-server \ -m "$MODEL" \ -ngl 99 --jinja --cache-reuse 256 \ -fa -ctk q8_0 -ctv q8_0 \ -c "$CTX" -ub 2048 -b 2048 \ --host 0.0.0.0 --port "$PORT"