Upgrade cudnn_frontend to 1.24 and enable cuDNN SDPA for MHA/GQA#28849
Conversation
There was a problem hiding this comment.
Pull request overview
This PR upgrades the cudnn_frontend dependency and integrates the newer cuDNN SDPA backend into the CUDA contrib MultiHeadAttention (MHA) and GroupQueryAttention (GQA) operators, including an SM≥90 auto-preference path to improve Hopper/Blackwell attention throughput.
Changes:
- Bump
cudnn_frontendfrom 1.12.0 → 1.24.0 and adjust build to treat its headers as SYSTEM includes. - Extend MHA to enable cuDNN SDPA for FP16/BF16 and optionally auto-prefer it on SM≥90 ahead of Flash Attention.
- Add a cuDNN SDPA execution path for GQA (non-quantized FP16/BF16, constrained feature set) and update kernel option handling to track explicit
sdpa_kernelselection / disable SM≥90 auto when env-var disables cuDNN.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| onnxruntime/contrib_ops/cuda/bert/multihead_attention.h | Adds state to support SM≥90 auto-preference of cuDNN SDPA when not kernel-pinned. |
| onnxruntime/contrib_ops/cuda/bert/multihead_attention.cc | Computes cuDNN SDPA eligibility earlier and updates selection priority (esp. SM≥90); enables BF16. |
| onnxruntime/contrib_ops/cuda/bert/group_query_attention.h | Adds flags for explicit vs auto cuDNN SDPA enablement. |
| onnxruntime/contrib_ops/cuda/bert/group_query_attention.cc | Introduces cuDNN SDPA path selection/dispatch and wires temp allocator + cuDNN handle. |
| onnxruntime/contrib_ops/cuda/bert/group_query_attention_impl.cu | Implements the cuDNN SDPA runner path for GQA and hooks it into the dispatch. |
| onnxruntime/contrib_ops/cuda/bert/cudnn_fmha/cudnn_flash_attention.cc | Migrates to cudnn_frontend v1.24 APIs; adds diagonal-band causal mask logic and mask synthesis. |
| onnxruntime/contrib_ops/cuda/bert/attention_kernel_options.h | Tracks explicit sdpa_kernel selection and adds a gate for SM≥90 cuDNN auto-preference. |
| onnxruntime/contrib_ops/cuda/bert/attention_kernel_options.cc | Implements explicit-kernel tracking and honors ORT_ENABLE_CUDNN_FLASH_ATTENTION=0 for disabling auto. |
| onnxruntime/contrib_ops/cuda/bert/attention_impl.cu | Enables BF16 flagging for the cuDNN SDPA wrapper. |
| onnxruntime/contrib_ops/cuda/bert/attention_data.h | Extends GQA data to carry cuDNN SDPA selection and required runtime handles. |
| cmake/onnxruntime_providers_cuda_plugin.cmake | Links CUDA::nvrtc for the CUDA plugin EP to satisfy cudnn_frontend NVRTC symbol needs. |
| cmake/external/cudnn_frontend.cmake | Marks cudnn_frontend headers as SYSTEM to avoid -Werror failures from upstream warnings. |
| cmake/deps.txt | Updates cudnn_frontend archive URL/hash to v1.24.0. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Review summary — cuDNN SDPA for MHA/GQA (cudnn_frontend 1.24)Reviewed by a 5-model team (readability, code, critical, deep-semantic, integration). Strong PR, well-reasoned. The causal-mask and GQA capacity/padding math was independently verified against the cudnn_frontend source and found mathematically correct. One bug to fix before merge. 🔴 Major — fix before merge1. MHA auto-enable path bypasses In 🟢 Minor
❓ Open question
⚪ Nits (optional polish)
✅ Verified correct (no action)Causal-mask migration (byte-identical to the old convenience setters), sliding-window mapping (no off-by-one), the
|
|
Thanks for the thorough multi-model review. Responses below. 🔴 Major #1 — MHA auto path bypasses
|
|
Correction on minor #5 above — I misspoke: the code calls |
Description
Upgrades the
cudnn_frontenddependency from 1.12.0 → 1.24.0 and wires the updated cuDNN SDPA (scaled dot-product attention) kernels into the CUDAMultiHeadAttentionandGroupQueryAttentionoperators. On SM≥90 (Hopper/Blackwell), cuDNN SDPA is auto-preferred for FP16/BF16 ahead of Flash Attention / cutlass FMHA, which significantly improves GQA prefill throughput.Key Changes
cmake/deps.txt:cudnn_frontend1.12.0 → 1.24.0.cmake/external/cudnn_frontend.cmake: mark cudnn_frontend headers asSYSTEMincludes so v1.24's unused static helper does not trip-Werror=unused-function.cudnn_fmha/cudnn_flash_attention.cc: migrate to the v1.24 API —set_generate_stats(false)(replaces deprecatedset_is_inference), diagonal-band causal masking (set_diagonal_alignment+set_diagonal_band_right_bound/set_diagonal_band_left_bound), and synthesize the missingseq_len_q/seq_len_kvside that v1.24 now requires when a padding mask is used.multihead_attention.{cc,h}: enable cuDNN SDPA for FP16 and BF16; compute cuDNN eligibility before Flash and prefer it on SM≥90 unless the user pinned a kernel.group_query_attention.{cc,h},group_query_attention_impl.cu,attention_data.h: add a cuDNN SDPA path (non-quantized FP16/BF16, no softcap/smooth-softmax/head-sink/local-window, BNSH KV cache), dispatched after XQA and before Flash/MEA/unfused.attention_kernel_options.{cc,h}: track explicitsdpa_kernelselection and honor an explicitORT_ENABLE_CUDNN_FLASH_ATTENTION=0so it disables the SM≥90 auto path.Kernel Priority
sdpa_kernelprovider option or setsORT_ENABLE_CUDNN_FLASH_ATTENTION=0.ORT_ENABLE_CUDNN_FLASH_ATTENTION=0disables cuDNN entirely (including the auto path);=1force-enables it; thesdpa_kernelprovider option overrides env vars.Benchmark Results
Measured with
onnxruntime/test/python/transformers/benchmark_gqa.pyon NVIDIA H200 (SM 9.0), CUDA 13.0 / cuDNN 9.19,Llama3-8B-shaped GQA (b1, 32 query heads, 8 KV heads, head size 128, FP16).ORT_ENABLE_CUDNN_FLASH_ATTENTION=0)The prefill (prompt) phase shows the largest gains for the dense variants:
ORT-GQA-Dense — prompt latency (ms, lower is better)
ORT-GQA-Dense-PackedQKV — prompt latency (ms, lower is better)
Prefill is ~1.5×–4× faster across sequence lengths for both dense variants. Decode (token) latency is unchanged within run-to-run noise.
Testing
onnxruntime_provider_test --gtest_filter='GroupQueryAttentionTest.*:MultiHeadAttentionTest.*'— GQA 44/44, MHA 18/18 pass on H200.AttentionTest.*:PackedMultiHeadAttentionTest.*:DecoderMaskedMultiHeadAttentionTest.*) — 143/143 pass.s_q==1causal-mask edge case handled for cuDNN ≤ 9.9).ORT_ENABLE_CUDNN_FLASH_ATTENTION=0disables the SM≥90 auto path (0 cuDNN selections) while the default run selects cuDNN.