# Apple Silicon 与 macOS 虚拟机：借助 Llama.cpp 实现 11-16 倍的 LLM 推理加速

- 来源：Hacker News 热门（buzzing.cc 中文翻译）
- 作者：frabonacci
- 发布时间：2026-08-12 00:41
- AIHOT 分数：73
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.virxact.com/items/cmsox86zv09u6rohdqr80wg0x
- 原文链接：https://github.com/trycua/cua/blob/main/blog/gpu-passthrough-macos-vms.md

## 精选理由

通过进程级 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 倍。

## 正文

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，请发送拉取请求。
