最近发现了一个很好用的相册备份软件immich,但是他的AI识别需要NVIDIA GPU,可惜我电脑上只有一块卡,需要直通给虚拟机做视频剪辑与转码工作,这下怎么办呢?
在网上找了半天,发现一个Nvidia显卡的虚拟化方案vGPU,类似于intel核显sr-iov,可以拆分物理显卡为多个虚拟化显卡,从而同时分配给docker和虚拟机使用,完美解决我的需求,可惜虚拟化显卡都有个弊端,那就是无法输出视频了,不过我的工作流也刚好不需要视频输出,完美😎
参考教程
感谢以下几位大佬们的教程!这篇文章算是我自己的一个记录,也把我踩的坑总结一下。
- stl88083365/unraid-nvidia-vgpu-driver (github.com)
- 在UNRAID上通过vGPU虚拟化把玩Tesla P4炼丹卡 | 杂乱的备忘录 (s1oz.github.io)
- 佛西博客 - 来自民间的VGPU授权fastapi-dls (buduanwang.vip)
- Proxmox 7 vGPU - Wim van 't Hoog (wvthoog.nl)
准备
- unRAID系统
- 合适的网络环境,需要访问github、docker hub、unRAID应用商店
- BIOS开启VT-d / Above 4G Decoding / IOMMU之类跟直通相关的选项,我这边re-bar也开了,似乎没有问题
- unRAID系统中不要绑定nvidia显卡,并且检查虚拟机是否有使用该显卡,把直通全部取消掉
- 一块受支持的NVIDIA显卡,下表仅供参考,实测我的1650也是可以模拟为RTX 6000从而支持vGPU,但是30系及以上必不支持。
Nvidia card | GPU Chip | vGPU unlock profile |
---|---|---|
GTX 900 Series (first gen) | GM107 x4 | Tesla M10 |
GTX 900 series (second gen) | GM204 x2 | Tesla M60 |
GTX 1000 Series | GP102 | Tesla P40 |
Titan V, Quadro GV100 | GV100 | Tesla V100 16GB |
RTX 1600/2000 Series | TU102 | Quadro RTX 6000 |
RTX 3000 Series | GA10x | Ampere isnot supported |
安装相关插件
-
不要安装CA中有ich777大佬提供的Nvidia-Driver插件,这个插件安装的驱动无法使用vGPU。如果已安装请卸载。
-
CA搜索安装User Scripts以及Dynamix File Manager,用于自动运行vGPU设置脚本,编辑配置文件
-
安装支持vGPU的NVIDIA驱动插件,该插件因为破解vGPU的原因无法通过CA审核,需要在插件-安装插件中手动输入链接进行安装。注意安装时会从github下载约500M的驱动文件,请确保网络连接正常,保持耐心等待,坐和放宽。
1
https://raw.githubusercontent.com/stl88083365/unraid-nvidia-vgpu-driver/master/nvidia-vgpu-driver.plg
-
终端运行此命令,告知由主机驱动程序管理设备;
1
echo "options nvidia cudahost=1" > /boot/config/modprobe.d/nvidia.conf
-
重启,此时去vgpu插件设置页面会显示一些错误,这应该是正常的,因为还没有设置脚本。可直接进入终端输入nvidia-smi确认显卡正常驱动。
设置vGPU拆分脚本
-
检查vGPU插件是否包含当前显卡型号
这一步相对而言比较复杂,主要原因在于显卡太多,且即便是同一个型号的显卡其ID也不尽相同,因此开发者无法全部全面覆盖,如果运气不好碰到没有包含的显卡,需要自行添加相关配置文件,我自己摸索的办法如下:
-
确认显卡支持vGPU破解,30系及以上均不支持;
-
使用以下命令检查是否已在配置文件中,如果有输出则说明运气比较好,直接跳转第二步设置脚本,否则需要修改配置文件
1
mdevctl types
-
在unraid-工具-系统设备中,定位到自己待设置的显卡,记住其ID,也就是下图红框中,以10de开始的内容,比如我的就是
10de:1f82
-
执行以下命令,将配置文件复制到启动U盘的
config
文件夹,方便在unraid网页进行可视化编辑。如果你熟悉命令行操作,也可直接命令行编辑,但是一定要复制到U盘中来,因为原始位置的配置文件每次启动系统后都会恢复。1
cp /usr/share/nvidia/vgpu/vgpuConfig.xml /boot/config/
-
进入unraid-主界面,进入Flash的文件管理器
-
转到config文件夹,打开刚刚复制的
vgpuConfig.xml
文件,在PCI\VEN_10DE - NVIDIA Corporation | Device Hunt中查找与自己型号较为接近的桌面端显卡ID,以我的1650为例子,在网站上搜索1660,查到其ID为2184,在vgpuConfig.xml
中搜索0x2184
,发现存在该型号的配置文件,故将0x2184
修改为我GTX1650的ID即0x1f82
。这个过程可能需要多找几次,但是肯定是可以找到的,修改后保存即可。<img src="assets/similar_gpu_id.png" alt="image-20240707182203146" style="zoom: 33%;" />
-
将原始配置文件重命名,复制修改后的文件到原始位置
1 2
mv /usr/share/nvidia/vgpu/vgpuConfig.xml /usr/share/nvidia/vgpu/vgpuConfig.xml.bak cp /boot/config/vgpuConfig.xml /usr/share/nvidia/vgpu/
-
-
修改脚本,进行诸如vGPU设置和配置文件修改等操作。脚本文件有四块地方需要修改
-
如需要使用自定义的
vgpuConfig.xml
文件,请取消注释修改1处的相关代码; -
定义虚拟机使用的vGPU的UUID,按下方vGPU的类型按需增删,分几个就用几个,uuid可用uuidgen命令创建,名字随意,注意在
arr
的括号中也要有相同内容; -
定义N卡的PCI位置,使用nvidia-smi或者去unraid-工具-系统设备中查看,一般只需要修改07为自己的显卡位置;
-
定义vGPU的类型。在Nvidia Vgpu Driver插件中或使用
medvctl types
查询支持的模式。这里的型号选取是根据显存来的。以我的1650 4GB为例,我决定使用Q模式,并将其拆分为2个vGPU,则每个vGPU显存为4096MB÷2=2048MB,查找可知应选用nvidia-257
型号的vGPU类型。 -
修改完成的脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
#!/bin/bash ### 修改1:如果你需要使用自己修改的vgpuConfig.xml,请删除下列两行的“#”号以取消注释; # mv /usr/share/nvidia/vgpu/vgpuConfig.xml /usr/share/nvidia/vgpu/vgpuConfig.xml.bak # cp /boot/config/vgpuConfig.xml /usr/share/nvidia/vgpu/ ### 修改2:定义虚拟机使用的vGPU的UUID,按下方vGPU的类型按需增删,分几个就用几个,uuid可用uuidgen命令创建,名字随意,注意在arr的括号中也要有相同内容 windows="ae9572f6-1259-4136-9aa4-497dda98d2db" other="868bfe06-47c1-40a3-82df-ffd518be72d3" arr=( "${windows}" "${other}" ) ### 修改3:定义N卡的PCI位置,使用nvidia-smi或者去unraid-工具-系统设备中查看,一般只需要修改07为自己的显卡位置 NVPCI="0000:07:00.0" ### 修改4:定义vGPU的类型。在Nvidia Vgpu Driver插件中或使用medvctl types查询支持的模式。这里的型号选取是根据显存来的。以我的1650 4GB为例,我决定使用Q模式,并将其拆分为2个vGPU,则每个vGPU显存为4096MB÷2=2048MB,查找可知应选用nvidia-257型号的vGPU类型。 MDEVLIST="nvidia-257" depmod -a nvidia-modprobe if [ ! -d /boot/config/nvidia-vgpu ]; then mkdir -p /boot/config/nvidia-vgpu fi if [ ! -d /etc/vgpu_unlock/ ]; then mkdir -p /etc/vgpu_unlock/ fi if [ -f /boot/config/nvidia-vgpu/profile_override.toml ]; then ln -sf /boot/config/nvidia-vgpu/profile_override.toml /etc/vgpu_unlock/profile_override.toml else touch /boot/config/nvidia-vgpu/profile_override.toml ln -sf /boot/config/nvidia-vgpu/profile_override.toml /etc/vgpu_unlock/profile_override.toml fi echo "unlock = false" > /etc/vgpu_unlock/config.toml env LD_PRELOAD=/usr/local/lib/libvgpu_unlock_rs.so >/dev/null if pgrep -x nvidia-vgpu-mgr > /dev/null then nvidia-vgpud stop nvidia-vgpu-mgr stop killall nvidia-vgpu-mgr fi LD_PRELOAD=/usr/local/lib/libvgpu_unlock_rs.so nvidia-vgpud LD_PRELOAD=/usr/local/lib/libvgpu_unlock_rs.so nvidia-vgpu-mgr sleep 3 for os in "${arr[@]}"; do if [[ "$(mdevctl list)" == *"$os"* ]]; then echo " [i] Found $os running, stopping and undefining..." mdevctl stop -u "$os" mdevctl undefine -u "$os" fi done for os in "${arr[@]}"; do echo " [i] Defining and running $os..." mdevctl define -u "$os" -p "$NVPCI" --type "$MDEVLIST" mdevctl start -u "$os" done echo " [i] Currently defined mdev devices:" mdevctl list
-
-
利用User Scripts添加脚本,并设置为
At First Array Start Only
(第一次启动阵列时运行脚本)。 -
重启系统,启动阵列。如果一切顺利,则可以在Nvidia Vgpu Driver插件中正常显示所有内容。
配置虚拟机以及vGPU授权
-
本文以windows为例,首先正常添加一个windows虚拟机,并安装好系统,注意使用
SPICE
而不是默认的VNC
作为虚拟显卡协议,因为VNC
和vGPU有冲突; -
为虚拟机添加vGPU。这一步需要手动编辑虚拟机的xml文件,注意编辑xml后如果切换普通视图再编辑保存,则自定义的xml内容会消失,需重新编辑xml。
-
切换为xml视图
-
在配置文件最末尾,找到
</video>
字符,在其后添加下列内容。有两处按需修改,其中,uuid
为自己脚本中配置的UUID,slot
中的数字比一定要和宿主机中的相同,如果在保存时提示创建虚拟机错误如XML error: Attempted double use of PCI Address 0000:00:07.0
,则可能是当前slot 07
已经被其他设备占用,修改成任意不会起冲突的数字后保存即可。1 2 3 4 5 6
<hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='off'> <source> <address uuid='868bfe06-47c1-40a3-82df-ffd518be72d3'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </hostdev>
-
-
启动虚拟机,安装驱动
- 在该链接下载驱动:适用于 NVIDIA RTX 虚拟工作站 (vWS) 的驱动程序 | Compute Engine Documentation | Google Cloud
- 不一定要使用最新的驱动,我使用551.78驱动出现代码43,使用538.46就正常
-
vGPU授权。为了能够正常使用vGPU,仅有驱动是不行的,还需要有NVIDIA的授权,但是消费级显卡是没有授权的,这就需要使用大佬们配置好的仿冒授权
-
UNRAID下载容器模板
1
wget -O /boot/config/plugins/dockerMan/templates/FastAPI-DLS.xml https://raw.githubusercontent.com/s1oz/unraid/master/fastapi-dls.xml
-
在docker中添加容器,选择对应的模板,自行修改模板中DLS_URL变量的IP,然后启动;
-
浏览器访问
https://容器IP:9443/-/client-token
,会下载一个授权config文件,将该文件放入C:\Program Files\NVIDIA Corporation\vGPU Licensing\ClientConfigToken
文件夹中,没有文件夹新建一个就好。
-
-
重启,即可看到自动跳出的授权,此时所有功能均可使用,除了物理显示输出。
配置Emby docker
如果需要使用emby调用显卡进行解码,需要进行一些修改。
- 编辑Emby docker配置,打开高级视图
- 在额外参数中添加
--runtime=nvidia
- 新建变量,名称随意,键为
NVIDIA_VISIBLE_DEVICES
,值为all<img src="assets/NVIDIA_VISIBLE_DEVICES.png" alt="image-20240707224039334" style="zoom:50%;" />
- 启动容器web界面,进入设置-转码,勾选显卡即可
总结
- 该功能适合不需要物理输出,需要同时在虚拟机和docker中使用Nvidia独立显卡的用户进行使用
- 过程比较复杂,需要细致进行配置
- 玩的愉快🙌🙌