Fine-tuning и веса · Fine-tuning and weights · урок 2 · 13 мин

LoRA и QLoRA изнутри

LoRA and QLoRA under the hood

ТемыFine-tuningLoRAЖелезо

Зачем

После урока ты посчитаешь на салфетке, сколько параметров обучает LoRA и сколько памяти стоит обучение в трёх режимах, и объяснишь, что QLoRA делает с базовой моделью. На собеседовании это стандартная задача «compute the trainable parameters», а на работе — решение, поместится ли обучение на твою GPU.

Проблема: полное обучение не помещается

Full fine-tuning (полное дообучение) обновляет все веса модели. Документация Hugging Face Transformers раскладывает память при обучении в смешанной точности с оптимизатором Adam так: веса — 6 байт на параметр (16-битная копия fp16 для прохода и 32-битная копия fp32 для точного обновления), состояния Adam — 8 байт (momentum и variance в fp32), gradients (градиенты, направление изменения каждого веса) — 4 байта. Итого около 18 байт на параметр, плюс activations (промежуточные значения прямого прохода, которые хранятся для обратного; растут с длиной последовательности и размером batch).

Для модели на 8B параметров это 8 × 18 = 144 ГБ ещё до activations. На одну GPU на 80 ГБ такое не помещается, а на выходе получается новая полная копия модели на 16 ГБ (8B × 2 байта в bf16, 16-битном формате чисел, стандартном для обучения). Если нужно десять вариантов поведения, это десять копий.

Идея LoRA: низкоранговая добавка

Линейный слой считает h = W·x, где W — матрица размером d × k. LoRA (low-rank adaptation) замораживает W и добавляет рядом поправку ΔW = B·A, где A имеет размер r × k, B — d × r, а rank r (ранг, ширина добавки) намного меньше d и k. Слой теперь считает:

h = W·x + (α / r) · B·A·x

Обучаются только A и B. Библиотека PEFT по умолчанию заполняет A случайными числами, а B — нулями, поэтому в начале обучения B·A = 0 и модель в точности равна базе. Почему это работает: авторы LoRA исходят из гипотезы, что изменение весов при адаптации имеет низкий «intrinsic rank» (внутренний ранг): чтобы научить модель новому тону, не нужно двигать матрицу во всех 4 096 направлениях. Для GPT-3 175B они сообщают сокращение обучаемых параметров в 10 000 раз, памяти GPU в 3 раза и «no additional inference latency» — добавку можно влить в W после обучения.

Посчитаем: матрица 4096 × 4096, rank 16

Теперь вся модель. Допустим, 32 слоя, и в каждом LoRA цепляется к четырём матрицам attention (механизм внимания) размером 4096 × 4096 (q_proj, k_proj, v_proj, o_proj). Это 32 × 4 × 131 072 = 16 777 216 параметров, около 16,8 млн. В bf16 (2 байта на параметр) adapter (файл обученной добавки) весит около 34 МБ против 16 ГБ полной копии. Оговорка: в моделях с grouped-query attention (одна пара матриц ключей и значений на группу голов внимания) матрицы k_proj и v_proj меньше, поэтому реальное число ниже.

Память на обучение: база в bf16 — около 2 байт на параметр, то есть 16 ГБ для 8B. Gradients и состояния Adam нужны только для 16,8 млн параметров adapter: даже по 18 байт на параметр это около 0,3 ГБ. Остаётся запас на activations. Ориентир из гайда Unsloth (открыт 10.10.2026): bf16 LoRA для Qwen3.5-9B требует 22 ГБ.

Ручки LoRA и их цена

Цена подхода измерена. Статья «LoRA Learns Less and Forgets Less» сравнила LoRA и полное дообучение на коде и математике: LoRA в стандартных настройках «substantially underperforms full finetuning» в целевом домене, зато лучше сохраняет умения базы вне его. Полное дообучение выучивает поправки с рангом в 10–100 раз выше типичной LoRA. Вывод инженера: LoRA — для стиля, формата и узкой задачи; полное обучение — для больших сдвигов вроде нового языка, когда есть кластер.

QLoRA: база в 4 битах

QLoRA — та же LoRA, но замороженная база хранится в 4 битах. В статье три приёма: 1. NF4 (4-bit NormalFloat) — 4-битный тип данных, по словам авторов «information theoretically optimal for normally distributed weights»: уровни квантования расставлены по форме нормального распределения, в котором лежат веса. Веса режутся на блоки по 64, у каждого блока своя константа масштаба. 2. Double quantization — квантуются и сами константы масштаба. Накладные расходы падают примерно с 0,5 до 0,127 бита на параметр, для модели на 65B это экономия около 3 ГБ. 3. Paged optimizers — состояния оптимизатора через unified memory NVIDIA выгружаются в оперативную память CPU при пике и возвращаются, когда нужны. Это сглаживает пики, из-за которых обучение падает с нехваткой памяти.

При каждом умножении 4-битные веса распаковываются в bf16, а gradients получают только параметры LoRA, которые хранятся в bf16. Итог статьи: модель на 65B дообучена на одной GPU на 48 ГБ вместо более чем 780 ГБ, с качеством полного 16-битного дообучения.

Режим Байт на параметр (без activations) Модель 8B
Full fine-tuning, Adam около 18 около 144 ГБ
LoRA, база в bf16 около 2 около 16 ГБ
QLoRA, база в NF4 около 0,5–0,6 около 4–5 ГБ

Чем платишь за QLoRA: шаг медленнее из-за распаковки, возможна небольшая потеря качества, нужна поддержка в библиотеке bitsandbytes. Adapter, обученный поверх 4-битной базы, обычно вливают в 16-битную копию базы, поэтому после слияния модель снова оценивают. И главное: поддержку проверяют для каждой модели. Гайд Unsloth для Qwen3.5 (открыт 10.10.2026) прямо пишет: «It is not recommended to do QLoRA (4-bit) training on the Qwen3.5 models» — ни для MoE (mixture of experts, модели из многих «экспертов»), ни для плотных, и советует bf16 LoRA.

Схема

Термины · Key terms

full fine-tuning
полное дообучение, обновление всех весов
LoRA (low-rank adaptation)
низкоранговая добавка B·A рядом с замороженной матрицей
rank (r)
ширина добавки LoRA, её ёмкость
lora_alpha
масштаб добавки; множитель alpha / r
target modules
матрицы, к которым цепляется LoRA
adapter
файл обученной добавки, который подключают к базе
activations
промежуточные значения прохода, хранимые для расчёта градиентов
QLoRA
LoRA поверх базы, хранящейся в 4 битах
NF4 (4-bit NormalFloat)
4-битный тип для нормально распределённых весов
double quantization
квантование самих констант квантования
paged optimizers
выгрузка состояний оптимизатора в память CPU при пиках

Сделай сам

Напиши 10 строк на Python без библиотек: функция lora_params(d, k, r) возвращает число обучаемых параметров и долю от d × k в процентах. Выведи результат для матрицы 4096 × 4096 при r = 8, 16 и 64 и для матрицы 4096 × 14336 (такие бывают в MLP, полносвязном блоке слоя) при r = 16. Затем посчитай размер adapter в МБ для модели из 32 слоёв, если цеплять LoRA r = 16 к четырём матрицам 4096 × 4096 на слой.

Обсуди с тьютором: покажи свои числа и спроси, почему доля обучаемых параметров растёт линейно с r, а качество — нет; попроси пример, когда r = 64 хуже, чем r = 16.

Проверь себя · ответ под вопросом

1Сколько обучаемых параметров у LoRA с rank 16 на матрице 4096 × 4096 и какая это доля?
A — 16 × 4096 = 65 536, B — 4096 × 16 = 65 536, вместе 131 072. Матрица содержит 16 777 216 параметров, доля 0,78 %. Частая ошибка — забыть вторую матрицу и получить половину.
2Почему в начале обучения модель с LoRA совпадает с базой?
PEFT инициализирует B нулями, поэтому произведение B·A равно нулю и добавка ничего не меняет. Обучение начинается ровно из точки базовой модели. Так adapter не портит модель в первые шаги.
3Какие три приёма добавляет QLoRA и что каждый экономит?
NF4 хранит замороженную базу в 4 битах вместо 16. Double quantization сжимает константы масштаба, примерно с 0,5 до 0,127 бита на параметр. Paged optimizers выгружают состояния оптимизатора в память CPU при пиках, чтобы обучение не падало.

Interview questions · US / UK

1Explain LoRA and compute the trainable parameters for rank 16 on a 4096 × 4096 matrix.
Strong answer: Freeze W, train B·A next to it with rank r; output is Wx + (alpha/r)·BAx; 16 × 4096 + 4096 × 16 = 131,072 vs 16.8M, about 0.78%; B starts at zero so training starts from the base; name target_modules and alpha.
2What does QLoRA change, and what does it cost you?
Strong answer: Frozen base stored in 4-bit NF4 with double quantization, paged optimizers for memory spikes, LoRA weights stay in bf16; base drops from about 2 to about 0.5 bytes per parameter; costs: slower steps, possible small quality loss, library support; check model-specific guidance (Unsloth advises against QLoRA for Qwen3.5) and re-evaluate after merging.
3When would you pay for full fine-tuning instead of LoRA?
Strong answer: Large distribution shifts such as continued pretraining on a new language; LoRA learns less in the target domain but forgets less outside it; full fine-tuning costs about 18 bytes per parameter plus activations and produces a full model copy; use LoRA for style, format and narrow tasks on one GPU.

Ключевые фразы · Say it aloud

Материалы