[BUG][CK][MHA] Fix for MHA with softmax-sink - #4612
Open
shurale-nkn wants to merge 2 commits into
Open
Conversation
shurale-nkn
commented
Aug 6, 2026
Comment on lines
+982
to
+987
| sink = torch.empty(nhead, device=device, dtype=torch.float32).uniform_( | ||
| -1.0, 1.0 | ||
| #3.0, 6.0 | ||
| #30.0,60.0 | ||
| ) | ||
| out, lse = _sink_run_fwd(q.detach(), k.detach(), v.detach(), softmax_scale, causal, sink) |
Author
There was a problem hiding this comment.
so buffer magnitude change .
- Updated the buffer data range. With the previous distribution
sink = torch.empty(batch, nhead, device=device, dtype=torch.float32).uniform_( 30.0, 60.0 )
, the BWD output values were extremely small in magnitude, making the validation ineffective since even incorrect implementations could still pass due to the negligible numerical differences. The range has been changed to reflect realistic input data, providing more meaningful validation coverage.
Below are examples of the output values produced with different input tensor ranges.
Contributor
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Fix the
sinkshape contract in the MHA backward bindings:[batch, num_heads]→
[num_heads]. The sink is a learnable per-head softmax offset — one scalar perquery head, shared across the batch — so a batch dimension was never meaningful.
The declared contract was inconsistent with the kernel and with itself:
sink_ptr[i_nhead], and accumulates the gradientatomically over all batches into a
[num_heads]d_sink. A[H]gradient canonly belong to an
[H]parameter — the output side already encoded the rightsemantics.
[H]:aiter/ops/mha.py:1285.today, also takes
[H]:aiter/ops/triton/attention/mha.py:139-141.So
[H]is not a choice, it is the only shape consistent with every othersurface. Backward was the sole outlier.
Changed
csrc/py_itfs_ck/mha_bwd_kernels.cu,csrc/py_itfs_ck/mha_varlen_bwd_kernels.cu—
TORCH_CHECKnow requires 1-D[num_heads]; comments updated.csrc/include/mha_bwd.h,csrc/include/torch/mha_bwd.h,csrc/include/torch/mha_varlen_bwd.h— doc comments.op_tests/test_mha.py,op_tests/test_mha_varlen.py— see Tests below.Consumer impact: no regression
The three consumers of this interface:
aiter::mha_bwd_argsC++ API directly (ck_fused_attn_bwd.cpp:534-535)(1, H, 1, 1), i.e. H contiguous fp32 (jax/cpp_extensions/attention.py:452)sink_ptr/d_sink_ptrtonullptr(SFINAE,mha_bwd_ck.hip:19-33)_nsinkinstances onlyattention_aiter_impl.py:10-12,146,265)[H_q]on the Triton pathTE is the only consumer that actually feeds sink to CK backward, and it already
supplies an H-element buffer. Under the old
[B, H]claim combined with CK'sbatch-major indexing, the kernel would index past the end of that buffer for
batch > 0. This change removes that, so for TE the fix is strictly corrective.Primus-Turbo gates on
sink is not Noneand routes to Triton unconditionally, sosink never reaches CK there. That Triton path takes
[H], which independentlycorroborates that
[H]is the intended contract rather than a convenience.Note the check is a runtime
TORCH_CHECK, not compile-time: any caller stillpassing
[B, H]is rejected at the binding boundary with a clear message ratherthan silently computing wrong numbers.
Tests
test_mha.py/test_mha_varlen.pysink tests were producing inputs no forwardpass can reach:
sinkwas passed to backward but not to forward, so the LSE didnot include the sink term and
P_sink = exp(sink - lse)could exceed 1. Now:sink_ptr, so the LSE is the one the kernelactually produces and the reference formula is exact rather than approximate;
rtol=0.02, atol=0.5tortol=1e-3, atol=1e-3,which is roughly a 450x margin over the observed max error.
All sink tests pass: 18 in
test_mha.py, 4 intest_mha_varlen.py.Technical Details
This is PR in CK
ROCm/rocm-libraries#10519
this is PR in TransformerEngine
ROCm/TransformerEngine#678
Test Plan
Test Result
Submission Checklist