[None][fix] KVv2 C++ backend: nanobind None/uint64 argument handling, constraint-floor parity, backend-aware OutOfPagesError - #2
Draft
lancelly wants to merge 9 commits into
Conversation
… backend Backend-neutral Python groundwork for the upcoming C++ implementation of KVCacheManagerV2 (introduced in a follow-up PR): - Expand the public API of tensorrt_llm.runtime.kv_cache_manager_v2: export layout descriptors (pool_group_descs: PoolDesc, PoolGroupDesc, SlotDesc, CoalescedBuffer, ExpandedBuffer), stats/eventing types, and a backend-neutral _introspection helper module. - Use the public layout/introspection APIs in the disaggregation kv_extractor and the DSv4/MiniMax sparse cache managers instead of reaching into implementation internals. - Keep vocab_size in the _build_cache_config() virtual-method contract but drop it from the generic KVCacheManagerConfig. - Add v2_blake3 / v2_blake3_64 KV cache event hash options to llm_args and regenerate the LLM args golden manifest. - Fix StagingBuffer wrap-around when the ring tail cannot satisfy min_size; misc small fixes surfaced while translating the code. - Extend unit test coverage (stats API, hash options); route tests through the public API where possible. - Fix create_perf_comparison_report.py crash when the only perf test is waived and no CSV is produced (pre-existing main issue). - Rename debug assertion env var to TLLM_DEBUG_MODE. Signed-off-by: Yao Yao <lowsfer@users.noreply.github.com>
Add the C++ translation of KVCacheManagerV2 under cpp/tensorrt_llm/batch_manager/kv_cache_manager_v2/ with nanobind bindings, vendored BLAKE3, build integration, and unit tests. Turn tensorrt_llm/runtime/kv_cache_manager_v2/__init__.py into a backend dispatcher (TLLM_KV_CACHE_MANAGER_V2_BACKEND, default: cpp) and add the C++-backend introspection paths in pyexecutor and tests. Signed-off-by: Yao Yao <lowsfer@users.noreply.github.com>
Signed-off-by: Jin Li <59594262+liji-nv@users.noreply.github.com> Signed-off-by: Yao Yao <lowsfer@users.noreply.github.com>
Signed-off-by: Jin Li <59594262+liji-nv@users.noreply.github.com> Signed-off-by: Yao Yao <lowsfer@users.noreply.github.com>
Signed-off-by: Jin Li <59594262+liji-nv@users.noreply.github.com> Signed-off-by: Yao Yao <lowsfer@users.noreply.github.com>
Port of main commit 7d600ec (DSv4 PR-6): a null beam_block page may now also mean a skipped stale block, not only an SWA scratch block, so drop the two TLLM_CHECK_DEBUG(mEnableSwaScratchReuse) checks in the page unlock/release paths and update the comments to match the Python reference implementation. Signed-off-by: Yao Yao <lowsfer@users.noreply.github.com>
…o and accept None in set_base_page_index_buf Two fixes found running the C++ backend on DeepSeek-V4 4p1d disagg: 1) StorageManager::computeMinSlotsFromConstraints — an explicit initialPoolRatio disabled constraint floors entirely and the floors were not scaled by 1/maxUtilForResume. This is the C++ counterpart of the Python-side fix in PR NVIDIA#16269 (DSv4 warmup starvation when pool_ratio is set and the estimation quota is tight); the Python backend has the fix, the C++ translation predates it. 2) set_base_page_index_buf's buf argument rejected None at the nanobind layer (missing .none() annotation), although the lambda body already handles is_none(). release_index_slot passes None to clear the DSA index buffer, so on the C++ backend every ctx worker died with 'incompatible function arguments ... NoneType' at the first index-slot release. Signed-off-by: Lance Liao <108499334+lancelly@users.noreply.github.com>
…nd reuse-scope salts CUDA_GRAPH_DUMMY_REQUEST_ID is 2**64-1 and sha256-derived reuse salts use the full 64-bit range; the previous std::optional<int64_t> casters raised TypeError (gen workers died in cuda-graph padding). Reinterpret as two's complement in both directions: bijective, small ids unchanged, and ReuseScope::toBytes serializes the same 8 bytes so reuse keys stay identical to the Python backend. Signed-off-by: Lance Liao <laliao@nvidia.com> Signed-off-by: Lance Liao <108499334+lancelly@users.noreply.github.com>
The nanobind module registers its own OutOfPagesError exception class, so 'except OutOfPagesError' clauses importing the pure-Python class from kv_cache_manager_v2._exceptions never match on the C++ backend and the guarded allocation paths crash instead of backing off. The package __init__ already re-exports the backend-appropriate class; import that. Signed-off-by: Lance Liao <108499334+lancelly@users.noreply.github.com>
lowsfer
force-pushed
the
kvCacheManagerV2-cpp
branch
20 times, most recently
from
July 22, 2026 16:34
6f646e5 to
2ca5340
Compare
lowsfer
force-pushed
the
kvCacheManagerV2-cpp
branch
17 times, most recently
from
July 29, 2026 05:29
cef027a to
f0852d3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Three fixes for issues hit while running this branch's C++ backend end-to-end on a DeepSeek-V4 4p1d disaggregated deployment (4×TP8 ctx + 1×TP16 gen, GB300, conc=1000, agentic multi-turn workload), plus an A/B validation of the backend itself. All three are interface-layer issues — the core design ran flawlessly once they were fixed (≈106K requests, zero crashes).
1.
set_base_page_index_bufrejectsNone→ every ctx worker dies (kvCacheManagerV2.cpp)release_index_slotpassesbuf=Noneto clear the DSA index buffer. The lambda body already handlesis_none(), but thenb::arg("buf")annotation lacks.none(), so nanobind rejects the call at the argument-casting layer:On the C++ backend every ctx worker crashes at the first index-slot release. One-line fix:
nb::arg("buf").none().2. int64 bindings reject valid ids/salts → gen workers die in CUDA-graph padding (
kvCacheManagerV2.cpp)Two producers exceed
int64range:CUDA_GRAPH_DUMMY_REQUEST_ID = 2**64 - 1(cuda_graph_runner.py) —create_kv_cache(id=...)raises the sameincompatible function argumentsTypeError inside CUDA-graph padding, killing all gen ranks (AssertionError: Sampling failed). Only gen uses graphs, and the Python backend's unbounded ints are unaffected — so this is cpp-backend-gen-specific and 100% reproducible.ReuseScope.saltis derived viaint.from_bytes(sha256(...)[:8])— a full 64-bit value, i.e. >2**63 with ~50% probability per salted request. Same crash, latent until acache_salt-carrying request arrives.Fix: accept
uint64at every id/salt boundary (create_kv_cache,ReuseScopector/accessors, the 5 stats APIs,get_dirty_stats_kv_cache_ids) and reinterpret via two's complement in both directions. This is bijective (small ids unchanged), andReuseScope::toBytesserializes the same 8 bytes either way, so reuse keys stay identical to the Python backend's.3.
except OutOfPagesErrornever matches on the C++ backend (py_executor.py)The nanobind module registers its own
OutOfPagesErrorexception class, whilepy_executorimports the pure-Python class fromkv_cache_manager_v2._exceptions— so the guarded allocation paths crash instead of backing off. The package__init__already re-exports the backend-appropriate class; import that instead (one line).Also included in the first commit: the C++
StorageManager::computeMinSlotsFromConstraintsport of the Python-side fix from NVIDIA#16269 — explicitinitialPoolRatiodisabled constraint floors entirely and floors weren't scaled by1/maxUtilForResume(DSv4 warmup starvation whenpool_ratiois set). The Python backend has this fix; the C++ translation predates it. More generally, a sweep for Python-side KVv2 fixes that postdate the translation snapshot might be worthwhile before merge.Validation
With these fixes,
TLLM_KV_CACHE_MANAGER_V2_BACKEND=cppvspythonA/B on the setup above (~100K requests per arm, arms differ only in the env var):Gen-side nsys (steady state, iters 25000–25100, 16 ranks/arm) attributes the win to the expected places:
_schedulep90 11.0→1.0 ms,update_resourcesp90 1.9→0.3 ms,_handle_responsesp90 4.6→1.7 ms, per-event GIL-wait p90 −57%.