Enable cuDNN SDPA for contrib Attention - #29717
Conversation
Route eligible FP16 and BF16 Attention nodes with compact sequence-length masks through the existing cuDNN SDPA runner on Hopper and newer GPUs. Keep raw masks and cache paths on the existing kernels.
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
@tianleiwu Could you please take a look and approve the pending GitHub Actions workflows when you have a chance? This PR extends the cuDNN SDPA integration from #28849 to the fused contrib |
There was a problem hiding this comment.
Pull request overview
This PR extends the CUDA implementation of the contrib com.microsoft::Attention operator to reuse the existing cuDNN SDPA (Flash Attention) runner when eligible (FP16/BF16, no raw mask, no KV cache, and cuDNN reports support), aligning its dispatch behavior more closely with existing MultiHeadAttention/GroupQueryAttention integration.
Changes:
- Add cuDNN SDPA enable/auto-enable flags to the contrib CUDA
Attentionkernel and compute cuDNN eligibility early in dispatch. - Route eligible contrib
Attentionexecutions toAttentionKernel_CudnnFlashAttention, including temp-space allocator wiring for the cuDNN runner. - Add a new contrib
Attentiontest using a 1D key sequence-length mask intended to exercise the cuDNN SDPA path.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| onnxruntime/test/contrib_ops/attention_op_test.cc | Adds a new CUDA-focused test case using a 1D key sequence-length mask and env-var kernel selection controls. |
| onnxruntime/contrib_ops/cuda/bert/attention.h | Adds member flags to track explicit and auto cuDNN SDPA enablement for contrib Attention. |
| onnxruntime/contrib_ops/cuda/bert/attention.cc | Implements cuDNN SDPA eligibility checks and dispatch integration for contrib Attention, and propagates the selection into workspace sizing and execution data. |
|
@tianleiwu The follow-up commit 55624f9 addresses the review feedback by asserting the actual cuDNN kernel selection. I validated it on H100: the targeted test passed (1/1) and the full |
|
The The sibling TensorRT CUDA Minimal build completed successfully, so this looks like a transient network/infrastructure failure. A rerun of the failed job should be sufficient. Failed job: https://github.com/microsoft/onnxruntime/actions/runs/29374987406/job/87230486564 |
|
Sorry for tagging you again, @tianleiwu. The failed Linux TensorRT CI job appears to be a transient Gradle download timeout. Could you please rerun the failed job when you have a chance? Thank you! |
@mastryukov1990, CI pipeline has some issues right now (some jobs are queued forever). I could help trigger CIs later. |
|
Hi @tianleiwu, sorry to follow up again. The PR currently has 20 successful workflows and 11 cancelled ones (mostly Windows workflows, plus ONNX Runtime CUDA Builds); none are queued or running now. Is the CI infrastructure healthy enough to rerun the cancelled workflows at this point, or should we wait a bit longer? If it is safe now, could you please trigger them? Thank you! |
|
@mastryukov1990, please merge latest main branch, which has a commit for CI pool change. |
|
@tianleiwu Done — I merged the latest |
tianleiwu
left a comment
There was a problem hiding this comment.
Reviewed the cuDNN SDPA enablement for the fused contrib Attention kernel. The change reuses the shared cudnn_sdpa::is_stable/is_supported predicate and AttentionKernel_CudnnFlashAttention dispatch already used by MultiHeadAttention, so no new kernel is introduced.
Verified against the surrounding paths:
- Mutual exclusion preserved —
cudnn_sdpa_supportedcorrectly gates off flash, the fused TRT runner, and memory-efficient attention; theQkvToContext<= 1fused-kernel assert still holds. - QKV format is valid — with cuDNN selected,
PrepareQkv_Attentionfalls into the unfused branch producingQ_K_V_BNSH, whichCudnnFlashAttention/build_graphexplicitly accept and stride correctly. - Workspace sizing is correct —
GetAttentionWorkspaceSize(..., cudnn_sdpa_supported, false)returns the fullqkv_bytestranspose buffer (previously this arg was hard-codedfalse). - Safe default —
AttentionData::kernel_typedefaults toAttentionKernel_Default, so non-eligible calls keep their existing dispatch. - Test validates both kernel selection (
SdpaKernel=CUDNN_FLASH_ATTENTION) and numerics (masked key/value token excluded from both outputs), and skips cleanly when cuDNN is unavailable.
No blocking issues. One maintainability suggestion left inline regarding the implicit attention_bias safety invariant.
|
Hi @tianleiwu, the latest head ( |
|
@microsoft-github-policy-service agree |
|
@tianleiwu I merged the latest |
|
@tianleiwu The latest push only merged the current |
|
@tianleiwu The newly failed builds appear to be an upstream Windows runner/toolchain issue rather than a regression from this PR. All of the red Windows workflows fail during CMake's compiler sanity check, before any ONNX Runtime source from this PR is compiled: The builds enable Could you please advise whether the Windows runner image/workflows are being fixed upstream and re-enable or rerun the workflows once that is ready? A rerun on the current runner image will likely fail in the same way. |
|
@mastryukov1990, it needs image update in CI machine pool. Please be patient. I can help re-run the failed CI when the image is updated. |
|
@tianleiwu Thank you for the clarification. Do you happen to have a rough ETA for when the CI machine-pool image is expected to be updated? No urgency — I just want to understand when it would make sense to check back and rerun the failed workflows. |
|
@tianleiwu Thank you — the CI image update appears to have resolved the previous Spectre/MSB8040 failures. Only three workflows remain red: VitisAI and XNNPACK lost communication with their self-hosted runners, and the WebGPU vcpkg job hit |
Description
Enable the existing cuDNN SDPA runner for the CUDA implementation of the contrib
Attentionoperator when:On Hopper and newer GPUs, cuDNN SDPA is auto-preferred consistently with
MultiHeadAttention. Explicit kernel selection continues to be respected. Raw attention masks and cache paths remain on their existing kernels.The new test forces cuDNN SDPA and uses a partial sequence-length mask, verifying that the masked key/value token is excluded from both output positions.
Motivation and Context
Transformer optimizer fusions can produce
com.microsoft::Attentionnodes with compact sequence-length masks. Although cuDNN SDPA was enabled forMultiHeadAttentionandGroupQueryAttentionin #28849, the legacy fusedAttentionpath did not dispatch to the shared cuDNN runner. On an H100, all 24 attention nodes in a BGE encoder consequently selected the math kernel.This change reuses the existing cuDNN implementation and eligibility checks rather than adding another attention kernel.
Performance
Exact A/B comparison using the same patched build of current
main, with cuDNN auto-dispatch disabled for the baseline viaORT_ENABLE_CUDNN_FLASH_ATTENTION=0:Environment: NVIDIA H100 (SM90), CUDA 12.8, cuDNN frontend 1.24, FP16 BGE encoder with right-padded batches. Debug dispatch confirmed
CUDNN_FLASH_ATTENTIONfor 24/24 fusedAttentionnodes.Numerical comparison against the same build with cuDNN disabled, over sampled embeddings:
0.001465;0.999955.Validation
ContribOpAttentionTest.CudnnFlashAttentionWithKeySequenceLengthMask: passed and reportedSdpaKernel=CUDNN_FLASH_ATTENTION.ContribOpAttentionTest.*: 46/46 passed (one pre-existing disabled test).clang-format --dry-run --Werroron all changed files.git diff --check.