Skip to content

[None][fix] align KV slice token_range.end with transferred block count - #15824

Merged
chuangz0 merged 2 commits into
NVIDIA:mainfrom
chuangz0:fix_token_range
Jul 15, 2026
Merged

[None][fix] align KV slice token_range.end with transferred block count#15824
chuangz0 merged 2 commits into
NVIDIA:mainfrom
chuangz0:fix_token_range

Conversation

@chuangz0

@chuangz0 chuangz0 commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

_create_kv_slice set the default token_range.end to req.prompt_len + num_extra_kv_tokens, but the block list is trimmed to total_blocks = ceil(prompt_len / tpb). The sender re-derives per-layer token starts from token_range.end via total_blocks = ceil(end / tpb), so including num_extra_kv_tokens inflates total_blocks past the trimmed block count whenever the extra tokens cross a block boundary, mis-deriving token_start by one block and corrupting the transfer.

Set token_range.end to req.prompt_len so it matches the blocks actually sent. The extra blocks reserved for speculative decoding hold uninitialized KV and should not be transferred (see NVIDIA/TensorRT-LLM PR #14546 review discussion).

Update the unit tests: flip test_includes_num_extra_kv_tokens to test_excludes_num_extra_kv_tokens and add a block-boundary regression.

Summary by CodeRabbit

  • Bug Fixes

    • Improved prompt KV cache transfers so the default token range now stops at the prompt length, avoiding inclusion of extra speculative tokens.
    • Kept block transfer boundaries consistent when prompt lengths align with block sizes, reducing mismatches in reconstructed KV slices.
  • Tests

    • Updated unit coverage to reflect the new token range behavior and verify correct block-boundary handling.

Description

Description

KvCacheTransceiverV2._create_kv_slice sets the default token_range.end to
req.prompt_len + num_extra_kv_tokens, but the block list is independently
trimmed to total_blocks = (req.prompt_len + tpb - 1) // tpb. This makes the
slice metadata inconsistent with the blocks it carries: base/transfer.py
documents the contract total_blocks = ceil(token_range.end / tpb), and the
sender reconstructs total_blocks from token_range.end (native/transfer.py)
to derive per-layer token starts. When num_extra_kv_tokens pushes
token_range.end across a block boundary, the reconstructed count no longer
matches the trimmed block list.

Scope — this is a metadata/contract-consistency fix, not a data-movement
change.
The extra num_extra_kv_tokens blocks are already excluded from the
transfer by the existing block_ids[:total_blocks] trim, so which blocks get
sent does not depend on token_range.end. The inflated total_blocks only
shifts src_start and dst_start by the same delta, which cancels in
_align_kv_blocks (the sole asymmetric consumer, dst_start_token, is always
None). So no transfer is corrupted today; this fix restores the documented
invariant and removes a latent hazard that would surface if dst_start_token
becomes non-None, or if num_extra_kv_tokens > tokens_per_block combines with
asymmetric prefix reuse.

Set token_range.end = req.prompt_len so the metadata matches what is actually
transferred. Keeping the extra speculative-decoding blocks out of the transfer
is consistent with the review discussion in
https://github.com/NVIDIA/TensorRT-LLM/pull/14546/changes#r3386942085; the
accuracy impact on speculative decoding is not yet confirmed.

Test Coverage

  • tests/unittest/disaggregated/test_cache_reuse_adapter.py
    • test_includes_num_extra_kv_tokenstest_excludes_num_extra_kv_tokens
      (asserts token_range.end == prompt_len).
    • Added test_extra_tokens_do_not_cross_block_boundary (block-boundary
      consistency regression).
  • All 58 tests in the file pass.

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.

@chuangz0
chuangz0 requested a review from a team as a code owner July 1, 2026 09:15
@chuangz0
chuangz0 requested review from HuiGao-NV and yizhang-nv July 1, 2026 09:16
@chuangz0

chuangz0 commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes the default TokenRange end calculation in KvCacheTransceiverV2._create_kv_slice to use req.prompt_len instead of req.prompt_len + num_extra_kv_tokens, updates related inline documentation, and revises unit tests to validate the new default range and block-boundary consistency.

Changes

TokenRange calculation fix

Layer / File(s) Summary
Update default TokenRange end
tensorrt_llm/_torch/disaggregation/transceiver.py
Default TokenRange for prompt transfers now ends at req.prompt_len rather than req.prompt_len + num_extra_kv_tokens; comments updated to clarify that extra reserved KV positions are not transferred.
Update tests for new TokenRange contract
tests/unittest/disaggregated/test_cache_reuse_adapter.py
Replaces the prior assertion (end includes num_extra_kv_tokens) with a test confirming default end equals prompt_len, plus a new test verifying extra tokens do not cross a block boundary when prompt_len aligns to tokens_per_block.

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

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 follows the required [None][fix] template and accurately summarizes the KV slice metadata fix.
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 PR description follows the template well and includes the issue, solution, test coverage, and checklist confirmation.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@chuangz0
chuangz0 requested a review from Shixiaowei02 July 1, 2026 09:17
@chuangz0
chuangz0 force-pushed the fix_token_range branch 2 times, most recently from 3e54ed8 to a2052de Compare July 1, 2026 09:18
@Shixiaowei02

Copy link
Copy Markdown
Collaborator

Could you please simplify the comments? Thanks!

@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: 1

🤖 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 `@tests/unittest/disaggregated/test_cache_reuse_adapter.py`:
- Around line 334-348: The boundary regression test in
test_extra_tokens_do_not_cross_block_boundary currently assumes the helper still
produces a crossing case only because tokens_per_block happens to be 8. Harden
the setup by asserting the fixture conditions around
_build_transceiver_for_kv_slice and _create_kv_slice still force a
block-boundary crossing before the final equality check, so the test fails
loudly if tokens_per_block or the constructed prompt/extra-token lengths no
longer exercise the intended case.
🪄 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: d992714e-931e-457c-a3e3-a4efdcd95942

📥 Commits

Reviewing files that changed from the base of the PR and between 790c866 and a2052de.

📒 Files selected for processing (2)
  • tensorrt_llm/_torch/disaggregation/transceiver.py
  • tests/unittest/disaggregated/test_cache_reuse_adapter.py

Comment thread tests/unittest/disaggregated/test_cache_reuse_adapter.py
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #56896 [ run ] triggered by Bot. Commit: a2052de Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@chuangz0
chuangz0 force-pushed the fix_token_range branch 3 times, most recently from da73c60 to b3bed32 Compare July 2, 2026 02:41
@chuangz0

chuangz0 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --stage-list "DGX_B200-4_GPUs-AutoDeploy-1, DGX_B200-8_GPUs-PyTorch-4, GB200-4_GPUs-PyTorch-5, A30-PyTorch-1, DGX_B200-AutoDeploy-1, DGX_H100-PyTorch-1, RTX5090-PyTorch-1, DGX_H100-PyTorch-2"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57074 [ run ] triggered by Bot. Commit: b3bed32 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57074 [ run ] completed with state SUCCESS. Commit: b3bed32
/LLM/main/L0_MergeRequest_PR pipeline #45863 (Partly Tested) 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

@chuangz0

chuangz0 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --stage-list "DGX_B200-8_GPUs-PyTorch-4, DGX_B200-4_GPUs-AutoDeploy-1"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57314 [ run ] triggered by Bot. Commit: b3bed32 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57314 [ run ] completed with state FAILURE. Commit: b3bed32
/LLM/main/L0_MergeRequest_PR pipeline #46072 (Partly Tested) 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

@chuangz0

chuangz0 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --stage-list "DGX_B200-8_GPUs-PyTorch-4, DGX_B200-4_GPUs-AutoDeploy-1"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57429 [ run ] triggered by Bot. Commit: ebf427d Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57429 [ run ] completed with state SUCCESS. Commit: ebf427d
/LLM/main/L0_MergeRequest_PR pipeline #46170 (Partly Tested) completed with status: 'SUCCESS'

CI Report

Link to invocation

@chuangz0

chuangz0 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

/bot skip --comment " all tests have passed"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57652 [ skip ] triggered by Bot. Commit: a727d68 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57652 [ skip ] completed with state SUCCESS. Commit: a727d68
Skipping testing for commit a727d68

Link to invocation

Comment thread tensorrt_llm/_torch/disaggregation/transceiver.py
Comment thread tensorrt_llm/_torch/disaggregation/transceiver.py Outdated
@chuangz0
chuangz0 requested a review from a team as a code owner July 15, 2026 07:59
chuangz0 added 2 commits July 15, 2026 08:08
_create_kv_slice set the default token_range.end to
req.prompt_len + num_extra_kv_tokens, while the block list is trimmed to
total_blocks = ceil(prompt_len / tpb). The sender reconstructs total_blocks
from token_range.end via ceil(end / tpb) to derive per-layer token starts,
so the two block counts disagree whenever num_extra_kv_tokens pushes
token_range.end across a block boundary.

In current configurations the resulting offset is applied symmetrically to
the src and dst token starts and cancels in _align_kv_blocks, so no transfer
is corrupted today (dst_start_token is always None and num_extra_kv_tokens
is smaller than tokens_per_block). It is nonetheless a latent violation of
the KVSlice contract (total_blocks = ceil(token_range.end / tpb)) that would
surface if dst_start_token becomes non-None, or if num_extra_kv_tokens
exceeds tokens_per_block together with asymmetric prefix reuse.

Set token_range.end to req.prompt_len so it matches the trimmed block list.
Not transferring the extra speculative-decoding blocks follows the
NVIDIA/TensorRT-LLM PR NVIDIA#14546 review discussion; the accuracy impact on
speculative decoding is not yet confirmed.

Update tests: flip test_includes_num_extra_kv_tokens to
test_excludes_num_extra_kv_tokens and add a block-boundary regression.

Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
@chuangz0
chuangz0 enabled auto-merge (squash) July 15, 2026 08:24
@chuangz0

Copy link
Copy Markdown
Collaborator Author

/bot skip --comment "all tests have passed"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #59407 [ skip ] triggered by Bot. Commit: b308579 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #59407 [ skip ] completed with state SUCCESS. Commit: b308579
Skipping testing for commit b308579

Link to invocation

@chuangz0
chuangz0 merged commit ad440e3 into NVIDIA:main Jul 15, 2026
8 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