Repository navigation
Conversation
cuDNN frontend 1.26 (NVIDIA/cudnn-frontend#316) changed two defaults that the DSA cuDNN call sites rely on. Sparse indexer backward: indexer_backward_wrapper treats top-k ids as per-batch local unless topk_indices_global=True. MCore's sparse-loss path has always materialized global B * S_k + local ids, so BSHD calls with more than one sequence per micro-batch lost or misplaced the sparse indexer gradient of every batch after the first (THD, one sequence per batch, is unaffected). Call the wrapper through _call_sparse_indexer_backward, which sets topk_indices_global=True whenever the installed wrapper names the parameter (or takes **kwargs) and keeps the historical call otherwise. Dense causal offsets: the dense indexer forward, dense attention score recompute and dense indexer backward kernels gained q_causal_offsets and, when it is not given, use a zero (top-left) q_causal_offset instead of the bottom-right alignment (seqlen_k * ratio - seqlen_q): FE <= 1.25 aligns bottom-right, FE >= 1.26 top-left. MCore's BSHD call sites pass no offsets and were written against the bottom-right contract. The single-sequence packed CP scorer in particular crops the key prefix of each query chunk so that bottom-right masking reproduces each row's absolute causal length; on a top-left frontend the same call masks top-left and the top-k reads -inf columns inside the row's length, silently changing the selection. Pass the bottom-right offset explicitly when the installed frontend is 1.26 or newer and the offset is non-zero. Older frontends and square (zero-offset) calls keep their exact call and kernel compile key. A top-left frontend whose wrapper lacks q_causal_offsets fails closed. Add CPU fakes of both frontend generations (dsa_cudnn_fe_fakes.py: BottomRightDefaultDSA for FE <= 1.25, Fe131DSA) and tests that the cropped segment scorer selects identical top-k on either default; the offset tests cover the 1.25 / 1.26 boundary. The native parity tests install fakes that model the frontend <= 1.25 wrappers, so while a fake namespace is installed they now report frontend 1.21 instead of the installed cudnn version; on a host with FE >= 1.26 the offset gate would otherwise treat those fakes as a top-left frontend and fail four tests. The real namespace keeps reporting the installed version, so the real-kernel tests still exercise the top-left path. The fake indexer_backward_wrapper of the five sparse-loss tests in test_dsa_native_parity.py (selected scores, masked query rows, TP reduction, batch-major ids for batched KV, sequence chunking) now takes a required topk_indices_global argument and asserts it is True, so they fail without the sparse-backward fix; the batched-KV test is the BSHD micro-batch > 1 case. Main port. Main has neither dev's DSA pre-attention scorer dispatch (NVIDIA#6206) nor its utils.filter_kwargs_for_callable or row-limit warning wrapper, so: - the cuDNN wrapper signature is probed locally (_wrapper_accepts_kwarg); - the multi-sequence packed CP THD scorer (_indexer_topk_multi_packed_cp_thd) gets per-segment bottom-right offsets on FE >= 1.26. On dev, NVIDIA#6206 already passes these offsets; on main this varlen call relied on the FE <= 1.25 default, so packed THD with CP > 1 selected from top-left-masked key prefixes on main's FE 1.29.1 pin. Tests cover it across both frontend defaults, with a negative control; - the tests call main's _indexer_topk_single_packed_cp_segments signature. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Robin Zhang <robinz@nvidia.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
This branch has not been deployed
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.
Summary
Main counterpart of #8534.
cuDNN frontend 1.26 (NVIDIA/cudnn-frontend#316) changed two defaults that the DSA cuDNN call sites rely on.
mainpins FE 1.29.1, so both issues are live onmain. Both are silent: no error, just wrong gradients or a wrong top-k selection.1. Sparse indexer backward: top-k ids are treated as per-batch local
Since FE 1.26,
indexer_backward_wrappertreats top-k ids as local to each batch unlesstopk_indices_global=True. The sparse-indexer-loss path passes global ids (b * S_k + local). With BSHD and more than one sequence per micro-batch, every batch after the first loses its sparse indexer gradient on FE 1.29.The wrapper is now called through
_call_sparse_indexer_backward. It setstopk_indices_global=Truewhenever the installed wrapper accepts that parameter (or takes**kwargs), and keeps the old call otherwise.2. Causal offsets: the default alignment moved from bottom-right to top-left
When
q_causal_offsetsis not given, FE <= 1.25 aligns the causal mask bottom-right (seqlen_k * ratio - seqlen_q), and FE >= 1.26 aligns it top-left (offset 0). Onmain, three callers relied on the old default:_indexer_topk_single_packed_cp_segments). It crops each query chunk's key prefix so that bottom-right masking gives each row its absolute causal length._indexer_topk_multi_packed_cp_thd). Its varlen call gives each query segment a longer key prefix and passed no offsets. Ondev, [dev](perf): DSA pre-attention: plan-driven scorer dispatch, host-built CP layout metadata #6206 already passes these offsets;maindoes not have [dev](perf): DSA pre-attention: plan-driven scorer dispatch, host-built CP layout metadata #6206.With FE 1.26 or newer, the bottom-right offsets are now passed explicitly: a uniform offset for BSHD calls, and per-segment offsets (
segment_k_lengths - segment_q_lengths) for the THD call. Older frontends and zero-offset calls keep their exact call and kernel compile key. A top-left frontend whose wrapper lacksq_causal_offsetsfails closed.Differences from the dev PR
mainhas noutils.filter_kwargs_for_callable, so the wrapper signature is probed locally (_wrapper_accepts_kwarg).devit is already correct.main's_indexer_topk_single_packed_cp_segmentssignature.Test plan
test_dsa_cudnn_fe_compat.py, 23 passed. They use fakes of both frontend generations (dsa_cudnn_fe_fakes.py) and cover:test_dsa_native_parity.py, the fakeindexer_backward_wrapperused by the sparse-loss tests requirestopk_indices_global=True.test_dsa_native_parity.pyandtest_attention_variant_dsa.pygive the same results on this branch and onmain. The 3 failures and 34 errors are identical on both and come from the CPU environment.main's pin. One standalone script ran againstmainand against this branch, calling the affected functions directly:Sparse indexer backward, BSHD micro-batch 2. The reference is the same rows run as two b=1 calls, scaled for the row-mean loss.
main: batch 1 gets all-zero dQ/dW/dK.Top-k recall against an fp32 torch top-k over each row's absolute causal keys (mean / min):
mainOn
main, the selected keys stay inside each row's bounds, but tens of thousands of them score below the reference k-th score: top-k ran over a top-left-masked key range.CHECK_ONLY=true BASE_REF=main tools/autoformat.sh(black 26.3.0, isort, pylint, ruff)Overlap with open PRs
dsa_cudnn_kernels.pyand conflicts textually; whichever lands second rebases.dsa_cudnn_kernels.py; the move would carry these hunks.🤖 Generated with Claude Code