Skip to content

[None][feat] Add TriAttention KV-cache compression method - #16957

Merged
Hudayday merged 193 commits into
NVIDIA:mainfrom
Hudayday:kvcache-v2-triattention-no-engine
Aug 4, 2026
Merged

[None][feat] Add TriAttention KV-cache compression method#16957
Hudayday merged 193 commits into
NVIDIA:mainfrom
Hudayday:kvcache-v2-triattention-no-engine

Conversation

@Hudayday

@Hudayday Hudayday commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add TriAttention NVIDIA work @ ICML 2026 KV-cache compression support to the TensorRT-LLM.
  • TriAttention is a training-free decode-time eviction algorithm: every beta confirmed generation tokens, it scores the evictable decode region using offline per-head query calibration, keeps budget important tokens, compacts their K/V data in place, and releases unused tail pages.
  • Integrate TriAttention as a KV-cache compression resource manager on top of KVCacheManagerV2; decode continues to use the model's standard attention backend.
  • Add the score/select pipeline: V2 page-table snapshot → mean-phase gather → CuTe paged-K scoring → normalize/reduce → TopK/tie settlement → batched physical compaction.
  • Support union, per_head, and per_layer_perhead eviction modes.
  • Support GPT-OSS-style kernel-masked SWA and one-model MTP/EAGLE3 draft-cache co-compaction in union mode.
  • Preserve logical RoPE positions after physical eviction by disabling RoPE fusion for eviction-based compression.
  • Add configuration/API wiring, usage documentation, B200 CI registration, and focused tests.

Performance

On Qwen3-8B, TriAttention (B=2048, β=2048) delivers up to 1.61× the throughput of the Dense baseline at the same batch size (BS=32: 4,930.6 vs. 3,057.5 output tok/s per GPU; 154.1 vs. 95.5 tok/s per user), while its verified capacity frontier reaches 2.63× the Dense baseline’s maximum aggregate throughput (8,053.0 vs. 3,057.5 output tok/s per GPU).
Screenshot 2026-07-29 at 10 56 06 AM

Main Files

File Purpose
_torch/kv_cache_compression/triattention/triattention.py Request lifecycle, calibration loading, eviction cadence, score/select/compact orchestration, and cache resize
triattention_cute_score_fused.py SM100 CuTe DSL paged-K score kernel and score pipeline
triattention_cute_selection.py CuTe DSL score normalization and union reduction
triattention_kernels.py Triton mean-phase, per-head reduction, TP-fold, and tie-settlement kernels
batch_manager/kvCacheManagerV2Utils.{h,cpp} Batched V2 page-table snapshot used by the scorer and compactor
llmapi/llm_args.py TriAttentionKvCacheCompressionConfig and KV-compression config dispatch
examples/triattention/README.md Calibration, configuration, support matrix, and usage

Key Design Decisions

  • Physical compression, not sparse attention: TriAttention changes which K/V entries are stored. It does not introduce a sparse-attention backend or modify the normal decode attention kernel.
  • In-place V2 compaction: The implementation does not create a new KV-cache instance or memory pool. Selected K/V entries are moved within the existing paged pools through the generic compaction API from [None][feat] Batched physical KV-cache compaction for KV cache compression #16836, then the same cache is resized.
  • Direct paged-pool scoring: The scorer consumes a batched snapshot of the current V2 page table and reads paged K directly; no Torch gather/reformat path is used.
  • Position correctness: Prompt tokens, selected-token RoPE information, and protected overlap/speculative tails are preserved. py_num_compressed_tokens maintains the logical sequence length after the physical cache becomes shorter.
  • Reusable runtime: Score buffers and compiled CuTe launches are retained and only rebuilt when a newly admitted request raises the scorer capacity high-water mark.

Known Limitations

  1. PyTorch backend, KVCacheManagerV2, and B200/SM100 only.
  2. KV-cache block reuse must be disabled.
  3. Native sliding-eviction layouts such as Gemma 4 are not supported; the current SWA path targets GPT-OSS-style full-length pools with kernel-side masking.
  4. Attention DP and disaggregated serving are not supported.
  5. TP beyond TP1 has not yet been validated end to end.

Test Plan

  • Focused TriAttention/KV suite: 55 passed
    • CuTe score vs. Torch oracle
    • all three eviction modes
    • ragged lengths and unaligned final tokens
    • deterministic heavy-tie settlement
    • target/draft physical co-compaction
    • GPT-OSS-style SWA
    • overlap/page-table staging and cache resize
    • RoPE-fusion gating
    • score scratch larger than 2^31 elements
  • Fused-union boundary file: 9/9 passed
  • Focused executor integration: 25 passed

Dev Engineer Review

  • Added TriAttention KV-cache compression for the PyTorch backend.
  • Implemented Triton and SM100 CuTe scoring, selection, tie settlement, and in-place K/V compaction.
  • Added configuration, public API, documentation, validation, RoPE-fusion gating, and IndexMapper.gatherKBlockOffsets bindings.
  • Added target/draft co-compaction for supported speculative modes.
  • Scope is limited to PyTorch, KVCacheManagerV2, and SM100/B200. Limitations include disabled block reuse, unsupported sliding-eviction layouts, attention DP, disaggregated serving, and TP configurations beyond TP1.

QA Engineer Review

  • Added coverage for offset gathering, manager lifecycle, capability validation, RoPE fusion, CuTe scoring, fused union processing, tie settlement, selection, compaction, page reuse, speculative decoding, and API dispatch.
  • Registered unittest/_torch/kv_cache_compression in tests/integration/test_lists/test-db/l0_b200.yml.
  • Reported 55 focused TriAttention/KV tests, 9 fused-union boundary tests, and 25 executor integration tests passing.
  • Verdict: sufficient for the registered B200 coverage. Unsupported TP, serving, and layout combinations need follow-up coverage if enabled.

Hudayday added 30 commits July 15, 2026 19:32
Signed-off-by: tianruih <tianruih@nvidia.com>
Signed-off-by: tianruih <tianruih@nvidia.com>
…hannel

Eager eviction pipeline (the standalone compression CUDA graph was
removed), optimized compaction kernels, and draft KV co-compression:
one-model speculation applies the target union keep set to the draft
cache and protects the unconfirmed draft tail; modes whose draft KV
cannot join the unified eviction fail fast at admission.

Signed-off-by: tianruih <tianruih@nvidia.com>
Signed-off-by: tianruih <tianruih@nvidia.com>
Signed-off-by: tianruih <tianruih@nvidia.com>
…l site

Signed-off-by: tianruih <tianruih@nvidia.com>
Signed-off-by: tianruih <tianruih@nvidia.com>
# Conflicts:
#	tensorrt_llm/_torch/pyexecutor/_util.py
- stage layered KV compaction vectors in registers (D64/D128 half-precision)

- single-pass eviction cohort bookkeeping

- drop the unprepared pack-compaction wrapper

- shared keep-set selector base for union and per-head modes

- adopt KvCacheCompressionMode and the call-site speculative gate

Signed-off-by: tianruih <tianruih@nvidia.com>
Signed-off-by: tianruih <tianruih@nvidia.com>
Signed-off-by: tianruih <tianruih@nvidia.com>
…fig docstring

Signed-off-by: tianruih <tianruih@nvidia.com>
Signed-off-by: tianruih <tianruih@nvidia.com>
# Conflicts:
#	tensorrt_llm/_torch/pyexecutor/_util.py
Signed-off-by: tianruih <tianruih@nvidia.com>
update_resources declared attn_metadata/kv_cache_dtype_byte_size but the
executor dispatches those extras to the KV cache manager slot only, and the
method body never read them; drop the dead parameters and the docstring
sentence that claimed a transparent pass-through.

Also document that on_generation_step_begin fires on context-only iterations
too, and that it should be split into context/generation-step hooks once an
algorithm needs the distinction.

Signed-off-by: tianruih <tianruih@nvidia.com>
- Dispatch the config union on the algorithm tag (discriminated union, like
  sparse attention and speculative configs) and drop the abstract base from
  the union: a mistyped algorithm now fails config validation with the list
  of valid tags instead of silently validating as the base class. The
  factory hard-cast that guarded against base instances is gone with it.
- Rename the base class to BaseKvCacheCompressionConfig and give the plain
  KvCacheCompressionConfig name to the user-facing union alias, matching the
  sparse/speculative naming convention.
- Raise on a config whose algorithm has no registered manager instead of
  warning and silently running without compression.
- Require model_path and calibration_path at config validation time; both
  are consumed at manager construction and previously failed deep in
  executor setup (or worse, fell back to an unrelated calibration).
- Drop the dead window_size field (nothing reads it; it also occupied a
  telemetry manifest entry) and its README row, and fix the README rows
  that still described a removed eviction mode.
- Add gt=0 to top_B/beta and collect the manager constructor kwargs in
  KvCacheCompressionConfig.to_manager_kwargs().

Signed-off-by: tianruih <tianruih@nvidia.com>
The dropped window_size field leaves the manifest; no other entries change.

Signed-off-by: tianruih <tianruih@nvidia.com>
Adjacent programs now walk consecutive K pages of one (request, layer,
head) and reuse its calibration/phase rows in L2. Median score-kernel
time drops 1.8-2.0% across two model geometries and both sequential and
shuffled page layouts, bit-exact against the segment-major order.

Segments move to the y grid axis, which CUDA caps at 65535; both launch
sites validate the request*layer count against that limit so the
unbounded x axis stays with the token tiles of long sequences.

Signed-off-by: tianruih <tianruih@nvidia.com>
- Promote the prepared Triton launch helper to its own module with a
  public name (it also backs the score, stats, and union selection
  launches) and validate the constexpr ordering against the kernel
  declaration at build time instead of by comment.
- Fail fast on combinations that previously degraded silently:
  selection tensors on the wrong device, swa_window without SWA layers,
  draft pools without draft layers, and (in the C++ op) flat source
  indices combined with per-layer source indices, with a unit test for
  the rejected op combination.
- Name the pack kernel launch-shape constants, split combined error
  messages, rename the pack launch keep_count to decode_keep_count,
  drop the grouping parameter that never affected grouping, and
  document the constructor staging-snapshot inputs.
- Deduplicate the block-offset encoder into the test conftest, reword
  generic C++ comments that named one consumer, and document the V2
  2*page+plane offset decode in the updater kernel.

Signed-off-by: tianruih <tianruih@nvidia.com>
Conflicts:
	tensorrt_llm/llmapi/__init__.py
	tensorrt_llm/usage/llm_args_golden_manifest.json
…in merge

The merge resolved the manifest to the main side; regenerating restores the
KV-cache compression entries alongside the fields main added.

Signed-off-by: tianruih <tianruih@nvidia.com>
…pec gate

Upstream replaced acceptance_window/acceptance_length_threshold with
use_rejection_sampling (base config) and use_relaxed_acceptance_for_thinking
(MTP only); the compression spec gate now rejects those, with the same
fail-fast intent: eviction is only validated with greedy acceptance.

Signed-off-by: tianruih <tianruih@nvidia.com>
Eviction cohorts were grouped by (prompt_len, keep_count) because the
batched pipeline treated the pinned prompt length as scalar geometry: the
selection rectangle carried a materialized prompt prefix, the score kernel
baked TOKEN_START as a compile-time constant, and the C++ compact launch
took one destination base. Real batches mix prompt lengths, so a 32-request
round split into up to 15 sub-rounds; a profiled step with 13 sub-rounds
spent 39.8 ms in update_resources against 2.3 ms for a single round.

Prompt lengths are now per-request runtime metadata end to end:
- the score kernel reads each request's decode-window origin from a staged
  token-starts row instead of a constexpr;
- selection rectangles are decode-only ([request(, rows), top_B]) with the
  per-row prompt offset rebasing emitted ordinals to absolute positions;
- the pack kernel drops its prompt constants (moves never touch the prompt);
- the compact op takes per-request destination bases (contiguous CUDA int32
  [batch]), and SWA landing positions rebase per request each round;
- the cohort key is gone: one due round launches once, chunked only by the
  staging memory bound.

A cohort mixing prompt lengths is asserted byte-identical to per-request
compactions, and the op gains a mixed-bases unit test.

Signed-off-by: tianruih <tianruih@nvidia.com>
The explicit instantiations still declared the scalar destination base;
match the per-request destinationBases pointer.

Signed-off-by: tianruih <tianruih@nvidia.com>
Torch schemas reject a non-default positional parameter after a
defaulted one; stub generation aborted on import.

Signed-off-by: tianruih <tianruih@nvidia.com>
…buffer set

The eviction path kept LRU caches of score staging, keep-set selectors,
and batched compaction launches keyed by exact cohort shapes, and split
large due cohorts into fixed 32-request chunks. Every new shape paid an
allocation storm next to a nearly full KV pool, and the caches were only
correct while their keys stayed exact.

Now one buffer set is built at first eviction and stays resident: the
request capacity follows the executor max batch size, the decode width
follows the eviction bound (top_B plus two eviction periods plus draft
tokens), and the page-table plane follows max_seq_len plus the protected
tail capacity. Buffers rebuild only when the V2 pool views change or a
round outgrows them. One generation batch is one eviction round; padding
rows carry zero widths and move nothing.

Protected tails become per-round state: BatchedKVCacheCompaction sizes
its move buffers by a tail capacity and set_protected_tails() loads each
cohort per-request tails into the move offsets consumed by the pack
kernel and the C++ compact launches.

Signed-off-by: tianruih <tianruih@nvidia.com>
@Hudayday

Hudayday commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63291 [ run ] triggered by Bot. Commit: aee6c52 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63291 [ run ] completed with state FAILURE. Commit: aee6c52
/LLM/main/L0_MergeRequest_PR pipeline #51286 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 Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63318 [ run ] triggered by Bot. Commit: aee6c52 Link to invocation

@yihwang-nv
yihwang-nv requested a review from yuxianq August 3, 2026 02:19
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63318 [ run ] completed with state SUCCESS. Commit: aee6c52
/LLM/main/L0_MergeRequest_PR pipeline #51314 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 Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63352 [ run ] triggered by Bot. Commit: aee6c52 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63352 [ run ] completed with state FAILURE. Commit: aee6c52
/LLM/main/L0_MergeRequest_PR pipeline #51340 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 Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63386 [ run ] triggered by Bot. Commit: aee6c52 Link to invocation

Comment thread tensorrt_llm/_torch/kv_cache_compression/triattention/triattention.py Outdated

@yihwang-nv yihwang-nv 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! The changes to the attention modules are very straightforward.

Signed-off-by: Tianrui 'Hudayday' Hu <32944717+Hudayday@users.noreply.github.com>
@Hudayday

Hudayday commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63395 [ run ] triggered by Bot. Commit: a27a55c Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63386 [ run ] completed with state ABORTED. Commit: aee6c52

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63395 [ run ] completed with state FAILURE. Commit: a27a55c
/LLM/main/L0_MergeRequest_PR pipeline #51374 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 Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63456 [ run ] triggered by Bot. Commit: a27a55c Link to invocation

@Hudayday

Hudayday commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63493 [ run ] triggered by Bot. Commit: a27a55c Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63456 [ run ] completed with state ABORTED. Commit: a27a55c

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63493 [ run ] completed with state SUCCESS. Commit: a27a55c
/LLM/main/L0_MergeRequest_PR pipeline #51462 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 Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63552 [ run ] triggered by Bot. Commit: a27a55c Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

CI Report

Link to invocation

@Hudayday
Hudayday merged commit b008616 into NVIDIA:main Aug 4, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-compatible Accepted LLM API contract change that is backwards-compatible

Projects

None yet

Development

Successfully merging this pull request may close these issues.