Repository navigation
[K1] Add KV-cache declarations for CPU/GPU memory planning - #34113
Chi Lo (chilo-ms) wants to merge 11 commits into
Conversation
Add strict declaration parsing, graph-derived GQA state resolution, and capacity/alias projection into S0. Document the owner-to-ORT workflow and distinguish contract helpers from future placement, admission, and owner integration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c132130a-b0c7-422c-9ff7-75826b6ea3fc
Extend the version-2 contract with PagedAttention pool and block-table declarations, checked physical backing bounds, and focused regression tests while preserving dense version-1 behavior. Condense the workflow document and distinguish declaration/accounting helpers from future runtime integration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c132130a-b0c7-422c-9ff7-75826b6ea3fc
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5170d5a1-509e-4b08-b4f8-241666469dd0
Record the reported GPT-OSS-20B capacity comparison and transfer/backing savings while separating the prototype's workload and correctness limits from K1 integration claims. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5170d5a1-509e-4b08-b4f8-241666469dd0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5170d5a1-509e-4b08-b4f8-241666469dd0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5170d5a1-509e-4b08-b4f8-241666469dd0
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved validation gaps accept unsupported dense GQA cache configurations and incompatible shared block-pool capacities, risking runtime failures or aliasing of independent state.
4 open issues
What changed in this PR
Adds the internal K1 KV-cache declaration contract on top of S0 capability planning, preparing ONNX Runtime for bounded CPU/GPU memory planning without enabling session integration or allocation.
Changes:
- Adds versioned parsing, graph resolution, and checked backing bounds for dense and paged caches.
- Extends planning queries with cache capacity shapes, workload bounds, and input/output alias facts.
- Adds validation tests and documents the contract, proposed owner workflow, and integration boundaries.
| File | Description |
|---|---|
| onnxruntime/test/framework/declared_state_test.cc | Tests parsing, resolution, backing bounds, and atomic projection. |
| onnxruntime/test/framework/capability_planning_test.cc | Tests alias validation and query snapshot binding. |
| onnxruntime/core/framework/declared_state.h | Defines declaration contracts and helper interfaces. |
| onnxruntime/core/framework/declared_state.cc | Implements parsing, resolution, backing calculations, and projection. |
| onnxruntime/core/framework/capability_planning.h | Adds per-port input/output alias constraints. |
| onnxruntime/core/framework/capability_planning.cc | Validates alias values and duplicate pairs. |
| docs/annotated_partitioning/declared_state_contract.md | Documents K1 schemas, accounting, workflow, and scope. |
| docs/annotated_partitioning/capability_planning_interfaces.md | Documents alias semantics and K1 projection into S0. |
Review effort: Balanced
Add dedicated declaration and support APIs, immutable options snapshots, refreshed session planning facts, and focused integration tests. Native build/runtime validation is delegated to CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79471f9a-ddf9-4874-8c41-81656c41b6c7
Address review feedback for dense quantization, one-sided cache pairs, mismatched identical-storage K/V shapes, and shared block-table coverage across pool lifetimes. Add six regression cases and use portable SAL annotations consistently for the new session setter. Native build/runtime validation remains with CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79471f9a-ddf9-4874-8c41-81656c41b6c7
Correct the environment-map initializer that selected the iterator-range constructor across native and WebAssembly toolchains. Exclude unsupported K1 ownership state from minimal builds while preserving full-build declarations and public API stubs; leave the Android binary-size threshold unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79471f9a-ddf9-4874-8c41-81656c41b6c7
|
Pushed 7849a38 to address the CI failures:
Native compilation and the resulting binary size still need confirmation from the new-head CI; no local native build was run, as requested. |
Use noexcept status creation for fixed-message argument validation. Keep exception translation only around full-build contract parsing and ownership, preserving null-argument errors and unsupported-build semantics without unnecessary minimal-build string allocation. Leave the Android size threshold and the unrelated timed-out Windows CMake probe unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79471f9a-ddf9-4874-8c41-81656c41b6c7
|
Follow-up in 41afd00: fixed-message argument validation now calls noexcept status creation directly, avoiding temporary strings in minimal-build K1 stubs. Exception translation remains around supported contract parsing/ownership. API errors, public slots, and the Android size threshold are unchanged; CI must confirm the new size. The Windows release failure at 7849a38 was |
After excluding unsupported K1 session ownership and temporary-string allocation, CI measures 1,611,898 section bytes. Raise the 1,611,802-byte limit by exactly the remaining 96 bytes for the required public API slots and nonthrowing unsupported-build stubs, with no additional headroom. The latest main baseline is 1,611,570 bytes; K1 parser and session integration remain unsupported in minimal builds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79471f9a-ddf9-4874-8c41-81656c41b6c7
|
Pushed 8847cef for the last measured minimal-size blocker. Removing unsupported ownership state and temporary-string allocation saved 576 section bytes; the required public API slots and nonthrowing NOT_IMPLEMENTED stubs remain. CI now measures 1,611,898 bytes, so the Android threshold is rebaselined from 1,611,802 by exactly 96 bytes, without extra headroom. The latest passing main baseline is 1,611,570 bytes. The other failures on 41afd00 were infrastructure/setup failures: Windows NuGet installation hit TLS EPROTO, and Detox failed terminating the not-yet-installed iOS simulator app before tests. No unrelated source changes or old-head reruns were made. Fresh-head CI will validate this adjustment. |

Description
Adds the K1 KV-cache declaration contract and session integration for CPU/GPU memory planning, following the merged S0 protocol (#33841).
com.microsoft::GroupQueryAttentionpairs and unquantized FP16/BF16SEPARATEPagedAttentionpools with shared int32 block tables. Checked backing bounds include whole pools, unique tables, alias policy, lifetime, and resident multiplicity without speculative prefix-sharing credit.GetDeclaredStateSupportpositively negotiates supported declaration schema versions;SessionOptionsSetDeclaredStateContractparses/copies JSON before session creation. Corresponding C++ wrappers are included. APIs are appended without changing shipped slots or bumpingORT_API_VERSION.SessionStateretains resolved byte/alias/geometry/lifetime facts and checked backing bounds with session-scoped graph identity and advancing revisions. Failed refreshes invalidate current metadata and fail initialization; unsupported subgraphs or transformed-away cache wiring do not produce stale/partial facts.past_presentK/V capacity shapes, and shared tables whose common block-ID range cannot cover all resident pools. Six regressions also preserve stateless GQA, disjoint-capacity bounds, declaration-order independence, and valid mixed-lifetime pools._In_reads_annotation for itscharbuffer in public/internal declarations and implementation; the API signature and byte-length semantics are unchanged.See the contract/workflow document.
Scope boundary: support negotiation advertises declaration transport, resolution, and retention only, not budget admission or bind-time enforcement. This PR does not adapt C1/C2 estimators, charge declared backing to the existing accountant, pass S0 queries into EP callbacks, select/commit a CPU/GPU cut, allocate/move KV, enforce resident-instance/Run-time envelopes, or wire GenAI/model-package producers.
session.declared_stateis not registered or consumed; use the dedicated API.follow_consumerremains the only location policy. Paged declarations do not add CPU kernels or prove provider/kernel eligibility. Sessions without a dedicated declaration retain legacy behavior.Motivation and Context
Related to the K-track in #33372. The planner needs bounded external-state requirements before owner allocation, independent of whether GenAI, an external harness, or ORT owns KV.
This extension makes K1 an explicit session feature rather than a helper-only contract or an arbitrarily accepted configuration key. It supplies stable resolved facts for the remaining C1/C2/M2/R3/I1/I2 integration. GenAI's separate dense per-cache colocation work is microsoft/onnxruntime-genai#2959; placement discovery/colocation alone is not admission.
Complete future handshake: owner declares before session creation -> ORT resolves and commits a budget-feasible placement -> owner queries each cache's required location -> allocates/binds colocated backing -> ORT enforces the binding contract before execution. Only transport, resolution/retention, bounds, and projection are implemented here.
KV-colocation experiment: performance and transfer savings
The reported GPT-OSS-20B v1 mixed CPU/GPU experiment kept GQA layers 12-15 on CPU, with MoE and projections on GPU. For the same mixed-placement cut:
At 32,768 capacity, colocation gave a 6.8x speedup over the same CPU cut with GPU-resident KV, eliminating 512 MiB of KV transfers per token and moving 256 MiB of KV backing off GPU. GPU-only execution remained faster at 10.39 ms/token: colocation reduces offload's transfer cost; it does not establish a performance advantage over GPU-only execution.
Scope of the result: synchronized capacity measurements with a 99-token prompt and 64 decode steps, not 32K active-context inference. The two KV layouts produced bit-identical logits and unforced generation for the same mixed-placement cut. CPU-versus-GPU compute differed in one top-1 prediction out of 65, so cross-device compute equivalence is not certified. This is separate prototype evidence, not K1/GenAI integration validation or an admission guarantee.
Validation
Native build/runtime validation is delegated to CI, as requested. The previous helper-only head completed its checks; those results are not claimed for this session-integration extension. No local native build/test pass, CUDA execution, placement/admission execution, or real-model K1 validation is claimed.
CI on the initial session-integration head found the undefined
_In_reads_bytes_annotation on non-MSVC compilers. This follow-up replaces it with the portable existing annotation; native results for the new head remain pending CI.Local checks completed in an isolated environment before committing:
Results: lintrunner passed for all five C++ files changed by this review follow-up; diff whitespace checks passed. The initial session-integration changes separately passed lint for 13 C++ files.
Focused native filter for
onnxruntime_test_all:This selects 40 declared-state/API/session cases plus 10 S0 protocol cases. New-head CI results are pending; a push starts fresh validation without re-running old-head workflows.