Разблокировка FP/BF16 на Nvidia RTX 30xx под Linux: проверил, работает
Наткнулся на интересный проект: gpu-unlock. Это модуль ядра Linux, который снимает искусственное ограничение скорости выдачи FP/BF16 FMA-инструкций (с FP32-аккумуляцией) на потребительских картах 30-й серии. Nvidia сделала ограничение, чтобы отделить игровые карты от профессиональных и дата-центровых. Работает на GA102, GA103, GA104 и GA106.
Как это устроено
Модуль выполняет разблокировку и записывает нужные регистры до того, как к карте подключится штатный драйвер Nvidia. Драйвер при этом остаётся оригинальным, без патчей, так что после обновления драйвера ничего заново патчить не нужно. Это главное отличие от предыдущих подходов.
Результаты
Автор приводит такие цифры для 3090 Ti (GEMM 8192³, 450 Вт, FP32-аккумуляция):
Вход До После
FP16 87.46 TFLOPS 118.39 TFLOPS
BF16 87.50 TFLOPS 157.41 TFLOPS
TF32 42.58 TFLOPS 82.61 TFLOPS
Мои результаты
- Stable Diffusion: прирост заметный, +50-60%.
- Обучение LoRA: примерно +50% к скорости.
- llama.cpp: прирост небольшой, но на практике ощущается.
Это логично: тренировка и диффузия упираются в матричные операции (BF16/FP16), а инференс LLM в основном ограничен пропускной способностью памяти, поэтому там выигрыш скромнее.
Видеокарта потребляет 200 Вт, а не 120-150 Вт, как было раньше.
Установка
git clone https://github.com/Zagitta/gpu-unlock
cd gpu-unlock
make install
Затем нужно добавить gpu_unlock.targets=all в параметры ядра. В GRUB это GRUB_CMDLINE_LINUX_DEFAULT в /etc/default/grub, после чего выполнить update-grub:
GRUB_CMDLINE_LINUX_DEFAULT="gpu_unlock.targets=all"
Поддерживаются Arch, Debian/Ubuntu и Fedora, есть примеры для systemd-boot и UKI. Можно указать конкретные карты по PCI-адресу, например gpu_unlock.targets=0000:21:00.0.
Если nvidia.ko лежит в initramfs (Debian/Ubuntu)
В этом случае модуль нужно загрузить раньше, чем udev свяжет карту с драйвером. Для этого создаём скрипт /etc/initramfs-tools/scripts/init-top/gpu-unlock:
#!/bin/sh
PREREQ=""
prereqs() { echo "$PREREQ"; }
case "$1" in prereqs) prereqs; exit 0;; esac
# Must run ahead of init-top/udev: with nvidia.ko in the initramfs,
# coldplug binds the card before load_modules reaches /conf/modules.
modprobe gpu_unlock 2>/dev/null || true
exit 0
Делаем его исполняемым и пересобираем initramfs:
chmod +x /etc/initramfs-tools/scripts/init-top/gpu-unlock
update-initramfs -u
Проверка
journalctl -k -b | grep gpu_unlock
[ 4.332473] pci 0000:05:00.0: engine reset propagation: phase=post-FLR base=0x840000 first=0x1 tenth=0x1
[ 4.332476] pci 0000:05:00.0: engine reset asserted: phase=post-FLR base=0x840000 error=0 last=0x1
[ 4.332479] pci 0000:05:00.0: engine reset release: phase=post-FLR base=0x840000 before=0x1 write=0x0
[ 4.332605] pci 0000:05:00.0: engine reset released: phase=post-FLR base=0x840000 engine=0x0 hwcfg2=0x67f7
[ 4.332616] pci 0000:05:00.0: post-FLR SEC2 reset released, GSP halted, BME=0 pending=0 WPR2=1ffffe00:00000000 SS0=88888888 SS1=00000008
[ 4.339315] pci 0000:05:00.0: driver probe resources: phase=handoff empty=1
[ 4.339318] pci 0000:05:00.0: restore streaming mask: actual=0xffffffff expected=0xffffffff
[ 4.339320] pci 0000:05:00.0: restore coherent mask: actual=0xffffffff expected=0xffffffff
[ 4.339322] pci 0000:05:00.0: restore PCI command: actual=0x3 original=0x3 mask=0x6
[ 4.339324] pci 0000:05:00.0: gpu_unlock: unlocked
P.S. Для 40xx серии ждём, но вроде есть форки с поддержкой.






