[https://nvbugs/6432948][fix] Add per-engine flag _trtllm_gen_jit_warmup_done; skip… - #16205
[https://nvbugs/6432948][fix] Add per-engine flag _trtllm_gen_jit_warmup_done; skip…#16205trtllm-agent wants to merge 3 commits into
_trtllm_gen_jit_warmup_done; skip…#16205Conversation
|
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
| perf/test_perf.py::test_perf[whisper_large_v3-bench-float16-input_output_len:128,20] SKIP | ||
| perf/test_perf_sanity.py::test_e2e[aggr_upload-deepseek_r1_fp4_v2_grace_blackwell-r1_fp4_v2_dep4_mtp1_1k8k] SKIP (https://nvbugs/6422339) | ||
| perf/test_perf_sanity.py::test_e2e[aggr_upload-deepseek_r1_fp8_blackwell-r1_fp8_tp8_mtp3_1k1k] SKIP (https://nvbugs/6445332) | ||
| perf/test_perf_sanity.py::test_e2e[aggr_upload-deepseek_r1_fp8_blackwell-r1_fp8_tp8_mtp3_8k1k] SKIP (https://nvbugs/6432948) |
There was a problem hiding this comment.
The code change looks like a good improvement, but I'm not seeing how it addresses the root cause of the flaky failure. The error was cudaStreamDestroy(stream): an illegal memory access was encountered, not an out of memory issue.
If you want to move forward with this as a fix, please run the test several times to ensure it passes consistently.
39b1dd5 to
2995242
Compare
2995242 to
4cb6611
Compare
4cb6611 to
acb9a9d
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp (1)
480-504: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse braces and
constin the fallback candidate loop.Add braces to the
ifbody at Lines 482-483. Declare unmodifiedt,env, andvalidvalues asconst.Proposed fix
- for (auto t : mSupportedTileN) + for (auto const t : mSupportedTileN) { if (t != tileN) + { tileN_candidates.push_back(t); + } } static int const fusedMinTileNFallback = []() { - char const* env = std::getenv("TLLM_MOE_FUSED_MIN_TILEN"); + char const* const env = std::getenv("TLLM_MOE_FUSED_MIN_TILEN"); return env != nullptr ? std::atoi(env) : 32; }(); - for (auto t : tileN_candidates) + for (auto const t : tileN_candidates) { if (t < fusedMinTileNFallback) { continue; } - auto valid = mRunners.at(t)->getValidConfigIndices( + auto const valid = mRunners.at(t)->getValidConfigIndices(As per coding guidelines, “always brace if/else, loop, and switch bodies” and “declare unmodified variables as
const.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp` around lines 480 - 504, Update the fallback candidate loop to brace the if body that skips candidates below fusedMinTileNFallback, and declare the unmodified loop variable t, environment pointer env, and valid configuration result as const. Preserve the existing candidate filtering and selection behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp`:
- Around line 480-504: Update the fallback candidate loop to brace the if body
that skips candidates below fusedMinTileNFallback, and declare the unmodified
loop variable t, environment pointer env, and valid configuration result as
const. Preserve the existing candidate filtering and selection behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: c17ff890-8c14-4a9a-8ea0-6dae2406b3fc
📒 Files selected for processing (1)
cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp
acb9a9d to
8946584
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
leslie-fang25
left a comment
There was a problem hiding this comment.
The title doesn't match what changes in this PR.
| for (auto& [tileN, runner] : mRunners) | ||
| { | ||
| if (numFusedSharedExpert.value_or(0) > 0 && tileN < fusedMinTileN) | ||
| if (tileN < fusedMinTileN) |
There was a problem hiding this comment.
I think the IMA issues we met only happens when numFusedSharedExpert large than 0. Please explain why apply it for all the fp8 tactic.
8946584 to
d6e0cc8
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
021a99e to
f6ceed3
Compare
…ase-2 warmup create_py_executor's two-phase KV-cache-estimation flow instantiates PyExecutor twice against the same model_engine, so warmup - and therefore _run_attention_warmup - runs twice. The TRTLLM-Gen FMHA JIT kernel cache is process-global, so the second grid enumeration compiles nothing new. For DeepSeek-R1 FP8 TP=8 MTP3 with max_num_tokens=12288 on B200, running the grid a second time - after autotuner exploration and CUDA-graph capture have consumed most of GPU memory - occasionally triggers an illegal memory access asynchronously reported at torch.cuda.synchronize() in _run_attention_warmup. Add a per-engine _trtllm_gen_jit_warmup_done flag: first call runs the full grid and sets the flag; subsequent calls short-circuit with a logger.info. Correctness is preserved because the JIT cache from Phase-1 already covers every shape Phase-2 could request; any kernel not yet compiled would JIT-compile lazily on first request anyway. Verified: 1 passed in 230.48s on B200 tp8 (previously EXIT_CODE=1 at 1071s with CUDA IMA in _run_attention_warmup during Phase-2 restart). Signed-off-by: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com>
Signed-off-by: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com>
…-scale MoE The TRTLLM-Gen small-tile (tileN 8/16) dynB batched-GEMM cubins flakily hit an illegal memory access in the gemm2 K-loop. PR NVIDIA#15297 already added a WAR for this exact fault -- restricting tactics to tileN >= 32 -- but scoped it to the fused shared-expert path via num_fused_shared_experts > 0. Shared-expert fusion is opt-in (TLLM_MOE_ENABLE_SHARED_EXPERT_FUSION, default off), so DeepSeek-R1 FP8 TP=8 runs unfused and never reached the exclusion. It faults identically: the defect is in the shared small-tile cubins, not caused by expert fusion. Apply the exclusion for every caller, at both selection sites (getValidConfigs and the tileN == -1 fallback in run()). Measured on DeepSeek-R1 FP8 EP=1 (B200, SM100f): the warmup shapes that fault (1/2/8 tokens) were the only ones able to select tileN 8/16, while the 12288 token shape gets tileN 64/128 and always passed. After the change every shape from 1 to 12288 tokens offers only tileN >= 32, and all five Phase-2 warmup shapes complete where the second previously crashed. The tiles stay in mSupportedTileN: the ctor builds one runner per tile and each asserts a non-empty passing-config list, so the exclusion must happen at tactic-selection time rather than by dropping the tile. This is safe because every FP8 block-scale MoE shape retains a tileN >= 32 tactic -- verified across DeepSeek-R1 (EP 1/4/8), Qwen3-235B and Qwen3-30B -- so the tactic list is never emptied. The waiver is kept: an independent illegal memory access remains in the Phase-2 autotuner warmup, which this change does not address. Signed-off-by: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com>
f6ceed3 to
f00fd2b
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp`:
- Line 423: Update the tile-selection flow around computeSelectedTileN to first
filter the supported tile list to values at least fusedMinTileN, pass that
eligible list into the heuristic, and explicitly reject fusedMinTileN values
above the largest supported tile. Ensure the later tileN threshold check only
evaluates tiles from the filtered list, while preserving valid selection of tile
64 and larger.
- Around line 482-483: Add braces around the body of the conditional in the
tileN candidate logic, preserving the existing push_back behavior when t !=
tileN.
- Around line 485-489: Replace the independent TLLM_MOE_FUSED_MIN_TILEN parsing
in both selection paths, including fusedMinTileNFallback, with one shared C++17
std::from_chars-based parser. Parse the environment variable once, reject
malformed, non-positive, and otherwise unsupported thresholds, and use the
validated fallback consistently so tileN 8/16 cubins cannot be selected by
invalid input.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 4f9de668-f431-4985-88fc-dab84dc98e63
📒 Files selected for processing (1)
cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp
| for (auto& [tileN, runner] : mRunners) | ||
| { | ||
| if (numFusedSharedExpert.value_or(0) > 0 && tileN < fusedMinTileN) | ||
| if (tileN < fusedMinTileN) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Filter the supported tile list before heuristic selection.
If TLLM_MOE_FUSED_MIN_TILEN is 64, a small workload can select only 8, 16, and 32. Line 423 then rejects every selected tile, even when tile 64 has valid configurations.
Build the eligible tile list first. Pass that list to computeSelectedTileN. Reject thresholds above the largest supported tile explicitly.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp` at line 423, Update the
tile-selection flow around computeSelectedTileN to first filter the supported
tile list to values at least fusedMinTileN, pass that eligible list into the
heuristic, and explicitly reject fusedMinTileN values above the largest
supported tile. Ensure the later tileN threshold check only evaluates tiles from
the filtered list, while preserving valid selection of tile 64 and larger.
| if (t != tileN) | ||
| tileN_candidates.push_back(t); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Brace the conditional body.
The C++ guidelines require braces for every conditional body.
Proposed fix
- if (t != tileN)
+ if (t != tileN)
+ {
tileN_candidates.push_back(t);
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (t != tileN) | |
| tileN_candidates.push_back(t); | |
| if (t != tileN) | |
| { | |
| tileN_candidates.push_back(t); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp` around lines 482 - 483, Add
braces around the body of the conditional in the tileN candidate logic,
preserving the existing push_back behavior when t != tileN.
Source: Coding guidelines
| static int const fusedMinTileNFallback = []() | ||
| { | ||
| char const* env = std::getenv("TLLM_MOE_FUSED_MIN_TILEN"); | ||
| return env != nullptr ? std::atoi(env) : 32; | ||
| }(); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Verify the declared C++ language standard before using std::from_chars.
rg -n -C 2 'CXX_STANDARD|cxx_std_|CMAKE_CXX_STANDARD' \
-g 'CMakeLists.txt' -g '*.cmake' -g 'meson.build' -g 'BUILD' -g 'BUILD.bazel' .
# Trace all threshold parsing sites that must use the same checked accessor.
rg -n -C 4 'TLLM_MOE_FUSED_MIN_TILEN|std::atoi' cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cppRepository: NVIDIA/TensorRT-LLM
Length of output: 6687
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- target source ---'
sed -n '380,435p' cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp
sed -n '455,515p' cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp
printf '%s\n' '--- declarations and includes relevant to parsing/selection ---'
sed -n '1,90p' cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp
rg -n -C 3 'computeSelectedTileN|fusedMinTileN|TLLM_MOE_FUSED_MIN_TILEN|atoi|from_chars|charconv' \
cpp/tensorrt_llm/thop cpp/tests
printf '%s\n' '--- repository guidance ---'
if [ -f CODING_GUIDELINES.md ]; then
sed -n '1,220p' CODING_GUIDELINES.md
fiRepository: NVIDIA/TensorRT-LLM
Length of output: 30379
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import ctypes
# Model the exact conversion used by std::atoi for representative environment
# values, without executing repository code.
samples = ["", "abc", "32abc", "-1", "0", "8", "16", "32", "64", "999999999999999999999"]
for value in samples:
encoded = value.encode()
result = ctypes.CDLL(None).atoi(encoded)
print(f"{value!r} -> {result}")
PYRepository: NVIDIA/TensorRT-LLM
Length of output: 282
Parse TLLM_MOE_FUSED_MIN_TILEN once and reject invalid values.
std::atoi returns 0 for malformed input such as abc. This disables the small-tile exclusion and can select the known unsafe tileN 8/16 cubins. Both selection paths parse the variable independently. Use one shared checked parser and reject malformed or unsupported thresholds. std::from_chars is available under the project’s C++17 standard.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp` around lines 485 - 489, Replace
the independent TLLM_MOE_FUSED_MIN_TILEN parsing in both selection paths,
including fusedMinTileNFallback, with one shared C++17 std::from_chars-based
parser. Parse the environment variable once, reject malformed, non-positive, and
otherwise unsupported thresholds, and use the validated fallback consistently so
tileN 8/16 cubins cannot be selected by invalid input.
Source: Coding guidelines
Summary
_trtllm_gen_jit_warmup_done; skip _run_attention_warmup's JIT warmup body on the second and subsequent invocations with an informational log — Phase-1 semantics unchanged, redundant Phase-2 grid enumeration eliminated.Test plan
Links
Dev Engineer Review
fp8BlockScaleMoe.cppto exclude tiles below the configured minimum for all tactic-selection callers.QA Engineer Review
No test changes.