Skip to content

[None][perf] Improve inference correctness and perf for Gemma4 - #15848

Merged
2ez4bz merged 2 commits into
NVIDIA:mainfrom
2ez4bz:dev-gemma4-opts
Jul 6, 2026
Merged

[None][perf] Improve inference correctness and perf for Gemma4#15848
2ez4bz merged 2 commits into
NVIDIA:mainfrom
2ez4bz:dev-gemma4-opts

Conversation

@2ez4bz

@2ez4bz 2ez4bz commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Added support for improved multimodal Gemma-4 handling, including image, video, and audio inputs.
    • Expanded B200 NVFP4 evaluation coverage for Gemma-4 multimodal runs.
  • Bug Fixes
    • Improved attention and KV cache handling to reduce extra processing and better support paged cache indexing.
    • Refined tokenizer incremental decoding so it can recover from certain prefix-related decode errors.
    • Updated Gemma-4 routing and masking behavior for more consistent model outputs.

Description

  • Why?

Gemma 4 diverged from the Hugging Face reference for multimodal
attention and MoE routing, while chunked prefill repeated avoidable
encoder and mask work. Incremental decoding could also fail on invalid
byte prefixes, and padded KV page tables added unnecessary overhead.

  • What?

This commit:

  • aligns Gemma 4 masks and routing with Hugging Face, streamlines mask
    construction, and reuses multimodal embeddings across prefill chunks.
  • recovers invalid HF decode streams and limit FlashInfer and KV cache
    page processing to each sequence's live block count.
  • tweaks unit tests against the HF reference implementation to tighten
    bounds by an order of magnitude.

Performance comparison

NVFP4, B200

26B

throughput_per_user_vs_total_output_throughput

31B

image

Test Coverage

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.

@2ez4bz
2ez4bz force-pushed the dev-gemma4-opts branch from 7e82889 to 23c002b Compare July 2, 2026 04:56
@2ez4bz 2ez4bz changed the title Dev gemma4 opts [None][perf] Improve inference correctness and perf for Gemma4 Jul 2, 2026
@2ez4bz
2ez4bz force-pushed the dev-gemma4-opts branch from 23c002b to 0b99fd6 Compare July 2, 2026 05:08
@2ez4bz
2ez4bz marked this pull request as ready for review July 2, 2026 05:09
@2ez4bz
2ez4bz requested review from a team as code owners July 2, 2026 05:09
@2ez4bz
2ez4bz force-pushed the dev-gemma4-opts branch from 0b99fd6 to b298ba0 Compare July 2, 2026 05:13
@2ez4bz
2ez4bz removed request for a team July 2, 2026 05:14
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

FlashInfer KV cache metadata planning shifts to host-side block counting with a new num_blocks_per_seq parameter threaded through KVCacheManagerV2/resource_manager. Gemma4 MoE routing, attention masking, and multimodal forward paths are refactored. Tokenizer decode gains invalid-prefix recovery. Tests and accuracy references are added.

Changes

KV Cache Block Index Planning

Layer / File(s) Summary
get_batch_cache_indices num_blocks_per_seq parameter
tensorrt_llm/_torch/pyexecutor/kv_cache_manager_v2.py, tensorrt_llm/_torch/pyexecutor/resource_manager.py, tests/unittest/_torch/executor/test_per_layer_head_dim.py
Adds optional num_blocks_per_seq to truncate per-request KV block indices in both KVCacheManagerV2 and KVCacheManager, validated by new unit tests covering padded entries and truncation.
FlashInfer host-side block planning
tensorrt_llm/_torch/attention_backend/flashinfer.py
prepare() computes kv_lens_host/self.num_blocks on host, passes num_blocks_per_seq into get_batch_cache_indices, and derives paged KV indices/last-page-len from host and GPU tensors.

Gemma4 Routing, Attention Masking, and Multimodal Encoding

Layer / File(s) Summary
MoE routing softmax/top-k order fix
tensorrt_llm/_torch/models/modeling_gemma4.py, tests/unittest/_torch/modeling/test_modeling_gemma4.py
Gemma4MoeRoutingMethod.apply applies softmax before top-k, drops an epsilon term, casts outputs, and gains routing-stabilization hooks, tightened tolerances, and a reference-matching unit test.
Attention mask and sliding-window mask construction
tensorrt_llm/_torch/models/modeling_gemma4.py
Removes global_attention_mask_data, restricts local mask usage to sliding layers, and refactors token-type/context/flashinfer mask construction with in-place ops and zip-based iteration.
Multimodal encoder refactor and PLE input wiring
tensorrt_llm/_torch/models/modeling_gemma4mm.py, tests/unittest/_torch/modeling/test_gemma4_multimodal.py
Forward path truncates multimodal params, filters active tokens, encodes via new helpers, rebuilds mm_token_type_ids and PLE inputs, and updates fuse_input_embeds wiring; tested for chunked prefill reuse and inactive chunks.
Accuracy references and NVFP4 integration test
tests/integration/defs/accuracy/references/mmmu.yaml, tests/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py, tests/integration/test_lists/test-db/l0_b200.yml
Adds a B200 NVFP4/FP8 accuracy baseline and a gated TestGemma4_26B_A4B::test_nvfp4 integration test registered in the B200 test list.

Tokenizer DecodeStream Invalid-Prefix Recovery

Layer / File(s) Summary
DecodeStream error handling and retry
tensorrt_llm/tokenizer/tokenizer.py, tests/unittest/llmapi/test_tokenizer_decode.py
Reworks hf_decode_incrementally to catch DecodeStream exceptions, reset state and retry on invalid-prefix errors, with a new test validating recovery.

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

Sequence Diagram(s)

sequenceDiagram
  participant FlashInferAttentionMetadata
  participant KVCacheManager
  participant KVCacheManagerV2
  FlashInferAttentionMetadata->>KVCacheManager: get_batch_cache_indices(request_ids, num_blocks_per_seq)
  KVCacheManager->>KVCacheManagerV2: get_batch_cache_indices(request_ids, num_blocks_per_seq)
  KVCacheManagerV2-->>KVCacheManager: truncated block indices per request
  KVCacheManager-->>FlashInferAttentionMetadata: paged KV block indices
Loading
sequenceDiagram
  participant Forward
  participant HasActiveMultimodalTokens
  participant ForwardMultimodalEncoder
  participant GetMultimodalEmbeddings
  participant FindInputMmEmbeds
  Forward->>HasActiveMultimodalTokens: filter active multimodal_params
  Forward->>GetMultimodalEmbeddings: encode via ForwardMultimodalEncoder
  GetMultimodalEmbeddings->>ForwardMultimodalEncoder: concat image/video/audio inputs
  ForwardMultimodalEncoder-->>GetMultimodalEmbeddings: mm_embeds
  GetMultimodalEmbeddings-->>Forward: mm_embeds
  Forward->>FindInputMmEmbeds: align embeds with active params
Loading

Possibly related PRs

  • NVIDIA/TensorRT-LLM#14384: Modifies the same fuse_input_embeds call path for mm_token_ids/mm_token_indices/text_token_indices wiring used in this PR's multimodal forward refactor.

Suggested labels: Multimodal

Suggested reviewers: byshiue, QiJune, Wanli-Jiang

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title follows the required format and clearly summarizes the Gemma4 inference correctness and performance focus.
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.
Description check ✅ Passed The description covers the why/what and includes checklist and performance context, but the Test Coverage section is left blank.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
tensorrt_llm/_torch/pyexecutor/resource_manager.py (1)

1323-1355: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Truncation is applied to the packed beam layout, not the raw per-beam block list.

result[i] = result[i][:num_blocks_per_seq[i]] runs after _pack_beam_cache_indices for beam_width > 1. The packed layout is "beam 0's full block list + one divergent final block per other beam that differs from beam 0's", which is not a simple ordered block count — slicing it by a raw block-count value could silently drop the wrong elements (e.g. cut into beam-0's shared prefix while intending to trim trailing padding) if this method is ever called with both beam_width > 1 and num_blocks_per_seq set.

Today only FlashInferAttentionMetadata.prepare() calls this with num_blocks_per_seq, and it always uses the default beam_width=1, so this isn't currently exercised. Still, worth a guard/comment (or an assertion that beam_width == 1 when num_blocks_per_seq is provided) to prevent silent misuse later.

🛡️ Suggested defensive guard
             result[i] = beams[
                 0] if beam_width == 1 else self._pack_beam_cache_indices(beams)
             if num_blocks_per_seq is not None:
+                assert beam_width == 1, (
+                    "num_blocks_per_seq truncation is only well-defined for "
+                    "beam_width == 1 (packed beam layout is not a simple "
+                    "block-ordered list)."
+                )
                 result[i] = result[i][:num_blocks_per_seq[i]]
🤖 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/pyexecutor/resource_manager.py` around lines 1323 - 1355,
The truncation in get_batch_cache_indices is applied after
_pack_beam_cache_indices, which makes num_blocks_per_seq unsafe for beam_width >
1 because the packed layout is not a simple block list. Update
get_batch_cache_indices to guard this path by asserting or rejecting
num_blocks_per_seq unless beam_width == 1, or move truncation to the raw
per-beam data before packing so the behavior stays correct and explicit.
🧹 Nitpick comments (5)
tests/unittest/_torch/modeling/test_modeling_gemma4.py (2)

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

Annotate the new routing-stabilization helper.

The new helper and nested hook currently infer untyped parameters/returns.

Proposed typing cleanup
-    def _stabilize_moe_routing(self, hf_model, trt_model, config):
+    def _stabilize_moe_routing(
+        self,
+        hf_model: torch.nn.Module,
+        trt_model: torch.nn.Module,
+        config: Gemma4TextConfig,
+    ) -> None:
@@
-        def add_expert_offsets(_module, _inputs, output):
+        def add_expert_offsets(
+            _module: torch.nn.Module,
+            _inputs: tuple[torch.Tensor, ...],
+            output: torch.Tensor,
+        ) -> torch.Tensor:
             return output + expert_offsets

As per coding guidelines, “Always annotate functions. Make the return type None if the function does not return anything.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/modeling/test_modeling_gemma4.py` around lines 790 -
817, The new routing-stabilization helper in test_modeling_gemma4.py is missing
explicit type annotations on its parameters and nested hook. Update
_stabilize_moe_routing to annotate hf_model, trt_model, and config, and annotate
the nested add_expert_offsets hook’s arguments and return type; also make the
outer helper’s return type None since it only registers hooks and returns
nothing.

Source: Coding guidelines


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

Add annotations to the new tests and local stub.

Coverage looks sufficient in tests/unittest/_torch/modeling/test_modeling_gemma4.py for this routing/mask layer; this is just to keep new test code typed.

Proposed typing cleanup
-    def test_bidirectional_mask_only_applies_to_sliding_layers(self):
+    def test_bidirectional_mask_only_applies_to_sliding_layers(self) -> None:
@@
-        def passthrough(*, hidden_states, **_kwargs):
+        def passthrough(*, hidden_states: torch.Tensor, **_kwargs: object) -> torch.Tensor:
             return hidden_states
@@
-    def test_gemma4_routing_matches_hf_reference(self):
+    def test_gemma4_routing_matches_hf_reference(self) -> None:

As per coding guidelines, “Always annotate functions.” As per path instructions, review tests/** changes for coverage sufficiency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/modeling/test_modeling_gemma4.py` around lines 2028 -
2080, The new test methods and the local passthrough stub in
test_modeling_gemma4 need explicit type annotations to satisfy the “Always
annotate functions” guideline. Add return and parameter annotations for the test
functions in Gemma4-related test cases, and annotate the nested passthrough
helper so its signature is typed while still matching the layer.forward call
shape. Keep the changes confined to the test helpers and methods around
test_bidirectional_mask_only_applies_to_sliding_layers and
test_gemma4_routing_matches_hf_reference.

Sources: Coding guidelines, Path instructions

tests/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py (1)

400-422: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Mutable dict class attribute flagged by static analysis.

EXTRA_EVALUATOR_KWARGS = {...} is a mutable default at class scope, flagged by Ruff (RUF012). Note: per a retrieved learning, this repo's Ruff select is limited to {D, E, F, I, PLE, W}, which does not include RUF-prefixed rules — so this may not actually be enforced by the lint gate here. Flagging for awareness only.

♻️ Optional fix
-    EXTRA_EVALUATOR_KWARGS = {
-        "chat_template_kwargs": {"enable_thinking": False},
-    }
+    EXTRA_EVALUATOR_KWARGS: ClassVar[dict] = {
+        "chat_template_kwargs": {"enable_thinking": False},
+    }

Based on learnings, "Ruff is configured in pyproject.toml to enable only {D, E, F, I, PLE, W}", so this specific rule category may not be enforced repo-wide.

🤖 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 400 - 422, The class-level EXTRA_EVALUATOR_KWARGS on TestGemma4_26B_A4B is
a mutable dict that Ruff’s RUF012 would flag; make it immutable at class scope
by replacing it with a non-mutable pattern or constructing it per instance in
the test harness path, keeping the same chat_template_kwargs content. Update the
TestGemma4_26B_A4B definition only, and preserve the existing sampling_params
and kv_cache_config behavior.

Sources: Learnings, Linters/SAST tools

tests/unittest/_torch/modeling/test_gemma4_multimodal.py (1)

705-758: 🎯 Functional Correctness | 🔵 Trivial

Good coverage for single-modality chunking; consider adding a mixed-modality ordering test.

test_chunked_prefill_reuses_cached_vision_embeddings and test_chunk_without_multimodal_tokens_is_inactive correctly validate the chunk-slicing math and inactive-chunk short-circuit for a single image-only param.

Coverage is currently insufficient for the scenario where a batch has multiple active multimodal_params with different modality types (e.g. one audio-only param followed by one image-only param). Per the concern raised in modeling_gemma4mm.py's _forward_multimodal_encoder (lines 902-994), such a batch could produce embeddings in a different order than the token sequence expects. Recommend adding a test to tests/unittest/_torch/modeling/test_gemma4_multimodal.py that exercises get_multimodal_embeddings/_forward_multimodal_encoder with two params of different modalities and asserts embedding-to-token alignment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/modeling/test_gemma4_multimodal.py` around lines 705 -
758, Add coverage for mixed-modality batching in the multimodal encoder path,
since the current tests only validate single-image chunking and inactive chunks.
Create a test in test_gemma4_multimodal.py that drives get_multimodal_embeddings
through _forward_multimodal_encoder with two active multimodal_params of
different types (for example audio-only then image-only) and assert the returned
embeddings preserve token-sequence order. Use the existing helpers and symbols
like MultimodalParams, MultimodalRuntimeData, get_multimodal_embeddings, and
find_input_mm_embeds to verify alignment.

Source: Path instructions

tensorrt_llm/_torch/attention_backend/flashinfer.py (1)

911-938: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant re-truncation after get_batch_cache_indices already truncates.

get_batch_cache_indices(..., num_blocks_per_seq=self.num_blocks) now already truncates each per-request block list server-side, so block_ids[:self.num_blocks[i]] here (and the analogous slice in the VSWA branch below at line 967) is redundant — harmless since slicing beyond length is a no-op, but slightly misleading since it implies the returned lists might still be longer than num_blocks[i].

♻️ Optional cleanup
-        paged_kv_indices_list = []
-        for i, block_ids in enumerate(block_ids_per_seq):
-            paged_kv_indices_list.extend(block_ids[:self.num_blocks[i]])
+        paged_kv_indices_list = [
+            idx for block_ids in block_ids_per_seq for idx in block_ids
+        ]
🤖 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/attention_backend/flashinfer.py` around lines 911 - 938,
`get_batch_cache_indices` already truncates each per-request block list, so the
extra slicing in the `paged_kv_indices_list` build inside the cache update path
is redundant and misleading. Remove the `[:self.num_blocks[i]]` truncation in
this loop, and make the same cleanup in the analogous VSWA branch so the
`block_ids_per_seq` handling matches the actual contract of
`get_batch_cache_indices`.
🤖 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_gemma4mm.py`:
- Around line 902-1019: The multimodal embeddings produced by
_forward_multimodal_encoder are currently concatenated by modality type instead
of the original multimodal_params/request order, which can misalign cached
slices later. Update _forward_multimodal_encoder and the downstream cache/slice
flow (including _cache_multimodal_embeddings and any use of
get_multimodal_embeddings/find_input_mm_embeds) so embeddings are emitted or
reassembled in per-request order, preserving each multimodal_param’s row mapping
across mixed image/video/audio batches.

In `@tests/unittest/_torch/executor/test_per_layer_head_dim.py`:
- Around line 22-26: The current coverage only exercises KVCacheManagerV2, so
add a matching V1 test in test_resource_manager.py that verifies
num_blocks_per_seq after beam packing with beam_width > 1 and truncation
behavior. Use the existing KVCacheManager test setup/helpers in that file to
build the case, then assert the expected num_blocks_per_seq values after
packing/truncation so the V1 path is covered alongside the new V2 test.

---

Outside diff comments:
In `@tensorrt_llm/_torch/pyexecutor/resource_manager.py`:
- Around line 1323-1355: The truncation in get_batch_cache_indices is applied
after _pack_beam_cache_indices, which makes num_blocks_per_seq unsafe for
beam_width > 1 because the packed layout is not a simple block list. Update
get_batch_cache_indices to guard this path by asserting or rejecting
num_blocks_per_seq unless beam_width == 1, or move truncation to the raw
per-beam data before packing so the behavior stays correct and explicit.

---

Nitpick comments:
In `@tensorrt_llm/_torch/attention_backend/flashinfer.py`:
- Around line 911-938: `get_batch_cache_indices` already truncates each
per-request block list, so the extra slicing in the `paged_kv_indices_list`
build inside the cache update path is redundant and misleading. Remove the
`[:self.num_blocks[i]]` truncation in this loop, and make the same cleanup in
the analogous VSWA branch so the `block_ids_per_seq` handling matches the actual
contract of `get_batch_cache_indices`.

In `@tests/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py`:
- Around line 400-422: The class-level EXTRA_EVALUATOR_KWARGS on
TestGemma4_26B_A4B is a mutable dict that Ruff’s RUF012 would flag; make it
immutable at class scope by replacing it with a non-mutable pattern or
constructing it per instance in the test harness path, keeping the same
chat_template_kwargs content. Update the TestGemma4_26B_A4B definition only, and
preserve the existing sampling_params and kv_cache_config behavior.

In `@tests/unittest/_torch/modeling/test_gemma4_multimodal.py`:
- Around line 705-758: Add coverage for mixed-modality batching in the
multimodal encoder path, since the current tests only validate single-image
chunking and inactive chunks. Create a test in test_gemma4_multimodal.py that
drives get_multimodal_embeddings through _forward_multimodal_encoder with two
active multimodal_params of different types (for example audio-only then
image-only) and assert the returned embeddings preserve token-sequence order.
Use the existing helpers and symbols like MultimodalParams,
MultimodalRuntimeData, get_multimodal_embeddings, and find_input_mm_embeds to
verify alignment.

In `@tests/unittest/_torch/modeling/test_modeling_gemma4.py`:
- Around line 790-817: The new routing-stabilization helper in
test_modeling_gemma4.py is missing explicit type annotations on its parameters
and nested hook. Update _stabilize_moe_routing to annotate hf_model, trt_model,
and config, and annotate the nested add_expert_offsets hook’s arguments and
return type; also make the outer helper’s return type None since it only
registers hooks and returns nothing.
- Around line 2028-2080: The new test methods and the local passthrough stub in
test_modeling_gemma4 need explicit type annotations to satisfy the “Always
annotate functions” guideline. Add return and parameter annotations for the test
functions in Gemma4-related test cases, and annotate the nested passthrough
helper so its signature is typed while still matching the layer.forward call
shape. Keep the changes confined to the test helpers and methods around
test_bidirectional_mask_only_applies_to_sliding_layers and
test_gemma4_routing_matches_hf_reference.
🪄 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: 3aa06af3-1969-43fa-ad0a-2a55ec2633eb

📥 Commits

Reviewing files that changed from the base of the PR and between c81fa33 and 0b99fd6.

📒 Files selected for processing (13)
  • tensorrt_llm/_torch/attention_backend/flashinfer.py
  • tensorrt_llm/_torch/models/modeling_gemma4.py
  • tensorrt_llm/_torch/models/modeling_gemma4mm.py
  • tensorrt_llm/_torch/pyexecutor/kv_cache_manager_v2.py
  • tensorrt_llm/_torch/pyexecutor/resource_manager.py
  • tensorrt_llm/tokenizer/tokenizer.py
  • tests/integration/defs/accuracy/references/mmmu.yaml
  • tests/integration/defs/accuracy/test_llm_api_pytorch_multimodal.py
  • tests/integration/test_lists/test-db/l0_b200.yml
  • tests/unittest/_torch/executor/test_per_layer_head_dim.py
  • tests/unittest/_torch/modeling/test_gemma4_multimodal.py
  • tests/unittest/_torch/modeling/test_modeling_gemma4.py
  • tests/unittest/llmapi/test_tokenizer_decode.py

Comment thread tensorrt_llm/_torch/models/modeling_gemma4mm.py
Comment thread tests/unittest/_torch/executor/test_per_layer_head_dim.py
@nvpohanh
nvpohanh requested a review from yizhang-nv July 2, 2026 05:51
@nvpohanh

nvpohanh commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

[by Codex] @yizhang-nv Friendly reminder: could you please review this PR? Thanks!

Comment thread tensorrt_llm/_torch/models/modeling_gemma4.py Outdated
* Why?

Gemma 4 diverged from the Hugging Face reference for multimodal
attention and MoE routing, while chunked prefill repeated avoidable
encoder and mask work. Incremental decoding could also fail on invalid
byte prefixes, and padded KV page tables added unnecessary overhead.

* What?

This commit:

- aligns Gemma 4 masks and routing with Hugging Face, streamlines mask
  construction, and reuses multimodal embeddings across prefill chunks.
- recovers invalid HF decode streams and limit FlashInfer and KV cache
  page processing to each sequence's live block count.
- tweaks unit tests against the HF reference implementation to tighten
  bounds by an order of magnitude.

Signed-off-by: William Zhang <133824995+2ez4bz@users.noreply.github.com>
@2ez4bz
2ez4bz force-pushed the dev-gemma4-opts branch from b298ba0 to 291999e Compare July 2, 2026 21:53
@2ez4bz

2ez4bz commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run

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

@Hudayday

Hudayday commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57304 [ run ] triggered by Bot. Commit: 291999e Link to invocation

@yizhang-nv yizhang-nv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM on KVCM part

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57304 [ run ] completed with state FAILURE. Commit: 291999e
/LLM/main/L0_MergeRequest_PR pipeline #46063 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

@Hudayday

Hudayday commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

Signed-off-by: William Zhang <133824995+2ez4bz@users.noreply.github.com>
@2ez4bz

2ez4bz commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57637 [ run ] triggered by Bot. Commit: b57cb63 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

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

Copy link
Copy Markdown
Collaborator

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

CI Report

Link to invocation

Comment thread tensorrt_llm/_torch/models/modeling_gemma4mm.py
Comment thread tensorrt_llm/_torch/models/modeling_gemma4.py
@2ez4bz
2ez4bz merged commit c5bdcaa into NVIDIA:main Jul 6, 2026
7 checks passed
kaiyux added a commit to kaiyux/TensorRT-LLM that referenced this pull request Jul 7, 2026
…nfer plans, CUDA graph padding prealloc

Combine three groups of Gemma4 single-GPU serving optimizations on top of
the page-table work from NVIDIA#15848:

- FlashInfer host-path: build all page-table metadata (kv lens, block
  counts, indptrs, last-page lens) with numpy on the host and stage
  through pinned tensors, add a flat KV cache indices path
  (get_batch_cache_indices_flat) that never materializes padded
  per-request lists, retain host copies of decode indptr and pool
  indices, and pre-build persistent trtllm-gen decode block tables on
  the host so decode plans need no GPU round trips; vectorize the VSWA
  decode block-table refresh.

- Fused Gemma4 modules: model-side fused QKV prep (norm + RoPE + FP8
  quant), fused GeLU-mul + NVFP4 quant, fused RMSNorm + NVFP4 quant, and
  a fused residual-add tail, wired into modeling_gemma4 with per-fusion
  opt-out env vars (TRTLLM_GEMMA4_DISABLE_*); FlashInfer emits BF16
  output when Q arrives pre-quantized to FP8.

- CUDA graph padding: pre-allocate the padding dummy request at warmup
  while the KV cache still has free blocks, so padded batches cannot
  permanently fall back to eager mode once the cache saturates.

Benchmark (1xB200, Gemma-4-31B-IT-NVFP4, ISL 1024 / OSL 128, 1024
prompts, concurrency 1024): output throughput 1324 -> 1733 tok/s
(+30.9%), median TTFT -23.6%, median TPOT -24.4%, median E2EL -23.9%.

Signed-off-by: Kaiyu Xie <26294424+kaiyux@users.noreply.github.com>
BrianLi23 pushed a commit to BrianLi23/TensorRT-LLM that referenced this pull request Jul 9, 2026
…A#15848)

* Why?

Gemma 4 diverged from the Hugging Face reference for multimodal
attention and MoE routing, while chunked prefill repeated avoidable
encoder and mask work. Incremental decoding could also fail on invalid
byte prefixes, and padded KV page tables added unnecessary overhead.

* What?

This commit:

- aligns Gemma 4 masks and routing with Hugging Face, streamlines mask
  construction, and reuses multimodal embeddings across prefill chunks.
- recovers invalid HF decode streams and limit FlashInfer and KV cache
  page processing to each sequence's live block count.
- tweaks unit tests against the HF reference implementation to tighten
  bounds by an order of magnitude.

Signed-off-by: William Zhang <133824995+2ez4bz@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.

9 participants