Skip to content

[None][refactor] Add derived properties for the thop.attention call site - #14279

Merged
yuxianq merged 12 commits into
NVIDIA:mainfrom
yuxianq:derived-attn-props
May 28, 2026
Merged

[None][refactor] Add derived properties for the thop.attention call site#14279
yuxianq merged 12 commits into
NVIDIA:mainfrom
yuxianq:derived-attn-props

Conversation

@yuxianq

@yuxianq yuxianq commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Enhanced attention backend with improved sparse attention support and optimized metadata handling for better performance.
    • Added configuration properties for RoPE embeddings and skip-softmax thresholds.
  • Tests

    • Added comprehensive sync validation tests ensuring attention kernel bindings remain consistent with the Python call-site implementation.

Review Change Stack

Description

Convert the inline thop.attention(...) call in TrtllmAttention._run from a ~75-arg positional call into an explicit-kwarg call where every kwarg is sourced as source.attribute from one of the rich objects (self / metadata / forward_args / sparse_args). Section comments at the call site mirror the rich-object boundaries.

This is a foundation PR — additive and behavior-preserving — extracted from a larger ongoing refactor of the attention dispatch path. It does not extract a _call_thop_attention wrapper method (that comes in a follow-up); the explicit-kwarg call remains inline in _run with section-comment organization.

Three pieces

1. interface.py — properties + dataclass + constants

  • AttentionForwardArgs:
    • mask_type @property — replaces the legacy TrtllmAttention._get_mask_type.
    • effective_out_scale @property — replaces the inline out_scale_sf if output_sf is not None else out_scale ternary.
    • mrope_rotary_cos_sin / mrope_position_deltas @property — pull from the mrope_config dict.
    • Drop the dead enable_attn_nvfp4_output field (no readers).
  • New AttentionSparseArgs dataclass for the sparse-attention args bag (sparse_kv_indices, sparse_kv_offsets, sparse_attn_indices, sparse_attn_offsets, sparse_attn_indices_block_size).
  • Module constants _THOP_EXCLUDED_FIELDS and _THOP_LITERAL_NONE for the sync test.

2. trtllm.py — metadata field, ~13 @Property accessors, call-site rewrite

  • TrtllmAttentionMetadata: add use_paged_context_fmha field (init from runtime_features in __post_init__; forward() applies per-call SM/sparse/MLA overrides). Add num_sparse_topk: int = 0 baseline. Add 6 derived metadata @property accessors (effective_workspace, helix_tensor_params, spec_decoding_bool_params, spec_decoding_position_offsets_for_cpp, effective_flash_mla_tile_scheduler_metadata, effective_flash_mla_num_splits, max_context_length).
  • TrtllmAttention: add 5 rotary_embedding_* @property accessors backed by self.rope_params. Add 2 skip_softmax_threshold_scale_factor_{prefill,decode} @property accessors backed by self.sparse_attention_config. Add a spec_decoding_tensor_params(metadata) method (not @property because the SM check lives on the backend).
  • Remove the dead _get_mask_type helper; remove output/output_sf from _run's signature (now sourced from forward_args.output after forward() writes it back); remove all inline pre-computations absorbed by the new properties.
  • Rewrite _run signature to take sparse_args: AttentionSparseArgs instead of the 7 loose sparse params.
  • Rewrite the inline thop.attention(...) call as explicit kwargs with 7 section comments (Inputs / Per-step batch state / AttentionForwardArgs / TrtllmAttention / Sparse-specific / Per-call locals / Literals).

3. test_attention_op_sync.py — AST-only sync test (new, GPU-free)

Parses the AST of TrtllmAttention._run, locates the thop.attention(...) call, and enforces five invariants:

  1. Every C++ binding kwarg appears at the call site (and nothing extra). Parses nb::arg(...) from cpp/tensorrt_llm/nanobind/thop/bindings.cpp because inspect.signature(thop.attention) returns (*args, **kwargs) for nanobind-bound functions.
  2. Every source.attr kwarg resolves to attr on exactly one of the four source classes.
  3. kwarg=None is only legal if the kwarg is in _THOP_LITERAL_NONE.
  4. Every AttentionForwardArgs field is consumed (directly, via a @property, or in _THOP_EXCLUDED_FIELDS).
  5. Every AttentionSparseArgs field is consumed.

The test is the load-bearing piece — it makes the derived-properties refactor self-enforcing: if a property is added but never consumed, the test fails; if a kwarg drifts vs the C++ binding, the test fails; if a dataclass field is silently dropped, the test fails.

Test Coverage

Validated on B200 (umbriel-b200-049, incremental build):

Suite Result
tests/unittest/_torch/attention_backend/test_attention_op_sync.py 6 passed (the new sync test)
tests/unittest/api_stability 35 passed (committed API surface unchanged)
tests/unittest/_torch/attention/test_attention.py 17 passed (thop.attention path)
tests/unittest/_torch/attention/test_attention_mla.py 80 passed (DeepSeek-V3 geometry, v1/v2 KV cache, bf16/fp8, multiple context-length sets — exercises all four rich-object source classes through the new properties)

Total: 138 passed, 0 failed.

Rebase notes

  • If drop-sink-token-length lands first: drop the sink_token_length=0 kwarg from the call site and the "sink_token_length" entry from expected_locals in the sync test.
  • If clean-attn-fwd-args lands first: rebase is mechanical; any AttentionForwardArgs field renames cascade to the @property bodies and _THOP_EXCLUDED_FIELDS.

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.

@yuxianq
yuxianq requested a review from a team as a code owner May 19, 2026 00:27
@yuxianq
yuxianq requested a review from PerkzZheng May 19, 2026 00:27
@yuxianq

yuxianq commented May 19, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR refactors the TensorRT-LLM attention backend to use structured parameters and derive kernel-ready values from metadata. It introduces AttentionSparseArgs and new properties on AttentionForwardArgs, extends TrtllmAttentionMetadata with computed properties, refactors TrtllmAttention._run() to accept structured objects instead of large positional argument lists, and adds comprehensive AST-based sync tests to validate Python/C++ binding consistency.

Changes

Attention Backend Refactor: Structured Parameters and Sync Testing

Layer / File(s) Summary
Interface Contracts: AttentionForwardArgs Properties and AttentionSparseArgs
tensorrt_llm/_torch/attention_backend/interface.py
Imports AttentionMaskType; adds four new properties to AttentionForwardArgs (mask_type, effective_out_scale, mrope_rotary_cos_sin, mrope_position_deltas); introduces AttentionSparseArgs dataclass; defines private allowlist constants (_THOP_EXCLUDED_FIELDS, _THOP_LITERAL_NONE) for synchronization validation.
TrtllmAttentionMetadata Fields and Derived Properties
tensorrt_llm/_torch/attention_backend/trtllm.py
Extends TrtllmAttentionMetadata with internal state (use_paged_context_fmha, num_sparse_topk) and multiple computed properties that expose kernel-ready values: workspace selection, helix tensor params, spec-decoding flags/tensors, FlashMLA gating, and max_context_length; initializes use_paged_context_fmha from runtime_features in post-init.
TrtllmAttention RoPE and Skip-Softmax Configuration Properties
tensorrt_llm/_torch/attention_backend/trtllm.py
Adds public properties for RoPE embedding configuration and skip-softmax thresholds; introduces spec_decoding_tensor_params(...) helper for SM-version-dependent tensor construction; updates _run(...) signature to accept forward_args and sparse_args structured objects.
_run() Execution Path: Spec-Decoding Locals, TRT-LLM-Gen, and thop.attention Dispatch
tensorrt_llm/_torch/attention_backend/trtllm.py
Refactors internal execution to compute per-call locals and dispatch both the TRT-LLM-Gen path (using forward_args tensors, mask_type, output_sf, and metadata.effective_workspace) and the C++ thop.attention binding with explicit keyword arguments sourced from metadata properties, forward_args fields, and the consolidated sparse_args object.
forward() Sparse Args Construction and Return Path
tensorrt_llm/_torch/attention_backend/trtllm.py
Updates forward(...) to override metadata.use_paged_context_fmha based on SM90 and sparse constraints, allocate forward_args output/scale when missing, build a single AttentionSparseArgs per call, invoke refactored _run(...), and simplify return to extract output/scale from forward_args.
Sync Test Suite: Python/C++ Binding Validation
tests/unittest/_torch/attention_backend/test_attention_op_sync.py
Introduces comprehensive static sync tests that parse _run AST, locate the thop.attention call, classify kwargs by source, and validate: call-site kwargs match C++ binding names, source.attribute kwargs resolve uniquely, literal None kwargs are allowlisted, AttentionForwardArgs fields are consumed or excluded, AttentionSparseArgs fields are sourced, and unexpected kwargs are rejected.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • PerkzZheng
  • laikhtewari
  • kaiyux
  • zhenhuaw-me
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.05% 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 describes the main refactoring work: adding derived properties to support the thop.attention call site.
Description check ✅ Passed The description is comprehensive and well-structured, covering the three main pieces of the change (interface.py, trtllm.py, test_attention_op_sync.py) with clear subsections and test validation results.
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.

✏️ 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.

🧹 Nitpick comments (2)
tests/unittest/_torch/attention_backend/test_attention_op_sync.py (2)

305-305: 💤 Low value

Minor: File should end with a newline.

Most style guides and editors expect files to end with a trailing newline character.

🤖 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/attention_backend/test_attention_op_sync.py` at line
305, Add a trailing newline character at the end of the file
tests/unittest/_torch/attention_backend/test_attention_op_sync.py so the file
ends with a newline (ensure the final byte is '\n'); open the file, place the
cursor at EOF and save to include the newline, then run linters/tests to confirm
the style warning is resolved.

282-298: 💤 Low value

Maintenance note: expected_locals requires manual updates when _run changes.

This hardcoded list couples the test to _run's internal structure. The comment on lines 295-297 already notes that sink_token_length will be removed with a future PR. Consider adding a brief inline comment at the top of this set documenting that updates are expected when _run locals change, to help future maintainers.

This is acceptable as-is since the sync test will fail fast if the lists diverge.

🤖 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/attention_backend/test_attention_op_sync.py` around
lines 282 - 298, The hardcoded set expected_locals in the
test_attention_op_sync.py couples the test to the internal locals of the _run
function; update the test by adding a brief inline comment immediately above the
expected_locals definition (the set named expected_locals) that notes this list
must be manually updated whenever _run's locals change (and mention the future
removal of sink_token_length), so future maintainers understand the coupling and
know to keep the set in sync with _run.
🤖 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.

Nitpick comments:
In `@tests/unittest/_torch/attention_backend/test_attention_op_sync.py`:
- Line 305: Add a trailing newline character at the end of the file
tests/unittest/_torch/attention_backend/test_attention_op_sync.py so the file
ends with a newline (ensure the final byte is '\n'); open the file, place the
cursor at EOF and save to include the newline, then run linters/tests to confirm
the style warning is resolved.
- Around line 282-298: The hardcoded set expected_locals in the
test_attention_op_sync.py couples the test to the internal locals of the _run
function; update the test by adding a brief inline comment immediately above the
expected_locals definition (the set named expected_locals) that notes this list
must be manually updated whenever _run's locals change (and mention the future
removal of sink_token_length), so future maintainers understand the coupling and
know to keep the set in sync with _run.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3f9b377c-6744-4992-ba75-f13f66bce952

📥 Commits

Reviewing files that changed from the base of the PR and between 55b6973 and aeb3d25.

📒 Files selected for processing (3)
  • tensorrt_llm/_torch/attention_backend/interface.py
  • tensorrt_llm/_torch/attention_backend/trtllm.py
  • tests/unittest/_torch/attention_backend/test_attention_op_sync.py

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49007 [ run ] triggered by Bot. Commit: aeb3d25 Link to invocation

yuxianq added a commit to yuxianq/TensorRT-LLM that referenced this pull request May 19, 2026
Address review feedback on the thop.attention derived-properties refactor:

- Move ``_THOP_EXCLUDED_FIELDS`` / ``_THOP_LITERAL_NONE`` to ``trtllm.py``;
  they describe the TRTLLM backend's call site, not the shared interface.

- Drop ``effective_flash_mla_tile_scheduler_metadata`` and
  ``effective_flash_mla_num_splits``: the raw fields are already gated by
  ``enable_flash_mla`` and default to ``None``, so the "view" properties
  re-stated a guarantee the producer already enforces.

- Move ``spec_decoding_tensor_params`` from a ``TrtllmAttention`` method to
  a ``TrtllmAttentionMetadata`` @Property; everything the list reads lives
  on metadata, including ``is_sm_version_trtllm_gen_kernel``.

- Extend the static sync test to walk @Property bodies on
  ``AttentionForwardArgs`` so that a field is recognized as consumed iff
  it's read either directly at the call site or transitively via a
  @Property that is itself accessed there. This lets the excluded-field
  set shrink to the three fields the TRTLLM backend genuinely ignores
  (``topk_indices`` / ``is_generation`` / ``attention_mask_data``).

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
@yuxianq

yuxianq commented May 19, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --extra-stage "DGX_B200-4_GPUs-AutoDeploy-1, DGX_H100-4_GPUs-AutoDeploy-1"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49083 [ run ] triggered by Bot. Commit: cc5269e Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49007 [ run ] completed with state ABORTED. Commit: aeb3d25

Link to invocation

@yuxianq
yuxianq requested a review from yihwang-nv May 19, 2026 07:54
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

yuxianq added a commit to yuxianq/TensorRT-LLM that referenced this pull request May 19, 2026
Address the eight-item review feedback on PR NVIDIA#14279. After this change,
every kwarg at the ``thop.attention`` call site sources from
``self`` / ``metadata`` / ``forward_args`` (incl. ``forward_args.sparse``)
or is an allowlisted literal — no per-call locals remain.

Schema changes (``AttentionForwardArgs``):
- Drop ``out_scale_sf`` and ``effective_out_scale`` @Property; the caller
  in ``modules/attention.py`` now picks ``input_scale`` vs
  ``inv_input_scale`` based on ``output_sf`` and assigns ``out_scale``
  directly. (Item 3)
- Rename ``kv_scales_sf`` → ``kv_scale_quant_orig`` and
  ``kv_scales_sf_inv`` → ``kv_scale_orig_quant`` to mirror the C++ kwarg
  names. (Item 8)
- Add ``is_fused_qkv: bool = False`` and ``update_kv_cache: bool = True``;
  ``TrtllmAttention.forward`` populates them from ``k`` and
  ``metadata.is_cross``. (Item 7)
- Add ``sparse: AttentionSparseArgs = field(default_factory=...)`` so the
  sparse sub-bag lives inside ``forward_args`` instead of being threaded
  separately. (Item 1)

``TrtllmAttention`` cleanups:
- Remove ``self.kv_scale_orig_quant`` / ``self.kv_scale_quant_orig`` /
  ``self.kv_cache_scaling_factor`` — they were stuck at ``torch.ones(1)``,
  a no-op. The four MLA preprocessing ops now pass ``None`` for the
  scales, which the C++ side accepts when KV cache quant is inactive.
  (Item 8)
- Add ``self.local_layer_idx`` field, written at the top of ``_run``;
  rename the C++ ``thop.attention`` kwarg ``layer_idx`` →
  ``local_layer_idx`` to disambiguate from the module-level
  ``self.layer_idx``. (Item 6)
- Mutate ``forward_args.attention_window_size`` in-place when it's
  ``None`` so the call site reads it as ``forward_args.<attr>``. (Item 5)
- Drop ``sparse_args`` from the ``_run`` signature; access via
  ``forward_args.sparse.<field>`` instead. (Item 1)
- Regroup the call site: ``spec_decoding_tensor_params`` joins the metadata
  block; ``sparse_mla_topk_lens`` / ``compressed_kv_cache_pool_ptr``
  retain literal ``None`` with a comment marking them as DeepSeek V4
  placeholders. (Items 2, 4)

Static sync test:
- Extend ``_classify_kwargs`` to walk arbitrary-depth attribute chains
  (``forward_args.sparse.X``) and resolve intermediate steps via
  ``__dataclass_fields__`` types.
- Drop ``sparse_args`` from the source-class set; sparse fields are now
  validated through the ``forward_args.sparse`` chain.
- Trim ``expected_locals`` to just ``q``/``k``/``v`` and the literal
  ``sink_token_length=0`` — all other per-call locals are gone.

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
@yuxianq

yuxianq commented May 19, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --extra-stage "DGX_B200-4_GPUs-AutoDeploy-1, DGX_H100-4_GPUs-AutoDeploy-1"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49185 [ run ] triggered by Bot. Commit: 8320c43 Link to invocation

yuxianq added a commit to yuxianq/TensorRT-LLM that referenced this pull request May 19, 2026
…ssert

Follow-up to PR NVIDIA#14279 review:

- Strip comments that explained where a value used to live or where it
  is set/read elsewhere; the surrounding code is self-evident now.
  Comments retained where they call out a current invariant or
  non-obvious branch (e.g. the SM90 paged-context override, the
  ``SkipSoftmax`` carve-out).

- Move the ``is_fused_qkv`` shape assert into
  ``TrtllmAttention.forward`` next to where ``forward_args.is_fused_qkv``
  is computed from ``k`` / ``metadata.is_cross`` — validating the caller
  belongs at the point where the value is derived, not in ``_run`` where
  it's already trusted.

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
@yuxianq

yuxianq commented May 19, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --extra-stage "DGX_B200-4_GPUs-AutoDeploy-1, DGX_H100-4_GPUs-AutoDeploy-1"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49194 [ run ] triggered by Bot. Commit: 5b49fcf Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49185 [ run ] completed with state ABORTED. Commit: 8320c43

Link to invocation

@yuxianq

yuxianq commented May 19, 2026

Copy link
Copy Markdown
Collaborator Author

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

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49221 [ run ] triggered by Bot. Commit: f1b159b Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49194 [ run ] completed with state ABORTED. Commit: 5b49fcf

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49221 [ run ] completed with state ABORTED. Commit: f1b159b

Link to invocation

@yuxianq
yuxianq force-pushed the derived-attn-props branch from f1b159b to 5c0153a Compare May 21, 2026 17:11
yuxianq added a commit to yuxianq/TensorRT-LLM that referenced this pull request May 21, 2026
Address review feedback on the thop.attention derived-properties refactor:

- Move ``_THOP_EXCLUDED_FIELDS`` / ``_THOP_LITERAL_NONE`` to ``trtllm.py``;
  they describe the TRTLLM backend's call site, not the shared interface.

- Drop ``effective_flash_mla_tile_scheduler_metadata`` and
  ``effective_flash_mla_num_splits``: the raw fields are already gated by
  ``enable_flash_mla`` and default to ``None``, so the "view" properties
  re-stated a guarantee the producer already enforces.

- Move ``spec_decoding_tensor_params`` from a ``TrtllmAttention`` method to
  a ``TrtllmAttentionMetadata`` @Property; everything the list reads lives
  on metadata, including ``is_sm_version_trtllm_gen_kernel``.

- Extend the static sync test to walk @Property bodies on
  ``AttentionForwardArgs`` so that a field is recognized as consumed iff
  it's read either directly at the call site or transitively via a
  @Property that is itself accessed there. This lets the excluded-field
  set shrink to the three fields the TRTLLM backend genuinely ignores
  (``topk_indices`` / ``is_generation`` / ``attention_mask_data``).

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
yuxianq added a commit to yuxianq/TensorRT-LLM that referenced this pull request May 21, 2026
Address the eight-item review feedback on PR NVIDIA#14279. After this change,
every kwarg at the ``thop.attention`` call site sources from
``self`` / ``metadata`` / ``forward_args`` (incl. ``forward_args.sparse``)
or is an allowlisted literal — no per-call locals remain.

Schema changes (``AttentionForwardArgs``):
- Drop ``out_scale_sf`` and ``effective_out_scale`` @Property; the caller
  in ``modules/attention.py`` now picks ``input_scale`` vs
  ``inv_input_scale`` based on ``output_sf`` and assigns ``out_scale``
  directly. (Item 3)
- Rename ``kv_scales_sf`` → ``kv_scale_quant_orig`` and
  ``kv_scales_sf_inv`` → ``kv_scale_orig_quant`` to mirror the C++ kwarg
  names. (Item 8)
- Add ``is_fused_qkv: bool = False`` and ``update_kv_cache: bool = True``;
  ``TrtllmAttention.forward`` populates them from ``k`` and
  ``metadata.is_cross``. (Item 7)
- Add ``sparse: AttentionSparseArgs = field(default_factory=...)`` so the
  sparse sub-bag lives inside ``forward_args`` instead of being threaded
  separately. (Item 1)

``TrtllmAttention`` cleanups:
- Remove ``self.kv_scale_orig_quant`` / ``self.kv_scale_quant_orig`` /
  ``self.kv_cache_scaling_factor`` — they were stuck at ``torch.ones(1)``,
  a no-op. The four MLA preprocessing ops now pass ``None`` for the
  scales, which the C++ side accepts when KV cache quant is inactive.
  (Item 8)
- Add ``self.local_layer_idx`` field, written at the top of ``_run``;
  rename the C++ ``thop.attention`` kwarg ``layer_idx`` →
  ``local_layer_idx`` to disambiguate from the module-level
  ``self.layer_idx``. (Item 6)
- Mutate ``forward_args.attention_window_size`` in-place when it's
  ``None`` so the call site reads it as ``forward_args.<attr>``. (Item 5)
- Drop ``sparse_args`` from the ``_run`` signature; access via
  ``forward_args.sparse.<field>`` instead. (Item 1)
- Regroup the call site: ``spec_decoding_tensor_params`` joins the metadata
  block; ``sparse_mla_topk_lens`` / ``compressed_kv_cache_pool_ptr``
  retain literal ``None`` with a comment marking them as DeepSeek V4
  placeholders. (Items 2, 4)

Static sync test:
- Extend ``_classify_kwargs`` to walk arbitrary-depth attribute chains
  (``forward_args.sparse.X``) and resolve intermediate steps via
  ``__dataclass_fields__`` types.
- Drop ``sparse_args`` from the source-class set; sparse fields are now
  validated through the ``forward_args.sparse`` chain.
- Trim ``expected_locals`` to just ``q``/``k``/``v`` and the literal
  ``sink_token_length=0`` — all other per-call locals are gone.

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
yuxianq added a commit to yuxianq/TensorRT-LLM that referenced this pull request May 21, 2026
…ssert

Follow-up to PR NVIDIA#14279 review:

- Strip comments that explained where a value used to live or where it
  is set/read elsewhere; the surrounding code is self-evident now.
  Comments retained where they call out a current invariant or
  non-obvious branch (e.g. the SM90 paged-context override, the
  ``SkipSoftmax`` carve-out).

- Move the ``is_fused_qkv`` shape assert into
  ``TrtllmAttention.forward`` next to where ``forward_args.is_fused_qkv``
  is computed from ``k`` / ``metadata.is_cross`` — validating the caller
  belongs at the point where the value is derived, not in ``_run`` where
  it's already trusted.

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50427 [ run ] triggered by Bot. Commit: ecf3fa5 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50353 [ run ] completed with state ABORTED. Commit: 5040cc7

Link to invocation

@yuxianq

yuxianq commented May 27, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50453 [ run ] triggered by Bot. Commit: 2aea9fc Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50427 [ run ] completed with state ABORTED. Commit: ecf3fa5

Link to invocation

yuxianq added 3 commits May 27, 2026 06:44
After commit 574c518 renamed AttentionForwardArgs.kv_scales_sf and
kv_scales_sf_inv to kv_scale_quant_orig and kv_scale_orig_quant, two
references in FlashInferTrtllmGenAttention._get_kv_scale_params were
left pointing at the old (now-nonexistent) field names. Because
AttentionForwardArgs uses slots=True, hitting these references at
runtime raises AttributeError. The path is gated by
TRTLLM_ENABLE_TRTLLM_GEN_ATTENTION=1, so default-config tests do not
exercise it; the failure surfaces only when the trtllm-gen kernel is
enabled (e.g. test_attention_mla with the env override).

Static-only fix: pure rename to the current field names. No GPU
validation possible without rebuilding the .so on a Blackwell node,
but the change cannot regress anything else — these are the only
references to the old names in tensorrt_llm/.

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
CI build #39880 surfaced NVFP4 accuracy regressions on DGX_B200:
- TestLlama3_1_8B.test_nvfp4:           5.517 vs threshold 23.479
- TestLlama3_1_8B.test_nvfp4_streaming: same
- TestQwen3_30B_A3B.test_nvfp4[latency_moe_*]: same root cause

Root cause: refactor commit 574c518 consolidated main's
out_scale/out_scale_sf pair into a single forward_args.out_scale
field, picking at the modules/attention.py call site based on
``output_sf is not None``. But ``output_sf`` at that point is the
``_attn_impl`` function argument, which forward_impl() never
populates (the buffer is created later inside the backend's forward
by ``create_output``). So the predicate was always False and the
NVFP4 path silently picked ``inv_input_scale`` instead of
``input_scale`` -> kernel-side rescale wrong -> ~5x accuracy drop.

Main avoided this by passing both scales through to trtllm.py and
deciding inside ``_run`` after ``output_sf`` is allocated.

Fix:
  * interface.py: re-introduce ``out_scale_sf`` field on
    AttentionForwardArgs.
  * modules/attention.py: populate both ``out_scale`` (=
    ``inv_input_scale``) and ``out_scale_sf`` (= ``input_scale``)
    whenever quantized output is enabled, matching main.
  * trtllm.py: in ``_run``, after the fp8-KV fallback, promote
    ``out_scale_sf`` -> ``out_scale`` when ``forward_args.output_sf``
    is allocated. The static sync test's ``_THOP_EXCLUDED_FIELDS``
    gains ``out_scale_sf`` since the kernel binding still takes only
    a single ``out_scale``.

Validation on B200 (umbriel-b200-081, sm_100):
  * TestLlama3_1_8B::test_nvfp4 PASSED (MMLU 62.622 vs threshold 61.343)
  * TestLlama3_1_8B::test_nvfp4_streaming[stream_interval_4,64] PASSED
  * test_attention_op_sync.py (5 tests) PASSED

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
After the AttentionForwardArgs field rename in 574c518, the trtllm-gen
backend's _get_kv_scale_params kept a two-tier lookup (per-call
forward_args.kv_scale_* OR layer-level attention_layer.kv_scale_*). The
layer-level fallback is dead for the PyTorch backend:

  * The PyTorch model loader never writes to TrtllmAttention.
    kv_cache_scaling_factor — it stays at the torch.ones(1) initial
    value, so attention_layer.kv_scale_quant_orig is always 1.0.
  * The attention-kernel side (mlaPreprocessOp / MMHA / unfused / sm_120
    XQA) now defaults to 1.0 when the scale pointer is null (commits
    319ec1c, 5040cc7), reproducing the exact same effective value.

Sourcing only from forward_args also removes the implicit dependency on
attention_layer's kv_scale_* attributes, allowing the layer-level
mirrors to be dropped from TrtllmAttention.__init__ in a follow-up.

Validation on B200 (umb-b200-236):
  * TestLlama3_1_8B::test_nvfp4 with TRTLLM_ENABLE_TRTLLM_GEN_ATTENTION=1
    PASSED (exercises the simplified _get_kv_scale_params).

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
@yuxianq

yuxianq commented May 27, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@yuxianq
yuxianq force-pushed the derived-attn-props branch from 2aea9fc to 5e5334f Compare May 27, 2026 06:48
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50489 [ run ] triggered by Bot. Commit: 5e5334f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50453 [ run ] completed with state ABORTED. Commit: 2aea9fc

Link to invocation

Add ``test_excluded_fields_match_real_fields`` to the AST sync test.
It walks ``AttentionForwardArgs`` (recursively into nested dataclass
sub-bags) and asserts every entry in ``_THOP_EXCLUDED_FIELDS`` names a
real field. A dead entry would silently allow a newly-added real field
to slip past ``test_every_forward_args_field_is_consumed``.

While at it, drop the dead ``is_generation`` entry — it was added in
574c518 but never matched a field on the renamed
``AttentionForwardArgs`` (the matching field was removed earlier in the
same refactor iteration).

The companion sanity check on ``_THOP_LITERALS`` already exists in
``test_literal_kwargs_match_allowlist`` (both directions: unknowns and
stales), so this commit covers only the gap on the exclude set.

Validation: ran the full sync test locally (no GPU); all 6 tests
pass, including the new check. Temporarily re-adding ``is_generation``
makes the new check fail with a clear message, as expected.

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
@yuxianq

yuxianq commented May 27, 2026

Copy link
Copy Markdown
Collaborator Author

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

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50497 [ run ] triggered by Bot. Commit: 15b0fdc Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50489 [ run ] completed with state ABORTED. Commit: 5e5334f

Link to invocation

L0 build #40005 surfaced 5 illegal-memory-access failures on
RTXPro6000D and 1 CUBLAS_STATUS_EXECUTION_FAILED on DGX_H100:
- TestLagunaXS.{test_fp8,test_nvfp4}                       (RTXPro6000D, sm_120)
- test_ptp_quickstart_advanced[{Llama3.1-8B-NVFP4,Qwen3-30B-A3B_{fp8,nvfp4}}_hf]
                                                            (RTXPro6000D, sm_120)
- TestNemotronV3Nano.test_fp8                              (DGX_H100, sm_90)

Cross-PR scan: 0 other PRs hit these tests; PR NVIDIA#14279 alone since
commit 5e5334f (which dropped the older ecf3fa5 "kv_scale
fallback" commit during the rebase that simplified trtllm_gen.py).

Root cause: dropping ecf3fa5 removed two things that turn out to be
load-bearing for fp8 KV cache models on the default-path (non-trtllm-gen)
attention kernels:

  1. Layer-level mirrors ``self.kv_cache_scaling_factor`` /
     ``self.kv_scale_quant_orig`` / ``self.kv_scale_orig_quant`` on
     ``TrtllmAttention.__init__``.
  2. The ``_run``-side fallback that defaults
     ``forward_args.kv_scale_*`` to those mirrors when the caller
     leaves them ``None``.

I earlier (correctly) noted the PyTorch backend never writes real
values to ``kv_cache_scaling_factor`` and concluded the mirrors were
1.0-no-ops the kernel could re-derive from a nullptr default. That
conclusion was incomplete: several XQA kernels still deref
``kvCacheScale[0]`` whenever ``isKVCacheQuantized`` is true and do
NOT check for nullptr —
  * cpp/kernels/xqa/mha.cu        (lines 1744, 2495)   - sm_100/sm_120
  * cpp/kernels/xqa/mha_sm90.cu   (lines 885, 1127, 1530, 1620) - sm_90
The earlier null-safe deref fixes (commits 319ec1c, 5040cc7)
only covered the MMHA template, the unfused KV-cache write path, and
``mla_sm120.cu`` — the non-MLA XQA kernels were missed. Passing a
nullptr to them on fp8-KV models reads invalid memory at the kernel
entry → illegal memory access at executor init → cascades to
CUBLAS_STATUS_EXECUTION_FAILED on subsequent calls.

Fix: restore the layer-level mirrors and the ``_run`` fallback. This
is verbatim equivalent to the trtllm.py state at the previously-passing
build NVIDIA#2656 (commit 2aea9fc) modulo this commit message's comment
edits. ``modules/attention.py`` continues to populate the per-call
fields only for fp4 KV cache; fp8-KV models fall through to the
layer-level mirrors and the kernel receives a valid 1.0 pointer.

Local validation: my single-arch / multi-arch sm_120 builds cannot
reproduce the CI's complete FMHA cubin set (e4m3 + sm_120 + head_dim 128
+ ReturnSoftmaxStats variants are not generated by setup.py /
fmha_cubin.cpp in the local build) — TestLagunaXS::test_fp8 fails at
executor init with "FMHA kernels are not found" before reaching the
attention runtime path. This is a build-environment gap, not a code
regression. The fix is byte-equivalent (modulo comments) to commit
2aea9fc which DID pass this test on RTXPro6000D in CI build NVIDIA#2656.

A follow-up should add null-safe ``kvCacheScale[0]`` guards in
``mha.cu`` and ``mha_sm90.cu`` so the layer-level mirrors are no
longer load-bearing, mirroring the pattern already in
``mla_sm120.cu``. Tracked separately.

Signed-off-by: Yuxian Qiu <142763828+yuxianq@users.noreply.github.com>
@yuxianq

yuxianq commented May 27, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50539 [ run ] triggered by Bot. Commit: 2d4798e Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50497 [ run ] completed with state ABORTED. Commit: 15b0fdc

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50539 [ run ] completed with state FAILURE. Commit: 2d4798e
/LLM/main/L0_MergeRequest_PR pipeline #40044 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

@yuxianq

yuxianq commented May 28, 2026

Copy link
Copy Markdown
Collaborator Author

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

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50640 [ run ] triggered by Bot. Commit: 2d4798e Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50640 [ run ] completed with state SUCCESS. Commit: 2d4798e
/LLM/main/L0_MergeRequest_PR pipeline #40133 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

@yuxianq

yuxianq commented May 28, 2026

Copy link
Copy Markdown
Collaborator Author

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

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50712 [ run ] triggered by Bot. Commit: 2d4798e Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #50712 [ run ] completed with state SUCCESS. Commit: 2d4798e
/LLM/main/L0_MergeRequest_PR pipeline #40196 completed with status: 'SUCCESS'

CI Report

Link to invocation

@yuxianq
yuxianq merged commit 09bad73 into NVIDIA:main May 28, 2026
7 checks passed
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.

5 participants