feat(kvcache): add ISO3/ISO4 KV-cache quantization (--kv-cache-iso) - #398
Open
AsmanovLev wants to merge 3 commits into
Open
feat(kvcache): add ISO3/ISO4 KV-cache quantization (--kv-cache-iso)#398AsmanovLev wants to merge 3 commits into
AsmanovLev wants to merge 3 commits into
Conversation
IsoQuant paged KV storage for plain full-attention models: per 128-value
block of a head vector, L2-normalize, rotate each 4D group by a fixed unit
quaternion, quantize to nearest Lloyd-Max centroid, store corrected norm.
Ported bit-exact from llama-cpp-turbo-planar-iso (its C reference is the
test oracle; golden vectors in tests/kernels/iso_golden.npz).
iso3: 50 B / 128 values (3.125 bpw, ~5.1x smaller KV than bf16)
iso4: 68 B / 128 values (4.25 bpw, ~3.8x smaller)
- kernel/csrc/jit/iso_{common.cuh,store.cu,attention.cu}: warp-cooperative
pack/unpack + paged decode/extend attention kernels reading packed KV
directly (extend = packed prefix + bf16 new tokens, deferred store).
- kvcache/iso_pool.py: ISOKVCache (uint8 slabs, packed rows, layer remap).
- attention/iso.py: iso backend (decode: quantize-on-write; extend:
deferred store after attention so prefill never sees its own quantized
K/V), CUDA-graph capture support.
- Engine wiring: --kv-cache-iso {off,iso3,iso4} forces --attention-backend
iso; validates plain-FULL specs, bf16, head_dim % 128 == 0.
- kvcache/base.py: solve_num_pages assert now prints the budget numbers.
Validated on a 35B-A3B hybrid (Qwen3.5-MoE) at 64k-80k context on a 6 GB
RTX 3060. Quality note: models with strong outlier K channels (Qwen3 dense)
degrade at iso3 -- see docs/cli.md caveat.
…sh kernel Prefill/extend on the ISO pool no longer runs the per-query-token custom CUDA extend kernel (O(prefix) packed reads per query). Instead the packed prefix is dequantized once per layer into a dense bf16 scratch and served by the existing tiled triton extend kernel; the CUDA extend kernel remains as the fallback for empty prefixes and oversized scratch (FREETOKEN_ISO_SCRATCH_MB, default 128 MiB cap). Measured on Qwen3.5-35B-A3B (Ornith NVFP4, iso3, RTX 3060 6GB): 30k-token prefill 3m42s -> 2m21s; throughput no longer degrades with prefix length (~213 tok/s at 30k vs ~146 before).
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces new CUDA kernels and a new attention backend in a core execution path, which warrants careful human validation despite strong test coverage.
Pull request overview
This PR adds optional ISO3/ISO4 quantization for the paged KV cache, including a new ISO attention backend and CUDA pack/dequant/attention kernels, exposed via a new --kv-cache-iso server flag and documented in the CLI docs.
Changes:
- Introduces
ISOKVCache(packed uint8 KV pool) and ISO3/ISO4 reference quantization utilities. - Adds ISO decode/extend attention CUDA kernels and wires them into a new
isoattention backend with config-time validation/forcing. - Adds targeted test coverage for quantization bit-exactness, store kernels, attention correctness, and pool sizing/accessors; updates CLI docs and server args.
File summaries
| File | Description |
|---|---|
| tests/kvcache/test_iso_pool.py | New unit tests for ISOKVCache sizing, allocation, remapping, and store packing. |
| tests/kernels/test_iso_store_kernel.py | New CUDA tests validating store/dequant kernels vs reference. |
| tests/kernels/test_iso_quant.py | New tests for ISO reference quantize/dequant and golden-vector bit-exactness. |
| tests/kernels/test_iso_attention.py | New CUDA tests validating ISO attention decode/extend vs dequantized oracle. |
| python/freetoken/server/args.py | Adds --kv-cache-iso CLI flag with choices and help text. |
| python/freetoken/kvcache/iso_pool.py | Adds ISOKVCache packed KV pool implementation. |
| python/freetoken/kvcache/base.py | Improves KV-cache “not enough memory” assertion with detailed sizing context. |
| python/freetoken/kvcache/init.py | Threads kv_cache_iso through KV pool creation and selects ISOKVCache when enabled. |
| python/freetoken/kernel/iso.py | Adds ISO3/ISO4 reference quantization + JIT bindings for store/dequant and attention kernels. |
| python/freetoken/kernel/csrc/jit/iso_store.cu | Adds CUDA pack/unpack (quantize-on-write) kernels for ISO KV. |
| python/freetoken/kernel/csrc/jit/iso_common.cuh | Adds shared constants and device helpers for ISO quant/dequant. |
| python/freetoken/kernel/csrc/jit/iso_attention.cu | Adds CUDA ISO attention decode/extend kernels (packed-prefix + bf16-extend). |
| python/freetoken/engine/engine.py | Adds config-time validation for kv_cache_iso and forces/guards attention backend selection. |
| python/freetoken/engine/config.py | Adds kv_cache_iso field to EngineConfig. |
| python/freetoken/attention/iso.py | Adds IsoAttentionBackend integrating packed KV + CUDA kernels + dequant-to-triton fast path. |
| python/freetoken/attention/init.py | Registers the new iso attention backend (FULL attention only). |
| docs/cli.md | Documents --kv-cache-iso and adds iso to attention-backend list. |
Review details
- Files reviewed: 17/18 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Optional IsoQuant quantization of the paged KV cache for plain
full-attention models, ported bit-exact from the llama.cpp fork
llama-cpp-turbo-planar-iso (ggml ISO3_0/ISO4_0):
--kv-cache-iso iso3: 3.125 bits/value (50 B per 128-value block) - 5.1x smaller KV than bf16--kv-cache-iso iso4: 4.25 bits/value (68 B per block) - 3.8x smallerPer 128-value block of a head vector: L2-normalize, rotate each 4D group by a
fixed unit quaternion, quantize to the nearest Lloyd-Max centroid, store the
corrected norm ||x||/||centroids|| (norm-preserving dequant).
The flag forces
--attention-backend iso: a newISOKVCachepool (packeduint8 slabs, drop-in MHAKVCache replacement incl. hybrid GDN layer remap) plus
custom CUDA kernels. Decode is quantize-on-write; extend attends the packed
prefix + bf16 new tokens and packs them after attention (deferred: prefill
never consumes its own quantized KV). Extend runs the packed prefix through a
one-time dequant into a bf16 scratch served by the existing tiled triton
kernel (custom CUDA extend kernel remains as fallback for empty prefix /
oversized scratch,
FREETOKEN_ISO_SCRATCH_MB, default 128 MiB).Why
On small-VRAM GPUs the KV cache - not the weights - caps the usable context.
Hardware:
Checkpoint:
(35B-A3B Qwen3.5-MoE hybrid; GPU-resident weights 4.03 GiB, experts offloaded)
Command:
Prefill A/B within the branch (custom CUDA extend kernel vs dequant+triton,
same 30k-token prompt): 3m42s -> 2m21s; throughput no longer degrades with
prefix length (~146 -> ~213 tok/s at 30k).
Correctness
(golden vectors: tests/kernels/iso_golden.npz); CUDA pack/unpack kernels
byte-identical to the torch reference
tests/kvcache/test_iso_pool.py); full tests/kvcache + tests/engine +
tests/kernels suite passes (597 passed, 21 skipped)
Caveats
Qwen3) degrade noticeably at iso3 (the 4D-group rotation cannot gaussianize
channel spikes). Documented in docs/cli.md. Validated well-behaved on the
Qwen3.5-MoE hybrid above (coherent 30k-context answers).
input, head_dim % 128 == 0 (validated at config time with clear errors).