Skip to content

[https://nvbugs/6517834][fix] Fix attn_dense LoRA input dim and Triton MoE padded-view output - #17153

Open
trtllm-agent wants to merge 1 commit into
NVIDIA:mainfrom
tensorrt-cicd:repair-bot-bug6517834
Open

[https://nvbugs/6517834][fix] Fix attn_dense LoRA input dim and Triton MoE padded-view output#17153
trtllm-agent wants to merge 1 commit into
NVIDIA:mainfrom
tensorrt-cicd:repair-bot-bug6517834

Conversation

@trtllm-agent

@trtllm-agent trtllm-agent commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Root cause: LoraModule::createLoraModules built the attn_dense/cross_attn_dense modules with hidden as the input dimension, but o_proj consumes the concatenated attention heads, so its true input dim is num_heads * head_dim — identical to hidden for most models but not for GPT-OSS-20B (hidden=2880 vs 64×64=4096), which sized the adapter buffers wrong. Independently, TritonMXFP4FusedMoEMethod returned a non-contiguous slice view when stripping alignment padding, and lora_grouped_gemm takes a bare data pointer and derives the row stride from the hidden size, so every row but the first was read at the wrong offset. The test itself could never pass regardless: its fixtures pip-installed a deleted requirements.txt (setup error) and its golden string encoded the pre-fix buggy output.
  • Fix: Fixed both product bugs at their producers — qOutSize for the dense-projection input dim in loraModule.cpp, and .contiguous() on the de-padded Triton MoE output so it matches the dense output every other MoE backend already emits. On the test side, dropped the four unused fixtures that caused the setup error and refreshed the golden string to the output now produced, cross-validated as byte-identical against HuggingFace+PEFT and the Cutlass MoE backend; the waiver was then removed. Both product fixes were shown load-bearing by ablation, and the golden was chosen over relaxing the 0.8 ROUGE gate whose discriminating power was measured against four injected-defect variants (0.61/0.02/0.34/0.47 — all correctly rejected).
  • Automated fix generated by repair-bot

Test plan

  • Verify fix on the same GPU type as the original failure
  • Check for regressions in related tests

Links

Dev Engineer Review

  • attn_dense and cross_attn_dense now use qOutSize (num_heads * head_dim) as the LoRA input dimension.
  • The change corrects GPT-OSS-20B adapter buffer sizing from hidden to 4096.
  • De-padded Triton MoE outputs are now contiguous before lora_grouped_gemm consumes them.
  • The change prevents incorrect row-stride interpretation for padded hidden sizes.
  • The test waiver for test_gpt_oss_20b_lora_torch was removed.
  • No API declarations changed.
  • The changes are scoped to the reported LoRA defects.

QA Engineer Review

  • Modified test function: test_gpt_oss_20b_lora_torch.
  • The test now removes unused fixtures and uses a refreshed deterministic output.
  • The expected output was cross-validated with HuggingFace, PEFT, and the Cutlass MoE backend.
  • The test is covered by the integration test configuration.
  • The waiver entry was removed from tests/integration/test_lists/waives.txt.
  • Regression testing confirmed that injected defect variants fail the 0.8 ROUGE threshold.
  • Verdict: sufficient.

… LoRA in_dim

The test failed on setup because it requested six fixtures its body never uses;
gpt_example_root pip-installs examples/models/core/gpt/requirements.txt, whose
directory no longer exists. Dropping them exposed two LoRA defects and a stale
reference value. The node ID is unchanged: none of the six are parametrized, and
pytest_generate_tests early-returns for every function but test_unittests_v2, so
the two indirect params remain the only contributors.

TritonFusedMoE was the only MoE backend returning a non-dense gemm2 output: it
de-padded by slicing, yielding a view whose row stride is the N-aligned padded
width. Cutlass passes unpadded_hidden_size into its kernel, and DeepGemm and
Marlin write a fresh tensor, so all three already emit dense rows. Consumers that
take a bare data pointer and derive the row stride from the hidden size -- the
LoRA grouped GEMM among them, whose ABI carries no stride -- therefore read every
row past the first at the wrong offset, silently. Instrumenting the run shows the
padded view reaching the op in 46 of 72 calls, as the next layer's attention q/k/v
hidden_states. Fixed at the producer so all consumers and both LoRA dispatch paths
benefit. The branch only runs when padding was applied (hidden_size % 256 != 0),
so aligned models are untouched.

attn_dense (o_proj) consumes the concatenated attention heads, so its LoRA in_dim
is numHeads * attnHeadSize, not hidden. These coincide for most models but not
GPT-OSS-20B: hidden is 2880 while 64 heads of 64 give 4096, and the adapter's
o_proj.lora_A is correspondingly (8, 4096) on disk. loraUtils only checks <=, so
the undersized dim silently made weightsOut start inside lora_A.

expected_output was recorded against a different base model -- the adapter
declares base_model_name_or_path workspace-gpt-oss-20b/nemo2, not the HF
checkpoint the test loads -- on a build carrying both defects above. It never
reaches EOS, running to the 50-token cap and starting a fresh User: turn, and it
contradicts its own prompt by saying the winner "will be a great opportunity"
rather than will get $100. Replaced with the reference generation, which
TensorRT-LLM, the CUTLASS MoE backend, and HuggingFace with PEFT all emit
token-for-token, terminating at EOS after 43 tokens. Decoding is greedy, so this
is deterministic rather than sampled. A sweep of 12 LoRA scales, 6 qkv/o splits,
and 5 prompt formulations run entirely under HuggingFace plus PEFT caps at 0.58
against the old value, so no implementation could reach the 0.8 gate.

The 0.8 threshold is unchanged and still rejects every regression it was written
for: the padded-stride output scores 0.61, an unapplied adapter 0.02, a wrong LoRA
scale 0.34, and the previous value 0.47. Reverting only the producer fix makes the
test fail again, confirming it is load-bearing.

Waiver removed.

Signed-off-by: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 1, 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: 19b39e5b-7f3d-49f3-9717-0f88d3d91678

📥 Commits

Reviewing files that changed from the base of the PR and between 7e6692a and cf079c9.

📒 Files selected for processing (4)
  • cpp/tensorrt_llm/runtime/loraModule.cpp
  • tensorrt_llm/_torch/modules/fused_moe/fused_moe_triton.py
  • tests/integration/defs/examples/test_gpt.py
  • tests/integration/test_lists/waives.txt
💤 Files with no reviewable changes (1)
  • tests/integration/test_lists/waives.txt

Walkthrough

Changes

LoRA dimension and integration test updates

Layer / File(s) Summary
Attention LoRA dimension update
cpp/tensorrt_llm/runtime/loraModule.cpp
Attention and cross-attention dense LoRA modules now use qOutSize for input dimensions and retain hidden for output dimensions.
GPT-OSS LoRA test alignment
tests/integration/defs/examples/test_gpt.py, tests/integration/test_lists/waives.txt
The test removes unused fixtures, updates the expected response, documents output equivalence, and removes the related waiver.

MXFP4 MoE output contiguity

Layer / File(s) Summary
Contiguous trimmed output
tensorrt_llm/_torch/modules/fused_moe/fused_moe_triton.py
_maybe_remove_padding now returns a contiguous tensor after trimming padded output.

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

Possibly related PRs

Suggested reviewers: bowenfu

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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 identifies both primary fixes and uses the required NVBugs and fix format.
Description check ✅ Passed The description explains the root causes, fixes, affected tests, validation, and linked bug, with sufficient coverage despite different section headings.
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.

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.

2 participants