In-Depth Study of LM Cache Integration in vLLM
LMCacheConnectorV1
初始化
- 创建
LMCacheConnectorLatestImpl,支持外部路径和内部路径 - 创建
KVConnectorKVEvents
注意:与 CUDA 有一些特殊处理问题,因为加载 cache 不是在 forward 前后处理的,而是在 forward 内部处理的。可能是为了解决延迟的问题。
Worker Side
register_kv_caches
调用 self.lmcache_engine.post_init(kvcaches=kvcaches) 注册 KV cache。
start_load_kv
self.lmcache_engine.post_init- 初始化引擎- slot-map to CUDA(slot 相当于 token 的物理地址)
- 创建 mask 标记哪些需要加载
- Blend:从多个缓存源智能选择最新数据
- 预加载两层
wait_for_layer_load
等待当前层数据加载完成。
next(retriever) # 阻塞等待数据加载到 GPU
save_kv_layer
异步启动 KV cache 保存操作(GPU → 外部存储)。
next(storer) # 异步等待数据从 GPU 写出
wait_for_save
等待所有保存操作完成。
self.lmcache_engine.lookup_unpin- 取消 pin 状态- 用
store_layer来阻塞等待 self.lmcache_engine.store- 执行存储
next(storer) # 等待最后一层保存完成
设计模式:通过迭代器实现异步操作的同时保持阻塞控制。
Scheduler Side
get_num_new_matched_tokens
- 使用 token 直接查询(client 如何实现?)
- 使用
load_specs和_lookup_requests_in_step来传递信息
update_state_after_alloc
- 清除 lookup 状态
- 保存 request 信息
- 检查状态
- 更新
can_load标志
@dataclass
class DisaggSpec:
req_id: str # 请求 ID
receiver_id: str # 接收方标识 (host + port)
receiver_host: str # 接收方主机地址
receiver_init_port: int # 接收方初始化端口
receiver_alloc_port: int # 接收方分配端口
is_last_prefill: bool = False # 是否是最后一次 prefill
num_transferred_tokens: int = 0 # 已传输的 token 数
传递路径:
update_state_after_alloc
→ tmp_disagg_tracker
→ RequestTracker
→ ReqMeta
→ Worker 侧传输
build_connector_meta
把任务打包,构建传输元数据。