Дотонування LLM методом LoRA (Low-Rank Adaptation)
LoRA — метод параметрично ефективного дотонування, при якому оригінальні ваги моделі замораживаються, а поруч із ними тренуються невеликі матриці низького рангу. Метод запропонований у 2021 році (Hu et al., Microsoft Research) та став стандартом de facto для дотонування LLM. LoRA дозволяє дотонувати модель 7B на одному GPU A100 40GB замість кількох, при цьому втрата якості порівняно з повним дотонуванням мінімальна для більшості завдань.
Математика LoRA
Для матриці ваг W ∈ R^(d×k) LoRA додає добуток двох матриць:
W' = W + ΔW = W + BA
де B ∈ R^(d×r), A ∈ R^(r×k), r << min(d, k)
Ранг r — ключовий гіперпараметр. При r=16 та d=k=4096 (типові розміри attention проекцій у моделі 7B) кількість тренованих параметрів у одному шарі: 16×4096 + 4096×16 = 131 072 замість 4096×4096 = 16 777 216. Це стиснення в 128 разів.
При ініціалізації A — випадкова гаусівська матриця, B — нульова. Це забезпечує ΔW=0 на початку — модель починає з оригінальної поведінки.
Конфігурація LoRA: ключові гіперпараметри
from peft import LoraConfig
config = LoraConfig(
r=16, # Ранг: 4, 8, 16, 32, 64, 128
lora_alpha=32, # Масштаб: звичайно = 2*r
target_modules=[ # Які шари адаптувати
"q_proj", "v_proj", # Мінімум
"k_proj", "o_proj", # Розширений варіант
"gate_proj", "up_proj", "down_proj" # MLP включно
],
lora_dropout=0.05, # Регуляризація адаптера
bias="none", # "none", "all", "lora_only"
task_type="CAUSAL_LM",
modules_to_save=["embed_tokens", "lm_head"], # Тренувати повністю
)
Вибір r: чим складніше завдання та чим більша відмінність домену від перетренування — тим вище r. Для класифікації та форматування: r=4–8. Для генерування в специфічному стилі: r=16–32. Для складної адаптації домену: r=64–128.
lora_alpha: контролює масштаб адаптера. Ефективний lr адаптера = lr × (alpha/r). Стандартна практика: alpha = 2r.
DoRA: поліпшення LoRA
DoRA (Weight-Decomposed Low-Rank Adaptation) розділяє оновлення ваг на компоненти magnitude та direction:
config = LoraConfig(
r=16,
use_dora=True, # Включає DoRA замість стандартної LoRA
...
)
DoRA поліпшує якість на 1–3% порівняно зі стандартною LoRA без збільшення витрат на логічний висновок.
Практичний випадок: LoRA для класифікації NER
Завдання: видалення іменованих сутностей з медичних записів (4 класи: MEDICATION, DOSAGE, CONDITION, PROCEDURE).
Базова модель: Llama 3.1 8B Instruct.
Конфігурація: r=16, alpha=32, target_modules=["q_proj","v_proj"], 3 епохи.
Набір даних: 2200 прикладів, A100 40GB, QLoRA 4-bit, час тренування 2.5 години.
| Метрика | Базова модель (5-shot) | LoRA r=8 | LoRA r=16 | LoRA r=32 |
|---|---|---|---|---|
| F1 MEDICATION | 0.71 | 0.88 | 0.91 | 0.92 |
| F1 DOSAGE | 0.64 | 0.83 | 0.87 | 0.88 |
| F1 CONDITION | 0.79 | 0.91 | 0.94 | 0.94 |
| F1 PROCEDURE | 0.68 | 0.85 | 0.89 | 0.90 |
Розрив між r=16 та r=32 незначний — r=16 оптимальна.
Об'єднання адаптера для розгортання
LoRA-адаптер можна об'єднати з базовою моделлю для спрощення логічного висновку:
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3.1-8B-Instruct")
model = PeftModel.from_pretrained(base_model, "./lora-adapter")
# Об'єднання: результат — звичайна модель без PEFT overhead
merged = model.merge_and_unload()
merged.save_pretrained("./merged-model")
Після об'єднання модель ідентична за швидкістю логічного висновку повністю потренованій — overhead LoRA на логічному висновку зникає.
Строки
- Підготовка даних: 2–4 тижні
- Тренування (7B, LoRA, A100 40GB): 2–8 годин
- Ітерації гіперпараметрів: 3–5 днів
- Усього: 3–6 тижнів







