Skip to content

[https://nvbugs/6293536][fix] order KV cache transfers with overlap scheduler - #15349

Closed
VALLIS-NERIA wants to merge 2 commits into
NVIDIA:mainfrom
VALLIS-NERIA:nvbug-6293536-kv-transfer-ordering
Closed

[https://nvbugs/6293536][fix] order KV cache transfers with overlap scheduler#15349
VALLIS-NERIA wants to merge 2 commits into
NVIDIA:mainfrom
VALLIS-NERIA:nvbug-6293536-kv-transfer-ordering

Conversation

@VALLIS-NERIA

@VALLIS-NERIA VALLIS-NERIA commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Refs NVBUG 6293536

Summary

  • Record the overlap scheduler execution-stream tail before KVCM prepares the next batch.
  • Make KVCM offload/onboard streams wait on that event, and make the next forward stream wait on transfer-completion events.
  • Gate the host wait before refresh_blocks() on has_pending_transfers() so iterations without KV transfers keep the normal overlap path.

Details

The overlap scheduler can enter KVCM prepare while previous forward work is still queued on the execution stream. The previous implementation synchronized transfer streams through the buffer-manager stream only. This PR adds explicit event ordering for the transfer-manager path while keeping BufferManager off the execution stream.

Validation

  • python ./scripts/build_wheel.py --trt_root /usr/local/tensorrt --use_ccache -a "100-real;103-real" -s -j 64 --benchmarks --use_ccache --extra-cmake-vars NIXL_ROOT=/opt/nvidia/nvda_nixl
  • python3 -m py_compile tensorrt_llm/_torch/pyexecutor/resource_manager.py tensorrt_llm/_torch/pyexecutor/py_executor.py
  • python3 overlap-kvcm-repro.py --worker-url http://localhost:8000 --n-prefixes 12 --isl-reps 850 --concurrency 4 --rounds 100 (ok=400 err=0)
  • No .nvcudmp generated after the repro run.

Summary by CodeRabbit

  • New Features

    • Added capability to query pending host-device transfers in KV cache management system for improved operation visibility.
  • Improvements

    • Enhanced synchronization between GPU forward execution and KV cache resource preparation to ensure proper ordering of memory transfer operations and prevent race conditions.

@VALLIS-NERIA VALLIS-NERIA changed the title [NVBUG-6293536][fix] order KV cache transfers with overlap scheduler [https://nvbugs/6293536][fix] order KV cache transfers with overlap scheduler Jun 14, 2026
@VALLIS-NERIA
VALLIS-NERIA force-pushed the nvbug-6293536-kv-transfer-ordering branch from 0c409cc to ad5b49f Compare June 14, 2026 11:32

Copy link
Copy Markdown
Collaborator Author

Update after force-push to ad5b49f681:

  • Removed syncTransferManagerWithStream / sync_transfer_manager_with_stream; in the PyTorch V1 KVCM path the BufferManager stream is already the executor execution_stream, so refresh_blocks()->syncTransfers() already orders transfer completion before subsequent forward work on that stream.
  • Removed the temporary fine-grained KVCM.* NVTX ranges added for debugging.
  • The remaining ordering change is limited to making transfer streams wait on the previous execution-stream tail event, plus a host wait before refresh_blocks() only when KVCM has pending H2D/D2H transfers.

@VALLIS-NERIA
VALLIS-NERIA force-pushed the nvbug-6293536-kv-transfer-ordering branch from ad5b49f to 1a3eea5 Compare June 14, 2026 11:51

Copy link
Copy Markdown
Collaborator Author

Update after force-push to 1a3eea5871:

  • Reverted the KVCacheManager.prepare_resources() entry path back to sync_transfer_manager_with_buffer_manager(); the explicit sync_transfer_manager_with_event() API and binding were removed.
  • Tightened the pending-transfer guard to has_pending_host_transfers(), so the host wait before refresh_blocks() is only used after H2D/D2H-style transfers. D2D partial-copy traffic no longer triggers this guard.
  • Rebuilt with build_wheel, including nanobind regeneration.
  • Reran overlap-kvcm-repro.py --worker-url http://localhost:8000 --n-prefixes 12 --isl-reps 850 --concurrency 4 --rounds 100; result: ok=400 err=0.

@VALLIS-NERIA
VALLIS-NERIA marked this pull request as ready for review June 16, 2026 01:32
@VALLIS-NERIA
VALLIS-NERIA requested review from a team as code owners June 16, 2026 01:32
@VALLIS-NERIA
VALLIS-NERIA requested a review from Tabrizian June 16, 2026 01:32
@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54402 [ run ] triggered by Bot. Commit: 1a3eea5 Link to invocation

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a hasPendingHostTransfers() boolean query to KVCacheTransferManager that is set during onboard()/offload() for non-primary blocks and cleared on synchronization calls. The query propagates through WindowBlockManager, BlockManager, BaseKVCacheManager (pure virtual), and KVCacheManager, and is exposed to Python via nanobind. In the overlap executor loop, PyExecutor records a CUDA tail event on execution_stream and passes it to prepare_resources, which waits on it before refresh_blocks() when host transfers are pending.

Changes

KV cache pending host transfer query and stream synchronization

Layer / File(s) Summary
Transfer flag tracking in KVCacheTransferManager
cpp/include/tensorrt_llm/batch_manager/kvCacheTransferManager.h, cpp/tensorrt_llm/batch_manager/kvCacheTransferManager.cpp
Adds mHasPendingHostTransfers private member, sets it via |= in onboard() and offload() for non-primary blocks, clears it in both sync methods, and exposes it via hasPendingHostTransfers() const. Updates sync documentation for ordering dependency.
C++ class hierarchy API propagation
cpp/include/tensorrt_llm/batch_manager/kvCacheManager.h, cpp/tensorrt_llm/batch_manager/kvCacheManager.cpp
Declares hasPendingHostTransfers() on WindowBlockManager and BlockManager, adds pure-virtual on BaseKVCacheManager, implements on KVCacheManager forwarding to mBlockManager. BlockManager scans all window managers; WindowBlockManager delegates to mTransferManager.
Python nanobind bindings
cpp/tensorrt_llm/nanobind/batch_manager/kvCacheManager.cpp
Increments PyKvCacheManager trampoline count from 39 to 40, adds hasPendingHostTransfers() const override forwarding through NB_OVERRIDE_PURE, and registers has_pending_host_transfers on BaseKVCacheManager binding with GIL release.
Python executor stream synchronization
tensorrt_llm/_torch/pyexecutor/py_executor.py, tensorrt_llm/_torch/pyexecutor/resource_manager.py
KVCacheManager.prepare_resources and ResourceManager.prepare_resources gain optional forward_done_event. Before refresh_blocks(), waits on the event when has_pending_host_transfers() is true. PyExecutor adds _record_execution_stream_tail_event() and passes the event in the overlap loop.

Sequence Diagram(s)

sequenceDiagram
  participant PyExecutor
  participant execution_stream as CUDA execution_stream
  participant ResourceManager
  participant KVCacheManager as KVCacheManager (Python)
  participant BaseKVCacheManager as BaseKVCacheManager (C++)

  PyExecutor->>execution_stream: record Event → forward_done_event
  PyExecutor->>ResourceManager: prepare_resources(scheduled_batch, forward_done_event)
  ResourceManager->>BaseKVCacheManager: has_pending_host_transfers()
  BaseKVCacheManager-->>ResourceManager: bool
  alt has pending host transfers
    ResourceManager->>execution_stream: forward_done_event.wait()
  end
  ResourceManager->>KVCacheManager: refresh_blocks(scheduled_batch)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.71% 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 and specifically describes the main change: fixing KV cache transfer ordering with the overlap scheduler, using the proper bug tracking reference format.
Description check ✅ Passed The PR description comprehensively covers the issue, solution, and validation; however, the Test Coverage and PR Checklist sections required by the template are not explicitly filled out.
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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tensorrt_llm/_torch/pyexecutor/resource_manager.py (1)

990-993: ⚡ Quick win

Add explicit -> None return annotations to touched prepare_resources methods.

These signatures were modified and should include explicit return annotations for typing consistency.

As per coding guidelines: “Always annotate functions. Make the return type None if the function does not return anything.”

✍️ Suggested patch
-    def prepare_resources(
-            self,
-            scheduled_batch: ScheduledRequests,
-            forward_done_event: Optional[torch.cuda.Event] = None):
+    def prepare_resources(
+            self,
+            scheduled_batch: ScheduledRequests,
+            forward_done_event: Optional[torch.cuda.Event] = None) -> None:
@@
-    def prepare_resources(
-            self,
-            scheduled_batch: ScheduledRequests,
-            forward_done_event: Optional[torch.cuda.Event] = None):
+    def prepare_resources(
+            self,
+            scheduled_batch: ScheduledRequests,
+            forward_done_event: Optional[torch.cuda.Event] = None) -> None:

Also applies to: 3852-3855

🤖 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 `@tensorrt_llm/_torch/pyexecutor/resource_manager.py` around lines 990 - 993,
Add explicit `-> None` return type annotations to the `prepare_resources` method
signatures in the file tensorrt_llm/_torch/pyexecutor/resource_manager.py. At
the first location (lines 990-993), add `-> None` between the closing
parenthesis of the method parameters and the colon to complete the type
annotation. Apply the same change at the second location (lines 3852-3855) where
another `prepare_resources` method signature appears. Both method signatures
should follow the pattern of ending with `-> None:` to match the coding
guideline that all functions must have explicit return type annotations.

Source: Coding guidelines

🤖 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 `@tensorrt_llm/_torch/pyexecutor/py_executor.py`:
- Around line 3280-3283: The forward_done_event is recorded at line 3280 after
_prepare_and_schedule_batch() has already executed, but that method can invoke
_prepare_disagg_gen_init() which directly calls the KV cache manager's
prepare_resources() without the event, causing potential race conditions in
overlap mode. Move the _record_execution_stream_tail_event() call to execute
before _prepare_and_schedule_batch() is called, or thread the recorded event
through to _prepare_disagg_gen_init() so that the event is passed to all
prepare_resources() calls in both the main path and the disagg-gen-init path,
ensuring proper synchronization with the previous forward operation.

---

Nitpick comments:
In `@tensorrt_llm/_torch/pyexecutor/resource_manager.py`:
- Around line 990-993: Add explicit `-> None` return type annotations to the
`prepare_resources` method signatures in the file
tensorrt_llm/_torch/pyexecutor/resource_manager.py. At the first location (lines
990-993), add `-> None` between the closing parenthesis of the method parameters
and the colon to complete the type annotation. Apply the same change at the
second location (lines 3852-3855) where another `prepare_resources` method
signature appears. Both method signatures should follow the pattern of ending
with `-> None:` to match the coding guideline that all functions must have
explicit return type annotations.
🪄 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: 8caf2160-83af-40ef-9198-f7ab43cfd1cb

📥 Commits

Reviewing files that changed from the base of the PR and between 4f46653 and 1a3eea5.

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

Comment on lines +3280 to +3283
forward_done_event = self._record_execution_stream_tail_event(
)
self.resource_manager.prepare_resources(
scheduled_batch, forward_done_event)

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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Thread the tail event through the earlier disagg-gen-init prepare path.

Line 3280 records the event only after _prepare_and_schedule_batch() has already run, but that path can call _prepare_disagg_gen_init() and directly invoke KV cache manager prepare_resources(...) without the event. In overlap mode, that still lets KVCM prepare/refresh work race ahead of the previous forward queued on execution_stream.

Potential direction
-                scheduled_batch, iter_stats = self._prepare_and_schedule_batch()
+                forward_done_event = self._record_execution_stream_tail_event()
+                scheduled_batch, iter_stats = self._prepare_and_schedule_batch(
+                    forward_done_event
+                )
...
-                    forward_done_event = self._record_execution_stream_tail_event(
-                    )
                     self.resource_manager.prepare_resources(
                         scheduled_batch, forward_done_event)
-    def _prepare_and_schedule_batch(self):
+    def _prepare_and_schedule_batch(
+            self,
+            forward_done_event: Optional[torch.cuda.Event] = None):
...
-            self._prepare_disagg_gen_init(fitting_disagg_gen_init_requests)
+            self._prepare_disagg_gen_init(
+                fitting_disagg_gen_init_requests, forward_done_event)
-    def _prepare_disagg_gen_init(self, fitting_disagg_gen_init_requests):
+    def _prepare_disagg_gen_init(
+            self,
+            fitting_disagg_gen_init_requests,
+            forward_done_event: Optional[torch.cuda.Event] = None):
...
-                    self.resource_manager.resource_managers[
-                        resource_mgr_type].prepare_resources(
-                            disagg_gen_init_to_prepare)
+                    manager = self.resource_manager.resource_managers[
+                        resource_mgr_type]
+                    if resource_mgr_type == ResourceManagerType.KV_CACHE_MANAGER:
+                        manager.prepare_resources(
+                            disagg_gen_init_to_prepare, forward_done_event)
+                    else:
+                        manager.prepare_resources(disagg_gen_init_to_prepare)
🤖 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 `@tensorrt_llm/_torch/pyexecutor/py_executor.py` around lines 3280 - 3283, The
forward_done_event is recorded at line 3280 after _prepare_and_schedule_batch()
has already executed, but that method can invoke _prepare_disagg_gen_init()
which directly calls the KV cache manager's prepare_resources() without the
event, causing potential race conditions in overlap mode. Move the
_record_execution_stream_tail_event() call to execute before
_prepare_and_schedule_batch() is called, or thread the recorded event through to
_prepare_disagg_gen_init() so that the event is passed to all
prepare_resources() calls in both the main path and the disagg-gen-init path,
ensuring proper synchronization with the previous forward operation.

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54402 [ run ] completed with state FAILURE. Commit: 1a3eea5
/LLM/main/L0_MergeRequest_PR pipeline #43468 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

Signed-off-by: Xiwen Yu <13230610+VALLIS-NERIA@users.noreply.github.com>
@VALLIS-NERIA
VALLIS-NERIA force-pushed the nvbug-6293536-kv-transfer-ordering branch from 1a3eea5 to 219e2a7 Compare June 16, 2026 04:02
@VALLIS-NERIA
VALLIS-NERIA requested review from a team as code owners June 16, 2026 04:02
@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54482 [ run ] triggered by Bot. Commit: 219e2a7 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54482 [ run ] completed with state FAILURE. Commit: 219e2a7
/LLM/main/L0_MergeRequest_PR pipeline #43544 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

Signed-off-by: Xiwen Yu <13230610+VALLIS-NERIA@users.noreply.github.com>
@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54805 [ run ] triggered by Bot. Commit: 3c36080 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #54805 [ run ] completed with state SUCCESS. Commit: 3c36080
/LLM/main/L0_MergeRequest_PR pipeline #43821 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

@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator Author

We have a real fix now #15546

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