使用llama-server自托管?修复每次轮次中提示缓存重载的问题
摘要
一份故障排除指南展示了将OpenClaw的contextInjection设置从 'always' 更改为 'continuation-skip' 后,如何解决使用 llama-server 时每次对话都会重载提示缓存的问题,从而在长时间会话中实现100倍的加速。
长话短说:我的 OpenClaw 会话随着增长变得越来越慢。在 90k+ token 时,每次回复都需要超过 2 分钟。我以为是 llama.cpp 的问题。但并不是。是 OpenClaw 的一个设置,它在每次轮次中默默使提示缓存失效。
**环境配置**
- Qwen3.6-27B-Q8_0 在双 RTX 3090 上(张量并行)
- llama-server 使用 `--cache-prompt`、`--ctx-size 400000`、`--parallel 2`
- OpenClaw 通过局域网连接
- 一切在会话超过约 90k token 之前都很快
**症状**
llama-server 日志在每次轮次显示:
```
forcing full prompt re-processing due to lack of cache data
erased invalidated context checkpoint (pos_min = 57172)
erased invalidated context checkpoint (pos_min = 60139)
erased invalidated context checkpoint (pos_min = 91076)
prompt eval time = 130511 ms / 91403 tokens
```
从头重新处理 91k token。130 秒。每次轮次都这样。
缓存已启用。检查点也存在。但 llama.cpp 一直找不到匹配,回退到完全重新处理。
**我首先检查的(不是问题所在)**
- `--ctx-size` 没问题(仍然从 320k 提高到 400k)
- `--cache-prompt` 已启用
- `--cache-reuse` 和 `--ctx-checkpoints` 已设置
- VRAM 不是瓶颈(双 3090,有大量余量)
- 模型量化稳定(Q8_0)
- GPU 性能正常(~25 tok/s 生成,~700 tok/s 提示处理)
llama.cpp 这边没有任何问题。服务器完全按指令执行。
**实际元凶**
OpenClaw 有一个名为 `contextInjection` 的设置。默认值为 `always`。这意味着 OpenClaw 会在每次轮次时将所有的 workspace 引导文件(AGENTS.md、SOUL.md、USER.md、TOOLS.md、MEMORY.md、HEARTBEAT.md,大约 15kb 文本)重新注入到系统提示中。包括在助手回复完成后的续接轮次。
llama.cpp 的提示缓存通过精确匹配 token 序列来工作。如果前缀发生任何细微变化,缓存就无法重用。通过每次轮次重新注入引导文件,OpenClaw 改变了系统提示的结构。时间戳偏移了。动态上下文变化了。token 序列不再匹配缓存的检查点。llama.cpp 正确地拒绝使用过期缓存,并重新处理一切。
缓存没有坏。只是每次轮次都被喂了不同的提示。
**修复方法**
```bash
openclaw config set agents.defaults.contextInjection continuation-skip --merge
```
然后重启网关。
`continuation-skip` 的含义是:仅在新用户消息时注入引导文件。在续接轮次中跳过它们。提示保持稳定。缓存保持有效。
**结果**
之前:
- 每次轮次重新处理 91,403 个 token
- 提示评估时间 130 秒
- 0% 缓存重用
- 长会话中每次回复超过 2 分钟
之后:
- 每次轮次仅处理 513 个新 token(仅实际新内容)
- 提示评估时间 1.3 秒
- 99.7% 缓存重用
- 每次回复约 5 秒
速度快 100 倍。相同硬件。相同模型。一行配置。
**为什么这很重要**
如果你在本地使用 llama.cpp 后端运行 OpenClaw,并且发现长会话变慢,请检查你的 llama-server 日志中是否有 `forcing full prompt re-processing`。如果看到它,问题很可能出在客户端,而不是服务器端。
默认的 `contextInjection: always` 对于每个调用独立的云 API 来说是合理的。但对于具有持久 KV 缓存的本地服务器来说则不合理。
这可能是任何运行 OpenClaw 与 llama.cpp 的人影响最大的设置。
**我们调整的其他项(非根本原因,但也值得做)**
- 将 `--ctx-size` 从 320k 提高到 400k(每个会话从 160k 提高到 200k)
- 将 OpenClaw 的 contextTokens 设置为 200k 以匹配
- 将 memoryFlush.softThresholdTokens 从 30k 降低到 10k,以便稍后刷新内存
这些是很好的改进,但缓存修复纯粹是 contextInjection 更改。
**如何自行诊断**
```bash
ssh your-server "journalctl -u llama.service --no-pager -n 50 | grep -iE 'cache|re-process|checkpoint'"
```
缓存损坏:
- `forcing full prompt re-processing due to lack of cache data`
- `erased invalidated context checkpoint`(重复多次)
- 提示处理时间超过 30 秒
健康缓存:
- `restored context checkpoint`
- `f_keep = 0.99+`
- `graphs reused =`(大数字)
- 提示处理时间低于 5 秒
希望这能节省其他人像我们一样花几个小时调试的时间。
相似文章
Llama-Server 正在丢弃您完美的KV缓存,以及如何修复
本文详细介绍了一个关键bug:在llama-server中,由于缺少检查点元数据,恢复的KV缓存会立即被丢弃。文章提供了一个117行的修复方法,使用sidecar文件跨重启持久化检查点,实现了约720倍的预填充加速。
如何在重新启动 llama.cpp 后处理长上下文会话?
用户提出在 llama.cpp 中为长上下文会话实现自动缓存机制,以避免重启后的重复预填充,提升在较慢硬件上的可用性。
CachyLLama:一个带有持久化KV缓存的llama.cpp分支,让长时间本地代理会话不再那么痛苦
CachyLLama是llama.cpp的一个分支,它增加了基于SSD的持久化KV缓存和多层缓存,显著减少了在较慢硬件上长时间本地代理会话的提示重新处理时间。
llama.cpp 中提示查询草稿生成速度提升 42 倍
本文详细介绍了 llama.cpp 中的性能优化,这些优化使得提示查询草稿生成速度最高提升 42 倍,并将内存使用减少 2.6 倍,基于 Daniel Lemire 和 Martin Ankerl 的技术。
Llama.cpp 服务器连续运行约两周后表现失常?
用户报告,在 llama.cpp 服务器上连续运行约两周后,Qwen3.6 模型的能力显著下降,且重启会话无法解决此问题。