Skip to content

Architecture.zh

sikkatu edited this page Nov 1, 2026 · 5 revisions

English | Русский | 中文

架构

拓扑

聊天客户端(OpenAI 兼容,长消息历史)
   │  /v1/chat/completions
   ▼
vLLM(TP4 或其他并行度,任意模型;生产配方不被修改)
   │  --kv-transfer-config:LMCacheMPConnector
   │  (kv_connector_module_path 固定使用 LMCache 提供的连接器)
   ▼
lmcache 服务(独立进程;ZMQ 请求端口 5555,HTTP 管理 8080)
   │  L1:主机内存缓冲(KVP_L1_SIZE_GB,默认 64 GB)
   ▼
L2 持久层:nixl_store_dynamic / POSIX → NVMe(KVP_CACHE_ROOT)
   淘汰控制器:LRU,trigger_watermark 0.9,eviction_ratio 0.1

数据流

  1. vLLM 计算 KV 块,通过连接器存入 L1(主机内存)。
  2. 存储控制器异步将每个对象写入 L2 —— 每个块键一个文件 (临时文件 + 原子重命名 —— 崩溃绝不会留下半成品文件)。
  3. 查找时先查 L1;未命中落到磁盘上的 L2。磁盘命中会预取进 L1 并返回给 vLLM。 内存索引启动时为空,按确定性文件名惰性填充 —— 这正是两个服务都重启后 仍能恢复的原因。
  4. 退出时 persist_enabled=true 保留 L2 文件(默认值;设为 false 会删除文件, 破坏核心需求)。

为什么选 nixl_store_dynamic

只有这一族 LMCache L2 适配器文档化了持久化/恢复语义:文件按操作打开 (没有随进程消亡的预分配注册表,在 1.5 TB 规模下没有文件描述符数量限制), 查找未命中会落到磁盘上的确定性文件。nixl_store(预分配变体)没有文档化 重启恢复。POSIX 后端是刻意选择的 —— 最简单可靠的 NVMe 路径 —— 不引入任何 GDS 之类的东西。

组件独立性

缓存服务是独立进程。重启 vLLM 不会清空持久 KV 数据;重启缓存服务时数据文件 保留在磁盘上。缓存只存在于进程内存中的模式不满足持久化要求,不使用。

兼容性命名空间

缓存键包含:

  • 模型 ID + 模型版本(完整 40 位十六进制提交 SHA)
  • 分词器名称 + 版本
  • 有效 KV 缓存数据类型(已解析 —— 不接受 auto)
  • KV 几何:块大小、KV 头数、头维度
  • 张量并行度(TP)
  • 连接器名称 + 固定的连接器/vLLM 构建标识
  • 最大模型长度
  • 聊天模板摘要(渲染后模板的 sha256)

命名空间 = kvp-<sha256(字段的规范 JSON)的前 32 个十六进制字符>。 这是逻辑标识符。在 LMCache 存储层,它被转换成 model_name (CacheIdentity.lmcache_model_name()),真正分离磁盘文件的正是它:适配器 nixl_store_dynamic 将文件命名为 <safe_model_name>_<kv_rank>_<group>_<chunkhash>.bin,直接放在 KVP_CACHE_ROOT 下(扁平布局 —— 不存在 kvp-<hash> 目录;每个文件名的 前缀就是携带该命名空间的净化模型名)。 任何空缺/不确定的字段 ⇒ 缓存未命中(重新计算),绝非错误命中。任一字段改变 都会进入新命名空间;旧数据变得不可达,但绝不会被自动删除 (见存储与淘汰)。

模型无关边界

层 位置 模型相关?
身份 / 命名空间 implementation/kvpersist/identity.py 仅输入数据
预算与配额 implementation/kvpersist/budget.py 否
保留排序 implementation/kvpersist/retention.py 否
lmcache 服务 + L2 适配器 configs/generic/* 否
身份与几何配置 configs/<model>/identity.env 是
vLLM 启动器 scripts/run-vllm-with-persist.sh 是

「模型无关」指机制支持多套部署 —— 并非它们的 KV 数据可以互换。 不同模型绝不共享 KV 块。

故障模型

故障 行为
未命中 / 部分命中 只重新计算缺失部分
不兼容条目 按命名空间不可达 ⇒ 未命中
损坏 / 未写完的文件 查找绕过 ⇒ 重新计算;输出绝不会错
写入中断 原子重命名 ⇒ 读者只看到旧文件或新文件
淘汰中断 同样的原子性;文件缺失只是普通未命中
磁盘满 / 预算用尽 拒绝写入;服务继续,只是不再缓存
缓存服务不可用 vLLM 退回无缓存模式;正确性不变
任一进程崩溃 重启 ⇒ 从磁盘惰性重建索引

缓存故障绝不可能破坏输出:最坏情况是重新计算。

进程布局

  • lmcache 服务 —— 后台运行,pid 文件 KVP_CACHE_ROOT/lmcache-server.pid。
  • vLLM 容器 —— 名为 mimo-pro-tp4-kvp(kv-persistence 启动器),或使用 KV_PERSIST=1 集成时配方自身的容器。
  • kvp-admin(控制台命令 / python3 -m kvpersist.cli)—— 报告与显式清理; 绝不会自动运行。

Clone this wiki locally