GPU 加速的容器 用于 Macs (支持 Adobe Firefly)
2024年7月14日更新:llama.cpp 现在实现了非常快速的 CPU 加速的 Q4_0_4_4 量化推理过程(比 Q4_0 在 ARM 上快最多 2.5 倍),本文提到的 Mac 上复杂的 Vulkan 透传基本上已经不再有用了。抱歉!
对我来说,苹果硅Mac电脑运行MacOS时始终有一个主要缺点——它们的GPU在容器或虚拟机(VM)中不可用。
容器或VM提供了一个干净、隔离且安全的软件安装环境,不会影响主机机器——然而直到现在,在M1/M2等MacOS容器或VM中的所有软件运行都比较慢,仅使用CPU。
但是基于Sergio López(https://sinrega.org/2024-03-06-enabling-containers-gpu-macos/)提出的精彩想法,我终于在容器中实现了部分GPU加速。
本文是关于如何实现这一目标的手动教程。虚拟化的GPU加速虽然不如原生GPU那么快,但比纯CPU要快得多。
对此“虚拟”GPU加速在MacOS上的(简化)技术解释: 容器或虚拟机都依赖于相同的基概念——所谓的主机计算机的虚拟化(容器实际上只是运行在宿主机上的更轻量级的Linux虚拟机,它们共享宿主机的资源)。所有虚拟化产品,如Parallels、Docker、Podman等,在配备Apple硅的MacOS上的Mac必须使用MacOS中内置的Hypervisor.framework。这是MacOS虚拟化的基础层,用于创建虚拟CPU/内存,以及一些通信能力,但其目前尚不支持虚拟GPU。然而,在hypervisor之上还有一个额外的虚拟化软件层,通常称为虚拟机监视器(VMM)。这个VMM实现虚拟计算机的基础硬件功能,包括I/O和图形等。许多虚拟化产品利用了Apple的Virtualization.framework,不过,其他解决方案也可以替代这个框架。聪明的新VMM解决方案(如Podman使用的Qemu)这并非直接提供可编程的虚拟GPU,而是通过容器/虚拟机内部的加速Vulkan GPU-API来实现。然后将容器内应用程序的Vulkan API调用路由到主机的GPU上执行。这虽然比直接GPU访问慢,但仍然比在CPU上运行要快得多,至少在我的M2 Max上已经得到了验证。Vulkan API也是一种高效的跨平台图形和计算API,它支持GPU的高效跨平台访问,被许多应用程序(如llama.cpp等)所采用。
如何(为容器)使用基于Podman的容器?
(参考了https://sinrega.org/2024-03-06-enabling-containers-gpu-macos/)
~/.config/containers/containers.conf
中添加:
[machine] provider = "applehv"
brew tap slp/krunkit brew install krunkit
与Sergio的说明不同,我并没有在Podman中安装libkrun,但这是否必要还需要进一步确认。
podman machine init ...
创建podman虚拟机(对于我的M2 Max,有8个p核心和大量内存,我使用了podman machine init --cpus 8 --memory 16384
)。虚拟机的内存取决于你计划如何使用容器。podman machine start
启动podman虚拟机(使用Podman 5.x时,此步骤总是会因为libkrun而产生错误,因此使用最新的4.9版本)podman machine ssh
,进入虚拟机后运行ls /dev/dri
,应显示一个设备而非空白。最后通过exit
退出ssh连接。最新的性能结果:
我在 Sergio 的容器(pod)中测试了 llama.cpp 程序,并使用了微软的 Phi-3(下载了 phi-3-mini-4k-instruct.Q4_K_S.gguf)。以下是在我的 M2 Max(96GB 内存/38个 GPU)上进行的标准化的 llama 性能测试。
原生支持GPU(Metal): pp512: ~1005, tg128: ~90
容器(8核CPU和虚拟Vulkan): pp512: ~138 , tg 128: ~56
原生仅CPU(-ngl 0): pp512: ~174, tg128: ~42
Parallels虚拟机(8核CPU,无加速): pp512 ~70, tg128 ~33
这些结果很有趣,但好坏参半,需要分析/调整。容器内的GPU加速提高了性能,相比同等CPU和内存配置的纯虚拟机,提升幅度没有我预期的那么显著。
我也测试了 llama2–7B,就像在llama.cpp Apple性能数字中所做的那样。虚拟GPU加速相比仅使用CPU的结果显示出显著的性能提升,但远远不及纯GPU的性能。
我的任务:
注意: 提前为首次得到一个令人兴奋的结果而可能过于热情的发布道歉,这还需要进一步研究。我觉得提前发布并不断更新比拖延到我有时间深入研究或改进要好。