GPU虚拟化被开源撕开一道口子

2026.09.24 20:34
Nestri Labs开源virtio-nvgpu,在KVM中实现驱动ABI级NVIDIA GPU转发。四台虚拟机共享一张RTX 3060,帧均匀度达到四个九级别,性能损失在2%以内。文章分析了这项技术如何从架构上挑战NVIDIA vGPU许可策略的定价权,以及它目前的安全局限。

当一个 KVM 虚拟机里的游戏渲染速度只比裸机慢了不到 2%,而 CPU 开销一分钱没多花,整个云 GPU 的供给逻辑就不再是“能不能虚拟化”,而是“谁还愿意为虚拟化付费”。

2026 年 9 月,Nestri Labs 在 GitHub 上开源了 virtio-nvgpu,一个在 KVM 虚拟机中实现近原生 NVIDIA GPU 访问的 virtio 设备。这不是又一个 API 级别的翻译层,而是在驱动 ABI 层面做 ioctl 转发。Guest 运行的是 NVIDIA 原版用户态驱动,未经任何修改,同一套 Vulkan 库,同一套 NVENC 编码器,直接和宿主机上的同一张物理显卡对话。

项目瞄准的目标场景是无头(headless)流媒体:虚拟机内部运行一个合成器,完成渲染、合成和编码,再将压缩后的视频流推送出去。虚拟机不需要接显示器,宿主机把显卡握在自己手里。

而它的核心设计选择,是从架构上切掉了 API 级虚拟化几十年没能摆脱的致命冗余。

两条旧路,各自走不通

GPU 虚拟化领域一直存在两条路线。一条叫 API 转发。最典型的代表是 Venus,virtio-gpu 的 Vulkan 前端。Guest 里的每一个 Vulkan 或 OpenGL 调用,都被序列化、打包、跨 VM 边界传输到宿主机,再由宿主机在真实驱动上回放一遍。另一条叫设备直通,VFIO PCIe passthrough,把整张物理卡通过 IOMMU 直接交给某个虚拟机独占。

两条路线各有各的死穴。

Venus 式的 API 转发,本质上是对每个绘图调用做一遍“序列化、传输、反序列化、回放”的完整往返。以 60fps 的一帧为例,帧预算只有 16.6 毫秒。这一帧内包含 1000 到 5000 次绘制调用,加上绑定、描述符更新和渲染通道切换,每次都要单独穿越一次序列化通道。累加下来,仅序列化延迟就能吃掉 1 到 3 毫秒。帧预算的 6% 到 18%,还没轮到 GPU 干活就已经没了。GPU 命令缓冲在宿主机上生成,Guest 没有独立的命令编译器。NVENC 编码器基本不可用,因为编码会话需要真正的 CUDA 互操作,而 API 代理层触碰不到这一层。

VFIO 直通没有这些性能损失。整张卡直接给 Guest,性能无限接近裸机。但它的代价是“整张卡只能给一个虚拟机”,做不到切分。一张 A100 给一个云游戏实例跑满,剩下七个核心空转,数据中心的经济账怎么也算不过来。

NVIDIA 官方 vGPU 方案能切分,但需要专门的 vGPU 管理器、vGPU 版驱动,以及一套商业许可服务器。以 vPC(虚拟 PC)为例,四年版权的每并发用户年费为 43.75 美元(据 CRN 2021 年报道,这是目前公开可查的最新定价基准)。一个运行 500 个并发用户的数据中心,仅许可费就是每年约 2.2 万美元,还不算 GPU 硬件本身。更要命的是 vGPU 只支持 GRID 系列和部分数据中心卡,消费级 RTX 完全无缘。

这就是 GPU 虚拟化过去十年的核心困境:要么性能好但不可切分,要么能切分但性能折损大,同时许可证成本居高不下。

驱动 ABI 级转发:一种更聪明的切法

virtio-nvgpu 的架构可以用一句话概括:让它看起来像没有中间层。

Guest 内的应用程序调用 NVIDIA 标准的用户态驱动,libGL、libvulkan,驱动在内核态发起 ioctl 调用访问 /dev/nvidia* 设备节点。这一切和裸机上没有任何区别,只不过 Guest 内核的 /dev/nvidia* 由 virtio-nvgpu 的 Guest 内核模块(driver/,GPL-2.0)注册,而不是 NVIDIA 物理驱动。

当 ioctl 到达 Guest 内核模块,它会被序列化并通过 virtqueue 发送到宿主机端。宿主机端的设备组件(device/,Apache-2.0,Rust 编写)在 VMM 进程中执行实际的 ioctl 调用,完成 Guest 句柄到宿主机文件描述符的翻译,以及缓冲区窗口的记账管理。

关键的差异在这里。API 转发在每一个绘图调用级别穿越 VM 边界,一帧数千次消息。virtio-nvgpu 在 ioctl 级别穿越,一帧只有 5 到 20 次消息,几乎全部是队列提交和内存分配。GPU 命令缓冲由 Guest 内部 NVIDIA 闭源编译器直接生成,不需要宿主机回放。Guest 的缓冲区由 Guest 自身拥有,合成器对其有完全的可见性和控制力。

项目在 RTX 3060(驱动 595.99.02)上跑出了一组极有说服力的基准数据。

当一帧的裸机渲染耗时 39 毫秒(纯 GPU 密集场景),Guest 的帧耗时是 38.847 毫秒,快了 0.4%,在噪声范围内。9.9 毫秒时,Guest 反而是 9.821 毫秒,快 0.7%。2.0 毫秒时,Guest 耗时 2.011 毫秒,慢 1.7%。

项目的结论很诚实:当一帧超过 2 毫秒,这是绝大多数游戏帧的渲染耗时,Guest 的性能在裸机的 2% 以内。短于 2 毫秒的帧,延迟主要来自 Guest 线程等待 GPU 完成时的唤醒开销,约 0.02 毫秒每次,而非转发本身的成本。而 60fps 的一帧是 16.7 毫秒,远高于这个阈值。

CPU 开销的数据更值得关注。未限帧约 100fps 跑 12 秒,裸机消耗了 0.40 秒 CPU,Guest 消耗 0.37 秒,比裸机还少。原因不难理解:渲染循环中没有任何东西被转发。在整个 813,691 帧的测试中,后端仅处理了 13,792 条消息,平均每 59 帧才有一次穿越,几乎全部是设备初始化阶段的流量。

多实例测试的数字同样值得细看。四台 Guest 在同一张 RTX 3060 上运行相同的负载,帧率分别为 25.84、26.49、25.57 和 25.79 fps,合计 103.7 fps,高于单 Guest 的 102.9。P50 帧时间分别为 39.165、39.164、39.168 和 39.165 毫秒,四个九级别的均匀度。四台 Guest 同时编码 H.264,每台以精确的 60Hz 节奏推送,没有触发 NVENC 会话上限。

“四就是运行过的数量,不是找到的极限。”项目的 README 中写道。

拼图在 2026 年恰好完整

virtio-nvgpu 不是凭空造出来的。它站在三个先行者的肩膀上。

最直接的先例是 gVisor 的 nvproxy。Google 的容器沙箱项目 gVisor 中的 nvproxy 组件,首次证明了一个判断:转发 NVIDIA 内核驱动 ABI 是可行的。它用版本化的 ABI 表描述了驱动 ioctl 接口的稳定性范围,virtio-nvgpu 直接继承了这套模式。区别在于,gVisor 的“Guest”是应用层沙箱,没有内核模块。virtio-nvgpu 需要把同样的思路推到完整的 KVM 栈里,意味着要自己写一个 GPL 的 Guest 内核模块来注册设备节点。

第二个支柱是 Intel 和 AMD 在开源 GPU 驱动中早已实现的 DRM 原生上下文方案。在 Intel 和 AMD 的世界里,Guest 运行真正的驱动,只有提交操作穿越 VM 边界。这是 Mesa 和 Venus 一直试图达到的设计目标。virtio-nvgpu 走到了同一个终点,但因为 NVIDIA 驱动闭源,它只能走一条不同的路,在 ABI 层面而不是 API 层面架桥。

第三个先例是 ChromeOS 的 virtio-media 项目。它展示了一种仓库布局:一个仓库同时放 GPL 的 Guest 驱动和宽松许可的 host 设备库。virtio-nvgpu 的仓库结构直接借鉴了它。driver/ 是 GPL-2.0,device/ 是 Apache-2.0,protocol/ 是 BSD-3-Clause OR GPL-2.0+ 双许可,确保 GPL 驱动和 Apache 库可以 include 同一份头文件。

这套拼图在 2026 年恰好完整。NVIDIA 闭源驱动的 ABI 经过多年版本迭代已相对稳定,项目目前支持 535.129.03、580.178.04、595.71.05 三个版本,通过范围匹配实现向后兼容,低于第一个版本的驱动被直接拒绝。开源 virtio 生态的成熟(KVM、virtqueue、Venus 社区多年积累的经验),独立开发者对 NVIDIA 驱动内部机制的理解深化,以及云游戏和云桌面对高效 GPU 虚拟化源源不断的需求,共同构成了这件事的时机窗口。

商业对冲:许可证定价权被撬开一条缝

virtio-nvgpu 的诞生,可以看作对 NVIDIA 虚拟化许可策略的一次技术性对冲。

NVIDIA 的 GPU 虚拟化产品线覆盖了从企业桌面(vPC、vApps)到专业图形(vDWS)再到云游戏(vGaming)多个细分市场,每一项都需要独立的许可证。Intel 已经在用“免许可费”的策略进攻同一市场。2022 年推出的 Intel Flex 系列 GPU 明确打出了“no licensing fees”的招牌。AMD 的 SR-IOV 方案同样没有许可层。

但 NVIDIA 的市场统治力不仅来自性能。GeForce NOW 的全球覆盖、GRID 和 vGPU 长达十年的生态积累,再加上从 A100、H100 到消费级 RTX 全线产品对 CUDA 生态的锁定效应,让竞争对手的“免许可”策略目前只能在边缘市场发力。在一个百分之百运行 CUDA 的数据中心里,“省了许可费但性能砍半”从来不是个好选项。

virtio-nvgpu 的出现改变了这个博弈的变量。它不是另一个 GPU 厂商的产品,不是 NVIDIA 自己的半开放项目,而是开源社区从底层攻击 GPU 虚拟化的核心瓶颈,并且用实测数据证明了“第三条路”确实走得通。

在此之前,云厂商面对的是一个二元选择:要么老老实实交许可费走 NVIDIA vGPU 路线,要么用 VFIO 直通并接受 GPU 利用率低下的财务损失。现在第三次出现了一个可选项:用实验性的开源项目在 KVM 上跑出 98% 以上的原生性能,NVIDIA 许可费的定价权就不再是不可挑战的。

对于云游戏和云桌面的服务商来说,这一点尤其致命。GeForce NOW 的竞争对手,Moon Gaming、Microsoft xCloud、腾讯云游戏、网易云游戏,都面临同一个问题:如何在不多付一层 NVIDIA 费用的前提下,让租户的 GPU 体验足够好。virtio-nvgpu 如果能从实验性阶段走到生产部署,它的战略杠杆远超项目规模本身。一个填补生态空白的开源组件,往往能撬动整套产业链的定价逻辑。

诚实的局限

virtio-nvgpu 在 README 里对自己的局限做了罕见的坦诚交代。

最核心的是安全性。项目完全没有 IOMMU 隔离。GPU 物理卡属于宿主机的 NVIDIA 驱动,位于宿主的 IOMMU 域内,Guest 获得的是驱动的 ioctl 接口,而不是物理设备。隔离 Guest 和宿主机内存的,是 GPU 自带的 MMU,以及 RM(NVIDIA 资源管理器)为 Guest 编程的页表。宿主机 NVIDIA 驱动处于可信计算基(TCB)中。

在互不信任的多租户场景中,VFIO 直通加 IOMMU 是严格更强的隔离方案。项目维护者对此态度清晰:“如果需要硬件隔离互不信任的租户,那还是每张卡配一个 Guest 加 IOMMU,或者走 vGPU。”

其他局限同样不容忽视。NVIDIA only,不兼容 AMD 或 Intel 显卡。版本锁定,只能匹配已实现 ABI 表的驱动版本。不支持统一内存(UVM),不支持 MIG 或 SR-IOV。窗口尺寸需要在创建 VM 前固定,超过配置的显存映射需求会直接失败。多 Guest 共享一张卡虽然通过了四路测试,但更重的负载和更大规模的场景尚未验证。隔离层组件(isolate/ 目录)目前仍只是一个设计笔记,连代码都没有。

“不信任的租户需要 IOMMU”不是一个可以用软件迭代来解决的短板。

支点正在推进

NVIDIA 的 GPU 虚拟化战略根植于一个结构性优势:如果你想在数据中心跑 CUDA、用 NVENC、调用 NVIDIA 闭源驱动栈,你没有第二条路可选。vGPU 许可证的定价权就来自这种锁定效应。

virtio-nvgpu 没有打破这把锁。它不可能一夜之间替代 NVIDIA 的 vGPU 产品线,安全性不足以承载公有云的互不信任多租户,实验性状态离生产级还有距离。

但它撬开了一条缝。

当一个项目用两千行不到的 Guest 驱动代码和一套 Rust 编写的、与任何 VMM 无关的设备库,就实现了四台 Guest 以 39.165 毫秒的四位精度共享同一张消费级 RTX 3060 同时编码 H.264 时,数据中心运营者和云服务商一定会重新算一笔账:向 NVIDIA 支付 vGPU 许可费的意愿,是不是可以重新评估了?

开源从来不一次性推翻一个阵营。它的方式是逐年拓宽可选项,直到有一天,商业许可的“不可替代性”缩水成一个窄窄的角落。

而 virtio-nvgpu 让这个角落,又窄了一点。

作品声明:内容由AI生成