knlp / inference

Inference · memory, quality and speed

Asymmetric KV
Cache Quantization

Use 16-bit keys and 8-bit values to shrink the KV cache. Keeping keys precise helps in some model recipes. Symmetric FP8 is a better memory choice when it passes the required quality objective. Serving speed needs its own measurement.

Memory25% less payload

At equal token slots, with equally sized key and value tensors.

PerformanceWorkload dependent

Batch gains are measured. HTTP serving has latency and reliability tradeoffs.

AvailabilityPublic forks

Try the pinned Qwen3 recipe. Upstream integration is pending.

When to choose it: choose K16/V8 when it passes your quality checks and K8/V8 does not. When symmetric FP8 also passes, it can save more memory—as the Qwen3.8 reference comparison shows.

Precision and scaling · two Qwen checkpoints

Precise keys matter for Qwen2.5. Qwen3 has more options.

Asymmetric KV is useful when compressing keys damages quality. On Qwen2.5-7B-Instruct, keeping keys precise avoids a severe math and retrieval failure under both tested scaling policies. On Qwen3-8B, symmetric FP8 remains a credible alternative: it saves more memory and passes the reference test for average math accuracy. These results do not establish a general asymmetric quality or speed advantage across models.

What the matched comparisons establish · GSM8K counts are out of 1,319
Model / executionObserved resultPractical interpretation
Qwen2.5-7B-Instruct BF16 · referenceNative: 1,211 correct. K16/V8: 1,207–1,208. K8/V8: 6–11. Key-quantized recipes also fail 8K retrieval.Strong reason to retain precise keys in these recipes. K16/V8 stays close to native, but its uncertainty bounds miss the full quality limits. It is a promising candidate, not a fully qualified deployment.

Qwen2.5-7B-Instruct has not appeared in OpenRouter’s daily text top 50 since November 10, 2025. We checked through October 22, 2026. It may still receive traffic below the top 50. See the Qwen2.5 usage analysis →

Qwen3-8B FP16 · reference · dynamic scalesK16/V8 and K8/V8 both pass the average-accuracy, prediction-loss and retrieval limits. Cache backing falls 24.22% and 48.44%, respectively.Symmetric FP8 is the better memory option under that objective. Asymmetric meets the separate answer-preservation requirement; symmetric is not qualified under that requirement. No direct math-accuracy advantage is established.
Qwen3-8B FP16 · actual serving workersFixed K16/V8 passes answer preservation against both native backends and saves 25% of cache backing. Dynamic K8/V8 works and saves 48.43%.Asymmetric is qualified for answer preservation. Neither compressed worker clears the average-accuracy bound against both controls. The new serving-speed comparison did not run.

Why the quality verdict depends on the objective: answer preservation bounds how many previously correct answers become wrong (at most 2% of all questions). Average accuracy allows gains to offset losses and must rule out a drop larger than one percentage point. Both include prediction-loss and retrieval checks. These are different requirements; neither is always stricter. Missing a confidence bound does not by itself prove worse quality.

Coverage: seven cache/scaling configurations ran on each of two checkpoints from the Qwen family. Only Qwen3-8B received the new actual-worker comparison. These panels do not establish a ranking across model families or a serving-speed winner. Exact coverage and remaining comparisons · Worker counts and memory · Reference results →

Measured inference value

Cache savings and speed are separate results.

The key/value (KV) cache stores information from previous tokens. Keys determine what attention selects; values supply the selected information. K16/V8 keeps keys at 16 bits and stores values at 8 bits. Model weights are separate: INT4 weights do not imply an INT4 KV cache.

Three cache formats

Payload only · equal token slots · lower is smaller

Native K16/V16100%
K · 16 bitV · 16 bit
Asymmetric K16/V875%
K · 16 bitV · 8 bitsaved
Symmetric K8/V850%
K · 8 bitV · 8 bitsaved
Equal-sized K/V tensors: 4, 3 or 2 bytes per element pair. This illustration excludes scales, recurrent state, weights and temporary buffers. Quality must be checked for each format. Measured state sizes ↓

In-process batch throughput

Qwen3-8B · 8K input · batch 32 · 128 output tokens

INT4 AWQ weights+3.45%
Dense FP16 weights+3.55%

Both pass the tested quality gates. AWQ is activation-aware weight quantization; this checkpoint stores packed INT4 weights.

One H100, FP16 compute. Gain versus each weight format’s native FP16 K/V FlashInfer control. These are complete-request batch measurements, separate from HTTP serving. Exact results and controls →

HTTP serving: a smaller gain, with limits

Dense Qwen3-8B passes the HTTP worker’s quality checks at 1K and 8K input. At 1K with 32 requests in flight, throughput improves 1.01% versus native FlashInfer. A gain versus native FlashAttention 3 (FA3) is not established. Request concurrency is not the GPU batch size.

At 8K, observed throughput increases do not qualify as a confirmed serving gain: 12 requests failed across the three arms. At the shared 2.9 requests/s offered load, p95 request latency is 4.34% higher than FlashInfer and 12.65% higher than FA3. Higher latency is slower; p95 is the 95th percentile.

HTTP tests use equal cache byte budgets, giving K16/V8 more token slots. They do not demonstrate a 25% reduction in whole-GPU memory or a general latency improvement. Throughput, time to first token, time per output token, failures and reproduction →

Choosing the precision · Qwen3.8 and Gemma 4

Symmetric FP8 is the stronger memory candidate for Qwen3.8.

Both K16/V8 and K8/V8 pass Qwen3.8-27B’s quality checks, while K8/V8 saves twice as many state bytes. Gemma 4 26B-A4B passes math and retrieval with both formats, but neither meets every prediction-loss limit. These are quality and physical-storage results; serving speed was not tested.

Qwen3.8-27B

Both compressed formats pass all quality gates

Native BF16 K/V595.75 MiB
Reference size
K16/V8467.78 MiB
21.48% less persistent state
K8/V8339.81 MiB
42.96% less persistent state
Scales and unchanged recurrent state are included. Recurrent state reduces the percentage saving: K16/V8 saves 11.99% at 1K input and 21.48% at 8K.

Gemma 4 26B-A4B

Neither compressed format passes all quality gates

Native BF16 K/V362.30 MiB
Reference size
K16/V8272.83 MiB
24.70% less persistent state
K8/V8183.35 MiB
49.39% less persistent state
K16/V8 misses the 1K prediction-loss bound; K8/V8 misses the 1K and 8K bounds. This does not prove general quality harm or a difference between candidates.

Measured after 8,192 input + 128 continuation tokens, with original BF16 weights and compute. Here K16 means BF16; the optimized Qwen3 recipe uses FP16. Each model’s bars are scaled to its own native state size. Sizes include FP32 scales; weights, temporary reconstruction and allocator reservations are separate.

Every arm ran all 1,319 GSM8K math questions, retrieval at 1K and 8K, and prediction-loss checks. The direct math comparison does not establish an accuracy advantage for either compressed format. Passing these tests is not a guarantee for every task.

Why this does not transfer automatically to the optimized stack

The reference uses a separate dynamic scale for each token and attention head. It stores real FP8 tensors, then temporarily reconstructs BF16 inputs for attention. The optimized Qwen3 asymmetric recipe uses calibrated fixed scales and direct mixed-precision decode. Dynamic symmetric FP8 also has verified Qwen3 worker support, with its own quality results. The precision/scaling experiment controls these choices within Qwen3-8B and Qwen2.5. Reference results alone do not establish serving performance or transfer support to another model.

Full quality results, state breakdown and reproduction →

Optimized stack compatibility

Start with the qualified Qwen3 recipe.

A quality pass covers the tested prediction-loss, retrieval and full GSM8K math checks. It does not establish universal accuracy.

Qualification belongs to a model, precision and execution path
Model / weightsQualityPerformance
Qwen3-8B · dense FP16Batch and HTTP passBatch gain; HTTP tradeoffs described above
Qwen3-8B · INT4 AWQBatch passes; HTTP preservation not establishedBatch gain; no HTTP confirmation
Phi-4 · FP16Model-transfer checks passNo confirmed speed gain
Ministral 3 8B · FP16Primary preservation not establishedNo performance confirmation
Qwen3.5-9B / Gemma 4 12BAsymmetric layout unsupported in the tested stackNative capability checks only

The Qwen3.8-27B and Gemma 4 26B-A4B reference results above do not qualify these models for the fused stack. Unsupported layouts are not measured quality failures. Quality counts, limits and model details →

How it works

Keep the compressed cache through decode.

Optimized Qwen3 path · FP16 K / FP8 V

Keys · FP16Values · FP8

Fresh prefill

Gather eligible pages into bounded FP16 staging.
Run native FA3 prefill.

Decode

Read FP16 keys and FP8 values directly.
Apply frozen value scales.

Staging is reused across layers. Casting values back to FP16 preserves quantization error; it does not recover discarded precision.

The optimized vLLM route also handles fresh whole prompts when other requests are decoding. The measured 8K batch improvement comes from the complete request path, including prefill routing; it does not establish a faster decode kernel. Routing diagram and fallback details →

Install and run

Install the tested batch recipe.

Use Linux x86-64, a CUDA 12.9 development environment, at least 100 GB system RAM and 100 GB free disk. Install Git, a C/C++ compiler and uv 0.8.17 using the complete setup instructions. The installer selects exact fork commits, checks the base wheel and records a package lock. No LMCache or private inputs are required.

git clone https://github.com/mcgrof/knlp.git
cd knlp
git switch main
export FLASHINFER_WORKSPACE_BASE="$PWD/stack/jit"
uv run --python 3.12.11 --no-project \
  -m tools.kv.native.october_setup "$PWD/stack" --recipe current
export KNLP_KV_FIXTURES=/path/to/experiment-inputs
stack/env/bin/python -m tools.kv.native.current download \
  --format awq --output awq-download.json
stack/env/bin/python -m tools.kv.native.current smoke \
  --install "$PWD/stack" --format awq --output awq-smoke

Fresh H100 installation passed for AWQ and dense FP16. Both selections passed sequentially on October 19, 2026, using installer 5a3d9d74. See the receipt and setup/check times.

The check loads the supplied calibrated scales before graph capture, generates a finite answer and verifies mixed prefill/decode admission, physical storage, changing graph inputs and memory accounting. A successful run writes receipt.json with "passed": true. Use --format fp16 in both commands for the dense selection, after the first process exits.

PASS: physical K16/V8; calibrated scales; mixed fresh-prefill route; changing decode graphs; clean memory; finite deterministic generation

This tries and validates the feature. To reproduce the numbers, use the frozen inputs, measured harness revisions and full protocol. The quick-start check is not a benchmark. Public model downloads need no token; optional authentication uses hf auth login.

Integration status

FlashInfer first, then vLLM integration.

vLLM upstreaming waits for the FlashInfer asymmetric K/V capabilities it uses to merge. The tested recipe is available now through pinned public forks. LMCache storage work can proceed in parallel. Status checked October 19, 2026.

Serving dependencies and the separate LMCache storage series
ComponentStatus / next dependencyCode and tracking
FlashInfer attention kernelsAsymmetric K/V support is under review. The open decode PR covers part of the required support.PR #3812 · tested fork
vLLM serving integrationWaiting for the required FlashInfer support to merge before upstream integration.Tested fork · 276305b
LMCache split K/V SerDesMerged June 16: separate key/value serialization and deserialization. This is the foundation, not full MP-mode placement.PR #3277
LMCache multi-process (MP) supportPrerequisite fixes, then typed dispatch, split-tier placement and FP8 byte-through storage.Issue #3710 · fixes PR #5502

See the itemized PR series, seven fixes, branch links and dependencies →

LMCache is optional for the current resident-GPU batch recipe. Full FP8 byte-through serving requires a matching vLLM/FlashInfer producer; the storage code can be reviewed independently.

Inspect and reproduce

The evidence, one level deeper.

Reference model comparison: Qwen3.8-27B and Gemma 4 26B-A4B →