Image

Как настроить небольшие языковые модели для мышления с подкреплением

Визуальный тур и руководство «с нуля» по обучению моделей рассуждений GRPO в PyTorch

Делиться

Алгоритм GRPO

Модели рассуждений сейчас в моде. DeepSeek-R1, Gemini-2.5-Pro, модели O-серии от OpenAI, Claude, Magistral и Qwen3 от Anthropic — каждый месяц появляется новая. Когда вы задаёте этим моделям вопрос, они прокручивают цепочку мыслей, прежде чем сгенерировать ответ.

80552c2ce53e64fb60ce5ec890843d79

Недавно я задал себе вопрос: «Хм… Интересно, стоит ли мне написать цикл обучения с подкреплением с нуля, который научит этому „мыслительному“ поведению очень маленькие модели — всего 135 миллионов параметров?». Должно быть, это просто, правда?

Ну, это не так.

У малых моделей просто нет такого же знания мира, как у больших. Это лишает модели с параметрами менее 1B «здравого смысла», необходимого для легкого решения сложных логических задач. Следовательно, нельзя полагаться только на вычисления, чтобы обучить их мышлению.

Вам нужны дополнительные козыри в рукаве.

В этой статье я не буду просто рассказывать о приёмах. Я расскажу об основных идеях, лежащих в основе обучения рассуждениям в языковых моделях, поделюсь простыми фрагментами кода и практическими советами по тонкой настройке малых языковых моделей (МЯМ) с помощью RL.

Эта статья разделена на 5 разделов:

  1. Введение в RLVR (обучение с подкреплением и проверяемыми вознаграждениями) и почему это суперкруто
  2. Визуальный обзор алгоритма GRPO и усеченных суррогатных потерь PPO.
  3. Пошаговое руководство по коду!
  4. Контролируемая тонкая настройка и практические советы по тренировке моделей рассуждения
  5. Результаты!

Если не указано иное, все изображения, использованные в данной статье, являются иллюстрациями автора.

В конце статьи я приведу ссылку на 50-минутное видео на YouTube, посвящённое этой статье. Если у вас есть вопросы, в этом видео, вероятно, есть ответы/разъяснения. Вы также можете связаться со мной через X (@neural_avb).

1. Обучение с подкреплением и проверяемыми вознаграждениями (RLVR)

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

Групповая оптимизация относительной политики (GRPO) — это (довольно новый) метод обучения с подкреплением (RL), который исследователи используют для точной настройки больших языковых моделей (LLM) для решения логических и аналитических задач. С момента своего появления в исследовательской среде LLM появился новый термин: RLVR ( обучение с подкреплением и проверяемым вознаграждением ).

Чтобы понять уникальность RLVR, полезно сравнить её с наиболее распространённым применением RL в языковых моделях: RLHF ( Reinforcement Learning with Human Feedback). В RLHF модуль RL обучается максимизировать результаты, полученные с помощью отдельной модели вознаграждения, которая служит проксисервером для человеческих предпочтений. Эта модель вознаграждения обучается на наборе данных, в котором люди ранжируют или оценивают различные ответы модели.

Другими словами, RLHF обучается так, чтобы LLM могли выдавать ответы, более соответствующие человеческим предпочтениям. Он стремится заставить модели точнее следовать инструкциям.

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

В то время как в RLHF использовалась субъективная модель вознаграждения, в RLVR используется объективный верификатор. Основная идея заключается в том, чтобы предоставлять вознаграждения, основанные на доказуемой правильности ответа, а не на прогнозе предпочтений человека.

24eb216439a7ad5821ac5370f870d61d

Именно поэтому эта система называется «обучение с поддающимися проверке наградами». Не на каждый вопрос можно легко проверить ответ. Особенно это касается открытых вопросов, таких как «Какой iPhone мне купить?» или «В какой колледж мне поступить?». Однако некоторые примеры использования легко вписываются в парадигму «поддающихся проверке наград», например, математика, логические задачи и написание кода. В разделе «Спортзал рассуждений» ниже мы рассмотрим, как именно можно моделировать эти задачи и как генерировать награды.

Но прежде вы можете спросить: какое место во всем этом занимает «рассуждение»?

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

Полный ответ языковой модели будет выглядеть примерно так:

Пользователь попросил меня посчитать количество букв «р» в слове «slubary». Давайте выполним кумулятивный подсчёт. s=0, t=0, r=1, a=0, w=0, b=0, e=0, r=2, r=3, y=4. Похоже, в слове «slubary» 3 буквы «р». Я заметил, что в слове «stomly» есть одна буква «р», а в слове «berry» — две. Поскольку 1+2=3, я более уверен, что там 3 буквы «р». 3

Эта структура позволяет нам легко извлечь только окончательный ответ и проверить его правильность. Проверяющий элемент — это единственный источник истины, и он может представлять собой простой фрагмент кода, который (буквально) подсчитывает буквы алфавита.

def count_alphabets(слово, буква): возвращает сумму([1 для l в слове, если l == буква]) вознаграждение = 1 если (lm_answer == count_alphabets(«клубника», «r») иначе -1

Мы будем вести учет опыта модели — её ответов и соответствующих вознаграждений, полученных от верификатора. Затем алгоритм обучения с подкреплением будет обучаться, стимулируя поведение, повышающее вероятность получения правильных окончательных ответов.

Последовательно поощряя правильные ответы и хорошее форматирование, мы увеличиваем вероятность появления маркеров рассуждения, которые приводят к правильным ответам.

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

f1b437d813dcb94761e8d018c7156c41

2. GRPO (оптимизация групповой политики)

Я пропущу здесь обычное введение в курс обучения с подкреплением (Reinforcement Learning 101). Я ожидаю, что большинство из вас, дочитавших до этого места, понимают основы обучения с подкреплением (RL). Есть агент, который наблюдает за состоянием окружающей среды и выполняет действие — среда вознаграждает агента в зависимости от того, насколько хорошо было выполнено действие. Агент сохраняет этот опыт и обучается выполнять более эффективные действия в будущем, что приводит к более высокому вознаграждению. Занятия по курсу RL 101 закончены.

Но как перенести парадигму RL на язык?

Давайте поговорим о выбранном нами алгоритме — оптимизации относительной групповой политики , чтобы понять, как он работает. GRPO работает в двух итеративно самоповторяющихся фазах: фазе сбора опыта, где языковая модель (LM) накапливает опыт в среде с текущими весами. И фазе обучения, где она использует собранные воспоминания для обновления своих весов с целью улучшения. После обучения она снова переходит к этапу сбора опыта с обновлёнными весами.

Коллекция опыта

Давайте теперь разберем каждый шаг на этапе сбора опыта.

  • Шаг 1: Окружающая среда — это чёрный ящик, который генерирует вопросы, связанные с логическими или математическими задачами. Мы обсудим это в следующем разделе, посвящённом библиотеке «Гимнастика рассуждений».
  • Шаг 2: Мы токенизируем входные вопросы в последовательность целочисленных токенов.
f1ebcf7c91511b76b11041c0c28c6c02
  • Шаг 3: «Агент» или «политика» — это текущий обучаемый SLM. Он отслеживает токенизированные вопросы среды и генерирует ответы. Ответ LLM преобразуется в текст и возвращается в среду. Среда вознаграждает за каждый ответ.
0c021fbd96c7defd4a4960960fbd4ffb
  • Шаг 4: На основе вознаграждений мы рассчитываем преимущество каждого ответа. В GRPO преимущество — это относительная ценность каждого ответа в группе. Важно отметить, что преимущества рассчитываются для каждой группы, то есть мы не стандартизируем вознаграждения для разных вопросов.
f7c2cbbbf2fac193922dd0e80b29dd86
  • Шаг 5: Исходный вопрос, логарифмические вероятности для каждого токена, сгенерированного LM, и преимущества накапливаются в буфере памяти.
  • Шаги 1–5 повторяются до тех пор, пока размер буфера не достигнет желаемого порога.
e7a4e89680f14d5bbf0aa32df793bed4

Фаза обучения

После завершения фазы сбора опыта наша цель — перейти к фазе обучения. Здесь мы изучим закономерности вознаграждения, наблюдаемые LLM, и используем RL для улучшения его весов. Вот как это работает:

  1. Случайным образом выберите мини-пакет воспоминаний. Помните, что каждое воспоминание уже содержало своё преимущество относительно группы (шаг 5 из этапа сбора опыта). Случайный выбор пар «вопрос-ответ» повышает надёжность обучения, поскольку градиенты рассчитываются как среднее значение разнообразного набора воспоминаний, что предотвращает переобучение по каждому отдельному вопросу.
  2. Для каждого мини-пакета мы хотим максимизировать этот член, следуя стандартной формуле PPO (Proximal Policy Optimization). Главное отличие GRPO заключается в том, что нам не нужна дополнительная модель вознаграждения или сеть создания ценности для расчёта преимуществ. Вместо этого GRPO выбирает несколько ответов на один и тот же вопрос, чтобы рассчитать относительное преимущество каждого ответа. Потребляемая память значительно сокращается, поскольку нам не нужно обучать эти дополнительные модели!
  3. Повторите вышеуказанные шаги.
b5a5d5f099e972216f9e76df70288c87

Что означает убыток PPO

Позвольте мне объяснить убыток PPO интуитивно понятно и пошагово. Убыток PPO выглядит следующим образом.

57d8c3b501c67750a844426a8f9aa371
  • Здесь pi_old — это нейронная сеть старой политики, которую мы использовали на этапе сбора данных.
  • π — это текущая обучаемая нейронная сеть политики. Поскольку веса π меняются после каждого обновления градиента, π и π_old не остаются неизменными на этапе обучения, отсюда и различие.
  • G — количество сгенерированных ответов на один вопрос. |o_i| — длина i-го ответа в группе. Таким образом, операция суммирования и нормализации вычисляет среднее значение по всем токенам по всем ответам. Что же вычисляется в результате? Это π/π_old * A_{it}. Что это значит?
d9ccea82d64f3be70fbc65d3fa904759
  • A_it — это преимущество t-го токена в i-м ответе. Помните, как мы вычисляли преимущество каждого ответа на шаге 5 во время сбора опыта? Самый простой способ назначить преимущество каждому токену — просто продублировать одно и то же преимущество для каждого токена. Это означает, что каждый токен в равной степени отвечает за генерацию правильного ответа.
  • Наконец, чему равно π(o_it | q, o_i < t)? Это означает, какова вероятность появления t-го токена в i-м ответе? То есть, насколько вероятным был этот токен на момент его генерации?
  • Коэффициент важности выборки переоценивает преимущества между текущей политикой обновления и старой политикой разведки.
  • Ограничение гарантирует, что обновления сети не станут слишком большими, а веса не будут слишком сильно отличаться от старой политики. Это повышает стабильность процесса обучения, поддерживая обновления модели близко к «области доверия» политики сбора данных.
8ffb006a97286362b8f4782548720213

Когда мы максимизируем цель PPO, мы фактически просим LLM увеличить логарифмическую вероятность токенов, которые привели к высокому преимуществу, одновременно уменьшая логарифмическую вероятность токенов, которые имели низкое преимущество.

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

Понимание убытка PPO на примере

Давайте пока забудем об отсечении и π_old и посмотрим, что означает максимизация 𝜋(𝑜_i) * A_i. Напоминаем, что эта часть уравнения означает просто «произведение вероятности i-го токена (o_i) и преимущества i-го токена (A_i)».

Допустим, в задании LLM сгенерировал две последовательности: «AB C» и «DE F», и получил преимущество +1 для первой и -1 для второй*. Допустим, у нас есть логарифмические вероятности для каждого из трёх токенов, как показано ниже.

* на самом деле, поскольку относительные групповые преимущества всегда имеют стандартное отклонение 1, правильные преимущества должны быть +0,707 и -0,707.

Обратите внимание, что происходит, когда вы умножаете преимущества A_it на текущее значение logprobs pi. А теперь подумайте, что значит максимизировать среднее значение этой матрицы-произведения.

70a62a98220f28d90261c94d9fd217ad

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

596dbf1aee7b7e2fbaaa44e5474ec9cf

Ниже представлен пример изменения логарифмических вероятностей после нескольких раундов обучения. Обратите внимание, как синяя линия приближается к нулю при высоком преимуществе? Это означает, что логарифмические вероятности увеличились (или вероятности увеличились) после прохождения обучения с обратным обучением. Сравните это с графиком справа, где показан другой ответ при низком преимуществе. Синяя линия удаляется от нуля, становясь менее вероятной для отбора в последующих раундах.

d2e698da5bed65eb5deccbd65f95a6e6

В следующем разделе давайте рассмотрим библиотеку «гимнастического зала рассуждений» и разберемся, как можно делать выборки задач.

3. Реализация

Итак, для обучения с подкреплением (RL) нам сначала нужны задачи. Обычно это делается с помощью существующего набора данных математических задач, например, GSM-8K. В этой статье рассмотрим другой случай — процедурную генерацию задач с помощью библиотеки Python Reasoning-Gym.

Для своих экспериментов я использовал две задачи: силлогизм и пропозициональную логику . Reasoning-gym содержит множество различных репозиториев разной степени сложности.

Задача на силлогизм — это тип логической головоломки, предназначенной для проверки дедуктивного мышления. По сути, мы предоставляем магистру права (LLM) две посылки и спрашиваем, верно ли заключение. Задача на пропозициональную логику — это задание на символическое рассуждение, где магистр права (LLM) получает задания с символами и должен сделать вывод. В отличие от силлогизма, это не классификационный ответ «ДА/НЕТ» — магистр должен сам сделать правильный вывод. Это значительно усложняет задачу.

79dab525e96ba5b56718fa76ed35c1e9

Прежде чем приступить к кодированию, я думаю, принято уточнять, что я подразумеваю под «маленькими» моделями.

Пока ещё не решено, какую модель считать «маленькой» (некоторые говорят <14 Б, некоторые — <7 Б), но для своего видео на YouTube я выбрал ещё более мелкие модели: SmolLM-135M-Instruct, SmolLM-360M-Instruct и Qwen3-0.6B. Это модели ~135 Мб, ~360 Мб и ~600 Мб соответственно.

Давайте посмотрим, как настроить базовый цикл обучения. Для начала мы можем использовать библиотеку трансформаторов Huggingface для загрузки модели, которую хотим обучить, например, небольшой модели SmolLM-135M-Instruct со 135 млн параметров.

Например, чтобы сгенерировать некоторые задачи пропозициональной логики, вы просто вызываете функцию reasoning_gym.create_dataset, как показано ниже.

import re from reasoning_gym import create_dataset, get_score_answer_fn from transformers import AutoModelForCausalLM, AutoTokenizer import torch model_name = «HuggingfaceTB/SmolLM-135M-Instruct» # загрузить модель из huggingface lm = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.bfloat16) tokenizer = AutoTokenizer.from_pretrained(model_name) # Это делает все модели обучаемыми for param in lm.parameters(): param.requires_grad = True # В моих экспериментах я использовал адаптер LORA (подробнее об этом позже) # указать имя окружения environment_name = «propositional_logic» # На практике вам следует обернуть это в загрузчик данных torch # для выборки мини-пакета вопросов dataset = create_dataset( environment_name, seed=42, size=DATA_SIZE ) для d в наборе данных: question = d[«question»] # Доступ к вопросу # Мы воспользуемся этим позже, чтобы проверить правильность ответа validation_object = d[«metadata»][«source_dataset»] score_fn = get_score_answer_fn(validation_object)

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

system_prompt = «»»Разговор между пользователем и помощником. Пользователь задаёт вопрос, а помощник отвечает на него. Помощник сначала обдумывает ход рассуждений, а затем предоставляет пользователю ответ. Процесс рассуждений и ответ заключены в теги и соответственно, то есть: процесс рассуждений здесь ответ здесь . Не создавайте новый код. Не пишите код на Python. Пользователь также может предоставить вам примеры с указанием ожидаемого формата ответа. Следуйте формату примеров, но решайте конкретную задачу, заданную пользователем, а не примеры. Очень важно — ещё раз помните, что формат вывода должен быть следующим: процесс рассуждений здесь ответ здесь Ваш ответ будет оцениваться путём извлечения подстроки между тегами . Крайне важно следовать указанному выше формату. feature_extraction_utilsling для соблюдения формата ответа приведёт к штраф. «»»

Чтобы сгенерировать ответы, мы сначала токенизируем системную подсказку и вопрос, как показано ниже.

# Создать структуру сообщений messages = [ {«role»: «system», «content»: system_prompt}, {«role»: «user», «content»: question}, # Получено из reasoning-gym ] # Создать токенизированное представление inputs = tokenizer.apply_chat_template( messages, tokenize=True, return_tensors=»pt», add_generation_prompt=True )

Затем мы передаём его через LM — генерируем несколько ответов с помощью параметра num_return_sequences и детокенизируем его обратно, чтобы получить строковый ответ. На этом этапе градиенты не рассчитываются.

generated_response = lm.generate( input_ids=inputs[«input_ids»], attention_mask=inputs[«attention_mask»], max_new_tokens=max_new_tokens, # Максимальное количество генерируемых токенов do_sample=True, # Вероятностная выборка top_p=0.95, # Ядерная выборка num_return_sequences=G, # Количество последовательностей на вопрос temperature=1, # Увеличение случайности eos_token_id=eos_token_id, pad_token_id=eos_token_id, )

Мы также пишем функцию extract_answer, которая использует регулярные выражения для извлечения ответов между тегами ответов.

def extract_answer(response): answer = re.search(r»(.*?)«, response, re.DOTALL) если ответ не None: вернуть answer.group(1).strip() иначе: вернуть «»

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

Преимущества рассчитываются путем стандартизации по каждой группе.

# Ответ — массив строк длиной [B*G] # B — количество вопросов, G — количество ответов на вопрос correctness_reward = score_fn(response, validation_object) format_reward = calculate_format_reward(response) # Общая награда — это взвешенная сумма наград за правильность и форматирование reward = correctness_reward * 0.85 + format_reward * 0.15 # Преобразуем награды из [B*G, 1] -> [B, G] rewards = rewards.reshape(B, G) # Рассчитать преимущества advantage = (rewards — np.mean(rewards, axis=1, keepdims=True)) / ( np.std(rewards, axis=1, keepdims=True) + 1e-8 ) advantage = advantage.reshape(-1, 1)

Сохраните (старый) журнал вероятностей, преимуществ, ответов и масок ответов в буфере памяти.

# Функция, возвращающая логарифм вероятности каждого выбранного токена log_probs = calculate_log_probs(lm, generated_response) buffer.extend([{ «full_response»: generated_response[i], «response_mask»: response_mask[i], # Двоичная маска для обозначения того, какие токены в сгенерированном ответе сгенерированы ИИ, 0 для системных подсказок и вопросов «old_log_probs»: log_probs[i], «advantages»: advantage[i] } for i in range(len(generated_response))])

После этапа сбора множественного опыта, когда буфер заполнен, мы запускаем цикл обучения. Здесь мы выбираем мини-пакеты из нашего опыта, вычисляем логарифм вероятности, вычисляем потери и фон.

# full_response, response_mask, old_log_probs, advantage <--- Buffer # Пересчитать новый log_probs. Обратите внимание, что torch.no_grad() отсутствует, поэтому здесь БУДУТ ИСПОЛЬЗОВАТЬСЯ градиенты. logits = llm(input_ids=full_response).logits # Извлечь log-prob из logits # Выполнить log_softmax по словарю и извлечь log-prob каждого выбранного токена log_probs = calculate_log_probs( logits, full_responses ) # Вычислить усеченные суррогатные потери reasoning_loss = calculate_ppo_loss( log_probs, # Обучаемые old_log_probs, # Получено из исследования, необучаемые advantage, # Получено из среды, необучаемые response_mask # Получено из исследования, необучаемые ) # Шаги оптимизации accelerator.backward(reasoning_loss) optimizer.step() optimizer.zero_grad()

Здесь вы можете использовать дополнительные потери энтропии или минимизировать KLD с помощью вашей эталонной модели, как предлагалось в исходной статье Deepseek-R1, но в последующих статьях сделан вывод, что это ограничивает процесс обучения и не является обязательным требованием.

4. Разогрев с контролируемой тонкой настройкой

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

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

47f1c4398f6ec7466e5320fd08f01550

Подумайте сами: обучение с подкреплением (RL) происходит путём сбора опыта и обновления политики для максимизации положительного опыта. Но если большинство опыта совершенно отрицательные, и модель получает нулевое вознаграждение, у неё нет возможности оптимизироваться, поскольку она вообще не получает сигнала для улучшения. Поэтому рекомендуемый подход — сначала обучить модель поведению, которому вы хотите обучиться, с помощью контролируемой тонкой настройки. Вот простой скрипт:

клиент = openai.AsyncClient() СРЕДА = «propositional_logic» модель = «gpt-4.1-mini» семафор = asyncio.Semaphore(50) num_datapoints = 200 system_prompt = ( system_prompt + «»»Вам также будет предоставлен настоящий ответ. Ваши размышления должны в конечном итоге привести к получению настоящего ответа.»»» ) dataloader = create_dataset(name=ENVIRONMENT, size=num_datapoints) @backoff.on_exception(backoff.expo, openai.RateLimitError) async def generate_response(item): async with semaphore: messages = [ {«role»: «system», «content»: system_prompt}, { «role»: «user», «content»: f»»» Вопрос: {item['question']} Метаданные: {item['metadata']} Ответ: {item['answer']} «»», }, ] response = await client.chat.completions.create(messages=messages, model=model) return { «question»: item[«question»], «metadata»: item[«metadata»], «answer»: item[«answer»], «response»: response.choices[0].message.content, } async def main(): responses = await asyncio.gather(*[generate_response(item) for item in dataloader]) fname = f»responses_{ENVIRONMENT}_{model}.json» json.dump(responses, open(fname, «w»), indent=4) print(f»Saved answers to {fname}») if __name__ == «__main__»: asyncio.run(main())

Чтобы создать набор данных для тонкой настройки, я сначала сгенерировал теги «мышление» и «ответ» с помощью небольшой LLM-подобной библиотеки GPT-4.1-mini. Сделать это невероятно просто: мы выбираем около 200 примеров для каждой задачи, вызываем API OpenAI для генерации ответа и сохраняем его на диск.

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

lora: r: 32 lora_alpha: 64 lora_dropout: 0 target_modules: [«q_proj», «v_proj», «k_proj», «o_proj», «up_proj», «down_proj», «gate_proj»]

LORA позволяет эффективнее использовать память при обучении, а также снижает риск повреждения исходной модели. Подробности параметрически эффективной контролируемой тонкой настройки можно найти в моём видео на YouTube, которое можно посмотреть здесь.

Я обучил адаптер LORA на 200 примерах данных силлогизмов с самой маленькой языковой моделью, которую мне удалось найти — HuggingfaceTB/SmolLM-135M-Instruct, — и получил точность 46%. Грубо говоря, это означает, что мы генерируем правильный ответ в 46% случаев. Что ещё важнее, мы часто правильно форматируем ответы, поэтому наше регулярное выражение может безопасно извлекать ответы из ответов чаще, чем нет.

Еще несколько оптимизаций для SLM и практических соображений

  1. Не все задачи на рассуждение могут быть решены всеми моделями. Простой способ проверить, является ли задача слишком сложной или слишком лёгкой для модели, — это проверить её базовую точность . Если она, скажем, ниже 10–20%, задача, вероятно, очень сложная, и вам требуется дополнительная разминка под руководством опытного специалиста.
  2. SFT, даже на небольших наборах данных, обычно может демонстрировать значительный прирост точности на небольших моделях. Если вам удастся получить хороший набор данных, во многих сценариях вам, возможно, даже не понадобится обучение с подкреплением. SLM обладают невероятной гибкостью настройки.
  3. В таких работах, как DAPO и Critical Perspectives on R1, утверждается, что исходная нормализация потерь DeepSeek имеет смещение длины . Они предложили другие методы нормализации, которые стоит рассмотреть. В моём проекте стандартная нормализация потерь DeepSeek сработала отлично.
  4. DAPO также упоминает об удалении члена KLD в исходной статье R1. Изначально целью этой потери было гарантировать, что политика обновления никогда не будет слишком далека от базовой политики, но DAPO рекомендует не использовать это, поскольку поведение политики может радикально меняться в процессе рассуждений, превращая член KLD в ненужный регуляризирующий член, который ограничит интеллектуальность модели.
  5. Генерация разнообразных ответов — КЛЮЧЕВОЙ фактор, делающий возможным обучение с подкреплением (RL). Если вы генерировали только правильные ответы или только неправильные, преимущество будет равно 0, и это не даст алгоритму RL никакого обучающего сигнала. Мы можем генерировать разнообразные ответы, увеличивая параметры temperature, top_p и num_return_sequences в методе generate().
  6. Вы также можете генерировать разнообразные вознаграждения , добавляя больше членов в функцию вознаграждения. Например, вознаграждение за длину, которое наказывает за слишком длинные рассуждения.
  7. Следующие параметры повышают стабильность обучения за счет увеличения объема вычислений : увеличение числа поколений на развертывание, увеличение размера буфера и снижение скорости обучения.
  8. Если у вас ограниченные ресурсы для обучения этих моделей, используйте накопление градиента (или даже контрольные точки градиента).
  9. В этой статье я пропустил несколько мелких деталей, связанных с заполнением . При сохранении опыта в буфере рекомендуется полностью удалить маркеры заполнения и создать их заново при загрузке мини-пакета во время обучения.
  10. Лучше всего оставлять пробелы вокруг и (и их закрывающих тегов). Это обеспечивает единообразие токенизации и немного упрощает обучение SLM.

4. Результаты

Вот мое видео на YouTube, в котором все, что я написал в этом блоге, объясняется более наглядно и дается практическое руководство по написанию кода для подобных вещей.

На SmolLM-135M с контролируемой настройкой в задаче на силлогизмы мы получили повышение до 60%! Здесь вы можете видеть кривую вознаграждения — хорошее стандартное отклонение вознаграждения показывает, что мы действительно получали разнообразные ответы на протяжении всего времени, что является положительным фактором, если мы хотим тренироваться с RL.

d58e38448129d60396cb0c9782458f9a

Вот набор гиперпараметров, которые мне хорошо подошли.

config: name: «path/to/sft_model» max_new_tokens: 300 # бюджет токенов рассуждения + ответа research_batchsize: 8 # количество вопросов в пакете во время развертывания G: 6 # количество ответов в группе temperature: 0.7 batch_size: 16 # размер мини-пакета во время обучения gradient_accumulation_steps: 12 learning_rate: 0.000001 # Рекомендуется поддерживать это значение низким, например 1e-6 или 1e-7 top_p: 0.95 buffer_size: 500

Я также повторил этот эксперимент с более крупными моделями — SmolLM-360M-Instruct и Qwen3-0.6B. В последней мне удалось добиться точности до 81%, что просто потрясающе! В среднем в задаче на силлогизмы мы получили аддитивный прирост на 20%!

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

Завершим статью GIF-изображением небольших моделей, выводящих данные для рассуждений и решающих задачи. Наслаждайтесь и будьте великолепны!

750dac833467bf26be6cf793b82312a9

Ссылки

Канал автора на YouTube : https://www.youtube.com/@avb_fj

Patreon автора : www.patreon.com/NeuralBreakdownwithAVB

Аккаунт автора в Twitter (X) : https://x.com/neural_avb

Математика Deepseek: https://arxiv.org/pdf/2402.03300
DeepSeek R1: https://arxiv.org/abs/2501.12948
ДАПО: https://arxiv.org/abs/2503.14476
Критические взгляды на R1: https://arxiv.org/abs/2503.20783
Библиотека Reasoning Gym: github.com/open-thought/reasoning-gym

Хорошее место, где можно почитать о Reasoning: https://github.com/willccbb/verifiers

Отличное место для изучения кода: https://github.com/huggingface/trl/blob/main/trl/trainer/grpo_trainer.py

Источник: towardsdatascience.com

✅ Найденные теги: Как, новости
Каталог бесплатных опенсорс-решений, которые можно развернуть локально и забыть о подписках

галерея

Фото сгенерированных лиц: исследование показывает, что люди не могут отличить настоящие лица от сгенерированных
Нейросети построили капитализм за трое суток: 100 агентов Claude заперли…
Скетч: цифровой осьминог и виртуальный мир внутри компьютера с человечком.
Сцена с жестами пальцами, где один жест символизирует "VPN", а другой "KHP".
‼️Paramount купила Warner Bros. Discovery — сумма сделки составила безумные…
Скриншот репозитория GitHub "Claude Scientific Skills" AI для научных исследований.
Структура эффективного запроса Claude с элементами задачи, контекста и референса.
Эскиз и готовая веб-страница платформы для AI-дизайна в современном темном режиме.
ideipro logotyp
Image Not Found
Звёздное небо с галактиками и туманностями, космос, Вселенная, астрофотография.

Система оповещения обсерватории Рубина отправила 800 000 сигналов в первую ночь наблюдений.

Астрономы будут получать оповещения о небесных явлениях в течение нескольких минут после их обнаружения. Теренс О'Брайен, редактор раздела «Выходные». Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной…

Мар 2, 2026
Женщина с длинными тёмными волосами в синем свете, нейтральный фон.

Расследование в отношении 61-фунтовой машины, которая «пожирает» пластик и выплевывает кирпичи.

Обзор компактного пресса для мягкого пластика Clear Drop — и что будет дальше. Шон Холлистер, старший редактор Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной странице вашего…

Мар 2, 2026
Черный углеродное волокно с текстурой плетения, отражающий свет.

Материал будущего: как работает «бессмертный» композит

Учёные из Университета штата Северная Каролина представили композит нового поколения, способный самостоятельно восстанавливаться после серьёзных повреждений.  Речь идёт о модифицированном армированном волокном полимере (FRP), который не просто сохраняет прочность при малом весе, но и способен «залечивать» внутренние…

Мар 2, 2026
Круглый экран с изображением замка и горы, рядом электронная плата.

Круглый дисплей Waveshare для креативных проектов

Круглый 7-дюймовый сенсорный дисплей от Waveshare создан для разработчиков и дизайнеров, которым нужен нестандартный экран.  Это IPS-панель с разрешением 1 080×1 080 пикселей, поддержкой 10-точечного ёмкостного сенсора, оптической склейкой и защитным закалённым стеклом, выполненная в круглом форм-факторе.…

Мар 2, 2026

Впишите свой почтовый адрес и мы будем присылать вам на почту самые свежие новости в числе самых первых