Repository navigation
[Triton/Gluon] [CI] Streamline Flash Attentions api - #6502
Conversation
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
One backend per PR: PR title tags & labels: |
7673041 to
387ee56
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Integration CI filters still target the old kernel directory, and the new routing suite is outside the required Triton test folder.
2 open issues
What changed in this PR
This PR exposes Dao-AI FlashAttention selection through Aiter’s public Triton MHA API and relocates its internal package under attention/dao_ai/.
Changes:
- Adds per-call implementation selection and preserves implementation, RNG state, and determinism for backward.
- Moves internal modules and updates imports, with a compatibility package for existing consumers.
- Adds routing tests and documents the API and package layout.
| File | Description |
|---|---|
op_tests/triton_tests/attention/test_mha_v3.py |
Updates the FP8 utility import. |
op_tests/triton_tests/attention/test_mha_fp8.py |
Updates the FP8 utility import. |
op_tests/triton_tests/attention/test_mha_dao_ai.py |
Tests per-call implementation selection. |
op_tests/test_mha_backend_dispatch.py |
Adds CPU routing and backward-state tests. |
op_tests/op_benchmarks/triton/bench_sage.py |
Updates the FlashAttention import. |
op_tests/op_benchmarks/triton/bench_mha.py |
Updates imports and implementation help text. |
op_tests/op_benchmarks/triton/bench_fav3_sage.py |
Updates the FlashAttention import. |
aiter/ops/triton/README.md |
Documents selection and compatibility behavior. |
aiter/ops/triton/attention/unified_attention.py |
Updates the architecture utility import. |
aiter/ops/triton/attention/mha.py |
Adds per-call selection and backward-state handling. |
aiter/ops/triton/attention/mha_v3.py |
Uses the relocated internal package. |
aiter/ops/triton/_triton_kernels/flash_attn_triton_amd/__init__.py |
Preserves compatibility imports. |
aiter/ops/triton/_triton_kernels/attention/fav3_sage_attention.py |
Updates the shared attention helper import. |
aiter/ops/triton/_triton_kernels/attention/dao_ai/utils.py |
Relocates existing FlashAttention utilities. |
aiter/ops/triton/_triton_kernels/attention/dao_ai/interface_v3.py |
Updates relocated FA3 interface imports. |
aiter/ops/triton/_triton_kernels/attention/dao_ai/interface_v2.py |
Updates relocated FA2 interface imports. |
aiter/ops/triton/_triton_kernels/attention/dao_ai/fwd_prefill.py |
Updates prefill kernel imports. |
aiter/ops/triton/_triton_kernels/attention/dao_ai/fwd_decode.py |
Updates decode kernel imports. |
aiter/ops/triton/_triton_kernels/attention/dao_ai/common.py |
Updates common helper imports. |
aiter/ops/triton/_triton_kernels/attention/dao_ai/bwd.py |
Updates backward kernel imports. |
aiter/ops/triton/_triton_kernels/attention/dao_ai/__init__.py |
Exposes interfaces from the relocated package. |
.github/instructions/aiter-ops-triton.instructions.md |
Updates documented kernel and test paths. |
Review effort: Balanced
8399e07 to
10176ea
Compare
10176ea to
d6d3c9a
Compare
WAITING ON AUTHORPR Self-ReviewRevision Waiting for the PR author. The readiness report will appear after the self-review answers are complete for this revision. Questions to answer in the PR description
Edit the Missing or invalid answers
Shadow mode reports what would block but keeps the status successful. Set |
There was a problem hiding this comment.
🟡 Changes recommended
The new Dao-AI RNG handoff lacks numerical backward validation with nonzero dropout: GPU cases use zero dropout, routing tests mock backward calls, and dense and varlen gradient checks against a reference using the returned dropout mask are still needed.
4 open issues
Review effort: Balanced
|
We have a conflict in |
d214073 to
8385bd3
Compare
brunomazzottiamd
left a comment
There was a problem hiding this comment.
LGTM!
Please remove Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> from the last commit before squashing and merging.
48e1c2f to
584e0fd
Compare
773108c to
ae15b8b
Compare
brunomazzottiamd
left a comment
There was a problem hiding this comment.
LGTM! The failing CI test is unrelated to this PR and the author claims it's also happening in main branch - IMHO it isn't a blocker for merging this PR.
Move the Dao-AI Triton attention from _triton_kernels/flash_attn_triton_amd/ to _triton_kernels/attention/dao_ai/; the old path forwards what FlashAttention main imports. mha.py's flash_attn_func and flash_attn_varlen_func take implementation="default" or "dao_ai", and _flash_attn_forward and _flash_attn_backward take it too; mha_v3.py adds _flash_attn_forward, _flash_attn_backward and _flash_attn_combine. FlashAttention's FA2 and FA3 interfaces call these instead of importing the Dao-AI package. Dao-AI returns rng_state on the device and the dropout record in q's dtype, as FlashAttention's fake ops declare; the backward kernels read rng_state on the device and the varlen backward checks no cu_seqlens values on the host, so a dropout backward does not sync and captures in a CUDA graph. The Flash Attention workflow runs its tests and benches from .github/scripts/flash_attention/; the full suites run one pytest process per test function. test_mha_dao_ai.py has one test per property: correctness, contract, routing, refusal and capture.
ae15b8b to
8948c3d
Compare
|
#7774 was merged and I rebased this one through GitHub web interface. Let's wait for CI to get green... |
Move the Dao-AI Triton attention from _triton_kernels/flash_attn_triton_amd/ to _triton_kernels/attention/dao_ai/; the old path forwards what FlashAttention main imports. mha.py's flash_attn_func and flash_attn_varlen_func take implementation="default" or "dao_ai", and _flash_attn_forward and _flash_attn_backward take it too; mha_v3.py adds _flash_attn_forward, _flash_attn_backward and _flash_attn_combine. FlashAttention's FA2 and FA3 interfaces call these instead of importing the Dao-AI package. Dao-AI returns rng_state on the device and the dropout record in q's dtype, as FlashAttention's fake ops declare; the backward kernels read rng_state on the device and the varlen backward checks no cu_seqlens values on the host, so a dropout backward does not sync and captures in a CUDA graph. The Flash Attention workflow runs its tests and benches from .github/scripts/flash_attention/; the full suites run one pytest process per test function. test_mha_dao_ai.py has one test per property: correctness, contract, routing, refusal and capture.
ROCm#6502 made _flash_attn_forward return rng_state, so the 5-value unpack fails. Index the output, and drop imports main already has at the top. Signed-off-by: Pham Binh <194774975+phambinhfin@users.noreply.github.com>
On ROCm, FlashAttention has two backends: its own CK extension and aiter. aiter has two implementations, selected by a flag: FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE selects its Triton kernels (as before) and FLASH_ATTENTION_AITER_AMD_ENABLE=TRUE its general MHA API, which picks FMHA v3 or CK per call. FA3 has no CK extension, so on ROCm it always uses aiter's Triton implementation and refuses the general one. flash_attn_amd.py (flash_attn/ for FA2, hopper/ for FA3, the same file) selects the backend as Ck() or Aiter(impl), for setup.py and the runtime. The runtime refuses aiter off ROCm, and FA2 on ROCm without its CK extension falls back to aiter's Triton implementation with a warning. USE_TRITON_ROCM stays, since downstream projects read it. flash_attn/flash_attn_interface_aiter.py and hopper/flash_attn_interface_aiter.py map FA's low-level calls to aiter's public MHA entry points (implementation="dao_ai" for Triton, aiter's default dispatcher for the general implementation). They return what FA's register_fake declarations state, so torch.compile works on both, and refuse what aiter cannot do (softcap, an explicit dropout generator, block_table on Triton, KV-cache attention on the general implementation) with a named error. tests/test_flash_attn_triton_amd.py adds test_amd_backend_routing, _refusal and _parity, the custom ops' opcheck and the aiter refusals. third_party/aiter moves to ROCm/aiter#6502's merge commit, which adds the public entry points the adapters call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Motivation
This PR reorganizes the aiter code that upstream FlashAttention uses. It follows the discussions in Dao-AILab/flash-attention#2981 and #5945. FlashAttention uses aiter's Triton attention through a private package. This PR moves that code and exposes it through the public Triton MHA API. FlashAttention can then use a public entry point. The matching FlashAttention change is Dao-AILab/flash-attention#3064. With it, FlashAttention can use aiter's Triton kernels or aiter's default dispatcher. The default dispatcher includes FMHA v3.
The PR also moves the test and bench commands of the Flash Attention workflow into scripts. The post-merge suite ran each test file in one pytest process. On main, a native abort stops the FA2 file at 4%. The abort hides all later tests.
Technical Details
_triton_kernels/flash_attn_triton_amd/to_triton_kernels/attention/dao_ai/. The old package forwards what FlashAttention main imports:flash_attn_2,flash_attn_3andutils.flash_attn_funcandflash_attn_varlen_funcinaiter/ops/triton/attention/mha.pyacceptimplementation="default"orimplementation="dao_ai".Noneuses the default frommha_set_impl. Backward uses the implementation and the dropout RNG state of its forward. MXFP8 and block-scale FP8 calls refuseimplementation="dao_ai".aiter/ops/mha.pydoes not change.mha.pyadds_flash_attn_backwardnext to_flash_attn_forward. Both takeimplementation=. The two autograd functions call them. FlashAttention calls them withimplementation="dao_ai"and does not import the Dao-AI package.mha_v3.pyadds_flash_attn_forward,_flash_attn_backwardand_flash_attn_combine. Its autograd functions and its KV-cache path call them. FlashAttention's FA3 interface calls them and does not import the Dao-AI package.rng_stateon the device and the dropout record inq.dtype, as FlashAttention's fake ops declare fortorch.compile.rng_stateis filled on the device, and the backward kernels read it there. The varlen backward does not checkcu_seqlensvalues on the host. A dropout backward does not sync and captures in a CUDA graph. Dense dropout without a returned record no longer fails an assertion..github/scripts/flash_attention/holdsinstall.sh,test.shandbench.sh.install.shisinstall_flash_attention.shwith no change. Each test and bench step of the workflow calls one of these scripts. CI and a local container run the same commands.test.shruns one pytest process for each test function of the full suites. A failure or an abort in one function does not stop the other functions. The script fails if a line fails.test.shdeselects 28 cases oftest_flash_attn_outputthat fail on main. All 28 use dropout and ALiBi. 24 are causal MHA cases with head dimension 59 or 64. 4 are non-causal GQA cases with head dimension 40. Some of these cases fail, and some abort the process. #6859 will remove the deselect lines when it fixes these cases.attention/dao_ai/**and.github/scripts/flash_attention/**.Test Plan
All tests ran on MI355X, gfx950, in the base image of the workflow. The branch was installed as the workflow installs it. The tests used
test.shwith the flags of the workflow.test.sh v2-pr,v2-full,v3-prandv3-fullagainst FlashAttention main, as aiter CI runs them.test.sh v2-fullandv3-fullagainst CI: Temporarily move Aiter build to linux-aiter-mi300x-1 #3064.test_mha_dao_ai.py,test_mxfp8_attention_kernel.pyandtest_block_scale_fp8_attention.py.bench.sh, two runs for this branch and two runs for main, on one GPU.Test Result
test_flash_attn_output, 5,228 cases passed, 24 skipped and 28 were deselected. All other functions passed or skipped themselves.v2-fullandv3-fullpassed against CI: Temporarily move Aiter build to linux-aiter-mi300x-1 #3064 with the same counts. The adapter tests of CI: Temporarily move Aiter build to linux-aiter-mi300x-1 #3064 passed.test_mha_dao_ai.py,test_mxfp8_attention_kernel.pyandtest_block_scale_fp8_attention.pypassed. This includes the new dropout, selector and routing tests.PR Self-Review
Reviewed revision
ae15b8be1Behavior and intent
The Dao-AI Triton attention moves from a private package to
attention/dao_ai/. The public Triton MHA wrappers select it for each call withimplementation="dao_ai". The old package path forwards its imports, so FlashAttention releases that import it keep working. The Flash Attention workflow runs its tests and benches from scripts. CI and local runs use the same commands. The post-merge suite runs one pytest process for each test function. An abort no longer hides later tests. 28 known failures on main are deselected by node ID until #6859 fixes them.Validation and unverified scope
All validation ran on MI355X, gfx950, in the base image of the workflow.
v2-full,v2-pr,v3-fullandv3-prpassed against FlashAttention main.v2-fullandv3-fullpassed against #3064.test_mha_dao_ai.pyand the MXFP8 and block-scale tests passed. The MHA bench shows no change against main. gfx942, RDNA3 and the Windows and Triton-only smoke jobs were not tested locally. CI runs them. The benches ran with the commands ofbench.sh, not through the script.PR-specific question
The
pull_requestevent starts the workflow, notpull_request_target. A fork PR therefore has a read-only token and no secrets. The new scripts run inside the test container throughdocker exec. Their environment has no secrets. They run the same commands as the old inline steps. The Docker login steps and the artifact steps do not change. Fork PR code already ran in these containers, because the jobs build and test the aiter of the PR.Changed op tests
test_mha_dao_ai.pynow has one test for each property of the Dao-AI implementation. Each test sweeps the inputs of its property.test_flash_attn_func_correctnessandtest_flash_attn_varlen_func_correctnessreplacetest_mha_dao_aiand keep its cases, split by function. Each adds dropout rows that compare output and gradients with a reference that applies the dropout record of the forward. The dropout rows also check that the gradients are closer to that reference than to one with a shifted mask, so they fail if backward loses the RNG state of the forward. They replacetest_mha_dao_ai_dropout_scores.test_flash_attn_with_kvcache_correctnessis new. It comparesflash_attn_with_kvcachewith attention over the valid cache entries of each batch, and checks that the new keys and values are appended to the cache. No other test covers this function.test_mha_dao_ai_contractcalls each function and checks the shapes, dtypes and devices of its returns._flash_attn_forwardand_flash_attn_backwardreturn what FlashAttention's fake ops declare.test_mha_dao_ai_routingchecks that a backward runs the implementation of its forward aftermha_set_implchanges, dense and varlen.test_mha_dao_ai_refusalchecks each unsupported call: MXFP8 and block-scale FP8 withdao_ai, unknown selectors, the Dao-AI varlenblock_tableandout, and KV-cache softcap and split counts. No forward runs.test_mha_dao_ai_capturereplaces the two graph tests. It captures each function in a CUDA graph under both default devices, including dropout training steps, and compares the replay with eager.test_mha.py,test_mha_fp8.py,test_mha_v3.py,test_block_scale_fp8_attention.py,bench_mha.py,bench_sage.py,bench_fav3_sage.pyandbench_block_scale_fp8_attention.pychange only import paths.