Skip to content

[None][chore] Replace cache_salt_id impl with main's TreeTaskId (cp #13793) - #14351

Merged
pcastonguay merged 3 commits into
NVIDIA:feat/deepseek_v4from
lancelly:feat/dsv4-align-kvcm-with-main
May 21, 2026
Merged

[None][chore] Replace cache_salt_id impl with main's TreeTaskId (cp #13793)#14351
pcastonguay merged 3 commits into
NVIDIA:feat/deepseek_v4from
lancelly:feat/dsv4-align-kvcm-with-main

Conversation

@lancelly

@lancelly lancelly commented May 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Replaces feat/deepseek_v4's parallel cache_salt_id impl (introduced as a side effect of PR #13624 / commit 07adb42, which mainly added V1↔V2 KV event hash matching) with main's TreeTaskId abstraction from PR #13793.

Both implementations achieve identical user-visible behavior (per-request salt-based KV cache reuse isolation). The differences are internal:

DSv4 (before) this PR (after)
Radix tree knows lora_task_id + cache_salt_id as 2 fields opaque tree_task_id: int | bytes | None
Hash mixing inside the tree, via _make_root_key + tag bytes above the tree, in _KVCache._make_tree_task_id
RootBlock stores both fields stores single tree_task_id

The opaque-seed shape allows mixing future dimensions (e.g. multi-modal digest) without changing the tree. It is also the prerequisite for cherry-picking PR #14140 (ReuseScope NamedTuple refactor) and PR #14333 (KV cache reuse probe), which will follow in subsequent PRs.

Conflict resolution notes

  • Dummy/warmup requests: adopted main's design — no salt on dummies. Rationale: dummy paths stop_committing() anyway so the salt choice is inert, but explicitly passing None avoids coupling synthetic data to any salted branch.
  • IndexMapper saturation guard: kept DSv4's None-return path in _create_kv_cache (needed for disagg gen-trans-in-progress requests).
  • Event manager / try_get_tree / other DSv4 hooks: preserved verbatim in the touched files — git auto-merge handled these because [None][feat] Support cache_salt_id in KV cache v2 manager #13793 does not touch the same lines.

@lancelly lancelly changed the title [None][chore] DSv4: replace cache_salt_id impl with main's TreeTaskId (cp #13793) [None][chore] Replace cache_salt_id impl with main's TreeTaskId (cp #13793) May 20, 2026
@lancelly

Copy link
Copy Markdown
Collaborator Author

@peihu-nv and @eopXD Could you please take a look at this PR? Currently the salt implementation seems to diverge on feat/deepseek_v4 and main branch. To cherry-pick other kv manager related code onto feat/deepseek_v4, we need to resolve this conflict first.

Signed-off-by: Yueh-Ting Chen <yueh.ting.chen@gmail.com>
(cherry picked from commit 4baeec3)
Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
@lancelly
lancelly force-pushed the feat/dsv4-align-kvcm-with-main branch from 0d9c7b9 to e457809 Compare May 20, 2026 10:23
@lancelly
lancelly marked this pull request as ready for review May 20, 2026 15:14
@lancelly
lancelly requested review from a team as code owners May 20, 2026 15:14
@lancelly
lancelly requested review from joyang-nv, laikhtewari and nv-guomingz and removed request for a team May 20, 2026 15:14
@lancelly

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@peihu-nv peihu-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.

Direction LGTM, approving to unblock the stack assuming follow up PR to land right after.

  • Seems to me that test_v2_root_key_distinguishes_lora_from_cache_salt_id still calls RootBlock.make_key(None, None), now it is a single arg.
  • _event_manager._root_attrs_from_root_block still reads lora_task_id/cache_salt_id off RootBlock, but this PR removes both → silently (None, None) for every event → V1-compat hashes break for any LoRA/salt request and Dynamo routing degrades. Not sure if dropping V1 compat is intentional or might need to address this in the ReuseScope follow-up (root.reuse_scope.lora_id/.salt).

@peihu-nv

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49467 [ run ] triggered by Bot. Commit: e457809 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request May 21, 2026
After NVIDIA#14140 (cherry-picked in NVIDIA#14353) RootBlock no longer exposes
``lora_task_id`` / ``cache_salt_id`` directly — both fields are folded
into a ``ReuseScope`` NamedTuple attached as ``root.reuse_scope``.
``KVCacheEventManager._root_attrs_from_root_block`` was still reading
the legacy attribute names via ``getattr(..., None)``, so every emitted
event silently received ``(None, None)`` and the V1-compat hash
collapsed to the same value for any LoRA/salt request. Downstream
Dynamo routing depends on those hashes, so this regression would
materially degrade prefix cache hit rate for any request carrying a
LoRA task id or a cache salt.

Fix ``_root_attrs_from_root_block`` to prefer ``root.reuse_scope`` and
fall back to the legacy attributes (keeps any in-flight pre-refactor
RootBlock instances working).

Also:
- Update the now-stale ``test_v2_root_key_distinguishes_lora_from_cache_salt_id``
  to use the new single-arg ``RootBlock.make_key(ReuseScope(...))`` API.
- Extend ``_FakeRootBlock`` with an optional ``reuse_scope`` kwarg so
  tests can mimic both the pre- and post-refactor RootBlock shape.
- Add a regression test ``test_v2_kv_cache_event_manager_v1_hash_reads_root_reuse_scope``
  that asserts (a) a ReuseScope-shaped root and a legacy root with the
  same lora/salt produce identical V1 event hashes, (b) different
  scopes still produce different hashes (no silent collapse), and
  (c) an empty ReuseScope matches a legacy root with no salt/lora.

Addresses reviewer feedback on NVIDIA#14351 (peihu-nv).

Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request May 21, 2026
After NVIDIA#14140 (cherry-picked in NVIDIA#14353) RootBlock no longer exposes
``lora_task_id`` / ``cache_salt_id`` directly — both fields are folded
into a ``ReuseScope`` NamedTuple attached as ``root.reuse_scope``.
``KVCacheEventManager._root_attrs_from_root_block`` was still reading
the legacy attribute names via ``getattr(..., None)``, so every emitted
event silently received ``(None, None)`` and the V1-compat hash
collapsed to the same value for any LoRA/salt request. Downstream
Dynamo routing depends on those hashes, so this regression would
materially degrade prefix cache hit rate for any request carrying a
LoRA task id or a cache salt.

Fix ``_root_attrs_from_root_block`` to prefer ``root.reuse_scope`` and
fall back to the legacy attributes (keeps any in-flight pre-refactor
RootBlock instances working).

Also:
- Update the now-stale ``test_v2_root_key_distinguishes_lora_from_cache_salt_id``
  to use the new single-arg ``RootBlock.make_key(ReuseScope(...))`` API.
- Extend ``_FakeRootBlock`` with an optional ``reuse_scope`` kwarg so
  tests can mimic both the pre- and post-refactor RootBlock shape.
- Add a regression test ``test_v2_kv_cache_event_manager_v1_hash_reads_root_reuse_scope``
  that asserts (a) a ReuseScope-shaped root and a legacy root with the
  same lora/salt produce identical V1 event hashes, (b) different
  scopes still produce different hashes (no silent collapse), and
  (c) an empty ReuseScope matches a legacy root with no salt/lora.

Addresses reviewer feedback on NVIDIA#14351 (peihu-nv).

Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request May 21, 2026
After NVIDIA#14140 (cherry-picked in NVIDIA#14353) RootBlock no longer exposes
``lora_task_id`` / ``cache_salt_id`` directly — both fields are folded
into a ``ReuseScope`` NamedTuple attached as ``root.reuse_scope``.
``KVCacheEventManager._root_attrs_from_root_block`` was still reading
the legacy attribute names via ``getattr(..., None)``, so every emitted
event silently received ``(None, None)`` and the V1-compat hash
collapsed to the same value for any LoRA/salt request. Downstream
Dynamo routing depends on those hashes, so this regression would
materially degrade prefix cache hit rate for any request carrying a
LoRA task id or a cache salt.

Fix ``_root_attrs_from_root_block`` to prefer ``root.reuse_scope`` and
fall back to the legacy attributes (keeps any in-flight pre-refactor
RootBlock instances working).

Also:
- Update the now-stale ``test_v2_root_key_distinguishes_lora_from_cache_salt_id``
  to use the new single-arg ``RootBlock.make_key(ReuseScope(...))`` API.
- Extend ``_FakeRootBlock`` with an optional ``reuse_scope`` kwarg so
  tests can mimic both the pre- and post-refactor RootBlock shape.
- Add a regression test ``test_v2_kv_cache_event_manager_v1_hash_reads_root_reuse_scope``
  that asserts (a) a ReuseScope-shaped root and a legacy root with the
  same lora/salt produce identical V1 event hashes, (b) different
  scopes still produce different hashes (no silent collapse), and
  (c) an empty ReuseScope matches a legacy root with no salt/lora.

Addresses reviewer feedback on NVIDIA#14351 (peihu-nv).

Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request May 21, 2026
Build #39108 of PR NVIDIA#14351 failed 7 tests in tests/unittest/disaggregated/
test_router.py with:

    TypeError: RootBlock.make_key() takes 1 positional argument but 2 were given

This PR collapses the prior (lora_task_id, cache_salt_id) pair into a
single TreeTaskId seed for the radix tree, but two callers on the base
feat/deepseek_v4 branch were not migrated:

- tensorrt_llm/serve/router.py — two call sites still pass
  (None, cache_salt_id) to V2RootBlock.make_key
- tests/unittest/disaggregated/test_router.py — two call sites still
  pass cache_salt_id as the 4th positional argument to
  sequence_to_blockchain_keys

Fix by computing the seed via _KVCache._make_tree_task_id(lora_task_id,
cache_salt_id) and passing it as the single TreeTaskId argument. The
helper returns lora_task_id unchanged when cache_salt_id is None so the
unsalted fast path is unaffected; with a salt it returns the SHA-256
digest that binds the two fields together.

Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
@lancelly
lancelly requested a review from a team as a code owner May 21, 2026 02:05
@lancelly

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49540 [ run ] triggered by Bot. Commit: a0824a2 Link to invocation

Build #39108 of PR NVIDIA#14351 failed 7 tests in tests/unittest/disaggregated/
test_router.py with:

    TypeError: RootBlock.make_key() takes 1 positional argument but 2 were given

This PR collapses the prior (lora_task_id, cache_salt_id) pair into a
single TreeTaskId seed for the radix tree, but two callers on the base
feat/deepseek_v4 branch were not migrated:

- tensorrt_llm/serve/router.py — two call sites still pass
  (None, cache_salt_id) to V2RootBlock.make_key
- tests/unittest/disaggregated/test_router.py — two call sites still
  pass cache_salt_id as the 4th positional argument to
  sequence_to_blockchain_keys

Fix by computing the seed via _KVCache._make_tree_task_id(lora_task_id,
cache_salt_id) and passing it as the single TreeTaskId argument. The
helper returns lora_task_id unchanged when cache_salt_id is None so the
unsalted fast path is unaffected; with a salt it returns the SHA-256
digest that binds the two fields together.

Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
@lancelly
lancelly force-pushed the feat/dsv4-align-kvcm-with-main branch from a0824a2 to eaddc9a Compare May 21, 2026 02:17
@lancelly

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@lancelly

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49544 [ run ] triggered by Bot. Commit: 70263ce Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49540 [ run ] completed with state ABORTED. Commit: a0824a2

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49546 [ run ] triggered by Bot. Commit: 70263ce Link to invocation

lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request May 21, 2026
After NVIDIA#14140 (cherry-picked in NVIDIA#14353) RootBlock no longer exposes
``lora_task_id`` / ``cache_salt_id`` directly — both fields are folded
into a ``ReuseScope`` NamedTuple attached as ``root.reuse_scope``.
``KVCacheEventManager._root_attrs_from_root_block`` was still reading
the legacy attribute names via ``getattr(..., None)``, so every emitted
event silently received ``(None, None)`` and the V1-compat hash
collapsed to the same value for any LoRA/salt request. Downstream
Dynamo routing depends on those hashes, so this regression would
materially degrade prefix cache hit rate for any request carrying a
LoRA task id or a cache salt.

Fix ``_root_attrs_from_root_block`` to prefer ``root.reuse_scope`` and
fall back to the legacy attributes (keeps any in-flight pre-refactor
RootBlock instances working).

Also:
- Update the now-stale ``test_v2_root_key_distinguishes_lora_from_cache_salt_id``
  to use the new single-arg ``RootBlock.make_key(ReuseScope(...))`` API.
- Extend ``_FakeRootBlock`` with an optional ``reuse_scope`` kwarg so
  tests can mimic both the pre- and post-refactor RootBlock shape.
- Add a regression test ``test_v2_kv_cache_event_manager_v1_hash_reads_root_reuse_scope``
  that asserts (a) a ReuseScope-shaped root and a legacy root with the
  same lora/salt produce identical V1 event hashes, (b) different
  scopes still produce different hashes (no silent collapse), and
  (c) an empty ReuseScope matches a legacy root with no salt/lora.

Addresses reviewer feedback on NVIDIA#14351 (peihu-nv).

Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request May 21, 2026
After NVIDIA#14140 (cherry-picked in NVIDIA#14353) RootBlock no longer exposes
``lora_task_id`` / ``cache_salt_id`` directly — both fields are folded
into a ``ReuseScope`` NamedTuple attached as ``root.reuse_scope``.
``KVCacheEventManager._root_attrs_from_root_block`` was still reading
the legacy attribute names via ``getattr(..., None)``, so every emitted
event silently received ``(None, None)`` and the V1-compat hash
collapsed to the same value for any LoRA/salt request. Downstream
Dynamo routing depends on those hashes, so this regression would
materially degrade prefix cache hit rate for any request carrying a
LoRA task id or a cache salt.

Fix ``_root_attrs_from_root_block`` to prefer ``root.reuse_scope`` and
fall back to the legacy attributes (keeps any in-flight pre-refactor
RootBlock instances working).

Also:
- Update the now-stale ``test_v2_root_key_distinguishes_lora_from_cache_salt_id``
  to use the new single-arg ``RootBlock.make_key(ReuseScope(...))`` API.
- Extend ``_FakeRootBlock`` with an optional ``reuse_scope`` kwarg so
  tests can mimic both the pre- and post-refactor RootBlock shape.
- Add a regression test ``test_v2_kv_cache_event_manager_v1_hash_reads_root_reuse_scope``
  that asserts (a) a ReuseScope-shaped root and a legacy root with the
  same lora/salt produce identical V1 event hashes, (b) different
  scopes still produce different hashes (no silent collapse), and
  (c) an empty ReuseScope matches a legacy root with no salt/lora.

Addresses reviewer feedback on NVIDIA#14351 (peihu-nv).

Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49546 [ run ] completed with state SUCCESS. Commit: 70263ce
/LLM/main/L0_MergeRequest_PR pipeline #39176 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

@lfr-0531

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49688 [ run ] triggered by Bot. Commit: 70263ce Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #49688 [ run ] completed with state SUCCESS. Commit: 70263ce
/LLM/main/L0_MergeRequest_PR pipeline #39295 completed with status: 'SUCCESS'

CI Report

Link to invocation

@pcastonguay
pcastonguay merged commit e696714 into NVIDIA:feat/deepseek_v4 May 21, 2026
6 checks passed
lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request May 21, 2026
After NVIDIA#14140 (cherry-picked in NVIDIA#14353) RootBlock no longer exposes
``lora_task_id`` / ``cache_salt_id`` directly — both fields are folded
into a ``ReuseScope`` NamedTuple attached as ``root.reuse_scope``.
``KVCacheEventManager._root_attrs_from_root_block`` was still reading
the legacy attribute names via ``getattr(..., None)``, so every emitted
event silently received ``(None, None)`` and the V1-compat hash
collapsed to the same value for any LoRA/salt request. Downstream
Dynamo routing depends on those hashes, so this regression would
materially degrade prefix cache hit rate for any request carrying a
LoRA task id or a cache salt.

Fix ``_root_attrs_from_root_block`` to prefer ``root.reuse_scope`` and
fall back to the legacy attributes (keeps any in-flight pre-refactor
RootBlock instances working).

Also:
- Update the now-stale ``test_v2_root_key_distinguishes_lora_from_cache_salt_id``
  to use the new single-arg ``RootBlock.make_key(ReuseScope(...))`` API.
- Extend ``_FakeRootBlock`` with an optional ``reuse_scope`` kwarg so
  tests can mimic both the pre- and post-refactor RootBlock shape.
- Add a regression test ``test_v2_kv_cache_event_manager_v1_hash_reads_root_reuse_scope``
  that asserts (a) a ReuseScope-shaped root and a legacy root with the
  same lora/salt produce identical V1 event hashes, (b) different
  scopes still produce different hashes (no silent collapse), and
  (c) an empty ReuseScope matches a legacy root with no salt/lora.

Addresses reviewer feedback on NVIDIA#14351 (peihu-nv).

Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
lfr-0531 pushed a commit to lfr-0531/TensorRT-LLM that referenced this pull request Jun 10, 2026
…VIDIA#13793) (NVIDIA#14351)

Signed-off-by: Yueh-Ting Chen <yueh.ting.chen@gmail.com>
Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
Co-authored-by: Yueh-Ting (eop) Chen <yuehtingc@nvidia.com>
lfr-0531 pushed a commit to lfr-0531/TensorRT-LLM that referenced this pull request Jun 11, 2026
…VIDIA#13793) (NVIDIA#14351)

Signed-off-by: Yueh-Ting Chen <yueh.ting.chen@gmail.com>
Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
Co-authored-by: Yueh-Ting (eop) Chen <yuehtingc@nvidia.com>
lfr-0531 pushed a commit to lfr-0531/TensorRT-LLM that referenced this pull request Jun 12, 2026
…VIDIA#13793) (NVIDIA#14351)

Signed-off-by: Yueh-Ting Chen <yueh.ting.chen@gmail.com>
Signed-off-by: lancelly <108499334+lancelly@users.noreply.github.com>
Co-authored-by: Yueh-Ting (eop) Chen <yuehtingc@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants