4. Paged Attention Serving Integration
Date: 2026-06-10
Status
Accepted
Context
core/paged_attention/ provides block-level PagedKVCache and paged_attention_forward.
ContinuousBatchingEngine uses per-slot KVCache buffers with batch_indices for continuous batching.
Decision
- ServingConfig flags (
use_paged_attention,enable_prefix_cache) wire intoContinuousBatchingEngine.from_serving_config(). enable_prefix_cache:SlotPrefixCachereuses KV slots for identical prompt prefixes (implemented).use_paged_attention: InstantiatesPagedKVCacheand routes the model forward through it (MHA / block / DecoderModel / engine all wired).paged_kv_cacheparallel parameter: MHA / TransformerBlock / DecoderModel accept a parallelpaged_kv_cache: PagedKVCache | Noneargument alongside the existing linearkv_cache. When set, the linear cache is unused; the model writes K/V into the block allocator and reads viapaged_attention_forward. The decoder iterates layers and passeslayer_idx=iso MHA can slice the per-layer K/V tensor fromPagedKVCache.k_cache[i].seq_id == slot_id: the engine's existingSlotAllocatordoubles as the paged sequence identifier. Block tables live inBlockManagerkeyed by seq id, get cleared onpaged_kv_cache.free(seq_id)when a request finishes.
Consequences
Advantages:
- Prefix reuse reduces redundant prefill work today.
- Paged allocator + paged forward path are wired end-to-end; the
memory benefit is now realised when
use_paged_attention=True. - The Python-fallback
paged_attention_forwardgeneralises to multi-token q (prefill + decode share the same kernel). PagedKVCache.updatehandles both fresh allocation and existing-sequence extension, so the same call site works for prefill and decode steps.
Limitations:
- The paged kernel is a Python gather / SDPA fallback; for production
throughput, swap in a fused CUDA / Triton paged-attention kernel
(e.g.
flash_attn_varlen_funcwith block tables). Wiring is independent of that future optimisation. attn_impl='mla'supports the paged KV cache as of Tier 3 #31. The placeholder MLA caches K, V frominput_kv_projand runs the latent attention over the gathered cached context — the architectural benefit of per-position caching is limited (output is uniform-mean over latents) but the cache saves theinput_kv_projcost on incremental decode.SlotPrefixCacheoperates on dense slot buffers; the paged-side prefix-cache replay path (PagedKVCache.add_prefix+try_get_prefix_blocks) is not yet wired into the engine's_lock_step_pre. A follow-up slice.flash_attnrejectspaged_kv_cache(no paged kernel exposed); useattn_impl="mha"when serving with paged KV.