Skip to content

[TRTLLM-15216][fix] Kimi K3 on KVCacheManagerV2: conv-state layout and SSM iteration stats - #17447

Open
brnguyen2 wants to merge 6 commits into
NVIDIA:mainfrom
brnguyen2:k3/kvcm-v2-fixes
Open

[TRTLLM-15216][fix] Kimi K3 on KVCacheManagerV2: conv-state layout and SSM iteration stats#17447
brnguyen2 wants to merge 6 commits into
NVIDIA:mainfrom
brnguyen2:k3/kvcm-v2-fixes

Conversation

@brnguyen2

@brnguyen2 brnguyen2 commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Description

Two fixes to the Kimi K3 path on KVCacheManagerV2, one commit per ticket.

TRTLLM-15216 — wrong conv-state layout (fix). The kimi_linear branch of the manager
selection hardcoded model_type="qwen3_next" and never passed conv_state_layout. The
V2 manager defaults to x_b_c and absorbs model_type through **kwargs, so an explicit
V2 opt-in silently built the wrong layout with no error. Selects the kwarg from the
manager class, following the idiom already used by the qwen3_hybrid branch. A
strict=True xfail test describing exactly this bug already existed; the marker is
dropped and a companion test covers the V1 branch.

TRTLLM-15217 — SSM life cycles missing from iteration stats (fix). The page-movement
recorders dropped every non-attention life cycle, so KDA recurrent-state offload, onboard
and drop were invisible in iteration statistics. Filters removed at the recording sites
and in the Python mirror. The filter is kept for the global
allocTotalBlocks/allocNewBlocks counters and for reuse hit/miss range accounting,
which are attention-only by definition.

Both are reachable only with an explicit use_kv_cache_manager_v2=True; "auto" does not
select V2 for this model today, so default runs are unaffected.

Not in scope:

Test Coverage

  • 15216: existing xfail un-marked (it forces use_kv_cache_manager_v2=True), plus a new
    test for the non-V2 branch.
  • 15217: new CPU-only test binding the real recorder methods to a duck-typed stand-in, so
    the production filtering logic is what is exercised.
  • Full run of the touched suites: 239 passed, 13 skipped, 0 failed.

PR Checklist

  • PR title is [JIRA/NVBUG/None][type] Summary
  • Commits are signed off (DCO)
  • New tests added and passing
  • No new dependencies

Dev Engineer Review

  • V2 managers now use conv_state_layout; V1 managers retain model_type.
  • V2 managers reject unexpected model_type arguments.
  • Hybrid layout dispatch uses one shared helper.
  • Lifecycle statistics now include attention and SSM/recurrent lifecycles.
  • Global allocation and cache hit/miss counters remain attention-only.
  • Changes are scoped to explicit V2 use. "auto" is unchanged.
  • No configuration or public API changes were identified.
  • Touched suites report 239 passed, 13 skipped, and 0 failed.
  • CI pipelines failed without specific test failures. Follow-up CI review is required.

QA Engineer Review

  • Activated test_kimi_k3_v2_cache_manager_layout.
  • Added V1 layout coverage.
  • Added V2 invalid-model_type coverage.
  • Added test_offload_is_recorded_for_every_life_cycle.
  • Added test_host_drop_is_recorded_for_every_life_cycle.
  • Added test_direct_iteration_stats_are_recorded_for_every_life_cycle.
  • Added test_onboard_counts_globally_only_for_attention.
  • Added test_ssm_resume_records_intra_device_copy.
  • Tests cover attention and SSM/recurrent lifecycle statistics on both backends.
  • No test-list, test-db/, qa/, or waives.txt changes are reported.
  • Test-list coverage is not declared.
  • Verdict: needs follow-up.

…nager V2

The kimi_linear branch of _create_kv_cache_manager passed
model_type="qwen3_next" unconditionally. MambaHybridCacheManagerV2 has no
model_type parameter: it absorbs it into **kwargs and selects the KDA
convolution-state sectioning from conv_state_layout, which defaults to
"x_b_c". An explicit use_kv_cache_manager_v2=True opt-in therefore built
the KDA conv state with the wrong section layout, silently, with no error
and no warning.

Select the kwarg from the manager class, matching what the qwen3_hybrid
branch in the same function already does: conv_state_layout="q_k_v" for
MambaHybridCacheManagerV2, model_type="qwen3_next" for the V1 managers.

This path is opt-in only today (use_kv_cache_manager_v2 must be set to
True; "auto" does not select V2 for kimi_linear), so no default
configuration changes behavior.

Test: test_kimi_explicit_v2_manager_uses_qkv_convolution_layout already
existed as a strict xfail describing this bug; the marker is dropped.
Adds test_kimi_v1_manager_still_selects_qwen3_next_model_type to guard the
V1 branch.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
…teration stats

The V2 page-movement recorders (_recordDirectIterationStats,
_recordMigratedSlots, _recordDroppedPages, and their Python mirrors)
returned early or skipped the page whenever the life cycle was not an
AttnLifeCycle. Offload, onboard, intra-device copy and host-tier drop of
recurrent (SSM/KDA) state were therefore never recorded, and any
recurrent-cache iteration statistics read back as zeros.

Iteration statistics are already keyed by life cycle, so recurrent
movement stays distinguishable from attention movement without the filter.
Keep the filter only where it is semantically required: the global
cache-hit counters (allocTotalBlocks / allocNewBlocks) and the block-reuse
hit/miss range accounting stay attention-only.

Observability only, no change to allocation or reuse behavior, and
reachable only under use_kv_cache_manager_v2=True.

Test: tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_stats_life_cycles.py
drives the Python recorders directly (no GPU needed) and asserts offload
and host-drop are reported for both life-cycle kinds while the global
cache-hit counters remain attention-only. The C++ recorders have no
equivalent CPU-only seam.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
@brnguyen2
brnguyen2 marked this pull request as ready for review August 9, 2026 17:22
@brnguyen2
brnguyen2 requested review from a team as code owners August 9, 2026 17:22
@brnguyen2 brnguyen2 changed the title [TRTLLM-15216][fix] Kimi K3 on KVCacheManagerV2: conv-state layout, SSM stats, pruning diagnostic [TRTLLM-15216][fix] Kimi K3 on KVCacheManagerV2: conv-state layout and SSM iteration stats Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The change initializes hybrid-pruning state, records KV-cache statistics for attention and SSM lifecycles, and centralizes manager-specific layout selection for hybrid cache managers.

Changes

Hybrid KV-cache management

Layer / File(s) Summary
Hybrid pruning and lifecycle statistics
cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/kvCache.cpp, tensorrt_llm/runtime/kv_cache_manager_v2/_core/_kv_cache.py, tests/unittest/kv_cache_manager_v2_tests/*
The cache initializes hybrid-pruning state. Lifecycle-specific statistics now include SSM and recurrent activity. Global allocation counters remain attention-only. Tests cover offload, host drop, migration, onboarding, and resume-copy statistics.
Hybrid manager layout wiring
tensorrt_llm/_torch/pyexecutor/_util.py, tensorrt_llm/_torch/pyexecutor/mamba_cache_manager.py
A shared helper selects conv_state_layout for V2 managers and model_type for V1 managers. V2 managers reject the V1-only model_type keyword.
Manager layout regression coverage
tests/unittest/_torch/executor/test_mamba_cache_manager.py
Tests verify Kimi V2 layout selection, V1 model-type propagation, and V2 keyword validation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: schetlur-nv, liji-nv, qijune

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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
Description check ✅ Passed The description explains both fixes, scope, tests, CI status, and checklist items with relevant implementation details.
Title check ✅ Passed The title follows the required format and clearly identifies the Kimi K3 conv-state layout and SSM iteration-statistics fixes.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/kvCache.cpp (1)

617-629: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Record SSM deferred-copy iteration stats in Python

Move _record_direct_iteration_stats() outside the if lc_idx != ssm_lc_id: block in tensorrt_llm/runtime/kv_cache_manager_v2/_core/_kv_cache.py. Keep only record_allocation_range() inside the block so Python reports SSM copy blocks and bytes like C++.

🤖 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 `@cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/kvCache.cpp` around lines
617 - 629, The C++ method _recordDirectIterationStats records statistics for
every lifecycle, including SSM, while the Python flow currently skips SSM stats.
In tensorrt_llm/runtime/kv_cache_manager_v2/_core/_kv_cache.py lines 505-513,
move _record_direct_stats() outside the if lc_idx != ssm_lc_id block, leaving
only record_allocation_range() inside it so SSM copy blocks and bytes are
reported consistently.
🧹 Nitpick comments (1)
tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_stats_life_cycles.py (1)

42-125: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy lift

Add coverage for KvCache.resume() deferred-copy path

  • Added tests: test_offload_is_recorded_for_every_life_cycle, test_host_drop_is_recorded_for_every_life_cycle, and test_onboard_counts_globally_only_for_attention. No modified or removed tests.
  • The file is registered through unittest/kv_cache_manager_v2_tests in l0_b200.yml and l0_h100.yml.
  • Coverage is insufficient. The tests call recorder methods directly and do not exercise KvCache.resume() for SSM deferred copies. Add this case and assert the per-life-cycle iter_intra_device_copy_* statistics.
🤖 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 `@tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_stats_life_cycles.py`
around lines 42 - 125, Add a test that exercises KvCache.resume() with an SSM
deferred-copy scenario rather than invoking recorder methods directly. Configure
the deferred copy and resume flow using the existing test fixtures/helpers, then
assert the committed SSM statistics include the expected
iter_intra_device_copy_blocks and iter_intra_device_copy_bytes values.

Source: Path instructions

🤖 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/kv_cache_manager_v2_tests/test_kv_cache_manager_v2.py`:
- Around line 2397-2434: Extend
test_num_tokens_before_hybrid_pruning_isolates_recurrent_truncation to capture
the relevant iter_intra_device_copy_* counter before and after kv.resume(stream)
for the reused SSM snapshot, then assert the expected delta from the deferred
copy. Ensure the assertion specifically covers the SSM resume path rather than
relying only on token-count diagnostics.

---

Outside diff comments:
In `@cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/kvCache.cpp`:
- Around line 617-629: The C++ method _recordDirectIterationStats records
statistics for every lifecycle, including SSM, while the Python flow currently
skips SSM stats. In tensorrt_llm/runtime/kv_cache_manager_v2/_core/_kv_cache.py
lines 505-513, move _record_direct_stats() outside the if lc_idx != ssm_lc_id
block, leaving only record_allocation_range() inside it so SSM copy blocks and
bytes are reported consistently.

---

Nitpick comments:
In `@tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_stats_life_cycles.py`:
- Around line 42-125: Add a test that exercises KvCache.resume() with an SSM
deferred-copy scenario rather than invoking recorder methods directly. Configure
the deferred copy and resume flow using the existing test fixtures/helpers, then
assert the committed SSM statistics include the expected
iter_intra_device_copy_blocks and iter_intra_device_copy_bytes values.
🪄 Autofix

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: 128cc974-fab3-4f1b-8330-d1ed9fa1fe99

📥 Commits

Reviewing files that changed from the base of the PR and between 1cef02e and 6db9d2e.

📒 Files selected for processing (11)
  • cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/blockRadixTree.cpp
  • cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/blockRadixTree.h
  • cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/kvCache.cpp
  • cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/kvCache.h
  • cpp/tensorrt_llm/nanobind/batch_manager/kvCacheManagerV2.cpp
  • tensorrt_llm/_torch/pyexecutor/_util.py
  • tensorrt_llm/runtime/kv_cache_manager_v2/_block_radix_tree.py
  • tensorrt_llm/runtime/kv_cache_manager_v2/_core/_kv_cache.py
  • tests/unittest/_torch/executor/test_mamba_cache_manager.py
  • tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_manager_v2.py
  • tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_stats_life_cycles.py

Comment thread tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_manager_v2.py Outdated
@brnguyen2

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64869 [ run ] triggered by Bot. Commit: 3f6c398 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@brnguyen2

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64877 [ run ] triggered by Bot. Commit: 3f6c398 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@brnguyen2

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64887 [ run ] triggered by Bot. Commit: 3f6c398 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64887 [ run ] completed with state SUCCESS. Commit: 3f6c398
/LLM/main/L0_MergeRequest_PR pipeline #52728 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/runtime/kv_cache_manager_v2/_core/_kv_cache.py
Comment thread tensorrt_llm/_torch/pyexecutor/_util.py Outdated
Comment thread tensorrt_llm/_torch/pyexecutor/_util.py Outdated
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
…backends

Review follow-up. The Python backend used to record
iter_intra_device_copy_{blocks,bytes} only for non-SSM life cycles in the
resume() deferred-copy loop, unlike the default C++ backend; the previous
commit aligned the call sites. Add the coverage that was missing:

- test_kv_cache_stats_life_cycles.py now drives
  _record_direct_iteration_stats (it was bound into the stand-in but
  never exercised) for both attention and SSM life cycles.
- TestSSMSupport.test_ssm_resume_records_intra_device_copy asserts the
  SSM intra-device-copy delta end to end against the selected backend,
  so the default C++ implementation is covered and a Python-backend
  parity break fails the same test (verified: it fails against the
  pre-fix Python backend).

Also comment why the recorder call sits outside the ssm_lc_id guard.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
…d dedupe layout dispatch

Review follow-up, two hardenings against the bug class fixed earlier in
this PR:

- MambaHybridCacheManagerV2.__init__ now raises TypeError when handed
  the V1 managers' model_type kwarg instead of conv_state_layout.
  Silently absorbing it into **kwargs is exactly how the wrong-layout
  bug went unnoticed.
- The three copies of the "V2 takes conv_state_layout, V1 takes
  model_type" dispatch in _create_kv_cache_manager (kimi, nemotron,
  qwen3_hybrid branches) collapse into one helper with a single
  model_type-to-layout mapping, so a future hybrid branch cannot pick
  one convention and drop the other.

Test: test_v2_manager_rejects_model_type_kwarg; existing kimi/qwen3
layout-selection tests cover the helper refactor.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
The module imported KvCache but the class is named _KVCache, so the file
failed pytest collection and none of its tests ever ran. Review follow-up
discovered while adding the _record_direct_iteration_stats case.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>

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

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

2025-2026: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use precise annotations for the new helper.

kv_cache_manager_cls: type and -> dict are too broad for this new function. Use a concrete manager-class type and a parameterized mapping, such as type[MambaHybridCacheManager] and dict[str, str].

As per coding guidelines, every function must be annotated and imprecise dict types must use precise generic types.

Suggested annotation update
-def _mamba_conv_layout_kwargs(kv_cache_manager_cls: type,
-                              model_type: str) -> dict:
+def _mamba_conv_layout_kwargs(
+        kv_cache_manager_cls: type[MambaHybridCacheManager],
+        model_type: str) -> dict[str, str]:
🤖 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/_util.py` around lines 2025 - 2026, Update
_mamba_conv_layout_kwargs annotations to use type[MambaHybridCacheManager] for
kv_cache_manager_cls and dict[str, str] for the return value, ensuring the
referenced manager type is available in scope.

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.

Nitpick comments:
In `@tensorrt_llm/_torch/pyexecutor/_util.py`:
- Around line 2025-2026: Update _mamba_conv_layout_kwargs annotations to use
type[MambaHybridCacheManager] for kv_cache_manager_cls and dict[str, str] for
the return value, ensuring the referenced manager type is available in scope.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4af1b507-0961-4d9f-affd-80ae1ac73890

📥 Commits

Reviewing files that changed from the base of the PR and between 9a11822 and 99b20ce.

📒 Files selected for processing (6)
  • tensorrt_llm/_torch/pyexecutor/_util.py
  • tensorrt_llm/_torch/pyexecutor/mamba_cache_manager.py
  • tensorrt_llm/runtime/kv_cache_manager_v2/_core/_kv_cache.py
  • tests/unittest/_torch/executor/test_mamba_cache_manager.py
  • tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_manager_v2.py
  • tests/unittest/kv_cache_manager_v2_tests/test_kv_cache_stats_life_cycles.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tensorrt_llm/runtime/kv_cache_manager_v2/_core/_kv_cache.py

@brnguyen2

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #65017 [ run ] triggered by Bot. Commit: 99b20ce 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.

3 participants