返回 文章 apply CMS 文章

GPU-unlock:在 Nvidia 30 系显卡上解锁 FP/BF16 指令发射速率

用内核模块在 Nvidia 驱动加载前解锁 30 系显卡的 FP/BF16 指令发射速率,让消费卡接近专业卡算力。

NvidiaGPU解锁Linux内核模块FP16/BF16
成长分 / 100 71 综合收获、行动、留存与影响

GPU-unlock:在 Nvidia 30 系显卡上解锁 FP/BF16 指令发射速率
为什么值得读展示了绕过厂商限制、在驱动绑定前修改硬件速度选择器的完整工程路径,对理解 GPU 固件与驱动加载时序很有价值。

提供了多款 RTX 30 系显卡的实测 GEMM 性能提升数据,可直观评估解锁收益与功耗限制的影响。

关键洞察
  1. 该模块结合 CMP 解锁器的 V67/PLM 技术与 UEFI 方法的预驱动时序,写入速度选择器 SS0=0x88888888 和 SS1=0x8 并执行 FLR,在未修改的 NVIDIA 驱动绑定前完成解锁。
  2. 解锁使 GA102/GA103/GA104/GA106 上 FP/BF16 FMA 到 FP32 操作的指令发射速度翻倍;3090 Ti 实测 BF16 从 87.50 提升到 157.41 TFLOPS。
  3. 收益集中在矩阵密集型负载(LLM prefill、扩散模型、FlashAttention),而受显存带宽限制的 LLM decode 和 INT8 工作基本不变,且输出逐位一致。
转成行动

深入阅读

正文与原文对照

原文保真覆盖:全文原文字符:10478

GPU unlock 1.0.0

解锁 Nvidia 3000 系列显卡的 FP/BF16 指令发射速率,使其达到专业显卡的等效水平

这个 Linux 内核模块结合了 CMP 解锁器的 V67/PLM 技术和 UEFI 方法的预驱动时序。它在未修改的 NVIDIA 驱动绑定显卡之前运行解锁,写入速度选择器(SS0 0x88888888,选择完整的 BF16 速率,以及 4 位 SS1 0x8 IMLA4)并执行 FLR。它既不是 UEFI 应用程序,也不是修补过的 NVIDIA 驱动。

这种早期 kmod 驱动的优点是,每次 NVIDIA 发布新驱动版本时,它不需要手动打补丁。

此解锁的效果是,在 GA102、GA103、GA104 和 GA106 显卡上,将 FP/BF16 FMA 到 FP32 操作的指令发射速度提高一倍。

3090 Ti 在 450 W 下密集 8192³ GEMM,五次采样中位数,使用 FP32 累加:

输入 之前 之后
FP16 87.46 TFLOPS 118.39 TFLOPS
BF16 87.50 TFLOPS 157.41 TFLOPS
TF32 42.58 TFLOPS 82.61 TFLOPS

测试过的显卡

用户报告的结果。该模块接受 kernel/gpu_unlock/main.c 中列出的所有 GeForce ID,但以下显卡是有人报告过的。请通过兼容性报告添加您的显卡,无论是否成功。

芯片 显卡 PCI ID 结果 BF16 GEMM 增益 报告
GA102 RTX 3090 Ti 10de:2203 已解锁 +68–80% #1
GA102 RTX 3090 10de:2204 已解锁 +25–67% #5, #9, #10, #17, #25, #27, #33
GA102 RTX 3080 Ti 20 GB (OEM, GA102-250) 10de:2205 解锁完成,BF16 保持半速 — #28
GA102 RTX 3080 10 GB 10de:2206 已解锁 +70–73% #14
GA102 RTX 3080 20 GB (显存升级) 10de:2206 已解锁 +56–59% #10, #15
GA104 RTX 3070 10de:2484 已解锁 +73–81% #10, #12
GA104 RTX 3070 Ti 10de:2482 未使用此模块测试(相同的解锁在 Windows 上通过 UEFI 移植成功) — #32
GA106 RTX 3060 12 GB 10de:2504 已解锁 约 +80% #13, #31
GA103 任何 10de:2414 暂无报告 — —

增益是来自每个报告自己的基准测试的密集 GEMM 吞吐量,因此它们不能直接比较。功耗限制影响很大:最低的数字(+25%)来自限制在 225 W 的显卡。

矩阵密集型工作加速:LLM 预填充(在 #9、#15、#25 和 #33 中提升 14–36%)、扩散和 FlashAttention。受内存带宽限制的 LLM 解码和 INT8 工作大致保持不变。比较输出的报告发现,前后输出位完全相同。

报告还涵盖了一台机器中最多四张显卡、驱动显示的显卡,以及通过 vfio-pci 直通到虚拟机的显卡(#17)。

如何安装

首次运行:

git clone https://github.com/Zagitta/gpu-unlock
cd gpu-unlock
make install

然后将 gpu_unlock.targets=all 追加到内核命令行,保留现有选项:

  • GRUB(Debian/Ubuntu/Mint):将其添加到 /etc/default/grub 中的 GRUB_CMDLINE_LINUX_DEFAULT 内,然后运行 sudo update-grub。
  • GRUB(Arch/CachyOS):同样编辑,然后运行 sudo grub-mkconfig -o /boot/grub/grub.cfg。
  • Fedora/RHEL:运行 sudo grubby --update-kernel=ALL --args="gpu_unlock.targets=all"。
  • systemd-boot:将其追加到启动项中的 options 行(bootctl status 显示其位置)。
  • UKI / 生成的启动项:将其添加到 /etc/kernel/cmdline,并重新生成启动镜像/启动项(例如针对 mkinitcpio UKI 使用 sudo mkinitcpio -P)。

本地构建

每次构建都会通过 HTTPS 下载固定版本的 NVIDIA/CachyOS 输入,校验其 SHA-256,并且只在构建目录和二进制包中生成固件。三种格式都通过相同的 make install-* 目标安装。软件包由已提交的 HEAD 构建。

一步完成构建、安装构建依赖并安装软件包(会要求输入 sudo 密码):

make install        # detect the distribution and select an installer
make install-arch   # makepkg -sif
make install-deb    # apt-get build-dep, dpkg-buildpackage, apt-get install
make install-rpm    # dnf builddep, rpmbuild, dnf install

make install 使用 /etc/os-release(先 ID,再 ID_LIKE)来检测 Arch、Debian/Ubuntu 或 Fedora/RHEL/CentOS 系列。RPM 安装器需要 DNF。对于其他发行版,请在上方选择兼容的显式目标。

make arch、make deb 和 make rpm 仅执行构建。Debian 和 RPM 包会生成到 build/deb 和 build/rpm。NVIDIA 输入缓存在 ~/.cache/gpu-unlock/inputs(make inputs;可用 INPUTS= 覆盖)。dpkg-buildpackage 本身从不使用网络,因此干净 chroot 构建(sbuild 或 pbuilder)需要将 GPU_UNLOCK_INPUTS 指向该缓存。make dist 归档、Debian 源码包和 .nosrc.rpm 不包含任何 NVIDIA 归档或生成的固件。

启动流程与启用方式

这些软件包会将 gpu_unlock 及其固件放入 initramfs 并在其中加载,早于 nvidia 绑定显卡:

  • mkinitcpio:/etc/mkinitcpio.conf.d/zz-gpu-unlock.conf 会将 gpu_unlock 插入到 MODULES 中 nvidia 的正前方,从而让显示卡黑屏的时间尽可能短。如果镜像中没有 nvidia,它会排在最后,并且仍会在从根文件系统加载的 nvidia 之前运行。安装时会重新构建镜像。对于使用 -c <config> 或预设 _config 构建的镜像,mkinitcpio 会忽略 drop-in;请自行将 gpu_unlock 放到该配置 MODULES 中 nvidia 的正前方。
  • initramfs-tools:/usr/share/initramfs-tools/modules.d/gpu-unlock.conf。
  • dracut:/usr/lib/dracut/dracut.conf.d/gpu-unlock.conf。

使用 initramfs-tools 和 dracut 时,会为每个已安装且带有头文件的内核构建该模块,并在安装时以及卸载时再次重新构建这些内核的镜像。之后安装的内核会通过其自身的安装钩子获得该模块和新镜像。

没有 softdep nvidia pre: 规则:kmod 只遵循它读到的第一条 softdep nvidia 行,因此其他软件包的规则(nvidia-utils、gddr6_hwmon)会静默覆盖它,或者它会覆盖它们的规则。

除非内核命令行启用,否则该模块不会执行任何操作:

gpu_unlock.targets=all                          # every unbound GA102/GA103/GA104/GA106 card
gpu_unlock.targets=0000:21:00.0                 # only these cards
gpu_unlock.targets=0000:21:00.0,0000:22:00.0    # comma-separated

地址是 lspci -D 打印出的完整 PCI 名称(十六进制数字大小写均可),与 GPU 编号和显示角色无关。不是 GA102/GA103/GA104/GA106 显卡的条目(包括与地址混在一起的 all)会被记录并忽略。这些显卡会并发解锁,无论数量多少总共约一秒,且各自独立:已绑定或已断电的显卡会被跳过。主板固件遗留的 bus mastering(Supermicro X11 无论其 option ROM 和 bus master 设置如何都会如此)会先被清除;已被某个驱动初始化的显卡仍会被拒绝。随后 nvidia 会照常加载并绑定每张显卡。

显示卡也可正常工作。其固件帧缓冲(启动控制台和 Plymouth)会在解锁的固件步骤运行期间继续运行,并在显卡复位前被移除,正如 nvidia-drm 稍后本来也会做的那样。从该复位到 nvidia-drm 接管之前,其屏幕为黑屏。

启动后手动加载该模块对 nvidia 已绑定的显卡没有任何作用。

挂起到 RAM 会关闭显卡电源,从而复位速度选择器。恢复后,该模块会在 nvidia 恢复它之前,再次解锁它在启动时解锁过的每张显卡:其挂起通知器会先于 nvidia 用来恢复其显卡的通知器运行(NVreg_UseKernelSuspendNotifiers=1,当前驱动中的默认值;nvidia-resume.service 运行得更晚)。这会使恢复时间增加约一秒。保持供电的显卡(如挂起到空闲)仍处于解锁状态,只会被读取。已被 nvidia 恢复或已绑定到其他驱动的显卡会保持原样,日志会说明原因。将 gpu_unlock.resume=0 添加到内核命令行,或将 0 写入 /sys/module/gpu_unlock/parameters/resume,可关闭此功能。休眠不在覆盖范围内。

使用以下命令检查结果:

journalctl -k -b | grep gpu_unlock
lspci -nnk -s 0000:21:00.0

要停止解锁,请从内核命令行中移除 gpu_unlock.targets=;对于一次性启动,可在引导程序的编辑界面中删除它。移除软件包也会移除该模块和 initramfs drop-in。

如果某张显卡上的固件始终无法停止,该模块会记录此情况,并保留该固件可能仍会使用的 DMA 缓冲区,直到下次断电。再次尝试前请先断电。

内核模块和本地打包采用 GPL-2.0-only 许可。生成的载荷源自固定版本的 CMP 参考;NVIDIA 固件仍受其自身条款约束。署名和声明见 firmware/NOTICE.md 和 licenses/。

支持我

帮我买更多 GPU <3

https://buymeacoffee.com/zagitta

ETH: 0xf4eee937937f92038D70B16AbD7736D8a53a1c5c

BTC: bc1qwpkwp70fn76z3s4kg2l9y3j4kst95twcznuugf

SOL: 8Rih6HY7V4LcdjYHz4iSffT4fTniqw5CACaBigSVxNYu