feat: add paged-attention monolithic decode-only AR foundation - #555
feat: add paged-attention monolithic decode-only AR foundation#555Graffioh wants to merge 3 commits into
Conversation
5f7b111 to
e5027ab
Compare
e5027ab to
5ff3bf7
Compare
51dda8f to
1a2e479
Compare
There was a problem hiding this comment.
All reported issues were addressed across 28 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
2a36448 to
f1851f9
Compare
| committed++; | ||
| cache_.cur_pos = committed; |
There was a problem hiding this comment.
the first emitted output token from prefill writes KV row only during the subsequent forward (that's right)
BUT here on the first decode step, we increment committed by 1, even though for cache we are still considering the first emitted token from prefill, leading to a gap of 1
was there a reason for this?
(in case this needs to be fixed also in other model's backend)
235ef11 to
f5a1078
Compare
|
|
||
| namespace dflash::common { | ||
|
|
||
| constexpr int PAGED_BLOCK_SIZE = 16; |
There was a problem hiding this comment.
we want this as user options or we fix as 16? (vllm default)
593b41b to
0efc8ee
Compare
| } | ||
| std::printf("[target] %s\n", dflash27b_last_error()); | ||
| if (cfg_.paged_attention && | ||
| (w_.n_embd_head_k != 256 || w_.n_embd_head_v != 256)) { |
There was a problem hiding this comment.
for now kernel impl and optimizied for kv head dim 256 but must be generic somehow
0efc8ee to
424c6c7
Compare
Add the paged KV allocator, ggml operator metadata, CUDA/HIP kernel, host allocator coverage, direct device tests, and benchmark target as one independently buildable low-level foundation.
Wire paged cache allocation and metadata into monolithic Qwen decode, centralize launch compatibility in the feature gate, preserve tensor-parallel initialization from current main, and cover the new configuration and pool-sizing rules.
Document the paged-attention architecture, validation matrix, benchmark procedure, and recorded CUDA/HIP performance independently from the implementation commits.
424c6c7 to
be8a8cf
Compare
Summary
GGML_OP_PAGED_ATTNdecode op for D=256 GQA with F16, Q4_0, and Q8_0 K/V.exp2fsoftmax; Q quantized once per step by a pre-pass; partition partials stored normalized in f16 (half the scratch traffic); occupancy-aware context partitioning with a stable split-softmax merge.--paged-attention(one CUDA or HIP device).Scope
Paged K/V is the memory-management foundation for heterogeneous 4–8-user serving. This PR establishes exact single-request Qwen integration and a multi-sequence GPU primitive first, following the block-table design in ggml-org/llama.cpp#21961.
HTTP integration stays one active sequence: Qwen3.6's Gated DeltaNet conv/SSM state is backend-global and the worker is run-to-completion. Sequence-indexed recurrent state, batched decode, and a continuous-batching scheduler are follow-up work. The primary benefit is memory capacity and request-lifecycle flexibility; the benchmarks below measure attention operations, not whole-model tokens/s.
Opt in with
--paged-attention. Unsupported combinations fail explicitly. Requests reaching--max-ctxfinish cleanly.Benchmark results
Qwen attention dims (
D=256,Hq=24,Hkv=4). Single metric:paged ÷ contiguous throughput— above 1.0x = paged faster.Uniform batches (identical context per sequence, Q4_0 K/V, batches 1/2/4/8)
Both rows reflect the reworked kernel. Measured on the same GPUs, the pre-rework kernel gave 0.46–0.77x on CUDA and 2.06–2.92x on HIP, so the rework is worth roughly 1.5–2.6x on CUDA and 1.3–2.3x on HIP in absolute paged step time. The HIP ratios are inflated by a weak native HIP
flash_attn_ext_vecbaseline — don't extrapolate them to whole-model throughput.Ragged 8-request workload (
128K + 7 × 8K, Q4_0 K/V)Standalone synthetic multi-sequence kernel benchmark (constructs the interleaved block table directly; does not use
PagedKvPoolor demonstrate concurrent requests — the server integration remains single-sequence). Paging stores only live, block-rounded tokens (188,416) instead of padding every sequence to 128K (1,048,576 slots).Small-context ragged batches (e.g. 4K + 7×256) remain behind contiguous: short sequences carry dead partitions sized by the longest sequence. The stream-K/persistent-kernel rework staged with continuous batching addresses this.
K/V capacity (projection over Qwen3.6's 16 full-attention layers from the one measured layer; excludes weights, activations, recurrent state):
→ 5.57x less K/V (82.03% saving), now alongside faster attention on CUDA rather than at its expense.
Roadmap
ggml_paged_attn, block manager, CUDA/HIP integration, benchmarks.Validation
DFLASH_QWEN35_NO_KVPAD=1dense, and paged vsGGML_CUDA_PAGED_ATTN_FORCE_PARTITIONS=1paged), so divergence is greedy argmax FP chaos, not a kernel defect. All checkable answers correct; paged output run-to-run deterministic; decode tok/s at parity.paged_kv_poolpasses, and the full 4K/32K/128K plus ragged benchmark matrix completed. Note the native HIP contiguous path's own oracle error reaches 3.3e-3–4.5e-3 at long context (near the benchmark's 5e-3 gate) while paged stays at ~5e-6, so paged is also the numerically better path on this backend.git diff --checkpasses.🤖 Generated with Claude Code
https://claude.ai/code/session_01Vkkox5Yo66K2Rn1oPuVoX7