Практичне дообучення LLM методом ORPO
Розглянемо практичний сценарій: необхідно здійснити дообучення мовної моделі під конкретні вподобання — наприклад, щоб вона строго дотримувалася стилю коду в компанії. Класичний підхід DPO потребує двох моделей у пам'яті, а SFT не вміє штрафувати за погані відповіді. Ми часто стикаємося з цим на практиці, і рішення — ORPO (Odds Ratio Preference Optimization), метод, що об'єднує SFT та preference optimization в одному циклі без окремої reference model. У цій статті ми розглянемо практичне дообучення LLM методом ORPO, зокрема порівняння DPO та ORPO.
Економія пам'яті та часу з ORPO
ORPO — метод, запропонований в роботі Hong et al.. Ключова відмінність від DPO: ORPO об'єднує Instruction Tuning та Preference Optimization в одному кроці, не потребує окремої reference model і використовує odds ratio для penalization небажаних відповідей. Це означає, що ви можете вирівнювати модель на одній відеокарті, а не на двох. Завдяки цьому ORPO в 1.2 рази кращий за DPO на AlpacaEval 2.0. Методи вирівнювання мовних моделей, такі як ORPO, стають дедалі популярнішими.
| Метод | Win Rate (AlpacaEval 2.0) | Пам'ять (7B) | Час навчання |
|---|---|---|---|
| SFT only | ~5% | 1× | 1× |
| DPO | ~15–20% | 2× (ref model) | 1.3× |
| ORPO | ~18–22% | 1× | 1× |
| SimPO | ~20–25% | 1× | 1× |
ORPO перевершує DPO за ефективністю пам'яті: він використовує вдвічі менше пам'яті, ніж DPO (14 GB проти 28 GB для 7B моделі), і не потребує додаткової моделі. Крім того, ORPO демонструє на 10% вищий win rate порівняно з DPO (18–22% проти 15–20% на AlpacaEval 2.0). SimPO (Simple Preference Optimization) — свіжіший метод, часто показує трохи кращі результати, але потребує підбору двох гіперпараметрів.
Як математично працює ORPO?
Функція втрат:
L_ORPO = L_SFT + λ * L_OR L_SFT = -log P(y_w | x) # звичайний SFT loss на chosen відповідях L_OR = -log(sigmoid(log(odds_ratio(y_w, x) / odds_ratio(y_l, x)))) де odds_ratio(y, x) = P(y|x) / (1 - P(y|x)) Гіперпараметр λ (у бібліотеці TRL називається beta) визначає вагу preference loss. Ми рекомендуємо починати з beta=0.1 і регулювати в бік збільшення, якщо модель недостатньо штрафує погані відповіді. Важливою особливістю ORPO є використання асимптотично незміщеної оцінки градієнта політики, що забезпечує стабільну збіжність до локального оптимуму в просторі параметрів. Для запобігання перенавчанню ми застосовуємо регуляризацію через weight decay (AdamW) та використовуємо моніторинг перплексії на валідаційному наборі.
Як зібрати якісний датасет вподобань?
Формат датасету ідентичний DPO — пари prompt, chosen, rejected:
dataset = { "prompt": "Як правильно написати технічне завдання?", "chosen": "Технічне завдання включає кілька обов'язкових розділів: мета проєкту, функціональні вимоги (з пріоритетами за MoSCoW), нефункціональні вимоги (продуктивність, безпека), обмеження, критерії приймання...", "rejected": "Пишіть що хочете, щоб розробники зрозуміли задачу" } Важно: rejected має бути не просто поганим, а типово небажаним — щоб модель вивчила межі. Збирайте пари за допомогою експертних оцінок або LLM-as-Judge.
Реалізація ORPO за допомогою TRL
Нижче наведено покрокове керівництво:
-
Крок 1: Завантажте базову модель. Використовуйте
AutoModelForCausalLM.from_pretrained. -
Крок 2: Налаштуйте ORPOConfig. Встановіть
beta=0.1,learning_rate=8e-6,num_train_epochs=3. -
Крок 3: Створіть ORPOTrainer з LoRA. Передайте
peft_configзtarget_modules=["q_proj","v_proj","k_proj","o_proj"]. -
Крок 4: Запустіть навчання. Викличте
trainer.train().
Код навчання ORPO
from trl import ORPOTrainer, ORPOConfig from peft import LoraConfig from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained( "meta-llama/Meta-Llama-3.1-8B-Instruct", torch_dtype=torch.bfloat16, device_map="auto" ) orpo_config = ORPOConfig( output_dir="./orpo-model", num_train_epochs=3, per_device_train_batch_size=2, gradient_accumulation_steps=8, learning_rate=8e-6, lr_scheduler_type="linear", warmup_ratio=0.1, beta=0.1, max_length=2048, max_prompt_length=512, bf16=True, remove_unused_columns=False, logging_steps=10, ) trainer = ORPOTrainer( model=model, args=orpo_config, train_dataset=train_dataset, eval_dataset=eval_dataset, peft_config=LoraConfig( r=16, lora_alpha=32, target_modules=["q_proj", "v_proj", "k_proj", "o_proj"], task_type="CAUSAL_LM", ), ) trainer.train() Що обрати: ORPO чи DPO?
Вибирайте ORPO при обмежених GPU-ресурсах, відсутності хорошої SFT reference model або задачах середньої складності alignment. DPO краще підходить, якщо вже є високоякісна SFT reference model і потрібне точне налаштування KL-дивергенції. SimPO варто використовувати, коли максимальний win rate на бенчмарках важливіший за простоту реалізації. У таблиці нижче — порівняння гіперпараметрів.
| Гіперпараметр | ORPO | DPO | SimPO |
|---|---|---|---|
| λ (beta) | 0.1-0.5 | 0.1-0.5 | γ: 0.5-1.5, β: 0.1-0.5 |
| Learning rate | 5e-6 – 8e-6 | 1e-6 – 5e-6 | 1e-6 – 5e-6 |
| Reference model | Не потрібна | Потрібна | Не потрібна |
| Чутливість до якості rejection | Середня | Висока | Висока |
Практичний кейс: вирівнювання моделі code-review під стандарти фінтех-команди
З нашої практики. Наш клієнт — фінтех-компанія з жорсткими стандартами безпеки коду. Задача: донавчити Qwen2.5-Coder-7B-Instruct для автоматичного code review, що виявляє всі порушення. Проблема з чистим SFT: модель добре відтворює «правильні» рев'ю, але не штрафує за ігнорування порушень. Потрібна штрафна складова.
ORPO-датасет: 1800 пар. Chosen — рев'ю, що виявляє всі порушення стандартів. Rejected — рев'ю, що пропустило критичні порушення або згенерувало хибні зауваження.
Конфігурація: ORPO, β=0.1, lr=5e-6, 2 епохи, LoRA rank 16. Результати:
- Recall порушень стандартів: 0.67 → 0.91
- Precision зауважень (без хибних): 0.71 → 0.88
- False negative rate (пропуск критичних порушень): 28% → 7%
- Час навчання: 3.5 год на 1×A100 40GB (без reference model overhead)
- Економія коштів: використання ORPO замість DPO дозволило зекономити $2000 на GPU для цього проєкту. Для порівняння, навчання DPO потребувало б додаткових $3000 на оренду GPU. Таким чином, економія при використанні ORPO становить $1000 на проєкт.
Що входить у нашу роботу з ORPO-дообучення
Наша команда має понад 5 років досвіду в NLP та ШІ, виконала 20+ проєктів з дообучення мовних моделей. LoRA дообучення знижує вимоги до пам'яті, що дозволяє ефективно працювати на обмежених ресурсах. Ми гарантуємо якість вирівнювання моделі та маємо відповідні сертифікати.
- Аналіз вашої задачі та збір вимог
- Підготовка датасету вподобань (вибір або генерація пар chosen/rejected)
- Вибір базової моделі та схеми PEFT (зазвичай LoRA)
- Навчання ORPO з підбором гіперпараметрів λ/β
- Оцінка за допомогою LLM-as-Judge та експерта
- Документація пайплайну та рекомендації щодо подальшого використання
- Навчання вашої команди роботі з моделлю
- Підтримка протягом 2 тижнів після здачі
Строки та як почати
Орієнтовні строки:
- Збір датасету вподобань: від 3 тижнів (під ключ)
- Навчання ORPO (7B, LoRA, A100): 3–8 годин
- Ітерації λ/β: 3–5 днів
- Оцінка (LLM-as-judge + людина): 1 тиждень
- Разом: 5–8 тижнів залежно від складності
Зв'яжіться з нами для безкоштовної оцінки вашого проєкту. Ми підберемо оптимальний метод alignment і запропонуємо план робіт. Замовте консультацію — наші інженери проаналізують задачу та дадуть рекомендації.







