快速结论:在多卡 ROCm/HIP 环境下用 llama.cpp 加载跨卡模型(尤其是 --split-mode layer)时出现乱码输出,问题通常不在模型本身,而在于多卡间的数据拷贝或 GPU 间通信路径。优先排查两项:一是主机 PCIe P2P/IOMMU(VT-d)是否干扰跨卡拷贝;二是 GPU 时钟是否在层分割计算中频繁升降导致计算异常。
适用环境:Ubuntu 24.04.3 LTS、ROCm 6.4.3、llama.cpp build 6688 (898acba6)、HIP 后端、3× AMD Instinct MI50/MI60(gfx906)、2× Intel Xeon E5-2683 v4。另一反馈环境为 AlmaLinux 10.1、kernel 6.12 + ROCm 7.1 amdgpu 驱动、2× MI50(gfx906)、2× Xeon E5-2680 v4、llama.cpp 容器镜像 b9549/b8209/b11669。
最快修复方案:暂无确认的一步修复方案。Issue 中有两条被报告有效的路径:其一是在编译时加 -DGGML_CUDA_NO_PEER_COPY=On(会降低性能的规避手段,或直接关闭内核 PCIe P2P);其二是报告者在 BIOS 中关闭 VT-d 后乱码消失(另一反馈者关闭 VT-d 仅减轻未完全修复)。
注意事项:该问题被描述为部分 ROCm 主机平台上的已知缺陷,可能与主板 PCIe 实现或 GPU 电源状态相关,并非 llama.cpp 自身的 bug。关闭 VT-d 会影响虚拟化与设备直通;GGML_CUDA_NO_PEER_COPY 有性能代价;GPU 时钟锁定属于硬件层规避,重启后失效,需自行确认对功耗与稳定性的影响。
问题场景
用户在 ROCm/HIP 后端下用 llama-cli 加载跨多张 GPU 的大模型(如 gpt-oss-120b GGUF,--n-gpu-layers 999、--split-mode layer),期望获得正常生成结果,但输入 prompt 后直接输出乱码。同一用户反馈:当模型小到能放进单张卡、并设置 --split-mode none 时一切正常。
报错原文
Eval bug: Using llama.cpp with ROCm produces garbage output with --split-mode layer
# 附带的运行日志关键片段
ggml_cuda_init: found 3 ROCm devices:
Device 0: AMD Instinct MI50/MI60, gfx906:sramecc+:xnack- (0x906), VMM: no, Wave Size: 64
Device 1: AMD Instinct MI50/MI60, gfx906:sramecc+:xnack- (0x906), VMM: no, Wave Size: 64
Device 2: AMD Instinct MI50/MI60, gfx906:sramecc+:xnack- (0x906), VMM: no, Wave Size: 64
原因分析
按 Issue 讨论,这属于影响部分 ROCm 平台的已知问题。有证据指向主机系统的 PCIe 硬件实现存在缺陷(另有反馈者定位到 VT-d/IOMMU 干扰),但确切根因尚未完全确定,结论是这并非 llama.cpp 本身的 bug。
另一名使用 2× MI50 的反馈者给出不同定位:其乱码源于 GPU DPM 电源状态。在层分割(layer split)模式下,两张卡交替空闲并计算,空闲卡会掉到低 DPM 状态(925 MHz),每生成一个 token 又切回高 P-state(1725 MHz),这一升降循环导致计算结果被破坏;把时钟固定在任意稳定档位后乱码消失。该反馈也指出 -sm row 的崩溃可能是另一种失败模式。
环境排查
- 确认 ROCm 版本(本例 6.4.3,反馈环境另见 6.3.3 / 7.1.4)与 HIP 后端是否启用。
- 确认 GPU 型号与架构(gfx906)、卡数及是否跨 PCIe root port、是否处于 PCIe bridge 芯片之后。
- 确认 BIOS 中 VT-d/IOMMU 状态,以及内核是否启用了 PCIe P2P。
- 确认
--split-mode取值(layer/row/none)与--tensor-split配置。 - 确认是否设置了
GGML_CUDA_NO_PEER_COPY、HSA_ENABLE_SDMA等环境变量。 - 观察多卡层分割时各卡的
pp_dpm_sclk时钟是否在空闲与计算之间反复升降。
解决步骤
- 先用单卡运行验证基线:将模型放到单张卡并设
--split-mode none,确认单卡输出正常,以排除模型与构建问题。 - 可优先尝试:编译 llama.cpp 时加
-DGGML_CUDA_NO_PEER_COPY=On,或在系统中关闭内核 PCIe P2P,避开有缺陷的跨卡 P2P 拷贝路径。 - 可优先尝试:在 BIOS 中关闭 VT-d/IOMMU,然后重新运行并对比输出(反馈称可消除乱码,但另一环境仅部分缓解)。
- 检查 GPU 拓扑:若某些 GPU 位于 PCIe bridge 芯片之后,可尝试更换插槽使其不再经过该芯片。
- 排查 GPU 时钟(针对另一反馈者的 MI50 场景):以 root 将两张卡的
power_dpm_force_performance_level设为manual,并把pp_dpm_sclk限制到较低档位(如 0–7 或 0–6),使时钟在层分割时保持稳定,观察是否仍出现乱码。 - 层分割模式下若出现 “Memory access fault by GPU node” 类错误,注意该错误与乱码可能是不同失效模式;
--split-mode row在本例中始终失败,暂不作为可行方案。
验证方法
使用同一模型、同一 prompt、--temp 0 连续运行多次(反馈者用 20 次以上串行请求),检查输出是否仍有乱码、错字或 token 崩坏。同时对比单卡运行、独立双卡并行、倾斜 --tensor-split(如 30,1)等配置的结果;若调整后多次运行输出均正常,视为问题已规避。若输出仍异常,需继续排查 PCIe 拓扑与电源状态。
参考来源
lemonade-sdk/llamacpp-rocm #75
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


