llama.cpp Bug: GGML_HIP_UMA导致一致性错误

ev7lccsx  于 2个月前  发布在  其他
关注(0)|答案(6)|浏览(63)

发生了什么?
GGML_HIP_UMA=1 是一个构建标志,通过使用 hipMallocManaged 获取受管理的内存,然后使用 hipMemAdvise 将此内存设置为粗粒度,以便为AMD iGPU加速。然而,这一步导致输出变得非确定性。对于大多数人来说,LLM文本生成不是一个精确的科学,所以我不确定这是否应该被称为一个错误,但至少应该引起注意。如果可能的话,可以尝试修复它而不损失性能,但我不知道这涉及到什么。
复现这个问题需要以下材料:准备好具有 GGML_USE_HIPBLAS=1 GGML_HIP_UMA=1 的Linux构建以及一个工作(例如使用 HSA_OVERRIDE_GFX_VERSION )的AMD iGPU,然后调用一个模型(任何模型),并使用参数应该使其每次都给出相同的输出。我以Phi 3 mini为例,因为即使在非常弱的GPU上,它也相当快。

./llama-cli -m ~/models/Phi-3-mini-4K-instruct-q4.gguf --seed 42 --sampling-seq k --top-k 1 -sm none -ngl 0 -f diagnoser.txt

Prompt attached 的内容并不重要,重要的是大小。你只需要一个相当大的提示来复现这个问题。请注意,我们在这里没有卸载任何层,只是提示处理。
输出可能会根据你的模型(Phi 3 mini还不错,但也不是特别好)多或少有启发性,但关键是重复这个命令。只要我们计算正确,具有固定种子并禁用top-K,就不会有变化,但是如果你使用iGPU进行操作,你应该观察到不同的输出(可能需要几个标记,但它们会发散)。
这不会发生在dGPU上;对于那些来说,使用受管理的内存要慢得多,而且没有好处。你需要一个iGPU,其中CPU和GPU可以互相践踏对方的脚印。如果修改代码以删除 hipMemAdvise 调用,这种情况也不会发生,这表明改变粗粒度是问题所在,很可能是因为尝试确保并发访问实际上不会发生的尝试并没有被执行。在这种情况下,你会受到性能影响——在我系统上影响很小,但是当我测试iGPU时(它几乎无法触及CPU的性能),不能被认为是代表性的。

名称和版本

版本:3400 ( 97bdd26 )
使用cc(GCC)14.1.1 20240522构建的x86_64-pc-linux-gnu
ROCm 6.1.2(如果有关系的话)。

你在哪台操作系统上看到问题?

Linux

42fyovps

42fyovps1#

使用--no-kv-offload是否仍然会发生这种情况?这可能是AMD和他们的LLVM实现中BF16 / FP16错误的一部分。

dhxwm5r4

dhxwm5r42#

是的,-nkvo仍然存在这个问题。
如果这是一个更广泛的问题,很奇怪它在我的dGPU上没有复现。此外,如果这是由于某个内核在某处的编译错误导致的,那么这将无法解释非确定性。如果我错了,请纠正我。你可以(实际上确实可以)根据你如何卸载来得到不同的结果,但只要你消除了随机性,你的硬件本身没有问题,重复相同的场景应该会产生相同的结果(即使是一个错误的结果)。

hgtggwj0

hgtggwj03#

如果你能提供 rocminfohipconfig 的输出,可能会帮助你找到正确的方向。将 AMD_LOG_LEVEL 设置为4也可能有所帮助。

我猜测你正在使用的是 rOCM 版本的预 Vega 设备,但这些事情涉及到很多因素,我所能做的只是提供已知可以纠正它的工作方法,并看看它是否也适用于你。

至于上游驱动程序的错误,Chromium 是我能知道的最好的地方来了解这些问题。最简单的方法是启用硬件加速,然后打开 chrome://gpu,它已经为你整理好了所有的信息。

https://chromium.googlesource.com/chromium/src/+/refs/tags/127.0.6533.59/gpu/config/gpu_driver_bug_list.json
在这个上下文中,确定性和非确定性有些模糊,你真正想要的是数学正确性。

1szpjjfi

1szpjjfi4#

我猜你使用的是ROCm 6版本的设备。
你怎么知道的?ROCm 6.0.2是否比早期版本有特殊支持?我正在使用https://github.com/lamikr/rocm_sdk_builder,以便我们拥有最新和最好的版本。但在任何人跳到这一点之前:问题也反映在Manjaro上可用的vanilla ROCm 6.0.2中,这不是针对这个构建的问题。
编辑:我怀疑你被误导了,因为rocminfo可以输出类似ROCk module version 6.7.0 is loaded的东西。这与ROCm SDK版本无关。它从/sys/module/amdgpu/version获取,而这个版本似乎是只有在安装了AMD的专有驱动程序后才会填充的。ROCm 6.1.2版本确实有一个6.7的版本号,例如。如果你不在RHEL、Ubuntu或Suse上,显然没有这个选项。
嵌入在Ryzen 5 7600中的GPU是Raphael(又名gfx1036),它是一个具有2个CU的RDNA 2单元。如果其他用户能够用其他iGPU重现这个问题,我会很感兴趣,因为我怀疑这不特定于任何型号。特别是,因为通过将内存分配类型从粗粒度更改为细粒度,问题可以消失。它可能与驱动程序版本有关,具体取决于同步是如何实现的,但我认为我们实际上只是得到了我们所要求的:对内存的不同步访问,这是我们在滥用的一种特权。
澄清一下:输出并非不可用或明显错误,只是每次运行时都不同。我怀疑这可能是一个一直没有注意到的问题,因为大多数用户只要能让他们自己的iGPU正常工作就足够了,而不关心它是否严格来说在做正确的事情。
感谢AMD_LOG_LEVEL的提示,看起来很有用。由于包含诸如指针值之类的内容,它输出的日志量令人难以置信且几乎无法区分,但这并不是什么小费力就能解决的问题。

vmpqdwk3

vmpqdwk35#

好的,我记得了一件可能非常相关的事情:我在Linux 6.10上进行测试,它有一个important change in how memory allocation is being handled for iGPUs。具体来说,现在事情直接进入GTT并避免在旧内核中产生大量的复制开销。这很好,但也正是可能导致这种问题暴露的类型的事情。当我有机会时,我会在内核6.9上重新测试。

wz8daaqr

wz8daaqr6#

嗯,不知何故我把6.0误读为5.6。
讽刺的是,如果它是gfx1036,那可能对你来说就是解决方案。
ROCm/ROCm#2867
Xnack支持通常似乎是第一个要去掉的功能,但如果他们甚至不想费心在集成平台上支持它,我开始怀疑他们计划退出GPU方面的事情。
你有没有检查过是否有任何调试代码来帮助转储Tensor?它们可能被截断或使用未初始化的内存。

相关问题