In-Depth Study of LM Cache Integration in vLLM

LMCacheConnectorV1

初始化

  1. 创建 LMCacheConnectorLatestImpl,支持外部路径和内部路径
  2. 创建 KVConnectorKVEvents

注意:与 CUDA 有一些特殊处理问题,因为加载 cache 不是在 forward 前后处理的,而是在 forward 内部处理的。可能是为了解决延迟的问题。

Worker Side

register_kv_caches

调用 self.lmcache_engine.post_init(kvcaches=kvcaches) 注册 KV cache。

start_load_kv

  1. self.lmcache_engine.post_init - 初始化引擎
  2. slot-map to CUDA(slot 相当于 token 的物理地址)
  3. 创建 mask 标记哪些需要加载
  4. Blend:从多个缓存源智能选择最新数据
  5. 预加载两层

wait_for_layer_load

等待当前层数据加载完成。

next(retriever)  # 阻塞等待数据加载到 GPU

save_kv_layer

异步启动 KV cache 保存操作(GPU → 外部存储)。

next(storer)  # 异步等待数据从 GPU 写出

wait_for_save

等待所有保存操作完成。

  1. self.lmcache_engine.lookup_unpin - 取消 pin 状态
  2. store_layer 来阻塞等待
  3. self.lmcache_engine.store - 执行存储
next(storer)  # 等待最后一层保存完成

设计模式:通过迭代器实现异步操作的同时保持阻塞控制。

Scheduler Side

get_num_new_matched_tokens

  1. 使用 token 直接查询(client 如何实现?)
  2. 使用 load_specs_lookup_requests_in_step 来传递信息

update_state_after_alloc

  1. 清除 lookup 状态
  2. 保存 request 信息
  3. 检查状态
  4. 更新 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

把任务打包,构建传输元数据。