Repository navigation
Recipes Integration.zh
sikkatu/recipes 的生产启动器带有一个可选开关,可在不改变配方普通行为的前提下
接入持久化缓存。
启动器(recipes/rtx-pro-6000/mimo-v2.6-pro-hotsplit 中的 scripts/run-tp4-uva.sh、
scripts/run-tp4-hotsplit.sh)包含一个 KV-PERSIST 块:
KV_PERSIST="${KV_PERSIST:-0}"
if [ "$KV_PERSIST" = "1" ]; then
... 派生缓存身份命名空间 ...
MODEL_ARGS=(--model "/models/$KV_PERSIST_NAMESPACE")
MODEL_ARGS+=(--kv-transfer-config "$KV_TRANSFER_CONFIG")
MODEL_ARGS+=(--enable-prompt-tokens-details)
MODEL_ARGS+=(--block-size "$KV_PERSIST_BLOCK_SIZE")
fi-
默认关闭 ——
KV_PERSIST未设置或为0时,配方行为与之前完全一致:无连接器、 无命名空间重挂载、无新参数。普通运行不需要MODEL_DIR,也不需要安装 kv-persistence。 -
开启(
KV_PERSIST=1)时该块做四件事(评审修正,第 19 轮):-
缓存身份命名空间 ——
MODEL_DIR挂载到/models/<命名空间>(而非/model)。 LMCache 以model_config.model(--model的值)为每个 L2 对象做键,因此固定的/model路径会让所有部署共享一个命名空间:不同版本、KV dtype 或几何配置 可能读到彼此的 KV 块。使用命名空间路径后,每个身份拥有独立命名空间,不兼容的部署 得到安全的缓存未命中 —— 前提是命名空间从引擎的实际参数派生(评审修正: 实际的 KV_CACHE_DTYPE、MAX_MODEL_LEN、block size、TP size 作为 KVP_* 覆盖传递给 CLI,auto先解析为模型的实际 dtype)。命名空间优先取自python3 -m kvpersist.cli model-name(已验证的身份哈希,需找到 kv-persistence 克隆KVP_REPO_ROOT或~/kv-persistence),否则由 KV 兼容性字段的确定性哈希 生成(config.json、权重索引 + shard 大小、tokenizer 文件、chat template、kv dtype、 max-model-len、block size、TP size)。 因此KV_PERSIST=1必须设置MODEL_DIR。 -
--kv-transfer-config—— LMCache 连接器(与 kv-persistence 自身启动器相同的 JSON)。 -
--enable-prompt-tokens-details—— 没有它就不会上报usage.prompt_tokens_details,cached_tokens(唯一机器可读的复用计数器)不可用,且 kv-persistence 的验收测试 (scripts/test-recovery.sh)永远无法 PASS。 - 固定
--block-size(默认 16,通过KV_PERSIST_BLOCK_SIZE覆盖)—— kv-persistence 的身份门禁(verify-engine-identity.sh)需要一个可验证的引擎参数。 参数记录在tp4.env.example/.ru/.zh(三种语言的名称、值和顺序一致):KV_PERSIST、KV_PERSIST_HOST、KV_PERSIST_PORT、KV_PERSIST_NAMESPACE、KV_PERSIST_BLOCK_SIZE。⚠️ KV_PERSIST_NAMESPACE(覆盖)—— 若手动设置,隔离保证由你自行负责: 启动器无法验证 namespace 是否与引擎的实际配置一致。仅在理解身份字段时使用覆盖。
-
缓存身份命名空间 ——
- 按 Quick Start 步骤 1–6 安装并启动缓存服务。
- 在配方的
tp4.env中添加:KV_PERSIST=1
- 如常启动配方:
bash scripts/run-tp4-uva.sh
块激活时启动器会打印两行确认:
KV_PERSIST=1: attaching LMCache connector … 和
KV_PERSIST=1: cache-identity namespace -> /models/<hash> …。
配方的块无法自动运行 kv-persistence 的 verify-engine-identity.sh(配方中未接入
kv-persistence 克隆路径),因此请在信任任何缓存复用之前手动运行:
bash ~/kv-persistence/scripts/verify-engine-identity.sh <容器名>退出码 0 = 身份已验证(在该范围内允许缓存复用)。退出码 4 = MISMATCH(不得复用
缓存 —— 将 configs/mimo-v2.6-pro/identity.env.local 与引擎参数对齐后重跑)。
退出码 5 = INCONCLUSIVE(先修复值来源)。门禁比较容器的启动参数和被服务模型的
config.json;KV_PERSIST=1 时启动器固定了 --block-size 和命名空间挂载,因此所有
字段均可检查。门禁只读取引擎配置 —— 不改变生产行为。
三个不同变量名指向同一端点(评审备注):
| 侧 | 主机 | 端口 |
|---|---|---|
缓存服务(kv-persistence configs/generic/lmcache-server.env) |
LMCACHE_HOST |
LMCACHE_PORT |
缓存服务(kv-persistence configs/generic/cache.env 文档别名) |
KVP_LMCACHE_HOST |
KVP_LMCACHE_PORT |
配方启动器(tp4.env) |
KV_PERSIST_HOST |
KV_PERSIST_PORT |
配方侧是 vLLM 用来连接的;缓存侧是服务监听的。如果在缓存侧更改端口(LMCACHE_PORT),
必须在配方侧 KV_PERSIST_PORT 设置相同值 —— 否则 vLLM 找不到缓存,连接器会静默重试
一个死端点。主机同理。默认值一致(127.0.0.1:5555)。
kv-persistence/scripts/run-vllm-with-persist.sh(专用启动器)和配方的
KV_PERSIST=1 分支现在在所有决定缓存兼容性的地方保持一致:
| 参数 | kv-persistence 启动器 | 配方 KV_PERSIST=1
|
配方普通运行 |
|---|---|---|---|
--model |
/models/<命名空间> |
/models/<命名空间> |
/model 或 MODEL_ID
|
--kv-transfer-config |
是(LMCacheMPConnector) | 是(相同 JSON) | 无 |
--enable-prompt-tokens-details |
是 | 是 | 无 |
--block-size |
16(固定) | 16(固定,经 KV_PERSIST_BLOCK_SIZE) |
不传(引擎默认) |
MAX_NUM_SEQS |
2 | 2 | 2(env;用户实测:速度不受影响,默认值更方便) |
KV_CACHE_DTYPE |
auto(解析为模型 dtype) |
auto(解析为模型 dtype) |
auto(env) |
MAX_MODEL_LEN |
1048576 | 1048576 | 1048576(env) |
| 身份门禁 | 自动(不匹配则拒绝) | 手动提醒 | 无 |
| 专用启动器还会自动运行身份门禁并在不匹配时拒绝挂载缓存;配方分支只提醒你手动 | |||
| 运行。任何身份字段(含 dtype 字符串)的值差异都是安全的缓存未命中 —— 命名空间 | |||
| 哈希改变,两条路径只是停止共享缓存块。它们绝不会读取错误的 KV;只是不再复用。若想 | |||
| 在两条路径间复用,请保持值完全一致。 |
删除 KV_PERSIST=1 行(或设为 0)并重新启动。这就是全部回滚:配方设计上不被触碰,
NVMe 上的缓存数据在禁用期间只是被忽略。
缓存服务必须在启动器接入之前运行。顺序:先 start-cache.sh,后配方启动器。如果
vLLM 启动时服务未运行 —— 移除 KV_PERSIST=1 并使用普通配方(或启动缓存后重新启动)
—— 绝不要让 vLLM 在生产中重试一个死连接器。
| 启动器 | 适用场景 |
|---|---|
run-tp4-uva.sh |
UVA 基线(已验证的配方路径) |
run-tp4-hotsplit.sh |
热/冷专家分离(动态/静态模式) |
kv-persistence/scripts/run-vllm-with-persist.sh |
需要自动身份门禁和完整 kv-persistence 工具链(preflight、benchmark、test-recovery)时 |
三者接受相同的 KV-PERSIST 参数(专用启动器从 kv-persistence 自身的配置读取)。 使用你今天运行的那个。
契约测试(文本检查)加上 sikkatu/recipes/tests/test_kv_persist_behaviour.py
中的行为测试:两个启动器用桩 docker/nvidia-smi/curl/python3 实际
执行,桩 python3 记录块传给它的 KVP_* 覆盖。覆盖范围:命名空间跟随引擎的
实际参数(fp8 与 bfloat16 产生不同命名空间)、auto 解析为模型的有效 dtype、
CLI 失败以真实错误中止启动(无静默 fallback)、KV_PERSIST_NAMESPACE 覆盖被
遵守、普通运行(KV_PERSIST=0)不派生任何命名空间、KV_PERSIST_BLOCK_SIZE 同时
到达 CLI 与 --block-size、model_name 前缀在两个启动器间稳定(两条路径都是
mimo-pro/<hash>)。kv-persistence 另有
tests/unit/test_launcher_namespace_coherence.py,执行
run-vllm-with-persist.sh 的真实默认值表达式 —— 回退到 basename $MODEL_DIR
会让测试失败。
缓存服务器本身、容量策略、身份固定和管理工具位于
kv-persistence;其 wiki 是设置、持久化
验证和回滚的参考。注意恢复验收(scripts/test-recovery.sh)仍需在 GPU 主机上实际
运行 —— 诚实状态见 kv-persistence 的 docs/final-report.md。配方的契约测试验证
启动器包含该机制;它们本身并不能证明真实的 NVMe 恢复。