Repository navigation
feat(rdna2): add LeapQuant GDN state with 512-token pages - #168
Conversation
…_LEAPQUANT) Port of LeapQuant (arXiv 2609.38166, vllm#64725) to the RDNA2 GDN path: the FP32 [V, K] state per value head becomes a 28,768-byte blob (INT8 residual + rank-4 FP16 compensator + FP16 per-token records, window 16). MTP verify commits accepted records instead of per-token state copies; align-mode prefix-cache copies commit bias + 1 records in the HIP copy kernel. Default off; gfx10x only. decode_kl.py: decode-path top-k KL between served configurations. Signed-off-by: BlivionIaG <kev29lt@gmail.com>
mono_gdn_lq_rdna2 is the fused mono GDN launch (conv + delta rule + gated norm) with the LeapQuant blob load/append in place of the FP32 state load/store; gdn_lq_normalize_rdna2 commits the accepted records first. The flag no longer refuses --monokernel, and the FP32 Triton decode warmup is skipped under the flag (it never runs there). Shared blob layout moves to gdn_leapquant_layout.cuh. decode_kl.py accepts a /v1/completions URL. Signed-off-by: BlivionIaG <kev29lt@gmail.com>
All LeapQuant GDN layers normalize with the same state indices and accepted counts each step, so the first layer of the model now normalizes every layer's paged blobs in one launch (gdn_lq_normalize_rdna2 gains an optional layer_offsets [layers] table, grid.y = layer; the group is rebuilt on bind_kv_cache, never under capture) and the other layers skip. Decode arenas stay per layer. Replaces 36 launches (~3 us each) and lets the folds of all layers run concurrently instead of one layer after the other. The record replay loops unroll by 2 (same arithmetic order). Per step, 36 layers, one V620, HIP graph (FP32 MonoKernel -> LeapQuant before -> after): decode n=1 343 -> 574 -> 361 us, verify n=1 ~500 -> 867 -> 582 us, decode n=8 1556 -> 1345 -> 1134 us, verify n=8 3323 -> 2217 -> 1851 us. test_grouped_normalize_matches_per_layer: same bytes as per-layer normalize, folds and NULL slots included. Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…yer group Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…he group Hybrid models spread their GDN layers over several KV-cache groups, each with its own block table, so a request sits at different state slots per group. The grouped normalize (8ba674a) let the first GDN layer of the model normalize every GDN layer at its own group's slots: the other groups' layers committed records at foreign slots and never at their own. On flashnext-mtp2 (6 KV-cache groups) decode fell into repetition loops (10-21 of 32 outputs at c=8 vs 2-7 for the base) while prefill KL and PPL stayed inside the floor. Groups are now built per KV-cache group in bind_kv_cache_to_layers, next to share_replayssm_ring_trackers (same namespace rule); without the group map every layer keeps its own launch. Signed-off-by: BlivionIaG <kev29lt@gmail.com>
Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…ip ci] Signed-off-by: BlivionIaG <kev29lt@gmail.com>
… ci] Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…ffs [skip ci] Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…k pause [skip ci] Signed-off-by: BlivionIaG <kev29lt@gmail.com>
Signed-off-by: BlivionIaG <kev29lt@gmail.com>
|
ITL optimization priorities (recommendations, not implemented or GPU-qualified):
No new GPU tests were started. Full acceptance/quality and 512 ABBA gates remain paused. |
Signed-off-by: BlivionIaG <kev29lt@gmail.com>
Signed-off-by: BlivionIaG <kev29lt@gmail.com>
|
Two fixes are now pushed:
The window-32/512-page candidate passes 22 GPU lifecycle tests. Its first full live run confirms recovery from a 64-token cap to 2048, zero preemptions/evictions/faults, and unchanged MTP2/FULL_AND_PIECEWISE. The earlier latency-cap trial is rejected (self-locked fitter, plus an overlong quiet window), not counted as a qualified result. Still draft: repeating the repaired candidate and baseline before accepting performance/acceptance and the corrected decode-quality comparison. The reference incurred 14 preemptions; they are retained as reference behavior, while the candidate is still required to have zero. |
Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…indow 32, MTP2, F&P) Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…rs and docs [skip ci] Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…=1 and c=8 [skip ci] Signed-off-by: BlivionIaG <kev29lt@gmail.com>
…st [skip ci] Signed-off-by: BlivionIaG <kev29lt@gmail.com>
Summary
LeapQuant stores each Gated DeltaNet (GDN) recurrent state as a small INT8 blob
instead of FP32 (arXiv 2609.38166,
vllm#64725).
It is opt-in (
VLLM_RDNA_GDN_LEAPQUANT=1), lossy, and gfx10x only.The default stays FP32 with 1024-token blocks.
MTP2, MonoKernel, FULL_AND_PIECEWISE and prefix caching stay enabled.
All LeapQuant ops are HIP. No Triton path is added.
Status: ready for review. The matrix is in (see Matrix). Two gates are not met; the owner accepted the 1k c=1 loss.
This description makes no speed or accuracy claim yet. The speed and trade-off
conclusions will be written from the full matrix. The table below is earlier
qualification data, kept as measured numbers only.
How a step works
flowchart LR P[Prefill chunk] -->|materialize blob to FP32,<br/>run HIP prefill, store back| B[(Blob in<br/>home block)] B --> N[Normalize: commit accepted records,<br/>fold when 32 records exist] N --> D[Decode or verify:<br/>read blob and replay records] D -->|append records,<br/>set pending| B(vLLM puts the 36 GDN layers in 3 groups. Each group has its own block table.)
Page layout (MTP2, 512-token block, per rank)
The FP32 state is 64 KiB per head. The blob is 1.77x smaller.
KV capacity goes from 266,945 to 273,456 tokens (+2.44%). This is not a 2x gain.
Changes
and every in-flight verify batch. Two unresolved prefills can retain five
pages. Decoders go first (FCFS). No speculative slot or checkpoint is removed.
buckets, refit the slope when the intercept is negative.
No sleeps, no watermark increase, no artificial decode-only cadence.
still shared). Boundary regressions and CPU CI wiring added.
flashnext-leapquant-mtp2(see Use).Qualification runs
Two baseline and two candidate boots, bracketed (A1, C1, C2, A2), with one
rejected diagnostic (B1) between A1 and C1. This is not uninterrupted ABBA.
These runs came before the full matrix. They cover only the cells listed.
Setup for all runs: Flash-Next AWQ, MTP2, MonoKernel, FULL_AND_PIECEWISE, TP4.
mixed-step budget, decode share 0, max overhead 1.
The explicit T0 cell is greedy. Coding requests use the real thinking chat
template and API seed 12345.
Rates are tok/s. Rate and latency columns are means of two boot summaries.
Acceptance pools
1 + accepted/draft_steps. PP/req = input tokens / mean TTFT.PP wave = effective concurrent wave / p99 TTFT (not a separately timed GPU prefill).
TG/req = 1 / mean TPOT.
Matrix (four boots: A1 FP32, C1 LeapQuant, C2 LeapQuant, A2 FP32)
Same build and protocol for all four boots: TP4 on V620, MTP2, MonoKernel, FULL_AND_PIECEWISE,
16 requests per cell, random prompts, ignore EOS, T1 / top-p 0.95 / top-k 20. FP32 uses block 1024
(the default flash-next recipe); LeapQuant uses
flashnext-leapquant-mtp2(block 512). One boot perarm and cell, so each range is two single boots. c=4 is not in this matrix.
PP/req and the full per-boot table are in
bench_results/2026-11-14_leapquant-matrix/.What the numbers show:
Verification
group normalization, prefix precopy, graph replay, MonoKernel.
regressions fail before the repair and pass after it.
corruption-detector flags. Coding output is not scored for correctness.
(97.8% probability mass): head 0.01398, floor 0.01262, ratio 1.107,
95% bootstrap interval [0.836, 1.317], below the 1.5x threshold.
This applies to these four boots only. It is not a full-trajectory or
universal accuracy guarantee.
zero-preemption gate applies to candidates only).
The repaired C1 run recovers 64 -> 2048 tokens without waits.
claimed fixed. The whole compatibility suite is not claimed green.
Merge gates
rdna_extrasis greenThe two unmet gates are accepted by the owner (2026-11-14): the 1k c=1 loss is the cost of the recipe.
Use
The recipe sets LeapQuant on, 512-token blocks, MonoKernel, MTP2,
FULL_AND_PIECEWISE and the 450 ms budget.
flashnext-mtp2is unchanged(LeapQuant off, 1024-token blocks).
Record:
docs/rdna2/leapquant-gdn-2026-11-13.md.Machine-readable data:
bench_results/2026-11-14_leapquant-acceptance/.Raw traces stay on the build box in
~/w4a8_runs/leapquant/.Packing two LeapQuant layers per page is a separate second PR.
Credits
Yi Pan, Haocheng Xi, Kan Zhu, Xingyang Li, Yibo Wu, Mayank Mishra,
Hongtao Zhang, William X. Zheng, Baris Kasikci, Song Han, Kurt Keutzer,
Rishabh Iyer, Ion Stoica.
(vllm#48018,
vllm#62004 by Johnny-Liou).
The GDN decode kernel of [Kernel] ReplaySSM: cache SSM inputs for faster Gated DeltaNet standard decode vllm-project/vllm#62004 is not in this tree.
by lihaoyang-amd. It has no source code, and none is used here.
original work for this fork. Existing files keep their upstream authors in git history.