
Eval bug: Qwen 3.5 Full prompt re-processing on every conversation turn
快速结论:该报错发生在使用 llama-server 运行 Qwen 3.5(Hybrid Attention + Mamba2/SSM 架构)模型进行多轮对话时,由于 server-context.cpp 中的缓存检查逻辑错误地将循环记忆(recurrent memory)的 pos_min 与针对 SWA 模型设计的 pos_min_thold 比较,导致每一轮对话都会强制重新处理完整 prompt。优先排查 llama_model_n_swa() 返回值及 pos_min_thold 的计算方式。
问题场景
用户使用 llama-server(版本 8182、8233、8149,基于 ggml-org/llama.cpp)加载 Qwen 3.5 27B GGUF 模型(如 Qwen3.5-27B.Q8_0.gguf),启用 flash attention 和长上下文(如 131072 tokens),通过 OpenAI 兼容 API 进行多轮对话。问题出现在发送第二轮及后续消息时,触发冗长的完整 prompt 重处理(full prompt re-processing),单次回复延迟可达数分钟。
报错原文
slot update_slots: id 0 | task 302 | n_past = 3, slot.prompt.tokens.size() = 357, seq_id = 0, pos_min = 356, n_swa = 1
slot update_slots: id 0 | task 302 | forcing full prompt re-processing due to lack of cache data (likely due to SWA or hybrid/recurrent memory, see https://github.com/ggml-org/llama.cpp/pull/13194#issuecomment-2868343055)
slot update_slots: id 0 | task 302 | n_tokens = 0, memory_seq_rm [0, end)
slot update_slots: id 0 | task 302 | prompt processing progress, n_tokens = 4096, batch.n_tokens = 4096, progress = 0.277714
<~2 minute wait per batch at 30 tok/s>
slot update_slots: id 0 | task 302 | n_tokens = 4096, memory_seq_rm [4096, end)
slot update_slots: id 0 | task 302 | prompt processing progress, n_tokens = 8192, batch.n_tokens = 4096, progress = 0.555427
其他用户报告类似日志:
srv update_slots: all slots are idle
...
slot update_slots: id 3 | task 30803 | new prompt, n_ctx_slot = 180224, n_keep = 0, task.n_tokens = 32329
slot update_slots: id 3 | task 30803 | n_past = 10995, slot.prompt.tokens.size() = 42687, seq_id = 3, pos_min = 42686, n_swa = 1
slot update_slots: id 3 | task 30803 | Checking checkpoint with [32666, 32666] against 10994...
slot update_slots: id 3 | task 30803 | Checking checkpoint with [30918, 30918] against 10994...
...
slot update_slots: id 3 | task 30803 | restored context checkpoint (pos_min = 10484, pos_max = 10484, n_tokens = 10485, size = 149.063 MiB)
slot update_slots: id 3 | task 30803 | erased invalidated context checkpoint (pos_min = 11078, pos_max = 11078, n_tokens = 11079, n_swa = 1, size = 149.063 MiB)
...
原因分析
可能原因:Qwen 3.5 的混合架构(Hybrid Attention + Mamba2/SSM)中,循环记忆(recurrent memory)的 pos_min(由 llama_memory_seq_pos_min() 返回)总是等于完整序列长度(例如 356 或 42686),而 server-context.cpp 中的缓存检查逻辑原本为 SWA(Sliding Window Attention)模型设计,计算出的 pos_min_thold 值过低(例如 n_past - n_swa,当 n_swa 仅为 1 时约为 30)。由于 pos_min(356)远大于 pos_min_thold(30),代码强制进入完整重处理路径。此外,checkpoint 搜索条件 cur.pos_min < pos_min_thold 同样无法匹配循环记忆场景,导致缓存无法被有效利用。
社区用户确认该问题在较新版本中恶化了:之前偶尔能触发缓存复用(约 1/3 或 50% 的概率),现在几乎持续触发完整重处理。
环境排查
- llama.cpp 版本:确认版本是否为 8182、8233、8149 或更早/更新版本。Issue 中指出问题在多个版本中均被观察到,且近期版本表现更差。
- 模型架构:确认使用 Qwen 3.5(Hybrid Attention + Mamba2/SSM)模型。非 SWA 模型在此逻辑下会返回
n_swa = 1(通过llama_model_n_swa()获取),与纯注意力模型不同。 - 启动参数:检查
--flash-attn on是否启用(非问题关键,但应记录)。 - 系统环境:确认在 AMD ROCm(HIP 后端)、Ryzen CPU + Radeon GPU 上触发。该问题可能不限特定硬件。
解决步骤
- 代码层面的临时修复(需确认是否已合入后续版本):修改
tools/server/server-context.cpp中约 2286–2378 行的逻辑。目前 Issue 中讨论了根本原因,但未提供明确修复方案。社区建议调整针对混合/循环记忆模型的pos_min_thold计算方式,或为 recurrent memory 添加独立的缓存处理分支。 - 升级 llama.cpp 到最新版本:截至 2026-03-08,Issue 状态为“bug-unconfirmed”且已关闭,但修复(如 PR #20087)可能未完全解决。可优先尝试拉取主分支最新代码重新编译。
- 调整服务器参数(临时缓解):
- 增大
--batch-size和--ubatch-size(如 4096/1024)以加快单次重处理速度。 - 考虑减小
-c(上下文长度)以避免极端情况下过长的重处理时间。 - 如果不需要长上下文,可尝试限制
-c 8192或更小值。
- 增大
- 监控日志:添加调试日志
--verbose输出,观察pos_min、pos_min_thold和n_swa的数值,确认是否频繁触发“forcing full prompt re-processing”消息。
验证方法
发送多轮对话请求(如首轮问“法国首都 XX 是?”、第二轮追回“德国呢?”),观察 llama-server 日志中是否出现“forcing full prompt re-processing”以及耗时是否从秒级变为分钟级。若修复后,后续轮次的日志中应显示 n_past 稳步增长而非重置,并且回复时间显著缩短。



