Skip to content

[None][feat] Add CSA2 Vanilla sparse attention - #20431

Open
yihwang-nv wants to merge 6 commits into
NVIDIA:mainfrom
yihwang-nv:vanilla-csa2-attention
Open

yihwang-nv wants to merge 6 commits into
NVIDIA:mainfrom
yihwang-nv:vanilla-csa2-attention

Conversation

@yihwang-nv

@yihwang-nv yihwang-nv commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Dev Engineer Review

  • The only working-tree change reformats imports in vanilla.py. It does not change runtime behavior.
  • The reported CSA2, DSA, utility, and test changes are not present in the inspected diff.

QA Engineer Review

No test changes.

Per-File QA Perspective

  • tensorrt_llm/_torch/attention/backends/vanilla.py: Import formatting only. No QA behavior change to verify.

Depends on #16309. Only the last commit belongs to this PR.

Description

  • Add CSA2VanillaAttention and a weightless CSA2VanillaIndexer (tensorrt_llm/_torch/attention/backends/sparse/csa2/vanilla_backend.py), a pure-PyTorch golden reference for CSA2 sparse attention:
    • On a layer's first call, write the new sliding-window rows and, on the layer that owns the shared cache, every compressed group the forward completes.
    • Publish the selection in production's format, plus the candidate list on the candidate-source layer (ascending blocks, newest block always kept, entries past the visible count masked).
    • Select an exact top-k over visible entries on mapped pages, restricted to the published candidates for a REINDEX consumer.
    • Attend over the window plus the selected rows with the attention sink; an empty selection gives zeros.
  • Geometry comes from independent sources: positions from kv_lens_cuda - seq_lens and pages from the cache manager's host page lists. The golden never reads the kernel-produced slot tables, page tables or visible lengths.
  • Rejected before anything is written: packed attention, decoder replay geometry, remote-tail and precomputed-KV passes, mixed-phase calls and CUDA graph capture. FP8 staging, approximate top-k and pre-packed index queries are accepted, but the golden always decodes, stages and selects exactly.
  • Move the RoPE and phase helpers shared with the DSA golden into sparse/_vanilla_utils.py (pure move; the phase_is_generation error now says "Sparse MLA requires…" instead of "DSA requires…", and DSAVanillaEmbedding is no longer listed in the DSA golden's __all__).

Scope: the sparse registry and the CSA2 module are unchanged, so attn_backend="VANILLA" still raises for csa2 (the module builds create_attention("TRTLLM", ...)). Tests construct the golden directly; plumbing the configured backend into the module is a separate change. Like the other Vanilla goldens, it rejects CUDA graph capture.

Test Coverage

tests/unittest/_torch/attention/sparse/csa2/test_vanilla_backend.py:

  • CPU-tensor tests with hand-derived expected values on shuffled and partly unmapped pages: selection and candidate publication, cache writes, a REINDEX consumer, attention-only decode, and rejection before writing.
  • SM100 GPU test running VANILLA, TRTLLM, and TRTLLM with the golden's selection injected on separate cache managers through a prefill forward and a chunked-prefill + decode forward:
    • identical selections: relative output error ≤ 1e-2 (measured ≈ 2.9e-3, BF16 staging);
    • selections: identical counts, per-row recall of the golden's entries ≥ 0.9 and ≥ 0.98 on average (BF16 index weights can swap near-tied boundary entries);
    • composed run: mean absolute error ≤ 5e-3 (measured ≤ 1.2e-3);
    • newly written cache rows: ≤ 1% mismatching bytes.

Results on B200:

  • pytest tests/unittest/_torch/attention/sparse/csa2/test_vanilla_backend.py — 18 passed (3 consecutive runs).
  • pytest tests/unittest/_torch/attention/sparse/csa2 (existing tests) — 592 passed, 12 skipped.
  • pytest tests/unittest/_torch/attention/sparse/dsa/test_dsa_sparse_mla.py (shared helper move) — 16 passed.

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.

Signed-off-by: Yihan Wang <yihwang@nvidia.com>
Signed-off-by: Yihan Wang <yihwang@nvidia.com>
Signed-off-by: Yihan Wang <yihwang@nvidia.com>
Preserve the independent DSA Vanilla backend and its regression coverage. Reconcile the indexer test helper with upstream and limit signature exclusions to optional non-DSA modes.

Signed-off-by: yihwang-nv <yihwang@nvidia.com>
Share phase, score, TopK mapping, and latent-cache helpers while preserving the independent PyTorch reference. Document quantization and cache contracts, improve input validation, and move kernel-only reference adapters into test utilities.

Trim redundant tests while retaining quantized Q projection and generation RoPE/cache ownership coverage.

Validation on umbriel-b200-043 (B200): 1305 passed, 4 existing skips, 0 failed. Ruff lint, formatting, and diff checks passed.

Signed-off-by: yihwang-nv <yihwang@nvidia.com>
Add CSA2VanillaAttention and CSA2VanillaIndexer, a pure-PyTorch golden of
CSA2 sparse attention: sliding-window and compressed-group cache writes,
candidate publication, exact top-k selection inside the published
candidates, and sink attention over the window plus selected rows. Geometry
comes from request lengths and the cache manager's host page lists, never
from the kernel-produced slot or page tables.

Tests cover the golden on CPU tensors with hand-derived values and compare
it with the TRTLLM backend on SM100.

Move the RoPE and phase helpers shared with the DSA golden into
sparse/_vanilla_utils.py.

Signed-off-by: yihwang-nv <yihwang@nvidia.com>
@yihwang-nv
yihwang-nv requested a review from a team as a code owner October 15, 2026 16:48
@yihwang-nv
yihwang-nv requested a review from yuxianq October 15, 2026 16:50
@coderabbitai

coderabbitai Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/TensorRT-LLM/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 3f803cd1-516c-4854-8903-a6fc21fc4114
📥 Commits

Reviewing files that changed from the base of the PR and between 7c03f0e and 088da25.

📒 Files selected for processing: 16
  • tensorrt_llm/_torch/attention/backends/sparse/_vanilla_utils.py
  • tensorrt_llm/_torch/attention/backends/sparse/csa2/vanilla_backend.py
  • tensorrt_llm/_torch/attention/backends/sparse/dsa/__init__.py
  • tensorrt_llm/_torch/attention/backends/sparse/dsa/vanilla_backend.py
  • tensorrt_llm/_torch/attention/backends/sparse/registry.py
  • tensorrt_llm/_torch/attention/backends/vanilla.py
  • tests/unittest/_torch/attention/backend_capability.py
  • tests/unittest/_torch/attention/backend_case.py
  • tests/unittest/_torch/attention/model_attn_config.py
  • tests/unittest/_torch/attention/sparse/csa2/test_vanilla_backend.py
  • tests/unittest/_torch/attention/sparse/dsa/_indexer_reference.py
  • tests/unittest/_torch/attention/sparse/dsa/test_cute_dsl_fp4_paged_mqa_logits.py
  • tests/unittest/_torch/attention/sparse/dsa/test_cute_dsl_fp8_paged_mqa_logits.py
  • tests/unittest/_torch/attention/sparse/dsa/test_dsa_indexer.py
  • tests/unittest/_torch/attention/sparse/dsa/test_dsa_sparse_mla.py
  • tests/unittest/_torch/attention/test_attention_backends.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Walkthrough

Adds pure-PyTorch reference implementations for DSA and CSA2 sparse attention. The changes connect DSA to the Vanilla backend registry and extend sparse-attention testing across indexer selection, cache handling, and attention outputs.

Changes

DSA sparse MLA

Layer / File(s) Summary
RoPE and phase metadata helpers
tensorrt_llm/_torch/attention/backends/sparse/_vanilla_utils.py
Adds packed-layout rotary embedding and helpers for MLA RoPE, phase bounds, cached lengths, and token positions.
Indexer projection, quantization, and selection
tensorrt_llm/_torch/attention/backends/sparse/dsa/vanilla_backend.py, tests/unittest/_torch/attention/sparse/dsa/_indexer_reference.py, tests/unittest/_torch/attention/sparse/dsa/test_dsa_indexer.py, tests/unittest/_torch/attention/sparse/dsa/test_cute_dsl_fp4_paged_mqa_logits.py, tests/unittest/_torch/attention/sparse/dsa/test_cute_dsl_fp8_paged_mqa_logits.py
Adds DSA indexer projection, quantization, paged-key scoring, and TopK selection. Tests use the indexer’s quantization helpers and shared logits references.
Sparse MLA attention and cache integration
tensorrt_llm/_torch/attention/backends/sparse/dsa/vanilla_backend.py, tensorrt_llm/_torch/attention/backends/sparse/dsa/__init__.py, tensorrt_llm/_torch/attention/backends/sparse/registry.py, tensorrt_llm/_torch/attention/backends/vanilla.py, tests/unittest/_torch/attention/sparse/dsa/test_dsa_indexer.py
Adds DSA RoPE, latent-cache operations, pool-index mapping, and sparse MLA execution. The registry selects DSAVanillaAttention for DSA; generic Vanilla MLA rejects sparse parameters.
Sparse MLA harness and backend comparisons
tests/unittest/_torch/attention/backend_case.py, tests/unittest/_torch/attention/backend_capability.py, tests/unittest/_torch/attention/model_attn_config.py, tests/unittest/_torch/attention/sparse/dsa/test_dsa_sparse_mla.py, tests/unittest/_torch/attention/test_attention_backends.py
Adds sparse case setup and context/generation execution. Tests compare backend selections with Vanilla selections and check selected-attention outputs and native-selection results.

CSA2 sparse attention

Layer / File(s) Summary
Request geometry and cache-row mapping
tensorrt_llm/_torch/attention/backends/sparse/csa2/vanilla_backend.py, tests/unittest/_torch/attention/sparse/csa2/test_vanilla_backend.py
Adds request geometry, page-table mapping, cache-row writers, and RoPE-position validation. Tests cover cache mappings and constructor constraints.
Candidate scoring and index selection
tensorrt_llm/_torch/attention/backends/sparse/csa2/vanilla_backend.py, tests/unittest/_torch/attention/sparse/csa2/test_vanilla_backend.py
Adds visible-entry scoring, candidate-block selection, sorted TopK results, and -1 padding. Tests cover candidate and REINDEX behavior.
Cache routing and sparse attention
tensorrt_llm/_torch/attention/backends/sparse/csa2/vanilla_backend.py, tests/unittest/_torch/attention/sparse/csa2/test_vanilla_backend.py
Adds layer routing, SWA and main-cache writes, slot mapping, and sink attention over valid rows. Tests cover layer modes, rejected execution cases, and GPU comparisons.

Priority: ➖ Normal

Estimated code review effort: 5 (Critical) | ~120 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Indexer as DSAVanillaIndexer
  participant Metadata as DSA metadata
  participant Cache as DSA cache manager
  participant Attention as DSAVanillaAttention
  Indexer->>Cache: Append projected indexer keys
  Indexer->>Metadata: Publish TopK selections
  Attention->>Metadata: Read selections and phase data
  Attention->>Cache: Load selected latent rows
  Attention->>Attention: Compute sparse MLA output
Loading
sequenceDiagram
  participant State as CSA2ForwardState
  participant Indexer as CSA2VanillaIndexer
  participant Cache as CSA2 cache pools
  participant Attention as CSA2VanillaAttention
  State->>Indexer: Supply query and visible cache metadata
  Indexer->>State: Publish selected indices and candidate blocks
  State->>Attention: Supply layer state and query tile
  Attention->>Cache: Write cache rows and resolve selected slots
  Attention->>Attention: Compute sink attention over valid rows
Loading

Suggested reviewers: bowenfu, yihuilu512

Merge Risk: ⚪ Minimal · up to 088da

This change adds pure-PyTorch reference backends for DSA and CSA2 sparse attention, along with validation tests. The Vanilla registry now maps DSA to its dedicated backend. Generic Vanilla MLA now fails explicitly when it receives sparse parameters instead of computing silently. No concrete merge-blocking issue was found.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 66.83% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 205 functions across 16 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title is concise, specific, and accurately identifies the primary change: adding CSA2 Vanilla sparse attention.
Description check Passed The description explains the purpose, implementation scope, limitations, and test coverage. It includes the required Description, Test Coverage, and PR Checklist sections and reports concrete test res…
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@yuxianq

yuxianq commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

@farazkh80, could you help to review this PR as trt-llm-torch-attention-devs? Thanks~

Assignment explanation
Componentsbackends/sparse (68%); integration/attention-tests (29%); backends/vanilla (3%)
Tagsalgorithm:sparse (100%); specific-algorithm:dsa (100%); representation:mla (100%); phase:prefill (50%); phase:decode (50%); features:quantization (40%); features:rope (25%); features:paged-kv (35%)
PR effort8 points — The supplied diff includes both CSA2 and DSA reference backends plus test-oracle consolidation. Quantized paged-cache coordinates, phase-specific writes, selection reuse and attention normalization warrant deep contract review. Shared-helper moves and deleted duplicate references contribute less effort than the new behavior.
ImportanceImportant — Changes correctness-reference contracts for sparse attention: DSA becomes selectable through the Vanilla registry, generic sparse MLA is rejected, and the added CSA2 reference specifies cache ownership, candidate selection and sink normalization. These require sensitive numerical and cache-coordinate review; no model architecture or kernel implementation is introduced.
Affinity (0–1)0.420 component/tag match; 0.315 after PIC preference
Outstanding points at selection35 → 43 (+8)
Points already reserved on this PR0
Effective weight1
Completed review points (preceding 168 hours)48
Combined points after assignment91
Demand-derived target83.00 points (soft share)
Additional fair share before assignment0.00 points
Share explanationWhole PR / qualification or coverage constraint exceeds a soft share; assignment is allowed.
Selection ruleaffinity with half-share guard

Affinity and workload are snapshots at selection, not live counters. Existing reservations on this PR are counted once.

@yuxianq
yuxianq requested review from farazkh80 and removed request for PerkzZheng, yunruis and yuxianq October 15, 2026 17:15

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

Approved from attention perspective, with two questions (non-blocking).

swa_slots,
state.swa_kv,
"swa",
state.swa_transform,

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.

main_transform and index_transform RoPE positions are checked against the golden's geometry, but swa_transform isn't. A wrong SWA position would match in both golden and TRTLLM.

Same check apply to swa_transform?

if query_start < batch.num_ctx_tokens < end:
raise ValueError("CSA2 query tiles must not cross the context/generation boundary")
if query_start == 0:
self._enter_layer(source, layer)

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.

_enter_layer runs before the write-time checks. After a rejection, a retry on the same metadata fails with "cannot be reused" instead of the real error.

Should we move it after those checks?

@github-actions

Copy link
Copy Markdown

Automatically added "ci: full pre-merge approved" because this PR has satisfied the required GitHub review approvals. Unresolved review conversations and other required checks remain independent merge requirements.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants