Дообчання LLM методом DPO (Direct Preference Optimization)

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Дообчання LLM методом DPO (Direct Preference Optimization)
Складний
від 1 тижня до 3 місяців
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    901
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

Дофіно-tunuing LLM методом DPO (Direct Preference Optimization)

DPO — метод alignment, що дозволяє навчити модель генерувати переважні відповіді без явного навчання reward model та RLHF-циклу. Запропонований Rafailov et al. (Stanford, 2023), DPO перетворює задачу RL у задачу supervised learning на датасеті переваг (chosen/rejected пари), що суттєво спрощує пайплайн alignment.

DPO vs RLHF: принципова відмінність

RLHF (класичний):

  1. Навчання Reward Model на парах переваг
  2. Навчання LLM через PPO з використанням Reward Model
  3. KL-дивергенція від reference policy як регуляризатор

Недоліки: нестабільність PPO, необхідність тримати 4 моделі в пам'яті (actor, critic, reward, reference), складне налаштування.

DPO:

  1. Пряма оптимізація на парах (chosen, rejected) без Reward Model
  2. Неявний reward визначається через log-відношення ймовірностей trained/reference моделі
  3. Стабільне навчання як звичайний SFT

Математично DPO мінімізує:

L_DPO = -E[log σ(β * (log π_θ(y_w|x)/π_ref(y_w|x) - log π_θ(y_l|x)/π_ref(y_l|x)))]

де y_w — переважна відповідь, y_l — відхилена, β — температура KL-регуляризації.

Формат датасету для DPO

# Приклад запису датасету переваг
{
    "prompt": "Поясни різницю між TCP та UDP",
    "chosen": "TCP (Transmission Control Protocol) забезпечує надійну доставку даних з підтвердженням отримання, управлінням потоком та контролем помилок. UDP (User Datagram Protocol) — без встановлення з'єднання, без гарантії доставки, але з мінімальною затримкою. TCP використовують для HTTP, FTP, SMTP; UDP — для DNS, відео-streaming, ігор у реальному часі.",
    "rejected": "TCP надійний, UDP швидкий. TCP повільніший, тому що перевіряє кожен пакет. Обидва це протоколи інтернету."
}

Реалізація DPO через TRL

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-дофіно-tuned модель
    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

  • sigmoid: оригінальний DPO loss
  • hinge: SLiC-HF, менш чутливий до outliers
  • ipo: IPO (Identity Preference Optimization), стабільніша версія
  • kto_pair: KTO (Kahneman-Tversky Optimization), працює з непарними даними

Створення датасету переваг: практичні методи

Метод 1: Human annotation. Найвища якість, але дорого. Анотатори бачать дві відповіді та вибирають кращу. Потрібно мінімум 2-3 анотатори на пару для надійності.

Метод 2: AI-генерація + human verification. GPT-4o генерує chosen (висока якість) та rejected (навмисне погіршена). Люди верифікують 20–30% вибірки.

Метод 3: Реальні дані з продакшену. Логи взаємодій з користувачами: лайки/дизлайки, рейтинги, коригування операторів.

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}

Практичний case study: покращення якості обслуговування клієнтів

Задача: мовна модель для підтримки клієнтів відповідала коректно, але з жорстким, безособистісним тоном. SFT-дофіно-tuning на нових даних частково вирішив проблему, але вимагав пересбору даних щоразу.

Рішення: DPO на парах переваг. Chosen — відповіді операторів з високим CSAT. Rejected — відповіді з низьким CSAT. Обсяг: 2100 пар.

Базова модель для DPO: SFT-дофіно-tuned 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, а не замість нього:

  1. SFT (Supervised Fine-Tuning): навчаємо модель форматувати та видавати релевантні відповіді в домені
  2. DPO: вирівнюємо якість відповідей під переваги користувачів

Пропуск SFT і прямий DPO на базовій моделі технічно можливий, але менш стабільний.

Часові рамки

  • Збір та розмітка датасету переваг: 3–6 тижнів
  • SFT (якщо не проводився): 2–3 тижні
  • DPO навчання та ітерації: 1–2 тижні
  • Оцінка якості (LLM-as-judge + людина): 1 тиждень
  • Всього: 7–12 тижнів