AMD Ryzen AI Max+ 395 (Strix Halo 128GB) Local LLM Benchmark: 96GB GTT Pool, Vulkan vs ROCm & Qwen3-30B-A3B MoE
Tested on a 128GB LPDDR5X-8000 Strix Halo Mini PC (Radeon 8060S gfx1151): unlocking the 96GB unified VRAM pool on Linux 6.16+, tuning ROCm hipBLASLt vs Vulkan RADV, and why Qwen3-30B-A3B MoE hits 78.4 tok/s while dense 70B models cap at 6.2 tok/s.
GMKtec EVO-X2 / Framework Desktop (AMD Ryzen AI Max+ 395 · Radeon 8060S 40CU gfx1151 · 128GB LPDDR5X-8000 256 GB/s) · Ubuntu 24.04.2 (Kernel 6.16.9)
Verified with Ethernet unplugged after kernel parameter update and GGUF weight caching; zero external calls.
- Legacy `amdgpu.gttsize` boot flags are deprecated and ignored on Linux 6.14+ for `gfx1151`; without BIOS 96GB UMA or `amdttm.pages_limit=25165824`, visible GPU memory stays trapped at ~15.5 GB.
- At ~256 GB/s LPDDR5X memory bandwidth, Strix Halo is a monster for Sparse MoE models (`Qwen3-30B-A3B` reads only 3.3B active params/token -> 78.4 tok/s), but dense 70B Q4 models read ~40GB per token and cap at ~6.2 tok/s.
1. Breaking the 15.5GB Linux GTT Ceiling on AMD Strix Halo (gfx1151)
# 1. Replace deprecated amdgpu.gttsize with amdttm 4KB page limits (25165824 pages = 96 GB): sudo sed -i 's/amdgpu.gttsize=[0-9]*//g' /etc/default/grub sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="amdttm.pages_limit=25165824 amdttm.page_pool_size=25165824 /' /etc/default/grub sudo update-grub # 2. After reboot, verify 96GB TTM pool is active: cat /sys/module/amdttm/parameters/pages_limit # Expected output: 25165824 # 3. Enable native gfx1151 hipBLASLt matrix kernels & q8_0 KV Cache in Ollama: sudo mkdir -p /etc/systemd/system/ollama.service.d cat << 'EOF' | sudo tee /etc/systemd/system/ollama.service.d/strix-halo.conf [Service] Environment="ROCBLAS_USE_HIPBLASLT=1" Environment="OLLAMA_FLASH_ATTENTION=1" Environment="OLLAMA_KV_CACHE_TYPE=q8_0" EOF sudo systemctl daemon-reload && sudo systemctl restart ollama
2. Vulkan (RADV) vs Tuned ROCm 7.2 & Why Sparse MoE Models Dominate Strix Halo
| Model & Architecture | Active / Total Params | Backend | Resident UMA | Prefill (1.8K tok) | Decode Speed |
|---|---|---|---|---|---|
| Qwen3-30B-A3B (Q4_K_M · MoE) | 3.3B / 30.5B | Vulkan (Mesa RADV) | 20.4 GB | 642 tok/s | 78.4 tok/s |
| Qwen3-30B-A3B (Q4_K_M · MoE) | 3.3B / 30.5B | ROCm 7.2 (hipBLASLt) | 20.9 GB | 886 tok/s | 74.1 tok/s |
| Qwen3-30B-A3B (Q8_0 · MoE) | 3.3B / 30.5B | ROCm 7.2 (hipBLASLt) | 34.8 GB | 710 tok/s | 49.6 tok/s |
| Qwen3-32B / QwQ-32B (Q4_K_M · Dense) | 32.5B / 32.5B | ROCm 7.2 (hipBLASLt) | 23.6 GB | 248 tok/s | 11.4 tok/s |
| Llama-3.3-70B (Q4_K_M · Dense) | 70.6B / 70.6B | ROCm 7.2 (hipBLASLt) | 46.8 GB | 112 tok/s | 6.2 tok/s |
3. Multi-Model Co-Residency: Running Coding Agent + Vision OCR + Embeddings in 96GB
Frequently Asked Questions & Edge Cases
Q: How does a 128GB AMD Strix Halo Mini PC compare to a 128GB Apple Mac Studio (M4 Max) for local LLMs?
Mac Studio M4 Max has ~546 GB/s memory bandwidth (2.1x higher than Strix Halo’s ~256 GB/s), so dense 70B models run ~2.1x faster on Mac Studio (~13 tok/s vs ~6.2 tok/s). However, Strix Halo costs roughly half as much, runs native x86 Linux/Docker with GPU passthrough (unlike macOS Docker Desktop which lacks Metal passthrough), and hits 78+ tok/s on Sparse MoE models like `Qwen3-30B-A3B`.
Q: Should I set BIOS UMA Frame Buffer to 96GB or use `amdttm.pages_limit` on Linux?
If the machine is a dedicated LLM server on Kernel 6.16.9+, setting BIOS UMA Frame Buffer to 96GB is the simplest zero-flag option. If you also use the machine for heavy CPU compilation or VMs when LLMs are idle, keep BIOS UMA at Auto/4GB and set `amdttm.pages_limit=25165824` so the 96GB pool is shared dynamically between CPU and iGPU.
AMD Ryzen AI Max+ 395 (Strix Halo 128GB) GTT/TTM Memory & MoE Benchmark Script
Verifies Linux kernel amdttm.pages_limit / BIOS 96GB UMA allocation on gfx1151, sets ROCBLAS_USE_HIPBLASLT=1, and benchmarks Qwen3-30B-A3B MoE vs dense models.
#!/usr/bin/env bash
# Tinker AI — AMD Ryzen AI Max+ 395 (Strix Halo 128GB · gfx1151) UMA & LLM Verifier (Guide #21)
set -euo pipefail
MODEL="qwen3:30b-a3b-q4_K_M"
TARGET_PAGES="25165824"
CTX="32768"
echo "=== [1/4] Kernel, BIOS UMA & TTM Page Limit Audit ==="
uname -r
if [ -f /sys/module/amdttm/parameters/pages_limit ]; then
CUR_PAGES=$(cat /sys/module/amdttm/parameters/pages_limit)
CUR_GB=$(( CUR_PAGES * 4 / 1024 / 1024 ))
echo "Current amdttm.pages_limit: $CUR_PAGES (~$CUR_GB GB addressable GTT pool)"
if [ "$CUR_PAGES" -lt "$TARGET_PAGES" ]; then
echo "[WARN] GTT pool is below target ($TARGET_PAGES pages). Add 'amdttm.pages_limit=$TARGET_PAGES amdttm.page_pool_size=$TARGET_PAGES' to GRUB_CMDLINE_LINUX_DEFAULT."
fi
fi
echo "=== [2/4] Verifying Radeon 8060S (gfx1151) Visible VRAM ==="
if command -v rocminfo >/dev/null 2>&1; then
rocminfo | grep -E "Name:\s+gfx|Size:" | head -n 6 || true
fi
echo "=== [3/4] Applying Strix Halo ROCm hipBLASLt & Flash Attention Optimizations ==="
export ROCBLAS_USE_HIPBLASLT=1
export OLLAMA_FLASH_ATTENTION=1
export OLLAMA_KV_CACHE_TYPE=q8_0
echo "Exported ROCBLAS_USE_HIPBLASLT=1 OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0"
echo "=== [4/4] Benchmarking $MODEL at num_ctx=$CTX (seed=42) ==="
curl -sS http://127.0.0.1:11434/api/generate -d "{
\"model\": \"$MODEL\",
\"prompt\": \"/no_think Compare sparse Mixture-of-Experts (MoE) memory bandwidth utilization against dense 70B models on 256 GB/s unified memory in 3 bullet points.\",
\"stream\": false,
\"options\": { \"num_ctx\": $CTX, \"temperature\": 0, \"seed\": 42 }
}" | python3 -c "
import sys, json
d = json.load(sys.stdin)
ec = d.get('eval_count', 0)
ed = d.get('eval_duration', 1) / 1e9
pc = d.get('prompt_eval_count', 0)
pd = d.get('prompt_eval_duration', 1) / 1e9
print(f'Prefill Speed : {pc} tokens ({pc/pd:.1f} tok/s)')
print(f'Decode Speed : {ec} tokens ({ec/ed:.2f} tok/s)')
"
ollama ps