LINUX.ORG.RU

Нвидиа душила RTX 30xx в матричных операциях: как снять ограничение на Linux

 , ,


4

1

Разблокировка 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 серии ждём, но вроде есть форки с поддержкой.

★★★★★

эти половые органы ещё блокируют задание кривой частоты-напряжения, причём только на линухе. вот бы кто ковырнул, а то либо сиди с конской заводской напругой либо лови глюки на рабочем столе

Laferadze
()
Ответ на: комментарий от anonymous

Речь про фактически потреблямую мощность, а не верхний лимит. Она по сути является произведением 4х факторов:

  1. от процента реально работающих разнотипных блоков внутри чипа (медленее чем линейно, так как блоки в простое тоже чуть-чуть потребляют)
  2. от частоты (по идее быстрее чем линейно)
  3. от напряжения на чипе, которое подбирается под частоту. (тут и от напряжения быстрее чем линейно и само напряжение быстрее чем линейно от частоты)
  4. от текущей температуроы чипа, там сложная зависимость, но с повышнеием температуры растут токи утечки, то есть если чип горячий - то паразитный нагрев становится ещё больше.

200W для 3060Ti это заданный верхний лимит в нагрузе, при достижении которого карта снижает частоту и напряжение на чипе (тротлится) чтоб вписаться в этот лимит. Лимит отслеживается мониторингом тока по токовым шунтам 0.002-0.005 Ом на линиях 12V. Технически, при максимальном значении всех множителей потребление 3060Ti на температуре порядка 85С составляет порядка 360W (это можно увидеть обойдя систему мониторинга, например уполовиниванием номиналов шунтов, но если это сделать на стандартной плате, она в очень скором времени просто сгорит).

При фактической работе не все сценарии «полной» нагруpки забирают все допустимые 200W. Некоторые вычисления «неэффективно (тем что используют мало типов блоков или зависят от инструкций в которых бОльшая часть блоков простаивает) используют GPU». Когда они выполняются - 100% GPU-времени занято, но фактически потребляемая мощность заметно ниже лимита, так как задействованы не все блоки и даже на максимальной boost-частоте потребление меньше лимита (за счёт малого первого множителя). При искуственном ограничении используемых блоков повторялся такой же эффект.

GPFault ★★★★
()
Ответ на: комментарий от cobold

Ну смотри, у меня большой охлад с тремя винтами. Когда гпу не работает, винты вообще не крутятся. В нагрузке выше 60-65 никогда не поднимается. При этом винты работают только на 40%.

Если так боишься, выстави максимальную мощность на 150W. Но честно говоря что так, что так - температура одинаковая.

Skullnet ★★★★★
() автор топика
Последнее исправление: Skullnet (всего исправлений: 1)
Ответ на: комментарий от anonymous

Понятно, но по моему важнее кол-во vram чем gpu частота.

Смотря в контексте чего, для генераторов картинок много RAM не нужно. Хотя желательно чтобы было 16Gb VRAM. Для LLM-ок памяти надо много да, и скорость пока что упирается в пропускную способность памяти, но если взлетят диффузионные LLM, то будет наоборот.

Skullnet ★★★★★
() автор топика
Последнее исправление: Skullnet (всего исправлений: 1)
Ответ на: комментарий от Skullnet

для генераторов картинок много RAM не нужно. Хотя желательно чтобы было 16Gb VRAM.

Как бы да, но вот тестировал я генератор с моделью на основе Krea2, три разных варианта одной и той же модели с разным квантованием. С весами 6Гб, 11 Гб и 18 Гб, соответственно, влазит в 8Гб VRAM, 16 Gb VRAM и 24 Gb VRAM. Был еще вариант на 24 Гб, но его потестить не смог из-за отсутствия карты с более 24 Гб VRAM. И вот вижу, что на один и тот же промпт они выдают очень похожий рисунок, хотя слегка все же меняются сюжетно, но слабо. Но количество и точность прорисованных мелких деталей разное. На это количество еще влияют такие параметры как число итераций и shift и все же, чем больше весов, тем более как бы живой и реалистичный в целом рисунок.

anonymous
()
Ответ на: комментарий от anonymous

чем больше весов

То есть, хотел сказать, что чем точнее веса. Количество весов было вроде одинаковым как раз. Но и количество весов наверняка влияет.

anonymous
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария