llama.cpp 修复 DeepSeek V4 Flash 卡死与崩溃
社区开发者为 llama.cpp 提交 DeepSeek V4 Flash 的 SWA 状态 bug 修复,解决每轮迭代…
一名 Reddit 用户(u/HockeyDadNinja)近日向 llama.cpp 提交了一个针对 DeepSeek V4 Flash(DSV4)的修复补丁,主要解决该模型在 llama.cpp 推理时反复出现的卡死与崩溃问题。问题与上游 master 分支中 SWA(Sliding Window Attention)状态无法正确回滚有关,修复后的 fork 已上线供测试。
问题背景与复现环境
作者在一台自组多卡机上运行 DSV4 用于「pi」的 agentic coding 任务,硬件配置为 2 张 RTX 3090 + 1 张 RTX 5060 Ti + 2 张 RTX 4060 Ti,共 96 GiB VRAM 与 125 GiB DDR4。该机型并非标准配置,作者称之为「Frankenstein rig」,但足以复现问题。
症状表现
症状具有可复现的确定性特征:
- 每轮对话之间等待时间极长;
- 出现分歧(divergent)的回合会重新预填充上千 token,而非仅预填充变化部分,导致 agent 长时间停留在「Working」状态而没有流式输出;
- 大约运行到第 29 次迭代时必然崩溃,报错为「Context size has been exceeded」;
- 崩溃发生时的逻辑深度仅约 1250 token,运行环境为 16k 上下文窗口,并非真正的长度超限。
作者还提到,即使仅以约 10 token/s 的速度运行,问题同样稳定复现,说明与速度无关。
根因分析
根据作者的技术分析,问题根源在于 DSV4 无法对部分序列执行 seq_rm 操作——压缩环(compressor ring)状态无法回滚,因此服务端只能通过 checkpoint 恢复来回退,但又不会清空未来的 SWA 单元,最终 find_slot 在 768 个单元的 SWA 窗口中耗尽资源。
- 一个原因,两个症状:回退不清窗 → SWA 窗口耗尽 → 停顿;窗口耗尽继续推进 → 触发「Context size exceeded」崩溃。
修复方案
修复方法是对已分歧(diverged)的后缀执行一次正确的 seq_rm,使后续只对增量部分重新预填充,从而消除卡顿与崩溃。
技术细节方面:
- 该 fork 基于 u/danielhanchen 的 checkpointing 提交(PR #25402);
- 同时参考了 u/tarruda 提供的 dsv4-fixes 与 MXFP4 GGUF 版本;
- 相关 issue 编号为 ggml-org/llama.cpp #25452;
- 修复仓库地址为 TacoTakumi/llama.cpp 的 dsv4-swa-churn-fix 分支。
现状与建议
作者呼吁 llama.cpp 维护者及其他 DSV4 用户复现并验证该补丁,并表示在本人机器上即使 10 t/s 的速度下,使用体验也已大幅改善。该问题在上游 master 分支仍可稳定复现,社区层面尚未给出合并时间表。
