对于 Proxmox VE 8,需要使用16.0+版本的 vGPU 驱动程序,低版本的驱动程序不支持 Linux 6.x 内核

最近我刚升级了我的 NAS 主机,并且购买了一块 Tesla P4 显卡。我想把 vGPU 分配给虚拟机上的 Jellyfin 容器硬解使用,经过几天的研究,我简单总结了使用方法。关于如何使用硬解,我会在下一篇文章中进行说明。

术语说明

简单介绍后面内容中的几个术语:

  • vGPU

    vGPU 技术通过将硬件 GPU 分割成多个虚拟 GPU 以支持多个虚拟机。每个虚拟 GPU 可以被分配给不同的虚拟机,从而使多个虚拟机拥有“独显”。

  • vGPU-unlock

    从硬件上来看,同代的数据中心显卡和消费者显卡 GPU 架构是一样的,只是驱动层限制了支持的特性。通过修改型号与宿主驱动等方式,将消费级显卡伪装成具有相同核心型号的专业卡,使得普通消费者显卡也可以支持虚拟化;对于虚拟机,同时在 vGPU 启动前后进行 hook,绕过特定检查、汇报虚假结果等,使得虚拟机的 vGPU 能正常启动。目前支持的消费卡型号可以参考此文章

  • vGPU 授权机制

    在宿主机上,驱动无需授权。不过,只有企业级 GPU 能够被 vGPU 宿主机驱动所识别,消费级显卡无法合法地用于 vGPU 硬件。

    在虚拟机上,使用 vGPU 客户端驱动需要获得 NVIDIA 授权。不同能力的 vGPU 子设备被分为 A、B、C、Q 四类,并对应不同的授权费用。未获得授权的驱动会逐渐降低 vGPU 子设备的性能,最终导致无法使用。

    在几种 vGPU 类型中,覆盖应用场景最广的是 Q 型 vGPU,授权为 vWS。

安装流程

关于 PVE 使用 GPU 有三种方法:

  • 显卡直通
  • 普通显卡 + vGPU-unlock
  • 数据中心显卡 vGPU

Tesla P4 是数据中心卡,原生支持 vGPU 功能,所以本文不涉及 vGPU-unlock,如需了解可以参考 PolloLoco 的 NVIDIA vGPU Guide

宿主机

  1. 主板 BIOS 配置

    需要开启 IOMMU / VT-d、Above 4G Decoding、SR-IOV,不同的主板选项所在位置可能不同,需要自行查找。

    IOMMU 是一种地址映射技术,而 VT-d 是 Intel 对该技术的别称;Above 4G Decoding 关系到 PCI-E 设备 RAM 的 64 位寻址能力,通常用于需要让 CPU 访问全部显存的场景,使用 vGPU 时推荐开启;SR-IOV 允许一个 PCI-E 设备被多个虚拟机使用,常用于网卡等设备共享。

  2. PVE 宿主机配置

    # 把下面几行追加到 /etc/modules 里,用于加载所需的内核模块
    vfio
    vfio_iommu_type1
    vfio_pci
    vfio_virqfd
    
    # 屏蔽开源驱动
    echo "blacklist nouveau" >> /etc/modprobe.d/pve-blacklist.conf
    
    # 开启IOMMU,参考:https://foxi.buduanwang.vip/yj/561.html
    ## AMD主板可能需要修改为:quiet amd_iommu=on iommu=pt pcie_acs_override=downstream,否则部分PCI设备可能会在同一个分组内,直通时会直通整个设备
    
    # 安装依赖包
    apt install build-essential dkms mdevctl pve-headers-$(uname -r)
    
    # 重启机器
    reboot
    
  3. 安装 NVIDIA Host 驱动

    NVIDIA 官网的驱动是非公开的,你需要注册 NVIDIA 商业账户才可访问;当然你也可以去网上寻找驱动包,比如:APQA 网盘GitHub

    # 本次安装环境:PVE版本7.4-3,Linux内核版本5.15.107-2,驱动版本15.1
    chmod +x NVIDIA-Linux-x86_64-430.67-vgpu-kvm.run
    ./NVIDIA-Linux-x86_64-430.67-vgpu-kvm.run
    
    # 安装过程完成后可以使用以下命令验证
    $ dkms status
    nvidia, 525.85.07, 5.15.107-2-pve, x86_64: installed
    $ nvidia-smi
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 525.85.07    Driver Version: 525.85.07    CUDA Version: N/A      |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |                               |                      |               MIG M. |
    |===============================+======================+======================|
    |   0  Tesla P4            On   | 00000000:81:00.0 Off |                    0 |
    | N/A   53C    P8    12W /  75W |   1899MiB /  7680MiB |      0%      Default |
    |                               |                      |                  N/A |
    +-------------------------------+----------------------+----------------------+
    
    
  4. 划分 PCI-E 设备给虚拟机

    通过 mdevctl types | grep '^[^ ]*$' 查看所有生成了 mdev 的 PCI 设备 ID,然后通过 PVE 网页控制台给虚拟机分配 PCI 设备,设备选择刚才查到的设备 ID。该处的 MDev 字段,后面半段的数字为显存容量,字母为 vGPU 类型,这里选 Q 全能型即可,显存按需分配。

虚拟机

下面来到虚拟机的部分,从下载的驱动包内,找到文件名包含 grid 的对应系统驱动包,上传至虚拟机。

  1. Windows

    双击运行直接根据引导安装即可,安装完成后打开 PowerShell,输入命令:

    nvidia-smi.exe # 验证是否安装成功
    nvidia-smi.exe -q | Select-String License # 查看授权,Unlicensed (Unrestricted) 表示未授权
    

    至此驱动安装已经完成,下一节再来解决授权的问题。

  2. Linux

    此处以 Debian 系统演示,理论兼容 Ubuntu。其他发行版的用户请酌情微调命令。

    # 和宿主安装驱动相似,禁用 nouveau 并安装必须软件包
    echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
    apt install build-essential gcc-multilib dkms mdevctl
    update-initramfs -k all -u
    reboot
    
    # 重启完成后安装 Guest 驱动
    chmod +x NVIDIA-Linux-x86_64-430.63-grid.run
    ./NVIDIA-Linux-x86_64-430.63-grid.run
    
    # 验证安装是否成功
    dkms status
    nvidia-smi
    nvidia-smi -q | grep License # 查看授权,Unlicensed (Unrestricted) 表示未授权
    

至此驱动方面的安装已经完成,下面来获取授权。

授权流程

授权方法分为如下几种方式:

  1. 向 NVIDIA 申请 90 天 free license(NVIDIA 中国只面向企业用户发放免费授权,个人可以尝试去海外官网申请),到期后购买 license
  2. Rust-based vgpu_unlock,通过 vGPU 伪装,从而可以在虚拟机使用不需要授权的消费级显卡驱动,此方式是唯一支持消费级显卡的方式
  3. vGPU_LicenseBypass,此方式将不限制性能的时间从 20 分钟延长为一天,并且每天定时重启驱动,以达成一直不受限的目地,但不适合需要长时间运行 GPU 的场景
  4. FastAPI-DLS,此方式通过模拟正规流程的激活服务器,对虚拟机进行许可证授权,支持容器部署

对于原生支持 vGPU 的显卡而言,使用 FastAPI-DLS 为最优解,整套方案除授权服务器虚假外与正规流程无异。而且只要不更新虚拟机驱动,证书验证算法不变,理论具有等同于正规授权的稳定性。

搭建授权服务器

  1. 首先安装容器环境,此步略过。

  2. 启动容器,原项目需要自行创建证书,这里使用一个二次封装的免证书容器镜像。

    # 此处的DLS_URL与DLS_PORT是后续生成授权文件,告知Guest如何访问授权容器IP地址和端口
    docker run -d -e DLS_URL=10.0.0.6 -e DLS_PORT=443 -p 443:443  makedie/fastapi-dls
    

获取授权

  1. Windows

    使用管理员身份启动 PowerShell 执行如下命令

    # <ls-hostname-or-ip>为你的授权服务IP端口
    curl.exe --insecure -L -X GET https://<dls-hostname-or-ip>/-/client-token -o "C:\Program Files\NVIDIA Corporation\vGPU Licensing\ClientConfigToken\client_configuration_token_$($(Get-Date).tostring('dd-MM-yy-hh-mm-ss')).tok"
    
    Restart-Service NVDisplay.ContainerLocalSystem
    nvidia-smi.exe -q | Select-String License # 查看授权状态
    
  2. Linux

    root 执行如下命令

    # <ls-hostname-or-ip>为你的授权服务IP端口
    curl --insecure -L -X GET https://<dls-hostname-or-ip>/-/client-token -o /etc/nvidia/ClientConfigToken/client_configuration_token_$(date '+%d-%m-%Y-%H-%M-%S').tok
    
    service nvidia-gridd restart
    nvidia-smi -q | grep License # 查看授权状态
    

现在 vGPU 已经可以正常使用了,只要确保授权服务容器正常运行,grid 驱动就会自动续期。

参考文章


Never give up your dreams.