Apple Silicon 与 macOS 虚拟机:借助 Llama.cpp 实现 11-16 倍的 LLM 推理加速
精选理由
通过进程级 Metal 能力注入,macOS 虚拟机中 llm 推理速度提升一个数量级,为在隔离环境运行大模型提供了此前缺失的算力基础。
AI 摘要
研究团队为 macOS 虚拟机中的 Metal 能力查询构建进程级兼容层,使 llama.cpp 能选用更新的 Metal 内核。在 M1 Ultra 上,TinyLlama 1.1B 的提示处理速度提升 11.08 倍、token 生成提升 16.36 倍,接近裸机性能的 98%;Gemma 4 12B 的提示处理与生成速度分别提升 7.20 倍和 14.54 倍。
正文 · AI 翻译
gpu-passthrough-macos-vms.md
历史
gpu-passthrough-macos-vms.md
文件元数据与控件
Apple Silicon 与 macOS 虚拟机:llama.cpp 推理速度提升 11–16 倍
发布于 2026 年 8 月 11 日,作者:Francesco Bonacci 与 Johnny Franks
如果你从一开始就在关注 Cua,你或许还记得,它始于我们 macOS 虚拟化栈 Lume 在 Show HN 上的发布。
通过 Apple 的 Virtualization.framework 运行的 macOS 客户机,使用的是由宿主机 Apple GPU 支撑的虚拟 GPU。在我们标准的 Tahoe 虚拟机中,该设备报告的是保守的 Metal 能力配置。应用程序会依据这些配置来选择内核与渲染路径,这导致 llama.cpp 运行的是慢得多的 GPU 代码。
我们构建了一个小型的、进程级作用域的兼容层,它能为单个客户机进程修改部分能力配置的返回值,从而让 llama.cpp 能够选用更新的 Metal 内核。这是我们更广泛工作成果中的第一个结果,该工作旨在将 Lume 的虚拟化基础连接到 Cua Driver 背后的本地计算机使用环境,以及 Cua Cloud 和 Fleets 背后的基础设施。
我们今天以研究发布的形式放出这项工作,采用与 Lume 和 Cua 相同的宽松许可证,以便其他人能够复现这些结果,并帮助摸清哪些 Apple Silicon 芯片、macOS 版本和 Metal 工作负载能从中受益。
在 M1 Ultra 上,通过 llama.cpp 运行的 TinyLlama 1.1B,其提示词处理速度比同一标准虚拟机中的相同工作负载快 11.08 倍,token 生成速度快 16.36 倍。提示词处理达到了我们裸机结果的 98%。源码、构建脚本、能力探测程序和原始基准日志均已包含在内,方便你查验并复现该结果。
我们用 Google 的 Gemma 4 12B QAT Q4_0(今年发布的 6.98 GB 模型)重复了该实验。同一兼容层将提示词处理速度提升了 7.20 倍,token 生成速度提升了 14.54 倍。解锁后的虚拟机达到了裸机提示词速度的 99.59%,以及裸机生成速度的 94.82%。
同样的能力差距也出现在其他 Virtualization.framework 前端中。Tart 是另一款 macOS 虚拟化 CLI,它有一个公开的 issue“macOS 客户机中无 GPU 透传?”,涵盖了 macOS 客户机内的图形与 LLM 性能问题。
macOS 虚拟机内部的限制
Apple 的 Virtualization.framework 会为 macOS 客户机提供一个虚拟图形设备。客户机通过一个专用 GPU 驱动程序提交 Metal 工作负载,而 Apple 的主机端栈会在物理 GPU 上执行这些工作。这种安排属于半虚拟化(paravirtualization),即主机端保留对硬件的控制权,客户机则使用一个能感知虚拟化的设备。
这与基于 QEMU 和 KVM 构建的其他虚拟化栈不同,后者可以采用不同的架构。在 x86 Linux 主机上,VFIO 可以通过 IOMMU 将兼容的物理 PCI 设备或硬件功能分配给虚拟机,让客户机直接访问该设备。这通常就是 GPU 直通(GPU passthrough)所指的模式。
在我们标准的 Tahoe 虚拟机中,半虚拟化设备报告的能力大约是 Apple 5 代系列,最大线程组内存为 32 KB,并且 SIMD 组矩阵支持不可用。现代 Metal 软件会利用这些返回值来选择内核,因此即使该设备能够执行更新的内核,llama.cpp 也还是选择了较慢的执行路径。
Apple 通过 GPU 系列(GPU families)和功能表来记录 GPU 能力,并建议在运行时查询设备。这使得所报告的能力边界变得至关重要:应用程序完全是在按照平台告诉它们的信息行事。
解决方案:一个进程作用域的 Metal 能力垫片(capability shim)
我们构建了一个小型 Metal 能力垫片(一种插入在应用程序与 API 之间的兼容层),它运行在单个客户机进程内部。它会拦截选定的 Metal 能力查询,并修改返回给该进程的答案。Metal 应用程序会利用这些答案来选择内核,因此返回经过测试的 Apple 系列和线程组内存值,可以让 llama.cpp 选择其更新的 GPU 路径。对于我们测试的配置,该垫片会:
将 `supportsFamily:` 的应答提升到 Apple family 9(1009);以及
将报告的最大线程组内存从 32 KB 提升到 64 KB。
这足以让所测试的 llama.cpp 构建版本选择更新的 SIMD 组归约(SIMD-group reduction)、SIMD 组矩阵(SIMD-group matrix)和 bfloat16 路径:
能力项 标准客户机 测试配置
supportsFamily:1009 false true
SIMD 组矩阵 关闭 开启
SIMD 组归约 关闭 开启
bfloat16 关闭 开启
最大线程组内存 32 KB 64 KB
测试所用的配置文件修改了两个上报值:Apple 系列标识和线程组内存上限。Common、Mac、Metal 和工作集大小等值在基准测试期间保持默认设置。我们移除了原始研究钩子中的私有功能配置文件钩子、时钟和计时插桩、网格替换、光线追踪覆盖、参数布局保护以及管线编译回退。其源码足够小,便于审计,且格式错误或缺失的配置会使进程保持在其默认能力路径上。
该工作负载仍走 Apple 的 Virtualization.framework 图形路径,并在宿主的 Apple GPU 上执行。能力变更仅限于注入的客户机进程范围内。
物理 GPU 分配、裸 PCI 或 VFIO 直通以及内核修改均不属于此机制范畴。上报的系列标识描述的是我们测试所覆盖的路径;每新增一个 Metal API 都需要单独验证。
该垫片在 Apple 现有的虚拟 GPU 路径上解锁了 Metal 能力。虚拟机用户通常以“GPU 直通”之名遇到这一更广泛的限制。
最小化工件的最新结果
我们在配备 48 核 GPU 的 Apple M1 Ultra 和 macOS 26.6.1 上进行了测试。客户机为运行在 Lume 0.5.1 中的当前公开 Tahoe Cua 镜像(macOS 26.5.2、8 vCPU、16 GiB)。三次运行均使用官方 llama.cpp b10167 版本和相同的 TinyLlama 1.1B Chat Q4_K_M 模型。
命令为:
llama-bench -m tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf \ -p 512 -n 128 -r 10 -t 8 -ngl -1 -o json
以下数值为每个基准测试行所输出的十个样本的中位数:
工作负载 裸机宿主 默认客户机 解锁客户机 客户机加速比 解锁 / 宿主
提示词处理,512 tokens 4,871.99 tok/s 431.86 tok/s 4,786.70 tok/s 11.08× 98.25%
Token 生成,128 tokens 286.71 tok/s 12.63 tok/s 206.60 tok/s 16.36× 72.06%
提示词处理几乎达到了宿主结果。生成速度达到宿主的 72.06%,仍存在可测量的虚拟机差距。该收益取决于宿主 GPU、客户机版本、应用程序和工作负载形态。
TinyLlama 的原始结果和环境记录包含确切的镜像摘要、模型和二进制哈希、命令、JSON 输出、stderr 以及校验和。这些候选发布结果验证了本文中使用的精简垫片。
一个当前的 12B 模型
TinyLlama 之所以能成为一个有用的受控基准,是因为它运行速度快,并且能清晰地暴露 Metal 路径。我们还想要一个开发者如今可能会选择的更大模型,因此我们通过同一个 llama.cpp 二进制文件,运行了 Google 官方的 Gemma 4 12B 指令微调版 QAT Q4_0 GGUF 模型。
主机、虚拟机、shim、基准测试形态以及十次采样方法均保持不变。我们禁用了推测解码,并保持多模态投影器未加载,从而将对比保持在同一条 Metal 推理路径上:
工作负载 裸机主机 原版虚拟机 解锁虚拟机 虚拟机加速比 解锁版 / 主机
提示词处理,512 tokens 517.88 tok/s 71.66 tok/s 515.76 tok/s 7.20× 99.59%
Token 生成,128 tokens 52.38 tok/s 3.41 tok/s 49.67 tok/s 14.54× 94.82%
Gemma 4 的证据将 Google 的模型修订版本和 SHA-256 与最终的原始采样数据一并固定下来。在检测到另一个主机计算工作负载后,我们丢弃并重新运行了一个初步的原版系列测试。保留的原版、解锁版和裸机文件均来自同一个无争用时段,并显示出紧密的采样范围。
我们还在 MLX 0.32.0 上测试了 MLX-LM 0.31.3 与 mlx-community/Llama-3.2-3B-Instruct-4bit 的组合。性能保持平稳,因为 MLX-LM 在原版虚拟机中已经很快了:
工作负载 原版虚拟机 解锁虚拟机 比率
提示词处理,512 tokens 1,656.55 tok/s 1,665.47 tok/s 1.005×
Token 生成,128 tokens 172.09 tok/s 170.86 tok/s 0.993×
这个平稳的结果有助于定义发布配置。在消融测试期间,通告 MTLGPUFamilyMetal3 使得 MLX 请求了一个通过半虚拟化设备无法获得的驻留集。发布版 shim 将更改后的答案限制在 Apple 家族的枚举值内,并保持 Metal 3 为其原版值。相关的 MLX 分支可以在其 Metal 驻留实现中看到。
这与 Apple 平台的关系
这完全在 Apple 硬件上运行,通过 Apple 随 Virtualization.framework 提供的半虚拟化 GPU 路径实现。该 shim 仅影响一个虚拟机进程读取的选定值。主机、虚拟机内核、其他虚拟机进程、内容保护状态和许可状态均保持其现有配置。
该技术依赖于客户机 Metal 实现中私有的、随版本变化的行为。Apple 可能会在 macOS 版本之间更改它,因此我们独立测试每个主机和客户机的组合。不受支持的方法会让进程保持其默认路径,而每个额外的 API 都需要自己的虚拟化测试。
我们欢迎 Apple 就半虚拟化图形不受限制功能级别的预期行为和支持性做出澄清。从事 Metal 或 Virtualization.framework 工作的 Apple 工程师可以通过 vz@trycua.com 联系我们。
在 Lume VM 中试用
源代码位于 libs/lume/metal-capability-shim。构建并验证两个特定于架构的 dylib:
cd libs/lume/metal-capability-shim ./Scripts/build.sh ./Scripts/verify.sh
停止 VM,为您的 macOS 用户启动的 VM 启用不受限制的功能级别,然后重新启动:
lume stop my-vm defaults write com.apple.gpusw.ParavirtualizedGraphics \ ForceUnrestrictedDeviceFeatureLevel -bool true lume run my-vm
将匹配的 dylib 以及探针或工作负载复制到客户机中,然后将激活范围限定到该进程:
lume ssh my-vm \ "DYLD_INSERT_LIBRARIES=/path/to/LumeMetalCapabilities-arm64.dylib \ LUME_METAL_APPLE_FAMILY_MAX=1009 \ /path/to/metal-capabilities 1009"
对于长时间运行的推理服务器、渲染器或工作进程,请使用按工作负载划分的 LaunchAgent。在该工作负载的环境中设置 DYLD_INSERT_LIBRARIES,以便登录会话保持默认状态。Lume 指南提供了完整的模板、校验和与验证步骤,以及回滚说明。
移除环境变量并重新启动工作负载即可使其恢复默认行为。要恢复主机偏好设置,请停止 VM,删除 ForceUnrestrictedDeviceFeatureLevel,然后再次启动 VM。
限制
实验性且随版本变化。该 shim 使用了私有的客户机 Metal 实现细节,这些细节可能在任何 macOS 版本中发生变化。
按进程生效。它仅影响被注入的工作负载及其子进程;经过加固或受平台保护的二进制文件可能会拒绝库注入。
配置的能力配置文件。它报告了我们测试所涵盖的 Apple 系列值。物理 GPU 能力发现不在其范围内。
验证范围有限。当前证据涵盖了在所列 M1 Ultra 主机和 Tahoe 客户机上对能力探针、两个 llama.cpp 工作负载以及一次 MLX-LM 兼容性运行的测试。其他芯片、客户机版本、模型和 Metal API 需要单独测试。
仍然是 VM。现有的 Virtualization.framework 渲染和虚拟化限制仍然存在。
总结
这位访客的保守回答背后,隐藏着一条出人意料的强大 GPU 路径。在我们的测试机器上,两项范围狭窄的能力变更将 TinyLlama 的提示词处理速度从每秒 432 个 token 提升到了每秒 4,787 个 token。对于 Gemma 4 12B,提示词处理速度从每秒 71.66 个 token 提升到 515.76 个 token,生成速度则从每秒 3.41 个 token 提升到 49.67 个 token,而工作负载始终保持在 Apple 现有的 GPU 桥上。
Lume 最初是为了让 macOS 虚拟机对开发者更实用而创建的。这一结果为我们提供了在更多 Apple Silicon 代际、客户机版本和 Metal 工作负载上进行测试的基础。
想帮忙吗?在 GitHub 上给 Cua 加星标,并在你的设备上测试这个 shim。如果你遇到问题,请提交 issue,并附上你的宿主机芯片、宿主机和客户机版本、确切的工作负载,以及默认和解除限制后的结果。如果你验证了新的组合或改进了 shim,请发送拉取请求。
原文
Original Title
Apple Silicon 与 macOS 虚拟机:借助 Llama.cpp 实现 11-16 倍的 LLM 推理加速
Source
Hacker News 热门(buzzing.cc 中文翻译)
Site
github.com
Author
frabonacci
Published
2026-08-12 00:41