Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7e1cf91
[None][feat] Support Gemma4 mixed-shape pools in KVCacheManager and r…
eopXD May 19, 2026
449cfcb
[None][fix] Translate Python PoolConfiguration to C++ at nanobind bou…
eopXD May 19, 2026
3311feb
[None][fix] AutoDeploy: register fallback KV pool for MLA-only models
eopXD May 20, 2026
aba166c
Merge remote-tracking branch 'origin/main' into sg/swa-take2
eopXD May 20, 2026
431c61a
[None][fix] AutoDeploy: update lingering test to per-pool nest_sequen…
eopXD May 21, 2026
fadd153
[None][fix] AutoDeploy: replicate warm-up cache metadata per pool for…
eopXD May 22, 2026
24778b0
[None][test] AutoDeploy: re-enable Gemma4 MoE on single-GPU H100
eopXD May 22, 2026
033130b
Merge remote-tracking branch 'origin/main' into sg/swa-take2
eopXD May 22, 2026
f61a9dc
[None][fix] AutoDeploy: attach Gemma4 get_per_layer_inputs on non-E2B…
eopXD May 22, 2026
2b5cdf2
Merge remote-tracking branch 'origin/main' into sg/swa-take2
eopXD May 22, 2026
c55f3b3
Merge remote-tracking branch 'origin/main' into sg/swa-take2
eopXD May 25, 2026
e658a9d
[https://nvbugs/6158397][test] AutoDeploy: re-waive Gemma4 MoE on H100
eopXD May 25, 2026
f8e9861
[None][feat] AutoDeploy: SWA front-eviction in same PR as Gemma-3n co…
eopXD May 25, 2026
ade3102
Revert untested changes, unnecessary explicit additions, and over-ver…
eopXD May 25, 2026
aea2a18
[None][test] AutoDeploy: fix VSWA metadata test backend selector
eopXD May 26, 2026
eaf7c2f
[None][test] AutoDeploy: size SWA eviction fixture above scenario length
eopXD May 26, 2026
20c0ff6
[None][chore] AutoDeploy: add SWA front-eviction debug traces
eopXD May 27, 2026
c5551ce
[None][chore] AutoDeploy: add Gemma3n E2B SWA repro script
eopXD May 27, 2026
a2e8ae0
[None][fix] AutoDeploy: revert releaseBlocks front-placeholder clamp
eopXD May 27, 2026
0b76919
[None][fix] AutoDeploy: per-pool host-prep for FlashInfer VSWA
eopXD May 27, 2026
6a739d1
[None][chore] AutoDeploy: revert SWA debug traces and repro script
eopXD May 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 137 additions & 16 deletions cpp/include/tensorrt_llm/batch_manager/kvCacheManager.h

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions cpp/tensorrt_llm/batch_manager/cacheFormatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,11 @@ void CacheFormatter::unformat(tensorrt_llm::batch_manager::TransferSession& sess
{
NVTX3_SCOPED_RANGE(formatInputRecvBuffer);

// TODO(disagg-multi-dtype): pool 0's dtype is treated as canonical for the wire
// transport here. Pools with differing dtypes are rejected up-front in
// CacheTransBufferManager's constructor (see cacheTransBuffer.cpp). When
// per-pool dtype dispatch lands, this single dataType variable must be replaced
// with a per-pool lookup keyed by the source pool of each block.
auto dataType = mCacheManager->getPrimaryPool(0)->getDataType();
bool layerWise = common::getEnvDisaggLayerwise() && numKvPools == 1;
if (layerWise)
Expand Down
22 changes: 22 additions & 0 deletions cpp/tensorrt_llm/batch_manager/cacheTransBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,28 @@ CacheTransBufferManager::CacheTransBufferManager(
{
// TODO: FP4 dataSize
TLLM_CHECK(mCacheManager);
// TODO(disagg-multi-dtype): Per-pool dtype dispatch in formatter / transfer buffer
Comment thread
eopXD marked this conversation as resolved.
// not yet implemented. Disagg currently picks pool 0's dtype as the canonical
// transport type (above), so any KV pool with a different dtype would be silently
// miscoerced on the wire. Fail loudly until per-pool dispatch lands. We restrict
// the comparison to KV pools (getNumPools(false, false)) since block-scale and
// indexer-K pools legitimately have their own dtypes and travel through their own
// code paths.
if (!transferIndexerKCache)
{
auto const numKvPools = mCacheManager->getBlockManager().getNumPools(
/*includeBlockScalePools=*/false, /*includeIndexerKCachePools=*/false);
auto const dtype0 = mCacheManager->getPrimaryPool(0)->getDataType();
for (SizeType32 i = 1; i < numKvPools; ++i)
{
auto const dtypeI = mCacheManager->getPrimaryPool(i)->getDataType();
TLLM_CHECK_WITH_INFO(dtypeI == dtype0,
"Disaggregated KV cache transfer does not yet support pools with differing dtypes "
"(pool 0 dtype=%d, pool %d dtype=%d). TODO(disagg-multi-dtype): per-pool dtype "
"dispatch in formatter.",
static_cast<int>(dtype0), i, static_cast<int>(dtypeI));
}
}
TLLM_LOG_INFO("CacheTransBufferManager created for KV cache");
}

Expand Down
115 changes: 90 additions & 25 deletions cpp/tensorrt_llm/batch_manager/kvCacheManager.cpp

Large diffs are not rendered by default.

33 changes: 31 additions & 2 deletions cpp/tensorrt_llm/nanobind/batch_manager/kvCacheManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,14 @@ void tb::kv_cache_manager::KVCacheManagerBindings::initBindings(nb::module_& m)
nb::enum_<tbk::LinearAttentionMetadata::LinearCacheType>(m, "LinearCacheType")
.value("RECURRENT_STATES", tbk::LinearAttentionMetadata::LinearCacheType::kRecurrentStates);

nb::class_<tbk::PoolConfiguration>(m, "PoolConfiguration")
.def(nb::init<>())
.def(nb::init<SizeType32, SizeType32, nvinfer1::DataType>(), nb::arg("window_size"), nb::arg("size_per_head"),
nb::arg("dtype"))
.def_rw("window_size", &tbk::PoolConfiguration::windowSize)
.def_rw("size_per_head", &tbk::PoolConfiguration::sizePerHead)
.def_rw("dtype", &tbk::PoolConfiguration::dtype);

nb::class_<tbk::PrefixReuseSummary>(m, "PrefixReuseSummary")
.def(nb::init<>())
.def_ro("reusable_blocks_allocated", &tbk::PrefixReuseSummary::reusableBlocksAllocated)
Expand Down Expand Up @@ -415,6 +423,7 @@ void tb::kv_cache_manager::KVCacheManagerBindings::initBindings(nb::module_& m)
nb::arg("world_config"), nb::arg("window_size_to_layers"), nb::arg("allotted_primary_mem_bytes"),
nb::arg("allotted_secondary_mem_bytes"), nb::arg("extra_cost_memory"), nb::arg("kv_factor"),
nb::arg("max_batch_size"), nb::arg("linear_attention_metadata") = std::nullopt,
nb::arg("pool_configurations") = std::vector<tbk::PoolConfiguration>{},
nb::call_guard<nb::gil_scoped_release>())
.def("allocate_pools", &BaseKVCacheManager::allocatePools, nb::call_guard<nb::gil_scoped_release>())
.def("release_pools", &BaseKVCacheManager::releasePools, nb::call_guard<nb::gil_scoped_release>())
Expand Down Expand Up @@ -597,6 +606,18 @@ void tb::kv_cache_manager::KVCacheManagerBindings::initBindings(nb::module_& m)
.def("analyze_prefix_reuse", &BaseKVCacheManager::analyzePrefixReuse, nb::arg("unique_tokens"),
nb::arg("llm_request"), nb::call_guard<nb::gil_scoped_release>())
.def("get_cache_block_ids", &BaseKVCacheManager::getCacheBlockIds, nb::call_guard<nb::gil_scoped_release>())
.def(
"get_num_front_blocks_removed",
[](BaseKVCacheManager const& self, tb::LlmRequest::RequestIdType requestId, SizeType32 windowSize)
{
auto const& seq = self.getSequence(requestId);
// Per-window query. windowSize is required (no aggregation): the Python
// wrapper in resource_manager.py provides a "default to first window"
// convenience layer; the C++/nanobind boundary stays explicit so that
// every caller is forced to think about which pool's counter it wants.
return seq.getNumFrontBlocksRemoved(windowSize);
},
nb::arg("request_id"), nb::arg("window_size"), nb::call_guard<nb::gil_scoped_release>())
.def("get_batch_cache_block_ids", &BaseKVCacheManager::getBatchCacheBlockIds,
nb::call_guard<nb::gil_scoped_release>())
.def("flush_iteration_events", &BaseKVCacheManager::flushIterationEvents,
Expand Down Expand Up @@ -631,7 +652,8 @@ void tb::kv_cache_manager::KVCacheManagerBindings::initBindings(nb::module_& m)
std::vector<SizeType32> const&, nvinfer1::DataType, SizeType32, int64_t, SizeType32, SizeType32, bool,
tbk::CacheType, std::optional<tensorrt_llm::executor::RetentionPriority>,
std::shared_ptr<tbk::KVCacheEventManager>, bool, bool, std::shared_ptr<tbc::KvCacheConnectorManager>,
bool, SizeType32, SizeType32, bool, std::optional<tbk::LinearAttentionMetadata>>(),
bool, SizeType32, SizeType32, bool, std::optional<tbk::LinearAttentionMetadata>,
std::vector<tbk::PoolConfiguration> const&>(),
nb::arg("num_kv_heads_per_layer"), nb::arg("size_per_head"), nb::arg("tokens_per_block"),
nb::arg("blocks_per_window"), nb::arg("max_num_sequences"), nb::arg("max_beam_width"),
nb::arg("max_attention_window_vec"), nb::arg("dtype"), nb::arg("sink_token_length"), nb::arg("stream"),
Expand All @@ -641,14 +663,21 @@ void tb::kv_cache_manager::KVCacheManagerBindings::initBindings(nb::module_& m)
nb::arg("copy_on_partial_reuse") = true, nb::arg("kv_connector_manager") = nullptr,
nb::arg("enable_indexer_k_cache") = false, nb::arg("indexer_k_cache_quant_block_size") = 128,
nb::arg("indexer_k_cache_index_head_dim") = 0, nb::arg("indexer_k_cache_use_fp4") = false,
nb::arg("linear_attention_metadata").none() = std::nullopt, nb::call_guard<nb::gil_scoped_release>())
nb::arg("linear_attention_metadata").none() = std::nullopt,
nb::arg("pool_configurations") = std::vector<tbk::PoolConfiguration>{},
nb::call_guard<nb::gil_scoped_release>())
.def(
"scheduling_has_free_blocks",
[](tbk::KVCacheManager& self, SizeType32 numRequired, SizeType32 windowSize)
{ return self.getBlockManager().schedulingHasFreeBlocks(numRequired, windowSize); },
nb::arg("num_required"), nb::arg("window_size"), nb::call_guard<nb::gil_scoped_release>())
.def_prop_ro(
"is_variable_window", [](tbk::KVCacheManager& self) { return self.getBlockManager().isVariableWindow(); })
// Per-pool introspection: lets Python discover (windowSize, sizePerHead, dtype) per
// hosted pool so a single KVCacheManager can host mixed-shape pools without a
// Python-side wrapper duplicating the layer->pool routing.
.def_prop_ro("pool_configurations",
[](tbk::KVCacheManager& self) { return self.getBlockManager().getPoolConfigurations(); })
.def("copy_linear_attention_block", &tbk::KVCacheManager::copyLinearAttentionBlock, nb::arg("llm_request"),
nb::call_guard<nb::gil_scoped_release>())
.def("copy_linear_attention_block_batch", &tbk::KVCacheManager::copyLinearAttentionBlockBatch,
Expand Down
Loading
Loading