# DeepSeek V4 target engine (CPU + optional CUDA tier)
[简体中文](deepseek-v4.zh-CN.md) (older; this English page is the reference)
DeepSeek V4 Flash runs from the official sharded safetensors checkpoint with
no conversion: routed experts stay native fp4, the dense set stays fp8-e4m3
with UE8M0 block scales, MLA + DSA sparse attention, 43 layers, 256 routed
experts + 1 shared, top-6. The engine is CPU-first and CPU-canonical: every
piece of state lives in host memory, and an optional CUDA tier accelerates
prefill and decode stage by stage, falling back to the CPU reference for any
stage it declines. Every GPU stage was accepted only when it reproduced the
engine's CPU reference on greedy text; what "identical" can and cannot mean
across kernels and cache states is spelled out in [Validation](#validation).
## Scope
- Production code is in `c/deepseek_v4.c` (amalgamated units); the public
engine/session API is `c/deepseek_v4.h`. The CUDA tier is
`c/backend_cuda_dsv4.cu` (+ `backend_loader_dsv4.c` on Windows).
- Official sharded safetensors checkpoints load through shared `st.h`;
standard MXFP4 matmul uses shared `quant.h`.
- Unified `c/coli` routes `run`, `chat`, `serve`, and `web` to V4; `serve` is
the OpenAI/Anthropic-compatible gateway (`c/openai_server.py`): it renders
OpenAI and Anthropic tools into V4's native prompt contract and parses DSML
call blocks back into each protocol (see the
[per-engine API matrix](api.md#tool-calling-support)); grammar remains
unsupported.
- Serving is greedy, one KV slot; speculative drafting exists and is off by
default (`V4_DRAFT`, `V4_MTP`).
- Build targets: x86-64/aarch64 Linux, Windows/MSYS2, arm64 macOS (CPU);
CUDA tier on Windows (runtime DLL) and Linux (`CUDA=1`, direct link;
verified under WSL2).
Destroy every session before destroying its engine.
## Memory policy
A checkpoint has 43 transformer layers, hidden size 4096, and 256 routed
experts per sparse layer with top-k 6. Dense weights occupy about 6.27 GiB and
a resident BF16 output head about 1.06 GiB. Routed-expert weights (~137 GiB
on disk, ~12.6 MB each) are streamed and cached according to the RAM budget:
the planner reserves workspace and a minimum expert working set, then enables
dense/head residency and grows the expert cache when memory permits.
`--ram GiB` is a planner budget, not an OS-enforced limit; without it the
budget is derived from available OS memory. `COLI_MODEL_MIRROR=
` (a
second copy of the checkpoint on another SSD) splits expert reads across two
drives — measured 2× read bandwidth; on this workload the two NVMe are the
limit for both prefill refill and decode (see Performance).
## Download
```bash
hf download deepseek-ai/DeepSeek-V4-Flash-0731 \
--local-dir /path/to/DeepSeek-V4-Flash
```
A download can finish with a truncated shard even when the client reports
success. If `st.h` rejects a shard as out of bounds, compare every local shard
size with the Hugging Face repository before treating it as an engine failure.
## Build
CPU engine (all platforms):
```bash
cd c
make deepseek-v4 # ARCH=native for the local CPU (default x86-64-v3)
```
### Windows CUDA tier
The engine is MinGW-built (MSYS2 **UCRT64** shell: `MSYSTEM=UCRT64`; the plain
MSYS shell picks the cygwin gcc and fails on `getrusage`), while the CUDA
kernels must be built by nvcc + MSVC into a DLL that the engine loads at
runtime. Two flavours of the same source ship side by side and the loader
picks at start-up by GPU:
| DLL | build target | kernels | GPUs |
|---|---|---|---|
| `coli_cuda_dsv4_dg.dll` | `make cuda-dsv4-dg-dll` (from a vcvars64 shell; fetches the pinned DeepGEMM headers on first use) | DeepGEMM tensor-core prefill paths + generic kernels | compute capability 12.x (RTX 50-series) |
| `coli_cuda_dsv4.dll` | `make cuda-dsv4-dll CUDA_ARCH=portable` | generic CUDA kernels only (fp32 compute from fp8/fp4 decode) | any sm_80+ (RTX 30/40/50, A/H series) |
The DeepGEMM sm120 headers the DLL needs are not in the repository:
`c/tools/fetch_deepgemm.sh` checks out the community sm120 port of DeepGEMM
(MIT; upstream DeepGEMM has no sm120 kernels) plus its CUTLASS/CuTe submodule
(BSD-3) at a pinned commit into the gitignored `c/third_party/deepgemm/`,
verifies both commit ids, and applies `c/patches-deepgemm-sm120-msvc.patch`
(MSVC ignores `alignas(64)` on by-value TMA descriptors — the patch pads
them). `make cuda-dsv4-dg-dll` and `DEEPGEMM=1` run it on first build
(`make deepgemm-fetch` runs it alone; ~40 MB, git required);
`DEEPGEMM_HOME=` points at an existing tree instead and `DEEPGEMM_PIN`
bumps the commit. Attribution: `THIRD_PARTY_NOTICES.md`. Loader rules:
try `_dg` first, ask it whether device 0 fits (`dsv4_cuda_backend_arch_ok`),
otherwise load the generic DLL; `COLI_DSV4_DLL=` forces one. The
start-up banner names the choice: `[DSV4 CUDA] backend=coli_cuda_dsv4_dg.dll
(deepgemm-sm120)`. Deploy = `deepseek_v4.exe` + both DLLs next to it.
### Linux CUDA tier
```bash
cd c
make -f Makefile.deepseek-v4 deepseek-v4 CUDA=1 CUDA_ARCH=portable # generic kernels, any sm_80+
make -f Makefile.deepseek-v4 deepseek-v4 CUDA=1 DEEPGEMM=1 # DeepGEMM flavour, sm_120a only (fetches the pinned headers)
make -f Makefile.deepseek-v4 deepseek-v4 CUDA=1 CUDA_ARCH=sm_86 NO_TC=1 # toolkit older than 12.8
```
`CUDA_HOME` defaults to `/usr/local/cuda` (`CUDA_HOME=/usr/local/cuda-13.3`
to pick a versioned install). `CUDA_ARCH` is `native` (the local card),
`portable` (sm_80/86/89/90/120 + PTX) or one `sm_XX`; `DEEPGEMM=1` ignores it
and builds sm_120a only — the DeepGEMM kernels use block-scaled MMA PTX that
exists for no other target. `NO_TC=1` (`-DCOLI_DSV4_NO_TC`) compiles out the
opt-in cuBLASLt MXFP8 path (`DSV4_CUDA_TC=1`), whose block-scaling API needs
cuBLASLt ≥ 12.8; use it for CUDA 12.6 toolkits (Jetson JetPack). `libcuda`
is linked from the toolkit's `lib64/stubs` (driver installs and WSL2 ship
only `libcuda.so.1`), and the binary carries an rpath to `$(CUDA_HOME)/lib64`.
Verified on Ubuntu 22.04 under WSL2 (gcc 11, CUDA 13.3.1 + 12.6.85, RTX
5080): the CPU-only build (6 s), the generic fat binary, the DeepGEMM
binary and the 12.6 `NO_TC=1` object all compile; without the gate the 12.6
compile fails on exactly the four cuBLASLt 12.8 symbols. At run time both
CUDA binaries bring the tier up (`[DSV4 CUDA] device 0: ... sm_120`,
`v4_gpu tier=dense-matvec`) and generate; see [Validation](#validation) for
the WSL2 numbers.
There is no loader on Linux: one flavour is linked directly. A DeepGEMM
binary on a non-sm120 card logs `v4_gpu warning=backend ... does not support
device` and runs CPU-only. Host-slab pinning for expert uploads is
Windows-only for now (`VirtualQuery`); Linux uses pageable copies (correct,
slower refill).
## Run
Canonical serve line (Windows, PowerShell; the environment used for every
number below):
```powershell
$env:COLI_MODEL_MIRROR = "D:\models\DeepSeek-V4-Flash" # optional second copy
$env:COLI_CUDA = "1"; $env:COLI_GPU = "0"; $env:CUDA_DENSE = "1"; $env:COLI_CUDA_PIPE = "2"
$env:COLI_CUDA_ATTN_BATCH = "1"; $env:COLI_CUDA_MOE_BATCH = "1"
$env:V4_MOE_REFILL_GROUP = "12"; $env:DSV4_CUDA_EXPERT_MIRRORS = "688"
python ./coli serve --model C:\models\DeepSeek-V4-Flash --ram 32 --ctx 20000
```
`coli run|chat|web` take the same environment. `--ngen` is a ceiling, not a
target (answers end at EOS; an oversized ceiling is clamped to the context
with a stderr note). `CTX`/`--ctx` sets the context window.
What the knobs do (full table in [Environment reference](#environment-reference)):
`COLI_CUDA_ATTN_BATCH=1` puts the batched prefill attention block on the GPU
(compressor/indexer projections, sparse attention on a persistent device KV
ring, wo, mHC) and enables the GPU decode attention/indexer paths;
`COLI_CUDA_MOE_BATCH=1` runs prefill MoE on a transient VRAM expert bank
(route-aware refill, expert-grouped GEMM); `DSV4_CUDA_EXPERT_MIRRORS` is the
decode-side VRAM expert cache; `V4_MOE_REFILL_GROUP` the refill lookup width.
All default to CPU-safe values when unset; the GPU tier itself is on when the
DLL loads (`DSV4_CUDA=0` disables it).
## VRAM budget and per-card settings
What the tier keeps in VRAM (measured on a 16 GB RTX 5080): dense/attention
mirrors **6.3 GB** (needed for GPU attention and the GPU dense matvecs in
decode), the transient prefill expert bank **2.2 GB** (`COLI_CUDA_MOE_BATCH`,
freed when decode starts), attention/KV/work buffers **~0.5 GB**, and the
rest as decode expert mirrors at **~8 MB each**. `DSV4_CUDA_EXPERT_MIRRORS`
is only an upper bound (default 4096): the cache grows while at least
`DSV4_CUDA_VRAM_RESERVE_MB` (default 2800 with the bank enabled, 600
without) stays free, so free VRAM sizes it at run time — you normally do not
need to set it. Decode is disk-bound, so more mirrors help in proportion to
the hit rate they add (~11 000 experts total; 600 mirrors ≈ 5 %); more RAM
(`--ram`) buys more than more VRAM.
| VRAM | dense mirrors | prefill bank | recommended env | expected |
|---|---|---|---|---|
| 6 GB | no (6.3 GB does not fit) | yes (2.2 GB) | `CUDA_DENSE=0 COLI_CUDA_MOE_BATCH=1 COLI_CUDA_ATTN_BATCH=0` | GPU MoE prefill (generic kernels on non-RTX50), CPU attention/decode; ~150 mirrors between prefills |
| 8 GB | yes | no (1.7 GB left) | `CUDA_DENSE=1 COLI_CUDA_ATTN_BATCH=1 COLI_CUDA_MOE_BATCH=0` | GPU attention + GPU decode dense; MoE prefill on the CPU union; ~100 mirrors |
| 10–12 GB | yes | yes (tight) | `CUDA_DENSE=1 COLI_CUDA_ATTN_BATCH=1 COLI_CUDA_MOE_BATCH=1 DSV4_CUDA_VRAM_RESERVE_MB=2500` | full GPU prefill; 100–350 decode mirrors after the bank is released |
| 16 GB (this box) | yes | yes | the canonical line above (mirror cap can be left unset) | ~600 mirrors, the numbers in this document |
| 24 GB | yes | yes | canonical | ~1 700 mirrors (~15 %); decode +10–15 % vs 16 GB |
| 32 GB | yes | yes | canonical | ~2 700 mirrors (~25 %); decode +25–35 %; raise `--ram` first if RAM allows |
On non-Blackwell cards the generic DLL is selected automatically (fp32
kernels): same settings, prefill roughly 2–3× slower than the DeepGEMM
numbers, still far ahead of CPU.
## Prefill: segments, chunks, checkpoints
- **Chunks/segments.** Prefill runs layer-major over 128-token chunks
(`V4_PREFILL_CHUNK`) inside 4096-token segments (`V4_PREFILL_SEGMENT`).
Segments are atomic; the client-cancel poll runs between them and completed
segments are recorded, so an identical retry resumes instead of restarting.
Each segment re-sweeps every layer's routed experts through the transient
bank, so fewer/larger segments = fewer disk sweeps, at the price of cancel
latency (~2.5 min worst case at 4096). Progress lines `v4_prefill N/M tokens`
print per segment on multi-segment prompts.
- **Prefix checkpoints** (`V4_PREFIX_CKPT`, min length `V4_PREFIX_CKPT_MIN`=512).
The window/compressor/indexer state cannot rewind, so reuse across
conversations needs a snapshot at the shared boundary. Three capture rules:
(1) the gateway tells the engine where the rendered system turn ends
(optional 8th `SUBMIT` header field) → snapshot there on the very first
request; (2) fallback: the longest common prefix of two successive fresh
prompts; (3) **prompt-end** snapshot after every prefill, because agent
clients re-render the assistant reply, so strict "extends everything fed"
reuse fails at the reply boundary. `V4_PREFIX_CKPT_SLOTS` (4) in-memory
slots, LRU with prompt-end evicted first. Log lines: `v4_ckpt store
prefix=N` / `prompt_end=N`, `v4_ckpt hit prefix=N`.
- **Persistence.** Prefix captures are written to `/.coli_ckpt/`
(`V4_PREFIX_CKPT_DISK`=1; `2` also persists prompt-end captures, `0` off;
~140 MB for an 8.3k-token prefix, config-fingerprinted, temp+rename) and
loaded lazily on the first request after a restart — a fresh serve no
longer re-prefills the system prompt.
## Performance (RTX 5080 16 GB, 2× NVMe mirror, 32 GB RAM, i9-class CPU)
| scenario | before this tier | now |
|---|---|---|
| 826-token prefill (cold) | 578 s (CPU) | ~40 s |
| 3324-token prefill (cold) | 271 s (early GPU) | **90 s** (DeepGEMM), 225 s (generic DLL) |
| 8.3k opencode system prompt, first turn after start | ~600 s | **~4 min** — once per model (checkpoint on disk) |
| every later session with the same system prompt | 300 s | **6–9 s** |
| follow-up turn in a conversation (tool result) | 677 s | **6 s** |
| decode at 3.3k context | 0.6 tok/s | **1.5–1.6 tok/s** |
Where the time goes now: prefill ≈ 35 % expert-bank refill (disk-bound,
~6 GB/s across two NVMe), ≈ 35 % attention block (many small GPU stages +
host↔device syncs), ≈ 5 % MoE GEMM, rest indexer/dense/mHC. Decode ≈ 75 %
routed-expert reads (~230 × 12.6 MB per token from disk at 6 % VRAM hit
rate), rest GPU stages. More RAM/VRAM (higher expert hit rate) is the only
lever left below the disk limit; a multi-GPU design exists on paper only.
Profilers: `DSV4_ATTN_PROF=1` (per chunk-layer `attnprof`/`blockprof`/
`idxprof`), `DSV4_DECODE_PROF=1` (per-token `decprof`), `DSV4_CUDA_MOE_PROF=1`,
`DSV4_IDX_VERIFY=1` (GPU indexer projection/scoring vs CPU, bitwise),
`V4_PREFIX_LOG=1` (checkpoint/hint decisions), `v4_mirror` per-drive I/O
telemetry after each request.
## GPU coverage
| build | GPUs | prefill | decode |
|---|---|---|---|
| CPU only (no DLL / `DSV4_CUDA=0` / Linux default) | — | CPU reference | CPU reference |
| generic DLL / `CUDA=1` | any sm_80+ | GPU attention block, indexer, generic batched MoE on the VRAM bank | GPU attention, indexer, expert mirrors |
| DeepGEMM DLL / `CUDA=1 DEEPGEMM=1` | compute 12.x | as generic + tensor-core dense/MoE GEMMs | same as generic |
| multi-GPU | — | single device today (`DSV4_CUDA_DEVICE` selects); expert-parallel design drafted, not implemented | — |
## Environment reference (V4 engine)
Defaults in parentheses; all read by `c/deepseek_v4.c` unless noted `.cu`.
**GPU tier**
| var | meaning |
|---|---|
| `DSV4_CUDA` (1) | master switch for the V4 GPU tier; `0` = CPU only |
| `DSV4_CUDA_DEVICE` (0) | CUDA device ordinal |
| `COLI_DSV4_DLL` | Windows: force a backend DLL file name (loader) |
| `COLI_CUDA_ATTN_BATCH` (0) | `1` = GPU batched prefill attention block + GPU decode attention/indexer |
| `COLI_CUDA_MOE_BATCH` (0) | `1` = prefill MoE on the transient VRAM expert bank |
| `COLI_CUDA_MOE_BATCH_MIN` (256) | min fresh tokens to engage the bank |
| `DSV4_CUDA_EXPERT_MIRRORS` (4096) | upper bound on decode VRAM expert mirrors (~8 MB each); free VRAM sizes the cache at run time |
| `DSV4_CUDA_VRAM_RESERVE_MB` (2800 with the bank, else 600) | VRAM kept free while mirrors grow (bank + attention buffers) |
| `V4_MTP_GPU_MIRRORS` (16) | separate mirror cache for the MTP drafter |
| `DSV4_CUDA_PIN_HOST` (1, `.cu`) | page-lock expert-cache slabs for DMA uploads |
| `DSV4_CUDA_MOE_GROUPED` (1, `.cu`) | expert-grouped MoE GEMM rows; `0` = legacy replicated |
| `V4_MOE_BANK_FULL` (off) | `=N`: prefetch a whole layer's experts above N tokens (measured worse) |
**Prefill / checkpoints**
| var | meaning |
|---|---|
| `V4_PREFILL_CHUNK` (128) | chunk width, clamp [1,128] |
| `V4_PREFILL_SEGMENT` (4096) | atomic segment length (cancel/resume granularity, expert re-sweeps) |
| `V4_PREFIX_CKPT` (1) / `V4_PREFIX_CKPT_MIN` (512) / `V4_PREFIX_CKPT_SLOTS` (4) / `V4_PREFIX_CKPT_DISK` (1) | prefix checkpoints, see above |
| `V4_PREFIX_LOG` | log hint boundary / reuse decisions |
| `V4_IDX_BATCH` (1) | batched indexer selection in prefill; `0` = legacy per-token |
| `V4_IDX_IDENTITY` (0) | `1` = skip indexer scoring when every candidate fits under `index_topk` (index order instead of upstream's score order; ~8 % faster prefill, changes rounding) |
| `COLI_V4_ROWS16` (1) | `0` = never repack hot experts into the rows16 layout (reference matvec for all; numerics comparisons) |
| `CTX` (4096) / `NGEN` | context window / generation ceiling (CLI + serve) |
**Experts / I/O**
| var | meaning |
|---|---|
| `COLI_MODEL_MIRROR`, `SNAP_MIRROR`, `COLI_DISK_WEIGHTS` | dual-SSD read split (see ENVIRONMENT.md) |
| `V4_MOE_REFILL_GROUP` (6, max 16) | parallel lookups per bank refill group (bounded by pin slots; 12 measured best) |
| `V4_LOADER_LANES` (3, max 16) | persistent expert-loader threads for decode |
| `V4_EXPERT_UNION` (1) | per-chunk expert union batching on the CPU path |
| `COLI_V4_DIRECT` (1) | O_DIRECT streaming reads |
| `COLI_V4_AUTOPIN`, `COLI_V4_PREWARM`, `COLI_V4_SAVE_USAGE` | hot-expert pinning from `.coli_usage` history |
**Speculative decoding** (off by default): `V4_DRAFT`, `V4_MTP`, `V4_MTP_GB`,
`V4_MTP_MIN`, `V4_MTP_DRAFT`, `V4_MTP_PARTIAL_KEEP`, `V4_NGRAM` (1),
`V4_NGRAM_PARTIAL_KEEP`, `COLI_V4_MARKOV_SPEC`, `COLI_V4_MARKOV_BLOCK`,
`COLI_V4_MARKOV_KEEP`.
**Diagnostics**: `DSV4_ATTN_PROF`, `DSV4_DECODE_PROF`, `DSV4_IDX_VERIFY`,
`DSV4_CUDA_MOE_PROF`, `DSV4_CUDA_DG_PROFILE`/`_AB`/`_DUMP` (`.cu`),
`COLI_NO_OMP_TUNE`, `OMP_NUM_THREADS`.
Note: `COLI_CUDA`, `COLI_GPU`, `CUDA_DENSE`, `COLI_CUDA_PIPE` in the serve
line are read by the CLI/`colibri.c` conventions; the V4 engine's own switch is
`DSV4_CUDA` and the two `COLI_CUDA_*_BATCH` gates above.
## Validation
Tiny fixture (generated locally, ignored):
```bash
python -m pip install -r tools/requirements-deepseek-v4-tiny.txt
make deepseek-v4-tiny-check
```
Real checkpoint oracle:
```bash
make deepseek-v4-oracle MODEL=/path/to/DeepSeek-V4-Flash \
MEMORY_GB=32 ORACLE_TEACHER_FORCING=32 ORACLE_GREEDY=20
```
GPU tier evidence (2026-08): each stage was accepted with greedy text
byte-identical to the engine's own reference chain at the time (826- and
3324-token benchmark prompts, 8 tokens; strip the CLI's trailing
`TUNE decode:` line before comparing); the GPU indexer projection/scoring and
the CPU-replica fp8 matmul are checked bitwise by `DSV4_IDX_VERIFY=1`; the CUDA
numerics test is `c/tests/test_dsv4_sparse_attn_batch_cuda.c`. Different
kernels are not bit-identical to each other in general — a GPU run and a CPU
run of the same prompt diverge by a rounding flip after some tokens, exactly
as two CPU runs with different hot-expert sets do (next section) — so text
identity is a regression check within one configuration, not a proof across
configurations.
### Linux CUDA tier under WSL2 (2026-08-16)
Ubuntu 22.04 on WSL2 (15 GB guest RAM, model read over `/mnt/c` + `/mnt/d`,
`--memory-gb 11`, canonical GPU env), prompt "Say hello in exactly one short
sentence.", 12-token ceiling. Both Linux binaries produced `Hello!` + EOS,
the same as the Windows engine on the same prompt; the wall-clock gap is the
9p file system (expert streaming), not the tier:
| build | tier | ttft | 3 decode tokens |
|---|---|---|---|
| Linux `CUDA=1 DEEPGEMM=1` (sm_120a) | `[DSV4 CUDA] device 0 ... sm_120`, dense mirrors 6.27 GiB | 119.9 s | 32.4 s |
| Linux `CUDA=1 CUDA_ARCH=portable` (generic) | same | 122.1 s | 33.2 s |
| Windows `deepseek_v4.exe` + `coli_cuda_dsv4_dg.dll` (NTFS, 2× NVMe) | same | 16.8 s | 2.0 s |
A native Linux box with the checkpoint on local NVMe is still the missing
measurement (host-slab pinning is Windows-only, so refill is pageable there).
### CPU-only audit (2026-08-15/16)
Question: does the CPU path still compute what upstream `dev` computes after
the GPU work? Method: 826-token prompt, 48 greedy tokens, real checkpoint,
upstream `dev` engine built from its own tree vs this tree's engine built
without the GPU tier (the Linux/macOS build shape) and with the tier
disabled.
- Compiles clean without `COLI_V4_GPU_TIER`; the tiny torch-reference suite
(`tests/test_deepseek_v4_tiny.py`) is token-exact on the CPU-only build for
every target case.
- On the real checkpoint, greedy text is **not** a stable identity check
across configurations, in upstream itself: hot (cache-resident) experts run
the vectorized `rows16` kernel while cold ones run the reference matvec, the
two accumulate in different orders, and which experts are hot depends on the
autopin history (`.coli_usage`, rewritten by every run), the chunk width and
the hit pattern. Upstream produced different 48-token texts with and without
its history; so did this tree; every variant is a coherent answer differing
by a rounding flip a few tokens in.
- With that variable removed on both sides (`COLI_V4_ROWS16=0`
`COLI_V4_AUTOPIN=0 COLI_V4_SAVE_USAGE=0`: reference kernels only, no
history) **upstream and this tree's CPU-only build produce identical
48-token text** — the CPU math is unchanged.
- One change of this branch did alter CPU accumulation order and is now off
by default: the indexer identity short-circuit for `count <= index_topk`
(returned candidates in index order; upstream returns them in score order,
and the sparse attention reference sums in that order). `V4_IDX_IDENTITY=1`
re-enables it (~8 % faster prefill on GPU, e.g. 96 s -> 88 s at 3.3k).
- CPU-only prefill speed: chunk 128 vs 64 identical within noise (788 vs
797 s for 826 tokens); the pinned-slab, pipelined refill and all kernel
work are GPU-only and do not touch the CPU path.
- Degenerate config guarded: a decode expert mirror cache below 8 entries
(`DSV4_CUDA_EXPERT_MIRRORS<8`) recycled a slot still referenced within one
layer and produced garbage; such caches now stay on the CPU.
## Follow-ups
- Non-greedy sampling and more serving slots.
- Linux CUDA tier: measure on a native Linux box (WSL2 verified), POSIX host pinning.
- Multi-GPU expert-parallel tier (design draft, untracked until built).
- Shared replacements for the two temporary private quant paths (rows16 cache).