快速结论:该报错(Misc. bug: server: slot KV is reused after the global lora config changes)通常出现在 llama-server 切换全局 LoRA 配置(POST /lora-adapters)后,后续请求未携带 lora 字段却复用了旧 KV 缓存的场景;应优先排查 slot 的 LoRA 一致性判断是否只覆盖了显式 lora 的情况。
适用环境:llama.cpp 0.6.0-dev(build 11552,commit 23b0202a1),AppleClang 17.0.0.17000603 编译的 Darwin arm64,macOS;受影响模块为 llama-server。Issue 未给出 Python、CUDA、PyTorch 版本信息,无法据此判断这些依赖。
最快修复方案:暂无确认的一步修复方案。Issue 评论给出的改法是:在复用 slot KV 缓存前先解析出实际生效的 LoRA 列表(target_lora),对每个任务都比较 slot.lora 与 target_lora,不一致就清空 slot.cache_tokens;该改法尚未见合并验证。
注意事项:复现时 --cache-ram 0(RAM 缓存关闭)仍会触发,说明与 --cache-ram 路径的修复(#30275)不是同一处;临时把 cache_prompt 设为 false、或在请求中显式携带 lora 字段,可绕开该问题,但会增加重复计算。
问题场景
在 llama-server 中加载 MoE 基础模型与 LoRA 适配器(示例使用 stories15M_MOE-F16.gguf 与 moe_shakespeare15M.gguf,并带 --lora-init-without-apply、-np 1、-c 2048、--cache-ram 0、-fit off)。先用 POST /lora-adapters 设置某个 scale,再发送不带 lora 字段的 POST /completion 请求(cache_prompt 默认 true),然后通过 POST /lora-adapters 切换 scale,再发同样的 completion 请求。此时服务端报告 cache_n: 46, prompt_n: 1,即沿用了旧配置下计算的 KV 缓存,输出错误。把新 scale 写进 completion 请求的 lora 字段时,缓存会被清空、输出正确。反向情况同样成立:先发带 lora 的请求,再发不带 lora 的请求,也会复用旧 KV。
报错原文
Misc. bug: server: slot KV is reused after the global lora config changes
Step 4 returns `cache_n: 46, prompt_n: 1`, so it reused the KV from step 2.
{
"content": "\nThe mother praise not the time and the child of the two of the",
"timings": {
"cache_n": 46,
"prompt_n": 1,
"prompt_ms": 7.979,
"prompt_per_token_ms": 7.979,
"prompt_per_second": 125.32898859506204,
"predicted_n": 16,
"predicted_ms": 32.512,
"predicted_per_token_ms": 2.167466666666667,
"predicted_per_second": 461.36811023622045
}
}
原因分析
根据 Issue 评论,原因在于:不带显式 "lora" 字段的 completion 任务会让 task.lora 为空,语义上表示“回退到服务端当前的 params_base.lora”;但 slot KV 失效判断只在 !task.lora.empty() 时触发,并且比较对象是 task.lora。由此留下两个盲区:
1)POST /lora-adapters 更新了 params_base.lora,而下一个 completion 请求未带 lora,因此不会拿 slot.lora 与更新后的 params_base.lora 比较;2)一个带显式 lora 的请求覆盖了 slot.lora,后续请求未带 lora 并重新采用 params_base.lora,两者不同却被 task.lora.empty() 跳过比较。Issue 还指出,首个引入问题的提交为 6ce863c(#18263),其前一提交会在 scale 变化后重新计算 prompt(cache_n 0),而该提交改为复用 KV(cache_n 46)。
环境排查
- 确认 llama.cpp 版本与构建信息:0.6.0-dev(build 11552,commit 23b0202a1),AppleClang 17.0.0.17000603,Darwin arm64。
- 确认运行模块为 llama-server,并记录启动参数中是否含
--lora-init-without-apply、--cache-ram、-np。 - 确认是否应用了 #30275 的 RAM prompt cache 修复:Issue 说明应用该 PR 后本复现仍失败,且
--cache-ram开或关均失败。 - 通过
POST /lora-adapters与 completion 请求中的lora字段分别测试,以区分全局配置路径与请求内显式路径。 - Issue 未提供 Python、CUDA、PyTorch 信息,如按其他部署环境排查,这些项目需另行核对。
解决步骤
- 先按要求复现:依次执行
POST /lora-adapters([{"id":0,"scale":0}])、不带lora的POST /completion、POST /lora-adapters([{"id":0,"scale":1}])、同样的 completion 请求,记录返回中的cache_n与prompt_n,确认是否出现cache_n: 46, prompt_n: 1。 - 做对照:同样的 completion 请求加上
"cache_prompt": false,或把新 scale 写进请求的lora字段,确认输出与缓存行为是否改变;若改变,可进一步定位到 slot KV 复用判断。 - 在
tools/server/server-context.cpp中,在判断 slot KV 缓存能否复用前,先解析实际生效的 LoRA 列表:const auto & target_lora = task.lora.empty() ? params_base.lora : task.lora;。 - 改为无论
task.lora是否为空,都比较slot.lora与target_lora;当!are_lora_equal(slot.lora, target_lora)时,清空slot.cache_tokens并把slot.lora设为target_lora。 - 若只是使用层面临时规避,可优先尝试:仅通过 completion 请求的
lora字段切换 scale,或在不确定 LoRA 状态时使用"cache_prompt": false。 - 对于在 llama-server 中固定组合多个 LoRA 的工作流,Issue 评论另建议在转换为 GGUF 之前,用
loraspectra(loraspectra merge --mode ortho-svd)离线合并为单个正交化.safetensors适配器,从而避免运行时多适配器切换;该做法属于替代方案,不是本 bug 的直接补丁。
验证方法
重新执行两条复现路径:切换 POST /lora-adapters 后的请求应返回 cache_n: 0 并重新计算完整 prompt(示例为 47 个 token),输出应与 cache_prompt: false 时一致;先带显式 lora 再不带 lora 的请求也应清空缓存而不是复用旧 KV。同时在 --cache-ram 0 条件下重复验证,确认两种情况都不再复用旧配置计算的 KV。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


