PVE 显卡直通听起来很复杂,其实原理很简单。就是把物理显卡从 Proxmox 主机剥离出来,整个交给某个虚拟机用。虚拟机里跑 Windows,装上驱动,显卡就跟真机一样能跑游戏、能做 AI 训练、能做视频渲染。这篇文章把整个流程讲清楚,包括那些容易踩的坑。
为什么要做显卡直通
最常见的场景是家庭服务器一机多用。白天这台机器跑 NAS、跑 Docker 容器、跑各种服务,晚上开一个 Windows 虚拟机打游戏,直通的显卡性能几乎没有损失。另一个场景是 AI 训练,很多人在 PVE 上开一个专门跑 PyTorch 的虚拟机,把显卡直通进去,跟宿主机隔离开,不会因为驱动冲突把整个系统搞崩。还有人是做核显直通,留着独显给宿主机用,核显直通给轻量的虚拟机做转码。
开始之前要确认的几件事
不是所有硬件都支持直通,先检查这几点,省得白折腾。
- 主板 BIOS 里要能开启 IOMMU,Intel 平台叫 VT-d,AMD 平台叫 AMD-Vi。老主板有些阉割了这个功能,尤其是一些低端的消费级板子。
- CPU 要支持虚拟化,现在主流 CPU 基本都支持,但服务器场景建议用带 VT-d 的型号,普通 i3 也可以,只是有些型号会阉割。
- 显卡要在独立的 IOMMU 分组里,或者能通过 ACS Override 补丁强行拆分组。分组混在一起会导致直通失败或者把不该直通的设备也带进去。
- 准备一块核显或者第二块显卡给宿主机自己用,不然直通之后主机没有输出,远程管理会麻烦一些,只能靠 SSH。
第一步:BIOS 里开启 VT-d 和 IOMMU
进 BIOS,找到 Advanced 或者 Chipset 设置,把 Intel VT-d(或 AMD IOMMU)打开,同时也把 SR-IOV 打开,虽然不是必须的,但有些主板需要一起开才生效。保存重启。
第二步:修改 PVE 内核参数
PVE 8.x 默认用 systemd-boot 或者 grub,看你安装时的分区方式。先确认用的是哪个:
ls /sys/firmware/efi 2>/dev/null && echo "UEFI,可能用 systemd-boot" || echo "Legacy,用 grub" proxmox-boot-tool status
如果是 systemd-boot,编辑:
nano /etc/kernel/cmdline
Intel 平台加上 intel_iommu=on iommu=pt,AMD 平台加 amd_iommu=on iommu=pt。保存后执行:
proxmox-boot-tool refresh
如果是 grub,编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX_DEFAULT 这一行里加上同样的参数,然后:
update-grub
重启主机,让参数生效。
第三步:确认 IOMMU 分组
重启后跑这段命令,看看显卡在哪个分组里,分组里有没有别的不相关设备:
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
printf 'IOMMU Group %s ' "$n"
lspci -nns "${d##*/}"
done | sort -V理想情况是显卡和它的 HDMI 音频控制器单独在一组。如果同一组里混进了主板的 USB 控制器或者 SATA 控制器,直通会把这些设备也一起拿走,宿主机可能用不了对应的接口。这种情况需要用 ACS override patch,或者干脆换个显卡插槽试试,有些主板不同插槽走的 PCIe 通道分组不一样。
第四步:让显卡绑定到 vfio-pci
先查显卡的 PCI ID:
lspci -nn | grep -i nvidia
会看到类似 10de:2504 这样的 ID,前面是厂商 ID,后面是设备 ID。记下来,显卡和它自带的音频设备通常各有一个 ID。
编辑 /etc/modprobe.d/vfio.conf:
echo "options vfio-pci ids=10de:2504,10de:228e" > /etc/modprobe.d/vfio.conf
把两个 ID 换成你自己显卡的实际值。然后屏蔽掉宿主机自带的显卡驱动,不然会跟 vfio 抢设备:
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf echo "blacklist nvidiafb" >> /etc/modprobe.d/blacklist.conf echo "options nouveau modeset=0" >> /etc/modprobe.d/nouveau-kms.conf
AMD 显卡对应屏蔽 radeon 和 amdgpu。更新一下 initramfs 再重启:
update-initramfs -u -k all reboot
重启后确认驱动是不是已经换成 vfio-pci:
lspci -nnk | grep -A3 -i nvidia
如果 Kernel driver in use 显示的是 vfio-pci,说明这一步做对了。
第五步:在虚拟机里挂载显卡
虚拟机建议用 OVMF(UEFI)而不是 SeaBIOS,Windows 虚拟机配合 q35 芯片组直通效果更稳定。在 PVE 网页界面里,进虚拟机的硬件设置,添加 PCI 设备,选中你的显卡,把它的音频子设备也一起勾上,勾选 All Functions,再勾选 PCI-Express。
如果是 NVIDIA 显卡,还要在虚拟机配置里加一条隐藏 KVM 特征的参数,不然驱动会检测到是虚拟机环境直接罢工,装完驱动报错误代码 43。在虚拟机的 Options 里找到 Args,或者直接改配置文件 /etc/pve/qemu-server/<虚拟机ID>.conf,加上:
args: -cpu host,kvm=off,hv_vendor_id=null
启动虚拟机,装 Windows,装好之后正常安装 NVIDIA 或 AMD 官方驱动,跟物理机操作一样。
常见的错误代码 43:NVIDIA 显卡在虚拟机里识别到但报错,多半是缺了 kvm=off 这个参数,或者显卡是消费级卡,NVIDIA 官方驱动主动屏蔽了虚拟化场景。后面这种情况需要用打了补丁的驱动或者换专业卡。
关机重启黑屏怎么办
很多消费级显卡(尤其是老一点的 NVIDIA 卡)有个著名的 reset bug,虚拟机第一次开机正常,关机再开就黑屏,必须重启整台物理机才能恢复。这是显卡本身不支持 FLR(功能级重置)导致的,跟配置对不对没关系。解决办法有几个:装 vendor-reset 内核模块(主要针对 AMD 卡),或者用脚本在虚拟机关机时手动执行一次 PCI 总线重置,或者干脆换一块支持 FLR 的显卡,专业卡(Quadro、RTX A 系列)基本都没这个问题。
Ubuntu、Win10、Win11 直通有什么区别
宿主机这边的配置流程完全一样,区别都在客户机系统里。Windows 直接装官方驱动就行,识别率最高,兼容性最好,游戏和 CUDA 都没问题。Ubuntu 客户机同样能直通显卡跑 CUDA 或者深度学习任务,但要注意在虚拟机里也要手动装官方驱动,而不是用系统自带的开源驱动,装之前记得先卸载或者屏蔽掉虚拟机里的 nouveau。Win10 和 Win11 直通没有本质差别,Win11 需要开 TPM 和安全启动,PVE 里加一个 TPM State 存储、勾选 UEFI 就能过检测,其他步骤跟 Win10 一样。
核显直通的特殊情况
Intel 核显直通比独显麻烦一点,因为核显跟主板的显示输出深度绑定,很多主板不支持真正意义上的核显直通,只能用 SR-IOV 虚拟化(也就是 GVT-g),把一块核显拆成多份共享给多个虚拟机,性能会打折扣,但适合轻量转码场景,比如 Jellyfin、Plex 的硬件转码。真正的核显直通(把核显整个独占给一个虚拟机)需要主板和 CPU 都支持,操作步骤跟独显类似,但坑更多,遇到问题的概率也更高。
小结:显卡直通的核心就是四步,开 IOMMU、绑定 vfio-pci、屏蔽宿主机驱动、虚拟机里挂 PCI 设备。中间容易出问题的是 IOMMU 分组没拆干净、NVIDIA 的错误代码 43、还有关机黑屏的 reset bug。这三个问题占了绝大多数直通失败的案例,遇到问题先从这三个方向排查,基本都能找到原因。

