执行摘要
- 一句话:重构 HiCache 主机池管理,多池统一编排,净删 152 行
- 推荐动作:值得精读。重点学习
HostPoolGroup 的 anchor + sidecar 组合、resolve_host_transfers 的原子分配与 rollback、packed_draft_device_pools 对 MTP draft 传输的剥离,这些设计对后续新增池类型(更多模型状态、更复杂的 draft 方案)有直接指导意义。建议在合入后重点补跑 GPU 套件与 HiCache + draft 的端到端回归,确认删除的 legacy 路径没有隐性依赖。
功能与动机
PR body 明确说明:主机缓存不再只是一块 L2 KV 缓冲,同一主机内存层现在承担三个角色:
1) 在存储层(L3)与设备内存(L1)之间暂存数据,2) 以 L2 形态保留缓存状态,3) 备份与恢复多种模型状态。旧接口仍把 host 池当成单一物理 KV 池,“every additional pool type needed special fields and controller branches”,Draft KV 是最典型例子:注册、分配、存储 I/O、传输、清理各自独立成路径。本次重构的目标是让 host-pool 管理对 UnifiedRadixCache 可组合,避免每新增一个池类型都要向控制器塞入专属分支。
实现拆解
- 抽取并增强池描述模型。新增
python/sglang/srt/mem_cache/pool_host/group.py,定义 PoolEntry dataclass(name、host_pool、device_pool、layer_mapper、is_primary_index_anchor、淘汰/分配回调、packed_draft_device_pools)与 HostPoolGroup 类(add_entry、get_entry、get_pool、alloc、free、resolve_host_transfers、release_transfers、_refresh_transfer_capabilities)。PoolEntry 与 HostPoolGroup 原定义从 memory_pool_host.py 尾部整体移除(净 -133 行),改由 pool_host/__init__.py 统一导出,避免破坏既有 import 链。
- 统一多池分配与传输解析入口。
hybrid_cache_controller.py 的 write() 改为调用 self.mem_pool_host.resolve_host_transfers(extra_pools, primary_device_indices=..., primary_host_indices=...);unified_radix_cache.py 的 retraction_backup、retraction_restore 与 retraction_discard 分别改用 host_pool_group.resolve_host_transfers、_resolve_device_transfers、release_transfers。调用方不再传 alloc_host、kv_device_indices、kv_host_indices。
- 删除控制器中的 draft 专用状态。
cache_controller.py 移除 has_draft、mem_pool_device_draft、mem_pool_host_draft、draft_page_get_func、draft_page_set_func、has_mtp_draft、mtp_draft_device_pools 等字段,以及 set_draft_kv_pool、set_mtp_draft_pools、_maybe_register_draft_with_storage、_draft_page_* 方法;新增 storage_host_pool 显式指向存储后端所需的物理 KV 池,避免 mem_pool_host 一词二义。
- 标准化 draft 池注册与 MTP 打包映射。
kv_cache_builder.maybe_register_hicache_draft 删除 legacy 分支,非 UnifiedRadixCache 直接抛 NotImplementedError;独立存储的 draft 池以 SidecarPoolSpec + PoolEntry 经 unified_radix_cache.register_sidecar_pool(spec, entry) 注册,L3 启用时注册物理池到存储后端;packed MTP draft 不单独占 host 分配,由所属 PoolEntry.packed_draft_device_pools 记录 device 视图,_l2_load_transfers 遍历 entry_map 推导 draft 层映射并追加 L2Transfer(is_draft=True)。
- 测试与配置配套。
test_mem_pool_host.py 新增 test_resolve_and_release_multi_pool_allocation 与 test_resolve_rolls_back_partial_allocation,覆盖多池分配、派生索引复用与失败回滚;test_hicache_staged_write_back_dispatch.py 适配新 API;第二个提交更新 config exposure ratchet。CI 十组 base-a-test-cpu 分片通过,GPU suite 在 PR 关闭时仍在运行。
关键文件:
python/sglang/srt/mem_cache/pool_host/group.py(模块 主机池组;类别 source;类型 core-logic;符号 PoolEntry, HostPoolGroup, _refresh_transfer_capabilities, add_entry): 本次重构的核心新增文件,承载 PoolEntry 与 HostPoolGroup,是多池统一编排、原子分配/回滚与生命周期管理的入口。
python/sglang/srt/managers/cache_controller.py(模块 缓存控制器;类别 source;类型 entrypoint;符号 storage_host_pool, attach_storage_backend, set_draft_kv_pool, set_mtp_draft_pools): 重构的主入口,删除约 168 行 draft 专用字段/分支,新增 storage_host_pool 锚定存储物理池,是理解整个重构收益的关键文件。
python/sglang/srt/mem_cache/memory_pool_host.py(模块 主机内存池;类别 source;类型 refactor;符号 PoolEntry, HostPoolGroup, add_entry): 原 PoolEntry/HostPoolGroup 定义所在,重构后整体迁移至 pool_host/group.py,净 -133 行,是理解接口迁移路径的关键文件。
python/sglang/srt/mem_cache/hybrid_cache/hybrid_cache_controller.py(模块 混合缓存;类别 source;类型 entrypoint;符号 write, _l2_load_transfers, _l2_transfers, draft_layer_mapper): 控制器适配新 group API:write 走 resolve_host_transfers,_l2_load_transfers 按 packed_draft_device_pools 推导 draft 层映射,是 packed MTP 路径的实际落点。
python/sglang/srt/mem_cache/unified_radix_cache.py(模块 基数缓存;类别 source;类型 dependency-wiring;符号 register_sidecar_pool, register_hicache_draft_pools, retraction_backup, retraction_restore): 侧车池注册与 retraction 路径改用 host_pool_group 统一分配/释放,并负责 group 生命周期,是多池语义在缓存树侧的接入点。
python/sglang/srt/mem_cache/kv_cache_builder.py(模块 缓存构建器;类别 source;类型 dependency-wiring;符号 maybe_register_hicache_draft, _register_legacy_hicache_draft): 删除 legacy draft 注册,非 UnifiedRadixCache 直接报错,draft 注册改走通用 sidecar 路径,明确新接口的适用范围。
test/registered/unit/mem_cache/test_mem_pool_host.py(模块 单元测试;类别 test;类型 test-coverage;符号 TestHostPoolGroup, test_resolve_and_release_multi_pool_allocation, test_resolve_rolls_back_partial_allocation): 新增多池分配与失败回滚单元测试,是本次重构多池语义的关键验证。
test/registered/unit/mem_cache/test_hicache_staged_write_back_dispatch.py(模块 回归测试;类别 test;类型 test-coverage): 适配新多池 API 的回归测试,验证 staged write-back 路径不受重构影响。
关键符号:HostPoolGroup.init, HostPoolGroup._refresh_transfer_capabilities, HostPoolGroup.add_entry, HostPoolGroup.alloc, HostPoolGroup.free, HostPoolGroup.resolve_host_transfers, HostPoolGroup.release_transfers, UnifiedRadixCache.register_sidecar_pool, UnifiedRadixCache.retraction_backup, HybridCacheController._l2_load_transfers, HybridCacheController.write, cache_controller.attach_storage_backend, kv_cache_builder.maybe_register_hicache_draft
关键源码片段
python/sglang/srt/managers/cache_controller.py
重构的主入口,删除约 168 行 draft 专用字段/分支,新增 storage_host_pool 锚定存储物理池,是理解整个重构收益的关键文件。
# 重构前,这里还有 has_draft / mem_pool_device_draft /
# mem_pool_host_draft / draft_page_get_func / draft_page_set_func /
# has_mtp_draft / mtp_draft_device_pools 等一整套 draft 专用字段,
# 以及 set_draft_kv_pool / set_mtp_draft_pools / _maybe_register_draft_with_storage
# 与 _draft_page_* 系列方法。重构后 draft 不再是特殊池类型,
# 统一由 HostPoolGroup 中的 PoolEntry 描述。
self.mem_pool_host = mem_pool_host
# 存储后端需要的是“一个”确切物理池(用于页面序列化),而不是编排组;
# 因此把原先 mem_pool_host 的双重含义拆分:
# mem_pool_host 承担 group 编排语义,storage_host_pool 固定指向物理 KV 池。
self.storage_host_pool = mem_pool_host
# 默认存储页面 IO 函数(可被 attach 覆盖)。
self.page_get_func = self._generic_page_get
self.page_set_func = self._generic_page_set
# attach 存储后端时也改用 storage_host_pool,保证 StorageBackend 拿到的始终是具体物理池。
try:
self.storage_backend = StorageBackendFactory.create_backend(
storage_backend, self.storage_config, self.storage_host_pool
)
self.storage_backend.register_mem_pool_host(self.storage_host_pool)
self.enable_storage = True
评论区精华
该 PR 没有 reviewer 评论或讨论线程,无法提炼交互式交锋。PR body 中披露的关键设计决策包括:anchor entry 机制——用 KV 池作为默认分配目标与兼容属性来源,使既有控制器代码无需感知多池;derived sidecar(indices_from_pool)——复用宿主索引并跳过 release,保证一次分配只释放一次;多池传输的原子分配加回滚策略。未解决疑虑:作者自述未运行模型精度测试与性能基准,GPU 套件(含 test_decode_retraction_backup.py)在合并时仍在运行;Legacy HiRadixCache 被有意排除在新接口之外,对存量用户的影响未见讨论。
风险与影响
- 风险:
- 核心路径大删改:
cache_controller.py 与 memory_pool_host.py 合计删除超过 300 行,draft 路径整体重写,GPU 测试未完成即合入,需要重点关注 test_decode_retraction_backup、staged write-back 路径的回归。
- 兼容性破坏:
kv_cache_builder 对非 UnifiedRadixCache 的 draft 注册直接抛 NotImplementedError,Legacy HiRadixCache 路径不再可用;若存量配置依赖旧 draft 注册方式,启动即失败。
- 属性访问更严格:
HostPoolGroup._refresh_transfer_capabilities 直接访问 entry.host_pool.can_use_write_back_jit(旧代码用 getattr(..., False) 兜底),任何未实现该属性的物理池 entry 会抛 AttributeError。
- 存储后端锚定:
storage_host_pool 必须正确指向 anchor 物理池,hybrid 控制器中显式取 mem_pool_host.anchor_entry.host_pool;若 anchor 选择逻辑出错,页面序列化会绑定错误池。
- 原子回滚复杂度:
resolve_host_transfers 的原子分配/回滚目前仅有单元测试覆盖,多池并发分配与淘汰回调触发场景缺少集成验证。
- 影响:代码维护层面,新增 HostPoolGroup 统一编排层后,后续新增池类型(如更多模型状态)无需再改 controller,只需注册 PoolEntry 与回调,长期降低 HiCache 相关代码维护成本。行为层面,设计上不改变缓存布局、传输内核与模型计算,默认用户行为应无变化,但 Legacy HiRadixCache 用户可能受影响。团队层面,重构横跨 cache_controller、hybrid cache、unified radix cache、SWA/Mamba 组件、存储注册与 KV builder,后续相关 PR 将大量引用新 API,需要关注符号迁移与文档同步。测试层面,新增多池分配与失败回滚单元测试,覆盖了原先缺失的回滚路径。
- 风险标记:核心路径大删改, Legacy HiRadixCache 兼容性破坏, 物理池属性访问无 getattr 兜底, 精度与 GPU 测试未跑, 多池原子回滚依赖新代码
关联脉络
- PR #27010 [HiCache] Fix PP inconsistency with HiCache L3 (#22607): 同属 HiCache 缓存一致性/内存管理主线,修改了 cache_controller.py、unified_radix_cache.py、hybrid_cache_controller.py 等相同模块,可对照理解控制器对 pool/cache 生命周期的既有约束。
- PR #36381 Fix SWA ownership across grouped frees: SWA 池所有权修复与本 PR 将 SWA 作为独立 PoolEntry 纳入 HostPoolGroup 的管理模型直接相关,可验证多池分配/释放语义。
- PR #36186 [Model] Support Nemotron 3.5 Lightning speculative decoding: 涉及 draft 模型支持,与本 PR 将 draft KV 纳入统一 host 池管理的方向一致,未来 draft 路径预计都依赖 PoolEntry/HostPoolGroup 接口。
参与讨论