Skip to content

[None][feat] DSv4 prep: MoE routing and backend support#15402

Merged
xxi-nv merged 11 commits into
NVIDIA:mainfrom
lfr-0531:user/fanrongl/dsv4-moe-routing
Jun 24, 2026
Merged

[None][feat] DSv4 prep: MoE routing and backend support#15402
xxi-nv merged 11 commits into
NVIDIA:mainfrom
lfr-0531:user/fanrongl/dsv4-moe-routing

Conversation

@lfr-0531

@lfr-0531 lfr-0531 commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for DeepSeekV4 model with new MoE routing method and gate-forward operation
    • Introduced optional SwigLU clamping support for FP8 quantization paths
    • Added MPI-based distributed initialization bootstrap for MegaMoE under MPI executor
  • Improvements

    • Enhanced MoE routing methods to support token-aware routing via input IDs
    • Improved FP8 activation kernel with configurable uniform clamp limits
    • Extended Cutlass kernel heuristics for optimized SM100/SM103 performance
  • Tests

    • Added comprehensive test suite for new MoE gate operation
    • New routing regression tests for DeepSeekV3/V4 configuration validation

Description

This is part of the DSv4 split from umbrella PR #14751. It isolates shared MoE/routing backend support so it can be reviewed independently from the DSv4 model and sparse attention wiring.

Included here:

  • DeepGEMM dependency update used by MoE backends.
  • MoE routing kernels and thop bindings, including gate_forward, dsv3_router_gemm_op, and RoutingKernelTopK.cuh.
  • Block-scale MoE runner updates, DeepGEMM/MegaMoE plumbing, routing scheduler changes, swiglu_limit plumbing, and DeepSeekV4 routing interface changes.
  • CUTLASS MoE candidate filtering needed for CUTLASS + NVFP4 on SM100-family fallback.

This PR has no dependency on earlier DSv4 split PRs after current main. PR-9 will depend on this PR for the final DSv4 model/API/tokenizer wiring.

Intentionally excluded: DSv4 model/config/tokenizer files, sparse attention backend/cache-manager files, compressor/mHC implementation, IndexerTopK implementation, and attention fusion custom ops.

Risk: this touches shared MoE backend code used by non-DSv4 consumers. The default-path behavior is covered by existing MoE module/routing tests below.

Test Coverage

Build/install:

  • CCACHE_DIR=/home/scratch.fanrongl_coreai/ccache_trtllm python3 ./scripts/build_wheel.py --trt_root /usr/local/tensorrt --benchmarks --use_ccache --cuda_architectures "90-real;100-real" --configure_cmake
  • ./.venv-3.12/bin/pip install --force-reinstall --no-deps build/tensorrt_llm-1.3.0rc19-cp312-cp312-linux_x86_64.whl

Smoke/static checks:

  • Import smoke confirmed tensorrt_llm.__file__ resolves to this PR worktree.
  • Verified fused_moe, moe_alltoall.py, torch.ops.trtllm.gate_forward, torch.ops.trtllm.dsv3_router_gemm_op, torch.ops.trtllm.fp8_block_scale_moe_runner, and tensorrt_llm.deep_gemm_cpp_tllm.
  • Routing signature smoke: DeepSeekV4MoeRoutingMethod.apply(..., input_ids=...) accepts optional input_ids; Gemma4MoeRoutingMethod.apply is restored to apply(router_logits) and PR-8 no longer changes modeling_gemma4.py.
  • git diff --check github/main..HEAD
  • PR-8 scope-leakage grep for attention backend, DSv4 model/tokenizer, compressor/mHC, IndexerTopK, and attention-fusion files.
  • ./.venv-3.12/bin/pre-commit run --files $(git diff --name-only HEAD) before the final rebase.

GPU tests after checking nvidia-smi; used idle CUDA_VISIBLE_DEVICES=1:

  • timeout 25m ./.venv-3.12/bin/python -m pytest tests/unittest/_torch/modules/moe/test_moe_module.py tests/unittest/_torch/thop/serial/test_moe_gate.py -> 270 passed, 2116 skipped.
  • timeout 20m ./.venv-3.12/bin/python -m pytest tests/unittest/_torch/modules/test_moe_routing.py tests/unittest/_torch/modules/test_moe_load_balancer.py -> 527 passed, 87 skipped.
  • timeout 20m ./.venv-3.12/bin/python -m pytest tests/unittest/_torch/thop/parallel/test_dsv3_router_gemm.py -> 48 passed.

After rebasing onto latest main (0ec325040087af5f98d040fe1dcf59273c19d209), new main only touched tests/integration/defs/perf/utils.py and did not overlap PR-8 files. Rebase verification:

  • import/routing signature smoke passed after the amend; modeling_gemma4.py is absent from github/main..HEAD.
  • git diff --check github/main..HEAD passed.
  • scope-leakage grep passed.
  • timeout 20m ./.venv-3.12/bin/python -m pytest tests/unittest/_torch/modules/test_moe_routing.py tests/unittest/_torch/modules/test_moe_load_balancer.py tests/unittest/_torch/thop/parallel/test_dsv3_router_gemm.py -> 575 passed, 87 skipped.
  • Post-amend rerun on CUDA_VISIBLE_DEVICES=1: timeout 45m ./.venv-3.12/bin/python -m pytest -q tests/unittest/_torch/modules/test_moe_routing.py tests/unittest/_torch/modules/test_moe_load_balancer.py tests/unittest/_torch/thop/parallel/test_dsv3_router_gemm.py -> 575 passed, 87 skipped.

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.

@lfr-0531
lfr-0531 requested review from a team as code owners June 16, 2026 06:37
@lfr-0531
lfr-0531 requested review from QiJune, hyukn and symphonylyh June 16, 2026 06:37
@lfr-0531
lfr-0531 requested review from Barry-Delaney and xxi-nv and removed request for symphonylyh June 16, 2026 06:43
@lfr-0531

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@lfr-0531

Copy link
Copy Markdown
Collaborator Author

/bot kill

@lfr-0531
lfr-0531 force-pushed the user/fanrongl/dsv4-moe-routing branch from 41dcd0e to 148479f Compare June 16, 2026 06:54
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54519 [ run ] triggered by Bot. Commit: 41dcd0e Link to invocation

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds DeepSeek-V4 MoE support: a new gate_forward CUDA kernel (hash and top-k modes) registered as a PyTorch custom op, a DeepSeekV4MoeRoutingMethod using it, optional input_ids threaded through all MoE forward and scheduler paths, a uniform swiglu_limit_scalar for FP8 activation clamping wired end-to-end, Sort<5–8> sorting network specializations, DSv4 router GEMM instantiations, and MPI-based torch.distributed bootstrap for MegaMoEDeepGemm.

Changes

DeepSeek-V4 MoE: Gate Kernel, Routing, SwiGLU Clamp, input_ids Threading

Layer / File(s) Summary
gate_forward CUDA kernel and PyTorch op
cpp/tensorrt_llm/kernels/customMoeRoutingKernels.cu, cpp/tensorrt_llm/kernels/customMoeRoutingKernels.h, cpp/tensorrt_llm/thop/moeGateOp.cpp, cpp/tensorrt_llm/thop/CMakeLists.txt, tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py
Implements gate_forward_kernel (softplus+sqrt, hash vs top-k selection, weight normalization for 256/384 experts), declares the public C++ API, registers trtllm::gate_forward as a PyTorch CUDA custom op with input validation, and adds the no-op fake registration for torch.compile.
DeepSeekV4MoeRoutingMethod and routing interface extension
tensorrt_llm/_torch/modules/fused_moe/routing.py, tensorrt_llm/_torch/modules/fused_moe/__init__.py, tensorrt_llm/_torch/models/modeling_gemma4.py, tensorrt_llm/tools/layer_wise_benchmarks/runner.py
Adds RoutingMethodType.DeepSeekV4, introduces DeepSeekV4MoeRoutingMethod (uses gate_forward op, hash/dense modes, requires_separated_routing=True), extends BaseMoeRoutingMethod.apply to accept optional input_ids, adds requires_separated_routing property, updates all conforming implementations, fixes perfect-router planner for None-bias routing, and exports the new class.
Sort<5–8> and DSv3/V4 router GEMM instantiations
cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/routing/RoutingKernelTopK.cuh, cpp/tensorrt_llm/kernels/dsv3MinLatencyKernels/dsv3RouterGemm.cu, cpp/tensorrt_llm/thop/dsv3RouterGemmOp.cpp, cpp/tensorrt_llm/kernels/cutlass_kernels/cutlass_heuristic.cpp, cpp/tensorrt_llm/kernels/cutlass_kernels/moe_gemm/moe_lora_problem_builder.cu
Adds explicit sorting network specializations for Sort<5–8>; adds invokeRouterGemm instantiations for kHiddenDim=4096 (kNumTokens 1–16); adds kHiddenDim4096 dispatch branch; extends SM103 TMA guard; unconditionally uses out_hidden_size in LoRA problem builder.
SwiGLU clamp in activation kernels and Triton ops
cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/DevKernel.h, cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/DevKernel.cu, cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/runner.h, cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/runner.cu, tensorrt_llm/quantization/utils/fp8_utils.py, tensorrt_llm/_torch/modules/swiglu.py, tensorrt_llm/_torch/modules/gated_mlp.py, tensorrt_llm/_torch/custom_ops/torch_custom_ops.py, tensorrt_llm/_torch/modules/linear.py
Adds swigluLimit/hasSwigluLimit to activation::Data and KernelParams; gates pre-activation clamping in both activation kernels; adds gemm1_clamp_limit_value/has_gemm1_clamp_limit_value to MoERunnerArgs; extends Triton silu_and_mul and post-quant kernel with HAS_SWIGLU_LIMIT; adds swiglu_limit to swiglu() and GatedMLP; removes stale disable_ue8m0_cast arg.
FP8 GEMM1 clamp wiring through C++ and Python layers
cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp, tensorrt_llm/_torch/custom_ops/trtllm_gen_custom_ops.py, tensorrt_llm/_torch/modules/fused_moe/moe_op_backend.py, tensorrt_llm/_torch/modules/fused_moe/ops/moe_op_deepgemm.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_trtllm_gen.py
Extends run_fp8_block_scale_moe (C++ and Python) with optional gemm1_clamp_limit; threads it through FP8BlockScaleMoERunner, fp8_block_scale_moe_runner custom op, TRTLLMOpBackend/FlashinferOpBackend (raises NotImplementedError), and DeepGemmMoEOp.
swiglu_limit_scalar wired into MoE base class and all backends
tensorrt_llm/_torch/modules/fused_moe/interface.py, tensorrt_llm/_torch/modules/fused_moe/create_moe.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_trtllm_gen.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_deepgemm.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_wide_ep.py, tensorrt_llm/_torch/modules/fused_moe/configurable_moe.py, tensorrt_llm/_torch/modules/fused_moe/mega_moe/mega_moe_deepgemm.py
Adds swiglu_limit_scalar to MoE.__init__, factory functions, and all backend constructors; renames MegaMoEDeepGemm.activation_clamp to swiglu_limit_scalar; adds MegaMoEDeepGemm-specific restriction rejecting the per-expert tensor form; extends _check_configs validation.
input_ids threading through all MoE forward and scheduler paths
tensorrt_llm/_torch/modules/fused_moe/moe_scheduler.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_deepgemm.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_wide_ep.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_trtllm_gen.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_triton.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_cute_dsl.py, tensorrt_llm/_torch/modules/fused_moe/fused_moe_vanilla.py, tensorrt_llm/_torch/modules/fused_moe/configurable_moe.py
Threads optional input_ids through MoEScheduler.forward (abstract and both concrete schedulers, including chunk splitting, DP empty-chunk substitution, and per-chunk fused launcher); propagates through forward_chunk/forward_impl in all backends; passes input_ids into all routing_method.apply(...) call sites; adds requires_separated_routing control-flow flag in TRTLLMGenFusedMoE.
MegaMoEDeepGemm MPI bootstrap, weight dedup, and communication state reset
tensorrt_llm/_torch/modules/fused_moe/mega_moe/mega_moe_deepgemm.py, tensorrt_llm/_torch/modules/fused_moe/quantization.py, tensorrt_llm/_torch/distributed/moe_alltoall.py, tensorrt_llm/_torch/modules/fused_moe/communication/nvlink_one_sided.py, tensorrt_llm/_torch/modules/fused_moe/moe_load_balancer.py, 3rdparty/fetch_content.json, tensorrt_llm/_torch/custom_ops/torch_custom_ops.py
Adds _maybe_init_dist_from_mpi() for NCCL bootstrap from mpi4py; adjusts DP/EP workspace sizing; adds weight deduplication and storage reseat in _transform_main_weights; adds reset_state() to MoeAlltoAll and NVLinkOneSided; adds DeepseekV4ForCausalLM to load-balancer arch list; updates deepgemm pin; initializes DeepGEMM PDL at import time.
Tests: gate_forward kernel, DSv4 routing, load balancer, MoE module skips
tests/unittest/_torch/thop/serial/test_moe_gate.py, tests/unittest/_torch/modules/test_moe_routing.py, tests/unittest/_torch/modules/test_moe_load_balancer.py, tests/unittest/_torch/modules/moe/test_moe_module.py, tests/unittest/_torch/thop/parallel/test_dsv3_router_gemm.py
Adds full gate_forward test suite (non-hash, hash, 384-expert, determinism, edge cases, performance benchmark with pytorch reference); adds V3/V4 routing property and perfect-router cache end-to-end tests; adds Kimi-K2.5 load-balancer test; adds SM120 NVFP4 skip helper for Cutlass tests.

Sequence Diagram(s)

sequenceDiagram
  participant Model as Model forward
  participant ConfigMoE as ConfigurableMoE.forward_impl
  participant Scheduler as ExternalCommMoEScheduler.forward
  participant Backend as TRTLLMGenFusedMoE.forward_impl
  participant Routing as DeepSeekV4MoeRoutingMethod.apply
  participant GateOp as trtllm::gate_forward (CUDA)
  participant RunMoE as run_fp8_block_scale_moe

  Model->>ConfigMoE: x, router_logits, input_ids=input_ids
  ConfigMoE->>Scheduler: forward(x, router_logits, input_ids=input_ids)
  Scheduler->>Backend: forward_impl(x, router_logits, input_ids=input_ids)
  Backend->>Routing: apply(router_logits, input_ids) [separated routing]
  Routing->>GateOp: gate_forward(scores_in, bias, input_ids, tid2eid, out_weights, out_indices, topk, route_scale, is_hash)
  GateOp-->>Routing: out_weights, out_indices written
  Routing-->>Backend: token_selected_experts, token_final_scales
  Backend->>RunMoE: run_fp8_block_scale_moe(..., gemm1_clamp_limit=swiglu_limit_scalar)
  RunMoE-->>Backend: MoE output
  Backend-->>Scheduler: output tensor
  Scheduler-->>ConfigMoE: output tensor
  ConfigMoE-->>Model: output tensor
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • NVIDIA/TensorRT-LLM#15271: Directly conflicts at the same line in moe_lora_problem_builder.cu — one PR adds the rank == 0 ? 0 : out_hidden_size guard, this PR removes it in favor of always using out_hidden_size.
  • NVIDIA/TensorRT-LLM#14944: Both PRs modify fused_moe_trtllm_gen.py routing paths and post_quant_comm/separated routing control flow, affecting DeepSeek MoE backend dispatch logic.
  • NVIDIA/TensorRT-LLM#15163: Modifies FP8BlockScalesLinearMethod.apply in linear.py and FP8 SM100/SM103 dispatch paths that this PR also touches (removing disable_ue8m0_cast and extending SM103 guard in cutlass_heuristic.cpp).

Suggested reviewers

  • schetlur-nv
  • chang-l
  • kaiyux
  • xxi-nv
  • byshiue
  • leslie-fang25
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@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: 12

Caution

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

⚠️ Outside diff range comments (4)
tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py (1)

1137-1142: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep input_ids optional at the forward_chunk boundary.

This is typed as optional but has no default, so existing callers of forward_chunk(x, router_logits, output_dtype=...) now fail before reaching the DSv4-aware path.

Proposed fix
     def forward_chunk(
         self,
         x: Union[torch.Tensor, Fp4QuantizedTensor],
         router_logits: torch.Tensor,
-        input_ids: Optional[torch.IntTensor],
+        input_ids: Optional[torch.IntTensor] = None,
         output_dtype: Optional[torch.dtype] = 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 `@tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py` around lines 1137
- 1142, The forward_chunk method has an input_ids parameter typed as
Optional[torch.IntTensor] but lacks a default value, causing existing callers
that skip this parameter to fail. Add a default value of None to the input_ids
parameter definition to make it truly optional and backward compatible with
callers that use forward_chunk(x, router_logits, output_dtype=...) without
providing input_ids.
cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/runner.h (1)

2-2: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the header year for this modified C++ header.

This file is modified in this PR, but the copyright range still ends at 2025.

Proposed fix
- * Copyright (c) 2022-2025, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2022-2026, NVIDIA CORPORATION.  All rights reserved.

As per coding guidelines, “All TensorRT-LLM source files should contain an NVIDIA copyright header including the year of latest meaningful modification.”

🤖 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/kernels/trtllmGenKernels/blockScaleMoe/runner.h` at line 2,
Update the copyright year range in the header comment at the top of runner.h to
reflect the current year, since this file is being modified in this PR. Change
the copyright line from ending at 2025 to the current year to comply with
TensorRT-LLM coding guidelines that require the copyright header to include the
year of the latest meaningful modification.

Source: Coding guidelines

tensorrt_llm/_torch/modules/fused_moe/fused_moe_trtllm_gen.py (1)

441-443: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Report routing-method separated routing here too.

DeepSeekV4 sets routing_method.requires_separated_routing = True, and forward_impl() honors it, but _supports_load_balancer() still returns False for quantized/non-DP cases. Any caller using this flag to decide whether top-k routing is external will misclassify DeepSeekV4.

Proposed fix
         """
+        if self.routing_method.requires_separated_routing:
+            return True
         if self._requires_separated_routing():
             return True
         return self.use_dp and self.parallel_size > 1
🤖 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/modules/fused_moe/fused_moe_trtllm_gen.py` around lines
441 - 443, The `_supports_load_balancer()` method needs to consistently report
when separated routing is required. Currently it returns True when
`_requires_separated_routing()` is true in the first condition, but ensure this
logic properly propagates to all code paths so that callers using this method to
determine whether top-k routing is external (such as for DeepSeekV4 which sets
`routing_method.requires_separated_routing = True`) correctly classify cases
with separated routing enabled. Verify that the separated routing requirement is
properly accounted for in the return statement logic, making sure the method
reports True whenever separated routing is in effect regardless of the DP or
parallel_size configuration.
tensorrt_llm/_torch/modules/fused_moe/create_moe.py (1)

428-445: ⚠️ Potential issue | 🔴 Critical

TritonFusedMoE should not accept swiglu_limit_scalar, but validation allows it.

TritonFusedMoE is included in the validation check at line 302, which permits both swiglu_limit and swiglu_limit_scalar to be provided. However, the constructor signature (at line 1466) only accepts swiglu_limit, swiglu_alpha, and swiglu_beta — there is no swiglu_limit_scalar parameter. The constructor call at line 428-444 does not pass swiglu_limit_scalar, whereas DeepGemmFusedMoE (line 414-421) receives both parameters.

The implementation processes only per-expert tensors (swiglu_limit), not scalar values. Either remove TritonFusedMoE from the validation list at line 302, or add explicit rejection logic if swiglu_limit_scalar is provided when moe_cls == TritonFusedMoE.

🤖 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/modules/fused_moe/create_moe.py` around lines 428 - 445,
There is a mismatch between validation logic and the TritonFusedMoE constructor
signature. The validation logic permits both swiglu_limit and
swiglu_limit_scalar for TritonFusedMoE, but the TritonFusedMoE constructor only
accepts swiglu_limit, swiglu_alpha, and swiglu_beta—not swiglu_limit_scalar.
Either remove TritonFusedMoE from the validation block that permits
swiglu_limit_scalar to be provided together with swiglu_limit, or add an
explicit assertion or error check in the TritonFusedMoE branch that rejects
swiglu_limit_scalar if it is provided, similar to how the assertion already
rejects apply_router_weight_on_input.
🧹 Nitpick comments (3)
tensorrt_llm/_torch/modules/fused_moe/moe_scheduler.py (1)

624-626: ⚡ Quick win

Add strict=True to the zip() call for defensive length-check.

While x_list, router_logits_list, and input_ids_list are all derived from the same chunk_size_list and the empty-chunk substitution loop (lines 607–620) maintains synchronization, making the length match explicit improves maintainability and guards against future refactoring mistakes.

♻️ Proposed fix
-        for idx_chunk, (x_chunk, router_logits_chunk, input_ids_chunk) in enumerate(
-            zip(x_list, router_logits_list, input_ids_list)
-        ):
+        for idx_chunk, (x_chunk, router_logits_chunk, input_ids_chunk) in enumerate(
+            zip(x_list, router_logits_list, input_ids_list, strict=True)
+        ):
🤖 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/modules/fused_moe/moe_scheduler.py` around lines 624 -
626, Add the `strict=True` parameter to the zip() call that iterates over
x_list, router_logits_list, and input_ids_list to enforce that all three lists
have equal length and protect against future refactoring mistakes that could
cause length mismatches.
cpp/tensorrt_llm/kernels/customMoeRoutingKernels.cu (1)

313-313: ⚡ Quick win

Consider centralizing kTOPK constant.

kTOPK = 6 is duplicated in customMoeRoutingKernels.cu (line 313) and moeGateOp.cpp (line 29). If this value changes, both files must be updated.

♻️ Suggested refactor

Define kTOPK in the header and reference it from both files:

 // In customMoeRoutingKernels.h
+static constexpr int kGateForwardTopK = 6;
+
 void gate_forward(void* scores_in, ...);

 // In customMoeRoutingKernels.cu
-static constexpr int kTOPK = 6;
+static constexpr int kTOPK = kGateForwardTopK;

 // In moeGateOp.cpp
-static constexpr int kTOPK = 6;
+static constexpr int kTOPK = tensorrt_llm::kernels::kGateForwardTopK;

Also applies to: 437-481

🤖 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/kernels/customMoeRoutingKernels.cu` at line 313, The kTOPK
constant is duplicated in customMoeRoutingKernels.cu (line 313) and
moeGateOp.cpp (line 29), creating maintenance issues if the value needs to
change. Define kTOPK as a static constexpr int in a shared header file that both
customMoeRoutingKernels.cu and moeGateOp.cpp can include, then remove the
duplicate static constexpr int kTOPK = 6 definitions from both implementation
files and replace them with includes of the header. This ensures a single source
of truth for the constant value.
tensorrt_llm/_torch/custom_ops/trtllm_gen_custom_ops.py (1)

1019-1023: Move gemm1_clamp_limit after use_dp to preserve backward compatibility and avoid future positional-argument binding issues.

The current parameter order places gemm1_clamp_limit before output, which could cause silent misinterpretation if future callers use positional arguments beyond topk_ids. All current call sites are safe (they use keyword arguments or stop at topk_ids), but reordering prevents potential breakage if the calling pattern evolves.

Apply the same parameter order to both the main function definition and the register_fake implementation.

Proposed adjustment

Move gemm1_clamp_limit to the end of the parameter list:

       act_type: int = 0,
-      gemm1_clamp_limit: Optional[float] = None,
       output: Optional[torch.Tensor] = None,
       tune_max_num_tokens: int = 8192,
-      use_dp: bool = False) -> torch.Tensor:
+      use_dp: bool = False,
+      gemm1_clamp_limit: Optional[float] = None) -> torch.Tensor:

Apply to both lines 1019–1023 and 1120–1124.

🤖 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/trtllm_gen_custom_ops.py` around lines 1019 -
1023, The function signature has gemm1_clamp_limit positioned before output,
which compromises backward compatibility with positional arguments. Move the
gemm1_clamp_limit parameter to the end of the parameter list (after use_dp) in
both the main function definition and the register_fake implementation to ensure
positional argument safety and prevent potential silent misinterpretation if
calling patterns evolve in the future.
🤖 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/kernels/customMoeRoutingKernels.cu`:
- Around line 333-334: The constexpr variable kExpertsPerThread at line 333
divides nExperts by WARP_SIZE without validating that nExperts is divisible by
WARP_SIZE. While current supported expert counts (256, 384) happen to work, add
a static_assert immediately before the kExpertsPerThread declaration to enforce
the compile-time constraint that nExperts must be evenly divisible by WARP_SIZE,
preventing future bugs if new expert counts are added that violate this
assumption.
- Around line 372-379: The kernel reads token_id from input_ids[global_warp_id]
and directly indexes into tid2eid without validating that token_id is within
bounds (token_id < vocab_size). Add vocab_size as a kernel parameter and insert
bounds checking before the line expert_ids = tid2eid + token_id * topK to ensure
token_id does not exceed the valid range. If validation fails, handle it
appropriately (skip processing or set a default value). Alternatively, if
runtime bounds checking is not feasible, add clear documentation in the kernel
and Python wrapper stating that input_ids must contain valid token indices
within [0, vocab_size), and implement corresponding validation in the Python
wrapper before kernel invocation.

In
`@cpp/tensorrt_llm/kernels/cutlass_kernels/moe_gemm/moe_lora_problem_builder.cu`:
- Line 72: The out-GEMM problem size calculation in the GemmCoord instantiation
now unconditionally sets N=out_hidden_size, but the test reference code expects
N to be 0 when rank=0 via a conditional (rank > 0) ? out_hidden_size : 0. Since
the test vector includes rank=0 cases and compares against this reference at the
verification point, the test will fail. Either revert the kernel code to use the
same conditional logic to match the test reference, or update the test reference
to use the new unconditional behavior and verify that CUTLASS correctly handles
the rank=0 GEMM case.

In `@tensorrt_llm/_torch/modules/fused_moe/create_moe.py`:
- Around line 300-304: The assertion validation logic checks both the
swiglu_limit and swiglu_limit_scalar parameters in the condition, but the error
message only references swiglu_limit. Update the error message string in the
assertion to mention both parameters so users providing either swiglu_limit or
swiglu_limit_scalar receive a clear and complete error message when using an
unsupported backend with the moe_cls validation.

In `@tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py`:
- Around line 1504-1505: Add `strict=True` parameter to both `zip()` calls to
enforce that the three lists being zipped have identical length. In
`tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py` lines 1504-1505,
modify the `zip(x_list, router_logits_list, input_ids_list)` call to include
`strict=True`. In `tensorrt_llm/_torch/modules/fused_moe/fused_moe_deepgemm.py`
lines 1285-1286, apply the same change to the corresponding `zip()` call that
combines three chunk-aligned lists. This prevents silent truncation when lists
are expected to have matching lengths by design.

In `@tensorrt_llm/_torch/modules/fused_moe/fused_moe_trtllm_gen.py`:
- Around line 469-478: The validation assertion currently allows per-expert
swiglu_limit (tensor variant) when has_deepseek_fp8_block_scales is true, but
the FP8 runner at line 772 only forwards swiglu_limit_scalar (the scalar
variant), causing the per-expert tensor to be silently ignored. Remove
has_deepseek_fp8_block_scales from the assertion condition to reject per-expert
swiglu_limit on the FP8 path, ensuring only swiglu_limit_scalar is used with the
deepseek_fp8_block_scales configuration.

In `@tensorrt_llm/_torch/modules/fused_moe/fused_moe_wide_ep.py`:
- Around line 789-790: Add strict=True parameter to the zip() call that iterates
over x_list, router_logits_list, and input_ids_list to ensure all three lists
have the same length and prevent silent truncation of mismatched items. This
will make the code raise an error immediately if the lists diverge in length
rather than silently dropping trailing chunks.

In `@tensorrt_llm/_torch/modules/fused_moe/mega_moe/mega_moe_deepgemm.py`:
- Around line 202-207: The function signature accepts activation_clamp through
**kwargs but no longer has it as an explicit parameter, causing existing code
that passes activation_clamp= to silently drop that argument with no warning.
Add logic after the function signature to check if activation_clamp exists in
kwargs, then either map it to swiglu_limit_scalar (if swiglu_limit_scalar is
None) or raise an error if both parameters are provided simultaneously. Remove
activation_clamp from kwargs after handling it to prevent it from being passed
downstream where it is not expected. This preserves backward compatibility while
preventing silent failures for callers using the deprecated parameter name.
- Around line 395-449: The exception handling is too broad in two places. First,
at the MPI local-rank discovery block (where comm.Split_type and Get_rank are
called), change the `except Exception:` clause to specifically catch
`mpi4py.MPI.Exception` to avoid masking unexpected failures. Second, at the
dist.init_process_group call, the bare `except RuntimeError:` assumes all
RuntimeErrors are port-race collisions and automatically retries. Instead, catch
RuntimeError as exc, check if the error message contains "address already in
use" or "eaddrinuse" (case-insensitive), and only proceed with the retry logic
if this condition is true; otherwise re-raise the exception to surface actual
NCCL or environment configuration errors.

In `@tensorrt_llm/_torch/modules/fused_moe/quantization.py`:
- Around line 5353-5357: The loop that empties the Parameters (w3_w1_weight,
w3_w1_weight_scale, w2_weight_scale) does not record metadata before reseating
them. Since the class inherits pre_reload_weights() which only rebuilds
parameters listed in module.rebuild_tensor_metadata, these buffers cannot be
properly restored during reload. Before emptying these parameters in the loop,
capture their original metadata by recording their shapes and dtypes in
module.rebuild_tensor_metadata, or use an existing replacement helper method to
maintain the reload contract. This ensures that when load_weights() is called
later, it can properly restore these tensors before copying data into them.

In `@tensorrt_llm/_torch/modules/fused_moe/routing.py`:
- Around line 553-558: The hashed routing path in the gate_forward call passes
self.callable_e_score_correction_bias() directly to
torch.ops.trtllm.gate_forward, but this callable can return None when there is
no bias (as documented for hashed DeepSeekV4). The gate_forward operation
expects a torch.Tensor for the bias parameter, not None. Before calling
gate_forward in the is_hashed block, normalize the bias by checking if
callable_e_score_correction_bias() returns None and providing an appropriate
zero tensor or default tensor value that matches the expected shape and device,
ensuring the dispatcher receives a valid tensor instead of None.

In `@tensorrt_llm/quantization/utils/fp8_utils.py`:
- Around line 497-499: The swiglu_limit activation semantics are inconsistent
across three files, treating zero and negative values destructively. In
tensorrt_llm/quantization/utils/fp8_utils.py lines 497-499, change the
has_swiglu_limit check from testing "swiglu_limit is not None" to "swiglu_limit
is not None and swiglu_limit > 0.0" (optionally also require math.isfinite for
additional robustness). In cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp lines
172-183, modify the logic that sets args.has_gemm1_clamp_limit_value to only
enable it when the limit is positive; otherwise explicitly clear both the flag
and value. In tensorrt_llm/_torch/modules/fused_moe/moe_op_backend.py lines
613-617, change the NotImplementedError condition to only trigger for positive
clamp limits, treating None or non-positive values as a no-op clamp instead of
an error.

---

Outside diff comments:
In `@cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/runner.h`:
- Line 2: Update the copyright year range in the header comment at the top of
runner.h to reflect the current year, since this file is being modified in this
PR. Change the copyright line from ending at 2025 to the current year to comply
with TensorRT-LLM coding guidelines that require the copyright header to include
the year of the latest meaningful modification.

In `@tensorrt_llm/_torch/modules/fused_moe/create_moe.py`:
- Around line 428-445: There is a mismatch between validation logic and the
TritonFusedMoE constructor signature. The validation logic permits both
swiglu_limit and swiglu_limit_scalar for TritonFusedMoE, but the TritonFusedMoE
constructor only accepts swiglu_limit, swiglu_alpha, and swiglu_beta—not
swiglu_limit_scalar. Either remove TritonFusedMoE from the validation block that
permits swiglu_limit_scalar to be provided together with swiglu_limit, or add an
explicit assertion or error check in the TritonFusedMoE branch that rejects
swiglu_limit_scalar if it is provided, similar to how the assertion already
rejects apply_router_weight_on_input.

In `@tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py`:
- Around line 1137-1142: The forward_chunk method has an input_ids parameter
typed as Optional[torch.IntTensor] but lacks a default value, causing existing
callers that skip this parameter to fail. Add a default value of None to the
input_ids parameter definition to make it truly optional and backward compatible
with callers that use forward_chunk(x, router_logits, output_dtype=...) without
providing input_ids.

In `@tensorrt_llm/_torch/modules/fused_moe/fused_moe_trtllm_gen.py`:
- Around line 441-443: The `_supports_load_balancer()` method needs to
consistently report when separated routing is required. Currently it returns
True when `_requires_separated_routing()` is true in the first condition, but
ensure this logic properly propagates to all code paths so that callers using
this method to determine whether top-k routing is external (such as for
DeepSeekV4 which sets `routing_method.requires_separated_routing = True`)
correctly classify cases with separated routing enabled. Verify that the
separated routing requirement is properly accounted for in the return statement
logic, making sure the method reports True whenever separated routing is in
effect regardless of the DP or parallel_size configuration.

---

Nitpick comments:
In `@cpp/tensorrt_llm/kernels/customMoeRoutingKernels.cu`:
- Line 313: The kTOPK constant is duplicated in customMoeRoutingKernels.cu (line
313) and moeGateOp.cpp (line 29), creating maintenance issues if the value needs
to change. Define kTOPK as a static constexpr int in a shared header file that
both customMoeRoutingKernels.cu and moeGateOp.cpp can include, then remove the
duplicate static constexpr int kTOPK = 6 definitions from both implementation
files and replace them with includes of the header. This ensures a single source
of truth for the constant value.

In `@tensorrt_llm/_torch/custom_ops/trtllm_gen_custom_ops.py`:
- Around line 1019-1023: The function signature has gemm1_clamp_limit positioned
before output, which compromises backward compatibility with positional
arguments. Move the gemm1_clamp_limit parameter to the end of the parameter list
(after use_dp) in both the main function definition and the register_fake
implementation to ensure positional argument safety and prevent potential silent
misinterpretation if calling patterns evolve in the future.

In `@tensorrt_llm/_torch/modules/fused_moe/moe_scheduler.py`:
- Around line 624-626: Add the `strict=True` parameter to the zip() call that
iterates over x_list, router_logits_list, and input_ids_list to enforce that all
three lists have equal length and protect against future refactoring mistakes
that could cause length mismatches.
🪄 Autofix (Beta)

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: 42c24abb-ea2e-42f4-b47d-e3167db8586f

📥 Commits

Reviewing files that changed from the base of the PR and between 0ec3250 and 41dcd0e.

📒 Files selected for processing (49)
  • 3rdparty/fetch_content.json
  • cpp/tensorrt_llm/kernels/customMoeRoutingKernels.cu
  • cpp/tensorrt_llm/kernels/customMoeRoutingKernels.h
  • cpp/tensorrt_llm/kernels/cutlass_kernels/cutlass_heuristic.cpp
  • cpp/tensorrt_llm/kernels/cutlass_kernels/moe_gemm/moe_lora_problem_builder.cu
  • cpp/tensorrt_llm/kernels/dsv3MinLatencyKernels/dsv3RouterGemm.cu
  • cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/DevKernel.cu
  • cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/DevKernel.h
  • cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/routing/RoutingKernelTopK.cuh
  • cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/runner.cu
  • cpp/tensorrt_llm/kernels/trtllmGenKernels/blockScaleMoe/runner.h
  • cpp/tensorrt_llm/thop/CMakeLists.txt
  • cpp/tensorrt_llm/thop/dsv3RouterGemmOp.cpp
  • cpp/tensorrt_llm/thop/fp8BlockScaleMoe.cpp
  • cpp/tensorrt_llm/thop/moeGateOp.cpp
  • tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py
  • tensorrt_llm/_torch/custom_ops/torch_custom_ops.py
  • tensorrt_llm/_torch/custom_ops/trtllm_gen_custom_ops.py
  • tensorrt_llm/_torch/distributed/moe_alltoall.py
  • tensorrt_llm/_torch/models/modeling_gemma4.py
  • tensorrt_llm/_torch/modules/fused_moe/__init__.py
  • tensorrt_llm/_torch/modules/fused_moe/communication/nvlink_one_sided.py
  • tensorrt_llm/_torch/modules/fused_moe/configurable_moe.py
  • tensorrt_llm/_torch/modules/fused_moe/create_moe.py
  • tensorrt_llm/_torch/modules/fused_moe/fused_moe_cute_dsl.py
  • tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py
  • tensorrt_llm/_torch/modules/fused_moe/fused_moe_deepgemm.py
  • tensorrt_llm/_torch/modules/fused_moe/fused_moe_triton.py
  • tensorrt_llm/_torch/modules/fused_moe/fused_moe_trtllm_gen.py
  • tensorrt_llm/_torch/modules/fused_moe/fused_moe_vanilla.py
  • tensorrt_llm/_torch/modules/fused_moe/fused_moe_wide_ep.py
  • tensorrt_llm/_torch/modules/fused_moe/interface.py
  • tensorrt_llm/_torch/modules/fused_moe/mega_moe/mega_moe_deepgemm.py
  • tensorrt_llm/_torch/modules/fused_moe/moe_load_balancer.py
  • tensorrt_llm/_torch/modules/fused_moe/moe_op_backend.py
  • tensorrt_llm/_torch/modules/fused_moe/moe_scheduler.py
  • tensorrt_llm/_torch/modules/fused_moe/ops/moe_op_deepgemm.py
  • tensorrt_llm/_torch/modules/fused_moe/quantization.py
  • tensorrt_llm/_torch/modules/fused_moe/routing.py
  • tensorrt_llm/_torch/modules/gated_mlp.py
  • tensorrt_llm/_torch/modules/linear.py
  • tensorrt_llm/_torch/modules/swiglu.py
  • tensorrt_llm/quantization/utils/fp8_utils.py
  • tensorrt_llm/tools/layer_wise_benchmarks/runner.py
  • tests/unittest/_torch/modules/moe/test_moe_module.py
  • tests/unittest/_torch/modules/test_moe_load_balancer.py
  • tests/unittest/_torch/modules/test_moe_routing.py
  • tests/unittest/_torch/thop/parallel/test_dsv3_router_gemm.py
  • tests/unittest/_torch/thop/serial/test_moe_gate.py
💤 Files with no reviewable changes (1)
  • tensorrt_llm/_torch/modules/linear.py

Comment thread cpp/tensorrt_llm/kernels/customMoeRoutingKernels.cu
Comment thread cpp/tensorrt_llm/kernels/customMoeRoutingKernels.cu
Comment thread cpp/tensorrt_llm/kernels/cutlass_kernels/moe_gemm/moe_lora_problem_builder.cu Outdated
Comment thread tensorrt_llm/_torch/modules/fused_moe/create_moe.py Outdated
Comment thread tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py
Comment thread tensorrt_llm/_torch/modules/fused_moe/mega_moe/mega_moe_deepgemm.py
Comment thread tensorrt_llm/_torch/modules/fused_moe/mega_moe/mega_moe_deepgemm.py
Comment thread tensorrt_llm/_torch/modules/fused_moe/quantization.py Outdated
Comment thread tensorrt_llm/_torch/modules/fused_moe/routing.py Outdated
Comment thread tensorrt_llm/quantization/utils/fp8_utils.py Outdated
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54520 [ kill ] triggered by Bot. Commit: 148479f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54519 [ run ] completed with state ABORTED. Commit: 41dcd0e

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54520 [ kill ] completed with state SUCCESS. Commit: 148479f
Successfully killed previous jobs for commit 148479f

Link to invocation

@lfr-0531

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54525 [ run ] triggered by Bot. Commit: 148479f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54525 [ run ] completed with state SUCCESS. Commit: 148479f
/LLM/main/L0_MergeRequest_PR pipeline #43580 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

@xxi-nv

xxi-nv commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Suggestion: collapse swiglu_limit_scalar into swiglu_limit; don't add it to backends that consume the per-expert tensor.

swiglu_limit (per-expert tensor) and swiglu_limit_scalar (uniform float) are the same concept (the SwiGLU clamp limit) in two representations. The split leaks an internal kernel-ABI difference into the public module/backend constructors, and the scalar is plumbed into backends that never read it.

Who actually consumes the scalar — only the FP8 separate-activation path:

fused_moe_deepgemm.py:726 → silu_and_mul_masked_post_quant_fwd(swiglu_limit=self.swiglu_limit_scalar)
ops/moe_op_deepgemm.py:266 → swiglu_limit=getattr(module, "swiglu_limit_scalar", None)
fused_moe_trtllm_gen.py:684 → gemm1_clamp_limit=self.swiglu_limit_scalar
mega_moe_deepgemm.py:731 → activation_clamp=self.swiglu_limit_scalar
Who does NOT consume it but still gets the new ctor arg: CutlassFusedMoE (uses the tensor via moe_op_cutlass.py:166), WideEPMoE (stores only), Triton (uses the tensor). For those, swiglu_limit_scalar is a dead parameter.

Why one public param is enough: the model always provides a uniform clamp (DSv4 config.swiglu_limit = 10.0). The per-expert tensor is derived internally for NVFP4 only, because the clamp is folded with per-expert fc31_alpha (quantization.py:3954 swiglu_limit.data.div_(fc31_alpha)) — that division is what makes it genuinely per-expert, not the public API. And the tensor→scalar reduction already exists: mega_moe_cute_dsl.py:_resolve_gate_up_clamp takes the per-layer swiglu_limit tensor, asserts uniformity, and reduces to one float.

Proposed shape:

Keep a single public swiglu_limit: Union[float, torch.Tensor] (or just float, since both known consumers — DSv4 and GPT-OSS — use a uniform limit). Drop swiglu_limit_scalar from MoE.init and from every backend constructor.
Each backend derives the form its kernel needs, internally:
NVFP4/MXFP4 fused-activation: keep the existing ÷ fc31_alpha post-load step → per-expert tensor (internal detail).
FP8 separate-activation: use the float directly (reuse the _resolve_gate_up_clamp uniformity-checked reduction when the input is a tensor).
This removes the dead ctor args on Cutlass/WideEP/Triton and keeps the per-expert representation as an internal NVFP4 weight-post-load concern rather than a second user-facing parameter.

**For the MOE API part, I will do the refactor in

TRTLLM-13501 -- [TRTLLM-13501](https://jirasw.nvidia.com/browse/TRTLLM-13501)**

@xxi-nv xxi-nv 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.

To unblock the merge, For the MOE API part, I will do the refactor in
TRTLLM-13501 -- TRTLLM-13501

Comment thread tests/unittest/_torch/modules/moe/test_moe_module.py Outdated
Comment thread tensorrt_llm/_torch/modules/fused_moe/fused_moe_cutlass.py
@xxi-nv
xxi-nv requested a review from yuanjingx87 June 17, 2026 06:48
@lfr-0531
lfr-0531 force-pushed the user/fanrongl/dsv4-moe-routing branch from 148479f to 42aeb73 Compare June 17, 2026 07:01
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55294 [ run ] completed with state FAILURE. Commit: dc89a4a
/LLM/main/L0_MergeRequest_PR pipeline #44246 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

@xxi-nv

xxi-nv commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55311 [ run ] triggered by Bot. Commit: dc89a4a Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55311 [ run ] completed with state FAILURE. Commit: dc89a4a
/LLM/main/L0_MergeRequest_PR pipeline #44262 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

@xxi-nv

xxi-nv commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55319 [ run ] triggered by Bot. Commit: dc89a4a Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55319 [ run ] completed with state FAILURE. Commit: dc89a4a
/LLM/main/L0_MergeRequest_PR pipeline #44270 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

@xxi-nv

xxi-nv commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55321 [ run ] triggered by Bot. Commit: dc89a4a Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55321 [ run ] completed with state FAILURE. Commit: dc89a4a
/LLM/main/L0_MergeRequest_PR pipeline #44272 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

@xxi-nv

xxi-nv commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55325 [ run ] triggered by Bot. Commit: dc89a4a Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55325 [ run ] completed with state FAILURE. Commit: dc89a4a
/LLM/main/L0_MergeRequest_PR pipeline #44276 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

@xxi-nv

xxi-nv commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@yuanjingx87 yuanjingx87 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.

approve on oss-compliance perspective.

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55347 [ run ] triggered by Bot. Commit: 6713a0d Link to invocation

@lfr-0531

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55351 [ run ] triggered by Bot. Commit: 6713a0d Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55347 [ run ] completed with state ABORTED. Commit: 6713a0d

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55351 [ run ] completed with state SUCCESS. Commit: 6713a0d
/LLM/main/L0_MergeRequest_PR pipeline #44301 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

@xxi-nv

xxi-nv commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55448 [ run ] triggered by Bot. Commit: 6713a0d Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #55448 [ run ] completed with state SUCCESS. Commit: 6713a0d
/LLM/main/L0_MergeRequest_PR pipeline #44383 completed with status: 'SUCCESS'

CI Report

Link to invocation

@xxi-nv
xxi-nv enabled auto-merge (squash) June 24, 2026 11:30
@xxi-nv
xxi-nv merged commit 71613f9 into NVIDIA:main Jun 24, 2026
8 checks passed
@xxi-nv
xxi-nv deleted the user/fanrongl/dsv4-moe-routing branch June 24, 2026 11:32
thorjohnsen added a commit to thorjohnsen/TensorRT-LLM that referenced this pull request Jul 6, 2026
… import

Between 1.3.0rc19 and rc20, an import-time deep_gemm.set_pdl() call
(added in NVIDIA#15402) instantiated DeepGEMM's DeviceRuntime (cuBLASLt handle
+ 32 MiB workspace tensor), creating a CUDA context (~0.5-1.2 GiB with
loaded modules, arch-dependent) in every process importing tensorrt_llm:
the trtllm-bench parent (which never launches a kernel) and every MPI
worker on its default device before torch.cuda.set_device. Those
contexts are resident when the KV cache pool is sized from free GPU
memory, shrinking the pool (RTX 6000D: 48.33 -> 47.39 GiB, max
concurrent requests 513 -> 503) and causing ~10% throughput regressions
on memory-tight GPUs (this bug and nvbugs 6405760, 6418453, 6419078)
via a long low-batch scheduling tail. The root cause was fixed on main
by NVIDIA#15632, which defers PDL configuration to PyTorchModelEngine init.

Add a regression test asserting that importing tensorrt_llm neither
configures DeepGEMM PDL nor creates a CUDA context, so the import path
stays free of device side effects.

Signed-off-by: Thor Johnsen <41591019+thorjohnsen@users.noreply.github.com>
BrianLi23 pushed a commit to BrianLi23/TensorRT-LLM that referenced this pull request Jul 9, 2026
Signed-off-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Signed-off-by: xxi <xxi@nvidia.com>
Co-authored-by: Fanrong Li <lfr-0531@users.noreply.github.com>
Co-authored-by: xxi <xxi@nvidia.com>
Co-authored-by: xingfei xi <95731198+xxi-nv@users.noreply.github.com>
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