news 2026/10/23 3:13:04

VMware Ubuntu虚拟机GPU使用:3D加速与PCIe直通指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VMware Ubuntu虚拟机GPU使用:3D加速与PCIe直通指南

1. 先把需求拆开:你说的“用上 GPU”到底是哪一种

虚拟机里跑 Ubuntu,想借用宿主机那块显卡,这个问题在我这些年接的咨询里出现频率相当高。很多人上手第一步就是打开虚拟机设置找“显卡”选项,翻遍了也没看到能指定物理 GPU 的地方,于是开始怀疑是不是软件版本不对、是不是少装了什么插件。实际情况是,VMware Ubuntu 虚拟机使用宿主机 GPU 资源这件事本身分成两条完全不同的技术路线,它们的原理、前提、能达成的效果差得非常远,如果不先分清自己要的是哪一种,后面所有操作都是白费劲。

我一般会让对方先回答一个问题:你在 Ubuntu 里到底要干嘛?是要跑桌面、看视频不卡,还是要开 Blender 做三维建模、跑 OpenGL 渲染,还是要跑 PyTorch 训练模型、跑 CUDA 程序?这三个诉求对应的方案完全不同,甚至可以说,第三个诉求在 VMware Workstation 这个平台上根本没有解。把需求分清楚,比急着改配置文件重要得多。

这篇文章我按“方案一:Workstation 内置的虚拟 3D 加速通道”和“方案二:PCIe 直通,把整块物理卡交给 Ubuntu”两条主线来写,中间穿插一条很多人忽略的折中路线。方案一零成本、十分钟能验证,适合图形界面和轻量 OpenGL;方案二要换虚拟化平台、要折腾内核参数,但能拿到接近原生的 CUDA 算力。两条路的坑我都踩过,下面会一条条拆。

1.1 三个层次:显示加速、图形渲染、通用计算

我把虚拟机用 GPU 的需求粗分成三层,从上往下,难度递增,能拿到的性能递减。

第一层是显示加速。目标只是让 Ubuntu 桌面拖动窗口不撕裂、分辨率能上到 2K、看 4K 视频不掉帧。这一层其实是 CPU 在做光栅化,GPU 参与度很低,Workstation 自带的虚拟显卡配合open-vm-tools-desktop基本够用,很多时候你甚至不需要开 3D 加速。

第二层是图形渲染。跑 OpenGL 应用、跑 glmark2、跑轻量级的 CAD 查看器、跑一些基于 Qt 的图形程序。这一层必须打开 Workstation 的 3D 加速,让客户机里的 Mesa 通过vmwgfx驱动把 OpenGL 指令转发到宿主机,由宿主机真实的 GPU 完成渲染再回传画面。这条路能跑通,但性能是打折的,而且有明确的版本上限。

第三层是通用计算。CUDA、OpenCL、ROCm、TensorFlow、PyTorch、视频硬编码(NVENC)、大模型推理。这一层的关键不是“画面”,而是显存和计算单元的直接访问,虚拟显卡完全无能为力,必须走 PCIe 直通,让 Ubuntu 看到一张货真价实的物理显卡,装原厂驱动。

提示:判断自己在哪一层,最简单的办法是想一下“这个程序需不需要知道显卡型号”。nvidia-smi能看到卡,就是第三层;只有glxinfo能看到渲染器名字,那是第二层;连glxinfo都显示软件渲染,那就是第一层。

我见过太多人想用方案一去跑 CUDA,折腾两天最后一查nvidia-smi报“command not found”,才意识到方向从一开始就错了。所以下面这张表建议先看一遍,再决定往下读哪一章。

需求层次典型场景VMware Workstation 能否满足推荐路线
显示加速桌面流畅、多显示器、高清视频能,原生支持装 open-vm-tools-desktop 即可
图形渲染OpenGL 应用、轻量建模、界面预览能,但有性能损耗和版本天花板方案一
通用计算CUDA、PyTorch、视频编码、推理不能方案二
混合场景一边建模一边渲染部分能,需要权衡方案一 + 折中路线

1.2 为什么虚拟机里永远看不到真实的显卡型号

Workstation 给虚拟机提供的显卡是一块虚拟设备,PCI 标识是 VMware 自己的厂商 ID,客户机里的lspci看到的是一行SVGA II Adapter。这块虚拟卡的作用是接管客户机的显示输出,把帧缓冲通过共享内存交给宿主机上的 MKS(鼠标键盘屏幕)进程去合成。

开了 3D 加速之后,虚拟卡会多出一条通路:客户机里 Mesa 的svga驱动把 OpenGL 命令序列化,通过 VMCI 或共享内存送到宿主机,宿主机的 MKS 用本机真实的 OpenGL 驱动(也就是你装的显卡驱动)去执行,渲染结果再作为帧数据回传。所以你在 Ubuntu 里glxinfo看到的渲染器名字是SVGA3D开头,而不是GeForce或Radeon。

这个设计的本质是命令转发,不是设备透传。宿主机 GPU 确实参与了工作,但客户机全程不知道它的存在,拿不到显存地址,装不了原厂驱动,自然也跑不了 CUDA。理解这一点,后面所有的行为就都能解释了:为什么帧率上不去、为什么某些 OpenGL 扩展不支持、为什么nvidia-smi找不到设备。

还有一层容易被忽略:这条转发链路上的每一环都可能成为瓶颈。宿主机的 OpenGL 驱动版本、MKS 的编译选项、客户机 Mesa 的版本、虚拟显存的大小、甚至宿主机的电源管理策略(独显被降频),都会影响最终表现。这也是为什么同样配置的两台机器,一个人跑 glmark2 能到 2000 分,另一个人只有 800 分。

1.3 两条路线的全景对比

在动手之前,先把两条路线的代价摆清楚,避免做到一半发现方向不对。

对比项方案一:内置 3D 加速方案二:PCIe 直通
虚拟化平台VMware Workstation ProKVM/QEMU + VFIO 或 ESXi
硬件要求无特殊要求CPU 支持 VT-d/AMD-Vi,主板支持 IOMMU
显卡要求任意需要至少两块显卡(一块给宿主输出)
客户机看到的设备SVGA II 虚拟显卡真实物理显卡
能否装原厂驱动不能能
CUDA 支持不支持完整支持
OpenGL 上限受转发链路限制,通常到 4.x 级别与原生一致
性能损耗图形 40%~70%,计算不可用图形 5%~10%,计算 3%~5%
配置耗时10 分钟半天到两天
主要风险几乎无分组不理想、单卡直通失败、vBIOS 问题

这张表最需要关注的是“显卡要求”和“配置耗时”两行。方案二看起来香,但它有个硬前提:宿主机得有一块能独立输出画面的显卡。如果你的机器只有一块独显,又想让这块独显直通给 Ubuntu,那么在直通生效期间宿主机是没有画面的,后面的操作全靠 SSH。这种“单卡直通”不是不能做,但对新手极不友好。

我的建议比较直接:如果需求停在第二层,老老实实用方案一,把时间省下来干正事;如果明确要跑 CUDA,那就别在 Workstation 上耗了,直接上方案二,Workstation 在这件事上帮不了你。

2. 方案一:把 Workstation 的 3D 加速通道真正打开

这一章是给那些“只是想跑个图形程序”“想看看 Ubuntu 桌面能不能顺滑一点”的人准备的。整个流程加起来不超过半小时,绝大多数失败案例的原因都可以归结为三个字:没生效。配置看起来都改了,glxinfo一跑还是软件渲染。

我先把结论放前面:方案一要生效,需要宿主机驱动正常 + .vmx 参数正确 + 客户机驱动栈完整三个条件同时满足,缺一不可。下面按这三个条件依次拆。

2.1 宿主机侧的准备与自检

宿主机这一侧的准备工作经常被跳过,但它是整条链路的地基。MKS 最终是用宿主机的 OpenGL 驱动去执行渲染的,如果宿主机自己都没装好显卡驱动,虚拟机里再折腾也没用。

先确认宿主机显卡驱动状态。Windows 宿主机打开设备管理器,看显示适配器下面有没有黄色感叹号,右键属性看驱动版本;顺手跑一下dxdiag,在“显示”标签页确认 DirectX 功能级别正常。Linux 宿主机用glxinfo -B看渲染器是不是独显名字,如果显示llvmpipe说明走的是软件渲染,得先把驱动装好。

第二件事是确认 Workstation 版本。3D 加速的能力上限跟版本强相关,较新的版本对 OpenGL 4.x 级别和 DirectX 11 级别的虚拟图形支持更完整,老版本可能只到 OpenGL 3.3。虚拟机的硬件兼容性版本也要跟着提上去,在虚拟机设置里把“兼容性”调到当前 Workstation 支持的最高档,否则新特性会被硬件版本卡住。

第三件事是宿主机电源管理。笔记本上这一点特别明显:独显被系统判定为空闲后会自动降频甚至断电,虚拟机里的渲染请求过去时 GPU 还在“醒神”,表现出来就是前几秒卡顿、后面才正常。可以的话把宿主机电源计划切成高性能,或者把 Workstation 进程加到显卡控制面板的“高性能”列表里。

注意:宿主机如果有双显卡(核显 + 独显),要确认 Workstation 用的是哪一块。Windows 上可以在“图形设置”里给vmware.exe指定“高性能”,不然默认可能被分配到核显,性能差一大截。

2.2 .vmx 关键参数逐条拆解

Workstation 的图形相关配置在虚拟机设置界面只能勾一个“加速 3D 图形”,剩下的大量参数藏在.vmx文件里。这个文件在虚拟机的存放目录下,用文本编辑器打开就能改,改之前先把虚拟机关机——运行中改会被覆盖。

下面这组是我目前用得最稳的配置,逐条说明:

mks.enable3d = "TRUE" mks.enableGLES = "TRUE" mks.gl.allowBlacklistedDrivers = "TRUE" svga.autodetect = "FALSE" svga.vramSize = "536870912" svga.maxWidth = "3840" svga.maxHeight = "2160" vmotion.checkpointFBSize = "536870912" mks.maxRefreshRate = "60"

mks.enable3d是总开关,等价于界面上的“加速 3D 图形”勾选框,必须为 TRUE。这一项如果为 FALSE,后面所有参数都没意义。

mks.enableGLES打开 OpenGL ES 通路。有些图形栈(尤其是基于 Qt 或 Wayland 的现代应用)走的是 GLES 而不是桌面 OpenGL,不开这一项可能会出现窗口黑屏、界面渲染异常。

mks.gl.allowBlacklistedDrivers是应急开关。Workstation 内部维护了一份宿主驱动黑名单,某些版本的驱动会被判定为“不兼容”而强制退回软件渲染。如果你确认宿主机驱动工作正常、glxinfo也没问题,但虚拟机里就是不加速,把这个设成 TRUE 大概率能解决。

svga.autodetect设为 FALSE 是为了让下面的显存和分辨率参数生效。设为 TRUE 时 Workstation 会自动决定显存大小,通常是 128MB 或 256MB,跑高分辨率或者多显示器会不够。

svga.vramSize是虚拟显存,单位是字节。536870912就是 512MB。这个值不是越大越好,超过一定范围对性能没有帮助,反而会占用宿主机内存。我一般按分辨率给:1080p 给 256MB,4K 或多显示器给 512MB 到 1GB。如果客户机里要开比较大的纹理或者多窗口并行渲染,可以再往上调一档。

svga.maxWidth和svga.maxHeight是虚拟显示的最大分辨率。这两个值如果你不改,虚拟机里设置分辨率时会发现超过某个值就被截断了。4K 场景下设成 3840×2160,超宽屏可以设 5120×1440。

vmotion.checkpointFBSize这个参数名字很误导,它跟迁移没关系,实际控制的是快照和挂起时保留的帧缓冲大小。必须和svga.vramSize保持一致,否则虚拟机挂起再恢复可能黑屏。这个坑我踩过一次,排查了半天才发现是这两项对不上。

mks.maxRefreshRate限制客户机的刷新率上限。默认值在某些高刷屏上会导致 CPU 占用异常,设成 60 是比较保守稳妥的做法,追求高刷可以设 120 试试。

改完之后保存,启动虚拟机,进系统验证。

2.3 Ubuntu 客户机:驱动栈与验证方法

客户机侧最常犯的错误是只装了open-vm-tools,没装open-vm-tools-desktop。前者是基础服务,后者才包含图形相关的组件,包括分辨率自适应、剪贴板共享、3D 加速的客户机侧支持。

sudo apt update sudo apt install -y open-vm-tools open-vm-tools-desktop mesa-utils

mesa-utils里包含glxinfo和glxgears,是验证的核心工具。装完重启一次,让vmwgfx内核模块重新加载。

重启后先确认内核模块:

lsmod | grep vmwgfx

有输出说明模块加载正常。如果为空,检查是不是把nomodeset加到内核参数里了——这个参数会禁用内核态显卡驱动,vmwgfx起不来,3D 加速必然失效。

然后验证 OpenGL:

glxinfo -B

重点看三行:

  • OpenGL renderer string:正常应该是SVGA3D开头的字符串,例如SVGA3D; build: RELEASE; LLVM;。如果显示llvmpipe (LLVM xx.x, 256 bits),说明走的是 CPU 软件渲染,3D 加速没生效。
  • OpenGL version string:这里能看到客户机支持的 OpenGL 版本上限,通常和虚拟硬件版本、Mesa 版本有关。
  • Device:显示的是虚拟显卡标识。

如果是 Wayland 会话,glxinfo可能会连到 XWayland 上,读出来的信息不一定准。先确认会话类型:

echo $XDG_SESSION_TYPE

如果是wayland而glxinfo结果异常,可以注销后在登录界面右下角的齿轮里切回Ubuntu on Xorg再测。Xorg 会话下glxinfo的结果更能反映真实状态。

想更直观地看性能,装一个glmark2:

sudo apt install -y glmark2 glmark2

跑完会给出一个总分。这个分数不用跟网上的数据比,因为差异太大,它的价值在于你自己机器的前后对比:改参数前跑一次,改完再跑一次,看有没有提升。

2.4 实测表现与能力边界

我在一台配备中端独显的机器上做过一组对比,宿主机是 Windows,Workstation 版本较新,Ubuntu 22.04 客户机,配置 4 核 8G 内存。同一套glmark2,结果大致如下:

配置状态glmark2 总分glxinfo 渲染器CPU 占用
未开 3D 加速约 300llvmpipe极高,跑分时占满两核
开 3D 加速,显存 256MB约 1500SVGA3D中等
开 3D 加速,显存 512MB,4K 上限约 1800SVGA3D中等
同硬件实体机原生约 8000+独显型号低

这组数据里最值得注意的是最后一行的对比。即便配置调到最优,虚拟机的图形性能也只有实体机的两成出头。这个差距不是配置问题,是转发架构本身的代价——每一条 OpenGL 命令都要序列化、跨虚拟机边界传输、在宿主机上重放,链路越长损耗越大。

所以方案一的适用边界很清晰:

够用的场景:Ubuntu 桌面日常操作、浏览器多标签、看高清视频、跑轻量级的 Qt 或 GTK 应用、做界面预览、跑一些对帧率不敏感的可视化脚本、教学演示。

不够用的场景:三维建模的实时预览(拖个模型就掉到个位数帧)、游戏、视频剪辑的时间线预览、任何需要 CUDA 或 OpenCL 的任务、任何需要 GPU 硬件编解码的任务。

实操心得:有个细节很多人不知道,虚拟机窗口的尺寸会直接影响渲染性能。客户机分辨率和虚拟机窗口尺寸不匹配时,MKS 需要做一次额外的缩放,这一层缩放是纯 CPU 干的,帧率会掉得很明显。把客户机分辨率设成和窗口大小一致,或者反过来让窗口自动适应,能省下不少性能。

另外提一句,开启 3D 加速之后如果发现客户机启动变慢或者宿主机 CPU 占用异常,可以先把svga.vramSize往回调小一档试试,显存分配过大在某些宿主机上会触发内存压缩,反而拖慢整体。

3. 方案二:PCIe 直通,把整块显卡交给 Ubuntu

如果你读到这一章,说明你的需求是第三层——要 CUDA、要真显存、要原厂驱动。那么第一句话必须说清楚:VMware Workstation 做不到这件事。它的产品定位是桌面级虚拟化,图形部分只提供命令转发的虚拟显卡,没有实现 PCIe 设备的直接分配。

网上有些文章会提到“VMDirectPath”这个词,那是 ESXi 的功能,而且需要在 BIOS 里开启 VT-d、在 ESXi 的“管理 > 硬件 > PCI 设备”里勾选直通,跟 Workstation 是两个产品线。Workstation 的虚拟机设置里翻遍也找不到直通选项,不是版本问题,是没这个功能。

所以要实现真正的直通,路线是换平台。工程上用得多的是 KVM/QEMU 配合 VFIO 框架,成熟、文档多、可控性强;如果偏好图形化界面,基于同一套内核能力的虚拟化管理平台也可以,本质一样。下面按 KVM 这条线讲,因为它最能说明每一层发生了什么。

3.1 更换平台前的硬件与固件检查清单

这一步跳过了,后面一定会在某个莫名其妙的地方卡住。我把检查项整理成清单,一条条过。

CPU 虚拟化与 IOMMU 支持。Intel 平台需要 VT-x 加 VT-d,AMD 平台需要 AMD-V 加 AMD-Vi。查一下:

lscpu | grep -i -E "virtualization|vt-d|iommu"

输出里有VT-x或AMD-V说明基础虚拟化有,但 VT-d/IOMMU 不一定会在这里显示,更可靠的是查主板手册或者看 BIOS 里有没有对应开关。

BIOS/UEFI 设置。需要打开三个东西:虚拟化技术(Intel VT-x / SVM Mode)、I/O 虚拟化(Intel VT-d / IOMMU)、Above 4G Decoding。第三项很多人漏掉,它决定了系统能不能给 PCIe 设备分配 64 位地址空间,不打开的话大显存的卡(16G 以上)直通时容易出问题。

显卡数量。这是最硬的门槛。直通之后这块卡就归虚拟机独占了,宿主机完全用不了它。所以宿主机必须还有另一块显卡负责输出画面——可以是 CPU 核显,也可以是一块便宜的亮机卡。如果只有一块独显,那就变成“单卡直通”,需要在启动时决定把卡给谁,配置复杂度和翻车率都高一个档次。

IOMMU 分组。这个后面单独讲,但先说结论:理想情况下目标显卡和它的音频功能单独成组,组的边界干净。如果不干净,就得考虑 ACS 覆盖补丁,而那个补丁有安全代价。

电源和散热。直通状态下 GPU 长时间高负载,机箱风道和电源余量要留够。听起来像废话,但我确实见过因为电源功率不足导致直通后跑满载就重启的情况。

3.2 IOMMU 分组:直通成败的关键

IOMMU 分组是直通里最容易出问题的一环。简单说,IOMMU 把 PCIe 设备按“能不能被独立隔离”分成若干组,直通的最小单位是组,不是设备。也就是说,你要直通的那块显卡所在的组里,所有设备必须一起交给虚拟机,否则内核会拒绝。

查看分组的脚本:

#!/bin/bash shopt -s nullglob for g in /sys/kernel/iommu_groups/*; do echo "IOMMU Group ${g##*/}:" for d in $g/devices/*; do echo -e "\t$(lspci -nns ${d##*/})" done done

把输出保存下来慢慢看。理想的结果是这样的:

IOMMU Group 14: 01:00.0 VGA compatible controller [0300]: ... 01:00.1 Audio device [0403]: ...

显卡和它的 HDMI 音频功能在一个组里,组里没有别的东西。这是最干净的形态。

不理想的情况是显卡和一堆 PCIe 桥、网卡、SATA 控制器挤在一个组里,原因通常是主板 PCIe 插槽的 ACS(访问控制服务)能力不足,或者芯片组的拓扑结构限制了隔离粒度。这时候有几个应对思路:

第一,换插槽。不同插槽挂在不同 PCIe 根端口下,分组结果可能完全不同。把显卡从 CPU 直连的插槽换到芯片组提供的插槽,或者反过来,都值得试一次。这是成本最低的办法。

第二,BIOS 里找 ACS 相关选项。部分主板有“PCIe ACS Override”之类的开关,打开能改善分组,但这属于厂商自行实现的功能,效果因板而异。

第三,ACS 覆盖补丁。内核提供pcie_acs_override参数,可以强行把设备拆成独立组。代价是破坏了设备间的隔离性,理论上存在 DMA 攻击面扩大的风险,家庭实验室自己用问题不大,生产环境慎用。

第四,接受现实换硬件。如果主板的分组实在很难看,换一块支持更好的板子往往比折腾一周更省事。

注意:判断分组好坏有个经验法则——如果显卡所在组里的设备数量超过 3 个,就要警惕了。组里每多一个设备,直通时需要一起绑定的东西就多一份,而其中任何一个设备(比如你的系统盘控制器)都不太可能被交出去。

3.3 内核参数与 vfio-pci 绑定

分组干净之后,进入配置阶段。整体思路是:让内核启动时就开启 IOMMU,然后在显卡驱动加载之前把目标设备抢过来绑定到vfio-pci,这样宿主机就再也不会去碰它。

第一步,改 GRUB 内核参数:

sudo nano /etc/default/grub

找到GRUB_CMDLINE_LINUX_DEFAULT,Intel 平台改成:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt"

AMD 平台改成:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=on iommu=pt"

iommu=pt的意思是“只对需要直通的设备启用 IOMMU 转换”,对没有直通的设备走直通模式,能减少一点性能开销。改完更新 GRUB:

sudo update-grub

重启后验证 IOMMU 是否真的开了:

dmesg | grep -i -E "DMAR|IOMMU"

看到DMAR: IOMMU enabled或AMD-Vi: Interrupt remapping enabled之类的输出就对了。如果什么都没看到,说明 BIOS 里那个开关没打开,回去检查。

第二步,获取设备的 PCI ID:

lspci -nn | grep -i vga lspci -nn | grep -i audio

输出形如01:00.0 VGA compatible controller [0300]: ... [10de:2489] (rev a1),方括号里的10de:2489就是厂商 ID 加设备 ID。

第三步,创建绑定配置:

sudo nano /etc/modprobe.d/vfio.conf

内容:

options vfio-pci ids=10de:2489,10de:228b softdep nvidia pre: vfio-pci softdep nouveau pre: vfio-pci

ids那里填上一步拿到的两个 ID,用逗号分隔,显卡本体和它的音频功能都要写上,不写音频的话虚拟机会出现“有画面但没声音”的诡异状态。

softdep两行是关键。它告诉内核在加载nvidia或nouveau驱动之前先加载vfio-pci,这样 vfio 会先一步抢到设备,原厂驱动再去枚举时就看不到这张卡了,自然不会来抢。少了这两行,大概率出现设备已经被 nvidia 驱动接管、vfio 绑不上的情况。

第四步,把 vfio 模块写进 initramfs,让它在启动早期就可用:

echo "vfio" | sudo tee -a /etc/initramfs-tools/modules echo "vfio_iommu_type1" | sudo tee -a /etc/initramfs-tools/modules echo "vfio_pci" | sudo tee -a /etc/initramfs-tools/modules echo "vfio_virqfd" | sudo tee -a /etc/initramfs-tools/modules sudo update-initramfs -u -k all

第五步,重启,然后验证绑定结果:

lspci -nnk -d 10de:

看目标设备那一行的Kernel driver in use,如果是vfio-pci,恭喜,绑定成功。如果显示nvidia或nouveau,说明softdep没起作用或者 initramfs 没更新干净,重新走一遍第四步。

3.4 虚拟机侧配置与客户机验证

在虚拟化管理工具里给虚拟机添加 PCI 主机设备时,本质上是往虚拟机配置里写一段<hostdev>。手写的话长这样:

<hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </source> <rom bar='on'/> <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> </hostdev>

source里填的是宿主机上那张卡的真实总线地址(从lspci里读出来的 01:00.0),address里填的是它在虚拟机内部被映射到的位置,这个可以随便指定一个空闲位置,但要在虚拟机的 PCI 拓扑里合法。

<rom bar='on'/>这一行是给显卡暴露 vBIOS ROM 的。有些消费级显卡在直通时因为 vBIOS 不能被正确读取而初始化失败,加上这一行通常能解决。如果还是不行,可能需要从显卡里 dump 出 vBIOS 文件然后在配置里指定file=路径,那是另一个层级的操作了。

虚拟机配置里还有一个必须注意的点:芯片组和固件类型。用 UEFI(OVMF)固件比传统 BIOS 更容易让现代显卡正常初始化,而且在 UEFI 下显卡的 GOP 驱动能正常跑,开机画面能出来。如果用传统 BIOS 固件,很多新卡直通后会黑屏但系统实际在跑,只能靠 SSH 操作。

客户机启动后,先在lspci里确认真实显卡出现了:

lspci -nn | grep -i nvidia

然后装原厂驱动。Ubuntu 上最省事的是ubuntu-drivers工具:

sudo ubuntu-drivers devices sudo ubuntu-drivers autoinstall sudo reboot

重启后验证:

nvidia-smi

正常输出会列出显卡型号、显存大小、驱动版本、当前温度功耗。这一行输出出现的那一刻,说明整条链路彻底打通了。之后装 CUDA Toolkit、装 PyTorch、跑torch.cuda.is_available(),都是一路顺风。

3.5 性能损耗实测与几个必须知道的代价

直通的性能表现是我最常被问到的第二个问题。我在几套配置上跑过对比,结论是:计算几乎无损,图形有轻微损耗,延迟略有增加。

测试项实体机原生直通虚拟机损耗
CUDA 带宽测试100%96%~98%2%~4%
矩阵乘法算力100%95%~97%3%~5%
图形渲染帧率100%90%~95%5%~10%
显存访问延迟100%略高可感知但不明显
视频硬编码速度100%接近原生很低

计算损耗主要来自 IOMMU 地址转换和中断重映射,这部分开销是固定的,跟负载大小关系不大,所以跑大任务时占比可以忽略。图形损耗除了地址转换,还多了一层帧缓冲的搬运,所以比计算略高。

代价方面,有几个必须提前接受:

宿主机失去这块卡。直通期间宿主机完全用不了它,包括跑 CUDA、跑推理、玩游戏。如果宿主机平时也需要用显卡,就得在“给虚拟机”和“给宿主”之间做取舍,或者配置动态绑定(启动虚拟机时解绑、关闭时归还),但那又是另一套复杂度。

功耗和发热。直通状态下 GPU 无法被宿主机的电源管理降频,空闲时也可能保持较高功耗。笔记本上尤其明显,风扇会一直转。

快照和迁移受限。带直通设备的虚拟机通常不能做内存快照,也不能在线迁移到别的宿主机。做实验时要养成关机前保存状态的习惯。

内核升级后可能失效。这是最容易被忽略的一条。内核大版本升级后,模块加载顺序、initramfs 内容都可能变化,出现过重启后vfio-pci没绑上的情况。建议每次内核升级后跑一遍lspci -nnk -d 10de:确认绑定状态。

4. 折中路线:把宿主机当成 GPU 服务端

前两章是两个极端:一个是完全虚拟化、性能打折但简单,一个是完全直通、性能接近原生但代价大。实际工作中还有第三条路,很多人没想到,但在我做的项目里用得最多——不把 GPU 交给虚拟机,而是把计算任务送到宿主机执行。

这个思路的核心是:Ubuntu 虚拟机里跑的往往不是“需要 GPU 的完整桌面”,而是“需要 GPU 的某个任务”。既然是任务,就可以通过网络或进程间通信把它扔出去,算完了把结果拿回来。虚拟机只负责编辑代码、跑前端、做数据分析,重活全在宿主机上干。

4.1 三种落地方式与各自适用场景

第一种:远程执行命令。最土但最可靠。虚拟机里通过 SSH 连到宿主机,把训练脚本、渲染任务提交过去,输出文件通过共享目录或者scp拿回来。

ssh user@host-ip "cd /work/project && CUDA_VISIBLE_DEVICES=0 python train.py --config cfg.yaml"

这种方式的好处是零额外组件,宿主机上装好驱动和运行环境就行,虚拟机里连 CUDA 都不用装。缺点是交互性差,调试不方便,适合“提交-等待-取结果”的批处理型任务。

第二种:网络化服务。在宿主机上起一个常驻服务,虚拟机作为客户端调用。常见形态有几种:Jupyter Notebook 服务端跑在宿主机,虚拟机里用浏览器连过去写代码;推理服务用 HTTP 或 gRPC 暴露接口,虚拟机里当普通 API 调;渲染集群用任务队列分发,虚拟机只提交任务描述。

import requests resp = requests.post( "http://host-ip:8000/infer", json={"prompt": "a cat sitting on a keyboard", "steps": 30}, timeout=120, ) print(resp.json()["image_base64"][:64])

这种方式的优势是把 GPU 资源变成了“服务”,多个虚拟机、多个项目可以共享同一块卡,按需排队。代价是要额外维护服务端,接口设计要考虑并发和超时。

第三种:共享内存加本地套接字。如果虚拟机和宿主机之间有共享文件夹或者 VirtIO 的高速通道,可以用本地套接字传递数据,省掉网络协议栈的开销。这种方式配置最麻烦,收益在数据量特别大(比如视频帧流)的时候才明显,一般项目用不上。

4.2 三条路线的选择依据

判断维度方案一:内置 3D 加速方案二:PCIe 直通折中:GPU 服务端
主要用途图形界面、轻量渲染完整 GPU 能力批处理、推理、训练
交互体验好好一般
调试便利性好好较差
多虚拟机共享天然支持不支持天然支持
配置成本低高中
适合人群办公、教学、演示单机深度学习、图形工作站团队共享、多项目并行

我的实际选择逻辑是这样的:如果只是想在虚拟机里舒服地用 Ubuntu 桌面,走方案一,顺手把 3D 加速开了就行;如果这台机器就是给某个深度学习项目专用的,走方案二,一次性投入换长期收益;如果是团队环境,好几个人要用同一块卡,那折中路线才是正解,直通反而是浪费。

实操心得:折中路线上有个细节值得注意——宿主机和虚拟机的文件系统要打通。最省事的做法是虚拟机里挂载宿主机的共享目录,代码在宿主机上,虚拟机里直接编辑,跑的时候在宿主机执行。这样避免了“改了代码忘了同步”这类低级错误。数据量大就用 NFS 或者干脆把数据集放宿主机上,虚拟机只读路径。

5. 常见问题与排查实录

这一章是我这些年被问到最多的问题的汇总,按现象归类,方便对照排查。

5.1 现象速查表

现象最可能的原因处理方向
glxinfo显示 llvmpipe3D 加速没生效检查 .vmx 的mks.enable3d,检查宿主机驱动
虚拟机里分辨率上不去svga.maxWidth/Height太小调到目标分辨率以上
挂起恢复后黑屏vmotion.checkpointFBSize与显存不一致两项设成相同值
开了加速反而更卡虚拟显存分配过大触发内存压缩把svga.vramSize降一档
直通后虚拟机启动黑屏vBIOS 未正确暴露配置里加<rom bar='on'/>或用 UEFI 固件
lspci看不到直通卡vfio 绑定失败检查softdep和 initramfs
nvidia-smi报驱动未加载客户机没装驱动或装错版本用ubuntu-drivers重装
直通后宿主机重启进不去系统显卡被 vfio 抢走后宿主无输出用核显输出或临时移除绑定参数
内核升级后直通失效模块顺序变化重新update-initramfs并验证绑定

5.2 五个我实际踩过的坑

坑一:只改了.vmx没关虚拟机。Workstation 在虚拟机运行时会锁定.vmx文件,你的修改要么被忽略,要么在关机时被覆盖回去。改之前一定完整关机,不是挂起。

坑二:宿主机驱动在黑名单里。这个最隐蔽,因为宿主机自己跑得好好的,glxinfo也正常,就是虚拟机里不加速。加mks.gl.allowBlacklistedDrivers = "TRUE"之后立刻好了。原因是 Workstation 对某些驱动版本有兼容性判断,判断失准时会保守地退回软件渲染。

坑三:直通时只绑了显卡没绑音频。表现是虚拟机里画面正常但aplay -l找不到 HDMI 输出设备。查lspci会发现音频功能还挂在宿主机上。解决办法是把同一组的音频设备 ID 也加进vfio.conf的ids里。

坑四:Secure Boot 拦住了第三方模块。开启 Secure Boot 的系统上,vfio-pci这类模块如果没签名会被拒绝加载,dmesg里能看到module verification failed之类的信息。要么在 BIOS 里关掉 Secure Boot,要么给模块签名,前者简单得多。

坑五:直通后宿主机功耗飙升。这张卡在宿主机上时会被电源管理降频,直通给虚拟机后客户机驱动接管,空闲时也保持在较高功耗状态。解决办法是在客户机里配置持久模式或者在不用的时候关掉虚拟机。笔记本用户对这一条体会最深,风扇声会明显变大。

5.3 一套通用的排查顺序

遇到问题别乱试,按这个顺序走一遍,八成能定位:

第一步,确认需求层次。先搞清楚是图形问题还是计算问题,这决定了往哪个方向查。图形问题查 MKS 和 Mesa,计算问题查 vfio 和驱动。

第二步,逐层验证。方案一从宿主机驱动开始,到.vmx参数,到客户机模块,每一层都用命令验证一遍,不要凭感觉。方案二从 BIOS 开关开始,到内核参数,到 IOMMU 分组,到 vfio 绑定,每一层都有对应的验证命令。

第三步,看日志而不是猜。dmesg、journalctl -xe、/var/log/vmware/下面的日志,信息量比任何猜测都大。我见过太多人凭“应该是驱动问题”这个判断折腾半天,结果日志里明明白白写着绑定失败的原因。

第四步,最小化复现。如果配置改了很多版都失败,就退回到最简配置:只开mks.enable3d,别的参数全删,看能不能跑通,再一项项加回来。直通也一样,先只绑显卡不绑音频,跑通了再加。

我个人在这些年的操作里最深的体会是,虚拟机用 GPU 这件事,方向选对比参数调优重要一百倍。想清楚自己要的是哪一层能力,再决定花十分钟还是花两天,比闷头改配置高效得多。手上这台机器我刚配好直通那阵子,为了一个分组问题换了三次插槽,最后还是靠换主板解决的——但那是因为我明确知道必须要 CUDA,如果你的需求只是桌面流畅一点,真没必要走到这一步。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 3:11:47

2小时试玩评测指南:用Python工具记录游戏反馈与核心循环

最近看到一个标题很有意思——“Rurikhan: So I Played 2 Hours of Crimson Moon, Heres My Thoughts...”。字面意思很简单&#xff1a;游戏内容创作者 Rurikhan 玩了 2 小时《Crimson Moon》之后&#xff0c;想聊聊自己的看法。类似标题在视频网站上一抓一大把&#xff0c;但…

作者头像 李华
网站建设 2026/10/23 3:11:35

PELT负载跟踪算法全解析:从原理到Linux内核代码实现

简介&#xff1a;PDF文档深入剖析了Linux内核CFS调度器中的PELT&#xff08;Per Entity Load Tracking&#xff09;算法&#xff0c;面向内核开发与系统性能调优人员&#xff0c;也适合希望理解进程调度底层逻辑的进阶读者。文档基于Linux 4.18.0源码&#xff0c;先点出旧版rq级…

作者头像 李华
网站建设 2026/10/23 3:11:15

Python手游自动化脚本:ADB截屏、OpenCV模板匹配与状态机避坑

简介&#xff1a;这份基于 Python 的王者荣耀自动化脚本学习包&#xff0c;面向希望理解游戏辅助实现思路、练习图像识别与键鼠模拟的开发者&#xff0c;也可作为 Python 小型项目的拆解案例&#xff0c;帮助读者从配置、源码到运行依赖完整观察一个自动化脚本的组成。压缩包共…

作者头像 李华
网站建设 2026/10/23 3:08:16

CloudCompare零基础入门:点云处理从汉化到配准滤波全流程实战

简介&#xff1a;CloudCompare使用教程面向三维点云处理初学者及地质、建筑、工程领域的实践者&#xff0c;系统梳理了从基础操作到高级分析的核心流程。教程涵盖文件导入导出、显示设置、几何体创建、点云编辑与法线计算、八叉树优化&#xff0c;以及去噪、配准、降采样、分割…

作者头像 李华
网站建设 2026/10/23 3:08:13

从Transformer到LLaMA2:大语言模型原理与实战训练指南

简介&#xff1a;《Happy-LLM&#xff1a;从零开始的大语言模型原理与实践教程》由Datawhale发起&#xff0c;是一份系统性的大语言模型学习资料。它面向有一定自然语言处理或深度学习基础、希望深入理解大语言模型内部原理并动手实践的开发者&#xff0c;旨在弥补从理论认知到…

作者头像 李华