Repository navigation
Commit 9975a72
authored
CUDA backend: keep wide attention heads that are not a power of 2 off the Triton SDPA kernel (#24427)
### What is wrong today
The CUDA backend replaces `scaled_dot_product_attention` with its own
Triton kernel when the kernel accepts the call. For head sizes that are
not a power of 2, that kernel holds the whole head in one tile of at
most 256 values. Wider heads of that kind, such as 288, 320, 384, 640 or
768, are still accepted. The kernel then uses only the first 256 values
of each query and key, and it never writes the rest of the output. The
program runs and returns wrong numbers, with no error. For example, the
mid-block attention of the LingBot-VA video VAE encoder has heads of
640, and its lowered encoder drifts far from eager.
```python
q, k, v = (torch.randn(2, 1, 64, 640, device="cuda", dtype=torch.bfloat16) for _ in range(3))
sdpa(q, k, v) # max error against PyTorch: about 4
```
### What this change does
The shape check that the kernel and the replacement pass share now
rejects head sizes that are not a power of 2 and are wider than that one
tile. The pass already leaves calls the kernel rejects to the regular
CUDA lowering, so such attention in an exported model now gives the
right result. Code that calls the Triton kernel directly, such as the
off-graph KV lowering, now gets an error instead of wrong numbers. Heads
that are a power of 2, including 512 and 1024, use the other Triton
kernel, which covers the whole head, so they still use Triton.
Because this fixes wrong results, it should also go to `release/1.6`.
### What was tested
On an A100 with torch 2.14:
- `test_sdpa_head_sizes` lowers attention with heads of 96, 192, 256,
512, 288, 320, 384, 640 and 768, runs it, and compares each result with
eager. Without this change the last five fail.
- `test_heads_the_kernel_takes_are_supported` checks that the pass still
gives heads of 192, 256, 512 and 1024 to the Triton kernel.
`test_wide_head_that_is_not_a_power_of_2_is_not_replaced` checks that a
head of 640 exports through the regular lowering and logs why.
`test_wide_non_pow2_head_rejected` checks that a direct call with a head
of 640 raises.
- The other Triton SDPA kernel tests and
`test_sdpa_splitk_replacement.py` still pass.
- At 64 tokens and head 640, one lowered attention call takes about as
long as before: 767 µs now, 784 µs with the wrong result. This was
measured at 64 tokens only. The regular lowering builds the full score
matrix, so for long sequences it can need much more time and memory than
the Triton kernel did.
- With torch 2.15, the LingBot-VA VAE encoder, lowered with default
settings, now matches eager within bfloat16 precision.1 parent e2bcb9d commit 9975a72
4 files changed
Lines changed: 70 additions & 2 deletions
File tree
- backends/cuda
- tests
- triton/kernels
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
815 | 815 | | |
816 | 816 | | |
817 | 817 | | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
818 | 855 | | |
819 | 856 | | |
820 | 857 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
275 | 275 | | |
276 | 276 | | |
277 | 277 | | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
278 | 282 | | |
279 | 283 | | |
280 | 284 | | |
| |||
320 | 324 | | |
321 | 325 | | |
322 | 326 | | |
323 | | - | |
| 327 | + | |
324 | 328 | | |
325 | 329 | | |
326 | 330 | | |
| |||
364 | 368 | | |
365 | 369 | | |
366 | 370 | | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
367 | 384 | | |
368 | 385 | | |
369 | 386 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
603 | 603 | | |
604 | 604 | | |
605 | 605 | | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
606 | 612 | | |
607 | 613 | | |
608 | 614 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
270 | 270 | | |
271 | 271 | | |
272 | 272 | | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
273 | 280 | | |
274 | 281 | | |
275 | 282 | | |
| |||
1301 | 1308 | | |
1302 | 1309 | | |
1303 | 1310 | | |
1304 | | - | |
| 1311 | + | |
| 1312 | + | |
1305 | 1313 | | |
1306 | 1314 | | |
1307 | 1315 | | |
| |||
0 commit comments