中文翻译暂不可用,显示俄语原文。
QLoRA vs LoRA — в чем разница и когда QLoRA лучше?
Краткий тезис
QLoRA — это техника адаптации больших языковых моделей, объединяющая LoRA с 4-битной квантизацией (4‑bit NormalFloat). Она позволяет fine-tune модели размером до 70B параметров на одной 24GB GPU, жертвуя 1–2% качества и 20–30% скорости обучения. QLoRA оптимальна при дефиците GPU и работе с моделями от 30B; LoRA предпочтительна для моделей до 13B, когда критичны точность и скорость.
1. Термины: LoRA, квантование, QLoRA
LoRA (Low‑Rank Adaptation) — метод параметро-эффективного fine-tuning. Вместо обновления весов W модели вводит для каждого слоя две небольшие матрицы A и B (ранг r), так что ∆W = BA. Обучаются только эти матрицы, что снижает число обучаемых параметров в тысячи раз.
Квантование (quantization) — снижение точности чисел (например, с 16‑bit float до 4‑bit), уменьшающее размер модели и скорость инференса. Для fine-tuning требуется, чтобы градиенты проходили через квантованные веса, что обычно делается с помощью QLoRA.
QLoRA (Quantized Low‑Rank Adaptation) — LoRA поверх 4‑битной квантованной модели. Веса базовой модели заморожены и хранятся в 4‑битном формате; адаптеры LoRA обучаются в полной точности (float32 или bfloat16). Использует специальные техники: NormalFloat4, Double Quantization, Paged Optimizers, чтобы минимизировать потерю качества при квантовании.
2. Как работает LoRA
LoRA вводит для каждого весового слоя (например, линейного) две низкоранговые матрицы A ∈ R^(d × r) и B ∈ R^(r × k), где r — ранг (обычно 8–64). Прямой проход: h = W₀x + BAx. Обучаются только A и B, исходные веса W₀ заморожены.
- Преимущества
- Число обучаемых параметров ↓ в 10 000 раз (для модели 7B c r=8 ~ 0.1% от полных весов).
- Не требует хранения полных градиентов базовой модели.
- Можно комбинировать несколько LoRA-адаптеров («переключать» их).
- Недостатки Базовая модель хранится в 16‑bit (или 32‑bit), что занимает много памяти (для 70B ~ 140 GB в float16).
Код (PEFT + Hugging Face Transformers):
from peft import LoraConfig, get_peft_model
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05
)
model = get_peft_model(base_model_16bit, lora_config)
3. Как работает QLoRA
QLoRA использует три ключевые инновации:
- 4‑bit NormalFloat (NF4) — специальный тип квантования, оптимально распределяющий значения по гауссовскому распределению весов. Сохраняет больше информации, чем обычный int4.
- Double Quantization — повторное квантование констант квантования (scale‑факторов) в 8‑битный формат, снижающее дополнительный расход памяти.
- Paged Optimizer — при нехватке GPU‑памяти автоматически выгружает градиенты в CPU (page‑out) и подгружает обратно, подобно swap.
Схема работы
- Базовая модель загружается в 4‑bit NF4 (например, модель 70B занимает ~35 GB).
- Для обратного прохода градиенты вычисляются в полной точности (float32 или bfloat16) с помощью параметризованных квантованных весов — веса на лету деквантуются до 16‑bit, применяется LoRA, градиент считается.
- Адаптеры LoRA хранятся и обучаются в full‑precision.
Код
from transformers import BitsAndBytesConfig, AutoModelForCausalLM
from peft import LoraConfig, get_peft_model
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.bfloat16
)
model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=bnb_config)
model = get_peft_model(model, lora_config)
4. Сравнение QLoRA vs LoRA
| Параметр | LoRA (16‑bit) | QLoRA (4‑bit NF4) |
|---|---|---|
| Память для базовой модели (7B) | ~14 GB (float16) | ~3.5 GB (4‑bit) |
| Память для градиентов / оптимизатора | ~0.1% от модели (дополнительно ~0.3 GB) | ~0.1% + overhead от деквантования |
| Максимальный размер модели на 24GB GPU | ~7‑13B | ~70B |
| Качество (точность на бенчмарках) | Эталон | Ниже на 1–2% (в среднем) |
| Скорость обучения | Быстрее (нет деквантования) | Медленнее на 20–30% |
| Скорость инференса | Высокая (‑bit) | Медленнее из‑за деквантования при каждом forward |
| Совместимость с переключением адаптеров | Да (хранить один адаптер) | Да (но базовая модель 4‑bit занимает мало места) |
| Когда использовать | Модели до 13B, достаточно GPU, важно качество | Модели 30B+, ограниченная память, эксперименты |
5. Когда QLoRA лучше
QLoRA — выбор для сценариев с жёсткими ограничениями по памяти:
- Модели от 30B до 70B на одной 24GB GPU можно обучать Llama‑3‑70B, что невозможно с LoRA (требует >140 GB).
- Экспериментирование с несколькими моделями можно быстро загружать разные 4‑bit модели и накатывать адаптеры.
- Прототипирование и исследование не критично падение качества на 1‑2%, но критично время и ресурсы.
- Сценарии с ограниченным бюджетом облачные GPU стоят дорого — QLoRA позволяет fine‑tune большие модели на дешёвых инстансах (T4, L4).
Пример: тонкий fine‑tune Llama‑3‑70B для задачи перевода на одном NVIDIA RTX 3090 (24 GB). С QLoRA это занимает ~2 дня, с LoRA невозможно.
6. Когда LoRA лучше
- Модели до 13B память позволяет хранить 16‑bit веса (7B ~14 GB, 13B ~26 GB). LoRA быстрее и точнее.
- Продакшн с требованием высокой точности даже 1% ухудшения недопустимы (например, финансовые задачи, медицинские рекомендации).
- Высокая скорость обучения если нужно много итераций (десятки тысяч шагов), QLoRA будет в 1.2‑1.3 раза медленнее.
- Когда базовая модель уже в 16‑bit и нет желания переквантовывать: LoRA работает «как есть».
- Сервинг с несколькими LoRA можно объединять адаптеры в производственном инференсе (через
merge_and_unload), после чего QLoRA может дать прирост скорости за счёт меньшего размера модели? (обычно после merge модель остаётся 16‑bit, поэтому LoRA выигрывает).
7. Практические рекомендации по выбору ранга и настройкам
- Rank (r): для QLoRA и LoRA ранг обычно 8–64. Для маленьких моделей (7B) r=16, для больших (70B) r=64 (больше ~ больше качество, но больше параметров). QLoRA не требует менять r из‑за квантования.
- Target modules: чаще всего
q_proj,v_proj(при LoRA), но в QLoRA можно добавлятьk_proj,o_proj,gate_proj. Не рекомендуется трогать embedding и lm_head (требуют полной точности). - Batch size: из‑за ограниченной памяти QLoRA использует gradient accumulation; обычный batch size = 1–2.
- Learning rate: для QLoRA чуть выше (2e‑4 vs 1e‑4 для LoRA), чтобы компенсировать шум квантования.
- double_quant: всегда включать (экономит ~0.5 GB без потерь).
8. Производительность: оценочные цифры для разных размеров моделей
| Модель | Метод | Память (GPU) | Время обучения на 1000 шагов (bs=1) | Качество (на датасете GSM8K) |
|---|---|---|---|---|
| Llama‑2‑7B | LoRA (16‑bit) | ~16 GB | ~6 часов | 45% |
| Llama‑2‑7B | QLoRA (4‑bit) | ~5 GB | ~8 часов | 43% |
| Llama‑2‑13B | LoRA | ~28 GB | ~10 часов | 53% |
| Llama‑2‑13B | QLoRA | ~8 GB | ~13 часов | 51% |
| Llama‑2‑70B | QLoRA | ~35 GB | - (на 2×A100) | 68% |
| Llama‑3‑70B | QLoRA | ~45 GB (с пагинацией) | на 24 GB T4 невозможен, на 48 GB ~3 дня | 80%+ |
Цифры приблизительные, зависят от датасета, ранга, реализации.
9. Влияние на качество: доказательства из литературы
В оригинальной статье QLoRA (Dettmers et al., 2023) показано, что при сохранении всех гиперпараметров, QLoRA уступает LoRA менее 1% на большинстве бенчмарков (MMLU, TruthfulQA, GSM8K). Лучший результат достигается при использовании NF4 + Double Quantization + Paged Optimizer. Если пренебречь Double Quantization, просадка увеличивается до 2–3%.
Пример поведения на MMLU (5‑shot):
Разница 0.7% — допустима для экспериментов, но может быть существенной в продакшне.
10. Инструменты и реализация
Основные библиотеки:
- Hugging Face PEFT — предоставляет
LoraConfigиget_peft_model. - Bitsandbytes (от Tim Dettmers) — реализация 4‑bit NF4, Double Quantization, Paged Optimizer.
- Transformers — интеграция через
quantization_config. - TRL — для RL‑настроек (PPO, DPO).
Типичный workflow:
from transformers import AutoTokenizer, TrainingArguments, Trainer
import torch
# 1. Load quantized model
bnb_config = BitsAndBytesConfig(load_in_4bit=True, ...)
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3-70b", quantization_config=bnb_config)
# 2. Wrap with LoRA
lora_config = LoraConfig(r=64, ...)
model = get_peft_model(model, lora_config)
# 3. Train
training_args = TrainingArguments(per_device_train_batch_size=1, gradient_accumulation_steps=16, ...)
trainer = Trainer(model=model, args=training_args, train_dataset=...)
trainer.train()
Пет-проект для закрепления
Задача Сравнить LoRA и QLoRA на одной модели (Llama‑2‑7B или Mistral‑7B) на задаче классификации сентиментов (датасет IMDB). Измерить время обучения, пиковую память, accuracy на тесте.
Инструменты
- Python 3.10+, PyTorch, Transformers, PEFT, Bitsandbytes, Datasets, Accelerate.
- GPU минимум 8 GB (подойдёт Colab T4).
Шаги:
- Загрузить токенизатор и базовую модель (Mistral‑7B) в 16‑bit.
- Применить
LoraConfig(r=8, target_modules= ["q_proj", "v_proj"], lora_alpha=16). - Обучить модель на 1000 примерах IMDB (fine‑tune на последовательность). Замерить время и память (с помощью
nvidia-smiили библиотекиpynvml). - Сохранить адаптер, протестировать accuracy.
- Повторить шаги 1–4, но загружая модель с
BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4", ...). - Сравнить: accuracy, время, пиковую память.
Ожидаемый результат
- QLoRA использует в 2–3 раза меньше памяти (например, 4.5 GB вместо 15 GB), но обучение длится на 20–30% дольше.
- Accuracy будет в пределах 1–2% от LoRA (например, 88% vs 89%).
- Вывод: на маленьких моделях LoRA предпочтительнее, но QLoRA позволяет работать с более сложными моделями на том же железе.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 26 | LoRA — принцип работы, отличие от full fine‑tuning |
| 28 | PEFT (Parameter‑Efficient Fine‑Tuning) — обзор методов |
| 29 | Quantization — виды (INT8, FP4, NF4), как влияет на точность |
| 30 | Как выбирать ранг LoRA / target modules |
| 31 | Fine‑tuning vs RLHF — когда какой подход |
| 32 | Memory optimization — Gradient Checkpointing, ZeRO, Paged Optimizer |
Навигация
- Предыдущий: 26
- Следующий: 28
- Индекс: 00. Индекс разборов