Pull requests / #2941
#2941 kv: mixed K16V8 (FP16 K, INT8 V)
open · @iskamag · 0 comments · View on GitHub
BenchmarksMulti-GPUAMD / HIPNVIDIA / CUDAModels & quantsDocumentationWindows
Description
## Title kv: mixed K16V8 (FP16 K, INT8 V) Issue: Resolves # (none) ## Summary Adds `--kv k16v8`, a KV cache format between `int8` and `fp16`: **FP16 K + INT8 V** (codes plus one FP16 scale per 64 values). It keeps FP16 precision for the attention scores while keeping the V-side memory saving: **1,552 B/cell** vs 1,056 for int8 and 2,048 for fp16. The format streams with `--kv-resident` (three runs: FP16 K, V codes, V scales), works with the MTP drafter (the drafter stays plain INT8, as under k8v4), and is independent of the SCR/suffix-reuse work. Full write-up and assets: [`docs/K16V8.md`](https://github.com/iskamag/Strata/blob/feat/k16v8/docs/K16V8.md) ## What changed - `include/strata/core/layer.hpp`, `src/core/layer.cpp`: `kv_f16k_q8v` state flag, format tag 4, pool sizing, elastic/streamed host allocation, zeroing, `qsa_attn_pools`, decode append. - `src/kernels/cuda/qsa_decode_attn.cu`: decode-attention mode 4 (FP16 K, INT8 V) across `step`, `batch`, `slots` and `rows`. - `src/kernels/cuda/kv_stream.cu`, `include/strata/kernels/kv_stream.hpp`: 3-run block movers and the folded K/V host helpers for appends. - `src/prefill/prefill.cpp`, `src/core/verify.cpp`, `src/core/mtp.cpp`: prefill/verify append paths; drafter forced to INT8 under k16v8. - `src/core/conversation_snapshot.cpp`: per-side K/V sizes and format tag 4 (modes 0/1/2). - `src/program/generate.cpp`: `--kv k16v8` parsing and help. - `src/kernels/kv_stream_parity.cpp`, `src/core/conversation_snapshot_test.cpp`: mixed-format coverage. - `docs/K16V8.md`, `docs/media/k16v8/`: results and the SVG output comparison. ## Extra Notes ### Performance Controlled A/B: same engine, IQ3_S, RX 6800 (gfx1030), HIP, `STRATA_HIP_PROMPT_F16=1`, MTP spec 4, 13,109-token prompt, fully resident KV. | KV | prefill tok/s | decode tok/s | bytes/cell | | --- | ---: | ---: | ---: | | `int8` | 919.2 | 32.15 | 1,056 | | `k16v8` | 917.9 | 34.48 | 1,552 | | `fp16` | 906.6 | 33.90 | 2,048 | The three are within run-to-run/draft-acceptance noise. K16V8 is effectively int8 speed with FP16 K, and 24% smaller than fp16. At 96k context and 12 QSA layers: 1.71 GiB host KV (vs ~1.16 GiB int8 / ~2.25 GiB fp16); 32,768 resident cells use ~610 MB VRAM (vs ~415 MB / ~805 MB). The extra VRAM against int8 can reduce the expert cache by roughly 200 MB. ### Output length on the same prompt Prompt: `Make an animated SVG of an anthropomorphic cat holding a sword` | KV | output tokens | | --- | ---: | | `int8` | 37k | | `k16v8` | 29k | | `fp16` | 25k | On this workload, higher KV precision correlated with fewer output tokens: int8 produced the longest response, fp16 the shortest, and k16v8 sat between them — consistent with **less overthinking** when the cache is more precise. This is one observation, not a general quality or latency guarantee. <table> <tr> <td align="center"><b>int8</b> — 37k output tokens<br><img src="https://raw.githubusercontent.com/iskamag/Strata/feat/k16v8/docs/media/k16v8/int8.png" width="260" alt="int8 SVG output"></td> <td align="center"><b>k16v8</b> — 29k output tokens<br><img src="https://raw.githubusercontent.com/iskamag/Strata/feat/k16v8/docs/media/k16v8/k16v8.png" width="260" alt="k16v8 SVG output"></td> <td align="center"><b>fp16</b> — 25k output tokens<br><img src="https://raw.githubusercontent.com/iskamag/Strata/feat/k16v8/docs/media/k16v8/fp16.png" width="260" alt="fp16 SVG output"></td> </tr> </table> Animated originals: [int8](https://raw.githubusercontent.com/iskamag/Strata/feat/k16v8/docs/media/k16v8/int8.svg), [k16v8](https://raw.githubusercontent.com/iskamag/Strata/feat/k16v8/docs/media/k16v8/k16v8.svg), [fp16](https://raw.githubusercontent.com/iskamag/Strata/feat/k16v8/docs/media/k16v8/fp16.svg). ### Compatibility Exercised: `--kv-resident 0` and `32768`, `--mtp`/`--spec 4`, `--prompt-cache` prefix reuse, 96k context, vision, control vectors, `--adapt-async`, `--expert-cache auto`, HIP gfx1030. `--no-fast-attn` and `--native-flash-attn-short` fall back to the fused decode attention for k16v8; the gather/native path is not implemented for this format. Not yet exercised: `--batch`, `--layer-split`, `--pipeline-windows`, `--kv-grow` (elastic), and CUDA. Batch slots/rows and elastic allocation are implemented. On CUDA the prompt attention falls back to the decode kernel; gfx1030 already uses that path for most formats. `--cache-suffix-reuse` and `--kv-pool-tokens` are not in `main`, so this change is independent of SCR. ### Tests - `kv_stream_parity`: all five formats pass; k16v8 streamed-vs-resident is bitwise and the ring restore is identical. - `conversation_snapshot_test`: 4,872 checks pass, including k16v8 modes 0/1/2. - Live model: 13k and 63k-token retrieval prompts, 96k service profile, MTP drafts accepted.
Related on this site
Quick links to related pages.