Skip to content

[None][perf] Optimize MiniMax-M3 MXFP8 GEMMs - #17238

Open
peihu-nv wants to merge 6 commits into
NVIDIA:mainfrom
peihu-nv:peihengh/m3-mxfp8-autotuner-main-20260803
Open

[None][perf] Optimize MiniMax-M3 MXFP8 GEMMs#17238
peihu-nv wants to merge 6 commits into
NVIDIA:mainfrom
peihu-nv:peihengh/m3-mxfp8-autotuner-main-20260803

Conversation

@peihu-nv

@peihu-nv peihu-nv commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Added FlashInfer MXFP8 decode-graph dispatch and warmup for eligible MiniMax-M3 workloads.
  • Preserved TensorRT-LLM execution for eager, context, prefill, and piecewise graph paths.
  • Added native CUTLASS tactic autotuning for large-M MXFP8 GEMMs.
  • Added thread-safe, shape-aware tactic caching through MXFP8GemmRunner.
  • Added backend validation, fallback handling, rank synchronization, and autotuning state controls.
  • Reported gains include higher throughput and lower latency on GB200 and GB300 benchmarks.

Dev Engineer Review

  • The implementation separates FlashInfer and native MXFP8 warmup passes.
  • enable_autotuner=False disables FlashInfer and native MXFP8 warmup.
  • Native autotuning falls back after a missing warmup batch.
  • FlashInfer availability is synchronized across tensor-parallel ranks.
  • Graph-captured FlashInfer output is compared with eager native output.
  • Tactic cache keys include SM version, output dtype, bucketed M, N, and K.
  • Dispatch order is explicit configuration, cached configuration, then default configuration.
  • Backend validation and fallback paths are covered by tests.
  • No configuration-file changes were reported.
  • Test-list changes add MXFP8 linear coverage to the B200 and B300 pre-merge suites.
  • Verdict: sufficient based on the reported implementation and validation results.

QA Engineer Review

Modified test-list files:

  • tests/integration/test_lists/test-db/l0_b200.yml
    • Added unittest/_torch/modules/test_mxfp8_linear.py.
  • tests/integration/test_lists/test-db/l0_b300.yml
    • Added unittest/_torch/modules/test_mxfp8_linear.py.

Added or updated test coverage:

  • Warmup tests cover disabled autotuning, separate warmup passes, missing-batch fallback, and rank-mismatch fallback.
  • MXFP8 linear tests cover backend dispatch, FlashInfer contracts, native autotuning, cache profiles, fallback behavior, and graph correctness.
  • MXFP8 GEMM tests cover large-M accuracy, tactic correctness, tactic caching, and cache cleanup.
  • The modified MXFP8 linear test is included in the B200 and B300 CI test lists.
  • The warmup and GEMM test files are not reported in the modified CI test lists.
  • Verdict: needs follow-up.

Description

This PR combines two complementary MiniMax-M3 MXFP8 GEMM optimizations:

  1. FlashInfer for decode CUDA graphs. During engine startup warmup, eligible MiniMax-M3 MXFP8 linear layers autotune FlashInfer, then captured decode graphs dispatch those GEMMs through flashinfer.mm_mxfp8. Eager execution, context/prefill execution, and piecewise CUDA graphs retain the native TensorRT-LLM path.
  2. Native large-M tactic autotuning. PyTorchModelEngine explicitly opts MXFP8 layers into native tuning during standard startup autotuning. The engine profiles the compiled CUTLASS tactic portfolio and caches the best tactic per shape. Standalone modules and engine paths that skip autotuner warmup, including Helix CP, remain on the direct native GEMM instead of retaining a serving-time Python autotuner lookup.

Native and FlashInfer tuning use separate startup forwards. FlashInfer availability is synchronized across tensor-parallel ranks, and a missing warmup batch safely falls back to the plain native GEMM. The native tactic cache uses stable 8K, 16K, and 32K context buckets, with Python/C++ boundary consistency covered by round-trip tests.

For advanced debugging and performance experiments, the MiniMax-M3 deployment guide now documents TRTLLM_MXFP8_GEMM_BACKEND={trtllm,flashinfer,auto}. Normal deployments should leave the variable unset and use automatic selection.

Together these changes select a better MXFP8 implementation at both ends of the workload: FlashInfer for the small-M captured decode path and shape-specific native CUTLASS tactics for large-M execution.

This main-branch port consolidates the implementations originally merged into feat/m3_with_msa in #16695 and #16816.

Performance

FlashInfer decode path

Matched GB200 MiniMax-M3 1P1D disaggregated serving:

  • +10.38% total/output-token throughput.
  • -9.78% median TPOT.

Native large-M autotuning

Matched GB300 MiniMax-M3 2P8D disaggregated serving (random 8K/1K, concurrency 256, 2,560 requests; CTX image changed only):

  • +3.92% total-token throughput.
  • -8.00% median TTFT.
  • -0.98% median TPOT.
  • -3.94% median E2E latency.

Test Coverage

  • Added focused coverage for FlashInfer dispatch, call contracts, automatic decode-graph routing, backend validation, graph replay, and output correctness.
  • Added engine-owned native-autotuner lifecycle coverage, including standalone/default direct dispatch, disabled autotuning, separate native and FlashInfer warmup passes, missing-batch fallback, and TP-rank availability mismatch.
  • Added native MXFP8 GEMM tactic validation, accuracy, fallback, cache-hit, cache-cleanup, large-M bucket, profile synchronization, and Python/C++ boundary round-trip coverage.
  • The MXFP8 linear tests are explicitly registered in the B200/B300 pre-merge lists. Native tactic-cache tests are covered by the existing unittest/_torch/thop/parallel suite entries without duplicate registration.
  • Focused GB300 validation passed: 52 tests passed.
  • The native autotuner populated 33 cache entries on each rank with no post-warmup MXFP8 cache misses.
  • Both performance A/B arms completed identical input and output token counts.
  • Changed-file pre-commit checks and Python syntax compilation pass.

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-compatible or api-breaking. For api-breaking, include BREAKING in 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.

@peihu-nv
peihu-nv force-pushed the peihengh/m3-mxfp8-autotuner-main-20260803 branch 2 times, most recently from d350653 to 4f71320 Compare August 4, 2026 04:47
Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
@peihu-nv
peihu-nv force-pushed the peihengh/m3-mxfp8-autotuner-main-20260803 branch from 4f71320 to 3c1a752 Compare August 4, 2026 05:37
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

MXFP8 GEMM now supports thread-safe tactic caching, autotuned Torch operators, configurable native or FlashInfer dispatch, and decode-graph capture integration. The executor coordinates separate warmup paths, with tests covering backend selection, tactic caching, graph capture, and numerical correctness.

Changes

MXFP8 autotuning

Layer / File(s) Summary
Native tactic cache and runner
cpp/tensorrt_llm/thop/mxfp8Gemm.cpp
Adds synchronized tactic caching, explicit configuration selection, the public MXFP8GemmRunner, and TorchScript registration.
Python autotuned GEMM operator
tensorrt_llm/_torch/custom_ops/torch_custom_ops.py
Adds large-M tuning buckets, scale-shape inference, runner caching, tactic synchronization, and the autotuned custom operator.
MXFP8 linear backend dispatch
tensorrt_llm/_torch/modules/linear.py
Adds native, FlashInfer, and automatic backend modes with context-local autotuning and decode-capture state.
Warmup and graph-capture orchestration
tensorrt_llm/_torch/pyexecutor/model_engine.py, tensorrt_llm/_torch/models/modeling_minimaxm3.py
Coordinates FlashInfer and native autotuning during warmup and generation graph capture. MiniMax-M3 enables the FlashInfer decode-graph default.
Autotuning validation and test enablement
tests/unittest/_torch/modules/test_mxfp8_linear.py, tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py, tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py, tests/integration/test_lists/test-db/*, docs/source/deployment-guide/deployment-guide-for-minimax-m3-on-trtllm.md
Adds coverage for backend transitions, tuning buckets, tactic caching, warmup behavior, graph capture, GEMM accuracy, and backend configuration documentation. Registers the tests for B200 and B300 suites.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested labels: api-compatible

Suggested reviewers: bowenfu, shixiaowei02, zongfeijing

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the MiniMax-M3 MXFP8 GEMM performance optimization and follows the repository's ticket and type format.
Description check ✅ Passed The description explains the motivation, implementation, performance results, test coverage, and checklist status in the required structure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (6)
tests/unittest/_torch/modules/test_mxfp8_linear.py (2)

354-357: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename the local Linear variable so it does not shadow the flashinfer module.

Line 355 imports flashinfer into a local name. Line 375 rebinds the same local name to a Linear instance. The availability check and the module reference are then unreachable in the rest of the test. Use a distinct name, for example flashinfer_linear.

Also applies to: 375-381

🤖 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 `@tests/unittest/_torch/modules/test_mxfp8_linear.py` around lines 354 - 357,
Rename the local Linear instance created later in the test to a distinct name
such as flashinfer_linear, preserving flashinfer as the imported module name
from the availability check. Update all subsequent references to that Linear
instance within the affected test.

88-88: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Patch the module reference instead of global torch.ops.

monkeypatch.setattr(linear_module.torch, "ops", ...) mutates the real torch module, because linear_module.torch is the global torch module object. Every module in the process sees the fake ops namespace for the duration of the test. monkeypatch restores it, but an unrelated torch.ops.* call inside the code under test fails with a confusing AttributeError.

Replace torch on the module under test instead, so only linear_module sees the fake.

♻️ Proposed scoping fix
-    monkeypatch.setattr(linear_module.torch, "ops", SimpleNamespace(trtllm=fake_trtllm_ops))
+    monkeypatch.setattr(
+        linear_module, "torch", SimpleNamespace(ops=SimpleNamespace(trtllm=fake_trtllm_ops))
+    )

Add any other torch attributes that MXFP8LinearMethod.apply needs, for example ones and float32.

🤖 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 `@tests/unittest/_torch/modules/test_mxfp8_linear.py` at line 88, Update the
test’s monkeypatch to replace the module-level torch reference on linear_module,
rather than assigning to linear_module.torch.ops and mutating global torch.ops.
Build the fake torch object with the attributes MXFP8LinearMethod.apply
requires, including the fake ops namespace and any needed symbols such as ones
and float32.
tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py (1)

79-82: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Do not hard-code the tactic count.

expected_tactics = 20 if getSMVersion() == 100 else 10 couples this pre-merge test to the exact CUTLASS configuration list. Both l0_b200.yml and l0_b300.yml run this test on every PR, so any added or removed configuration fails CI for an unrelated change. Assert that at least one configuration exists and iterate the reported count instead.

♻️ Proposed fix
-    expected_tactics = 20 if getSMVersion() == 100 else 10
-    assert runner.get_num_configs() == expected_tactics
+    num_configs = runner.get_num_configs()
+    assert num_configs > 0
 
-    for tactic in [-1, *range(expected_tactics)]:
+    for tactic in [-1, *range(num_configs)]:
🤖 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 `@tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py` around lines 79
- 82, Replace the hard-coded expected_tactics calculation with a check that
runner.get_num_configs() is greater than zero, then iterate tactics using the
count returned by runner.get_num_configs() while preserving the existing -1
tactic case.
tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py (1)

244-244: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Narrow the environment patch.

patch.dict("os.environ", {}, clear=True) removes every environment variable for the duration of the block. The test only needs TRTLLM_MXFP8_GEMM_BACKEND to be absent. Clearing everything can change unrelated behavior inside the warmup path, for example logging or autotuner cache-path handling.

♻️ Proposed narrower patch
-            patch.dict("os.environ", {}, clear=True),
+            patch.dict("os.environ", {}),

Then delete only the one variable inside the block:

os.environ.pop("TRTLLM_MXFP8_GEMM_BACKEND", None)
🤖 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 `@tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py` at line
244, In the warmup test’s environment patch, stop clearing the entire
environment and preserve all unrelated variables. Within the relevant block,
remove only TRTLLM_MXFP8_GEMM_BACKEND using the existing test setup around the
warmup invocation.
tensorrt_llm/_torch/custom_ops/torch_custom_ops.py (1)

605-620: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Annotate unique_id and consider narrowing the tactic-cache sync.

Two points:

  1. unique_id has no return annotation. The coding guidelines require an annotation on every function.
  2. sync_tactic_cache re-scans every cache entry for the op on each autotuned call while tuning mode is active. Each MXFP8 linear layer repeats the same full scan and re-registers already registered tactics. The work is redundant during warmup.

Track the last synchronized cache size, or sync once after warmup instead of per call.

♻️ Proposed annotation fix
-    def unique_id(self):
+    def unique_id(self) -> tuple[torch.dtype, int]:
         return (self.output_dtype, self.sm_version)
As per coding guidelines: "Annotate every function, use `None` for procedures".
🤖 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 `@tensorrt_llm/_torch/custom_ops/torch_custom_ops.py` around lines 605 - 620,
Annotate the `unique_id` function with its concrete return type. In
`sync_tactic_cache`, avoid rescanning and re-registering the entire profiling
cache on every autotuned call by tracking the last synchronized cache size or
performing synchronization once after warmup, while preserving synchronization
for newly added cache entries.

Source: Coding guidelines

cpp/tensorrt_llm/thop/mxfp8Gemm.cpp (1)

285-289: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a message to the bounds check.

TORCH_CHECK(configIdx >= 0 && configIdx < getNumConfigs()); produces an error without context. A message makes an out-of-range tactic index from the Python autotuner easy to diagnose.

♻️ Proposed diagnostic message
-        TORCH_CHECK(configIdx >= 0 && configIdx < getNumConfigs());
+        TORCH_CHECK(configIdx >= 0 && configIdx < getNumConfigs(), "MXFP8 config index ", configIdx,
+            " is out of range [0, ", getNumConfigs(), ").");
🤖 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/mxfp8Gemm.cpp` around lines 285 - 289, Update the
TORCH_CHECK in getConfig to include a descriptive message for an invalid
configIdx, identifying the out-of-range tactic index and the valid configuration
range so Python autotuner failures are diagnosable.
🤖 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 `@tensorrt_llm/_torch/modules/linear.py`:
- Around line 3120-3123: In tensorrt_llm/_torch/modules/linear.py:3120-3123,
remove the backend check from needs_native_autotune, gate operator selection in
apply() on the FlashInfer dispatch decision, and consistently clear
use_native_autotuner and _native_autotuned in disable_flashinfer_auto(). In
tensorrt_llm/_torch/pyexecutor/model_engine.py:1569-1582, collect
native_mxfp8_methods before calling quant_method.enable_flashinfer_auto() so
native tuning remains eligible.

In `@tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py`:
- Around line 319-341: Add the missing _release_megamoe_profiling_scratch mock
or callable to the engine SimpleNamespace in
test_flashinfer_mxfp8_autotunes_before_graph_capture, matching the stub’s other
engine methods so both _run_autotuner_warmup calls can complete without
AttributeError.

---

Nitpick comments:
In `@cpp/tensorrt_llm/thop/mxfp8Gemm.cpp`:
- Around line 285-289: Update the TORCH_CHECK in getConfig to include a
descriptive message for an invalid configIdx, identifying the out-of-range
tactic index and the valid configuration range so Python autotuner failures are
diagnosable.

In `@tensorrt_llm/_torch/custom_ops/torch_custom_ops.py`:
- Around line 605-620: Annotate the `unique_id` function with its concrete
return type. In `sync_tactic_cache`, avoid rescanning and re-registering the
entire profiling cache on every autotuned call by tracking the last synchronized
cache size or performing synchronization once after warmup, while preserving
synchronization for newly added cache entries.

In `@tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py`:
- Line 244: In the warmup test’s environment patch, stop clearing the entire
environment and preserve all unrelated variables. Within the relevant block,
remove only TRTLLM_MXFP8_GEMM_BACKEND using the existing test setup around the
warmup invocation.

In `@tests/unittest/_torch/modules/test_mxfp8_linear.py`:
- Around line 354-357: Rename the local Linear instance created later in the
test to a distinct name such as flashinfer_linear, preserving flashinfer as the
imported module name from the availability check. Update all subsequent
references to that Linear instance within the affected test.
- Line 88: Update the test’s monkeypatch to replace the module-level torch
reference on linear_module, rather than assigning to linear_module.torch.ops and
mutating global torch.ops. Build the fake torch object with the attributes
MXFP8LinearMethod.apply requires, including the fake ops namespace and any
needed symbols such as ones and float32.

In `@tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py`:
- Around line 79-82: Replace the hard-coded expected_tactics calculation with a
check that runner.get_num_configs() is greater than zero, then iterate tactics
using the count returned by runner.get_num_configs() while preserving the
existing -1 tactic case.
🪄 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: 2cb98156-18c1-4b0a-b787-853c692a480a

📥 Commits

Reviewing files that changed from the base of the PR and between 536326f and 325a8df.

📒 Files selected for processing (10)
  • cpp/tensorrt_llm/thop/mxfp8Gemm.cpp
  • tensorrt_llm/_torch/custom_ops/torch_custom_ops.py
  • tensorrt_llm/_torch/models/modeling_minimaxm3.py
  • tensorrt_llm/_torch/modules/linear.py
  • tensorrt_llm/_torch/pyexecutor/model_engine.py
  • tests/integration/test_lists/test-db/l0_b200.yml
  • tests/integration/test_lists/test-db/l0_b300.yml
  • tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py
  • tests/unittest/_torch/modules/test_mxfp8_linear.py
  • tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py

Comment thread tensorrt_llm/_torch/modules/linear.py Outdated
Comment thread tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py
@BowenFu

BowenFu commented Aug 5, 2026

Copy link
Copy Markdown

Could you address these correctness edges before merge?

  • Make enable_autotuner=False disable the FlashInfer warmup path too.
  • If no warmup batch materializes, avoid leaving needs_native_autotune active indefinitely; retry with a bound or latch to the plain GEMM fallback.
  • Add a numerical agreement test between graph-captured FlashInfer execution and eager native execution for backend="auto".
  • Make the FlashInfer-availability decision consistent across ranks before any rank returns or enters the TP warmup.

These cases affect runtime behavior, not only initialization performance.

@peihu-nv peihu-nv changed the title [None][perf] Autotune large-M MXFP8 GEMM tactics [None][perf] Optimize MiniMax-M3 MXFP8 GEMMs Aug 5, 2026

@brnguyen2 brnguyen2 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main issue is that the PR's two optimizations appear to be mutually exclusive within a single process (detailed inline at model_engine.py:1577): enabling the FlashInfer decode-graph path flips backend to "auto", which disqualifies the layer from native large-M autotuning. The description says the changes "together" cover both ends of the workload, but in aggregated MiniMax-M3 serving with decode graphs — the default configuration — context/prefill GEMMs stay on the untuned default CUTLASS config. The two perf measurements were separate disagg arms (CTX-only and GEN-only processes), so they don't demonstrate the combined behavior. If the exclusivity is intentional, please say so in the description and docstring; if not, the backend == "trtllm" condition in needs_native_autotune looks like the culprit, since auto mode still runs the native op for everything except captured decode graphs.

Two smaller asks:

  • This is a nontrivial perf feature; it should carry a TRTLLM JIRA ticket rather than [None].
  • TRTLLM_MXFP8_GEMM_BACKEND is a new user-facing env var documented only in a docstring — consider adding it to the docs where other TRTLLM_* knobs live.

The test coverage is genuinely good, especially the GPU graph-replay parity test for the FlashInfer scale-layout contract.

quant_method.enable_flashinfer_auto()
if quant_method.needs_flashinfer_autotune:
flashinfer_mxfp8_methods.append(quant_method)
if enable_trtllm_autotuner and quant_method.needs_native_autotune:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ordering bug (or undocumented design decision): enable_flashinfer_auto() on line 1574 flips backend to "auto", and needs_native_autotune requires backend == "trtllm" (linear.py:3121-3123) — so any layer that gets the FlashInfer decode path is silently excluded from native large-M autotuning. In auto mode, eager/context execution still calls the plain mxfp8_mxfp8_gemm, whose tactic cache is now never populated, so large-M context GEMMs run the untuned default config. For aggregated MiniMax-M3 serving with decode graphs, the PR's second optimization never engages. If the intent is that the native op is still the eager path in auto mode, dropping the backend == "trtllm" condition (or checking needs_native_autotune before calling enable_flashinfer_auto()) would let both apply.

@peihu-nv peihu-nv Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks! Fixed in c031804: native and FlashInfer tuning are now independent and run in separate warmup passes. Auto mode keeps the tuned native path for eager/context GEMMs and uses FlashInfer only for decode graphs.

return act.new_empty((act.size(0), weight.size(0)), dtype=output_dtype)


_MXFP8_LARGE_M_BUCKETS = (8192, 16384, 32768)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These bucket bands duplicate kMxfp8LargeMMin/kMxfp8M16kMin/etc. in cpp/tensorrt_llm/thop/mxfp8Gemm.cpp:47-53. If either side drifts, the failure is silent: Python tunes and registers tactics at bucket M while C++ maps runtime M to a different key, so every lookup misses and falls back to the default config — no error, just the perf win quietly disappearing. Consider exposing the bucket mapping from the C++ runner (single source), or at minimum a unit test that round-trips register_tactic/get_cached_tactic across the band boundaries to pin the two implementations together. The thresholds themselves (6553/13106/19659) also deserve a one-line derivation comment.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, agreed. I added a GB300 boundary test that registers tactics through C++ and verifies the Python and C++ mappings at every bucket boundary. I also documented where the thresholds came from.

global_scale = torch.ones([1],
dtype=torch.float32,
device=input.device)
gemm = (torch.ops.trtllm.mxfp8_mxfp8_gemm_autotuned

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs_native_autotune defaults True for every MXFP8LinearMethod, and only _run_autotuner_warmup ever resolves it (mark/disable). Any path that skips that warmup — helix CP returns early at model_engine.py:1208, or Linear used outside the PyExecutor engine — leaves it True forever, so every apply() routes through mxfp8_mxfp8_gemm_autotuned and pays an AutoTuner.choose_one cache-miss lookup per GEMM call for the life of the process. Consider defaulting use_native_autotuner off and having the engine opt in, so non-engine users keep the direct op call.

@peihu-nv peihu-nv Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Fixed in daed63f: native autotuning now defaults off, and PyTorchModelEngine explicitly enables it during startup warmup. Standalone and Helix paths therefore use the direct native GEMM.

flashinfer_autotune_context = (
flashinfer_mxfp8_autotune() if self.cuda_graph_runner.is_warmup_only
and flashinfer_methods else contextlib.nullcontext())
with flashinfer_autotune_context, flashinfer_mxfp8_decode_graph_capture(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphs can also be captured lazily during serving (needs_capture path in forward, model_engine.py:6538) — outside this contextvar. A decode graph key not captured during warmup (e.g. a spec-decode on/off variant) bakes the native GEMM instead of FlashInfer, so per-shape decode perf silently depends on which keys happened to capture during warmup. Worth either setting the capture contextvar in the lazy-capture path too, or noting the limitation here.

@peihu-nv peihu-nv Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for flagging this. I double-checked the current graph-runner behavior: runtime shapes are first padded to an existing graph key. If the resulting key is still missing, _capture_allowed is false during serving, so it falls back to eager execution instead of capturing a native-GEMM graph. Therefore, no change is needed in this PR.

- unittest/_torch/modules/test_rotary_embedding.py
- unittest/_torch/modules/mamba
- unittest/_torch/modules/tests_lora_modules
- unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This same pre-merge section already contains unittest/_torch/thop/parallel TIMEOUT (90) (line 143), which picks up the new file automatically — this explicit entry double-registers it. Same duplication in l0_b300.yml (directory at line 23, explicit entry at line 36). The test_mxfp8_linear.py additions are fine since modules tests are enumerated individually.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks. I removed the duplicate explicit entries from both B200 and B300 lists; the existing directory entries already include this test.

Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unittest/_torch/modules/test_mxfp8_linear.py (1)

298-322: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Reset synced_cache_keys with the profiling cache lifecycle. MXFP8GemmRunner.synced_cache_keys is shared across instances, but AutoTuner.clear_cache() does not clear it. A reprofiled cache entry with the same cache_key can therefore skip register_tactic(). id(tuner.profiling_cache) is also reusable after object destruction. Key synchronization state by cache lifetime or clear it when the profiling cache is cleared.

Test coverage: test_mxfp8_auto_fallback_does_not_rearm_native_autotuning covers fallback state, and test_mxfp8_native_autotuner_syncs_profiles covers repeated synchronization for one live cache. Add a regression test for cache clearing and cache replacement. The test file is listed in test-db/l0_b200.yml and test-db/l0_b300.yml. Coverage verdict: insufficient.

🤖 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 `@tests/unittest/_torch/modules/test_mxfp8_linear.py` around lines 298 - 322,
Update MXFP8GemmRunner.sync_tactic_cache and the synced_cache_keys lifecycle so
clearing or replacing AutoTuner.profiling_cache cannot suppress register_tactic
for a reprofiled cache_key; avoid relying solely on reusable profiling-cache
object IDs, and reset or scope synchronization state to the cache lifetime.
Extend test_mxfp8_native_autotuner_syncs_profiles with regression coverage for
cache clearing and cache replacement while preserving the existing repeated-sync
behavior.
🧹 Nitpick comments (5)
tensorrt_llm/_torch/custom_ops/torch_custom_ops.py (2)

576-576: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the required modern type annotations.

Replace List[...] with built-in list[...]. Type **kwargs as object because the override accepts arbitrary keyword values.

Proposed annotation update
-def _mxfp8_scale_infer_shape(input_shapes: List[List[int]]) -> int:
+def _mxfp8_scale_infer_shape(input_shapes: list[list[int]]) -> int:

-    def get_valid_tactics(self, inputs: List[torch.Tensor],
-                          profile: OptimizationProfile, **kwargs) -> List[int]:
+    def get_valid_tactics(self, inputs: list[torch.Tensor],
+                          profile: OptimizationProfile,
+                          **kwargs: object) -> list[int]:

Also applies to: 607-608

🤖 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 `@tensorrt_llm/_torch/custom_ops/torch_custom_ops.py` at line 576, Update
_mxfp8_scale_infer_shape and the additionally referenced definitions to use
modern built-in list[...] annotations instead of List[...]. Annotate any
**kwargs parameters in the affected override as object while preserving the
existing method signatures and behavior.

Source: Coding guidelines


583-585: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Annotate the mutable runner caches with ClassVar.

MXFP8GemmRunner.runner_dict and synced_cache_keys are shared by instances of MXFP8GemmRunner, not process-wide. Combine each annotation with its initializer. Apply the same change to the other mutable runner-cache declarations in this file; Ruff reports 11 RUF012 violations.

🤖 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 `@tensorrt_llm/_torch/custom_ops/torch_custom_ops.py` around lines 583 - 585,
Update the mutable runner-cache declarations throughout this file, including
MXFP8GemmRunner.runner_dict and synced_cache_keys, to combine each ClassVar
annotation with its initializer. Apply the same ClassVar treatment to all 11
runner-cache declarations reported by Ruff RUF012, preserving their existing
types and initial values.

Source: Linters/SAST tools

tests/unittest/_torch/modules/test_mxfp8_linear.py (1)

88-93: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the fake torch delegate unknown attributes to the real module.

fake_torch exposes only ops, ones, and float32. Any other torch.* attribute reached by MXFP8LinearMethod.apply raises AttributeError, which reads as a test bug rather than a production change. ones and float32 were already added for that reason. A delegating proxy keeps the operator stubs while letting every other attribute resolve to the real torch.

♻️ Proposed refactor
-    fake_torch = SimpleNamespace(
-        ops=SimpleNamespace(trtllm=fake_trtllm_ops),
-        ones=torch.ones,
-        float32=torch.float32,
-    )
-    monkeypatch.setattr(linear_module, "torch", fake_torch)
+    class _FakeTorch:
+        ops = SimpleNamespace(trtllm=fake_trtllm_ops)
+
+        def __getattr__(self, name):
+            return getattr(torch, name)
+
+    monkeypatch.setattr(linear_module, "torch", _FakeTorch())
🤖 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 `@tests/unittest/_torch/modules/test_mxfp8_linear.py` around lines 88 - 93,
Update the fake_torch setup in the MXFP8LinearMethod test so unknown attributes
delegate to the real torch module while preserving the custom ops, ones, and
float32 overrides. Use a proxy mechanism such as attribute fallback to torch,
then continue monkeypatching linear_module.torch with that delegating fake.
tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py (2)

481-555: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the forced-FlashInfer rank mismatch.

This test covers the automatic (auto) path, where a rank mismatch logs a warning and falls back. _run_autotuner_warmup has a second branch: if any method has backend == "flashinfer" (set through TRTLLM_MXFP8_GEMM_BACKEND=flashinfer), the mismatch must raise RuntimeError instead of falling back silently. No test asserts that branch, so a regression that downgrades the error to a warning would pass CI.

Add a variant that sets TRTLLM_MXFP8_GEMM_BACKEND=flashinfer and asserts RuntimeError with assertRaises.

🤖 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 `@tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py` around
lines 481 - 555, Add a test variant for _run_autotuner_warmup that sets
TRTLLM_MXFP8_GEMM_BACKEND to flashinfer while retaining the simulated TP rank
mismatch, and assert the call raises RuntimeError. Verify the forced FlashInfer
path fails before warmup rather than falling back, using the existing engine,
tuner, and dist setup from
test_flashinfer_mxfp8_rank_mismatch_falls_back_before_warmup.

220-576: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Complete MXFP8 warmup coverage and registration.

The five added tests run through unittest/_torch/executor in l0_b300.yml, but l0_b200.yml does not include this directory. Add the module to the B200 list if B200 is an intended target. Add tests for the forced-FlashInfer RuntimeError path and pipeline-parallel rank divergence.

Test coverage summary: The MXFP8 linear and GEMM tests are listed in both B200 and B300. Warmup coverage remains insufficient.

🤖 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 `@tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py` around
lines 220 - 576, Add the warmup test module containing
test_flashinfer_mxfp8_respects_disabled_global_autotuner and related MXFP8 tests
to the B200 test list when B200 is an intended target. Extend the warmup
coverage with tests for the forced-FlashInfer RuntimeError path and
pipeline-parallel rank divergence, following the existing
PyTorchModelEngine._run_autotuner_warmup test patterns.

Source: Path instructions

🤖 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.

Outside diff comments:
In `@tests/unittest/_torch/modules/test_mxfp8_linear.py`:
- Around line 298-322: Update MXFP8GemmRunner.sync_tactic_cache and the
synced_cache_keys lifecycle so clearing or replacing AutoTuner.profiling_cache
cannot suppress register_tactic for a reprofiled cache_key; avoid relying solely
on reusable profiling-cache object IDs, and reset or scope synchronization state
to the cache lifetime. Extend test_mxfp8_native_autotuner_syncs_profiles with
regression coverage for cache clearing and cache replacement while preserving
the existing repeated-sync behavior.

---

Nitpick comments:
In `@tensorrt_llm/_torch/custom_ops/torch_custom_ops.py`:
- Line 576: Update _mxfp8_scale_infer_shape and the additionally referenced
definitions to use modern built-in list[...] annotations instead of List[...].
Annotate any **kwargs parameters in the affected override as object while
preserving the existing method signatures and behavior.
- Around line 583-585: Update the mutable runner-cache declarations throughout
this file, including MXFP8GemmRunner.runner_dict and synced_cache_keys, to
combine each ClassVar annotation with its initializer. Apply the same ClassVar
treatment to all 11 runner-cache declarations reported by Ruff RUF012,
preserving their existing types and initial values.

In `@tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py`:
- Around line 481-555: Add a test variant for _run_autotuner_warmup that sets
TRTLLM_MXFP8_GEMM_BACKEND to flashinfer while retaining the simulated TP rank
mismatch, and assert the call raises RuntimeError. Verify the forced FlashInfer
path fails before warmup rather than falling back, using the existing engine,
tuner, and dist setup from
test_flashinfer_mxfp8_rank_mismatch_falls_back_before_warmup.
- Around line 220-576: Add the warmup test module containing
test_flashinfer_mxfp8_respects_disabled_global_autotuner and related MXFP8 tests
to the B200 test list when B200 is an intended target. Extend the warmup
coverage with tests for the forced-FlashInfer RuntimeError path and
pipeline-parallel rank divergence, following the existing
PyTorchModelEngine._run_autotuner_warmup test patterns.

In `@tests/unittest/_torch/modules/test_mxfp8_linear.py`:
- Around line 88-93: Update the fake_torch setup in the MXFP8LinearMethod test
so unknown attributes delegate to the real torch module while preserving the
custom ops, ones, and float32 overrides. Use a proxy mechanism such as attribute
fallback to torch, then continue monkeypatching linear_module.torch with that
delegating fake.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 51483533-5edf-4903-b893-e8ea35bcd9d2

📥 Commits

Reviewing files that changed from the base of the PR and between 325a8df and c031804.

📒 Files selected for processing (7)
  • cpp/tensorrt_llm/thop/mxfp8Gemm.cpp
  • tensorrt_llm/_torch/custom_ops/torch_custom_ops.py
  • tensorrt_llm/_torch/modules/linear.py
  • tensorrt_llm/_torch/pyexecutor/model_engine.py
  • tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py
  • tests/unittest/_torch/modules/test_mxfp8_linear.py
  • tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py
  • cpp/tensorrt_llm/thop/mxfp8Gemm.cpp
  • tensorrt_llm/_torch/modules/linear.py

Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
@peihu-nv
peihu-nv requested a review from a team as a code owner August 6, 2026 03:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py (1)

170-172: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add the procedure return annotation.

Add -> None to test_mxfp8_native_tactic_cache_large_m_bucket_boundaries. The Python guidelines require annotations on every function.

Proposed fix
 def test_mxfp8_native_tactic_cache_large_m_bucket_boundaries(
     lower_bound: int, upper_bound: int, bucket: int
-):
+) -> None:

As per coding guidelines, annotate every function.

🤖 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 `@tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py` around lines
170 - 172, Add the required `-> None` return annotation to the
`test_mxfp8_native_tactic_cache_large_m_bucket_boundaries` test function
signature, leaving its parameters and implementation unchanged.

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.

Inline comments:
In `@docs/source/deployment-guide/deployment-guide-for-minimax-m3-on-trtllm.md`:
- Around line 108-112: Update the `flashinfer` entry in the execution-mode
descriptions so it states that eager, context/prefill, and piecewise execution
remain on the native TensorRT LLM GEMM path, while FlashInfer applies only to
eligible decode CUDA-graph GEMMs. Leave the `trtllm` and `auto` descriptions
unchanged.

---

Nitpick comments:
In `@tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py`:
- Around line 170-172: Add the required `-> None` return annotation to the
`test_mxfp8_native_tactic_cache_large_m_bucket_boundaries` test function
signature, leaving its parameters and implementation unchanged.
🪄 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: d40f8b20-d73c-4b22-9457-a78e277c449c

📥 Commits

Reviewing files that changed from the base of the PR and between c031804 and daed63f.

📒 Files selected for processing (9)
  • docs/source/deployment-guide/deployment-guide-for-minimax-m3-on-trtllm.md
  • tensorrt_llm/_torch/custom_ops/torch_custom_ops.py
  • tensorrt_llm/_torch/modules/linear.py
  • tensorrt_llm/_torch/pyexecutor/model_engine.py
  • tests/integration/test_lists/test-db/l0_b200.yml
  • tests/integration/test_lists/test-db/l0_b300.yml
  • tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py
  • tests/unittest/_torch/modules/test_mxfp8_linear.py
  • tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py
💤 Files with no reviewable changes (2)
  • tests/integration/test_lists/test-db/l0_b200.yml
  • tests/integration/test_lists/test-db/l0_b300.yml
🚧 Files skipped from review as they are similar to previous changes (4)
  • tensorrt_llm/_torch/pyexecutor/model_engine.py
  • tensorrt_llm/_torch/custom_ops/torch_custom_ops.py
  • tensorrt_llm/_torch/modules/linear.py
  • tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py

Comment on lines +108 to +112
* `trtllm` uses the native TensorRT LLM GEMM for eager execution and CUDA graphs.
* `flashinfer` forces FlashInfer for both eager execution and CUDA graphs; it
requires the pinned `flashinfer-python` package and Blackwell MXFP8 support.
* `auto` keeps eager execution on the native GEMM and uses FlashInfer in
captured decode CUDA graphs after startup tuning.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the flashinfer behavior description.

Line 109 states that flashinfer uses FlashInfer for eager GEMMs. The stated runtime contract keeps eager, context/prefill, and piecewise execution on the native TensorRT LLM GEMM path. Document FlashInfer as applying only to eligible decode CUDA-graph GEMMs.

Proposed documentation fix
-* `flashinfer` forces FlashInfer for both eager execution and CUDA graphs; it
-  requires the pinned `flashinfer-python` package and Blackwell MXFP8 support.
+* `flashinfer` forces FlashInfer for eligible decode CUDA-graph GEMMs. Eager,
+  context/prefill, and piecewise graph execution use the native GEMM. It
+  requires the pinned `flashinfer-python` package and Blackwell MXFP8 support.

As per PR objectives, FlashInfer dispatch is limited to eligible decode CUDA-graph GEMMs.

📝 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.

Suggested change
* `trtllm` uses the native TensorRT LLM GEMM for eager execution and CUDA graphs.
* `flashinfer` forces FlashInfer for both eager execution and CUDA graphs; it
requires the pinned `flashinfer-python` package and Blackwell MXFP8 support.
* `auto` keeps eager execution on the native GEMM and uses FlashInfer in
captured decode CUDA graphs after startup tuning.
* `trtllm` uses the native TensorRT LLM GEMM for eager execution and CUDA graphs.
* `flashinfer` forces FlashInfer for eligible decode CUDA-graph GEMMs. Eager,
context/prefill, and piecewise graph execution use the native GEMM. It
requires the pinned `flashinfer-python` package and Blackwell MXFP8 support.
* `auto` keeps eager execution on the native GEMM and uses FlashInfer in
captured decode CUDA graphs after startup tuning.
🤖 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 `@docs/source/deployment-guide/deployment-guide-for-minimax-m3-on-trtllm.md`
around lines 108 - 112, Update the `flashinfer` entry in the execution-mode
descriptions so it states that eager, context/prefill, and piecewise execution
remain on the native TensorRT LLM GEMM path, while FlashInfer applies only to
eligible decode CUDA-graph GEMMs. Leave the `trtllm` and `auto` descriptions
unchanged.

Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
cpp/tensorrt_llm/thop/mxfp8Gemm.cpp (1)

221-237: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add Doxygen documentation for the new C++ interfaces.

Document mxfp8_mxfp8_gemm, MXFP8GemmRunner, and its public methods with Doxygen comments. Include tensor shapes, supported dtypes, tactic sentinel values, cache scope, and error conditions.

The coding guidelines require Doxygen documentation for new interfaces.

Also applies to: 243-294

🤖 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/mxfp8Gemm.cpp` around lines 221 - 237, Add Doxygen
comments for mxfp8_mxfp8_gemm, MXFP8GemmRunner, and each public method. Document
tensor shapes, supported input/output dtypes, tactic sentinel values, cache
scope, and the error conditions each interface can raise, while keeping the
existing declarations and behavior unchanged.

Source: Coding guidelines

tensorrt_llm/_torch/custom_ops/torch_custom_ops.py (1)

584-612: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the new Python interfaces and tensor contracts.

Add Google-style docstrings to MXFP8GemmRunner and mxfp8_mxfp8_gemm_autotuned. Document input tensor dimensions, required dtypes, scale layouts, output shape, tactic semantics, and raised exceptions.

The coding guidelines require docstrings for externally usable interfaces and dimensions for public Tensor-like arguments.

Also applies to: 640-676

🤖 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 `@tensorrt_llm/_torch/custom_ops/torch_custom_ops.py` around lines 584 - 612,
Add Google-style docstrings to the public `MXFP8GemmRunner` class and
`mxfp8_mxfp8_gemm_autotuned` function. Document tensor dimensions, required
dtypes, scale layouts, output shape, tactic-selection semantics, and exceptions
raised, including dimension details for every public Tensor-like argument;
preserve the existing behavior and interfaces.

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/mxfp8Gemm.cpp`:
- Around line 221-237: Add Doxygen comments for mxfp8_mxfp8_gemm,
MXFP8GemmRunner, and each public method. Document tensor shapes, supported
input/output dtypes, tactic sentinel values, cache scope, and the error
conditions each interface can raise, while keeping the existing declarations and
behavior unchanged.

In `@tensorrt_llm/_torch/custom_ops/torch_custom_ops.py`:
- Around line 584-612: Add Google-style docstrings to the public
`MXFP8GemmRunner` class and `mxfp8_mxfp8_gemm_autotuned` function. Document
tensor dimensions, required dtypes, scale layouts, output shape,
tactic-selection semantics, and exceptions raised, including dimension details
for every public Tensor-like argument; preserve the existing behavior and
interfaces.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6a40e78c-6864-407e-b72c-cbf43f4b4985

📥 Commits

Reviewing files that changed from the base of the PR and between be9b16c and ae5c672.

📒 Files selected for processing (11)
  • cpp/tensorrt_llm/thop/mxfp8Gemm.cpp
  • docs/source/deployment-guide/deployment-guide-for-minimax-m3-on-trtllm.md
  • tensorrt_llm/_torch/custom_ops/torch_custom_ops.py
  • tensorrt_llm/_torch/models/modeling_minimaxm3.py
  • tensorrt_llm/_torch/modules/linear.py
  • tensorrt_llm/_torch/pyexecutor/model_engine.py
  • tests/integration/test_lists/test-db/l0_b200.yml
  • tests/integration/test_lists/test-db/l0_b300.yml
  • tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py
  • tests/unittest/_torch/modules/test_mxfp8_linear.py
  • tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py
🚧 Files skipped from review as they are similar to previous changes (9)
  • tests/integration/test_lists/test-db/l0_b200.yml
  • tests/unittest/_torch/thop/parallel/test_mxfp8_mxfp8_gemm.py
  • tensorrt_llm/_torch/models/modeling_minimaxm3.py
  • docs/source/deployment-guide/deployment-guide-for-minimax-m3-on-trtllm.md
  • tensorrt_llm/_torch/pyexecutor/model_engine.py
  • tests/integration/test_lists/test-db/l0_b300.yml
  • tests/unittest/_torch/modules/test_mxfp8_linear.py
  • tensorrt_llm/_torch/modules/linear.py
  • tests/unittest/_torch/executor/test_pytorch_model_engine_warmup.py

@peihu-nv

peihu-nv commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64214 [ run ] triggered by Bot. Commit: ae5c672 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64214 [ run ] completed with state FAILURE. Commit: ae5c672
/LLM/main/L0_MergeRequest_PR pipeline #52122 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@peihu-nv

peihu-nv commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants