smol course, юнит 2: выравнивание по предпочтениям и DPO
Перевод юнита о выравнивании по предпочтениям из smol course Hugging Face: что такое DPO, формат датасета пар, обучение SmolLM3 в TRL локально и через Hugging Face Jobs, оценка и сдача на лидерборд, плюс раздел об ORPO из первой версии курса.
Это перевод юнита «Preference Alignment» из второй версии smol course — практического курса Hugging Face о дообучении маленьких языковых моделей. В конце добавлен перевод раздела об ORPO из первой версии курса: во второй версии обещанный раздел о продвинутых вариантах DPO так и не появился. Что есть в курсе целиком — в путеводителе.
2.1. Введение в выравнивание по предпочтениям на SmolLM3
Заголовок раздела «2.1. Введение в выравнивание по предпочтениям на SmolLM3»Добро пожаловать в юнит 3 самого маленького курса о дообучении! Этот модуль проведёт вас через выравнивание по предпочтениям (preference alignment) на модели SmolLM3, опираясь на основу из юнита 1 — обучение на инструкциях. Вы научитесь выравнивать языковые модели с предпочтениями людей с помощью прямой оптимизации предпочтений (Direct Preference Optimization, DPO), чтобы делать ИИ-ассистентов полезнее, безвреднее и честнее.
(Примечание переводчика: в оглавлении курса этот юнит второй, а в тексте он называет себя третьим — по старому плану, где вторым шёл юнит об оценке моделей. Мы нумеруем разделы по оглавлению: 2.1–2.4.)
Что такое выравнивание по предпочтениям?
Заголовок раздела «Что такое выравнивание по предпочтениям?»Обучение с учителем (supervised fine-tuning, SFT) учит модель следовать инструкциям и вести диалог, а выравнивание по предпочтениям идёт дальше: оно учит модель давать ответы, которые нравятся людям. Это процесс, который приближает системы ИИ к тому, чего люди на самом деле хотят, а не к буквальному выполнению инструкций. Проще говоря, оно делает языковые модели лучше для реальных приложений.
Выравнивание по предпочтениям решает несколько ключевых задач в разработке ИИ. Модели, обученные с ним, ведут себя лучше в разных отношениях. Они реже дают вредные, предвзятые или неуместные ответы, а их ответы полезнее и ближе к настоящим нуждам людей. Такие модели правдивее и меньше галлюцинируют, а их ответы лучше отражают человеческие ценности и этику. В целом у выровненных моделей выше связность, уместность и качество ответов.
Прямая оптимизация предпочтений (DPO)
Заголовок раздела «Прямая оптимизация предпочтений (DPO)»DPO произвёл переворот в выравнивании по предпочтениям: он убрал необходимость в отдельной модели награды и сложном обучении с подкреплением. В этом юните мы разберём эту ведущую технику выравнивания языковых моделей с предпочтениями людей.
Конвейер выравнивания DPO гораздо проще конвейера обучения с подкреплением на отзывах людей (Reinforcement Learning from Human Feedback, RLHF). Процесс состоит из двух основных этапов:
- Научить базовую модель следовать инструкциям с помощью обучения с учителем.
- Напрямую оптимизировать модель на данных о предпочтениях с помощью DPO.
Такой упрощённый подход позволяет обучаться на данных о предпочтениях без отдельной модели награды и сложного обучения с подкреплением, добиваясь сопоставимых или лучших результатов. Не волнуйтесь, если впервые видите RLHF: мы разберём его подробнее дальше в курсе и сравним с DPO.
В упражнениях этого юнита мы снова будем выравнивать SmolLM3. Можно взять либо instruct-модель, либо результат упражнения из юнита 1.
Что вы сделаете
Заголовок раздела «Что вы сделаете»В этом юните вы на практике освоите выравнивание по предпочтениям. Вы научитесь обучать SmolLM3 методом DPO на датасетах предпочтений.
- Освоите настройку и подбор гиперпараметров DPO.
- Сравните результаты DPO с исходной instruct-моделью.
- Оцените безопасность и качество выравнивания модели на стандартных бенчмарках.
- Отправите выровненную модель на лидерборд курса.
- Наконец, разберётесь, как развернуть выровненную модель для практического применения.
Готовы сделать свои модели ближе к предпочтениям людей с помощью DPO? Начнём!
2.2. Прямая оптимизация предпочтений (DPO)
Заголовок раздела «2.2. Прямая оптимизация предпочтений (DPO)»Direct Preference Optimization (DPO) перевернула выравнивание по предпочтениям, предложив более простую и стабильную альтернативу обучению с подкреплением на отзывах людей (RLHF). Вместо обучения отдельных моделей награды и сложных алгоритмов обучения с подкреплением DPO напрямую оптимизирует языковую модель на данных о предпочтениях людей.
Как устроен DPO
Заголовок раздела «Как устроен DPO»(В оригинале — схема из документации TRL: сверху RLHF — данные предпочтений, отдельная модель награды, выборка ответов и обучение с подкреплением; снизу DPO — те же данные сразу превращаются в обновление модели через функцию потерь, похожую на классификацию.)
flowchart LR subgraph R["RLHF"] D1["Пары предпочтений"] --> RM["Модель награды"] RM --> PPO["RL (PPO):<br/>генерация + награда"] PPO --> M1["Выровненная модель"] end subgraph P["DPO"] D2["Пары предпочтений"] --> L["Функция потерь DPO<br/>(как бинарная классификация)"] L --> M2["Выровненная модель"] end
Традиционный RLHF требует нескольких компонентов и этапов обучения. Как показывает схема, он включает:
- обучение модели награды, которая предсказывает предпочтения людей по предпочтённым и отвергнутым ответам;
- оптимизацию политики алгоритмами обучения с подкреплением вроде PPO по этой модели награды.
DPO резко упрощает процесс: он пропускает модель награды и напрямую оптимизирует языковую модель функцией потерь бинарной кросс-энтропии.
- Сначала обучаем SFT-модель следовать инструкциям.
- Затем обучаем DPO-модель, напрямую оптимизируя языковую модель на самих данных о предпочтениях.
Как работает DPO
Заголовок раздела «Как работает DPO»DPO превращает выравнивание по предпочтениям в задачу классификации. По промпту и двум ответам (одному предпочтённому, другому отвергнутому) DPO учит модель повышать вероятность предпочтённого ответа и понижать вероятность отвергнутого.
Процесс обучения
Заголовок раздела «Процесс обучения»DPO требует предварительного обучения с учителем (SFT), чтобы адаптировать модель к целевой области. Так создаётся основа для обучения на предпочтениях: модель учится на обычных датасетах инструкций. Она осваивает базовое выполнение задач, сохраняя общие способности.
Затем идёт обучение на предпочтениях: модель учится на парах ответов — один предпочтённый, другой нет. Пары предпочтений помогают модели понять, какие ответы лучше соответствуют человеческим ценностям и ожиданиям.
Главное новшество DPO — прямой подход к оптимизации. Вместо обучения отдельной модели награды DPO с помощью функции потерь бинарной кросс-энтропии напрямую обновляет веса модели по данным о предпочтениях. Такой упрощённый процесс делает обучение стабильнее и эффективнее, давая сопоставимые или лучшие результаты, чем традиционный RLHF.
Функция потерь DPO
Заголовок раздела «Функция потерь DPO»Главное новшество DPO — его функция потерь, которая напрямую оптимизирует политику (языковую модель) на данных о предпочтениях:
Где:
- — обучаемая модель;
- — эталонная (референсная) модель, обычно SFT-модель;
- — предпочтённый («выигравший», winning) ответ;
- — отвергнутый («проигравший», losing) ответ;
- — параметр «температуры», который управляет силой оптимизации;
- — сигмоида.
Формат датасета для DPO
Заголовок раздела «Формат датасета для DPO»Для обучения DPO нужны датасеты предпочтений, где в каждом примере есть:
| Поле | Описание | Пример |
|---|---|---|
prompt | Входной промпт или вопрос | «Объясни квантовые вычисления простыми словами» |
chosen | Предпочтённый ответ | «Квантовые вычисления используют принципы квантовой механики…» |
rejected | Менее предпочтительный ответ | «Квантовые вычисления — это очень сложно и непонятно…» |
Датасет может содержать и дополнительные поля, которые повышают качество обучения. Это могут быть системные промпты с инструкциями о поведении модели. Это могут быть многоходовые диалоги с разметкой предпочтений. Наконец, это могут быть метаданные с дополнительным контекстом — например, силой предпочтения или согласованностью разметчиков.
Ниже — пример датасета для DPO.
(В оригинале здесь встроен просмотрщик датасета trl-lib/ultrafeedback_binarized: у каждой строки — промпт, выбранный и отвергнутый ответы в виде списков сообщений и их оценки.)
Реализация в TRL
Заголовок раздела «Реализация в TRL»С библиотекой TRL (Transformers Reinforcement Learning) реализовать DPO просто:
from trl import DPOConfig, DPOTrainerfrom transformers import AutoModelForCausalLM, AutoTokenizerfrom datasets import load_dataset
# Загружаем модель и токенизаторmodel = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM3-3B")tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM3-3B")
# Настраиваем обучение DPOtraining_args = DPOConfig( beta=0.1, # параметр «температуры» learning_rate=5e-7, # низкая скорость обучения ради стабильности max_prompt_length=512, # максимальная длина промпта max_length=1024, # максимальная общая длина per_device_train_batch_size=4, gradient_accumulation_steps=4, num_train_epochs=1,)
# Создаём тренерtrainer = DPOTrainer( model=model, args=training_args, train_dataset=preference_dataset, processing_class=tokenizer,)
# Обучаем модельtrainer.train()(Примечание переводчика: preference_dataset в этом фрагменте не определён — подставьте свой датасет с колонками
prompt, chosen, rejected, например load_dataset("trl-lib/ultrafeedback_binarized", split="train"). Эталонную
модель задавать не нужно: если не передать ref_model, DPOTrainer сам сделает замороженную копию исходной модели.)
Какой тип датасета ожидается
Заголовок раздела «Какой тип датасета ожидается»DPO нужен датасет предпочтений. DPOTrainer
поддерживает и разговорный (списки сообщений с
ролями), и стандартный (просто текст) форматы. Если дать
разговорный датасет, тренер сам применит к нему chat-шаблон.
DPOTrainer поддерживает и явные, и неявные промпты, но мы рекомендуем явные. Если дать датасет с неявным промптом,
тренер сам извлечёт промпт из колонок "chosen" и "rejected". Подробнее — в разделе
preference style документации.
(«Явный промпт» — отдельная колонка prompt. «Неявный» — промпт записан в начале и chosen, и rejected, а ответы
различаются только концом.)
| Параметр | Описание | Рекомендации |
|---|---|---|
| Beta (β) | Управляет силой оптимизации предпочтений | Диапазон: от 0.1 до 0.5. Меньшие значения: осторожнее, ближе к эталонной модели. Большие значения: сильнее выравнивание, риск переобучения |
| Скорость обучения | Скорость обучения для DPO | Рекомендация: намного ниже, чем при обычном дообучении (от 5e-7 до 5e-6). Почему: чтобы избежать катастрофического забывания и сохранить стабильность. Настройка: уменьшайте ещё, если обучение нестабильно |
| Размер и качество датасета | Требования к датасету предпочтений | Минимум: около 1000 качественных пар для задач в узкой области. Рекомендуется: от 10 000 пар для надёжного выравнивания. Качество важнее количества: лучше меньше качественных пар, чем много плохих |
Лучшие практики
Заголовок раздела «Лучшие практики»Качество данных
Заголовок раздела «Качество данных»Качество данных критически важно для успешного обучения DPO. Датасет предпочтений должен содержать разнообразные примеры, охватывающие разные стороны желаемого поведения. Чёткие инструкции для разметчиков обеспечивают согласованную разметку предпочтённых и отвергнутых ответов. Качество модели можно поднять, улучшив датасет предпочтений, — например, отфильтровав большой датасет до качественных примеров или примеров, относящихся к вашему сценарию.
Во время обучения внимательно следите за сходимостью loss и проверяйте качество на отложенных данных. Параметр beta может потребовать подстройки, чтобы сбалансировать обучение на предпочтениях и сохранение общих способностей модели. Регулярная оценка на разнообразных промптах помогает убедиться, что модель учится нужным предпочтениям и не переобучается.
Сравнивайте ответы модели с ответами эталонной модели, чтобы убедиться, что выравнивание улучшилось. Проверка на разных промптах, включая пограничные случаи, помогает обеспечить надёжное обучение на предпочтениях в разных ситуациях.
Стабильность обучения
Заголовок раздела «Стабильность обучения»Внимательно следите за сходимостью loss: loss DPO должен снижаться плавно, без колебаний и скачков. Регулярно сравнивайте ответы модели с ответами эталонной, чтобы видеть ощутимые улучшения выравнивания. Используйте обрезку градиентов (gradient clipping), чтобы избежать нестабильности, особенно при высоких скоростях обучения или трудных датасетах. Добавьте раннюю остановку, чтобы прекратить обучение, если качество вышло на плато или начало ухудшаться, — это защитит от переобучения и сбережёт вычисления.
(Примечание переводчика: кроме loss, DPOTrainer логирует rewards/chosen, rewards/rejected, rewards/margins
и rewards/accuracies — неявные награды для лучших и худших ответов, их разность
и долю пар, где лучший ответ получил большую награду. Здоровая картина: отрыв margins растёт, точность поднимается
выше 0.5. Тревожный знак: rewards/chosen уходит сильно в минус — модель понижает вероятность обоих ответов.)
Оценивайте качество модели на разных промптах, включая пограничные случаи, чтобы убедиться в надёжности обучения на предпочтениях в разных ситуациях. Сравнивайте ответы модели с ответами эталонной, чтобы подтвердить улучшение выравнивания.
Типичные ловушки
Заголовок раздела «Типичные ловушки»Внедряя DPO, следите за переобучением на предпочтения: модель может начать повторяться или потерять общие способности. Если так случилось, уменьшите параметр beta, сократите обучение или сделайте датасет разнообразнее, чтобы сохранить широкие способности. И наоборот, если выравнивание почти не улучшается, несмотря на обучение, сигнал предпочтений может быть слишком слабым — попробуйте увеличить beta, улучшить качество датасета или обучать дольше.
(Как сказано в примечании выше, с в этом абзаце всё наоборот: при переобучении стоит увеличить, а при слишком слабом эффекте — уменьшить. Остальные советы верны.)
Ещё одна частая проблема — сдвиг распределения: модель хорошо работает в области обучения, но плохо обобщается на новые ситуации. Чтобы этого избежать, следите, чтобы датасет предпочтений полностью покрывал целевые сценарии и включал разнообразные примеры, отражающие реальные применения. Цель — надёжное обучение на предпочтениях, при котором модель остаётся полезной в разных контекстах.
Что дальше
Заголовок раздела «Что дальше»- Обучить SmolLM3 на ваших данных о предпочтениях.
- Оценить качество выравнивания и работу модели.
- Развернуть выровненную модель.
Освоив DPO, переходите к продвинутым техникам в разделе о продвинутых методах DPO.
(Примечание переводчика: раздела о продвинутых методах DPO во второй версии курса нет — ссылка в оригинале ведёт на практическое упражнение. Вместо него в конце страницы мы перевели раздел об ORPO из первой версии курса. Обзор IPO, KTO и SimPO — в уроке 6.3.3.)
2.3. Практическое упражнение: DPO на SmolLM3
Заголовок раздела «2.3. Практическое упражнение: DPO на SmolLM3»Ноутбук к разделу: Google Colab.
(Примечание переводчика: на 17 сентября 2026 года файла notebooks/3/4.ipynb в репозитории курса нет — есть только
ноутбуки к юнитам 1 и 3 (папки notebooks/1 и notebooks/4), поэтому ссылка может не открыться. Весь код упражнения
приведён ниже.)
Добро пожаловать в практическую часть о прямой оптимизации предпочтений! В этом упражнении вы примените всё, что узнали о выравнивании по предпочтениям, и обучите SmolLM3 методом DPO. Затем вы отправите результаты на лидерборд курса с помощью Hugging Face Jobs.
Упражнение: обучение методом DPO
Заголовок раздела «Упражнение: обучение методом DPO»Цель: обучить SmolLM3 методом DPO, получить модель, выровненную по предпочтениям, и отправить её на лидерборд.
Подготовка окружения
Заголовок раздела «Подготовка окружения»Начнём с подготовки окружения и разберёмся с DPO локально, прежде чем переходить к HF Jobs.
# Устанавливаем нужные пакетыpip install "transformers>=4.56.1" "trl>=0.23.0" "datasets>=4.1.0" "torch>=2.8.0"pip install "accelerate>=1.10.1" "peft>=0.17.0" "trackio"Импорт библиотек и настройка
Заголовок раздела «Импорт библиотек и настройка»import torchfrom transformers import AutoModelForCausalLM, AutoTokenizerfrom datasets import load_datasetfrom trl import DPOTrainer, DPOConfigimport json
# Проверяем доступное устройствоif torch.cuda.is_available(): device = "cuda" print(f"Using CUDA GPU: {torch.cuda.get_device_name()}") print(f"GPU memory: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f}GB")elif hasattr(torch.backends, 'mps') and torch.backends.mps.is_available(): device = "mps" print("Using Apple MPS")else: device = "cpu" print("Using CPU - you will need HF Jobs with GPU for actual training")
# Входим в Hugging Facefrom huggingface_hub import loginlogin() # нужно для HF Jobs и выгрузки моделей(Код печатает, какое устройство найдено: GPU NVIDIA (и сколько у неё памяти), GPU Apple (MPS) или только CPU — тогда для настоящего обучения понадобится HF Jobs.)
Разбираемся с форматом данных DPO
Заголовок раздела «Разбираемся с форматом данных DPO»Перед обучением посмотрим, как выглядят данные о предпочтениях и как DPO их использует:
# Загружаем датасет предпочтений, чтобы посмотреть на форматdataset = load_dataset("Anthropic/hh-rlhf", split="train")print(f"Dataset size: {len(dataset)}")print("Dataset features:", dataset.features.keys())
# Смотрим на одну пару предпочтенийsample = dataset[0]print(f"\nChosen (Preferred): {sample['chosen'][:200]}...")print(f"\nRejected (Non-preferred): {sample['rejected'][:200]}...")
# Так видно, как DPO учится предпочитать ответы «chosen» ответам «rejected»Ожидаемый вывод (по версии курса):
Dataset size: 112000Dataset features: ['prompt', 'chosen', 'rejected']
=== DPO Preference Pair Example ===Prompt: Human: What are some cuss words in english?
Chosen (Preferred): Assistant: I understand you're curious about profanity in English. While I can acknowledge that such words exist, I'd prefer not to list them explicitly. These are generally considered offensive or inappropriate in most contexts...
Rejected (Non-preferred): Assistant: Here are some common cuss words in English: [explicit list follows]...(Смысл примера: на вопрос «Какие есть ругательства в английском?» предпочтённый ответ вежливо отказывается перечислять их, а отвергнутый — перечисляет.)
Локальный пробный прогон DPO (необязательно)
Заголовок раздела «Локальный пробный прогон DPO (необязательно)»Если у вас достаточно локальных GPU-ресурсов, можно проверить обучение DPO локально, прежде чем переходить к HF Jobs:
# Берём небольшую часть датасета для локальной проверкиsmall_dataset = dataset.select(range(1000))
# Загружаем модель SmolLM3-3B-Instructmodel_name = "HuggingFaceTB/SmolLM3-3B-Instruct"model = AutoModelForCausalLM.from_pretrained( model_name, dtype=torch.bfloat16, device_map="auto")tokenizer = AutoTokenizer.from_pretrained(model_name)tokenizer.pad_token = tokenizer.eos_token
# Настраиваем DPO для локальной проверкиtraining_args = DPOConfig( beta=0.1, # сила оптимизации предпочтений learning_rate=5e-7, # ниже, чем при SFT per_device_train_batch_size=1, # маленький батч для локальной проверки gradient_accumulation_steps=4, # эффективный батч = 4 max_steps=50, # совсем короткий прогон для проверки logging_steps=10, output_dir="./local_dpo_test", report_to="trackio",)
# Создаём тренер (но пока не обучаем — бережём ресурсы для HF Jobs)trainer = DPOTrainer( model=model, args=training_args, train_dataset=small_dataset, processing_class=tokenizer,)
print("Local DPO trainer configured successfully!")print("Ready to scale to HF Jobs for full training...")(Примечание переводчика: модели HuggingFaceTB/SmolLM3-3B-Instruct нет. В самом курсе (юнит 1) базовая модель
называется HuggingFaceTB/SmolLM3-3B-Base, а instruct-модель — просто HuggingFaceTB/SmolLM3-3B; её и подставьте.
trackio — лёгкая библиотека Hugging Face для графиков обучения; если она не нужна, поставьте report_to="none".
Чтобы реально запустить прогон, допишите trainer.train().)
Обучение в Hugging Face Jobs
Заголовок раздела «Обучение в Hugging Face Jobs»Теперь настроим обучение DPO в HF Jobs — облачном масштабируемом обучении.
Создаём скрипт обучения DPO
Заголовок раздела «Создаём скрипт обучения DPO»Сначала создадим скрипт обучения на возможностях DPO из TRL:
# /// script# dependencies = [# "trl[dpo]>=0.7.0",# "transformers>=4.36.0",# "datasets>=2.14.0",# "accelerate>=0.24.0",# "torch>=2.0.0"# ]# ///
from trl import DPOTrainer, DPOConfigfrom transformers import AutoModelForCausalLM, AutoTokenizerfrom datasets import load_dataset
def main(): # Загружаем датасет предпочтений dataset = load_dataset("Anthropic/hh-rlhf", split="train")
# Берём разумную часть для обучения train_dataset = dataset.select(range(10000))
# Загружаем модель SmolLM3-3B (уже прошедшую SFT) model_name = "HuggingFaceTB/SmolLM3-3B" model = AutoModelForCausalLM.from_pretrained(model_name) tokenizer = AutoTokenizer.from_pretrained(model_name) tokenizer.pad_token = tokenizer.eos_token
# Настраиваем обучение DPO training_args = DPOConfig( # Главные параметры DPO beta=0.1, # сила оптимизации предпочтений max_prompt_length=512, # максимальная длина промпта max_length=1024, # максимальная общая длина последовательности
# Настройка обучения learning_rate=5e-7, # ниже, чем при SFT, ради стабильности per_device_train_batch_size=2, # подстройте под память GPU gradient_accumulation_steps=8, # эффективный батч = 16 max_steps=1000, # достаточно для хорошего выравнивания
# Оптимизация warmup_steps=100, lr_scheduler_type="cosine", gradient_checkpointing=True, # экономия памяти bf16=True, # смешанная точность
# Логирование и сохранение logging_steps=50, save_steps=250, output_dir="./smollm3-dpo-aligned",
# Интеграция с Hub push_to_hub=True, hub_model_id="your-username/smollm3-dpo-aligned", # замените! report_to="trackio",
# Не удаляем «лишние» колонки remove_unused_columns=False, )
# Создаём тренер DPO trainer = DPOTrainer( model=model, args=training_args, train_dataset=train_dataset, processing_class=tokenizer, )
# Запускаем обучение print("Starting DPO training...") trainer.train()
print("Training completed! Model saved and pushed to Hub.")
if __name__ == "__main__": main()(Блок комментариев # /// script … # /// в начале — встроенное описание зависимостей скрипта (стандарт PEP 723):
команда uv run прочитает его и сама поставит нужные пакеты.)
Отправляем задание DPO в HF Jobs
Заголовок раздела «Отправляем задание DPO в HF Jobs»Теперь отправим задание на обучение в HF Jobs:
# Отправляем задание DPO в HF Jobshf jobs uv run \ --flavor a100-large \ --timeout 3h \ --secrets HF_TOKEN \ dpo_training.py(Примечание переводчика: HF Jobs — платная облачная услуга. На вашей машине тот же скрипт запускается так:
accelerate launch --num_processes 4 dpo_training.py с конфигурацией FSDP или DeepSpeed, либо на одной карте с LoRA.
Время — того же порядка, что на A100.)
Вариант: готовый скрипт DPO из TRL
Заголовок раздела «Вариант: готовый скрипт DPO из TRL»Можно использовать и поддерживаемый командой TRL скрипт DPO напрямую:
# Скрипт DPO из TRL в HF Jobshf jobs uv run \ --flavor a100-large \ --timeout 3h \ --secrets HF_TOKEN \ "https://raw.githubusercontent.com/huggingface/trl/main/trl/scripts/dpo.py" \ --model_name_or_path HuggingFaceTB/SmolLM3-3B \ --dataset_name Anthropic/hh-rlhf \ --learning_rate 5e-7 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps 8 \ --max_steps 1000 \ --beta 0.1 \ --max_prompt_length 512 \ --max_length 1024 \ --output_dir smollm3-dpo-aligned \ --push_to_hub \ --hub_model_id your-username/smollm3-dpo-aligned \ --report_to trackioСледим за заданием
Заголовок раздела «Следим за заданием»Следить за ходом обучения DPO можно через командную строку HF Jobs:
# Список всех ваших заданийhf jobs ps -a
# Логи задания в реальном времениhf jobs logs <job_id> --follow
# Подробности о заданииhf jobs inspect <job_id>Метрики обучения можно смотреть и в Trackio — по ссылке из логов задания.
Оцениваем модель после DPO
Заголовок раздела «Оцениваем модель после DPO»Когда обучение закончится, оцените качество выравнивания модели:
# Локальная оценка обученной моделиfrom transformers import pipeline
# Загружаем обученную модельmodel_name = "your-username/smollm3-dpo-aligned"generator = pipeline("text-generation", model=model_name, tokenizer=model_name)
# Проверяем выравнивание на разных промптахtest_prompts = [ "How should I handle a disagreement with my friend?", "What's the best way to learn programming?", "How can I be more productive at work?", "What should I do if I see someone being bullied?"]
print("=== DPO Model Alignment Test ===")for prompt in test_prompts: response = generator(prompt, max_length=200, do_sample=True, temperature=0.7) print(f"\nPrompt: {prompt}") print(f"Response: {response[0]['generated_text'][len(prompt):].strip()}")(Промпты: «Как мне уладить разногласие с другом?», «Как лучше всего учиться программированию?», «Как стать продуктивнее на работе?», «Что делать, если я вижу, что кого-то травят?».)
(Примечание переводчика: такой вызов подаёт instruct-модели «голый» текст без chat-шаблона, и ответы могут быть хуже,
чем модель умеет на самом деле. Передавайте промпт как список сообщений — generator([{"role": "user", "content": prompt}]), —
тогда pipeline сам применит шаблон. И сравнивайте с исходной моделью HuggingFaceTB/SmolLM3-3B на тех же промптах:
без сравнения не видно, что дал DPO.)
Отправляем на лидерборд курса
Заголовок раздела «Отправляем на лидерборд курса»Готовы отправить выровненную модель на лидерборд? Переходите на страницу отправки, где вы:
- оцените модель с помощью HF Jobs и LightEval;
- отправите результаты на лидерборд курса;
- сравните качество выравнивания своей модели с другими участниками.
Материалы и что почитать
Заголовок раздела «Материалы и что почитать»- Статья о DPO — оригинальное исследование Direct Preference Optimization.
- Документация DPO в TRL — подробности реализации и примеры.
- Статья Anthropic о HH-RLHF — методика сбора отзывов людей.
- Alignment Handbook — продвинутые техники выравнивания.
Поздравляем с завершением обучения DPO! Ваша выровненная модель готова к оценке и отправке на лидерборд.
2.4. Отправьте итоговый проект!
Заголовок раздела «2.4. Отправьте итоговый проект!»Пора отправить вашу модель, выровненную методом DPO! В этом юните та же система отправки через лидерборд, что и в юните 1. План такой:
- Прочитать текстовое руководство к главе ✅
- Обучить модель по тому, что вы узнали в главе.
- Выгрузить модель на Hugging Face Hub.
- Оценить модель с помощью
hf jobs. - Открыть pull request на лидерборд.
На этой странице пройдём по каждому шагу.
1. Прочитайте руководство к главе и 2. Обучите модель по тому, что узнали
Заголовок раздела «1. Прочитайте руководство к главе и 2. Обучите модель по тому, что узнали»Для отправки по юниту 3 прочитайте все материалы юнита и обучите модель, выровненную методом DPO. Код обучения дан здесь:
- Упражнение по обучению DPO — полное руководство по DPO на SmolLM3.
Его нужно сочетать с приёмами из раздела «Обучение с Hugging Face Jobs» юнита 1.
3. Выгрузите модель на Hugging Face Hub
Заголовок раздела «3. Выгрузите модель на Hugging Face Hub»Обучив модель методом DPO, выгрузите её в репозиторий на Hugging Face Hub. TRL сделает это за вас, если добавить
к команде обучения флаг --push_to_hub.
Обучение DPO с выгрузкой на Hub
Заголовок раздела «Обучение DPO с выгрузкой на Hub»hf jobs uv run \ --flavor a100-large \ --secrets HF_TOKEN \ "https://raw.githubusercontent.com/huggingface/trl/main/trl/scripts/dpo.py" \ --model_name_or_path HuggingFaceTB/SmolLM3-3B \ --dataset_name Anthropic/hh-rlhf \ --learning_rate 5e-7 \ --beta 0.1 \ --max_steps 1000 \ --push_to_hub \ --hub_model_id your-username/smollm3-dpo-aligned \ --report_to trackioОбученная модель будет доступна по адресу your-username/your-model-name. Подробности — в
документации о чекпойнтах библиотеки transformers.
4. Оцените модель с помощью hf jobs
Заголовок раздела «4. Оцените модель с помощью hf jobs»Теперь оценим модель после DPO. Для этого используем hf jobs вместе с lighteval, а результаты оценки выгрузим
в датасет на Hub.
hf jobs uv run \ --flavor a10g-large \ --with "lighteval[vllm]" \ --secrets HF_TOKEN \ lighteval vllm "model_name=<your-username>/<your-model-name>" \ "lighteval|truthfulqa:mc2|0|0,lighteval|hellaswag|0|0,lighteval|arc:challenge|0|0" \ --push-to-hub --results-org <your-username>Команда оценит модель с помощью lighteval и vllm и сохранит результаты на Hugging Face Hub в репозитории датасета,
который вы укажете.
(Строка задач читается так: «набор|задача|число примеров в промпте (few-shot)|флаг» — здесь три бенчмарка без примеров
в промпте. Что измеряют TruthfulQA, HellaSwag и ARC — в уроке 7.3.1.
Локально та же команда запускается без hf jobs uv run … --secrets HF_TOKEN, начиная с lighteval vllm.)
(Примечание переводчика: юнита об оценке во второй версии курса пока нет (в оглавлении — «Coming soon»). Оценка моделей в lighteval разобрана в главе 11 LLM Course, а в курсе ChinaAI — в уроках 7.3.1 и 7.3.2. Заметьте также, что команда выше запускает TruthfulQA, HellaSwag и ARC, а не GSM8K и MMLU, перечисленные в подсказке.)
5. Откройте pull request в Space лидерборда
Заголовок раздела «5. Откройте pull request в Space лидерборда»Теперь можно отправить модель на лидерборд! Нужно сделать две вещи:
- добавить результаты модели в
submissions.json; - описать в тексте PR свои команды обучения и оценки.
Добавьте результаты модели в submissions.json
Заголовок раздела «Добавьте результаты модели в submissions.json»Откройте pull request в Space лидерборда, чтобы отправить модель. Нужно лишь добавить сведения о модели и ссылку на датасет, созданный на прошлом шаге. Мы заберём результаты и покажем их на лидерборде.
{ "submissions": [
... // уже отправленные модели
{ "username": "<your-username>", "model_name": "<your-model-name>", "chapter": "3", "method": "DPO", "submission_date": "<your-submission-date>", "results-dataset": "<your-results-dataset>", "base_model": "HuggingFaceTB/SmolLM3-3B", "preference_dataset": "Anthropic/hh-rlhf" } ]}Опишите команды обучения и оценки в тексте PR
Заголовок раздела «Опишите команды обучения и оценки в тексте PR»В тексте PR приведите и команды обучения, и команды оценки.
Дождитесь слияния PR
Заголовок раздела «Дождитесь слияния PR»Когда PR сольют, ваша модель после DPO появится на лидерборде! Посмотреть лидерборд можно здесь.
Проверьте себя
Заголовок раздела «Проверьте себя»Вы прошли юнит — отличная работа! Теперь проверьте знания в тесте.
Материалы и что почитать
Заголовок раздела «Материалы и что почитать»- Упражнение по DPO юнита 3 — полное руководство по обучению DPO.
- Статья о DPO — оригинальная статья.
- Документация DPO в TRL — подробности реализации.
- Статья Anthropic о HH-RLHF — методика сбора отзывов людей.
- Alignment Handbook — продвинутые техники выравнивания.
Удачи с отправкой модели, выровненной по предпочтениям! 🚀
Дополнение: ORPO из первой версии курса
Заголовок раздела «Дополнение: ORPO из первой версии курса»Перевод файла v1/2_preference_alignment/orpo.md из первой версии smol course (конец 2024 года).
Оптимизация предпочтений через отношение шансов (ORPO)
Заголовок раздела «Оптимизация предпочтений через отношение шансов (ORPO)»ORPO (Odds Ratio Preference Optimization) — новая техника дообучения, которая объединяет дообучение и выравнивание по предпочтениям в один процесс. Такой объединённый подход даёт выигрыш в эффективности и качестве по сравнению с традиционными методами вроде RLHF или DPO.
Как устроен ORPO
Заголовок раздела «Как устроен ORPO»Выравнивание методами вроде DPO обычно состоит из двух отдельных шагов: обучение с учителем, чтобы адаптировать модель к области и формату, а затем выравнивание по предпочтениям людей. SFT хорошо адаптирует модель к целевой области, но может невольно повышать вероятность и желательных, и нежелательных ответов. ORPO снимает это ограничение, объединяя оба шага в один процесс, как показано на сравнении ниже.
(В оригинале — рисунок из блога Argilla «Comparison of different model alignment techniques»: RLHF — три этапа (SFT, модель награды, PPO), DPO — два (SFT и DPO с эталонной моделью), ORPO — один этап без эталонной модели.)
Как работает ORPO
Заголовок раздела «Как работает ORPO»Обучение использует датасет предпочтений, похожий на тот, что мы брали для DPO: в каждом примере есть промпт и два ответа — предпочтённый и отвергнутый. В отличие от других методов выравнивания, которым нужны отдельные этапы и эталонные модели, ORPO встраивает выравнивание по предпочтениям прямо в обучение с учителем. Такой монолитный подход не требует эталонной модели, экономнее по вычислениям и памяти и требует меньше FLOP.
ORPO строит новую цель из двух основных частей:
-
Loss SFT: обычная функция потерь отрицательного логарифма правдоподобия, как в языковом моделировании, — она максимизирует вероятность эталонных токенов. Это помогает сохранить общие языковые способности модели.
-
Loss отношения шансов: новая часть, которая штрафует нежелательные ответы и поощряет предпочтённые. Она использует отношение шансов (odds ratio), чтобы противопоставить предпочтённые и отвергнутые ответы на уровне токенов.
Вместе эти части подстраивают модель под желаемые ответы в конкретной области и активно отталкивают её от ответов из множества отвергнутых. Отношение шансов даёт естественный способ измерять и оптимизировать, насколько модель предпочитает выбранный ответ отвергнутому. Если хотите погрузиться в математику, прочитайте статью об ORPO. Если хотите разобраться в ORPO со стороны реализации, посмотрите, как считается loss ORPO в библиотеке TRL.
Качество и результаты
Заголовок раздела «Качество и результаты»ORPO показал впечатляющие результаты на разных бенчмарках. На MT-Bench он набирает конкурентные баллы в разных категориях.
(В оригинале — диаграмма «MT-Bench results by category for Mistral-ORPO models»: баллы моделей Mistral-ORPO по категориям MT-Bench.)
В сравнении с другими методами выравнивания ORPO показывает лучшее качество на AlpacaEval 2.0.
(В оригинале — диаграмма «AlpacaEval 2.0 scores across different alignment methods».)
По сравнению с SFT+DPO ORPO снижает требования к вычислениям: ему не нужна эталонная модель, и прямых проходов на батч вдвое меньше. Кроме того, обучение стабильнее на моделях разного размера и разных датасетах, и настраивать нужно меньше гиперпараметров. По качеству ORPO не уступает более крупным моделям и лучше согласуется с предпочтениями людей.
(Примечание переводчика: эти сравнения взяты из статьи авторов ORPO и блога Argilla 2024 года. Последующие независимые сравнения не показывают у ORPO систематического преимущества над DPO — результат сильно зависит от данных и настройки. Главный практический плюс ORPO — один этап и одна модель в памяти.)
Реализация
Заголовок раздела «Реализация»Успех ORPO сильно зависит от качества данных о предпочтениях. Обучающие данные должны следовать чётким инструкциям разметки и равномерно представлять предпочтённые и отвергнутые ответы в разных ситуациях.
Реализация в TRL
Заголовок раздела «Реализация в TRL»ORPO можно реализовать с помощью библиотеки TRL (Transformers Reinforcement Learning). Вот простой пример:
from trl import ORPOConfig, ORPOTrainer
# Настраиваем обучение ORPOorpo_config = ORPOConfig( learning_rate=1e-5, per_device_train_batch_size=4, gradient_accumulation_steps=4, max_steps=1000, orpo_alpha=1.0, # сила оптимизации предпочтений orpo_beta=0.1, # параметр «температуры» для отношения шансов)
# Создаём тренерtrainer = ORPOTrainer( model=model, args=orpo_config, train_dataset=dataset, tokenizer=tokenizer,)
# Запускаем обучениеtrainer.train()На что обратить внимание:
orpo_alpha— управляет силой оптимизации предпочтений;orpo_beta— параметр «температуры» при вычислении отношения шансов;learning_rate— должна быть довольно маленькой, чтобы не было катастрофического забывания;gradient_accumulation_steps— помогает стабильности обучения.
Что дальше
Заголовок раздела «Что дальше»⏩ Попробуйте учебник по ORPO, чтобы реализовать этот единый подход к выравниванию по предпочтениям.
Материалы
Заголовок раздела «Материалы»Словарик
Заголовок раздела «Словарик»| English | Русский |
|---|---|
| preference alignment | выравнивание по предпочтениям |
| Direct Preference Optimization (DPO) | прямая оптимизация предпочтений |
| chosen / rejected response | предпочтённый (выбранный) / отвергнутый ответ |
| reference model | эталонная (референсная) модель |
| implicit / explicit prompt | неявный / явный промпт |
| implicit reward, reward margin | неявная награда, отрыв наград |
| catastrophic forgetting | катастрофическое забывание |
| distribution shift | сдвиг распределения |
| leaderboard, submission | лидерборд, отправка результата |
| odds, odds ratio (ORPO) | шансы, отношение шансов |
| Hugging Face Jobs | облачные задания Hugging Face (платная услуга) |