Add GQA workspace preparation recipes - #32446
Ti-Tai Wang (titaiwangms) merged 4 commits into
Conversation
Introduce graph-free checked workspace recipes for GroupQueryAttention preparation buffers, including windowed cache staging, compaction, sequence metadata, and QKV preprocessing layouts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b24d04bb-12ab-41a0-8941-76eb9769005d
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b24d04bb-12ab-41a0-8941-76eb9769005d
There was a problem hiding this comment.
🟢 Approval recommended
The implementation matches runtime allocation formulas and has comprehensive boundary and parity coverage.
Pull request overview
Adds graph-free CUDA GroupQueryAttention workspace recipes with checked sizing and validation.
Changes:
- Models staging, compaction, sequence metadata, and QKV preprocessing.
- Adds overflow, validation, layout, and runtime-parity tests.
- Verifies plugin-safe standalone header compilation.
No actionable issues identified.
File summaries
| File | Description |
|---|---|
group_query_attention_workspace.h |
Defines workspace recipe interfaces. |
group_query_attention_workspace.cc |
Implements checked sizing and validation. |
group_query_attention_workspace_test.cc |
Tests recipes and edge cases. |
group_query_attention_workspace_header_test.cc |
Verifies isolated header compilation. |
cmake/onnxruntime_unittests.cmake |
Adds the plugin header test. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Found one blocking issue: GetGQAPreparationRecipe accepts impossible XQA routes and may underestimate workspace ( group_query_attention_workspace.cc:127-166, 254-264 ). Runtime XQA requires decode with sequence_length == 1 , not first prompt, and either both caches unquantized or both K/V quantization types supported ( group_query_attention.cc:489-552 ). The recipe currently permits multi-token/first-prompt XQA and even tests asymmetric quantization ( K=PerTensor , V=None ) as valid. For packed multi-token input it returns Q-only storage, while the actual fallback route can require Q+K+V. I recommend validating those available XQA eligibility facts or representing this as preprocessing behavior rather than an XQA route. |
Reject route facts that cannot select XQA at runtime so preparation recipes cannot underestimate fallback QKV materialization. Clarify the graph-free workspace contract and cover invalid decode and quantization combinations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Fixed the blocking XQA-route validation issue in 02064f7. |
|
Chi Lo (@chilo-ms) PTAL |
|
• head_size ∈ {64, 128, 256} The recipe has both head_size and head counts available but does not validate these constraints ( group_query_attention_workspace.cc:167-190 versus group_query_attention.cc:547-568 ). The updated XQA tests even use head_size = 8 , so they validate routes that runtime always rejects. This can still underestimate preprocessing when actual dispatch falls through to a route such as MEA, particularly for packed QKV. |
Use one graph-free head and group-size contract in runtime dispatch and workspace validation, enforce cache representation for selected XQA routes, and test only runtime-reachable XQA fixtures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Thanks — this was correct. Fixed in c0dadf6. The fix is structural rather than another estimator-only copy of the constraints:
This prevents the preparation estimator from accepting a claimed final XQA route that runtime would fall back from and therefore underestimating fallback preprocessing. The same shared-predicate change is synchronized to #32453 (4ac4ce9) and #32454 (8fac283). |
b03fb52
into
microsoft:main
## Summary Stacked on #32446, add graph-free checked workspace recipes for the CUDA GroupQueryAttention decode backends: - reproduce XQA semaphore and multi-block scratch sizing from plain device/shape scalars; - retain XQA RoPE Q/K and dynamic FP32 head-sink conversion allocation parity; - reproduce Flash regular and fast-decode LSE/split-accumulator sizing; - preserve the GQA fast-decode distinction between KV heads used for split selection and query heads used for accumulator allocation; - fail closed for unsupported XQA cache/storage configurations. ## Flash bounded-estimation constraint Flash workspace is not monotonic in KV length. For `B=1`, `S_q=1`, two heads, head size 64, and 108 SMs, increasing KV length from 13,824 to 13,825 changes the selected split count from 54 to 28 and reduces workspace. Future Level-1/Level-2 aggregation must compute a conservative envelope or report unavailable rather than evaluating only the maximum shape. The split heuristic matches runtime double-threshold semantics, including a regression boundary where using `0.85f` would select 17 splits instead of the runtime 20. ## Scope This PR adds concrete selected-backend recipes only. It does not add MEA/unfused recipes, complete-route composition, dynamic-bound route reachability, L1/L2 adapters, cuDNN workspace queries, runtime allocation changes, or #32071 planner integration. ## Validation - CUDA provider test target built successfully. - 201 CUDA internal tests passed; 2 unrelated Lean Attention tests skipped. - 44 GQA preparation/XQA/Flash tests passed, including runtime-helper parity and Flash discontinuity regressions. Tracking: #29775 Dependency: #32446 > This draft temporarily targets `main` because GitHub cannot use a fork-only branch as the base of an upstream PR. Its diff will reduce to this commit after #32446 merges. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b24d04bb-12ab-41a0-8941-76eb9769005d
## Summary Stacked on #32446 and #32453, complete the graph-free CUDA GroupQueryAttention selected-route workspace model: - add CUTLASS memory-efficient Attention K/V expansion and optional FP32 accumulator recipes; - add the unfused aligned Q/Y/FP32-QK/softmax workspace recipe; - compose preparation and exactly one selected backend into one checked 256-byte-aligned operator root; - preserve effective staged KV-cache capacity for MEA; - report cuDNN workspace as unavailable rather than treating its allocator-based graph workspace as zero. ## Scope This PR creates concrete selected-route roots. It does not enumerate routes reachable under dynamic bounds, add Level-1/Level-2 framework adapters, query cuDNN graphs, change runtime allocation topology, or opt into #32071 planning. ## Validation - CUDA provider test target built successfully. - 213 CUDA internal tests passed; 2 unrelated Lean Attention tests skipped. - 56 GQA workspace tests passed, including MEA, unfused, complete-route composition, XQA/Flash parity, and cuDNN-unavailable behavior. - 73 related GroupQueryAttention runtime tests passed; 12 WebGPU-only tests skipped because WebGPU was unavailable. Tracking: #29775 Dependencies: #32446 and #32453 > This draft temporarily targets `main` because GitHub cannot use a fork-only branch as the base of an upstream PR. Its diff will reduce to this commit after the preceding stacked PRs merge. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b24d04bb-12ab-41a0-8941-76eb9769005d
## Summary Add the graph-free workspace preparation foundation for CUDA `GroupQueryAttention`, following the checked-recipe architecture established by #32321. - model windowed KV-cache staging and compaction without changing runtime allocations; - model 3-vector/6-vector sequence metadata and Flash fast-decode suppression; - model route-selected QKV preprocessing requirements; - use checked arithmetic and one internally 256-byte-aligned preparation layout; - distinguish transient staging/compaction from output KV cache and persistent/prepacked state. ## Scope This is the first GQA workspace-estimation PR in the #29775 rollout. It intentionally does **not** add backend-internal workspace recipes, route aggregation, Level-1 estimation, Level-2 declaration, cuDNN workspace queries, or #32071 planner integration. Existing `GetScratchBuffer()` allocation count, size, lifetime, and pointer layout are unchanged. Follow-up PRs will add: 1. XQA and Flash regular/fast-decode workspace recipes. 2. CUTLASS MEA and unfused fallback recipes plus the complete route aggregate. 3. Optional-aware Level-1/Level-2 adapters with one 256-byte-aligned operator root. 4. cuDNN support only if an exact runtime-parity workspace query can be established. ## Validation - 30 GQA workspace recipe and validation tests passed. - 73 related GroupQueryAttention runtime tests passed; 12 WebGPU-only tests skipped because WebGPU EP was unavailable. - CUDA provider test target built successfully. Tracking: #29775 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b24d04bb-12ab-41a0-8941-76eb9769005d
## Summary Stacked on #32446, add graph-free checked workspace recipes for the CUDA GroupQueryAttention decode backends: - reproduce XQA semaphore and multi-block scratch sizing from plain device/shape scalars; - retain XQA RoPE Q/K and dynamic FP32 head-sink conversion allocation parity; - reproduce Flash regular and fast-decode LSE/split-accumulator sizing; - preserve the GQA fast-decode distinction between KV heads used for split selection and query heads used for accumulator allocation; - fail closed for unsupported XQA cache/storage configurations. ## Flash bounded-estimation constraint Flash workspace is not monotonic in KV length. For `B=1`, `S_q=1`, two heads, head size 64, and 108 SMs, increasing KV length from 13,824 to 13,825 changes the selected split count from 54 to 28 and reduces workspace. Future Level-1/Level-2 aggregation must compute a conservative envelope or report unavailable rather than evaluating only the maximum shape. The split heuristic matches runtime double-threshold semantics, including a regression boundary where using `0.85f` would select 17 splits instead of the runtime 20. ## Scope This PR adds concrete selected-backend recipes only. It does not add MEA/unfused recipes, complete-route composition, dynamic-bound route reachability, L1/L2 adapters, cuDNN workspace queries, runtime allocation changes, or #32071 planner integration. ## Validation - CUDA provider test target built successfully. - 201 CUDA internal tests passed; 2 unrelated Lean Attention tests skipped. - 44 GQA preparation/XQA/Flash tests passed, including runtime-helper parity and Flash discontinuity regressions. Tracking: #29775 Dependency: #32446 > This draft temporarily targets `main` because GitHub cannot use a fork-only branch as the base of an upstream PR. Its diff will reduce to this commit after #32446 merges. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b24d04bb-12ab-41a0-8941-76eb9769005d
Summary
Add the graph-free workspace preparation foundation for CUDA
GroupQueryAttention, following the checked-recipe architecture established by #32321.Scope
This is the first GQA workspace-estimation PR in the #29775 rollout. It intentionally does not add backend-internal workspace recipes, route aggregation, Level-1 estimation, Level-2 declaration, cuDNN workspace queries, or #32071 planner integration. Existing
GetScratchBuffer()allocation count, size, lifetime, and pointer layout are unchanged.Follow-up PRs will add:
Validation
Tracking: #29775