
Checkpoint erasure during normal conversation flow due to is_last_user_message bypass of checkpoint_min_step
快速结论:该报错发生在长时间运行的大模型对话流程(如 Agent 工作流)中,密集的用户消息会导致 checkpoint 被错误地频繁创建,从而压缩了 checkpoint 窗口,最终引发缓存失效和全量重计算。优先排查 checkpoint_min_step 是否被 is_last_user_message 逻辑绕过。
问题场景
用户在 llama.cpp 的 llama-server 中启用上下文 checkpoint 功能,运行长时间 Agent 工作流(连续多轮对话,上下文长度约 138K token)。关键参数:llama-server --ctx-checkpoints 8 --checkpoint-min-step 8192。
报错原文
llama_server : [task 21487] request at position 30,646 outside checkpoint window, erasing all checkpoints
llama_server : reprocessing 40,000 tokens... 18.2s
日志中还会出现大量间距远小于 checkpoint_min_step 的 checkpoint(如间距 2–304 token),以及 f_keep 值从 0.96–0.99 骤降至 0.350 甚至 -1.0 的情况。
原因分析
根本原因:在 tools/server/server-context.cpp 的 checkpoint 创建逻辑中,is_last_user_message 条件直接跳过了 checkpoint_min_step 的间距检查。在 Agent 工作流中,每一轮对话的最后一个用户消息都会触发此条件,导致 checkpoint 以极短间距(2–304 token)被密集创建。这使得有限的 checkpoint 槽位(如 8 个)只能覆盖非常窄的上下文窗口(约 7.4K token),远小于预期跨度(8×8192≈57K token)。当后续请求引用窗口外的位置时,所有 checkpoint 被清空并触发全量重计算。
关键代码行(约第 3564 行):
do_checkpoint = do_checkpoint && (slot.prompt.checkpoints.empty() || is_last_user_message || n_tokens_start > slot.prompt.checkpoints.back().n_tokens + params_base.checkpoint_min_step);
环境排查
- llama.cpp 版本为 commit 27407af(对应构建号 9789)
- GPU:NVIDIA RTX 4090
- 需确认
--ctx-checkpoints数量和--checkpoint-min-step配置值 - 检查
llama.cpp-router.log日志中的 checkpoint 间距和擦除事件
解决步骤
- 应用补丁(可优先尝试):修复方式为对
is_last_user_message引入“宽松下限”(relaxed floor),要求即使对于最后一个用户消息,也需要满足checkpoint_min_step / 2的最小间距。该修复已在本地分支9895 (a4107133a)中验证通过。 - 补丁代码:修改
tools/server/server-context.cpp第 3573–3579 行,将:do_checkpoint = do_checkpoint && (slot.prompt.checkpoints.empty() || is_last_user_message || n_tokens_start > slot.prompt.checkpoints.back().n_tokens + params_base.checkpoint_min_step);替换为:
const int32_t checkpoint_floor = slot.prompt.checkpoints.empty() ? 0 : slot.prompt.checkpoints.back().n_tokens + params_base.checkpoint_min_step / 2; do_checkpoint = do_checkpoint && (slot.prompt.checkpoints.empty() || (is_last_user_message && n_tokens_start > checkpoint_floor) || n_tokens_start > slot.prompt.checkpoints.back().n_tokens + params_base.checkpoint_min_step); - 重新编译并测试:保存修改后重新编译 llama.cpp,使用相同参数启动
llama-server并运行多轮 Agent 对话。
验证方法
观察 llama-server 日志中的 checkpoint 创建记录:
- 确认 checkpoint 间距不再远小于
checkpoint_min_step(如原本间距 2–304 token 的情况应消失) - 检查
f_keep值应稳定在 0.96–0.99 附近,不再出现骤降至 0.35 或更低 - 确认无新的报错
request at position ... outside checkpoint window, erasing all checkpoints



