От базовой модели к ассистенту: SFT, RLHF, DPO и GRPO
Базовая модель продолжает текст, а не отвечает. Как SFT, RLHF, DPO и GRPO превращают предиктор token в ассистента.
На этой странице
Попросите GPT-2 — компетентно предобученную языковую модель — написать хайку о море:
prompt: Write a haiku about the sea.
The sea is a beautiful place.
The sea is a beautiful place.
The sea is a beautiful place.
The sea is a beautiful place.
The sea is a beautiful place.Она не запуталась и не провалила задачу. Она делает ровно то, чему её обучила глава 10: по заданному тексту производить правдоподобное продолжение. В интернете за строкой вроде Write a haiku about the sea. часто следует проза о море, а предложение, которое только что появилось, с необычно высокой вероятностью появится снова. Модель — превосходный предиктор следующего token и бесполезный ассистент.
Теперь тот же запрос к модели, построенной тем же способом, — Qwen2.5, полмиллиарда параметров, в четыре раза больше GPT-2 выше и всё ещё крошечной по любым меркам 2026 года, — после этапов обучения, о которых эта глава:
Whispers of the ocean,
Silent depths where waves meet,
Mysteries in the vast blue.В четыре раза больше параметров не учат модель замолкать. Разрыв между этими двумя выводами — не масштаб, не архитектура и не объём данных. Это post-training: вторая фаза, на порядки меньшая, чем pretraining, которая берёт предиктор текста и превращает его во что-то, что отвечает.
Этап первый: показать, как выглядит ответ
Ссылка на раздел: Этап первый: показать, как выглядит ответПервый шаг наименее эффектен и делает большую часть работы. Соберите примеры инструкций в паре с хорошими ответами и продолжайте обучение на них ровно с той же функцией потерь из главы 8 — предсказывать следующий token, — но только на части с ответом. Это supervised fine-tuning, или SFT.
Модель не учат ничему новому о языке. Её учат формату: за текстом такой формы следует текст такой формы, а затем он останавливается. Ещё раз посмотрите на сбой базовой модели. Она ответила на вопрос в первом предложении, а потом не смогла остановиться, потому что в её обучении ничто не отмечало конец ответа. Остановка — выученное поведение.
Именно поэтому модели также нужно указать, где находятся границы. Для этого и нужен chat template:
<|im_start|>system
You are Qwen, created by Alibaba Cloud. You are a helpful assistant.<|im_end|>
<|im_start|>user
What is the capital of France?<|im_end|>
<|im_start|>assistantЭти маркеры <|im_start|> и <|im_end|> — реальные tokens в словаре, добавленные перед fine-tuning, и модель видела миллионы таких markers ровно в этих позициях. Так она понимает, чей сейчас ход и где ход заканчивается.
Пропустите template и передайте модели голый вопрос — и вы даёте ей последовательность, которой она не видела при обучении. Измерено: та же модель, тот же вопрос, тот же greedy decoding:
Без template — сырая строка What is the capital of France?:
The capital of France is Paris.
To verify this, I will use a simple
Python code snippet to confirm that
Paris is indeed the capital city of
France.
[...and then it starts writing a
Python script to check its own answer]С template:
The capital of France is Paris.Ответ верный в обоих случаях, но без маркеров модель начинает писать Python, чтобы проверить себя, потому что полученный prompt не похож ни на что из того, на чём её fine-tuned. Это самая частая причина фразы «модель стала глупее, когда я вызвал её напрямую»: template — не украшение вокруг модели, это часть модели, а неправильный template — тихая деградация без какой-либо ошибки.
Этап второй и проблема, которую он решает
Ссылка на раздел: Этап второй и проблема, которую он решаетУ SFT есть потолок, и этот потолок — данные. Чтобы fine-tune на демонстрации, нужен кто-то, кто напишет идеальный ответ, — а для большинства интересных вопросов хороший ответ писать трудно, долго, дорого, и в итоге получается ровно один ответ, качество которого вы не можете проверить.
В чём люди сильны, так это в сравнении. Увидев два ответа, аннотатор за несколько секунд надёжно скажет, какой лучше, даже если не смог бы написать ни один из них. На этом факте построен весь второй этап, и именно эту часть большинство объяснений переворачивает с ног на голову:
Люди не пишут ответы. Они ранжируют пары.
Значит, данные — это пары: prompt, два ответа и указание, какой победил. Это нельзя подставить в next-token loss, потому что целевой последовательности нет. Нужна другая машина.
Reward model и чему она на самом деле учится
Ссылка на раздел: Reward model и чему она на самом деле учитсяНельзя просить человека оценивать каждый ответ во время обучения — это миллионы суждений. Поэтому вы обучаете модель имитировать людей: reward model, которая принимает ответ и возвращает скаляр.
Обучение на сравнениях использует результат 1952 года. Модель Bradley–Terry2 говорит: если у двух объектов есть скрытые силы, вероятность того, что один победит другой, равна логистической функции от их разности. Разверните это, и получится loss: если человек предпочёл вместо , максимизируйте
что в коде и есть весь цикл обучения:
loss = -F.logsigmoid(reward(chosen) - reward(rejected)).mean() Обратите внимание, чего модель никогда не видит: абсолютной оценки. Она учит только различия — ровно то, что содержится в данных.
Теперь часть, которую стоит измерить. Reward model учится тому, что вознаграждали аннотаторы, а аннотаторы — люди. Вот симуляция, где истинное качество ответа зависит только от полезности и правильности — длина не стоит ничего, — но у симулированного аннотатора есть лёгкое предпочтение более длинных ответов, когда всё остальное близко; это хорошо задокументированное человеческое смещение. Обучите reward model на 2000 сравнениях и прочитайте её веса:
| смещение аннотатора к длине | выученный вес на полезность | на правильность | на длину |
|---|---|---|---|
| 0.0 | +1.00 | +1.00 | +0.01 |
| 0.3 | +0.98 | +1.00 | +0.15 |
| 0.6 | +0.97 | +1.00 | +0.27 |
| 1.2 | +1.00 | +0.99 | +0.59 |
Reward model работает идеально. Она добросовестно выучила предпочтения, которые ей показали, — включая ту их часть, которая не имеет отношения к качеству. Reward model — не мера хорошего; это мера того, что выбрали аннотаторы, и каждое смещение в пуле разметки теперь стало коэффициентом в дифференцируемой функции, которую гораздо более крупная модель вот-вот начнёт оптимизировать.
Reward hacking, измеренный
Ссылка на раздел: Reward hacking, измеренныйИ это приводит нас к тому, что происходит при оптимизации. Дайте policy фиксированный бюджет усилий, который нужно распределить между свойствами ответа, с реалистичной асимметрией: быть полезным и правильным дорого, а быть длиннее дёшево — нужно просто продолжать писать.
Reward на единицу усилия для модели, обученной выше: полезность 8.26, правильность 8.31, длина 31.70. Длина окупается почти в четыре раза лучше правильности — не потому, что reward model сломана, а потому, что это дёшево.
Оптимизируйте по этому reward и смотрите на оба числа:
| оценка reward model | истинное качество | произведённая длина | |
|---|---|---|---|
| starting policy | 12.588 | 0.974 | 3.365 |
| после оптимизации | 31.696 | 0.000 | 12.497 |
Reward вырос в 2,5 раза. То, что reward должен был измерять, ушло в ноль. Policy обнаружила, что может получать огромные баллы, если писать много и не говорить ничего, и никакая часть обучающего цикла не могла это заметить, потому что reward model и есть определение хорошего внутри цикла.
Это reward hacking, и если вы когда-нибудь задавались вопросом, почему chat models такие многословные, эта таблица — значительная часть ответа.
Что на самом деле даёт KL-штраф
Ссылка на раздел: Что на самом деле даёт KL-штрафСтандартная защита — штрафовать policy за слишком большое отклонение от начальной точки, измеряя расстояние KL-дивергенцией из главы 4:
Reference — это SFT-модель, policy до reinforcement-этапа. Утверждается, что это не даёт модели уйти в дегенеративное поведение. Давайте выясним, сколько в этом утверждении остаётся после измерения. Та же постановка, перебор :
| reward | истинное качество | длина | KL | |
|---|---|---|---|---|
| 0 | 31.699 | 0.000 | 12.498 | 2.994 |
| 1 | 31.697 | 0.000 | 12.497 | 2.993 |
| 5 | 28.318 | 0.285 | 10.700 | 2.163 |
| 15 | 12.860 | 1.542 | 2.552 | 0.151 |
| 30 | 10.426 | 1.719 | 1.303 | 0.025 |
| 60 | 9.632 | 1.769 | 0.908 | 0.005 |
| только reference model | 9.162 | 1.791 | 0.687 | 0 |
Читайте последнюю строку относительно остальных. При и штраф вообще ничего не делает: reward стоит настолько больше, чем KL, что optimiser платит штраф и всё равно взламывает метрику. Между 5 и 15 поведение резко меняется. А при истинное качество поднимается обратно до 1.769 — что всё ещё ниже 1.791, которые были у reference model до того, как всё это началось.
Одна оговорка, прежде чем кто-то где-то процитирует это число: 1.791 в последней строке и 0.974, которые первая таблица даёт starting policy, — это два разных измерения одной и той же pre-RL модели, сделанные отдельно в двух экспериментах. Сравнивайте строки внутри таблицы, никогда между таблицами: вывод каждой таблицы держится на её собственных строках, и ни один не зависит от baseline другой.
Так что честное резюме — не «KL-штраф предотвращает reward hacking». Оно такое:
KL-штраф не предотвращает reward hacking. Он ограничивает, насколько далеко policy может отойти от reference, — а поскольку для сбоя нужно движение, это помогает. Но это поводок, а не исправление: при низком поводок рвётся, а при высоком вы получаете обратно reference model, и весь дорогой этап не купил ничего.
Полезная полоса узкая, её положение зависит от reward model, и найти её можно только наблюдением. Поэтому reference model должна быть хорошей: KL — это пол на уровне качества reference, а не потолок для сбоя. И это большая часть причины, по которой этот этап труден на практике, а не в принципе.
PPO и почему DPO его вытеснил
Ссылка на раздел: PPO и почему DPO его вытеснилАлгоритм, благодаря которому это заработало в масштабе, — Proximal Policy Optimization.3 В одном абзаце: он оценивает advantage каждого ответа, обновляет policy, чтобы повысить вероятность ответов выше baseline, и clipping размера каждого отдельного обновления, чтобы большая оценка advantage не разрушила policy за один шаг. В применении к языковым моделям4 это означает держать в игре сразу четыре модели — policy, reference, reward model и critic, — причём policy генерирует свежие samples на протяжении всего обучения.
Он работает, он породил InstructGPT и всё, что от него произошло, и он действительно сложен: четыре модели в памяти, sampling в обучающем цикле и заслуженная репутация нестабильности. Делать вид, что его можно реализовать в blog post, было бы нечестно, поэтому эта глава этого не делает.
То, что заменило его для большинства целей, возникло из одного наблюдения. У KL-регуляризованной цели выше есть оптимальная policy в closed form, и это выражение можно обратить: reward можно записать через оптимальную policy и reference. Если подставить это обратно в loss Bradley–Terry, reward model полностью исчезает. Остаётся supervised loss на preference pairs — без sampling, без critic, без reward model, две модели в памяти вместо четырёх.
Это Direct Preference Optimization,5 и это две строки:
def dpo_loss(pi_w, pi_l, ref_w, ref_l, beta=0.1):
"""pi_* and ref_* are summed log-probabilities of a full response."""
logits = beta * ((pi_w - ref_w) - (pi_l - ref_l))
return -F.logsigmoid(logits) Прочитайте, что они говорят. Вверх проталкивается величина, показывающая, насколько сильнее policy предпочитает победителя, чем это делала reference, минус насколько сильнее она предпочитает проигравшего. Reference — не штраф, прикрученный потом; она находится внутри loss, поэтому DPO не нужен отдельный KL-член.
Самое важное свойство — в gradient. Посчитайте loss и его gradient на одной и той же паре в пяти разных состояниях policy:
| состояние policy | loss | величина gradient |
|---|---|---|
| уже сильно предпочитает победителя | 0.5130 | 0.0401 |
| уже предпочитает его, слабо | 0.6685 | 0.0488 |
| идентична reference | 0.6931 | 0.0500 |
| предпочитает проигравшего | 0.7981 | 0.0550 |
| сильно предпочитает проигравшего | 1.0055 | 0.0634 |
Gradient растёт по мере того, как policy ошибается сильнее. Пары, с которыми модель уже справляется, почти ничего не вносят; пары, которые она переворачивает наоборот, доминируют в обновлении. DPO взвешивает каждый пример по тому, насколько policy сейчас ошибается, автоматически, без расписания — и это самовзвешивание является механизмом, который выполняет работу, раньше выполнявшуюся оценкой advantage и critic в PPO. (Loss в третьей строке равен ровно — это якорь для проверки любой реализации: policy, идентичная своей reference, ничему не научилась и должна сидеть на .)
GRPO6 выбирает другой выход из той же проблемы. Он сохраняет цикл sampling, но удаляет critic: вместо обучения модели предсказывать baseline он сэмплирует группу ответов на один и тот же prompt и напрямую использует средний reward группы как baseline. Advantage ответа — это то, насколько он лучше своих соседей. Это меняет целую модель на больший batch, и именно это сделало практичным обучение на проверяемых rewards — тему главы 12.
Показать детали
Ещё три элемента ландшафта post-training, кратко.
RLAIF и Constitutional AI.7 Аннотатор не обязан быть человеком. Дайте модели письменный набор принципов и попросите её критиковать и исправлять собственные выводы или выбирать между двумя кандидатами — и вы получите preference dataset со скоростью и стоимостью машины. Очевидное возражение — модель проверяет собственную домашнюю работу — реально, а честный ответ в том, что это работает лучше, чем звучит, потому что судить проще, чем генерировать; на той же асимметрии держится вся глава.
LIMA и как мало данных для этого нужно.8 Тысяча тщательно отобранных демонстраций дала конкурентоспособного ассистента. Предложенное объяснение: pretraining уже установил знания и формат, а post-training должен лишь выбрать, какие из существующих поведений модели вывести на поверхность. Если это верно, качество данных для post-training важнее количества — и поведение области с тех пор показывает, что люди в это верят.
LoRA и QLoRA.910 Fine-tuning каждого веса большой модели требует памяти для весов, их gradients и состояния optimiser — шестнадцать байт на параметр из главы 10, поверх двух средних, которые глава 6 собрала вручную, — в масштабе, где нужен кластер. LoRA замораживает исходные веса и обучает рядом с ними пару низкоранговых матриц, сокращая число обучаемых параметров на порядки; QLoRA дополнительно quantizes замороженную базу до 4 бит. Обе рассматриваются здесь как technique. Стоит ли вообще тратить деньги на fine-tuning — другой вопрос, и он принадлежит главе 20.
Налог на alignment и вопрос, на который никто не ответил
Ссылка на раздел: Налог на alignment и вопрос, на который никто не ответилДве мысли, которые нужно унести дальше.
Первая: у этого этапа есть стоимость, и она проявляется как способность. Модели часто измеримо хуже справляются с некоторыми benchmark tasks после alignment training — это alignment tax, — потому что цель изменилась: безопасный, оговоренный и хорошо отформатированный ответ не всегда является ответом, максимизирующим точность. Часть этого разрыва удалось инженерно убрать, а часть — реальный trade-off, а не баг, который нужно исправить.
Вторая — вопрос, который скрывает слово aligned. С кем aligned? Цепочка такова: компания пишет guidelines, подрядчики их интерпретируют, их сравнения обучают reward model, reward model формирует policy, а policy отвечает на вопрос человека, который ничего из этого не видел. Каждое звено — выбор конкретных людей, и ни один алгоритм в этой главе не имеет собственного мнения о том, хороши ли эти выборы.
Это не риторический эффект. Это конкретная причина, по которой две frontier models отказывают на разные запросы, почему одна и та же модель меняет мнение между версиями, и почему «aligned» — описание процесса, а не свойство артефакта. Математика в этой главе устоялась. Эта часть — нет.
Куда дальше
Ссылка на раздел: Куда дальшеPost-training научил модель отвечать. Он не научил её думать перед ответом, а это две разные вещи — причём, как оказывается, вторую тоже можно обучать.
Глава 12 — о том, что происходит, когда вы позволяете модели тратить больше вычислений на сложный вопрос во время ответа, а не во время обучения: chain of thought, reinforcement learning from verifiable rewards и причина, по которой модель, показывающая ход решения, не просто объясняет себя, а вычисляет иначе. Там же закрывается долг этой главы: GRPO появляется в ней и выполняет работу, которую раньше делал critic в PPO, на rewards, которым вообще не нужен аннотатор, потому что доказательство либо проверяется, либо нет.
Источники и метод
Ссылка на раздел: Источники и методГенерации выше получены из gpt2 и Qwen/Qwen2.5-0.5B-Instruct с greedy decoding, поэтому воспроизводятся точно. Глава 11 Hugging Face LLM Course проходит SFT и DPO с trl и peft, если вы хотите запустить настоящий вариант, а не симуляцию; глава 7 книги Sebastian Raschka Build a Large Language Model (From Scratch) реализует instruction fine-tuning от начала до конца без библиотеки.
Сноски
Ссылка на раздел: Сноски-
Sutton, R. S. and Barto, A. G. Reinforcement Learning: An Introduction, 2nd edition (MIT Press, 2018). Делегирование намеренное: блок словаря выше — минимальный пригодный поднабор, а настоящая тема — это книга. ↩
-
Bradley, R. A. and Terry, M. E. Rank Analysis of Incomplete Block Designs: I. The Method of Paired Comparisons. Biometrika 39(3/4), pp. 324–345 (1952). Модель попарных сравнений, лежащая под каждой reward model, используемой сегодня. ↩
-
Schulman, J., Wolski, F., Dhariwal, P., Radford, A. and Klimov, O. Proximal Policy Optimization Algorithms. arXiv:1707.06347 (2017). ↩
-
Ouyang, L. et al. Training language models to follow instructions with human feedback. arXiv:2203.02155 (2022). InstructGPT — статья, сделавшая трёхэтапный рецепт стандартом. Ей предшествовали Christiano et al. (arXiv:1706.03741), где было введено обучение reward model на человеческих сравнениях, и Stiennon et al. (arXiv:2009.01325), применившие его к summarisation. ↩
-
Rafailov, R., Sharma, A., Mitchell, E., Ermon, S., Manning, C. D. and Finn, C. Direct Preference Optimization: Your Language Model is Secretly a Reward Model. arXiv:2305.18290 (2023). Вывод, убирающий reward model, находится в разделе 4 и заслуживает полного прочтения; он короче своей репутации. ↩
-
Shao, Z. et al. DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models. arXiv:2402.03300 (2024). Вводит GRPO в разделе 4.1. ↩
-
Bai, Y. et al. Constitutional AI: Harmlessness from AI Feedback. arXiv:2212.08073 (2022). ↩
-
Zhou, C. et al. LIMA: Less Is More for Alignment. arXiv:2305.11206 (2023). ↩
-
Hu, E. J. et al. LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685 (2021). ↩
-
Dettmers, T., Pagnoni, A., Holtzman, A. and Zettlemoyer, L. QLoRA: Efficient Finetuning of Quantized LLMs. arXiv:2305.14314 (2023). ↩