ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Day 12·2 磁盘KV快照格式:0.47GB从哪来

Day 12·2 磁盘KV快照格式:0.47GB从哪来 真机实测通过本文实验已在 RK3588 板端实测完成2026-09方法学与原始记录见仓库 docs 与《实验脚本》目录一句话导读跨进程恢复进程内缓存再快、进程一死全没真实服务必遇更新与重启——本篇讲--disk-kv把 KV 快照落盘、新进程扫描建索引、重启后按前缀找回复用回答“服务重启了会话为什么不能断”。11-3 结尾说了句扎心的实话进程内缓存再快进程一死全没。真实服务一定会碰到“更新/重启/断电”。今天解决它--disk-kv把 KV 快照落盘重启后按前缀找回——仓库基准报告里的13.1× 跨进程恢复就是这条路径。1. 知识点为什么“进程内缓存”救不了重启11-3 的缓存一生里KV 区是进程内存的一部分进程退出 → 内存归还 OS → 算好的 KV 烟消云散重启后客户端重发同样的历史 → 引擎只能从零全量 prefill——多轮长会话直接回到“最贵的那一段”。解决思路直白得像把大象装进冰箱把 KV 从内存“复制”到磁盘。存下三样东西token 序列这一段的身份跨进程的“缓存键”——11-2 的 LCP 在磁盘上同样适用KV 行K、V 张量跨进程的“缓存状态”模型几何层数、头数、维度——防止用错模型的快照去恢复几何不符直接跳过。重启后新进程扫描目录建索引把请求的 token 序列与每个快照做 LCP还是 11-2 那套kv_lcp最长且 ≥16 的命中就把 KV 读回内存然后只 prefill 增量尾巴。用户在客户端无感知——他照常重发全历史引擎在内部把“全量重算”偷换成“读盘 算尾巴”。两个诚实边界先摆出来F32 快照很大28 层 × 8 KV 头 × 128 维 × 4B ×KV 229 KB/token——8K 会话 ≈ 1.87 GB。它买的是位级一致恢复 重算贵但绝不引入误差落盘有成本turn1 响应后要同步写盘8K 会话 16s wall这个成本换“重启不丢长会话”。2. 对应代码save/load 与“启动扫描建索引”写盘vllm_safetensors.c 第 12357 行st_kv_disk_save头注释第 12312–12335 行把文件布局写得明明白白——64B 头VLKVmagic 版本 几何 token 数 FNV-1a 哈希 token ids 逐层逐块的 K/V F32 行。每层按kv_bs块写先 K 块后 V 块第 12389–12400 行尾块只写有效行。serve 侧触发vllm_server.c 第 620–621 行每个成功的文本请求结束后调用 save并打印[KV-DISK] saved %d-token KV - %s。启动建索引 命中恢复新进程启动时vllm_server_diskkv_scan扫描目录main.c 第 4465/4717 行serve 日志[KV-DISK] index: N checkpoint(s)把每个快照的 token 序列读进内存请求来时vllm_server.c 第 1308–1317 行用dkv_best_lcp找最长前缀命中st_kv_disk_load读回日志打[KV-DISK] loaded %d-token KV prefix from %s。读回第 12406 行st_kv_disk_load先校验头里每个几何字段——有一个对不上就拒载第 12428–12430 行这是“绝不用错模型的 KV”的硬闸随后跳过 token ids它们已被 serve 层 LCP 逐 token 验证过只按文件块的边界把 K/V 行读进缓存。容量纪律快照上限DISKKV_MAX_TOKENS 8192vllm_server.c 第 451 行覆盖 max_seq 窗口、目录最多DISKKV_MAX_FILES 8个文件、按 mtime LRU 淘汰第 648 行——磁盘缓存不是无限膨胀的。3. 改动后果同一台板子跨进程恢复实测口径RK3588 / Qwen3-VL-2B / 2026-09 /--disk-kv//v1/completions贪婪。S1 进程全量 prefill 2K 上下文并生成回答 → 快照落盘 →杀掉 S1→ 启动 S2 → 客户端重发“历史追问”观察 S2 是“读盘恢复 增量”还是“全量重算”。阶段事件实测S1turn1 全量prefill 2044-token 上下文46.37 s请求总耗时 51.34 s日志[KV-DISK] saved 2056-token KV - kv_a0db…cb8.kv落盘快照写入 eMMC471,605,344 B≈450 MiBls 实测杀 S1 / 启 S2模拟“服务重启”S2 启动即扫描目录[KV-DISK] index: 1 checkpoint(s)S2turn2历史追问恢复 增量日志loaded 2034-token KV prefixprefilln31 / 1.96 s请求总耗时 7.27 s判读S2 没有全量重算日志loaded 2034-token KV prefix from kv_a0db…证明恢复的是 S1 的 KV[PREFILL-TIMING] n31 total1962.2ms证明只算了增量尾巴本轮 31 个新 tokenprefill 加速 ≈23.6×46.37s → 1.96s请求总耗时 51.34s → 7.27s≈7.1×双方都含 decode见 12-3 的“口径拆解”输出正确S2 在恢复的完整上下文上答出了追问——Based on the provided information, Bob lives in Tokyo.KV 是“算出来的状态”恢复 重算F32 位级一致所以回答与从未重启一致。仓库基准报告的 8K 档同款实验RK3588_性能基准报告.md §3.2turn1 全量 TTFT 201.7s → 快照 1.87 GB16s 写盘→ 重启 boot 1.0s → 恢复后首 token15.4sloaded 8104-token prefix→ 相对全量13.1×。llama.cpp 无等价物重启即失诚实标注这是本引擎相对它的架构级差异。我们这轮 2K 复现的 prefill 口径加速比 ≈23.6×、与 13.1× 同向差异来自上下文比例与口径12-3 细拆。4. 学员调试任务A 档板端动手复刻第 3 节S1 发长 prompt → 记[KV-DISK] saved与快照文件大小杀进程S2 同参启动 → 重发“历史追问” → 抄[KV-DISK] loaded与[PREFILL-TIMING] n。用ls -la看快照字节数对照 12-2 的公式估算是否吻合。把上下文拉长一档再跑观察加速比变化。B 档纯读源码读st_kv_disk_loadvllm_safetensors.c 第 12406 行起的几何校验段回答① 换一个不同几何的模型加载同一个 kv 目录会不会发生错误恢复② 文件名是 token 序列的 FNV-1a 哈希——哈希碰撞最坏会怎样提示serve 层还做逐 token LCP预期输出你能演示一次“杀掉进程再回来会话没断”的完整闭环并报出自己的恢复加速比与快照字节数。收尾本篇源码点名vllm_safetensors.cst_kv_disk_save12357、st_kv_disk_load12406、布局注释 12312–12335、vllm_server.csave 620、索引 560、LRU 648、DISKKV_MAX_TOKENS451、命中路径 1308–1317、main.c--disk-kv4798、启动扫描 4465/4717。开源仓库Kestrel-LLM (Gitee)源码可得双许可学习 / 学术研究免费下篇预告快照文件里到底躺着什么12-2 用xxd拆一个真实的.kv文件VLKV 头、token ids、按块排布的 K/V——顺便回答“为什么 2K 会话就要 ~0.47GB”。关键词跨进程恢复、磁盘 KV、KV cache、前缀缓存上一篇Day 12·1 跨进程KV恢复服务重启后让会话不断下一篇Day 12·3 复现 13.1×——跨进程恢复实测怎么做含口径拆解
返回列表