нейропоток
ГайдыПрактик

LoRA: почему дообучение нейросети теперь занимает 1% памяти

LoRA — дообучение нейросети на 1% памяти. Объясняю как работают адаптеры, параметры rank и alpha, чем отличается QLoRA и как запустить через Unsloth.

Павел·9 мин чтения
LoRA: почему дообучение нейросети теперь занимает 1% памяти
Поделиться:TelegramVK

Когда я впервые попробовал дообучить нейросеть «по-взрослому», первым делом полез смотреть, сколько памяти нужно. Посмотрел на требования к full fine-tuning GPT-2 — и закрыл вкладку. 12 гигабайт GPU-памяти. На «маленькой» модели 1.5B параметров.

У меня был MacBook. Игра закончилась, не начавшись.

Потом узнал про LoRA. Попробовал. Та же модель, та же задача — 1.2 гигабайта. В 10 раз меньше. Работает.

Вот с этого стоит начать разговор про LoRA: это не абстрактная техника из академической статьи, это способ запустить то, что иначе не запустить.

Для кого: для тех, кто уже понимает что такое fine-tuning (если нет — сначала fine-tuning нейросети: полный гид) и хочет разобраться, как LoRA работает изнутри и как его настроить.


Проблема: full fine-tuning требует памяти на порядок больше самой модели

Начнём с того, почему вообще нужны какие-то альтернативы.

При полном дообучении (full fine-tuning) вы обновляете каждый параметр модели. Например, у Llama 3.1 8B — восемь миллиардов параметров. Каждый параметр хранится как 32-битное число (float32) — это 4 байта. Итого только на хранение весов нужно 32 ГБ.

Но это ещё не всё. Во время обучения нужно хранить градиенты (ещё столько же), оптимайзер-стейт (Adam хранит ещё 2× веса) — и в итоге вам нужно 80-100 ГБ GPU-памяти. Это одна A100 на пределе или несколько H100.

Стоимость аренды такой инфраструктуры — сотни долларов за обучение. Для большинства задач это просто нерелевантный вариант.

Конкретные числа для GPT-2 (1.5B параметров):

  • Full fine-tuning: ~12 ГБ GPU
  • LoRA (rank=16): ~1.2 ГБ GPU
  • QLoRA (rank=16, 4-бит): ~0.5 ГБ GPU

GPT-2 сегодня — это маленькая модель. Но разница в 10× применима к любому размеру.


Что такое LoRA: матрицы малого ранга за 2 минуты

LoRA расшифровывается как Low-Rank Adaptation — адаптация с матрицами малого ранга.

Аналогия, которая мне помогла понять: представьте коллегу, который знает всё. Огромный объём знаний, энциклопедическая память. Но вам нужно, чтобы он работал именно в вашей области — медицине, или юриспруденции, или вашем конкретном продукте.

Вы не переписываете его мозг целиком. Вы даёте ему «накладки» — специализированные шпаргалки, паттерны, примеры — поверх того, что он уже знает.

LoRA работает ровно так: не меняет исходные веса модели, а добавляет рядом маленькие «адаптерные» матрицы. При инференсе веса модели + адаптер = итоговое поведение.

Математика простыми словами:

Исходный слой модели — это матрица W с миллионами параметров. При full fine-tuning вы обновляете W напрямую. LoRA вместо этого добавляет изменение ΔW = A × B, где A и B — гораздо меньшие матрицы (их размер определяется параметром rank).

Если W = 4096 × 4096 = 16 миллионов параметров, а rank = 16, то:

  • A = 4096 × 16 = 65 тысяч параметров
  • B = 16 × 4096 = 65 тысяч параметров
  • Итого в 122 раза меньше на один слой.

Вот откуда такая экономия памяти. Обучаете только A и B. Исходная W остаётся замороженной.

После обучения LoRA-адаптер можно опубликовать на HuggingFace отдельно от базовой модели. Это удобно: весит несколько мегабайт, а не гигабайты. Можно делиться с командой, публиковать, версионировать — и у каждого будут одинаковые результаты поверх одной и той же базовой модели.


Параметры LoRA: rank, alpha и target_modules

Три параметра, которые определяют поведение LoRA. Разберём каждый.

Rank (r)

Это размер «узкого места» в адаптерных матрицах A и B. Чем выше — тем больше параметров, тем больше адаптивной способности, тем больше памяти.

Типичные значения: 8, 16, 32.

Мои наблюдения:

  • rank=8 — минимум, достаточный для простых задач: изменить стиль, научить специфическому формату ответов
  • rank=16 — хорошее начало для большинства задач, золотая середина по соотношению качество/память
  • rank=32 — нужен когда учите совершенно новую область знаний, которой в базовой модели нет совсем

Начинайте с 16. Если результат плохой при хорошем датасете — попробуйте 32.

Alpha

Масштабирующий коэффициент. Контролирует «силу» адаптера. Итоговое изменение весов = ΔW × (alpha / rank).

Практическое правило: alpha = 2 × rank. Если rank=16, то alpha=32. Это стандартное начало. Точно настраивается экспериментально.

Если адаптер «не берёт» — увеличьте alpha. Если модель слишком сильно меняет поведение (теряет базовые способности) — уменьшите.

target_modules

Какие именно слои модели получают адаптеры. Не все слои одинаково полезны.

Типичный выбор для LLM:

python
target_modules=["q_proj", "v_proj"] # минимум target_modules=["q_proj", "k_proj", "v_proj", "o_proj"] # стандарт target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"] # максимум

Для большинства задач стиля/тона — достаточно q_proj и v_proj. Для сложной адаптации знаний — включайте все проекции.


QLoRA: то же самое, но ещё в 4 раза меньше памяти

QLoRA (Quantized LoRA) — это LoRA поверх квантизованной модели.

Квантизация — это сжатие весов модели с float32 до int4 (4 бита вместо 32). Качество немного падает, но память сокращается в 8 раз.

Схема QLoRA:

  1. Загрузить базовую модель в 4-битной квантизации (через bitsandbytes)
  2. Добавить LoRA-адаптеры поверх — они обучаются в float16/bfloat16
  3. Инференс: квантизованная модель + адаптер в полной точности

Результат: модели, которые не помещались даже с обычным LoRA, теперь запускаются на потребительских GPU.

Когда QLoRA вместо LoRA:

  • Видеокарта меньше 16 ГБ (RTX 3080/4080, Apple M-серия с ограниченным unified memory)
  • Модели 13B+ на одной GPU
  • Если LoRA всё равно не помещается

Когда LoRA лучше QLoRA:

  • Достаточно памяти — LoRA даёт чуть лучшее качество
  • Нужна максимальная точность дообучения (например, медицинские данные)

Честно: для большинства задач разница в качестве между LoRA и QLoRA не критична. Я начинаю с QLoRA, потому что оно просто работает на любом железе.


LoRA для картинок (Stable Diffusion) vs LoRA для LLM

LoRA изначально придумали для языковых моделей, но быстро перетащили в диффузионные модели — и теперь «LoRA» в контексте Stable Diffusion означает немного другое.

LoRA для LLM (то, что мы обсуждаем):

  • Адаптирует языковое поведение, стиль, знания
  • Работает с трансформерными весами (attention layers)
  • Примеры: дообучить Llama под ваш стиль, научить модель отвечать по-другому

LoRA для Stable Diffusion (чаще называют «дримбут»):

  • Добавляет новые концепты в картиночные модели: персонажей, стили, объекты
  • Можно обучить LoRA на 10-20 своих фотографиях — и модель научится рисовать вас
  • Популярные LoRA-адаптеры публикуются на Civitai

Математика одинаковая, но цель разная. Если вы видели «скачать LoRA для Midjourney» — это именно такие стилевые адаптеры для генерации изображений.

В этой статье мы про LLM.


Пример: обучаю LoRA-адаптер через PEFT за 15 строк

Hugging Face PEFT (Parameter-Efficient Fine-Tuning) — библиотека, которая делает LoRA из одной строчки конфига.

python
from transformers import AutoModelForCausalLM, AutoTokenizer from peft import LoraConfig, get_peft_model, TaskType # Загружаем базовую модель model = AutoModelForCausalLM.from_pretrained("microsoft/phi-2") tokenizer = AutoTokenizer.from_pretrained("microsoft/phi-2") # Конфигурируем LoRA lora_config = LoraConfig( task_type=TaskType.CAUSAL_LM, r=16, # rank lora_alpha=32, # alpha = 2 × rank target_modules=["q_proj", "v_proj"], lora_dropout=0.1, bias="none", ) # Оборачиваем модель в LoRA model = get_peft_model(model, lora_config) # Посмотрим сколько параметров обучаем model.print_trainable_parameters() # trainable params: 2,097,152 || all params: 2,779,000,000 || trainable%: 0.0755%

Обратите внимание на последнюю строку: обучаем всего 0.08% параметров от общего числа. Вот почему так мало памяти.

После этого обычный цикл обучения через Trainer или собственный loop — PEFT добавляет LoRA прозрачно, вы работаете как с обычной моделью.

Сохранение адаптера:

python
model.save_pretrained("./my-lora-adapter") # Сохраняет только адаптер (~10 МБ), не всю модель (~5 ГБ)

Запускаем через Unsloth: в 2 раза быстрее и бесплатно

Писать тренировочный цикл руками — необязательно. Unsloth Studio делает весь процесс через UI без кода.

Что Unsloth даёт поверх обычного PEFT:

  • Обучение в 2-5× быстрее за счёт кастомных CUDA-ядер
  • 60-70% экономия памяти (можно взять rank выше при той же GPU)
  • Готовые шаблоны для популярных моделей: Llama, Mistral, Phi, Qwen
  • Экспорт в GGUF (для запуска через Ollama) прямо из интерфейса

Детальный пошаговый гайд: Unsloth Studio: дообучаем AI-модель без кода.

Если хотите больше контроля (свои данные, кастомный training loop) — PEFT + Python. Если нужно просто быстро попробовать — Unsloth.


Когда LoRA не поможет: честные ограничения

LoRA — отличный инструмент, но не серебряная пуля. Когда он не справится:

Нужны актуальные данные. LoRA не добавляет новые факты «в реальном времени». Если вашей задаче нужны свежие события, цены, текущие данные — это RAG, а не fine-tuning. LoRA хорошо запоминает паттерны поведения, но плохо «запоминает» конкретные факты из большого корпуса.

Очень узкий датасет. 50-100 примеров — это минимум для заметного эффекта. Если у вас 10 диалогов, LoRA переобучится и станет хуже.

Нужен принципиально новый навык. LoRA хорошо адаптирует существующие паттерны. Если базовая модель вообще не умеет что-то (например, работать с уникальным форматом данных, которого нет в интернете) — нужен full fine-tuning или предобучение с нуля.

Нужна гарантированная безопасность. Alignment через LoRA слабее, чем через полный RLHF-пайплайн. Для задач где критична безопасность — LoRA не замена полному дообучению.


FAQ

Что такое LoRA простыми словами?

LoRA (Low-Rank Adaptation) — это метод дообучения нейросети, при котором исходные веса модели не изменяются. Вместо этого рядом добавляются маленькие «адаптерные» матрицы, которые и обучаются. Это в 10-100 раз снижает требования к памяти по сравнению с полным дообучением.

Какой rank LoRA выбрать: 8, 16 или 32?

Начните с rank=16. Это золотая середина для большинства задач. Rank=8 — если очень ограничена память или задача простая (изменить стиль). Rank=32 — если учите сложную новую область и качество важнее экономии. После первого эксперимента уже будет понятно, нужно ли менять.

Чем LoRA отличается от QLoRA?

QLoRA — это LoRA поверх квантизованной (4-битной) модели. QLoRA использует ещё меньше памяти (ещё в 4-8 раз), но качество дообучения немного ниже. Если базовая LoRA не помещается в вашу GPU — берите QLoRA. Для большинства задач разница в качестве незначительная.

Можно ли обучить LoRA бесплатно?

Да. Google Colab бесплатный T4 (15 ГБ) + Unsloth Studio позволяют дообучить модели до 13B параметров. Unsloth снижает потребление памяти на 60-70%, что делает возможным обучение на бесплатном GPU. Детали — в гайде по Unsloth Studio.

Сколько памяти нужно для LoRA fine-tuning?

Зависит от размера модели и rank. Ориентир: модель 7B с rank=16 через QLoRA требует ~5-6 ГБ GPU. С обычным LoRA — ~10-12 ГБ. GPT-2 (1.5B) с LoRA rank=16 — ~1.2 ГБ. Unsloth дополнительно снижает эти цифры на 30-60%.