快速结论:该报错通常出现在 Apple Silicon 上用 llama.cpp Metal 后端、经由共享库(in-process)反复调用 Qwen2.5-Omni 音频推理时:负载下偶发返回 2,048 个乱码 token,但没有任何后端报错。优先排查采样是否可复现(temp 0 + 固定 seed)、上下文是否被并发调用或未在请求间清理,以及 KPQ/KQV 算子是否走 Metal。
适用环境:macOS arm64;llama.cpp b10809(commit 5266f24da),复现者使用 b10842(commit 473599738);Metal 后端;Apple M5 Max / 128 GB 统一内存;模型 ggml-org/Qwen2.5-Omni-3B-Q8_0.gguf + mmproj-Qwen2.5-Omni-3B-Q8_0.gguf;音频 samples/jfk.wav;通过 Kronk/Yzma 共享库调用。
最快修复方案:暂无确认的一步修复方案。Issue 中唯一观察到的“0 次损坏”配置是关闭 op_offload(`op_offload=false`)以及将全部模型层 + projector 放到 Metal 且 `op_offload=false`;这属于可优先尝试的规避路径,而非已验证修复。
注意事项:样本量很小(每行 n=3 到 n=5),0/5 不等于稳定解决;且关闭 op_offload 会改变计算路径,可能带来性能影响,是否影响输出质量未被验证。该 Issue 标签为 bug-unconfirmed,关闭时未给出官方根因或补丁。
问题场景
用户在 macOS(Apple Silicon)上使用 llama.cpp b10809 的 Metal 后端,通过 Kronk/Yzma 共享库(共享库/API 路径,in-process)反复发送 Qwen2.5-Omni-3B 音频请求:模型 Q8_0 加 Q8_0 mmproj,输入 samples/jfk.wav,prompt 为 “Transcribe the following audio and then summarize who said it and when.”,temperature 0.7 / top-p 0.9 / top-k 40,max_tokens 2048,模型与多模态 projector 都 offload 到 Metal。在机器空闲时通常正常;当同时运行 Go 测试套件等并发负载时,偶发返回 2,048 个不相关内容、替换字符和混合文字脚本的乱码输出。后续复现者改用 b10842、temperature 0、固定 seed 1、128 token 的确定性请求,在空闲状态下也复现出同一类损坏。
报错原文
Eval bug: intermittent silent Qwen2.5-Omni audio corruption on Metal under system load (b10809)
AB in De Morgan: - Can it
The number·AB. The package. - ,dial AB, the Can the AB: ...
Input: 786 Reasoning: 0 Completion: 2048 Total: 2834 TPS: 64.71
# 期望输出
The original content of this audio is: 'and so my fellow americans ask not what your country can do for you ask what you can do for your country' by 'john f kennedy'.
# 损坏运行的 token ids(首 token 即偏离)
[100472 100454 44934 63431 30709 52510 46683 13 ...]
原因分析
这不是 #23986 中那种确定性的 im2col pipeline 选择 bug:坏日志中没有 `command buffer` / `failed with status` / `backend is in error state`,说明不是 Metal command buffer 被丢弃,而是“静默错误结果”分支;日志中编译的是 `kernel_im2col_f16`(基础分支),说明 #23986 的修复生效。维护者在评论中提出四个变量在“正常 CLI 运行”和“损坏的共享库运行”之间同时变化:进程模型(每请求新进程 vs in-process)、采样参数(temp 0 + seed 1 vs temp 0.7/top-p 0.9/top-k 40)、token 预算(128 vs 2048)、warmup(关闭 vs 开启)。可能原因包括:
- 计算路径差异:复现者用 temp 0 + 固定 seed 后发现同一请求在空闲状态下也会首 token 偏离,token id 与正常运行完全不同,因此被认为更偏向“计算结果差异”而非采样不稳定。
- 上下文并发:llama.h 只在 Tokenization 一节声明线程安全,`llama_decode` / `llama_context` 未声明线程安全,`src/llama-context.cpp` 中没有 mutex / lock_guard / atomic;两个 `llama_decode` 在同一 context 上重叠属于未定义行为,而并发的 Go 测试套件正好可能触发重叠(空闲串行运行则不会)。
- 上下文状态未清理:运行到 2048 token、从不触发 EOS、混合脚本和替换字符,形似残留 KV —— 若上一个请求的 cell 还在,新请求的音频 embedding 会落在错误位置。
- KPQ/KQV 算子下放:隔离矩阵显示仅仅关闭 `offload_kqv=false` 仍有 1/5 损坏,而 `op_offload=false` 为 0/5,提示 Metal 算子下放路径可能是触发条件之一。
环境排查
- 确认 llama.cpp 构建版本与 commit:原始报告 b10809 / 5266f24da;复现使用 b10842 / 473599738。
- 确认操作系统:macOS 26.6.2 (25G83),arm64。
- 确认硬件:MacBook Pro Mac17,6,Apple M5 Max,128 GB 统一内存。
- 确认后端:Metal;模型与 mmproj 是否 offload 到 Metal。
- 确认模型文件:Qwen2.5-Omni-3B-Q8_0.gguf 与 mmproj-Qwen2.5-Omni-3B-Q8_0.gguf。
- 确认推理参数:NSeqMax / n_seq_max 是否为 1;temperature、seed、top-p、top-k、max_tokens;是否开启 warmup。
- 确认调用方式:是单进程 CLI 还是共享库 in-process(Kronk/Yzma);是否存在多个 goroutine 同时调用同一 llama context;请求之间是否清理 context 内存(KV)。
- 本次 Issue 未提供 Python / CUDA / PyTorch 版本信息,这些不属于该问题的排查范围。
解决步骤
- 先把采样固定下来,隔离“计算差异”和“采样差异”:把共享库调用改成 temperature 0 + 固定 seed,在相同负载下运行,并与空闲运行逐 token 比对 token id。id 完全相同说明计算没问题,损坏发生在状态或采样;id 不同则说明计算路径本身存在差异。
- 用采样 token 的 vocab id 记录输出,而不是把渲染后的文本重新分词,避免比对对象不一致。
- 检查 Kronk/上层代码对 context 的使用:确认不会有两个 goroutine 同时进入同一 context 的 `llama_decode`;因为 `llama_decode` / `llama_context` 未被声明为线程安全,重叠调用属于未定义行为。
- 检查请求之间是否清理上下文内存(KV 状态):若上一个请求的 cell 仍存在,新请求的音频 embedding 会落在错误位置。
- 在下次坏运行时捕获两项信息:`llama_n_seq_max(ctx)` 的返回值,以及是否可能有两个 goroutine 同时处于该 context 的 `llama_decode` 中。
- 按隔离矩阵逐项改变配置(一次只改一项):
默认 Metal 模型 + Metal projector(空闲,1/3 损坏)→ projector 强制走 CPU(1/5)→ `n_gpu_layers=0`、projector CPU、默认 host-op/KQV(2/3)→ 仅 `op_offload=false`(0/5)→ 仅 `offload_kqv=false`(1/5)→ 全部模型层 + projector 在 Metal 且 `op_offload=false`(0/5)。 - 若需要先恢复可用性,可优先尝试关闭 `op_offload` 的配置,因为这是 Issue 中唯一观察到 0 次损坏的路径。
验证方法
用同一 temperature 0 / 固定 seed / 相同 token 预算的共享库请求,在相同负载条件下重复运行,并逐 token 对比生成的 vocab id:若每次都与空闲运行的 40 token 正常结果(含 “John F. Kennedy” 转写)完全一致,说明损坏不再出现;同时确认坏运行不再出现满 128 / 2048 token 的混合脚本乱码、替换字符输出。由于 Issue 样本量较小且未确认根因,建议至少在多个重复运行和负载条件下验证,而不是只跑一次。
参考来源
ggml-org/llama.cpp #23986(相关的前序 im2col pipeline 选择问题)
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


![Dify python code execution error: No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/'] error: exit status 255](https://www.chat-gpts.plus/wp-content/uploads/2026/09/18678-8dcba7c2-768x403.jpg)