Skip to content

[TRTLLM-14054][perf] Qwen3.5-VL: pass the inner LM's normalized model_config to the weight mapper#16353

Merged
kaiyux merged 1 commit into
NVIDIA:mainfrom
kaiyux:perf/qwen35-mapper-normalized-config-20260713
Jul 14, 2026
Merged

[TRTLLM-14054][perf] Qwen3.5-VL: pass the inner LM's normalized model_config to the weight mapper#16353
kaiyux merged 1 commit into
NVIDIA:mainfrom
kaiyux:perf/qwen35-mapper-normalized-config-20260713

Conversation

@kaiyux

@kaiyux kaiyux commented Jul 14, 2026

Copy link
Copy Markdown
Member

Description

_Qwen3_5VLModel.load_weights handed Qwen3_5MoeHfWeightMapper the VLM wrapper's model_config, but only the inner LM's config goes through the Qwen3.5 quant-dict normalization applied in the inner LM's __init__ (HF→TRT-LLM key translation + synthesis of the fused in_proj_qkvz FP8 entry).

With the wrapper's un-normalized copy, the mapper misses that FP8 entry, dequantizes the GDN in_proj projections to bf16 and drops their calibrated scales; the FP8-built module then re-casts the weights with weight_scale=1.0 and quantizes activations dynamically in front of every GDN in_proj GEMM.

Fix: pass self.llm.model_config. The GDN in_proj weights stay FP8 with their calibrated scales, the projection runs on the static per-tensor FP8 path (static_quantize_e4m3_per_tensor + scaled-mm), and the per-call dynamic-quant chain disappears from both prefill and decode. One functional line plus a comment.

Test Coverage

concurrency before (tok/s) this PR (tok/s) delta
1 331.22 382.96 +15.62%
2 628.48 712.48 +13.37%
4 1180.78 1374.39 +16.40%
8 2208.70 2540.62 +15.03%
16 3984.19 4490.79 +12.72%
32 7161.73 8064.49 +12.61%
64 12360.83 13571.48 +9.79%
128 19579.72 21250.80 +8.53%
256 17442.00 17304.34 −0.79%
512 16998.46 16993.55 −0.03%

Output throughput improves +10.32% on average across the 10-point curve — up to +16.4% at low concurrency, flat within run-to-run noise at the saturated top end. No latency trade-away at the top point: median TPOT/ITL flat, median TTFT at concurrency 512 improves 28% (6835 ms → 4911 ms; large-M prefill GEMMs no longer pay the per-call dynamic-quant chain).

PR Checklist

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

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved Qwen3.5 vision-language model weight loading with quantized configurations.
    • Prevented certain FP8 weights from being incorrectly converted to bfloat16, improving compatibility and preserving expected model behavior.

…to the weight mapper

_Qwen3_5VLModel.load_weights handed Qwen3_5MoeHfWeightMapper the VLM
wrapper's model_config, but only the inner LM's config goes through the
Qwen3.5 quant-dict normalization applied in the inner LM's __init__
(HF->TRT-LLM key translation + synthesis of the fused in_proj_qkvz FP8
entry). With the wrapper's un-normalized copy the mapper misses that
FP8 entry, dequantizes the GDN in_proj projections to bf16 and drops
their calibrated scales; the FP8-built module then re-casts the weights
with weight_scale=1.0 and quantizes activations dynamically in front of
every GDN in_proj GEMM.

Passing self.llm.model_config keeps GDN in_proj FP8 with its calibrated
scales, so the projection runs on the static per-tensor FP8 path and
the per-call dynamic-quant chain disappears (prefill and decode).

Measured with trtllm-serve + benchmark_serving on Qwen3.6-35B-A3B-NVFP4
(hybrid gated-delta-net + MoE) on 2x B200 (TP2 + EP2), ISL=1024/
OSL=6144, concurrency sweep 1..512: output throughput improves 10.3%
on average across the 10-point curve (up to +16.4% at low concurrency,
flat within noise at the saturated top end), and median TTFT at
concurrency 512 improves 28%.

Signed-off-by: Kaiyu Xie <26294424+kaiyux@users.noreply.github.com>
@kaiyux

kaiyux commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1454ea5c-88e8-4831-acff-43f5ca59df12

📥 Commits

Reviewing files that changed from the base of the PR and between 7d7c364 and aaf1179.

📒 Files selected for processing (1)
  • tensorrt_llm/_torch/models/modeling_qwen3_5.py

📝 Walkthrough

Walkthrough

Qwen3_5VLModel.load_weights now initializes the weight mapper with the inner language model’s normalized configuration, preserving quantization metadata for fused FP8 modules.

Changes

Qwen3.5 weight loading

Layer / File(s) Summary
Use normalized inner LM configuration
tensorrt_llm/_torch/models/modeling_qwen3_5.py
load_weights passes self.llm.model_config to weight_mapper.init_model_and_config, retaining the inner model’s quantization normalization for fused FP8 handling.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: chang-l, aswinvisva

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 matches the change: it names the Qwen3.5-VL weight-mapper config fix and includes a valid ticket and type.
Description check ✅ Passed The description follows the template with Description, Test Coverage, and PR Checklist, and it provides concrete implementation and validation details.
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.

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

Out of curiosity, how did you find this issue?

@kaiyux

kaiyux commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

Out of curiosity, how did you find this issue?

The agent found this when optimizing performance for Qwen-3.6 model : )

@kaiyux

kaiyux commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@kaiyux
kaiyux enabled auto-merge (squash) July 14, 2026 06:02
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #59127 [ run ] triggered by Bot. Commit: aaf1179 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@kaiyux

kaiyux commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

1 similar comment
@kaiyux

kaiyux commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #59178 [ run ] triggered by Bot. Commit: aaf1179 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #59178 [ run ] completed with state SUCCESS. Commit: aaf1179
/LLM/main/L0_MergeRequest_PR pipeline #47679 completed with status: 'SUCCESS'
Pipeline passed with automatic retried tests. Check the rerun report for details.

CI Report

Link to invocation

@kaiyux
kaiyux merged commit 924978f into NVIDIA:main Jul 14, 2026
12 checks passed
@kaiyux
kaiyux deleted the perf/qwen35-mapper-normalized-config-20260713 branch July 14, 2026 14:53
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