[https://nvbugs/6432948][fix] Exclude TRTLLM-Gen small tileN (8/16) for all FP8 block-scale MoE tactic selection - #16205
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughFP8 block-scale MoE tactic selection now excludes undersized tiles for fused and unfused workloads. Fallback selection validates configurations, skips undersized tiles, prioritizes the heuristic tile, and errors when no valid configuration exists. ChangesFP8 MoE tactic selection
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
98dcf31 to
39b1dd5
Compare
39b1dd5 to
2995242
Compare
2995242 to
4cb6611
Compare
4cb6611 to
acb9a9d
Compare
298e6ec to
94ec436
Compare
95a8a46 to
b98332e
Compare
…FP8 block-scale MoE The small-tile (tileN 8/16) dynB TRTLLM-Gen batched-GEMM cubins flakily hit an illegal memory access (garbage TMA-descriptor pointer, MMU fault in the gemm2 K-loop). tileN >= 32 is unaffected (10/10 clean vs minutes-to-crash baseline on B300 TP=4). The existing workaround excluded those tiles only when shared experts were fused into the grouped GEMM (num_fused_shared_experts > 0). That scoping was wrong: the defect is in the shared small-tile cubins and is not caused by expert fusion. DeepSeek-R1 FP8 TP=8 (unfused) faults identically during warmup, where the 1/2/8-token shapes are the only ones that can select tileN 8/16 (12288 tokens gets tileN 64/128 and always passes). The same was already observed in NVIDIA#15297, where the IMA reproduced with num_fused_shared_experts=0. Changes: - Hoist the threshold into a single moeMinTileN() accessor built on common::getIntEnv, replacing two independently parsed function-local statics that both used unchecked std::atoi. Rename the knob to TLLM_MOE_MIN_TILEN and keep TLLM_MOE_FUSED_MIN_TILEN as a deprecated alias, since the exclusion is no longer scoped to the fused path. - Precompute mEligibleTileN in the ctor and drive both tactic selection and the tileN heuristic from it. Running computeSelectedTileN on the eligible list rather than on mSupportedTileN keeps the excluded tiles from consuming the returned neighbourhood: a shape whose heuristic tile is 8 now gets {32, 64, 128} instead of being left with 32 as its only candidate. - Reject a threshold that excludes every supported tile at construction time instead of silently returning an empty tactic list. - Include the problem dimensions in the fused fallback's no-valid-config error so a report from an unchecked model is actionable without a repro. The unfused fallback keeps getDefaultValidConfigIndex. An earlier revision of this change routed it through getValidConfigIndices(...).front() as well, but that helper returns the first pair in raw cartesian order, whereas getDefaultValidConfigIndex returns the first entry of the list sorted by the perf heuristic in KernelRunner.cpp. Switching it would have changed the selected kernel config for all default-path traffic, which is unrelated to this fix. Signed-off-by: ZhaoyangWang <zhaoyangw@nvidia.com>
|
/bot run |
|
PR_Github #68644 [ run ] triggered by Bot. Commit: |
|
PR_Github #68644 [ run ] completed with state
|
|
The PR fix was not the root case, #18133 fix it, closed this PR. |
Description
The small-tile (tileN 8/16) dynB TRTLLM-Gen batched-GEMM cubins flakily hit an illegal memory access
(garbage TMA-descriptor pointer, MMU fault in the gemm2 K-loop). tileN >= 32 is unaffected
(10/10 clean vs. minutes-to-crash baseline on B300 TP=4).
The existing workaround excluded those tiles only when shared experts were fused into the grouped GEMM
(
num_fused_shared_experts > 0). That scoping was wrong: the defect is in the shared small-tile cubinsand is not caused by expert fusion. DeepSeek-R1 FP8 TP=8 (unfused) faults identically during warmup,
where the 1/2/8-token shapes are the only ones that can select tileN 8/16 (12288 tokens gets tileN
64/128 and always passes). The same was already observed in #15297, where the IMA reproduced with
num_fused_shared_experts=0and cuda-gdb pointed at a tileN-8dynB_sm100fcubin faulting onUTMALDG.4D.Changes:
moeMinTileN()accessor built oncommon::getIntEnv, replacing twoindependently parsed function-local statics that both used unchecked
std::atoi(an unparseable valuesilently disabled the WAR). The knob is renamed to
TLLM_MOE_MIN_TILEN, withTLLM_MOE_FUSED_MIN_TILENkept as a deprecated alias since the exclusion is no longer scoped to thefused path.
mEligibleTileNin the ctor and drive both tactic selection and the tileN heuristic fromit. Running
computeSelectedTileNon the eligible list rather than onmSupportedTileNkeeps theexcluded tiles from consuming the returned neighbourhood: a shape whose heuristic tile is 8 now gets
{32, 64, 128}instead of being left with 32 as its only candidate.returning an empty tactic list.
unchecked model is actionable without a repro.
The unfused fallback keeps
getDefaultValidConfigIndex. An earlier revision of this PR routed itthrough
getValidConfigIndices(...).front()as well; that was reverted because the two differ inordering, not in validation --
getDefaultValidConfigIndexreturns the first entry of the list sortedby the perf heuristic in
KernelRunner.cpp:540-598, whereasgetValidConfigIndices(...).front()takesthe first valid pair in raw cartesian order. Switching it would have changed the selected kernel config
for all default-path traffic, which is unrelated to this fix. This PR is now scoped to widening the
tileN exclusion only.
This is a runtime-side workaround; it can be reverted once the kernel-side fix lands.
Test Coverage
No new tests -- this changes tactic selection only and is covered by the existing FP8 block-scale MoE
tests (
test_trtllm_fp8_block_scales*intests/unittest/_torch/modules/moe/test_moe_backend.py, onl0_b200/l0_b300).Crash-freedom:
Cost of the exclusion, measured op-level on B200 with DeepSeek-R1 FP8 EP=8 shapes
(hidden=7168, intermediate=2048, num_experts=256, local_experts=32, top_k=8). Each (num_tokens, tileN)
combination runs in its own process; the number reported is the best config for that tile, i.e. what the
autotuner would converge to.
Worst case is +5.3% at 16 tokens, with every other point within +/-3% and two points slightly faster.
Note that the small tiles did not fault during this sweep -- the IMA is flaky and reproduces with
cascaded runs over real captured
token_ids-- so these numbers bound the cost of the WAR but saynothing about its necessity.
TLLM_MOE_MIN_TILEN=0restores the previous behaviour for A/B experiments.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.
Links
GitHub Bot Help
To see a list of available CI bot commands, please comment
/bot help.