在UNRAID上通过vGPU虚拟化把玩Tesla P4炼丹卡

废话 直接跳

  • 主要还是折腾,心痒痒,对~就是玩
  • 从1660直通虚拟机,核显转码>拆掉独显,直通核显>用炼丹卡玩下vGPU
  • 说实话就是一开始直通独显玩游戏,但是没啥意思就拆了省电,然后虚拟机没显卡又不好玩放置类小游戏,所以又直通了核显,然后又嫌弃性能过低...就又搞了大显存的P4来给Emby转码+虚拟机串流玩游戏+试试Ai涩图?

需要准备些什么

  1. 一台正常使用的UNRAID电脑
  2. BIOS正确开启VT-d / Above 4G Decoding 之类跟直通相关的选项
  3. 一张身经百战的Tesla P4炼丹卡
  4. 无所畏惧的精神

UNRAID安装vGPU插件

前提

  1. 保证UNRAID上不要安装Nvidia-Driver插件
  2. 正常插入P4炼丹卡到主机中,在UNRAID的系统设备中不要勾选P4炼丹卡

安装插件

  1. 安装stl88083365大佬开发的Unraid vGPU插件 再次感谢大佬搞了这么方便的插件
    releases页面显示的就是插件支持的最新内核版本号
    需要注意的是插件的版本是跟UNRAID的内核走的,如UNRAID版本过新,请降级后安装对应插件
  2. 插件安装完毕后可以根据大佬项目中的README.md流程走
    大致就是安装'user scripts'插件,新建个用于加载驱动的脚本并粘贴以下内容
    需要修改的两段我中文注释了
#!/bin/bash
# set -x

# Load drivers 
depmod -a
nvidia-modprobe

## 一共两段
### 段落1
### 定义虚拟机使用的vGPU的UUID,按下方vGPU的类型按需增删,分几个就用几个,uuid可用uuidgen命令创建
vm1="2b6976dd-8620-49de-8d8d-ae9ba47a50db"
vm2="5fd6286d-06ac-4406-8b06-f26511c260d3"
#vm3="f090c00f-338b-47b4-a419-700101cd70c5"
#vm4="cee34c0a-6144-4f3e-8bdb-51538a98ba80"
#vm5="692c4c12-0def-4aa8-87b4-732fd5ef43ea"
#vm6="bc4b8513-43f0-49d2-81b1-a4aa9fe35826"
#vm7="e46b8864-0271-41ce-86b4-d5df5579d332"
#vm8="6fb3f4a0-a17d-43e5-b4fd-1a52acc3e382"
## 定义N卡的PCI位置
NVPCI="0000:03:00.0"
## 定义vGPU的类型 玩游戏只用Q模式,其他都不考虑,更多信息可以在Nvidia Vgpu Driver插件中查询
## 8个1G显存写63,4个2G显存的写64,2个4G显存写65,1个8G显存写66,
MDEVLIST="nvidia-65"

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

### 段落2
### 上方定义几个vm,这就填几个
#### 例子arr=( "${vm1}" "${vm2}" "${vm3}" "${vm4}" )
arr=( "${vm1}" "${vm2}" )

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

然后把脚本设置为At First Array Start Only(第一次启动阵列时运行脚本)
然后运行此命令,告知由主机驱动程序管理设备

echo "options nvidia cudahost=1" > /boot/config/modprobe.d/nvidia.conf

最后点击运行脚本,现在已经可以在UNRAID中输入命令查看显卡信息了

验证是否正常加载驱动
lsmod |grep vfio 

查看机器上所有N卡信息
nvidia-smi

查看vGPU显卡信息
nvidia-smi vgpu

关闭ECC,释放所有显存
nvidia-smi -e 0

滚动显示设备状态
nvidia-smi dmon

实时显示显存 5秒刷新一次
nvidia-smi -l 5

更多信息可以直接在UNRAID的设置-Nvidia Vgpu Driver中查询

更新插件

通过plugin_update_helper脚本来更新
使用方法很简单:

  1. 在'user scripts'插件中,新建个脚本并粘贴plugin_update_helper中内容
  2. 点击此脚本右侧Run In Background,让其后台运行
  3. 工具-系统更新-检查更新,然后点击更新来安装新版本,等待安装完毕不要点重启
  4. 这时刚后台运行的脚本会自动判断changes.txt已更新,对比releases版本是否对应系统内核版本,如果对应会自动更新,更新结束会发送通知,然后再重启系统即可
  5. 如果出现不能使用,就恢复,并删除插件后重新安装插件即可

虚拟机上使用

验证vGPU驱动

  1. 先在UNRAID的设置-Nvidia Vgpu Driver中查看刚脚本定义的vGPU的UUID是否正常显示
## mdevctl list命令也可查询
root@Tower:~# mdevctl list
2b6976dd-8620-49de-8d8d-ae9ba47a50db 0000:03:00.0 nvidia-65 manual (defined)
5fd6286d-06ac-4406-8b06-f26511c260d3 0000:03:00.0 nvidia-65 manual (defined)

新建虚拟机

  1. 新建WIN10虚拟机,切记添加SPICE不要用VNC,因为安装vGPU驱动VNC有bug,完成安装后关机
  2. 编辑虚拟机xml文件,在video标签下方增加以下内容
#vGPU 更改为自己的uuid跟正确的PCI位置
    <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='off'>
      <source>
        <address uuid='2b6976dd-8620-49de-8d8d-ae9ba47a50db'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </hostdev>
#声卡 按需添加
    <sound model='ich9'>
    </sound>
#题外话 硬盘想显示为ssd,只需加在对应硬盘后面加 rotation_rate='1' 即可
#例子 只限IDE SATA 不支持virtio
      <target dev='hdc' bus='sata' rotation_rate='1'/>

修改保存后应该是这样的

安装驱动

  1. 开启虚拟机,通过浏览器直接访问 切记不要使用自动安装驱动或者驱动精灵之类来安装驱动
    先拜读justin-himself佬的项目这个仓库包含了 NVIDIA vGPU 驱动的历史版本
    win虚拟机无脑安装Releases页面中最新版本
    下载NVIDIA-GRID-Linux-KVM开头的几个分卷解压
    安装Guest_Drivers文件夹中exe结尾GRID驱动

    大佬已删库,请直接从Google Cloud下载所需要的版本安装即可

搭建民间vGPU激活方案

  • UNRAID直接下载容器模板后添加启动即可(自行修改模板中DLS_URL变量的 IP)
wget -O /boot/config/plugins/dockerMan/templates/FastAPI-DLS.xml https://raw.githubusercontent.com/s1oz/unraid/master/fastapi-dls.xml

项目源码为oscar.krause大佬的fastapi-dls,更多内容请自行拜读
使用的镜像为来自佛西博客中的makedie/fastapi-dls,感谢大佬自封证书挽救懒人

  • WIN10虚拟机激活授权
    虚拟机浏览器中打开https://容器IP:9443 切记是https 默认页面为配置说明
    Windows激活方式如下:
    浏览器访问 https://容器IP:9443/client-token 后会自动下载授权文件
    将文件导入到C:\Program Files\NVIDIA Corporation\vGPU Licensing\ClientConfigToken文件夹中后重启即可
    重启后右下角就弹出激活了
    判断是否激活
nvidia-smi -q |findstr Lincese

开启串流远程玩游戏

得益于vGPU加成,安装驱动后直接附带了一个虚拟显示器
可以直接通过浏览器使用SPICE访问虚拟机来进行操作
安装parsec然后开始畅玩(都是成年人了,这点你肯定会的)
唯一要注意的就是在桌面右击-显示设置-多显示器-仅在2上显示

说个题外话:

一般串流要么插HDMI欺诈器之类,要么额外安装一个虚拟显示器来让远程游戏正确工作
举例个虚拟显示器:
先下载虚拟显示驱动程序
解压后以管理员身份运行usbmmidd_v2文件夹中的usbmmidd.bat即可
运行后会自动添加一个虚拟显示器

如果要停用虚拟显示器
在文件夹路径以管理员身份运行的命令行中输入以下命令  停用多个虚拟显示器运行多次
deviceinstaller64 enableidd 0
如果重新运行就输入
deviceinstaller64 enableidd 1

想完全卸载虚拟显示器可以在设备管理器中删除USB Mobile Monitor Virtual Display

多样串流按需选择

串流玩游戏方案有很多,mstsc / anydesk / parsec / moonlight等
不过moonlight不支持远程剪贴板复制粘贴,
两种解决方案,

  1. 额外安装natclip,实现windows、macos或及其之间的剪切板文本共享, 可用于moonlight串流等远程控制剪切板不能用或失效的问题
  2. 换mstsc / anydesk / parsec 之类

虚拟机直接安装Sunshine来让P4支持moonlight
服务端安装使用自行拜读Sunshine Wiki
客户端安装使用自行拜读Moonlight Wiki

超频

先用nvidia-smi -q -d SUPPORTED_CLOCKS查询下显卡最高支持的频率

root@Tower:~# nvidia-smi -q -d SUPPORTED_CLOCKS

==============NVSMI LOG==============

Timestamp                                 : Sat May 27 12:46:25 2023
Driver Version                            : 525.105.17
CUDA Version                              : 12.0
vGPU Driver Capability
        Heterogenous Multi-vGPU           : Supported

Attached GPUs                             : 1
GPU 00000000:03:00.0
    Supported Clocks
        Memory                            : 3003 MHz
            Graphics                      : 1531 MHz
            Graphics                      : 1518 MHz
            Graphics                      : 1506 MHz
            Graphics                      : 1493 MHz

                        ~~~~~~~~~~

            Graphics                      : 455 MHz
        Memory                            : 405 MHz
            Graphics                      : 455 MHz

得知显存最高3003*,核心最高1531**
我就保守点来个3003,1531吧
输入nvidia-smi -ac 3003,1531

root@Tower:~# nvidia-smi -ac 3003,1531
Applications clocks set to "(MEM 3003, SM 1531)" for GPU 00000000:03:00.0
All done.


超频完成,恭喜性能增加了.功耗也增加了
不怕耗电的,就直接新建脚本,然后把脚本设置为At First Array Start Only(第一次启动阵列时运行脚本

给Emby添加炼丹卡解码转码

转码是会员功能,请先白嫖
调用N卡只要加以下参数
额外参数中添加 --runtime=nvidia
新建变量 键NVIDIA_VISIBLE_DEVICESall
然后转码中勾选即可

P4独有bug

  • 开机后需先开有vGPU的虚拟机后再开Emby
  • 不然就会造成显卡占用100%,Docker卡死
  • 正常开启后随意关闭.重启虚拟机.Emby无影响