Skip to content

[None][feat] Add shared KV runtime assembly - #20266

Draft
chienchunhung wants to merge 2 commits into
NVIDIA:mainfrom
chienchunhung:dev/ri-01-canonical-projection
Draft

chienchunhung wants to merge 2 commits into
NVIDIA:mainfrom
chienchunhung:dev/ri-01-canonical-projection

Conversation

@chienchunhung

@chienchunhung chienchunhung commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Add private runtime assembly for shared KV transfers. Use canonical lender views and bind consuming write returns to the originating lender.

Scope

  • Assembly and profile checks derive content identity from model provenance and writer semantics, preserve the complete region namespace, and validate the initial single-rank BF16 MHA HOST/NAMED profile.
  • Pass lender views through unchanged. Canonical region records own their geometry validation.
  • Add a bound write-return endpoint that forwards the exact masks and reuse permission, retains its lender, and propagates errors without retry.
  • Cover identity, placement, ownership, and real-manager return/progress behavior. Align an inherited test fixture with main to avoid duplicate arguments during automatic merges.

No provider is activated. Request orchestration, DEVICE activation, provider qualification, and qualified nonfatal containment remain separate integration work.

Verification

Revision: dce241c32ab9b8b61fc40589274680d5ab734dbc.

  • 823 passed, 0 failed, 4 skipped on NVIDIA A30, using normal pytest imports and plugins. All four real-manager tests and every changed test passed.
  • Ran the staging/runtime projection, backend/public contract, lender, generation, capacity, and forward-error survival suites with python3 -m pytest -c tests/unittest/pytest.ini -v -ra. The four skips are inherited Blackwell-only foundation cases.
  • The previously failing A30 test also passed in isolation. Full CI test ordering was not reproduced.
  • Used the native wheel built for [TRTLLM-16186][feat] Lend KV cache pages and recurrent state in place #20534 at bc07138a5; candidate native/build sources match that foundation. This is not provider or multi-rank qualification.
  • Repository hooks, GitHub pre-commit/DCO/metadata checks, and a fresh independent review passed. Full CI launched; results are pending.

Notes

Based on #20534 at bc07138a5f8ca79088a9a6c1aece3eebdd9d95ed; #20117 is already merged in that base. #20534 must land first.

One implementation commit follows the lender prerequisite. Implementation-only diff.

  • Contribution checklist reviewed: private interfaces, focused tests, no new dependencies or public configuration fields.

@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #77703 [ run ] triggered by Bot. Commit: 8079d06 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #77703 [ run ] completed with state SUCCESS. Commit: 8079d06
/LLM/main/L0_MergeRequest_PR pipeline #64057 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

@chienchunhung
chienchunhung force-pushed the dev/ri-01-canonical-projection branch from 8079d06 to 13eb253 Compare October 14, 2026 23:29
@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #77928 [ run ] triggered by Bot. Commit: 13eb253 Link to invocation

@chienchunhung
chienchunhung force-pushed the dev/ri-01-canonical-projection branch from 13eb253 to f01ed34 Compare October 15, 2026 00:22
@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #77935 [ run ] triggered by Bot. Commit: f01ed34 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github/20266-13eb253 #77928 was force-killed by a newer pipeline run.
L0 job information not available (job may not have been triggered yet).

Link to superseding invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tests/unittest/_torch/executor/kv_cache/sharing/test_runtime_projection.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tests/unittest/_torch/disaggregation/test_backend_contract.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
@Shixiaowei02
Shixiaowei02 requested a review from bo-nv October 15, 2026 08:54
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/resource/staging.py Outdated
@chienchunhung
chienchunhung force-pushed the dev/ri-01-canonical-projection branch from f01ed34 to a9854b9 Compare October 15, 2026 23:09
@chienchunhung chienchunhung changed the title [None][feat] Add canonical shared KV staging projection (RI-01) [None][feat] Add shared KV runtime assembly (RI-01) Oct 15, 2026
@chienchunhung
chienchunhung force-pushed the dev/ri-01-canonical-projection branch from a9854b9 to cea5825 Compare October 15, 2026 23:17

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@chienchunhung
chienchunhung force-pushed the dev/ri-01-canonical-projection branch from cea5825 to 27ce45d Compare October 15, 2026 23:35

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@chienchunhung
chienchunhung force-pushed the dev/ri-01-canonical-projection branch from c318349 to 9e91263 Compare October 21, 2026 01:17
@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #79460 [ run ] triggered by Bot. Commit: 9e91263 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #79460 [ run ] completed with state SUCCESS. Commit: 9e91263
/LLM/main/L0_MergeRequest_PR pipeline #65442 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

"compatibility_id": profile.compatibility_id,
"writer_layout": profile.model_layout,
"cache_dtype": profile.dtype,
"attention": {"full": True, "sparse": False, "sink_tokens": 0},

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.

The lender leaves windows, sinks, sparsity, LoRA and draft facts to this scope, and its layout id deliberately excludes them, yet here they are constants. Widening the profile later without touching this function would silently share bytes between different configurations. Suggest deriving each from its field, with a test that each one changes the scope.

retain their exact access/registration meaning.
"""

BackendFactory = Callable[[tuple[SlotRegion, ...], WakeFn, object, OwnerCleanupFn], Backend]

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.

With this signature each factory captures lender access privately. Suggest a data-only factory, __call__(inputs: BackendInputs) -> BuiltBackend, so no factory can reach lend_*: inputs carry regions, page layout, meaning digest, device, hold entry, wake, trip, lease limit, trusted registry and config, and BuiltBackend returns the backend with its hint factory.

if TYPE_CHECKING:
from tensorrt_llm._torch.pyexecutor.kv_cache.kv_cache_manager_v2 import KVCacheManagerV2

OwnerCleanupFn = Callable[[Callable[[], None]], bool]

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.

With this dispatcher every provider decides when its hold may be released. This supersedes the earlier finalizer suggestion: the factory takes the hold through inputs.take_hold() before registering anything, the assembly keeps it, and the holder calls release_hold() only once that binding's shutdown() returns empty with no lease unreturned.

"""
if not isinstance(profile, ProfileSpec):
raise TypeError("profile must be ProfileSpec")
lender = attach_lender(manager, scope=profile.scope, staging=profile.staging)

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.

This attaches the lender for one store profile on this rank alone, and a failed profile check leaves it attached. Suggest a small private attach module, called from the assembly entry, whose outcome is agreed across ranks before any binding is built: a failure on any rank fails startup everywhere.



@dataclass(frozen=True)
class RegionNamespace:

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.

This fixes one memory kind per lender, yet one lender serves every binding: native peers take DEVICE/ALL leases, stores HOST/NAMED. Suggest making the kind a binding property: a routing table maps direction, lending method, row selection and kind to a binding, and each factory registers only the kinds it declares.

object.__setattr__(self, "scope", derive_kv_scope(self))


def derive_kv_scope(profile: ProfileSpec) -> bytes:

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.

Every attach needs a scope, native-only ones included. Superseding the earlier placement, suggest moving derive_kv_scope to tensorrt_llm/_torch/disaggregation/kv_scope.py, one rule for P and D, over the KV-meaning parts of SourceIdentity (not GEMM, fusion or allreduce choices), checkpoint revision or commit, writer layout, cache dtype, speculative mode, draft pool and lora_enabled.

normal shutdown, without retrying attachment or detaching the lender.

Args:
manager: Serving manager, never a sizing probe.

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.

Once native peers use the lender, the capacity-estimation executor is assembled too, registering backends during sizing. Suggest two rules: its shutdown report must be clean, every binding's shutdown() empty and hold released, or startup fails; and a single_instance factory refuses a new instance while the previous one lives.

"draft_pool": None,
}
encoded = json.dumps(payload, sort_keys=True, separators=(",", ":"), allow_nan=False)
return b"trtllm-kv-scope-v1\0" + hashlib.sha256(encoded.encode("utf-8")).digest()

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.

The scope reaches only the lender's object names, so rows lent in place between peers are never checked against it. Suggest a meaning digest, the scope plus layout declarations that change what bytes mean, that every backend compares with each peer at first contact, refusing a mismatch with a reason.

return DomainBinding(lender, profile, namespace)


def check_view_compatibility(lease_view: LeaseView, namespace: RegionNamespace) -> None:

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.

This per-lease check refuses every row without keys or addresses, which is every in-place DEVICE row. Suggest removing it: routing matches memory kinds, factories register only accessible regions, and the next #20534 update has the lender validate region geometry and overlap at attach, so RegionNamespace can go too.

scope: bytes = field(init=False)

def __post_init__(self) -> None:
"""Reject unsupported facts before any memory or backend exposure."""

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.

Configurations not yet served are better refused in the assembly, before any attach, naming every reason in one error: a manager other than KVCacheManagerV2, CSA2 until generation computes the remote tail, and a remote cache beside a KV connector that loads KV. This supersedes failing at config load.

The initial profile consumes HOST/NAMED leases from the lender's complete mixed
memory namespace. Model provenance and writer facts derive its canonical scope;
public layout and region facts validate the serving profile. Neither
a provider name nor a caller-supplied hint establishes compatibility or isolation.

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.

Nothing here builds hints or vets their endpoints. Suggest each backend family hand over a hint factory, which orchestration calls with a pairing key and the peer's entry, and one trusted endpoint registry owned by the assembly: orchestration checks hint endpoints against it, and each backend checks again.

raise TypeError("sink_token_length must be an integer")
if self.sink_token_length != 0:
raise ValueError("initial profile excludes attention sinks")
if self.lora_enabled is not False:

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.

Refusing lora_enabled disables remote reuse for every LoRA deployment, though many requests lack adapters. Suggest a per-request bypass: orchestration neither lends, fetches nor publishes for requests with a lora_task_id, so no request reads another adapter's bytes. lora_enabled still enters the scope, so deployments with and without LoRA never share names.

Comment thread tests/unittest/_torch/executor/kv_cache/sharing/test_runtime_projection.py Outdated
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Private runtime assembly shared by transfer and Store integrations.

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.

Suggest making this module the single construction point: one entry per executor attaches the lender, agrees the outcome across ranks, and builds every backend and routing once. Reason: with construction split across modules, run-time code can create or swap backends, and ownership and shutdown order lose one source of truth.



@dataclass(frozen=True)
class DomainBinding:

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.

Suggest dropping the per-profile binding: keep one lender record per KV manager, and put records shared by construction, holding and request handling in a small private module that none of them owns. Reason: tying the lender to one store profile breaks once another backend kind shares the same pages.

"""

id: str
lifecycle_profile_id: str

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.

Suggest dropping lifecycle_profile_id and choosing containment per backend from what that backend can prove: a backend that can isolate a failed peer keeps serving, and one that cannot is stopped as a whole. Reason: a per-profile policy ties safety to deployment shape rather than to the evidence a backend provides.

draft_pool: SourceIdentity | None
joint_reuse: bool
staging: StagingOptions
backend_config: object = None

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.

Suggest configuring each backend instance separately, with its own settings and lease limit read once at construction. Reason: one lender serves several backends at once, such as peers plus one or more stores, and a single opaque profile-level configuration cannot express their different limits or failure behavior.

Signed-off-by: Shixiaowei02 <39303645+Shixiaowei02@users.noreply.github.com>
@chienchunhung
chienchunhung force-pushed the dev/ri-01-canonical-projection branch from 9e91263 to 1a5fc31 Compare October 23, 2026 23:08
@chienchunhung chienchunhung changed the title [None][feat] Add shared KV runtime assembly (RI-01) [None][feat] Add shared KV runtime assembly Oct 23, 2026
Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
@chienchunhung
chienchunhung force-pushed the dev/ri-01-canonical-projection branch from 1a5fc31 to dce241c Compare October 23, 2026 23:15

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #80286 [ run ] triggered by Bot. Commit: dce241c Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants