Skip to content

[None][feat] Enable MTP for Step-3.7 NVFP4 and port Step-3.7VL vision tower to TRT-LLM modules#14926

Merged
kaiyux merged 7 commits into
NVIDIA:mainfrom
kaiyux:user/kaiyu/step3p7_nvfp4_mtp
Jun 10, 2026
Merged

[None][feat] Enable MTP for Step-3.7 NVFP4 and port Step-3.7VL vision tower to TRT-LLM modules#14926
kaiyux merged 7 commits into
NVIDIA:mainfrom
kaiyux:user/kaiyu/step3p7_nvfp4_mtp

Conversation

@kaiyux

@kaiyux kaiyux commented Jun 4, 2026

Copy link
Copy Markdown
Member

Description

Enables Multi-Token Prediction (MTP) speculative decoding for the Step-3.7-Flash NVFP4 checkpoint and ports the Step-3.7VL vision tower and MLP onto TRT-LLM's native modules. Bundled changes:

  • Enable MTP for Step-3.7 NVFP4 + fix spec token ids on the VLM path. The NVFP4 ModelOpt export ships the 3 plain-path MTP layers (45..47) under the bare model.layers.* namespace, so the NVFP4 checkpoint can now run speculative decoding like the FP8/BF16 checkpoints. On the multimodal path the main model consumes fused inputs_embeds and input_ids is None, so the VLM wrapper now forwards the pre-fusion token ids via a new spec_input_ids argument (image tokens remapped into vocab range) so the MTP/spec worker always receives valid token ids.

  • Port the Step-3.7VL vision tower to the TRT-LLM Attention module. Replaces the raw-torch SDPA vision attention so the vision encoder runs through the backend FMHA dispatch (context-only, FULL mask, varlen via per-image attn_metadata). The PerceptionEncoder head_dim (96) is not a trtllm-gen FMHA cubin size, so q/k/v/o head dims are zero-padded to 128 while 2D RoPE runs on the real channels; a compensating q_scaling preserves the softmax scale. Fused HF in_proj_*/out_proj weights are remapped onto qkv_proj/o_proj during weight loading.

  • Port the Step-3.7VL vision MLP to the base TRT-LLM MLP module. Dispatches the non-gated vision FFN through up_proj -> activation -> down_proj instead of a bespoke c_fc/c_proj nn.Module. HF mlp.c_fc/mlp.c_proj weights are remapped onto up_proj/down_proj during weight loading.

  • Resolve MTP layer count across checkpoint field names. update_spec_config_from_model_config previously read the MTP layer count only from num_nextn_predict_layers (DeepSeek-style). Qwen3Next-style configs (including Qwen3.5) expose it as mtp_num_hidden_layers; the resolver now reads whichever field is present and falls back to a single shared MTP / EAGLE layer when neither exists.

  • Optimize vision RoPE and multimodal H2D copies. Precomputes the vision tower's 2D-RoPE cos/sin tables once per forward pass and threads them through all 47 blocks instead of re-evaluating cos()/sin() inside every attention call. Restricts multimodal device copies to only the tensors the vision tower actually consumes on GPU. Skips the spec_input_ids OOV-sentinel rewrite when speculative decoding is disabled.

Test Coverage

Unit tests:

  • tests/unittest/_torch/modeling/test_modeling_step3p7.py — refreshed for the NVFP4 MTP layer layout; removed test_config_and_weight_accounting_1_nvfp4 waive.
  • tests/unittest/_torch/modeling/test_modeling_step3p7vl.py — vision tower / MLP TRT-LLM module port and weight remapping, RoPE precomputation path.

Accuracy / integration tests (parametrized over mtp_nextn ∈ {0, 3}):

  • accuracy/test_llm_api_pytorch.py::TestStep3_7::test_nvfp4
  • accuracy/test_llm_api_pytorch.py::TestStep3_7::test_fp8_block_scales
  • accuracy/test_llm_api_pytorch_multimodal.py::TestStep3_7::test_fp8_block_scales
  • accuracy/test_llm_api_pytorch_multimodal.py::TestStep3_7::test_nvfp4

Accuracy reference updates:

  • references/gsm8k.yaml: added NVFP4 + MTP entry (accuracy 88, reuses non-spec baseline).
  • references/mmmu.yaml: updated FP8 and NVFP4 baselines from 64 → 60; added FP8+MTP and NVFP4+MTP entries.

Test list updates:

  • tests/integration/test_lists/test-db/l0_dgx_b200.yml: moved NVFP4 MTP case to QA.
  • tests/integration/test_lists/qa/llm_function_core.txt: added Step-3.7 / Step-3.7VL NVFP4 + FP8 MTP accuracy cases (both text and multimodal, mtp_nextn=0 and 3).
  • tests/integration/test_lists/waives.txt: removed test_config_and_weight_accounting_1_nvfp4 skip (NVFP4 MTP now works).

PR Checklist

Please review the following before submitting your PR:

  • PR description clearly explains what and why.

  • PR Follows TRT-LLM CODING GUIDELINES to the best of my knowledge.

  • Test cases are provided for new code paths (see test instructions).

  • If PR introduces API changes, an appropriate PR label is added.

  • Any new dependencies have been scanned for license and vulnerabilities.

  • CODEOWNERS updated if ownership changes.

  • Documentation updated as needed.

  • 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

@kaiyux
kaiyux requested review from a team as code owners June 4, 2026 02:14
@kaiyux
kaiyux requested review from Wanli-Jiang and moraxu June 4, 2026 02:14
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR ports the Step3p7 vision stack to TRT‑LLM building blocks, adds optional spec_input_ids routing for multimodal speculative decoding, rewrites the vision tower batching pipeline, and updates unit and integration tests (GPU gating, bf16, and MTP parameterization).

Changes

Step3p7 Vision Porting and MTP Integration

Layer / File(s) Summary
Step3p7 causal LM spec_input_ids support
tensorrt_llm/_torch/models/modeling_step3p7.py
Step3p7ForCausalLM.forward() gains optional spec_input_ids used by the spec/draft worker; when attention padding is active, spec tokens and position ids are truncated to attn_metadata.num_tokens.
Vision TRT-LLM modules and RoPE wiring
tensorrt_llm/_torch/models/modeling_step3p7vl.py
Adds TRT-LLM primitive imports, reworks RoPE helpers, introduces Step3VisionRope2D.freqs_for_grid(), Step3VisionMLP, Step3VisionAttention and updates transformer blocks to thread AttentionMetadata and per-token flat RoPE (cos, sin).
Vision encoder/tower init & weight remap
tensorrt_llm/_torch/models/modeling_step3p7vl.py
Step3p7VisionEncoder now accepts a single-rank ModelConfig; projector moved to TRT-LLM Linear; HF→TRT-LLM weight remapping added (fused qkv → qkv_proj, o_proj; MLP → up_proj/down_proj) with per-head padding.
Encoder forward, flat RoPE, and embed helper
tensorrt_llm/_torch/models/modeling_step3p7vl.py
Adds _embed(pixel_values), cached attention-metadata helpers, _flat_rope_cos_sin, and refactors forward_features() to run the TRT-LLM transformer on flattened varlen token streams using context-only metadata and per-token RoPE.
Vision tower gather/group/scatter batching
tensorrt_llm/_torch/models/modeling_step3p7vl.py
Step3p7VisionTower.forward() gathers full/patch images across requests, groups by pixel shape, encodes groups in batched passes, scatters embeddings back, and reassembles per-request embeddings in patch-first-then-full order.
Multimodal device paths & spec_input_ids computation
tensorrt_llm/_torch/models/modeling_step3p7vl.py
Adds multimodal_data_device_paths to constrain H2D transfers; when speculative worker exists, computes spec_input_ids by mapping token ids >= vocab_size to image_token_id and forwards them into the inner causal LM.
Integration tests: MTP parameterization
tests/integration/defs/accuracy/test_llm_api_pytorch.py, tests/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py
Parameterizes TestStep3_7 tests over mtp_nextn [0,3], conditionally constructs MTPDecodingConfig when mtp_nextn>0, and wires speculative_config into LLM initialization.
QA/test-list updates and CI matrix
tests/integration/test_lists/qa/llm_function_core.txt, tests/integration/test_lists/test-db/l0_dgx_b200.yml, tests/integration/test_lists/waives.txt
Replaces timeouts with parameterized ids including mtp_nextn, adds B200 pre-merge NVFP4 MTP case, and removes a waiver entry for an NVFP4 weight-accounting test.
Checkpoint layout & safetensors key accounting updates
tests/unittest/_torch/modeling/test_modeling_step3p7.py
Test docs and safetensors-key accounting updated: NVFP4 now treated as exporting MTP layers 45–47 under model.layers.*; regex-based key classification and assertions updated accordingly.
Vision test infra & component tests (GPU)
tests/unittest/_torch/modeling/test_modeling_step3p7vl.py
Adds requires_gpu gating and _GPU_DTYPE (bf16), propagates torch_dtype in test helpers, and refactors many vision tests to run on GPU/bf16 with strengthened numerics and weight-remap assertions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • moraxu
  • Wanli-Jiang
  • nv-guomingz
  • zhenhuaw-me
  • pcastonguay

"A rabbit in the lab, with whiskers bright,
Pokes at RoPE and pads heads at night.
Tokens and pixels hop in a queue,
Spec drafts bounce, then stitch back through.
Hooray — models run, and tests take flight! 🐇"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.82% 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 concisely and clearly describes the two main changes: enabling MTP for Step-3.7 NVFP4 and porting the vision tower to TRT-LLM modules, matching the primary objectives of the PR.
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.
Description check ✅ Passed The PR description is comprehensive, well-structured, and covers all required sections: clear explanation of objectives, detailed test coverage, and completed PR checklist items.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py (1)

801-819: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Assert that the mtp_nextn=3 cases actually stay on the MTP path.

Right now these tests only prove that MMMU still runs after passing speculative_config. If Step-3.7 silently falls back to non-speculative decoding, the new [0, 3] matrix can still pass and we would miss the regression this PR is meant to cover. Please add one direct assertion for the nonzero branch in both tests (or via a shared helper) so coverage is explicitly sufficient for MTP enablement.

Suggested assertion
     def test_fp8_block_scales(self, mtp_nextn):
         with self._make_llm(f"{llm_models_root()}/Step-3.7-Flash-FP8", mtp_nextn=mtp_nextn) as llm:
             assert llm.args.quant_config.quant_algo == QuantAlgo.FP8_BLOCK_SCALES
+            if mtp_nextn > 0:
+                assert llm.args.speculative_config is not None
+                assert llm.args.speculative_config.max_draft_len == mtp_nextn
             task = MMMU(self.MODEL_NAME)
             task.evaluate(
                 llm,
                 sampling_params=self.sampling_params,
                 extra_evaluator_kwargs=self.EXTRA_EVALUATOR_KWARGS,
             )
@@
     def test_nvfp4(self, mtp_nextn):
         with self._make_llm(
             f"{llm_models_root()}/Step-3.7-Flash-NVFP4", mtp_nextn=mtp_nextn
         ) as llm:
             assert llm.args.quant_config.quant_algo == QuantAlgo.NVFP4
+            if mtp_nextn > 0:
+                assert llm.args.speculative_config is not None
+                assert llm.args.speculative_config.max_draft_len == mtp_nextn
             task = MMMU(self.MODEL_NAME)
             task.evaluate(
                 llm,
                 sampling_params=self.sampling_params,
                 extra_evaluator_kwargs=self.EXTRA_EVALUATOR_KWARGS,
             )

As per coding guidelines, for tests/**: “suggest concrete list file names and whether coverage is sufficient, insufficient, or needs follow-up outside the PR.”

🤖 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/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py` around
lines 801 - 819, Add an explicit assertion in both test_fp8_block_scales and
test_nvfp4 to ensure the nonzero mtp_nextn branch actually uses the
MTP/speculative path: when mtp_nextn == 3 assert the LLM instance reports
MTP/speculative enabled (e.g. check llm.args.mtp_nextn == 3 and/or
llm.args.speculative_config is truthy and llm.args.speculative_config.mtp_nextn
== 3) before running MMMU.evaluate so the test fails if Step-3.7 silently falls
back to non-speculative decoding.
🧹 Nitpick comments (2)
tensorrt_llm/_torch/models/modeling_step3p7vl.py (2)

936-937: 💤 Low value

Type annotation mismatch with initialization.

The lists are typed as List[torch.Tensor] but initialized with None values. This works at runtime but is technically a type annotation inaccuracy.

✨ Suggested fix for type accuracy
-        full_feats: Dict[int, List[torch.Tensor]] = {r: [None] * len(full_imgs[r]) for r in order}
-        patch_feats: Dict[int, List[torch.Tensor]] = {r: [None] * len(patch_imgs[r]) for r in order}
+        full_feats: Dict[int, List[Optional[torch.Tensor]]] = {r: [None] * len(full_imgs[r]) for r in order}
+        patch_feats: Dict[int, List[Optional[torch.Tensor]]] = {r: [None] * len(patch_imgs[r]) for r in order}

Note: This also requires importing Optional for the inner list type if not already used.

🤖 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/models/modeling_step3p7vl.py` around lines 936 - 937, The
type annotations for full_feats and patch_feats are inaccurate: they declare
List[torch.Tensor] but initialize lists with None; change their types to
Dict[int, List[Optional[torch.Tensor]]] (import Optional from typing if not
present) so the annotation matches initialization, e.g. update the annotations
for full_feats and patch_feats in modeling_step3p7vl.py to use
Optional[torch.Tensor] for the inner list element type.

318-318: 💤 Low value

Optional: Use tuple unpacking for cleaner shape construction.

The static analysis hint suggests using unpacking syntax which is slightly more idiomatic.

✨ Suggested style improvement
-            pad_shape = q_real.shape[:-1] + (self.head_dim_pad,)
+            pad_shape = (*q_real.shape[:-1], self.head_dim_pad)
🤖 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/models/modeling_step3p7vl.py` at line 318, The pad_shape
assignment currently builds the tuple via concatenation; change it to use tuple
unpacking for clarity: replace the expression assigning pad_shape (which
references q_real and self.head_dim_pad) with an unpacking form like pad_shape =
(*q_real.shape[:-1], self.head_dim_pad) so the shape construction is more
idiomatic and easier to read.
🤖 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/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py`:
- Around line 801-819: Add an explicit assertion in both test_fp8_block_scales
and test_nvfp4 to ensure the nonzero mtp_nextn branch actually uses the
MTP/speculative path: when mtp_nextn == 3 assert the LLM instance reports
MTP/speculative enabled (e.g. check llm.args.mtp_nextn == 3 and/or
llm.args.speculative_config is truthy and llm.args.speculative_config.mtp_nextn
== 3) before running MMMU.evaluate so the test fails if Step-3.7 silently falls
back to non-speculative decoding.

---

Nitpick comments:
In `@tensorrt_llm/_torch/models/modeling_step3p7vl.py`:
- Around line 936-937: The type annotations for full_feats and patch_feats are
inaccurate: they declare List[torch.Tensor] but initialize lists with None;
change their types to Dict[int, List[Optional[torch.Tensor]]] (import Optional
from typing if not present) so the annotation matches initialization, e.g.
update the annotations for full_feats and patch_feats in modeling_step3p7vl.py
to use Optional[torch.Tensor] for the inner list element type.
- Line 318: The pad_shape assignment currently builds the tuple via
concatenation; change it to use tuple unpacking for clarity: replace the
expression assigning pad_shape (which references q_real and self.head_dim_pad)
with an unpacking form like pad_shape = (*q_real.shape[:-1], self.head_dim_pad)
so the shape construction is more idiomatic and easier to read.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 9a9d48ea-055c-438b-853e-1554da434630

📥 Commits

Reviewing files that changed from the base of the PR and between d64b217 and 2f4c150.

📒 Files selected for processing (8)
  • tensorrt_llm/_torch/models/modeling_step3p7.py
  • tensorrt_llm/_torch/models/modeling_step3p7vl.py
  • tests/integration/defs/accuracy/test_llm_api_pytorch.py
  • tests/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py
  • tests/integration/test_lists/qa/llm_function_core.txt
  • tests/integration/test_lists/test-db/l0_dgx_b200.yml
  • tests/unittest/_torch/modeling/test_modeling_step3p7.py
  • tests/unittest/_torch/modeling/test_modeling_step3p7vl.py

@kaiyux

kaiyux commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

/bot --help

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

GitHub Bot Help

/bot [-h] ['run', 'kill', 'skip', 'reuse-pipeline'] ...

Provide a user friendly way for developers to interact with a Jenkins server.

Run /bot [-h|--help] to print this help message.

See details below for each supported subcommand.

Details

run [--reuse-test (optional)pipeline-id --disable-fail-fast --skip-test --stage-list "A10-PyTorch-1, xxx" --gpu-type "A30, H100_PCIe" --test-backend "pytorch, cpp" --add-multi-gpu-test --only-multi-gpu-test --disable-multi-gpu-test --post-merge --extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx" --detailed-log --debug(experimental) --high-priority]

Launch build/test pipelines. All previously running jobs will be killed.

--reuse-test (optional)pipeline-id (OPTIONAL) : Allow the new pipeline to reuse build artifacts and skip successful test stages from a specified pipeline or the last pipeline if no pipeline-id is indicated. If the Git commit ID has changed, this option will be always ignored. The DEFAULT behavior of the bot is to reuse build artifacts and successful test results from the last pipeline.

--disable-reuse-test (OPTIONAL) : Explicitly prevent the pipeline from reusing build artifacts and skipping successful test stages from a previous pipeline. Ensure that all builds and tests are run regardless of previous successes.

--disable-fail-fast (OPTIONAL) : Disable fail fast on build/tests/infra failures.

--skip-test (OPTIONAL) : Skip all test stages, but still run build stages, package stages and sanity check stages. Note: Does NOT update GitHub check status.

--stage-list "A10-PyTorch-1, xxx" (OPTIONAL) : Only run the specified test stages. Supports wildcard * for pattern matching (e.g., "*PerfSanity*" matches all stages containing PerfSanity). Examples: "A10-PyTorch-1, xxx", "PerfSanity". Note: Does NOT update GitHub check status.

--gpu-type "A30, H100_PCIe" (OPTIONAL) : Only run the test stages on the specified GPU types. Examples: "A30, H100_PCIe". Note: Does NOT update GitHub check status.

--test-backend "pytorch, cpp" (OPTIONAL) : Skip test stages which don't match the specified backends. Only support [pytorch, cpp, tensorrt, triton]. Examples: "pytorch, cpp" (does not run test stages with tensorrt or triton backend). Note: Does NOT update GitHub pipeline status.

--only-multi-gpu-test (OPTIONAL) : Only run the multi-GPU tests. Note: Does NOT update GitHub check status.

--disable-multi-gpu-test (OPTIONAL) : Disable the multi-GPU tests. Note: Does NOT update GitHub check status.

--add-multi-gpu-test (OPTIONAL) : Force run the multi-GPU tests in addition to running L0 pre-merge pipeline.

--post-merge (OPTIONAL) : Run the L0 post-merge pipeline instead of the ordinary L0 pre-merge pipeline.

--extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx" (OPTIONAL) : Run the ordinary L0 pre-merge pipeline and specified test stages. Supports wildcard * for pattern matching. Examples: --extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx", --extra-stage "Post-Merge".

--detailed-log (OPTIONAL) : Enable flushing out all logs to the Jenkins console. This will significantly increase the log volume and may slow down the job.

--debug (OPTIONAL) : Experimental feature. Enable access to the CI container for debugging purpose. Note: Specify exactly one stage in the stage-list parameter to access the appropriate container environment. Note: Does NOT update GitHub check status.

--high-priority (OPTIONAL) : Run the pipeline with high priority. This option is restricted to authorized users only and will route the job to a high-priority queue.

kill

kill

Kill all running builds associated with pull request.

skip

skip --comment COMMENT

Skip testing for latest commit on pull request. --comment "Reason for skipping build/test" is required. IMPORTANT NOTE: This is dangerous since lack of user care and validation can cause top of tree to break.

reuse-pipeline

reuse-pipeline

Reuse a previous pipeline to validate current commit. This action will also kill all currently running builds associated with the pull request. IMPORTANT NOTE: This is dangerous since lack of user care and validation can cause top of tree to break.

@kaiyux

kaiyux commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

/bot run --only-multi-gpu-test --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52054 [ run ] triggered by Bot. Commit: 2f4c150 Link to invocation

@kaiyux

kaiyux commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

/bot run --stage-list "DGX_B200-4_GPUs-PyTorch-3"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52086 [ run ] triggered by Bot. Commit: d7d192e Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52054 [ run ] completed with state ABORTED. Commit: 2f4c150

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52086 [ run ] completed with state FAILURE. Commit: d7d192e
/LLM/main/L0_MergeRequest_PR pipeline #41414 (Partly Tested) 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 Jun 5, 2026

Copy link
Copy Markdown
Member Author

/bot run --stage-list "DGX_B200-4_GPUs-PyTorch-3"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52201 [ run ] triggered by Bot. Commit: d7d192e Link to invocation

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

LGTM. No major blocking components. Thanks for addressing previous PR's comments.

Comment thread tensorrt_llm/_torch/models/modeling_step3p7vl.py
Comment thread tensorrt_llm/_torch/models/modeling_step3p7vl.py Outdated
Comment thread tensorrt_llm/_torch/models/modeling_step3p7vl.py Outdated
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52201 [ run ] completed with state SUCCESS. Commit: d7d192e
/LLM/main/L0_MergeRequest_PR pipeline #41521 (Partly Tested) 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 force-pushed the user/kaiyu/step3p7_nvfp4_mtp branch from d7d192e to 810d431 Compare June 5, 2026 07:07
@kaiyux

kaiyux commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

/bot run --stage-list "DGX_B200-4_GPUs-PyTorch-3"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52290 [ run ] triggered by Bot. Commit: 810d431 Link to invocation

@xinhe-nv

xinhe-nv commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai why didn't you review the code as a QA engineer at the first commit?

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@xinhe-nv — A few common reasons why an automatic review might not have fired on the first commit:

  1. PR opened as a draft – CodeRabbit skips draft PRs by default and only reviews once the PR is marked ready for review.
  2. Auto-review paused or disabled – If a previous /bot pause or a CodeRabbit configuration (reviews.auto_review.enabled: false, or drafts: false) was in effect for the repo, no review fires automatically.
  3. PR predates CodeRabbit activation – If the PR was opened before CodeRabbit was installed/enabled on the repository, the open event is never replayed.
  4. Base-branch filter – Some repo configurations restrict automatic reviews to specific target branches.

You can check and adjust these settings in your .coderabbit.yaml or via the CodeRabbit dashboard. If you'd like me to run a full review of the current diff right now, just let me know — or I can trigger one immediately below.

(ᵕ ᴗ ᵕ)∫

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@xinhe-nv

xinhe-nv commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai review the pr as a QA engineer to check the test coverage.

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== modeling_step3p7.py (relevant forward method) ==="
rg -n "spec_input_ids|spec_worker|spec_token" tensorrt_llm/_torch/models/modeling_step3p7.py -C 5

echo ""
echo "=== modeling_step3p7vl.py key exports and new code ==="
rg -n "spec_input_ids|image_token_id|freqs_for_grid|Step3VisionRope2D|Step3VisionAttention|Step3VisionMLP|Step3VisionBlock|Step3VisionTransformer|Step3p7VisionEncoder|Step3p7VisionTower" tensorrt_llm/_torch/models/modeling_step3p7vl.py | head -80

echo ""
echo "=== test_modeling_step3p7.py full content ==="
cat tests/unittest/_torch/modeling/test_modeling_step3p7.py

echo ""
echo "=== test_modeling_step3p7vl.py full content ==="
cat tests/unittest/_torch/modeling/test_modeling_step3p7vl.py

Length of output: 78756


🏁 Script executed:

#!/bin/bash
echo "=== integration test for pytorch ==="
rg -n "Step3_7|step3p7|mtp_nextn|MTPDecodingConfig" tests/integration/defs/accuracy/test_llm_api_pytorch.py -C 3

echo ""
echo "=== integration test for multimodal ==="
rg -n "Step3_7|step3p7|mtp_nextn|MTPDecodingConfig" tests/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py -C 3

echo ""
echo "=== l0_dgx_b200.yml new entries ==="
rg -n "step3|Step3|mtp_nextn" tests/integration/test_lists/test-db/l0_dgx_b200.yml -C 3

echo ""
echo "=== qa llm_function_core.txt ==="
rg -n "step3|Step3|mtp_nextn" tests/integration/test_lists/qa/llm_function_core.txt -C 2

echo ""
echo "=== New methods in modeling_step3p7vl.py ==="
rg -n "def " tensorrt_llm/_torch/models/modeling_step3p7vl.py

echo ""
echo "=== spec_input_ids usage in vl file ==="
rg -n "spec_input_ids" tensorrt_llm/_torch/models/modeling_step3p7vl.py -C 5

echo ""
echo "=== head_dim padding logic ==="
rg -n "pad|zero|128|96" tensorrt_llm/_torch/models/modeling_step3p7vl.py | head -40

echo ""
echo "=== update_spec_config_from_model_config ==="
rg -rn "update_spec_config_from_model_config|mtp_num_hidden_layers|num_nextn_predict_layers" tensorrt_llm/ | head -30

Length of output: 108651



@xinhe-nv Here is a QA-focused coverage review of the PR. The vision-tower porting (SDPA numeric match, weight remapping, head-dim padding) and the end-to-end MTP accuracy paths are well tested. I found four concrete gaps worth tracking:


✅ Good coverage

Area Test
Vision attention FMHA vs SDPA numeric match (padded head_dim + 2D RoPE + q_scaling) test_vision_attention_matches_reference_sdpa
Weight remap: in_projqkv_proj (with padded-channel zeros), c_fc/c_projup_proj/down_proj test_vision_tower_load_weights_remaps_and_routes
Zero-LayerScale identity test_vision_block_zero_layerscale_is_identity
Batched encoding consistency across requests test_vision_tower_batches_across_requests
`[patches… full_image]` flattening contract
MTP spec config defaults to checkpoint layer count test_mtp_spec_config_defaults_to_checkpoint_layer_count
Integration: fp8 + nvfp4, mtp_nextn ∈ {0,3}, text + VLM paths TestStep3_7.test_fp8_block_scales, test_nvfp4 (both files)

⚠️ Coverage gaps

1. spec_input_ids OOV-sentinel remap — no unit test

modeling_step3p7vl.py lines 1357–1369 contain this new logic:

spec_input_ids = input_ids
if input_ids is not None and mm_embeds:
    if self.spec_worker is not None:
        vocab_size = self.llm.model.embed_tokens.num_embeddings
        image_token_id = int(getattr(self.config, "image_token_id", 128001))
        spec_input_ids = torch.where(
            input_ids >= vocab_size,
            input_ids.new_full((), image_token_id),
            input_ids,
        )

This is new, non-trivial logic (OOV boundary: input_ids >= vocab_size) and is the primary fix for spec-token correctness on the VLM path. It has no dedicated unit test and is only exercised if a GPU integration test happens to run with a live spec_worker. A small unit test that sets up a stub VLM and verifies the mapping (OOV → image_token_id, in-vocab → unchanged) would provide a quick regression gate.

2. spec_token_ids truncation for padded_num_tokens — never hit in VLM tests

modeling_step3p7.py lines 1508–1510:

if attn_metadata.padded_num_tokens is not None:
    if spec_token_ids is not None:
        spec_token_ids = spec_token_ids[: attn_metadata.num_tokens]

_make_llm in test_llm_api_pytorch_multimodal.py uses CudaGraphConfig(enable_padding=False), so padded_num_tokens is never set on the VLM path. The truncation is exercised for the text path only (via enable_padding=True tests for other models). Consider adding enable_padding=True as a variant for at least one VLM+MTP multimodal integration test, or a targeted unit test.

3. NVFP4 MTP spec-config resolution — untested at unit level

test_mtp_spec_config_defaults_to_checkpoint_layer_count runs only against STEP3P7_FP8_DIR. Since NVFP4 exports MTP layers under the bare model.layers.* namespace (different from the FP8/BF16 layout), the NVFP4 path through update_spec_config_from_model_config + _prepare_step3p7_mtp_spec_config has no unit-level coverage. A @parameterized.expand over [("fp8", STEP3P7_FP8_DIR), ("nvfp4", STEP3P7_NVFP4_DIR)] in that test would close this gap.

4. L0 gate for MTP+FP8 text path is missing

l0_dgx_b200.yml adds:

- accuracy/test_llm_api_pytorch.py::TestStep3_7::test_nvfp4[tp_size=4-ep_size=4-mtp_nextn=3]  # TIMEOUT 90

But the corresponding test_fp8_block_scales[mtp_nextn=3] entry is absent from L0 (only mtp_nextn=0 is in the QA list, not L0). If NVFP4+MTP gets L0 coverage, the FP8+MTP text path arguably deserves it too for pre-merge confidence.


Minor observation

Step3VisionTransformer.forward() is only tested indirectly through Step3p7VisionEncoder. Given the signature changed from grid_hw: Tuple to attn_metadata + freqs, a single direct call test would make regressions easier to isolate, but this is low priority given the encoder test exercises the same code.

@kaiyux
kaiyux force-pushed the user/kaiyu/step3p7_nvfp4_mtp branch from 7d348d5 to df1ad38 Compare June 9, 2026 05:54
@kaiyux

kaiyux commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52978 [ run ] triggered by Bot. Commit: df1ad38 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52907 [ run ] completed with state ABORTED. Commit: 7d348d5
/LLM/main/L0_MergeRequest_PR pipeline #42153 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

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52978 [ run ] completed with state SUCCESS. Commit: df1ad38
/LLM/main/L0_MergeRequest_PR pipeline #42211 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 Jun 9, 2026

Copy link
Copy Markdown
Member Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53059 [ run ] triggered by Bot. Commit: df1ad38 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53059 [ run ] completed with state SUCCESS. Commit: df1ad38
/LLM/main/L0_MergeRequest_PR pipeline #42272 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 force-pushed the user/kaiyu/step3p7_nvfp4_mtp branch from df1ad38 to 7798287 Compare June 9, 2026 13:35
@kaiyux

kaiyux commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53072 [ run ] triggered by Bot. Commit: 7798287 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53072 [ run ] completed with state SUCCESS. Commit: 7798287
/LLM/main/L0_MergeRequest_PR pipeline #42284 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 added 7 commits June 10, 2026 11:51
update_spec_config_from_model_config previously read the MTP layer count
only from `num_nextn_predict_layers`, which DeepSeek-style configs expose.
Qwen3Next-style configs (including Qwen3.5) instead expose it as
`mtp_num_hidden_layers`, so MTP spec config resolution failed on those
checkpoints. Read whichever field is present and fall back to a single
shared MTP / EAGLE layer when neither exists.

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

[None][feat] Enable MTP for Step3p7 NVFP4 and fix spec token ids on VLM path

The NVFP4 modelopt export ships the 3 plain-path MTP layers (45..47) under
the bare model.layers.* namespace, so it can now run speculative decoding
like the FP8/BF16 checkpoints.

On the multimodal path the main model consumes fused inputs_embeds and
input_ids is None, so the VLM wrapper forwards the pre-fusion token ids via
a new spec_input_ids argument (image tokens remapped into vocab range) so the
MTP/spec worker always receives valid token ids.

Update accuracy tests to parametrize mtp_nextn, refresh the checkpoint unit
test for the new MTP layout, and adjust the L0/QA test lists accordingly.

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

[None][feat] Port Step3p7VL vision tower to TRT-LLM Attention module

Replace the raw-torch SDPA vision attention with TRT-LLM's Attention
module so the vision encoder runs through the backend FMHA dispatch
(context-only, FULL mask, varlen via per-image attn_metadata).

The PerceptionEncoder head_dim (96) is not a trtllm-gen FMHA cubin size,
so q/k/v/o head dims are zero-padded to 128 while 2D RoPE runs on the
real channels; a compensating q_scaling preserves the softmax scale.
Fused HF in_proj_*/out_proj weights are remapped onto qkv_proj/o_proj
during weight loading with the head_dim padding.

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

[None][feat] Port Step3p7VL vision MLP to TRT-LLM MLP module

Dispatch the non-gated vision FFN through the base TRT-LLM MLP module
(up_proj -> activation -> down_proj) instead of a bespoke c_fc/c_proj
nn.Module. HF mlp.c_fc / mlp.c_proj weights are remapped onto up_proj /
down_proj in Step3p7VisionTower._remap_vision_weights (renamed from
_remap_vision_attention_weights). Update unit tests accordingly.

Signed-off-by: Kaiyu Xie <26294424+kaiyux@users.noreply.github.com>
Signed-off-by: Kaiyu Xie <26294424+kaiyux@users.noreply.github.com>
Precompute the vision tower's 2D-RoPE cos/sin tables once per forward and
thread them through every layer instead of re-evaluating cos()/sin() inside
each attention call. Restrict multimodal device copies to the tensors the
vision tower consumes on GPU, and skip the spec_input_ids OOV-sentinel
rewrite when speculative decoding is off.

Update gsm8k/mmmu accuracy references for the NVFP4 MTP path.

Signed-off-by: Kaiyu Xie <26294424+kaiyux@users.noreply.github.com>
Signed-off-by: Kaiyu Xie <26294424+kaiyux@users.noreply.github.com>
Signed-off-by: Kaiyu Xie <26294424+kaiyux@users.noreply.github.com>
Signed-off-by: Kaiyu Xie <26294424+kaiyux@users.noreply.github.com>
@kaiyux
kaiyux force-pushed the user/kaiyu/step3p7_nvfp4_mtp branch from 7798287 to d86dc09 Compare June 10, 2026 03:51
@kaiyux

kaiyux commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53219 [ run ] triggered by Bot. Commit: d86dc09 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53219 [ run ] completed with state SUCCESS. Commit: d86dc09
/LLM/main/L0_MergeRequest_PR pipeline #42414 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 Jun 10, 2026

Copy link
Copy Markdown
Member Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53274 [ run ] triggered by Bot. Commit: d86dc09 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53274 [ run ] completed with state SUCCESS. Commit: d86dc09
/LLM/main/L0_MergeRequest_PR pipeline #42464 completed with status: 'SUCCESS'

CI Report

Link to invocation

@kaiyux
kaiyux merged commit 62c6521 into NVIDIA:main Jun 10, 2026
7 checks passed
@kaiyux
kaiyux deleted the user/kaiyu/step3p7_nvfp4_mtp branch June 10, 2026 11:39
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