Skip to content

[None][fix] Batch addSequence with pre-claim to fix host offloading M…#12892

Open
liji-nv wants to merge 1 commit intoNVIDIA:mainfrom
liji-nv:fix/batch-addsequence-mnt-overflow-v2
Open

[None][fix] Batch addSequence with pre-claim to fix host offloading M…#12892
liji-nv wants to merge 1 commit intoNVIDIA:mainfrom
liji-nv:fix/batch-addsequence-mnt-overflow-v2

Conversation

@liji-nv
Copy link
Copy Markdown
Collaborator

@liji-nv liji-nv commented Apr 9, 2026

…NT overflow

When host offloading is enabled, onboarding a host block to GPU during addSequence can trigger eviction of other reusable host blocks from the radix tree. This causes actual KV cache reuse to be less than the scheduler estimated, leading to max_num_tokens (MNT) overflow assertions.

Add a new addSequenceBatch API that processes all first-chunk context requests in two phases:

  • Phase 1: Walk the radix tree and claimBlock() for all matching blocks across all requests. No onboarding, no allocation. This protects reusable blocks from eviction.
  • Phase 2: Onboard host blocks and allocate non-matching blocks. Since all reusable blocks are already claimed, evictions during onboarding cannot touch them.

On the Python side, replace the TOCTOU-prone revalidation loop (count_reusable_blocks + budget check) with a single batch call.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added batch sequence onboarding API for improved KV cache management, enabling more efficient allocation and reuse of cache blocks for multiple concurrent sequences.

Description

Test Coverage

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)

  • 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.

@liji-nv liji-nv requested a review from a team as a code owner April 9, 2026 14:01
@liji-nv
Copy link
Copy Markdown
Collaborator Author

liji-nv commented Apr 9, 2026

/bot run

@tensorrt-cicd
Copy link
Copy Markdown
Collaborator

PR_Github #42543 [ run ] triggered by Bot. Commit: 2344609 Link to invocation

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

Introduces a new two-phase batch sequence onboarding API for KV cache management. Phase 1 claims matching cached blocks under lock; Phase 2 onboards and allocates remaining blocks. Adds corresponding methods to WindowBlockManager, BlockManager, BaseKVCacheManager, and KVCacheManager classes, along with Python bindings and integration into the resource manager's context allocation path when block reuse is enabled.

Changes

Cohort / File(s) Summary
KV Cache Manager Core
cpp/include/tensorrt_llm/batch_manager/kvCacheManager.h, cpp/tensorrt_llm/batch_manager/kvCacheManager.cpp
Added two-phase batch sequence onboarding: new ClaimResult struct and three methods (claimMatchingBlocks, onboardAndAllocateBlocks, addSequenceBatch) in WindowBlockManager; addSequenceBatch delegation in BlockManager; new pure virtual addSequenceBatch in BaseKVCacheManager and implementation in KVCacheManager with input validation, sequence creation, cache offset updates, and statistics tracking.
Python Bindings
cpp/tensorrt_llm/nanobind/batch_manager/kvCacheManager.cpp
Added add_sequence_batch Python-exposed binding method on BaseKVCacheManager that marshals list arguments into C\+\+ tuples and reference vectors, forwarding to the underlying C\+\+ implementation.
Resource Manager Integration
tensorrt_llm/_torch/pyexecutor/resource_manager.py
Modified prepare_resources method to conditionally batch eligible first-context-chunk requests when block reuse is enabled, calling add_sequence_batch() once per batch instead of per-request add_sequence calls, while preserving the original path for non-block-reuse scenarios.

Sequence Diagram(s)

sequenceDiagram
    participant ResourceMgr as Resource Manager
    participant KVCacheMgr as KVCacheManager
    participant BlockMgr as BlockManager
    participant WindowBlockMgr as WindowBlockManager
    
    ResourceMgr->>KVCacheMgr: addSequenceBatch(requestInfos, llmRequests)
    
    activate KVCacheMgr
    KVCacheMgr->>KVCacheMgr: Validate constraints (block reuse enabled)
    KVCacheMgr->>KVCacheMgr: Create GenerationRequest sequences<br/>Compute inputLengths & numContextBlocksVec
    KVCacheMgr->>BlockMgr: addSequenceBatch(sequences, inputLengths,<br/>numContextBlocksVec, llmRequests, windowSize)
    
    activate BlockMgr
    BlockMgr->>WindowBlockMgr: addSequenceBatch(...)
    
    activate WindowBlockMgr
    WindowBlockMgr->>WindowBlockMgr: Acquire mCachedBlocksRootMutex
    
    loop For each sequence (Phase 1)
        WindowBlockMgr->>WindowBlockMgr: claimMatchingBlocks(sequence, inputLength,<br/>numContextBlocks, llmRequest)
        note over WindowBlockMgr: Radix-tree walk, claim blocks,<br/>update priorities
    end
    
    loop For each sequence (Phase 2)
        WindowBlockMgr->>WindowBlockMgr: onboardAndAllocateBlocks(sequence,<br/>llmRequest, claimResult)
        note over WindowBlockMgr: Onboard copied blocks, allocate<br/>non-matching & non-shared blocks,<br/>finalize prepopulated length
    end
    
    WindowBlockMgr->>WindowBlockMgr: Release mCachedBlocksRootMutex
    WindowBlockMgr-->>BlockMgr: Return prepopulated lengths
    deactivate WindowBlockMgr
    
    BlockMgr-->>KVCacheMgr: Return prepopulated lengths
    deactivate BlockMgr
    
    KVCacheMgr->>KVCacheMgr: Update per-window cache offsets
    KVCacheMgr->>KVCacheMgr: Set llmRequest prepopulated<br/>prompt lengths & clear reusable tokens
    KVCacheMgr-->>ResourceMgr: Return (batch complete)
    deactivate KVCacheMgr
    
    ResourceMgr->>ResourceMgr: Apply per-token add_token calls<br/>& KV connector updates
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title concisely summarizes the main change: batching addSequence with pre-claim to fix host offloading MNT overflow. It clearly identifies this as a fix and captures the key technical approach.
Description check ✅ Passed The PR description comprehensively explains the problem (host offloading eviction causing MNT overflow), the solution (two-phase batch API with pre-claiming), and implementation details on both C++ and Python sides. However, the description is provided outside the template structure with no explicit Test Coverage or Checklist sections completed.

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cpp/include/tensorrt_llm/batch_manager/kvCacheManager.h`:
- Around line 1789-1796: The Python trampoline class PyKvCacheManager is missing
a pure-virtual override for the new C++ method addSequenceBatch, causing Python
subclasses not to dispatch; add an override method in PyKvCacheManager with the
signature matching addSequenceBatch that calls
NB_OVERRIDE_PURE(addSequenceBatch, requestInfos, llmRequests), and increment the
NB_TRAMPOLINE count for tbk::BaseKVCacheManager from 36 to 37 so the trampoline
table matches the new virtual. Ensure the override uses the exact parameter
types (std::vector<std::tuple<tb::LlmRequest::RequestIdType, SizeType32,
SizeType32>> const& requestInfos and
std::vector<std::reference_wrapper<tb::LlmRequest>> const& llmRequests) and that
NB_TRAMPOLINE is updated accordingly.

In `@cpp/tensorrt_llm/batch_manager/kvCacheManager.cpp`:
- Around line 3408-3411: The current approach captures baseline totals in
numAllocTotalBlocksPre, numAllocNewBlocksPre, numReusedBlocksPre and
numMissedBlocksPre once for the whole batch and then computes per-request stats
by subtracting those global baselines, which causes earlier requests' work to be
attributed to later ones; instead compute per-request deltas either by
snapshotting the totals immediately before and after processing each individual
request (or at the exact request completion point) or by recording increments
during Phase 2 as each request performs allocations/reuses/misses; update the
logic in
updateAllocTotalPerRequest/updateAllocNewPerRequest/updateReusedPerRequest/updateMissedPerRequest
to use these per-request snapshots or Phase 2 counters rather than the
single-batch pre-snap variables so each request only accounts for its own
changes.
- Around line 3387-3449: Before calling mBlockManager.addSequenceBatch in
KVCacheManager::addSequenceBatch, enforce the same recurrent-state chunking
guard that WindowBlockManager::addSequence rejects: for each request, if its
kvCacheRetentionConfig indicates a recurrent-state retention mode and
inputLength != llmRequest.getPromptLen(), fail early (use TLLM_CHECK_WITH_INFO
or similar) with a message that batched recurrent-state requests must have
inputLength equal to the prompt length; perform this check using the
already-captured kvCacheRetentionConfig and llmRequest variables for each index
prior to invoking mBlockManager.addSequenceBatch.

In `@cpp/tensorrt_llm/nanobind/batch_manager/kvCacheManager.cpp`:
- Around line 396-413: The lambda bound to "add_sequence_batch" currently uses
nb::call_guard<nb::gil_scoped_release>() which drops the GIL for the entire body
and makes nb::len, list indexing, and nb::cast calls unsafe; change the
implementation so the GIL is held while marshalling the Python inputs into the
C++ locals (i.e., build requestInfos and llmRequests using nb::len, nb::cast,
nb::tuple, nb::list, std::ref) and only release the GIL immediately before
calling BaseKVCacheManager::addSequenceBatch (call self.addSequenceBatch under a
scoped GIL release). Ensure nb::call_guard<nb::gil_scoped_release>() is applied
only around the actual addSequenceBatch invocation or use an explicit
gil_scoped_release scope for that call.

In `@tensorrt_llm/_torch/pyexecutor/resource_manager.py`:
- Around line 644-678: The batching path currently calls
impl.add_sequence_batch(batch_request_infos, batch_llm_requests) for block-reuse
requests which breaks VSWA; change the control so batching only happens when
self.is_vswa is False (i.e., gate the add_sequence_batch call with not
self.is_vswa) and if self.is_vswa is True, fall back to the per-request
impl.add_sequence(...) flow used earlier (including the subsequent
impl.add_token(...) loops and kv_connector_manager.update_state_after_alloc
calls for each req). Ensure the logic around enable_block_reuse,
batch_request_infos, batch_llm_requests and batch_ctx_requests remains
consistent so VSWA continues using the single-request path.
🪄 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: Pro

Run ID: 21f2daa7-dcc7-468a-a725-8af6a3a2a2f3

📥 Commits

Reviewing files that changed from the base of the PR and between 3e942cc and 2344609.

📒 Files selected for processing (4)
  • cpp/include/tensorrt_llm/batch_manager/kvCacheManager.h
  • cpp/tensorrt_llm/batch_manager/kvCacheManager.cpp
  • cpp/tensorrt_llm/nanobind/batch_manager/kvCacheManager.cpp
  • tensorrt_llm/_torch/pyexecutor/resource_manager.py

@tensorrt-cicd
Copy link
Copy Markdown
Collaborator

PR_Github #42543 [ run ] completed with state FAILURE. Commit: 2344609
/LLM/main/L0_MergeRequest_PR pipeline #33280 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

Link to invocation

@liji-nv liji-nv force-pushed the fix/batch-addsequence-mnt-overflow-v2 branch 2 times, most recently from 9d5acd8 to a9a7f73 Compare April 10, 2026 02:56
…NT overflow

When host offloading is enabled, onboarding a host block to GPU during
addSequence can trigger eviction of other reusable host blocks from
the radix tree. This causes actual KV cache reuse to be less than the
scheduler estimated, leading to max_num_tokens (MNT) overflow assertions.

Add a new addSequenceBatch API that processes all first-chunk context
requests in two phases:
- Phase 1: Walk the radix tree and claimBlock() for all matching blocks
  across all requests. No onboarding, no allocation. This protects
  reusable blocks from eviction.
- Phase 2: Onboard host blocks and allocate non-matching blocks. Since
  all reusable blocks are already claimed, evictions during onboarding
  cannot touch them.

On the Python side, replace the TOCTOU-prone revalidation loop
(count_reusable_blocks + budget check) with a single batch call.

Signed-off-by: Jin Li <59594262+liji-nv@users.noreply.github.com>
@liji-nv liji-nv force-pushed the fix/batch-addsequence-mnt-overflow-v2 branch from a9a7f73 to e5d8513 Compare April 10, 2026 04:48
@liji-nv
Copy link
Copy Markdown
Collaborator Author

liji-nv commented Apr 10, 2026

/bot run

@tensorrt-cicd
Copy link
Copy Markdown
Collaborator

PR_Github #42669 [ run ] triggered by Bot. Commit: e5d8513 Link to invocation

@tensorrt-cicd
Copy link
Copy Markdown
Collaborator

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

Link to invocation

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants