Билол Саидумаров
Все статьи

LoRA, QLoRA, Qwen2.5 — почему этот стек, а не другой

19 мая 2026 · 6 минут · LoRA, QLoRA, PEFT, fine-tuning
Если коротко
  • SFT, PEFT, LoRA, QLoRA — это не четыре параллельных метода. Это матрёшка.
  • Из шести PEFT-методов выбрана LoRA — и не за хайп, а потому что мерджится в базу.
  • 7B на 8 ГБ домашней карты — арифметика, а не магия. И почему Qwen2.5, а не Llama.
Изображение · hero · 1600×900
Большой полупрозрачный куб (foundation-модель). К нему сбоку подключается маленький лёгкий куб с надписью «LoRA» через две низкоранговые матрицы A и B.
Minimalist editorial illustration of a large translucent indigo cube (foundation model) with a small light-violet cube labeled "LoRA" attached to its side via two thin matrix grids labeled "A" and "B". Clean white background with a subtle grid. No harsh shadows, no logos, no text other than "LoRA", "A", "B". 16:9, 1600x900, professional editorial style.

Перед тем как нажать «Start training», я перебрал шесть PEFT-методов, три модели и поспорил сам с собой про SFT и RLHF.

Ниже — выбор и причины. Без хайпа и без «потому что так делают все».

Сначала — что во что вкладывается

В одной вакансии пишут «SFT / LoRA / QLoRA / PEFT», как будто это четыре равноправных метода. Это матрёшка:

SFT             — парадигма обучения (supervised, размеченные input→output)
 └── PEFT       — стратегия: обновляем только небольшой кусок параметров
      ├── LoRA          — низкоранговые матрицы на attention-проекциях
      ├── QLoRA         — LoRA поверх 4-битной квантизированной базы
      ├── IA³           — мультипликативные векторы (~10× меньше LoRA)
      ├── Prefix tuning — обучаемые «виртуальные» токены K/V
      ├── Prompt tuning — обучаемый soft prompt на входе
      └── Adapter-слои  — bottleneck-MLP между transformer-блоками

SFT — это что мы учим. PEFT — это как распределяем градиенты. LoRA и соседи — конкретные реализации PEFT.

Кто запускает LoRA — по определению занимается PEFT. Если эти слова стоят в одной вакансии, значение простое: «знай, что PEFT — это семья, а не синоним LoRA».

Почему SFT, а не RLHF

RLHF требует пар «лучший / худший» — это совсем другой бюджет на разметку.

Для structured extraction у нас уже есть «правильный JSON», и SFT-loss на нём работает прекрасно. RLHF имеет смысл, когда задача про предпочтения и стиль («какой ответ кажется человеку лучше»). Для «достань три поля из контракта» — это лишняя ступень сложности и три месяца ради нулевого прироста.

Почему LoRA, а не пять других PEFT-методов

МетодПочему не взяли
LoRA (выбран)Адаптер — мегабайты. Мерджится в базу при инференсе → 0 мс оверхеда. vLLM умеет --enable-lora. Самая зрелая тула.
IA³Адаптер ещё меньше, но по статье Liu 2022 хуже на генеративных задачах.
Prefix / Prompt tuningПотолок качества ниже, чувствителен к длине промпта, дебажить — мучение.
Adapter-слоиДобавляют латентность на инференсе. LoRA после merge — не добавляет.
Full fine-tuningПолная копия 7B-модели на каждую задачу. ~14× больше VRAM. Зачем.

Главное преимущество — мерджится в базу. В проде модель ведёт себя как обычный single-checkpoint Qwen, без лишнего forward-прохода через адаптер. Для надёжного inference это критично.

Зачем QLoRA, если есть LoRA

Простая арифметика. Qwen2.5-7B в fp16 — это ~14 ГБ под одни веса. RTX 4060 — 8 ГБ. Не помещается.

QLoRA — это LoRA, но базу загружаем не в fp16, а в 4-битной квантизации nf4 с двойной квантизацией через bitsandbytes. Веса сжимаются до ~4 ГБ. LoRA-дельта остаётся в fp16. Оптимизатор — paged AdamW 8-bit (пейджится между CPU и GPU).

На обучении я видел пик ~7,6 ГБ — впритык, но влезает.

Это и есть основная заявка статьи QLoRA: «можно дообучать 65B-модели на одной 48GB GPU». В моём случае — «7B на 8GB домашней карте». Цифры повторяются.

Почему Qwen2.5, а не Llama 3 или Mistral

Три простых критерия:

  1. Лицензия Apache-2.0. У Llama 3 — community-лицензия с ограничениями для крупных пользователей. Для развёртывания в регулируемой среде это уже препятствие.
  2. Мультиязычность из коробки. Qwen2.5 нативно сильна в китайском, русском и английском. Llama 3 — английский в первую очередь. Mistral — европейские получше. Узбекский — ни у кого, и это требует адаптации в любом случае.
  3. Размерная лесенка. Qwen2.5 идёт линейкой 0.5B / 1.5B / 3B / 7B / 14B / 32B / 72B с одним токенайзером. Один скрипт обучения, разные точки на кривой цена/качество.

Я обучил две модели одним и тем же кодом: 0.5B LoRA — 20 секунд на RTX 4060, 7B QLoRA — 5 минут. Одна команда, разный --base-model.

Гиперпараметры — где не выпендривался

Взял дефолты из оригинальной статьи LoRA (Hu et al., 2021) и не делал sweep:

  • r=16, alpha=32, dropout=0.05
  • Target modules: q_proj, k_proj, v_proj, o_proj (только attention, без MLP)
  • Learning rate 2e-4, AdamW (или paged-8bit для QLoRA)
  • 3 эпохи, batch 1 + grad accumulation 8 → эффективный 8

На 95 примерах sweep — самообман: тюнить нечего. На датасете в 5 000 — да, делайте grid по r ∈ {8, 16, 32}, lr ∈ {1e-4, 2e-4, 5e-4} и числу эпох. И смотрите на eval-loss, а не train-loss.

Одно простое движение, которое часто пропускают

LoRA-адаптер можно смержить в базу перед сохранением:

merged = model.merge_and_unload()
merged.save_pretrained("./qwen-merged")

После этого на инференсе нет дополнительной матричной операции. Модель ведёт себя как обычный single-checkpoint. Это и есть «0 мс оверхеда», ради которого мы выбирали LoRA, а не adapter-слои.

Минус — теряется возможность держать несколько адаптеров на одной базе. В проде у нас лежат оба варианта: смерженный — для быстрого инференса под одну задачу; отдельный адаптер — для vLLM с --enable-lora --max-loras 4, чтобы переключаться между «извлеки поля» / «классифицируй» / «суммаризируй» без перезагрузки.

Что сделать дальше