02 — sizes, streaming speed evidence, performance model & measurement plan #
3. sizes [est] #
expert = 4.915M params. totals across 48 layers:
| experts/layer | IQ2_XS (2.31 bpw) | Q2_0 (2.25 bpw [src: ggml.h type 42, 64w=18B]) |
Q3_K / IQ3_S (3.44 bpw) | IQ3_XXS (3.06 bpw) |
|---|---|---|---|---|
| 512 | 34.9 GB | 34.0 GB | 51.9 | 46.2 |
| 320 | 21.8 | 21.2 | 32.4 | 28.9 |
| 256 | 17.5 | 17.0 | 26.0 | 23.1 |
| 224 | 15.3 | 14.9 | 22.7 | 20.2 |
other fixed costs:
- dense ≈ 3.2 GB
- KV at 128K: fp16 3.0 GiB, q8 1.6 GiB, q4 0.84 GiB
- GDN state ≈ 110 MiB (fp32)
- mmproj ≈ 0.5–0.9 GB
fast-memory budget for experts:
- desktop: ~4.3 GB VRAM + ~7.5 GB RAM ≈ 11.8 GB ≈ 178 experts/layer at Q2_0 (1.3824 MB/expert)
- laptop: ~7.5 GB ≈ 113 experts/layer at Q2_0
- so on both machines, even 224 is partly streamed from SSD
desktop note: Strata needs ≥32 GB system RAM [src: Strata MODELS.md, web], and the measured 7600 XT run had 64 GB. 16 GB RAM is the desktop bottleneck, not the GPU. options:
- (a) more RAM
- (b) Strata/llama.cpp low-RAM mode with heavier SSD streaming
- (c) prune harder for the desktop
4. what's known about streaming speed #
4.1 Mac evidence [src: Strata docs/MAC.md, the only streamed-Mac measurement] #
M4 Mac mini, 32 GB, experts streamed, 11.5–14.7 GB arena, no MTP, medians of 5:
| Q2_0 | IQ3_XXS | |
|---|---|---|
| decode, short | 14.1 | 10.0 |
| decode after 6K doc | 13.1 | 7.7 |
| prompt, 4K tokens | 93.6 | 65.8 (84.1 with experts' copy) |
- M5 Max 128 GB, resident: Q2_0 prompt ~1,430 tok/s at 4K, decode 87 tok/s without MTP.
- Slotstream [src]: 24–48 GB Macs, decode ~5–16 tok/s (est. table), 20.9–23.7 tok/s on a 48 GB M5 Pro. no prefill numbers.
4.2 ds4-recipe evidence [src: tangled.org/astrra.space/ds4-recipe] #
DeepSeek V4.1 Flash, Strix Halo 128 GB UMA, 3 NVMe, ~31% of experts resident:
- cold prefill 354–391 tok/s (README says ~450 now), from:
- 4 lanes × 8,192-token chunks sharing one read of each layer's expert union
- hipBLASLt prepared GEMMs
- p50 prefill by turn size:
| new tokens in turn | p50 tok/s |
|---|---|
| 64–256 | 19 |
| 256–1k | 46 |
| 1k–4k | 106 |
| 4k–16k | 236 |
| 16k+ | ~340 |
small turns are SSD-bound.
4.3 Air thermals & local M5 hardware microbench [src: local bench/README.md + web] #
- measured on this 13" M5 Air (
Mac17,3, 10-core GPU, 1 TB SSD,bench/run_01..03):- M5 10-core GPU FP16 GEMM (
K=2560): 12.60 TFLOP/s at M=512, 13.66 TFLOP/s at M=1024, 14.07 TFLOP/s at M=4096 (recommendedMaxWorkingSetSize = 17.76 GiB). exactly 1/4 of the 40-core M5 Max, confirming the ~356–360 tok/s resident prefill compute ceiling. - 60-second continuous GPU thermal sag test (
M=4096, K=2560, N=2560FP16): started at 14.00 TFLOP/s (t=0..15s) and ended at 13.88 TFLOP/s att=55..60s(−0.86% sag over a full minute). so single-prompt cold prefills (even 15–30 s) do not hit a thermal cliff; multi-minute sustained loads [web: Notebookcheck ~9 W sustained] still favor KV reuse. - 1 TB SSD uncached read bandwidth (
F_NOCACHE=1, 100.0% physicaldisk0verified viaiostat -Idon virgin 1 GiB slices):- standard GGUF (
512 KiB× 3 reads/expert): 2.41 GB/s (1 thread) → 5.52 GB/s (2 threads) → 7.03 GB/s (4 threads) - contiguous
.expertscopy (1.5 MiB× 1 read/expert): 3.85–3.93 GB/s (1 thread) → 6.84 GB/s (2 threads) → 6.60–6.89 GB/s (4 threads) - PLE n-gram table (
4 KiBrandom page reads): 0.04 GB/s (~10k IOPS, ~1.6 ms/tok for 16 heads) at 1 thread → 0.33 GB/s (~82k IOPS, ~0.2 ms/tok) at 8 threads
- standard GGUF (
- methodological trap caught (
run_02→run_03): on macOS APFS, repeatingpreadon identical file offsets across benchmark iterations can partially hit APFS cache on pass 2+ even withF_NOCACHE=1. always use virgin slices and checkiostat -Id(disk0MiB delta == 100% of requested MiB).
- M5 10-core GPU FP16 GEMM (
5. performance model [est, to be replaced by measurements] #
5.1 the metric: per-turn floor #
- each prefill chunk (or each turn, however short) reads, for every layer, the union of experts its tokens picked. with top-10 of 512, even ~256 tokens touch most of a layer (uniform-routing approximation; real routing is skewed, so less).
- so per-turn floor ≈ non-resident expert bytes ÷ SSD read rate, plus compute.
- kernel opts move the ceiling. pruning, residency and MoCE move the floor.
5.2 laptop model (anchored to measured M5 Air SSD & GPU constants) #
inputs:
- Q2_0 (2.25 bpw = 1.3824 MB/expert [src:
ggml.htype 42]), ~7.5 GB experts resident (~113 experts/layer) - compute ceiling 356 tok/s [src: local Metal FP16 GEMM 14.07 TFLOP/s on M5 10-core GPU, scaled from M5 Max 1,430 tok/s @ 40c]
- measured SSD rates on this 13" M5 Air (
iostat -Id100% physicaldisk0verified) [src:bench/README.md]:- 2.41 GB/s: 1-thread standard GGUF (3 × 512 KiB/expert)
- 3.90 GB/s: 1-thread contiguous
.expertscopy (1 × 1.5 MiB/expert) - 6.80 GB/s: 2–4 thread
preadfan-out (saturates PCIe Gen4 x4 NVMe)
- no IO/compute overlap (pessimistic), before MoCE (measured Phase 1b OOS
lruλ = 0 -> 0.09withprotect_top_j = 3cuts decode misses 17.4–19.9% on its own, or −36.4% atK320_reap_hybrid/ −47.4% atK256_reap_l2_sumcombined with pruning; see §7.1 for exact OOS decode tok/s)
| experts (non-resident Q2_0 @ 2.25 bpw) | SSD mode (measured) | 1024 chunk | 4096 | 8192 | 256-tok cold prefill floor (pre-MoCE) |
|---|---|---|---|---|---|
| 512 (26.5 GB) | 2.41 GB/s (std 1-th) | 74 tok/s | 182 | 241 | ~11.7 s |
| 512 (26.5 GB) | 3.90 GB/s (.experts 1-th) |
106 | 224 | 275 | ~7.5 s |
| 512 (26.5 GB) | 6.80 GB/s (2–4 th) | 151 | 266 | 304 | ~4.6 s |
| 320 (13.7 GB) | 3.90 GB/s (.experts 1-th) |
160 | 273 | 309 | ~4.2 s |
| 320 (13.7 GB) | 6.80 GB/s (2–4 th) | 209 | 303 | 327 | ~2.7 s (warm 256-tok decode: 5.88 s @ 43.5 tok/s w/ MoCE) |
| 256 (9.5 GB) | 3.90 GB/s (.experts 1-th) |
193 | 294 | 322 | ~3.2 s |
| 256 (9.5 GB) | 6.80 GB/s (2–4 th) | 240 | 318 | 336 | ~2.1 s (warm 256-tok decode: 5.40 s @ 47.4 tok/s w/ MoCE) |
| 224 (7.4 GB) | 3.90 GB/s (.experts 1-th) |
215 | 306 | 329 | ~2.6 s |
| 224 (7.4 GB) | 6.80 GB/s (2–4 th) | 259 | 325 | 340 | ~1.8 s (warm 256-tok decode: 5.01 s @ 51.0 tok/s w/ MoCE) |
reading:
- 200 tok/s on cold prompts is mostly a chunk-size question
- pruning mostly buys the per-turn floor
- Air throttling will pull sustained cold prefill down (guess 150–250 tok/s, unmeasured)
- design implication for the Air: maximize reuse so the GPU only works in short bursts (disk KV cache, SCR, preserved thinking)
5.3 decode #
- per token reads ~1.5–2 GB of weights [est] vs ~150 MB of context-dependent traffic at 128K (QSA KV ~50 MB + indexer scan ~100 MB)
- Strata RTX 5070: 94 → 76 tok/s from short to 128K [src]
- on the Air, decode is dominated by SSD misses (~14 tok/s measured on M4 vs ~80 tok/s bandwidth bound)
- so MoCE / residency / prefetch matter. attention tricks don't.
6. measurement plan #
principle:
- Colab measures hardware-independent quantities (quality, routing, misses per token/turn under each policy)
- the local machines measure hardware constants (SSD GB/s with the real read pattern, resident compute ceiling, thermals)
- multiply them to predict latency for every configuration, then validate only the top 2–3 for real
6.1 Colab (A100 80 GB) #
- setup:
- HF token (Swift repos are gated)
- download Swift GSQ-RCO IQ3_S (≈ 78 GB total; shard 1 resident in VRAM, PLE shard on disk via mmap/lazy)
- build mainline llama.cpp with CUDA
- routing-trace logger:
- find the router-logit tensors in the qwen4exp graph (name unverified), hook them via the eval callback
- log real agent sessions, prefill and decode, marked separately
- format [est]: per token per layer, top-64 (expert id u16, logit fp16) = ~12 KB/token, so 1M tokens ≈ 12 GB. full 512-wide logits for a sampled subset only.
- also log token ids, turn boundaries, session ids
- offline cache replayer (CPU, can be written locally now):
- policies: LRU, LFU, popularity EMA, EMA + near-pick credit, inverse-router score, Belady MIN (ceiling)
- cache sizes matching each machine × each prune
- output: misses per decoded token and per turn (by turn size), prefetch recall / read amplification for next-layer prediction
- pruning variants 224 / 256 / 320:
- saliency from our traces and/or RCO
- GGUF slicing script
- each variant ~40–60 GB: build → eval → upload to private HF → delete (disk is ~236 GB)
- quality evals for each prune and each λ:
- KL vs unpruned on held-out traces
- JA probe
- world-knowledge fabrication set and "said idk when it knew" set
- persistent-agent evals (§6.4)
- vision check (ISTA lesson)
- persona style score (after the tune)
- MoCE λ sweep, closed loop: simulate the cache inside the forward pass (routing depends on residency, so open-loop replay is wrong for λ > 0, as ds4 notes). λ ∈ {0, 0.05, 0.075, 0.1}, protect top-J ∈ {2, 3}.
- SCR staleness on GDN: nats/token of SCR splices vs fresh prefill on real edited contexts.
- prefix-sliding toggle and top-k 8 override: quality on the same evals.
- teacher top-k logits + known/unknown labels for healing (phase 3).
6.2 laptop (phase 0, no training) #
- Strata-Metal (or Slotstream) running Swift GSQ-RCO Q2_0 / IQ2_XS with a persona system prompt
- raw SSD read rate with expert-sized reads (and Strata's actual pattern)
- resident compute ceiling: prefill on a small model / short prompt (gives the ~360 tok/s check)
- cold prefill at 4K and 32K, chunk 1024 / 4096 / 8192 (if memory allows)
- thermals: 3 back-to-back 32K cold prefills with
sudo powermetrics --samplers gpu_power. watch tok/s sag and watts - decode at 4K / 64K / 128K context (tells us if prefix sliding has anything to win)
- seconds per agent turn at 500 / 2K / 8K fresh tokens, warm cache
- log two clocks: wall + server counters (REAP card lesson)
- early warning: if per-turn time is unusable even with reuse, revisit "same model on laptop" (§10)
6.3 desktop (phase 0) #
- same list, on Strata HIP (gfx1102) or llama.cpp
--n-cpu-moe+ mmap, in low-RAM mode - answers how bad 16 GB RAM really is
6.4 persistent-agent eval #
what it's for: picking K, λ / top-J, the top-k 8 and prefix-sliding flags, accepting SCR's GDN error, and regression checks after healing / persona / FTPO. model-level metrics miss compounding errors over long tool loops (ISTA Coder: LiveCodeBench kept 98.7%, SWE-bench only 91.3% [src]).
- tier 1, fast screen (every variant):
- teacher-forced KL and top-1 agreement vs unpruned Swift on a fixed set of synthetic/curated persistent-agent traces (not personal session transcripts)
- minutes per variant, no generation
- tier 2, task suite (finalists only), ~30–50 tasks with scripted pass checks, run through the real harness:
- ops: in a throwaway VM/container. e.g.: find why a systemd unit fails, fix a cron job, free disk, read logs and report, install and configure a package
- python-tool: data wrangling, file inspection, quick calculations, the albedo-style kernel use pattern
- memory across sessions: plant facts/preferences, run unrelated turns + a compaction, then check recall and correct use later. this exercises SCR + compaction.
- long-horizon persona consistency: voice still right after 100K+ tokens and many tool outputs. judged by a rubric, plus the slop rate.
- abstention: world-knowledge questions where the right move is "not sure" or a search call, plus ones it should just answer
- context-instruction following: does it obey what the harness injects (memories, its own self-edited prompt rules, LCM/compaction summaries, tool protocols), including instructions that override the voice (exact formats, writing for other people, files/commits in a specified style). this replaces generic IFBench as the category that matters.
- JA conversation and tool use
- vision spot checks
- existing benchmarks worth borrowing from (check licenses/fit): Terminal-Bench (ops), tau-bench (tool + user loops), LongMemEval / LoCoMo (long-term memory)
- report per variant:
- pass rate per category
- the speed side from the latency model: seconds per turn for a typical turn mix, i.e. many small turns (user message, tool output), occasional compaction, rare cold starts