The Jerusalem PostFormer Yisrael Beytenu MK Esterina Tartman dies at 68ESPN DeportesMessi domina el presente y el futuro del futbol en Estados UnidosESPNWhat does the future hold for Knicks, Spurs, Thunder and every NBA team? We stacked all 30Daily Maverick‘LIFE’S A GLITCH’: ANC to ‘exercise its legal rights’ after Electoral Court dismisses candidate list casePunchBolt sees 92% spike in Nigerian driver registrations after Uber exitוואלהמשאית פגעה בכבל מתח גבוה באזור בית שמש; הפסקות חשמל בכמה יישוביםBollywood HungamaVijay Varma announces Matka King season 2 with first episode script: "Ek aur baazi"RTP DesportoVasco chega às `meias` da Sul-Americana após 15 anosDeadline‘Spring Awakening’ Revival Sets Principal Cast Including ‘John Proctor Is The Villain’s Amalia YooIl Fatto QuotidianoIl Tottenham di De Zerbi perde ancora, Dugarry lo demolisce: “Sta facendo una rapina. È fuori di testa, nessuno gli dice di stare zitto”VanguardWike should meet APC governors, explain his Rainbow Coalition — Joe Igbokwe
The Daily Newsstand · Free, Always
Wednesday, September 16, 2026

[Перевод] Создание моделей, способных к рассуждению, с помощью дообучения GRPO

Translate

Модели вроде DeepSeek показали, что способность к последовательному рассуждению можно заметно улучшить на этапе дополнительного обучения. Если задача состоит в том, чтобы получить похожее поведение от локальной LLM, один из вариантов - Group Relative Policy Optimization, или GRPO.

В отличие от Supervised Fine-Tuning, где модель в основном учится воспроизводить шаблоны из обучающих примеров, GRPO использует обучение с подкреплением. В этом случае модель получает сигнал о качестве сгенерированных ответов и постепенно увеличивает вероятность более удачных вариантов.

Разберём, как GRPO связан с современными подходами RLHF и что происходит во время такого обучения.

RLHF, PPO, GRPO и DPO

RLHF (Reinforcement Learning from Human Feedback) сегодня часто используют, как общее обозначение методов, в которых поведение модели корректируется с помощью обратной связи.

PPO, GRPO и DPO решают похожую задачу разными способами: модель должна чаще генерировать ответы, соответствующие заданному критерию качества или человеческим предпочтениям.

Если сильно упростить:

  • RLHF - общий подход к обучению модели с использованием обратной связи.

  • PPO - более ранний и ресурсоёмкий вариант, обычно использующий отдельную value model.

  • GRPO - подход без отдельного critic, где baseline вычисляется по группе ответов.

  • DPO - метод, который обучается непосредственно на парах предпочтительных и непредпочтительных ответов.

Основа обучения с подкреплением

В классическом Reinforcement Learning взаимодействие можно представить так:

State (s) → Action (a) → Environment → Reward (r) → Next State (s')

В случае RLHF агентом становится языковая модель.

При использовании PPO обычно присутствуют несколько компонентов:

  1. Generating Policy - текущая обучаемая модель.

  2. Reference Policy - зафиксированная версия исходной модели.

  3. Value Model - модель, оценивающая ожидаемую награду.

Отдельная reward model может использоваться для вычисления награды за сгенерированный ответ. Задача обучения - изменить параметры policy так, чтобы ожидаемая награда росла.

PPO и GRPO в сравнении

PPO и GRPO в сравнении

PPO использует Actor-Critic-подход. Actor - сама LLM, генерирующая ответы. Critic, или Value Network, оценивает ожидаемую награду, наличие дополнительной сети увеличивает требования к памяти и вычислениям.

GRPO не использует отдельный critic. Вместо предсказания baseline модель генерирует несколько ответов на один и тот же prompt. Каждый ответ получает reward, после чего результаты сравниваются внутри группы.

За счёт этого ожидаемое качество ответа можно оценивать относительно других ответов на тот же вопрос без отдельной Value Network.

GRPO был представлен DeepSeek в работе DeepSeekMath в 2024 году, а позднее этот подход использовался при обучении DeepSeek-R1.

Что происходит внутри GRPO

Основную логику GRPO можно разобрать через несколько выражений.

1. Коэффициент политики

Пусть :

[
r_i(\theta)=\frac{\pi_\theta(y_i|x)}
{\pi_{\theta_{\text{old}}}(y_i|x)}
]

Здесь :

  • (\pi_\theta(y_i|x)) - вероятность ответа "y_i" при текущих параметрах модели.

  • (\pi_{\theta_{\text{old}}}(y_i|x)) - вероятность того же ответа до текущего обновления.

Коэффициент политики показывает, насколько изменилась вероятность конкретного ответа.

Если :

[
r_i(\theta)>1,
]

текущая модель считает этот ответ более вероятным, чем предыдущая версия.

При :

[
r_i(\theta)<1
]

его вероятность уменьшилась.

Если отношение равно единице, текущий шаг обучения не изменил вероятность ответа.

Это важно из-за того, что прямое увеличение вероятности всех ответов с высокой наградой может привести к слишком резкому изменению policy. PPO и GRPO ограничивают величину обновления с помощью clipping.

То есть модель не должна за один шаг слишком сильно изменить распределение вероятностей только потому, что конкретный ответ получил высокий reward.

2. Средняя награда

Для ясности обозначим награду отдельного ответа как "R_i":

[
\mu=\frac{1}{G}\sum_{i=1}^{G}R_i
]

Здесь "G" - количество ответов, сгенерированных на один prompt.

Предположим, модель получила одну математическую задачу и сгенерировала пять решений. После оценки у них могут быть такие reward:

[
1.0,;0.5,;0,;1.0,;0.5
]

Среднее значение показывает качество группы ответов на конкретный prompt.

Именно здесь находится одно из основных отличий GRPO от PPO.

В PPO ожидаемый reward оценивает critic. В GRPO несколько ответов уже были сгенерированы и оценены, поэтому baseline можно получить непосредственно из этих результатов.

Отдельно обучать сеть для его предсказания не требуется.

3. Стандартное отклонение наград

Среднее значение само по себе не показывает, насколько сильно ответы отличаются друг от друга. Для этого используется стандартное отклонение:

[
\sigma=
\sqrt{
\frac{1}{G}
\sum_{i=1}^{G}
(R_i-\mu)^2
}
]

Если "\sigma" велико, rewards внутри группы сильно отличаются. Одни ответы получили высокую оценку, другие низкую.

При небольшом "\sigma" результаты находятся близко друг к другу.

Например:

  • набор 90, 10, 95, 5, 88 имеет большой разброс,

  • набор 58, 56, 60, 57, 59 - небольшой.

В GRPO стандартное отклонение используется для нормализации advantage. Благодаря этому абсолютный масштаб reward меньше влияет на дальнейшее обновление policy.

4. Групповое относительное преимущество

Для каждого ответа рассчитывается относительный advantage:

[
A_i=\frac{R_i-\mu}{\sigma}
]

Он показывает положение конкретного ответа относительно остальных ответов в той же группе.

Если reward выше среднего, "A_i" положителен. Если ниже - отрицателен.

Допустим, средний результат группы равен 40, а отдельный ответ получил 60. Для GRPO важно не только абсолютное значение 60, но и то, насколько оно выше результатов других генераций для того же prompt.

Такой подход даёт несколько свойств:

  1. Отдельный critic не нужен: baseline получается из самой группы.

  2. Абсолютный масштаб reward становится менее важен. Если система оценки систематически выдаёт более высокие или низкие числа, нормализация внутри группы частично компенсирует этот эффект.

  3. ответы для разных prompts можно сравнивать через нормализованный advantage, даже если сами распределения наград отличаются.

5. Штраф за дивергенцию Кульбака

Во время обучения недостаточно просто увеличивать вероятность ответов с высоким reward. Если policy слишком сильно отклонится от исходной модели, часть исходных возможностей может ухудшиться.

Для ограничения этого отклонения используется KL divergence относительно reference policy.

В исходном варианте формула приведена в следующем виде:

\frac{\pi_{ref}}{\pi_\theta}

\ln\left(
\frac{\pi_{ref}}{\pi_\theta}
\right)
-1
]

Здесь:

  • "\pi_\theta" - текущая обучаемая policy.

  • "\pi_{ref}" - зафиксированная reference model.

Небольшое значение означает, что распределение текущей модели остаётся близким к исходному, большое - что policy заметно изменилась.

Это особенно важно из-за несовершенства reward-функций. Если существует простой способ получить большую награду, не решая исходную задачу лучше, модель может начать эксплуатировать эту особенность.

KL penalty ограничивает такие изменения, удерживая обучаемую policy рядом с reference model.

На практике соответствующий член добавляется в loss с небольшим коэффициентом, например 0.01 или 0.04.

Полный цикл GRPO

Один шаг обучения можно представить следующим образом:

  1. Для одного prompt генерируется группа ответов.

  2. Каждый ответ получает reward.

  3. Для группы рассчитываются среднее "\mu" и стандартное отклонение "\sigma".

  4. Для каждого ответа вычисляется относительный advantage.

  5. Сравниваются вероятности ответа при текущей и предыдущей policy.

  6. Слишком большие изменения ограничиваются clipping.

  7. Добавляется штраф за отклонение от reference policy.

  8. Параметры модели обновляются так, чтобы ответы с положительным relative advantage становились вероятнее.

В результате обучение зависит не только от того, получил ли конкретный ответ высокий reward, но и от того, насколько хорошо он выглядит по сравнению с другими генерациями той же модели для той же задачи.

От формул к trainer.train()

Теперь можно перейти к примеру реализации.

Сначала загружается модель и подключаются LoRA-адаптеры:

from unsloth import FastLanguageModel from datasets import load_dataset import re # 1. Load 4-bit model with vLLM backend for fast group generation model, tokenizer = FastLanguageModel.from_pretrained( model_name="unsloth/Llama-3.2-3B-Instruct", max_seq_length=1024, load_in_4bit=True, fast_inference=True, max_lora_rank=32, gpu_memory_utilization=0.6, ) # 2. Attach LoRA adapters model = FastLanguageModel.get_peft_model( model, r=32, target_modules=["q_proj","k_proj","v_proj","o_proj","gate_proj","up_proj","down_proj"], lora_alpha=64, use_gradient_checkpointing="unsloth", ) # 3. Enforcing reasoning format - GRPO needs structure to reward SYSTEM_PROMPT = "Respond in the following format:\n<reasoning>\n...\n</reasoning>\n<answer>\n...\n</answer>" # 4. Load GSM8K and wrap prompts dataset = load_dataset("openai/gsm8k", "main")["train"] dataset = dataset.map(lambda x: { "prompt": [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": x["question"]} ], "answer": x["answer"].split("####")[1].strip() })

В примере используется Llama-3.2-3B-Instruct в 4-битном формате. Для параметроэффективного дообучения подключаются LoRA-адаптеры к основным projection-слоям трансформера.

В system prompt задаётся фиксированная структура ответа:

<reasoning>
...
</reasoning>
<answer>
...
</answer>

Для обучения используется GSM8K. Из каждого элемента датасета формируется prompt, а эталонный ответ извлекается из поля answer.

Reward-функции

Reward-функции определяют, какое поведение GRPO будет усиливать. Если система оценки построена неудачно, модель может научиться максимизировать reward, не улучшая решение исходной задачи, поэтому здесь используется несколько сигналов одновременно. Их значения складываются и формируют итоговый reward "R_i", который затем участвует в вычислении advantage.

correctness_reward

Основной сигнал качества.

Функция извлекает содержимое тега <answer> и сравнивает его с эталонным ответом. При полном совпадении модель получает +2.0, иначе - 0.0.

Больший вес нужен для того, чтобы правильность ответа оставалась основным критерием.

int_reward

Дополнительный сигнал на ранних этапах обучения.

Если модель ещё часто ошибается, бинарный correctness_reward может почти всегда возвращать ноль. int_reward выдаёт +0.5, если в <answer> содержится корректно сформированное целое число.

Это обеспечивает ненулевой обучающий сигнал даже для неправильных ответов.

soft_format_reward и strict_format_reward

Обе функции проверяют структуру:

<reasoning>...</reasoning>
<answer>...</answer>

soft_format_reward допускает более свободное форматирование.

strict_format_reward требует точного расположения тегов и переводов строк.

Каждая функция может добавить +0.5.

xmlcount_reward

Эта функция отдельно проверяет наличие XML-тегов и правильность их расположения. За каждый корректно расположенный элемент добавляется 0.125. Если после закрывающего тега остаётся лишний текст или теги дублируются, reward уменьшается.

Вместе эти функции создают несколько сигналов: правильность ответа имеет наибольший вес, формат задаёт необходимую структуру, а дополнительные проверки постепенно приучают модель соблюдать её точнее.

Код выглядит так:

def extract_xml_answer(text: str) -> str:
    return text.split("<answer>")[-1].split("</answer>")[0].strip()

# Primary signal: is the final answer correct?
def correctness_reward(prompts, completions, answer, **kwargs):
    responses = [c[0]["content"] for c in completions]
    extracted = [extract_xml_answer(r) for r in responses]
    return [2.0 if r == a else 0.0 for r, a in zip(extracted, answer)]

# Dense shaping rewards - keep learning signal alive even when answers are wrong
def int_reward(completions, **kwargs):
    return [0.5 if extract_xml_answer(c[0]["content"]).isdigit() else 0.0 for c in completions]

def strict_format_reward(completions, **kwargs):
    pattern = r"^<reasoning>\n.*?\n</reasoning>\n<answer>\n.*?\n</answer>\n$"
    return [0.5 if re.match(pattern, c[0]["content"]) else 0.0 for c in completions]

def soft_format_reward(completions, **kwargs):
    pattern = r"<reasoning>.*?</reasoning>\s*<answer>.*?</answer>"
    return [0.5 if re.match(pattern, c[0]["content"]) else 0.0 for c in completions]

def xmlcount_reward(completions, **kwargs):
    def score(text):
        count = 0.0
        if text.count("<reasoning>\n") == 1: count += 0.125
        if text.count("\n</reasoning>\n") == 1: count += 0.125
        if text.count("\n<answer>\n") == 1:
            count += 0.125
            count -= len(text.split("\n</answer>\n")[-1]) * 0.001
        if text.count("\n</answer>") == 1:
            count += 0.125
            count -= (len(text.split("\n</answer>")[-1]) - 1) * 0.001
        return count
    return [score(c[0]["content"]) for c in completions]

Суммарный результат этих функций становится raw reward для конкретной генерации.

GRPOTrainer

После определения reward-функций можно настроить сам trainer:

from trl import GRPOConfig, GRPOTrainer

trainer = GRPOTrainer(
    model=model,
    processing_class=tokenizer,
    reward_funcs=[
        xmlcount_reward,      # tag quality
        soft_format_reward,   # structure (forgiving)
        strict_format_reward, # structure (exact)
        int_reward,           # partial credit
        correctness_reward,   # ground-truth match
    ],
    args=GRPOConfig(
        learning_rate=5e-6,
        per_device_train_batch_size=1,
        gradient_accumulation_steps=1,
        num_generations=8,          # G = group size
        max_prompt_length=256,
        max_completion_length=200,
        max_steps=250,
        warmup_ratio=0.1,
        max_grad_norm=0.1,
        output_dir="outputs",
    ),
    train_dataset=dataset,
)

trainer.train()

Здесь num_generations=8 означает, что для каждого prompt модель генерирует восемь вариантов ответа. Именно они образуют группу, относительно которой затем рассчитывается advantage.

На каждом шаге GRPOTrainer генерирует ответы, вызывает reward-функции, вычисляет относительные оценки и обновляет policy.

Почему DPO хуже подходит для такой схемы

DPO решает задачу иначе. Вместо полноценного цикла reinforcement learning он получает prompt и пару ответов, после чего обучается увеличивать вероятность предпочтительного варианта относительно второго. Такой подход хорошо работает, когда есть качественные preference pairs.

Для задач с рассуждением возникает другое ограничение: DPO учится только на тех вариантах ответа, которые уже присутствуют в обучающих данных.

Предположим, требуется доказать геометрическую теорему. Для DPO нужно иметь как минимум два решения и знать, какое из них предпочтительнее. Если оба неправильные или нужный способ решения вообще не попал в датасет, сама пара не содержит нового корректного пути.

GRPO во время обучения генерирует несколько вариантов для одного prompt и оценивает каждый из них, поэтому удачно найденный вариант может получить более высокий reward и увеличить свою вероятность даже в том случае, если именно такой ход рассуждения заранее не был записан человеком в preference dataset. За это приходится платить дополнительными вычислениями: на каждом шаге требуется несколько генераций.

В упрощённом виде различие можно сформулировать так: DPO обучается на уже подготовленных предпочтениях, а GRPO во время обучения исследует несколько собственных генераций и сравнивает их между собой.

Итог

GRPO обучает модель увеличивать вероятность ответов, которые оказываются лучше других её ответов на тот же prompt.

Главное отличие от PPO состоит в отказе от отдельного critic: baseline для вычисления advantage получается из группы генераций. Это уменьшает количество компонентов, необходимых во время обучения. Reward-функции при этом определяют, какое именно поведение будет усиливаться. В приведённом примере отдельно оцениваются правильность ответа, его тип и соблюдение заданной структуры.

Такая схема позволяет дообучать локальную LLM с использованием reinforcement learning и групповой оценки генераций, не добавляя отдельную Value Network.

Чтобы не тратить время на ежедневный мониторинг десятков AI-релизов, я делаю это за вас: тестирую новые модели и обновления и публикую в ДругОпенсурса только то, что действительно стоит внимания. Там же короткие выводы из тестов и мои наблюдения о том, что реально полезно в работе.

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.