Skip to content

[https://nvbugs/6434512][fix] Select Marlin for Qwen3.5 MoE on Hopper - #17293

Open
lfr-0531 wants to merge 3 commits into
NVIDIA:mainfrom
lfr-0531:user/fanrongl/fix-nvbug-6434512-h20-moe-profiles
Open

[https://nvbugs/6434512][fix] Select Marlin for Qwen3.5 MoE on Hopper#17293
lfr-0531 wants to merge 3 commits into
NVIDIA:mainfrom
lfr-0531:user/fanrongl/fix-nvbug-6434512-h20-moe-profiles

Conversation

@lfr-0531

@lfr-0531 lfr-0531 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Description

Qwen3.5 MoE checkpoints with NVFP4 experts currently inherit the Qwen3-Next defaults without selecting a Hopper-compatible MoE GEMM backend. This affects both globally NVFP4 and mixed-precision checkpoints. On H20, the default CUTLASS W4A4 path requires Blackwell and fails during warmup because no supported MoE tactic remains.

This change preserves the existing Qwen3-Next defaults and selects Marlin for Qwen3.5 text and VL MoE models when the checkpoint quantization algorithm is NVFP4 or MIXED_PRECISION and the GPU is in the Marlin-supported SM range. Other quantization configurations and Blackwell keep their existing backend selection.

The change restores the default H20 execution path without introducing an API, dependency, documentation, ownership, or architecture change. Same-node 8-GPU H20 measurements confirmed that the fixed automatic selection matches an explicit-Marlin reference within normal run-to-run variation.

Related NVBug: https://nvbugs/6434512

Test Coverage

  • Diff-scoped pre-commit checks: passed.
  • pytest tests/unittest/_torch/modeling/test_modeling_qwen3_5_vl_moe.py -k qwen35_moe_model_defaults: 3 passed, 6 deselected.
  • Full source build and editable installation in the H20 Docker environment: passed.
  • Runtime verification confirmed that the benchmark loaded commit 050a0d3036 and the modified modeling_qwen3_5.py.
  • The seven Qwen3.5 H20 cases from tests/integration/test_lists/qa/llm_perf_core.yml: all passed on 8 H20 GPUs.
  • Global-NVFP4 same-node H20 A/B results versus explicit Marlin: +0.787% output throughput for 128/128, +0.017% for max-batch-size-1 8000/1000, and -0.151% for max-batch-size-512 8000/1000.
  • Mixed-precision Qwen3.5-397B-A17B-NVFP4-V2 verification on 8 H20 GPUs:
    • Checkpoint metadata: MIXED_PRECISION with 375 FP8 and 60 NVFP4 layer entries.
    • Unfixed automatic path: failed during warmup with No supported MoE GEMM tactic remains after replacing unsupported NO_SMEM epilogues.
    • Explicit Marlin reference: 1442.346951 output tokens/s.
    • Fixed automatic path: 1458.025686 output tokens/s and selected MoeConfig(backend='MARLIN') with allowed_backends=['marlin'].
    • Fixed automatic versus explicit Marlin: +1.087%.

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 a review from a team as a code owner August 5, 2026 07:11
@lfr-0531
lfr-0531 requested a review from yechank-nvidia August 5, 2026 07:11
@lfr-0531
lfr-0531 requested a review from nv-guomingz August 5, 2026 07:11
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Qwen3.5 MoE models now share hardware-aware backend defaults. Supported Hopper configurations select MARLIN for MoE and NVFP4 GEMM. Tests cover Hopper, mixed-precision, and Blackwell configurations.

Changes

Qwen3.5 NVFP4 backend defaults

Layer / File(s) Summary
Backend default resolution
tensorrt_llm/_torch/models/modeling_qwen3_5.py
Adds shared defaults for Qwen3.5 MoE models. The causal-LM and VLM classes use the helper for hardware-aware backend selection.
Backend default validation
tests/unittest/_torch/modeling/test_modeling_qwen3_5_vl_moe.py
Tests Hopper NVFP4 selection, mixed-precision behavior, Blackwell NVFP4 behavior, and KV-cache defaults for both model classes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: yechank-nvidia, nv-guomingz, bowenfu

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title follows the required ticket and type format and clearly summarizes the Marlin backend fix for Qwen3.5 MoE on Hopper.
Description check ✅ Passed The description explains the issue, solution, test coverage, performance results, and checklist status with sufficient detail.
✨ 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: 1

🤖 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/models/modeling_qwen3_5.py`:
- Line 58: Annotate every listed function: add parameter and return annotations
to _get_qwen35_moe_model_defaults, Qwen3_5MoeForCausalLM.get_model_defaults, and
Qwen3_5MoeVLModel.get_model_defaults in
tensorrt_llm/_torch/models/modeling_qwen3_5.py; annotate monkeypatch and add ->
None to the three affected test functions in
tests/unittest/_torch/modeling/test_modeling_qwen3_5_vl_moe.py at lines 161,
184, and 201.
🪄 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: 88037976-5a87-4cc1-85d9-fe18ea04a3b1

📥 Commits

Reviewing files that changed from the base of the PR and between 7608520 and ec8827d.

📒 Files selected for processing (2)
  • tensorrt_llm/_torch/models/modeling_qwen3_5.py
  • tests/unittest/_torch/modeling/test_modeling_qwen3_5_vl_moe.py

Comment thread tensorrt_llm/_torch/models/modeling_qwen3_5.py Outdated
@lfr-0531

lfr-0531 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63983 [ run ] triggered by Bot. Commit: 7ea8d3f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63983 [ run ] completed with state SUCCESS. Commit: 7ea8d3f
/LLM/main/L0_MergeRequest_PR pipeline #51917 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

@lfr-0531

lfr-0531 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64036 [ run ] triggered by Bot. Commit: 7ea8d3f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64036 [ run ] completed with state SUCCESS. Commit: 7ea8d3f
/LLM/main/L0_MergeRequest_PR pipeline #51966 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

@lfr-0531

lfr-0531 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64064 [ run ] triggered by Bot. Commit: 7ea8d3f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64064 [ run ] completed with state SUCCESS. Commit: 7ea8d3f
/LLM/main/L0_MergeRequest_PR pipeline #51993 completed with status: 'SUCCESS'

CI Report

Link to invocation

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

Approving — the comments below are optional touch-ups, not blockers.

Change looks right for the reported H20 failure and the marlin-only GEMM list is fine in practice — the other NVFP4 backends are all SM100+, so nothing is lost on Ada/Hopper.

Two things to confirm before merge (details inline): whether the trigger covers the ModelOpt MIXED_PRECISION NVFP4 exports this file already normalizes, and whether the dense Qwen3.5 classes need the same nvfp4_gemm_config treatment.

Description nit: the auto-generated summary claims three new test functions (test_qwen35_moe_model_defaults_select_marlin_on_hopper, ..._keep_non_nvfp4_backends, ..._keep_blackwell_backends) — the diff actually adds one parametrized test with three params. Worth fixing so a future reader grepping for those names isn't confused.

One more question: MarlinFusedMoE doesn't support the MoE load balancer. Since this now flips the backend by default, is there a configuration (EPLB / wide-EP) where the new default turns a working run into a startup error? If so, a note in the helper's comment would help the next person.

def _get_qwen35_moe_model_defaults(llm_args):
defaults = Qwen3NextForCausalLM.get_model_defaults(llm_args)
quant_config = getattr(llm_args, "quant_config", None)
if getattr(

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 gates on the global quant_algo. ModelOpt MIXED_PRECISION exports for Qwen3.5 — which _normalize_qwen35_quant_config_dict / _lm_head_nvfp4_enabled below go to some length to handle — report quant_algo=MIXED_PRECISION with the real algorithms per layer, so they'd never take this branch and would still hit the no-supported-tactic failure on H20.

Was the validated checkpoint (Qwen3.5-397B-A17B-NVFP4) a plain NVFP4 export? If mixed-precision exports exist for this family, note that widening the predicate alone isn't enough: on SM90 _normalize_qwen35_quant_config_dict leaves routed experts at W4A16_NVFP4 (convert_to_nvfp4 is SM100/103 only), and MarlinFusedMoE.can_implement rejects anything but NVFP4. Worth either handling explicitly or stating in the comment that mixed-precision is out of scope.

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, Brian! Added MIXED_PRECISION support.

}


def _get_qwen35_moe_model_defaults(llm_args):

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.

Only the MoE classes get this. Qwen3_5ForCausalLM / Qwen3_5VLModel (dense) still inherit the default allowed_backends=['cutlass','cublaslt','cuda_core'], and all three of those NVFP4 paths require SM100+ (CudaCoreNVFP4Runner.MIN_SM_VERSION = 100), so a dense NVFP4 Qwen3.5 checkpoint on Ada/Hopper would fail on the plain Linear GEMMs.

The nvfp4_gemm_config half of this dict isn't MoE-specific — consider splitting it into a _qwen35_nvfp4_gemm_defaults(llm_args) helper wired into the dense classes too, and keeping moe_config on the MoE classes only. If dense NVFP4 exports don't exist yet, a one-line note saying so would keep the asymmetry from reading like an oversight.

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! This PR is scoped to the nvidia/Qwen3.5-397B-A17B-NVFP4 MoE checkpoint. I'll keep this change MoE-only and we can handle dense NVFP4 separately.

}
)

llm_args = SimpleNamespace(quant_config=SimpleNamespace(quant_algo=quant_algo))

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 builds llm_args from SimpleNamespace and compares against a literal copy of the dict the helper returns, so it's close to tautological: a typo'd field name (nvfp4_config), a wrong enum spelling ("Marlin"), or a value the Pydantic Literal rejects would all still pass here and only blow up at runtime on the machine that actually loads the model.

Suggest making at least the hopper-nvfp4 case round-trip through the real schema — construct a TorchLlmArgs, run apply_model_defaults_to_llm_args(llm_args, defaults), and assert llm_args.moe_config.backend == "MARLIN" / llm_args.nvfp4_gemm_config.allowed_backends == ["marlin"]. That also pins the behavior the fix depends on (defaults applied only when the user didn't set the field).

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.

Fixed. The consolidated test now uses real TorchLlmArgs and QuantConfig, applies the defaults, and checks the parsed backend fields for both text and VL MoE models.

Signed-off-by: Fanrong Li <23290157+lfr-0531@users.noreply.github.com>
Signed-off-by: Fanrong Li <23290157+lfr-0531@users.noreply.github.com>
@lfr-0531
lfr-0531 force-pushed the user/fanrongl/fix-nvbug-6434512-h20-moe-profiles branch from 7ea8d3f to 69b54e4 Compare August 7, 2026 08:46
@coderabbitai

coderabbitai Bot commented Aug 7, 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.

…Hopper

Signed-off-by: Fanrong Li <23290157+lfr-0531@users.noreply.github.com>
@lfr-0531
lfr-0531 force-pushed the user/fanrongl/fix-nvbug-6434512-h20-moe-profiles branch from 62cbf9e to 050a0d3 Compare August 7, 2026 09:25
@lfr-0531

lfr-0531 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64574 [ run ] triggered by Bot. Commit: 050a0d3 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64574 [ run ] completed with state SUCCESS. Commit: 050a0d3
/LLM/main/L0_MergeRequest_PR pipeline #52438 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

@lfr-0531 lfr-0531 changed the title [https://nvbugs/6434512][fix] Select Marlin for Qwen3.5 NVFP4 on Hopper [https://nvbugs/6434512][fix] Select Marlin for Qwen3.5 MoE on Hopper Aug 7, 2026
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.

3 participants