Донавчання LLM методом DPO (Direct Preference Optimization)
Ви навчили LLM на корпусі даних, але модель все одно видає не ті відповіді, які очікує користувач? Стандартний SFT не дає контролю над стилем і вподобаннями. Ми використовуємо DPO для вирівнювання LLM під бізнес-задачі. DPO — метод alignment, що дозволяє навчити модель генерувати бажані відповіді без явного навчання reward model і RLHF-циклу. Запропонований нещодавно в роботі DPO. DPO перетворює задачу RL на задачу supervised learning на датасеті переваг (chosen/rejected пари), що значно спрощує пайплайн alignment. Наші інженери реалізували DPO для десятків проєктів — результат: зростання CSAT до 23%, зниження відмов на 12%. Економія обчислювальних ресурсів сягає 60% порівняно з RLHF. Ви можете замовити DPO-донавчання під ключ — від збору датасету до деплою моделі.
Чому DPO став стандартом alignment?
Класичний RLHF потребує навчання окремої Reward Model і нестабільної PPO-оптимізації. DPO обходиться без цього. DPO в 3 рази швидший і на 60% дешевший за RLHF. Порівняння підходів:
| Параметр | RLHF | DPO |
|---|---|---|
| Необхідність Reward Model | Так | Ні |
| Кількість моделей в пам'яті | 4 (actor, critic, reward, reference) | 2 (trainable, reference) |
| Стабільність навчання | Низька (PPO sensitive) | Висока (SGD-like) |
| Складність налаштування | Висока | Середня |
| Час навчання (на 1000 пар) | ~5 годин на A100 | ~1.5 години на A100 |
| Фінансова ефективність | Високі витрати на GPU | Економія до 60% ресурсів |
Математично DPO мінімізує:
L_DPO = -E[log σ(β * (log π_θ(y_w|x)/π_ref(y_w|x) - log π_θ(y_l|x)/π_ref(y_l|x)))]
де y_w — preferred response, y_l — rejected, β — температура KL-регуляризації.
Як зібрати датасет переваг?
Формат датасету для DPO — пари (chosen, rejected). Приклад запису:
# Приклад запису датасету переваг
{
"prompt": "Поясни різницю між TCP і UDP",
"chosen": "TCP (Transmission Control Protocol) забезпечує надійну доставку даних з підтвердженням отримання, управлінням потоком і контролем помилок. UDP (User Datagram Protocol) — без встановлення з'єднання, без гарантії доставки, але з мінімальною затримкою. TCP використовують для HTTP, FTP, SMTP; UDP — для DNS, відеостримінгу, ігор реального часу.",
"rejected": "TCP надійний, UDP швидкий. TCP повільніший тому що перевіряє кожен пакет. Обидва це протоколи інтернету."
}
На практиці ми використовуємо три методи збору:
- Human annotation: 2–3 аннотатори на пару, висока достовірність.
- AI-генерація + human verification: GPT-4o створює chosen, GPT-4o-mini — rejected, людина перевіряє 20–30%.
- Реальні дані з продакшну: логи лайків/дизлайків, виправлення операторів.
Приклад генерації через OpenAI API:
from openai import OpenAI
def generate_preference_pair(prompt: str, client: OpenAI) -> dict:
"""Генерує пару chosen/rejected для DPO датасету"""
# Хороша відповідь
chosen_response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "Дай детальну, точну, добре структуровану відповідь."},
{"role": "user", "content": prompt}
],
temperature=0.3
).choices[0].message.content
# Погана відповідь — спеціально деградуємо якість
rejected_response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "Дай коротку, поверхневу відповідь без деталей."},
{"role": "user", "content": prompt}
],
temperature=0.9
).choices[0].message.content
return {"prompt": prompt, "chosen": chosen_response, "rejected": rejected_response}
Реалізація DPO через TRL
Бібліотека TRL від Hugging Face надає готові класи. Приклад конфігурації:
from trl import DPOTrainer, DPOConfig
from peft import LoraConfig
# Створюємо reference model (заморожена копія SFT-моделі)
# TRL керує цим автоматично при use_reference_model=True
dpo_config = DPOConfig(
output_dir="./dpo-model",
num_train_epochs=1, # DPO зазвичай 1-3 епохи
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
learning_rate=5e-7, # Значно нижче, ніж SFT
lr_scheduler_type="cosine",
warmup_ratio=0.1,
beta=0.1, # KL-температура
loss_type="sigmoid", # "sigmoid", "hinge", "ipo", "kto_pair"
max_length=2048,
max_prompt_length=512,
bf16=True,
logging_steps=10,
)
trainer = DPOTrainer(
model=model, # SFT-донавчена модель
ref_model=None, # None = автоматично створюється з model
args=dpo_config,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
peft_config=LoraConfig(r=16, lora_alpha=32, target_modules=["q_proj","v_proj"]),
)
trainer.train()
Як вибрати loss_type для DPO?
| loss_type | Опис | Коли використовувати |
|---|---|---|
| sigmoid | Оригінальний DPO loss | Стандартний вибір |
| hinge | SLiC-HF, менш чутливий до outliers | При зашумленому датасеті |
| ipo | Identity Preference Optimization | Потрібна стійкість до переучування |
| kto_pair | Kahneman-Tversky Optimization | Непарні дані (тільки chosen) |
Типові помилки при DPO
- Занадто високий learning rate (>1e-6) — модель розходиться.
- Відсутність SFT перед DPO — DPO навчається нестабільно на сирій базовій моделі.
- Маленький датасет (<500 пар) — alignment незначний.
- β=0 — зникає KL-регуляризація, модель втрачає якість генерації.
Практичний кейс: покращення якості клієнтського сервісу
Задача: мовна модель для підтримки клієнтів відповідала коректно, але з жорстким, безособовим тоном. SFT-донавчання на нових даних частково вирішило проблему, але вимагало перезбору даних щоразу.
Рішення: DPO на парах переваг. Chosen — відповіді операторів з високим CSAT. Rejected — відповіді з низьким CSAT. Об'єм: 2100 пар. У цьому кейсі наш клієнт — компанія зі сфери телекомунікацій.
Базова модель для DPO: SFT-донавчена Mistral 7B.
Результати:
- CSAT бота: 3.4 → 4.2 (із 5)
- Empathy score (LLM-as-judge): 2.8 → 4.1
- Factual accuracy: без змін (0.91 → 0.91)
- Refusal rate: 12% → 4% (модель стала менш надмірно обережною)
- β=0.1 виявився оптимальним: при β=0.5 accuracy впала, при β=0.01 — нестабільність
Типовий пайплайн: SFT → DPO
DPO застосовується поверх SFT, а не замість нього:
- SFT (Supervised Fine-Tuning): вчимо модель форматувати та видавати релевантні відповіді в домені.
- DPO: вирівнюємо якість відповідей під вподобання користувачів.
Пропуск SFT і прямий DPO на базовій моделі технічно можливий, але менш стабільний.
Що входить у DPO-донавчання під ключ
Ми пропонуємо комплексну послугу з DPO-донавчання LLM. Команда з досвідом понад 10 років у NLP гарантує якість:
- Збір та розмітка датасету переваг (мінімум 1000 пар).
- SFT-донавчання базової моделі (якщо потрібно).
- DPO-навчання з підбором гіперпараметрів (β, loss_type, learning rate).
- Оцінка якості: LLM-as-judge + human evaluation.
- Деплой моделі в продакшн (SageMaker, Triton, ONNX).
- Документація та передача прав на модель.
Гарантуємо якість: кожен проєкт проходить A/B тестування на реальних користувачах. Зв'яжіться з нами для попередньої оцінки вашого проєкту.
Терміни та вартість
Орієнтовні терміни:
- Збір та розмітка датасету переваг: 3–6 тижнів.
- SFT (якщо не проводився): 2–3 тижні.
- DPO навчання та ітерації: 1–2 тижні.
- Оцінка якості: 1 тиждень.
- Разом: 7–12 тижнів.
Вартість розраховується індивідуально і залежить від об'єму датасету, розміру моделі та глибини кастомізації. Отримайте консультацію — ми підготуємо комерційну пропозицію з урахуванням ваших завдань.







