[None][fix] Make indexer top-K launch policy device-aware#13886
Conversation
e35aea3 to
e72ae10
Compare
|
/bot run |
|
PR_Github #47374 [ run ] triggered by Bot. Commit: |
|
PR_Github #47374 [ run ] completed with state
|
|
/bot run |
959db42 to
a948f52
Compare
|
/bot run |
1 similar comment
|
/bot run |
|
PR_Github #47675 [ run ] triggered by Bot. Commit: |
a948f52 to
a373c1a
Compare
|
PR_Github #47675 [ run ] completed with state |
|
/bot run --add-multi-gpu-test --disable-fail-fast |
|
PR_Github #47682 [ run ] triggered by Bot. Commit: |
|
PR_Github #47682 [ run ] completed with state |
72c3df9 to
1f8e33c
Compare
longcheng-nv
left a comment
There was a problem hiding this comment.
Reviewed end-to-end with focus on substantive correctness / perf / coverage concerns. Posted 4 inline comments + this top-level point on perf table coverage. Detailed analysis is in the inline threads.
Perf table coverage gaps (top-level / PR description)
Table is K ∈ {512, 1024, 2048} × BS ∈ {1, 32} × cols ∈ {131K, 196K} = 9 cells. The policy change affects considerably more state space:
BS ∈ {64, 96, 128, 148}— exactly the wave-fit edge and the bump-to-2 band (see inline thread onindexerTopK.cu). Nothing currently shows whether the win generalizes here or whether it regresses.BS=1, N≈8K— production GVR heuristic path on DeepSeek decode; this PR refactors the single-block dispatcher and the aux-skip logic that this path traverses. One row would prove no regression.- Prefill — see inline thread on
invokeIndexerTopKPrefill. Algorithm-selection change deserves at least 1-2 prefill perf rows.
Adding ~3-4 rows would close the loop.
Overall: solid framing on device-aware launch + wave-fit. The headline BS=32 × cols=131K = 1.27× wins are clean — the inline comments are about widening confidence the win generalizes (1-3) and maintainability hardening (4).
352fa49 to
c5d85fb
Compare
0a93d10 to
118e7a5
Compare
computeIndexerTopKDecodeBlocksPerRow used a fixed kDecodeTargetTotalBlocks
= 132 for smTarget. On B200 (148 SMs) the fixed constant leaves 16 SMs
idle in the ceil-rounded band (numRows in [133, 148]): smTarget rounds to
1 (132/numRows < 1) so each row launches a single block, even though two
sub-blocks per row would fit in one wave. Querying the device via
getSchemeXBounds().smCount lifts that band to smTarget = 2 and saturates
both waves' worth of SMs.
Adds test_indexer_topk_decode_launch_policy_transitions covering
batch_size in {1, 64, 100, 133, 256} so the smTarget transitions stay
regression-protected; complements the existing decode_sm_saturation case.
The new helper _run_indexer_topk_prefill_check extracts the prefill check
body so future prefill regression tests can call it directly.
Measured on B200, fp32 logits, topK = 2048, next_n = 1:
numRows | numColumns | baseline | after | speedup
--------|------------|---------:|-------:|--------:
133 | 196608 | 261.4us | 124.6us| 2.10x
133 | 131072 | 175.3us | 92.2us| 1.90x
64/100 | 131072+ | - | - | unchanged
148/200 | 196608 | - | - | unchanged
Supersedes PR NVIDIA#13886. The competing computeIndexerTopKDecodeLaunchPolicy
struct and canUseHeuristicTopKDecode helper in that PR are made
redundant by the SchemeX v1.2 dispatcher that landed independently;
the bump-to-2 path is similarly subsumed by smTarget = ceil(smCount /
numRows). Only the device-aware change is retained here.
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com>
93c46ff to
af25d9d
Compare
af25d9d to
2ec03c9
Compare
|
/bot run --disable-fail-fast |
|
PR_Github #48396 [ run ] triggered by Bot. Commit: |
|
PR_Github #48396 [ run ] completed with state |
Remove the hardcoded constants in computeIndexerTopKDecodeBlocksPerRow
and route the cliff band through the multi-block path:
* kDecodeTargetTotalBlocks = 132 (H100 SM count) is deleted. The
smTarget heuristic now queries the actual device SM count via
getSchemeXBounds().smCount (cudaDeviceGetAttribute, cached) so the
dispatch tracks the hardware on B200 (148 SMs) and beyond.
* kNumBins is hoisted to namespace scope (was duplicated as two
function-local copies inside topKPerRowDecode / topKPerRowPrefill).
kDecodeMinColsPerSubBlock = kNumBins and kSortingAlgorithmThreshold
= 6 * kNumBins are now derived from it instead of being independent
magic numbers.
* Function-local copies of kSortingAlgorithmThreshold = 12288 and
kDefaultSplitWorkThreshold = 200000 in invokeIndexerTopKDecodeDtype,
invokeIndexerTopKPrefill, and canIndexerTopKDecodeUseGvr are removed
in favor of the file-scope constants.
The new dispatch heuristic uses two device-derived branches:
numRows < smCount / 2 → wave-quantization-aware sweep over bp ∈
[2, maxBp] minimizing waves(bp) / bp; this
avoids the +1-block-per-row wave-boundary
spill that a naive ceil(smCount / numRows)
target would produce on B200 (e.g. BS=15
stays at 1 wave instead of 2).
numRows >= smCount / 2 → bp = 2. bp=1 in this band lands on the
single-block radix kernel, which pays a
sharp wave-scheduling cliff once gridDim.x
approaches smCount (B200, cols=196608,
topK=2048: BS=131=125us, BS=132=312us,
BS=148=390us). The multi-block split+merge
path is a different kernel instantiation and
does not have this cliff; bp=2 is the
cheapest split (smallest merge input).
Measured speedup on B200 vs baseline (cols=196608, fp32 logits,
next_n=1, no preIdx), across the three production topK values:
topK BS BASELINE NEW speedup
512 100 93.5 89.3 1.05x
512 132 288.4 107.6 2.68x
512 148 384.0 112.2 3.42x
512 200 409.8 144.0 2.85x
512 300 460.9 228.4 2.02x
1024 100 93.6 90.2 1.04x
1024 132 289.0 109.0 2.65x
1024 148 386.3 113.3 3.41x
1024 200 413.3 145.1 2.85x
1024 300 465.3 230.7 2.02x
2048 100 107.7 105.6 1.02x
2048 132 296.6 124.7 2.38x
2048 148 392.1 130.3 3.01x
2048 200 419.4 172.9 2.43x
2048 300 473.3 274.1 1.73x
BS < smCount / 2 is unchanged within measurement noise.
Adds test_indexer_topk_decode_launch_policy_transitions covering
batch_size in {1, 64, 100, 132, 148, 256} so the path-switch boundary
stays regression-protected; the existing test_indexer_topk_decode_sm_saturation
parametrization is kept verbatim. The new helper
_run_indexer_topk_prefill_check extracts the prefill check body so
future prefill regression tests can call it directly.
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com>
2ec03c9 to
fb2be5e
Compare
|
Looking at the force-pushed 1. The The new
The new in-code comment justifies the bump with 2. Test comment contradicts the code. The new comment above
But the actual threshold in the code is 3. Undocumented behavior change: SM-count query failure now hard-aborts. - int const smCount = bounds.smCount > 0 ? bounds.smCount : 132;
+ TLLM_CHECK_WITH_INFO(bounds.smCount > 0, "indexerTopK: failed to query device SM count");
+ int const smCount = bounds.smCount;Previous revs had a soft 132 fallback; this rev throws. Two questions: (a) is there any test/CI environment (CPU-only sandbox, mocked CUDA) where 4. CI has not run on The last The PR-type bump ( |
|
/bot run --disable-fail-fast |
1 similar comment
|
/bot run --disable-fail-fast |
|
PR_Github #48497 [ run ] triggered by Bot. Commit: |
|
PR_Github #48497 [ run ] completed with state |
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com> (cherry picked from commit 4aad70b) Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com> (cherry picked from commit 4aad70b) Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com> (cherry picked from commit 4aad70b) Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com> (cherry picked from commit 4aad70b) Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com> (cherry picked from commit 4aad70b) Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com> (cherry picked from commit 4aad70b) Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com> (cherry picked from commit 4aad70b) Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Signed-off-by: Mingyang Hao <mingyangh@nvidia.com> (cherry picked from commit 4aad70b) Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
@coderabbitai summary
Description
Magic number audit
kDecodeTargetTotalBlocks132(H100 SM count)getSchemeXBounds().smCountkNumBins2048× 2 function-local copieskSortingAlgorithmThreshold12288(file-scope + 2 function-local copies)6 * kNumBins(namespace scope only; duplicates removed)kDecodeMinColsPerSubBlock2048kNumBinskDefaultSplitWorkThreshold200 * 1000(file-scope + 2 function-local copies)kMaxBlocksPerRowDecode10Perf data (B200, fp32 logits, cols=196608, next_n=1, no preIdx)
Production batch sizes (BS=1/32/128 — covering the original PR's perf table):
Cliff band (BS=100-300):
Test Coverage
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)
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.