Eval bug: Vulkan graph optimizer silently corrupts output for models with view-aliased state

该报错发生在 llama.cpp 使用 Vulkan 后端运行带有 view-aliased 状态(如循环状态)的模型时,Vulkan 图优化器可能错误地重排节点导致输出静默损坏,贪心解码可能选错 token。优先排查 Vulkan 优化器对张量视图依赖关系的判断,并尝试升级到包含修复补丁的版本。

快速结论:该报错发生在 llama.cpp 使用 Vulkan 后端运行带有 view-aliased 状态(如循环状态)的模型时,Vulkan 图优化器可能错误地重排节点导致输出静默损坏,贪心解码可能选错 token。优先排查 Vulkan 优化器对张量视图依赖关系的判断,并尝试升级到包含修复补丁的版本。

适用环境:llama.cpp 0.1.2-dev(build 10511);Vulkan 后端;已在 AMD Radeon RX 7800 XT、AMD Strix Halo/Ryzen AI Max+ 395、NVIDIA Quadro RTX 5000(Windows,驱动 572.61)上复现;Linux 与 Windows 均受影响;CUDA 后端不受影响。

最快修复方案:暂无确认的一步修复方案。Issue 中给出的补丁修改了 ggml_vk_graph_optimizeis_src_of 函数的依赖判断逻辑,将每个张量解析到其 view_src 基张量后再比较,测试中 12/12 次运行输出与参考文本一致。

注意事项:该修复由提交者自行测试验证,PR 尚未合入主线;修复后不同 draft 长度仍可能产生与目标模型不一致的输出,说明问题可能不局限于推测解码。

问题场景

用户使用 llama.cpp 的 Vulkan 后端运行带有循环状态(recurrent state)的模型(如 Qwen3.8-27B,配合 DFlash 2 draft 模型进行推测解码)。在温度 0、seed 0 的确定性条件下,同一输入在不同运行中产生了不同的输出文本——这是确定性解码下不应出现的情况。使用推测解码时,错误路径会接受模型本未选择的 draft token,导致接受率和速度数据失效。

报错原文

Eval bug: Vulkan graph optimizer silently corrupts output for models with view-aliased state

原因分析

问题定位在 ggml/src/ggml-vulkan/ggml-vulkan.cpp 文件 ggml_vk_graph_optimize 函数的 is_src_of 依赖检查中。当前实现无法识别两个视图(view)指向同一底层张量时实际上是“依赖”关系。优化器因此可能将一个节点移动到对同一内存的读或写操作之前/之后,造成数据竞争。Qwen3.8 通过视图保存循环状态,DFlash 2 的 verify 图在 AMD 和 NVIDIA 的 Vulkan 后端上都触发了该问题;同一 NVIDIA GPU 上 CUDA 输出正确。DFlash 2 是触发条件而非根因,根因在 ggml-vulkan.cpp

环境排查

  • llama.cpp 版本:0.1.2-dev(build 10511,commit f7aadef09),基于未合入的 #27342 构建
  • Vulkan 后端:确认 -DGGML_VULKAN=ON 已启用
  • 显卡驱动:AMD 使用 RADV Mesa 26.2.1(Linux 6.18);NVIDIA 使用驱动 572.61(Windows)
  • CUDA 对照:同一 NVIDIA GPU 上 CUDA 后端输出正确,可用于交叉验证
  • 模型:任何量化版本均可复现,问题与量化无关,与模型的循环状态图(recurrent-state graph)相关

解决步骤

  1. 确认当前构建版本是否包含 ggml-vulkan.cppis_src_of 函数的修复补丁。
  2. 如果问题仍在,可优先尝试 Issue 中提供的补丁:在 is_src_of 函数中新增 base() 辅助函数,将每个张量解析到其 view_src 基张量,然后比较:
    • 检查 dst->src[s] 的基张量是否与 src 的基张量相同(源视图可能通过不同视图读取同一存储);
    • 检查 src->src[s] 的基张量是否与 dst 的基张量相同(向前移动 dst 可能覆盖 src 仍通过视图读取的存储);
    • 最终比较 base(dst)base(src) 是否相等。
  3. 重新编译 llama.cpp,使用 cmake --build 完成构建。
  4. 使用原问题的复现参数(温度 0、seed 0)重新运行,对比多次运行的输出是否一致且与参考文本匹配。

验证方法

在温度 0、seed 0 条件下,对同一输入执行多次独立运行(建议至少 3 次)。修复前,推测解码场景下三次运行会产生三个不同哈希的输出;修复后应得到与无推测解码参考运行一致的单一输出。提交者测试结果为 12/12 次运行与参考文本一致。注意:修复后不同 draft 长度仍可能产生与目标模型不同的输出,但应表现为一致的第二套输出,而非随机错误。

参考来源

ggml-org/llama.cpp #27805

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 21319

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注