Дообучение LLM методом ORPO
ORPO (Odds Ratio Preference Optimization) — метод дообучения с предпочтениями, предложенный Hong et al. (2024). Ключевое отличие от DPO: ORPO объединяет SFT и preference optimization в одном шаге, не требует отдельной reference model, и использует odds ratio (отношение шансов) вместо log-вероятностей для penalization нежелательных ответов.
ORPO vs DPO: технические различия
DPO:
- Требует SFT-дообученной reference model
- Держит в памяти две модели (trained + reference) или использует PEFT-трюки
- Оптимизирует: log-отношение вероятностей
- Гиперпараметр β определяет силу KL-штрафа
ORPO:
- Reference model не нужна
- Одна модель в памяти
- Оптимизирует SFT loss + OR-weighted rejection loss одновременно
- Гиперпараметр λ (lambda) — вес odds ratio loss
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))
Реализация ORPO через TRL
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, # ORPO обычно требует меньший lr, чем SFT
lr_scheduler_type="linear",
warmup_ratio=0.1,
beta=0.1, # λ в ORPO — вес OR loss (в TRL называется beta)
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, # Формат: prompt, chosen, rejected
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 — пары предпочтений:
dataset = {
"prompt": "Как правильно написать техническое задание?",
"chosen": "Техническое задание включает несколько обязательных разделов: цель проекта, функциональные требования (с приоритетами по MoSCoW), нефункциональные требования (производительность, безопасность), ограничения, критерии приёмки...",
"rejected": "Пишите что хотите чтобы разработчики поняли задачу"
}
Сравнение эффективности: ORPO vs DPO vs SimPO на практике
Независимые бенчмарки на AlpacaEval 2.0 (Win Rate vs GPT-4 Turbo):
| Метод | Win Rate | Память (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 по эффективности памяти при сопоставимом качестве. SimPO (Simple Preference Optimization) — более свежий метод, часто показывающий чуть лучшие результаты.
Практический кейс: выравнивание кода под стандарты команды
Задача: дообучить модель для code review под конкретные стандарты кода компании — правила наименования, обязательные паттерны безопасности, запрещённые практики.
Проблема с чистым SFT: модель хорошо воспроизводит «правильные» ревью, но не штрафует за игнорирование нарушений. Нужна штрафная составляющая.
ORPO-датасет: 1800 пар. Chosen — ревью, выявляющий все нарушения стандартов. Rejected — ревью, пропустивший критические нарушения или сгенерировавший ложные замечания.
Базовая модель: Qwen2.5-Coder-7B-Instruct.
Конфигурация: ORPO, β=0.1, lr=5e-6, 2 эпохи.
Результаты:
- Recall нарушений стандартов: 0.67 → 0.91
- Precision замечаний (нет ложных): 0.71 → 0.88
- False negative rate (пропуск критических нарушений): 28% → 7%
- Время обучения: 3.5ч на 1×A100 40GB (без reference model overhead)
ORPO vs DPO: когда выбирать
Выбирайте ORPO:
- Ограниченные GPU-ресурсы (одна модель вместо двух)
- Нет хорошей SFT-дообученной reference model
- Задача средней сложности alignment
Выбирайте DPO:
- Уже есть высококачественная SFT reference model
- Требуется точная настройка KL-дивергенции
- Накоплен опыт работы с DPO пайплайном
Выбирайте SimPO:
- Нужен максимальный win rate на бенчмарках
- Есть ресурсы на подбор γ и β параметров
Сроки
- Сбор датасета предпочтений: 3–5 недель
- Обучение ORPO (7B, LoRA, A100): 3–8 часов
- Итерации λ/β: 3–5 дней
- Оценка (LLM-as-judge + человек): 1 неделя
- Итого: 5–8 недель







