llamaperf
Oct 13, 2026
Throughput
16.7 t/s gen · 245.5 tokens/s prompt processing (prefill)Prompt processing measures input prefill speed; it does not tell you the time to first token.
Quant
Q4_K_M (GGUF)
KV cache
Q8
Flash Attention
on
System RAM
32 GB

Summary

Source-reported campaign measured 2026-06-05 by Kelly, published in SymbolStar/gemma4-mac-mini-bench; recovered 2026-10-13. This is newly recovered historical evidence, not a new run or local reproduction. Primary report: https://github.com/SymbolStar/gemma4-mac-mini-bench/blob/main/REPORT-longctx.md . Data: https://github.com/SymbolStar/gemma4-mac-mini-bench/blob/main/data/longctx-results.json . Short-task report/data: https://github.com/SymbolStar/gemma4-mac-mini-bench/blob/main/REPORT.md and https://github.com/SymbolStar/gemma4-mac-mini-bench/blob/main/data/results.json . Headline is one source row, the first long-context tier: 16.66 tokens/s decode and 245.5 tokens/s native prompt processing, 5709 actual input tokens and 505 actual output tokens, with num_ctx=8192. This is not an average, maximum, concurrency throughput or a full 8192-token prompt. The same-row source TTFT estimate is 23.53 s and request wall time 53.9 s. Hardware: one Apple Mac mini M4, Mac16,10, 10 CPU cores (4P+6E), 10 GPU cores, 32 GB unified memory; macOS 26.5.1. Ollama detected Metal and 25.0 GiB available in the unified pool; that available-memory value is not dedicated VRAM or installed RAM. Power, clock, temperature, storage model and GPU offload layer count are unknown. Model: unsloth/gemma-4-E4B-it-GGUF, gemma-4-E4B-it-Q4_K_M.gguf, GGUF Q4_K_M. The source says it downloaded Unsloth GGUF files and registered local aliases gemma4-e4b-q4 and gemma4-12b-q4 after the registry pull stalled. The generic README reproduction command uses the Ollama registry; do not substitute today's registry build for these measured Unsloth files. HF identity and currently available file were verified at https://huggingface.co/unsloth/gemma-4-E4B-it-GGUF/blob/main/gemma-4-E4B-it-Q4_K_M.gguf. Historical measured HF revision, file hash and complete Modelfile are unknown. Current HF main is not the tested revision. Runtime: Ollama 0.30.5 macOS cask build. Source flags: OLLAMA_FLASH_ATTENTION=1 and OLLAMA_KV_CACHE_TYPE=q8_0. Text-only local /api/generate calls, serial request loop, stream=false. Long-context request explicitly uses think=false, temperature=0.3, num_predict=512 and the listed num_ctx. Speculative decoding/MTP and other sampling settings are not reported and must remain unknown. Long-context workload: prefixes of Project Gutenberg's The Adventures of Sherlock Holmes plus a fixed Chinese structured-summary request. Input construction uses 3.5 characters per target token, while saved actual input counts come from Ollama prompt_eval_count; nominal targets are not measured token counts. Each of the listed tiers has one stored run. The script changes num_ctx per request. The report says KV allocation changes between tiers; no explicit cache flush, cached-token counter or independent cold/warm validation is provided, so do not label these as proven cold-prefill measurements. Native metric definitions verified in the published longctx.py: prompt_eval_count / (prompt_eval_duration in seconds) and eval_count / (eval_duration in seconds). It stores rounded PP to 1 decimal and TG to 2 decimals. The source's TTFT is (load_duration + prompt_eval_duration), a server-phase estimate from a nonstreaming request, not measured first-token arrival. PP is not input divided by TTFT or request wall time. Original unrounded phase durations are not retained in longctx-results.json. All long-context rows for this model (configured context; actual input/output; native PP/TG; source phase-TTFT estimate; request wall): 8192; 5709/505; 245.5/16.66 tokens/s; 23.53 s; 53.9 s 16384; 12703/512; 216.6/14.85 tokens/s; 60.31 s; 94.9 s 32768; 26275/479; 186.6/12.72 tokens/s; 142.51 s; 180.3 s 65536; 52358/512; 175/12.24 tokens/s; 300.84 s; 342.9 s Each row records swap_after=27 MB and swap_delta=0 MB. Thus there was no measured increase, not zero pre-existing swap. The script's mem_pct_after is a vm_stat non-free-page calculation and not a reliable macOS memory-pressure or model-allocation measurement; it is not used as VRAM/RAM capacity. Separate short-task campaign, same source setup and configured context8192, one warmup 'Say OK.' call per model then a2-second pause, then translation, SwiftUI coding and pandas analysis in sequence. The published bench.py omits explicit think/temperature options, so their measured settings remain unknown; do not copy long-context think=false into these rows. TG is eval_count/eval_duration. In each line below: task; actual input/output; prompt/eval durations in seconds; TG; load duration; source TTFT estimate; request wall. translate; 94/864; 0.420291000/44.762873000; 19.30171015 tokens/s; 0.260641833 s; 0.680932833 s; 45.44966912 s swift_code; 74/1926; 0.379493000/100.263726000; 19.20933998 tokens/s; 0.274004667 s; 0.653497667 s; 100.92706800 s data_analysis; 174/1256; 0.620109000/70.736921000; 17.75593258 tokens/s; 0.275672542 s; 0.895781542 s; 71.64154196 s Short-task prompt rates can be recomputed from the retained native counts/durations, but are not combined with the long-context headline. Short-task 'peak_rss_gb' is a post-request ps RSS sample over matching processes, not a continuously monitored GPU peak. Repository provenance: data files show commit f6cffa8f4680ce1e0dcab8b21ee65b281c88d2ce (June6). Published harness currently shows 2bc218b3fa7b931916f837a5b3cb406571d1155a, whose commit description says it sanitizes local paths. The historical executable/harness revision is not pinned to the run, and the saved preview length differs from the current script; use the published script to establish the reported metric method, not a claim of byte-for-byte reproduction. Model quality is not independently validated by this throughput campaign.