[None][perf] Skip DeepGEMM clean_logits in DSA indexer prefill on custom top-k path#16789
Open
dc3671 wants to merge 1 commit into
Open
[None][perf] Skip DeepGEMM clean_logits in DSA indexer prefill on custom top-k path#16789dc3671 wants to merge 1 commit into
dc3671 wants to merge 1 commit into
Conversation
…-k path The DeepGEMM MQA-logits kernels (fp8_mqa_logits / fp8_fp4_mqa_logits) default clean_logits=true: after computing logits they launch smxx_clean_logits to fill every element outside each row's causal window [ks, ke) with -inf. This protects consumers that scan the full padded logits row. The default prefill path (use_custom_topk=True) uses the custom indexer_topk_prefill kernel (cpp/tensorrt_llm/kernels/indexerTopK.cu), whose topKPerRowPrefill reads strictly [rowStart, rowEnd) == [ks, ke) per row and never touches the padding outside that window. So the -inf fill is pure waste on this path. Only the torch-fallback path (use_custom_topk= False), which runs logits.topk over the full padded row, needs the fill. This plumbs a clean_logits flag through _call_mqa_logits and passes clean_logits=not use_custom_topk at both prefill call sites (chunked-prefill tile loop and single-pass fallback). Decode is unaffected: the paged variants already default clean_logits=false. Validated on Rubin DEP8 MTP3 8k1k (DeepSeek-V4-Pro, aggregated ctx-only): nsys confirms smxx_clean_logits (5.96 ms x210 instances, 0.11% GPU kernel time) is fully removed while fp8_fp4_mqa_logits (19.45 ms) and topKPerRowPrefill (32 ms) are byte-identical, so top-k output is unchanged. Indexer unit tests pass with and without the fill (tests/unittest/_torch/attention/sparse/, -k indexer). End-to-end throughput is flat (within run-to-run noise) since the removed kernel is tiny and PDL-overlapped; the change is correctness-neutral waste removal. Signed-off-by: Zhenhuan Chen <chenzhh3671@gmail.com>
Contributor
Walkthrough
ChangesDSA logits cleaning
Estimated code review effort: 3 (Moderate) | ~15–30 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Collaborator
Author
|
/bot run |
Collaborator
|
PR_Github #61260 [ run ] triggered by Bot. Commit: |
Collaborator
|
PR_Github #61260 [ run ] completed with state
|
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.
Description
Background
The DeepGEMM MQA-logits kernels used by the DeepSeek-V3.2/V4 DSA indexer (
fp8_mqa_logits/fp8_fp4_mqa_logits) defaultclean_logits=true. After computing the logits they launch an extrasmxx_clean_logitskernel that fills every element outside each row's causal window[ks, ke)with-inf. The logits buffer istorch.emptywith a padded, 1024-byte-aligned row stride, so this fill exists to stop consumers that scan the full padded row from selecting uninitialized garbage into the top-k.The default prefill path (
use_custom_topk=True) does not scan the full row. It uses the customindexer_topk_prefillkernel (cpp/tensorrt_llm/kernels/indexerTopK.cu), whosetopKPerRowPrefillreads strictly[rowStart, rowEnd) == [ks, ke)per row (rowStart = rowStarts[rowIdx],rowEnd = rowEnds[rowIdx], and every load intopKPerRowJob/processHistogramStepis bounded by that window). The padding outside the window is never read, so the-inffill is pure waste on this path.Only the torch-fallback path (
use_custom_topk=False), which runslogits.topkover the full padded row, actually needs the fill.Solution
Plumb a
clean_logitsflag throughIndexer._call_mqa_logitsand passclean_logits=not use_custom_topkat both prefill call sites (the chunked-prefill tile loop and the single-pass fallback). Production runs (custom top-k, the default; no caller overrides it) skip the clean kernel; the torch fallback keeps the fill and stays correct. Decode is unaffected — the paged variants already defaultclean_logits=false.Impact
[ks, ke), so skipping the fill cannot change its output.Validation
Rubin, DeepSeek-V4-Pro, DEP8 (TP8/EP8 attention-DP) MTP3, 8k-in/1k-out, aggregated ctx-only
trtllm-bench, nsys on rank 0:smxx_clean_logitsfp8_fp4_mqa_logitstopKPerRowPrefillThe MQA-logits and top-k kernels are byte-identical across the two runs, i.e. top-k output is unchanged. End-to-end throughput is flat within run-to-run noise.
Test Coverage
Existing indexer top-k tests in
tests/unittest/_torch/attention/sparse/compare against a reference implementation and pass on both flag states, so no new tests are added:PR Checklist
Please review the following before submitting your PR:
PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.
PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.
Test cases are provided for new code paths (see test instructions)
If PR introduces API changes, an appropriate PR label is added - either
api-compatibleorapi-breaking. Forapi-breaking, includeBREAKINGin the PR title.Any new dependencies have been scanned for license and vulnerabilities
CODEOWNERS updated if ownership changes
Documentation updated as needed
Update tava architecture diagram if there is a significant design change in PR.
The reviewers assigned automatically/manually are appropriate for the PR.
Please check this after reviewing the above items as appropriate for this PR.
GitHub Bot Help
To see a list of available CI bot commands, please comment
/bot help.