feat: native-paged decode CUDA graphs - #182
Open
drunkcoding wants to merge 26 commits into
Open
Conversation
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Contributor
Author
|
Momus plan review: [OKAY] on the first review round. |
Introduce PagedKVStorage as the single authoritative owner of block allocation and per-layer native K/V tensors. Bind PagedKVCache and PagedAttentionBackend to one instance, add an exact-type Qwen3 paged attention registry that classifies DeepSeek V2/V3 MLA as unsupported, and add an allocation-free current-token KV writer. Ultraworked with Sisyphus
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Make serving-engine graph cleanup idempotent so replacement and shutdown cannot leak scratch reservations. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Order active steps, graph invalidation, replacement, and application shutdown under one lifecycle lock. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Report graph private-pool bytes and authoritative scratch reservations separately from existing memory budgets. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Publish bounded capability, proof coverage, storage ownership, and graph memory state in engine statistics. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Expose fixed-name graph counters and gauges while restricting fallback labels to the enumerated reason set. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Pass typed graph-safety evidence separately from the lower-level offload engine and fail closed when omitted. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Expose disabled-by-default batch, context, warmup, and memory controls through both server initialization paths. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Keep full bucket logits inside capture and verify real-row slicing, metadata updates, fixed devices, and per-layer KV persistence on CUDA. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Build a persistent two-layer Qwen3 fixture with one authoritative storage owner and native paged attention. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Record paired raw CUDA timings, launch profiles, replay coverage, memory, capability proof counts, and KV checksums without a speedup threshold. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Keep explicit CUDA indices intact on CPU-only gate hosts so storage and runner mismatches fail closed. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Adopt authoritative storage only from the concrete native paged backend, preserving legacy eager engines and mocks. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Document native-Qwen3 eligibility, bounded monitoring, paired qualification, staged rollout, and immediate rollback without a speedup claim. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Verify resident non-paged and offloaded runtimes never capture, including immediate kill-switch precedence. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Record raw eager-only samples and zero graph activity when real loaders report unsafe decode graph capability. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Use frozen per-layer registration evidence instead of class-name heuristics when splitting mixed batches. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Fail configuration validation rather than treating a negative private-pool budget as unlimited. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Accept the explicit decode graph capability provider added to both server initialization paths. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Contributor
Author
|
Implementation completion update (
PR remains draft; no merge/ready/force operation was performed. |
added 2 commits
August 29, 2026 14:20
Defer the BlockAllocator import into PagedKVStorage.__init__ so importing moe_infinity.runtime.paged_kv_storage (or any module that pulls it in, e.g. the paged KV write kernel and attention registry) before moe_infinity.serving no longer triggers a partially-initialized circular import via serving/__init__ -> engine -> cuda_graph -> paged_kv_storage. Ultraworked with Sisyphus
All 12 tasks implemented, tested (RED/GREEN), and committed. Mark every plan step checkbox to reflect completed TDD work. Ultraworked with Sisyphus
drunkcoding
marked this pull request as ready for review
September 2, 2026 21:53
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.
Description
Opt-in decode CUDA graph capture/replay for resident ordinary-GQA Qwen3 native-paged attention only, integrated into active continuous-batching serving with explicit deny-by-default capability proof and eager execution as the authoritative fallback.
Full implementation of the Momus-approved plan in
docs/superpowers/plans/2026-08-21-decode-cuda-graphs.md(12 tasks, strict TDD).What changed
runtime/paged_kv_storage.py): onePagedKVStorageowns block allocation + per-layer native K/V tensors; bothPagedKVCacheandPagedAttentionBackendbind the same instance (owner-id enforced).models/paged_attention_registry.py): registers only exact-typeQwen3PagedAttention; classifies DeepSeek V2/V3 asmla_layout_unsupportedbefore anyhead_dimread; per-instance generated bound subclasses with uniquelayer_idx.kernel/paged_kv_write.py): writes per-layer K/V before decode attention; safe under graph capture.runtime/attention_types.py,serving/model_runner.py,runtime/model_offload.py,entrypoints/big_modeling.py): typedDecodeGraphCapabilitywith 15 fixed reasons; composed from runtime + backend + storage-identity + device-equality + per-layer write proofs.serving/cuda_graph.py): bucketed (batch,context) keys, lazy warmup/capture, scratch reservation from the authoritative allocator, capture-failure quarantine, per-batchMOE_DISABLE_CUDA_GRAPHSkill switch, exact device-equality gates, real-row-only replay slicing.serving/engine.py): pure decode routed through the runner only when eligible; mixed batches split eager-prefill + graph-decode + order-preserving recombine; sampler receives only real rows.serving/engine.py,entrypoints/openai/api_server_v2.py):invalidate_cuda_graphson reload, idempotentshutdown,_replace_enginecloses the old runner and releases scratch under a documented lock order.reasonlabels only.--enable-decode-cuda-graphsand bucket/warmup/memory flags; the enable flag never marks a runtime safe.benchmarks/serving/decode_cuda_graph.py,_fixture.py): paired eager/replay launch measurement;fixturemode needs no checkpoint;modelmode requires--model+--offload-dir; no speedup claim.docs/serving.mdanddocs/benchmarking.mdrollout, limitations, metrics, rollback.Scope / limitations (unchanged)
Offloaded MoE, FlashInfer plan path, DeepSeek MLA, prefill, and sampling remain eager/unsupported. No speedup is claimed or auto-enabled.
Verification
tests/python/serving: 214 passed.tests/python/serving/test_cuda_graph.py: 20 passed (CUDA equivalence runs on-GPU, no skips).MOE_DISABLE_CUDA_GRAPHS=1): passed, zero capture/replay.capability_reason=eligible, eager==replay, no speedup claim.python -m compileall: exit 0.Note: the single failing
test_mixed_batch_flashinfer_correctnesswas verified to fail identically at the plan base commit (dd83676) — a pre-existing FlashInfer environment issue (missing CUDA dev headers), not a regression from this PR.Type of Change
Checklist