Дистилляция рассуждений и режимы мышления
Как передать рассуждения маленькой модели без собственного RL — R1-Distill, strong-to-weak у Qwen3, on-policy дистилляция с обратной KL — и как управлять тем, сколько модель думает: /think и /no_think, бюджет мышления, test-time compute.
Зачем это нужно
Заголовок раздела «Зачем это нужно»R1 — это 671 миллиард параметров. На ноутбуке её не запустить, а дообучать её своим RL могут единицы. Нужны маленькие модели, которые умеют рассуждать. Очевидный путь — повторить рецепт R1-Zero на маленькой базе. Но прошлые уроки показали, что RL лишь усиливает то, что в базе уже было: у TinyZero 0.5B-модель рассуждать не научилась вовсе, а Qwen-32B после 10 тысяч шагов большого RL набрала на AIME 47%.
Оказалось, есть путь дешевле и лучше: научить маленькую модель у большой — дистилляциядистилляцияEN (knowledge) distillation.
В 2025–2026 годах она прошла путь от «просто SFT на ответах R1» до on-policy дистилляции, которой DeepSeek-V4,
по обзорам её техотчёта, заменила целый этап RL. Вторая половина урока — о том, как управлять «длиной мысли»: режимы /think и /no_think,
бюджет мышления и общий принцип test-time compute.
R1-Distill: SFT на трассах большой модели
Заголовок раздела «R1-Distill: SFT на трассах большой модели»Рецепт из статьи R1 предельно прост. Те же ~800 тысяч примеров, на которых дообучали саму R1 (≈600K рассуждений,
отобранных отбором с отклонениемотбор с отклонением (rejection sampling)EN rejection samplingСгенерировать много ответов и оставить только прошедшие проверку. В пост-трейнинге — способ собрать SFT-данные из RL-модели., и ≈200K прочих задач), используют как
SFT-данные для шести открытых моделей. Формат — тот, что вы строили в уроке 6.1.2:
промпт, затем ответ ассистента с рассуждением внутри <think>…</think> и итоговым ответом; loss — только на ответе.
Никакого RL — авторы сознательно оставили его сообществу.
| Модель | База | AIME 2024 pass@1 | MATH-500 pass@1 |
|---|---|---|---|
| R1-Distill-Qwen-1.5B | Qwen2.5-Math-1.5B | 28.9 | 83.9 |
| R1-Distill-Qwen-7B | Qwen2.5-Math-7B | 55.5 | 92.8 |
| R1-Distill-Qwen-14B | Qwen2.5-14B | 69.7 | 93.9 |
| R1-Distill-Qwen-32B | Qwen2.5-32B | 72.6 | 94.3 |
| R1-Distill-Llama-8B | Llama-3.1-8B | 50.4 | 89.1 |
| R1-Distill-Llama-70B | Llama-3.3-70B-Instruct | 70.0 | 94.5 |
| для сравнения: GPT-4o-0513 | — | 9.3 | 74.6 |
Модель на 1.5 миллиарда параметров решает олимпиадную математику втрое лучше GPT-4o — только за счёт того, что училась на чужих рассуждениях. А эксперимент §4.1 ставит точку в споре на одной базе: Qwen-32B после большого RL — 47.0%, после дистилляции из R1 — 72.6%. Вывод авторов: маленьким моделям выгоднее учиться у большой, а двигать границу возможностей по-прежнему должны сильные базы и большой RL. Дистилляция копирует, а не изобретает.
LeapLab из Цинхуа, чья работа о pass@k обсуждалась в прошлых уроках, добавляет важное наблюдение: дистилляция и RLVR устроены принципиально по-разному. RL затачивает решения, которые база и так находила; дистилляция способна принести новые паттерны рассуждений — ведь они приходят от более сильной модели.
Почему простого SFT мало
Заголовок раздела «Почему простого SFT мало»У SFT на ответах учителя две слабости.
1. Смещение экспозиции (смещение экспозициисмещение экспозиции (exposure bias)EN exposure biasПри обучении модель видит только «правильные» префиксы, а при генерации — свои собственные, с ошибками. Отсюда накопление ошибок.). На обучении ученик видит только «идеальные» префиксы учителя. На генерации он продолжает свои префиксы — с собственными ошибками, которых в данных не было. Ошибка на десятом токене выводит его в незнакомую область, и дальше ошибки копятся. Чем длиннее рассуждение, тем больнее.
2. Слабый ученик и прямая KL. SFT на сэмплах учителя — это минимизация прямой KL:
Штраф огромен, если ученик дал маленькую вероятность тому, что учитель делает часто. На числах: учитель даёт ответу вероятность 0.5, ученик — 0.001; слагаемое . Обратная ситуация (учитель 0.001, ученик 0.5) почти бесплатна: . Поэтому ученик старается покрыть всё, что умеет учитель. Если ёмкости (параметров ученика) не хватает, он размазывает вероятность между способами решения — и генерирует то, чего учитель не делал никогда: начало одного решения, конец другого.
Альтернатива — обратная KLобратная KL-дивергенция (reverse KL)EN reverse KL divergenceKL(q ‖ p), где q — модель, p — цель. «Ищет моду» — модель концентрируется на одном пике цели. Прямая KL(p ‖ q) «покрывает» все пики.:
Теперь среднее берётся по ответам ученика. Штраф огромен, если ученик кладёт вероятность туда, где учитель уверен, что ответа нет: с теми же числами (ученик 0.5, учитель 0.001) слагаемое снова . Ученик выбирает один способ и делает его хорошо. Это и называют «покрытие мод» против «поиска моды». Мода распределения — его «пик», самое вероятное значение; у распределения может быть несколько пиков, и тогда говорят о нескольких модах. Учитель, который знает два способа решения, — распределение с двумя модами.
Проверим на игрушке. Учитель знает два способа решения (две моды в точках −3 и +3, между ними почти пусто), ученик проще — одна «гауссиана», то есть колокол нормального распределениянормальное (гауссовское) распределениеEN normal (Gaussian) distribution«Колокол» N(μ, σ²). Правило 68–95–99.7 — доля значений в пределах 1, 2 и 3 σ от среднего. с центром и шириной (урок 1.3.1).
import torch
x = torch.linspace(-10, 10, 801) # сетка «вариантов ответа»
def gauss(mu, sigma): p = torch.exp(-0.5 * ((x - mu) / sigma) ** 2) return p / p.sum() # нормируем на сетке → распределение
# Учитель знает два хороших способа решения: моды в −3 и +3, между ними почти пустоteacher = 0.6 * gauss(torch.tensor(-3.0), 1.0) + 0.4 * gauss(torch.tensor(3.0), 1.0)gap = (x.abs() <= 1) # «провал» между модами
def fit(kind, steps=3000): mu = torch.tensor(-1.0, requires_grad=True) # ученик проще учителя: одна гауссиана log_sigma = torch.tensor(0.0, requires_grad=True) # учим log σ: σ = exp(log_sigma) всегда > 0 opt = torch.optim.Adam([mu, log_sigma], lr=0.02) for _ in range(steps): s = gauss(mu, log_sigma.exp()) + 1e-12 # + крошечное число, чтобы не было log(0) = −∞ if kind.startswith("прямая"): loss = (teacher * (teacher.log() - s.log())).sum() # KL(учитель ‖ ученик): SFT на сэмплах учителя else: loss = (s * (s.log() - teacher.log())).sum() # KL(ученик ‖ учитель): on-policy opt.zero_grad() loss.backward() opt.step() s = gauss(mu, log_sigma.exp()).detach() print(f"{kind:34s} μ = {mu.item():+.2f}, σ = {log_sigma.exp().item():.2f}, масса в провале: {s[gap].sum():.3f}")
print(f"{'учитель':34s} масса в провале: {teacher[gap].sum():.3f}")for kind in ["прямая KL (SFT на ответах учителя)", "обратная KL (on-policy)"]: fit(kind)учитель масса в провале: 0.023прямая KL (SFT на ответах учителя) μ = -0.61, σ = 3.13, масса в провале: 0.249обратная KL (on-policy) μ = -2.99, σ = 1.02, масса в провале: 0.026Прямая KL поставила ученика между способами (, это ровно среднее учителя ) и в 10 раз раздула массу в провале: четверть ответов ученика — то, чего учитель не делает никогда. Обратная KL выбрала один способ (, ) и повторила его почти точно. Цена — второй способ потерян: обратная KL жертвует разнообразием ради качества.
On-policy дистилляция
Заголовок раздела «On-policy дистилляция»on-policy дистилляцияon-policy дистилляция (OPD)EN on-policy distillation (OPD)Ученик сам генерирует ответы, учитель оценивает каждый токен; минимизируется обратная KL(π_ученика ‖ π_учителя). Qwen3, DeepSeek-V4. соединяет обратную KL и идею RL «учиться на своих ответах»:
- Ученик генерирует ответ на промпт — как роллаут в GRPO.
- Учитель прогоняет этот ответ одним прямым проходом (без генерации — это дёшево) и выдаёт свои вероятности на каждой позиции.
- Loss — обратная KL на каждом токене: по сэмплированным токенам или точная KL по всему словарю на каждой позиции.
- Повторить.
flowchart LR P["Промпт"] --> S["Ученик генерирует ответ"] S --> T["Учитель: один прямой проход по ответу ученика"] T --> L["Обратная KL на каждом токене"] L -->|"градиент"| S subgraph RL["Сравните с GRPO"] S2["Ученик генерирует G ответов"] --> R["Одна награда на ответ"] end
Почему это работает лучше и SFT, и RL:
- Против SFT: ученик учится на своих префиксах — учитель поправляет его ровно там, где он реально ошибается. Обучение идёт на том же распределении префиксов, что и генерация, поэтому exposure bias снимается.
- Против RL: вместо одного бита «верно/неверно» на тысячи токенов — оценка каждого токена. Сигнал на порядки плотнее. На языке RL это обычный градиент политики (урок 6.0.3), только у каждого токена своё преимущество (со stop-gradient): токен, который учитель считает вероятнее, чем ученик, поднимается. В отчёте DeepSeek-V4 прямо сказано, что так on-policy дистилляцию обычно встраивают в готовые RL-фреймворки, — и что такая потокенная оценка даёт большую дисперсию градиента, поэтому сами они считают KL по всему словарю (см. ниже).
- Цена: нужны логиты учителя, то есть его веса (дистилляция «белого ящика»). По API, где видны только тексты, так не сделать. И у учителя с учеником должен быть общий токенизатор, иначе их вероятности относятся к разным токенам и несравнимы. Поэтому дистиллируют обычно внутри семейства: Qwen3-8B → Qwen3-0.6B.
Идея не нова. В 2023 году почти одновременно вышли две работы этой линии: MiniLLM группы CoAI Университета Цинхуа
и Microsoft Research (обратная KL вместо прямой для генеративных LLM) и GKD из Google DeepMind (обучение на ответах,
сгенерированных самим учеником; в TRL есть экспериментальный GKDTrainer). Но в массовую практику on-policy
дистилляция вошла в 2025 году вместе с reasoning-моделями.
Strong-to-weak у Qwen3
Заголовок раздела «Strong-to-weak у Qwen3»Для маленьких моделей семейства (0.6B, 1.7B, 4B, 8B, 14B и MoE 30B-A3B) Qwen не повторяет четырёхэтапный конвейер флагмана, а применяет дистилляция «от сильной к слабой»дистилляция «от сильной к слабой»EN strong-to-weak distillationСхема Qwen3 для маленьких моделей. Сначала обучение на ответах большой модели (off-policy), затем подгонка к её логитам на собственных генерациях ученика (on-policy). в две фазы:
- Off-policy: SFT на ответах учителей в обоих режимах — с рассуждением и без.
- On-policy: ученик сам генерирует ответы в режиме
/thinkили/no_think, а его логиты подтягивают к логитам учителя (Qwen3-32B или Qwen3-235B-A22B), минимизируя KL.
Таблица 21 отчёта сравнивает два продолжения для Qwen3-8B после off-policy фазы на математике и коде:
| Метод | AIME’24 pass@1 | AIME’24 pass@64 | GPU-часыGPU-часыEN GPU hoursЧисло ускорителей × часы работы. 2048 GPU за сутки — 49 152 GPU-часа. |
|---|---|---|---|
| Off-policy дистилляция (старт) | 55.0 | 90.0 | — |
| + RL | 67.6 | 90.0 | 17 920 |
| + on-policy дистилляция | 74.4 | 93.3 | 1 800 |
Дистилляция лучше по качеству и в 10 раз дешевле. Обратите внимание на pass@64: RL оставил его на месте (90.0 → 90.0) — знакомый эффект «затачивания» — а дистилляция подняла (93.3): учитель расширил то, что ученик умеет в принципе.
2026: дистилляция вместо RL
Заголовок раздела «2026: дистилляция вместо RL»В отчёте DeepSeek-V4 сказано прямо: смешанный RL-этап, завершавший пост-трейнинг V3.2, полностью заменён on-policy дистилляцией. Схема:
- Для каждого домена (математика, код, агенты, следование инструкциям…) отдельно обучают специалиста: SFT, затем RL с GRPO.
- Одна общая модель-ученик учится у более чем десяти учителей сразу: минимизирует взвешенную сумму обратных KL к каждому из них на своих траекториях. Для математического промпта главным оказывается математический учитель, для кода — кодовый.
- KL считают по всему словарю на каждой позиции, а не по одному сэмплированному токену: так градиент стабильнее.
Похожую многоучительскую схему (MOPD) описывает Xiaomi для MiMo-V2-Flash. Тренд понятен: RL с наградами выращивает сильных узких специалистов, а дистилляция дёшево и стабильно собирает их в одну модель.
Режимы мышления
Заголовок раздела «Режимы мышления»Рассуждение — это токены, а токены — это деньги и задержка. Спросить «столица Франции?» и получить 2000 токенов размышлений — плохой продукт. Отсюда гибридный режим мышлениягибридный режим мышленияEN hybrid thinking modeОдна модель умеет отвечать и с длинным рассуждением, и сразу. В Qwen3 режим переключается флагами /think и /no_think.: одна модель, два режима.
Qwen3 (апрель 2025) получил гибридный режим на третьем этапе пост-трейнинга — «слиянии режимов». Модель,
уже обученную рассуждать (холодный старт + reasoning RL), дообучают на смеси данных двух типов: с рассуждением и без.
Режим выбирают флагами в сообщении пользователя или системном промпте: /think или /no_think; в многоходовом
диалоге модель следует последнему флагу. По умолчанию модель рассуждает.
Важная деталь шаблона: в режиме без рассуждения модель всё равно выдаёт блок <think> — пустой. Так формат
ответа всегда одинаковый, а разработчик может «выключить мысли», просто подставив пустой блок в шаблон. В библиотеке
transformers это параметр enable_thinking=False в tokenizer.apply_chat_template.
Честный эпилог. Уже в июле 2025 года Qwen выпустила обновление Qwen3-2507 с отдельными Instruct- и Thinking-моделями: команда решила, что раздельное обучение даёт лучшее качество в каждом режиме, чем два режима в одних весах. Другие лаборатории выбрали иначе: DeepSeek-V3.1 (август 2025) — гибридная, а DeepSeek-V4 предлагает три режима рассуждения — без мышления, «Think High» и «Think Max». Каждый режим в V4 выращен отдельным специалистом с собственным штрафом за длину и окном контекста на RL, а затем все они слиты дистилляцией; для максимального режима в начало системного промпта добавляется специальная инструкция «думать максимально тщательно».
Бюджет мышления
Заголовок раздела «Бюджет мышления»У Qwen3 есть бюджет мышлениябюджет мышленияEN thinking budgetЛимит токенов на рассуждение; при его исчерпании рассуждение обрывают и просят модель ответить. Ручка «точность ↔ задержка».. Механизм прост: когда рассуждение доходит до заданного числа токенов,
генерацию останавливают, дописывают короткую служебную фразу в духе «время вышло, отвечаю по уже сделанному»
и закрывающий тег </think>. Дальше модель пишет ответ по тому, что успела надумать. Авторы отмечают, что этому
специально не учили: умение отвечать по незаконченному рассуждению появилось само после слияния режимов. А качество
на математике и коде плавно растёт с бюджетом — получается ручка «точность ↔ задержка» в руках пользователя.
Похожие ручки есть и у других: MiniMax-M1 выпущена в версиях с бюджетом 40K и 80K токенов, Kimi k1.5 переносит навыки длинных рассуждений в короткие (long2short, урок 6.4.3), а работа s1 (2025) показала обратный приём — продлевать рассуждение, дописывая «Wait», когда модель пытается закончить слишком рано.
Test-time compute
Заголовок раздела «Test-time compute»Общий принцип за всем этим — вычисления во время инференсавычисления во время инференса (test-time compute)EN test-time computeБольше вычислений на ответ вместо большей модели: длинное рассуждение, много сэмплов с голосованием, поиск с проверщиком.: тратить больше вычислений не на обучение, а на каждый ответ. Три способа:
| Способ | Как | Пример |
|---|---|---|
| Последовательный | длиннее рассуждение, перепроверка | R1, режимы Think High и Think Max, бюджет мышления |
| Параллельный | ответов + голосованиесамосогласованность (голосование большинством)EN self-consistency (majority voting)Сгенерировать N ответов и выбрать самый частый итоговый. В отчётах — maj@k или cons@k. или выбор лучшего проверщиком | cons@64 в отчётах R1 (голосование по 64 ответам, урок 6.4.2) |
| Поиск | дерево шагов с оценкой каждого шага (PRMпроцессная модель вознаграждения (PRM)EN process reward model (PRM)Оценивает каждый шаг рассуждения, а не только итоговый ответ. В DeepSeek-R1 описана как «неудачная попытка».) | статьи 2024 года, в R1 не прижилось |
Ключевой вопрос — когда это выгоднее большей модели. Snell и соавторы (UC Berkeley и Google DeepMind, 2024) сравнили при равных FLOPs маленькую модель с умно распределённым test-time compute и модель в 14 раз больше. На лёгких и средних задачах — и даже на части трудных, где маленькая модель хотя бы иногда права, — дополнительный инференс выигрывал. На самых трудных задачах выигрыша почти не было: там нужна более сильная модель. Отсюда и практичный вывод: бюджет мышления стоит подбирать под трудность задачи, а не ставить максимальным всегда.
Вторая сторона медали — «передумывание»«передумывание» (overthinking)EN overthinkingМодель тратит тысячи токенов там, где хватило бы сотни. Лечат штрафом за длину, long2short, бюджетом мышления.: тысячи токенов там, где хватило бы сотни. С ним борются штрафом за длину на RL (Kimi k1.5, DeepSeek-V4), long2short и тем же бюджетом.
Практика
Заголовок раздела «Практика»Сравнение прямой и обратной KL вы уже запустили выше. Осталось увидеть, как бюджет мышления выглядит на уровне текста. Вместо настоящей модели — готовое «рассуждение» из токенов-слов.
STOP = "\n(Время на размышление вышло — отвечаю по уже сделанным выкладкам.)\n</think>\n\n"
def apply_thinking_budget(thinking_tokens, budget): """Если рассуждение длиннее бюджета — обрываем его и закрываем блок <think> служебной фразой.""" if len(thinking_tokens) <= budget: return "<think>\n" + " ".join(thinking_tokens) + "\n</think>\n\n", False return "<think>\n" + " ".join(thinking_tokens[:budget]) + STOP, True
thinking = "17 * 24 = 17 * 20 + 17 * 4 = 340 + 68 = 408 . Проверю : 24 * 17 = 240 + 168 = 408 .".split()print("токенов в рассуждении:", len(thinking))for budget in [40, 12]: text, cut = apply_thinking_budget(thinking, budget) print(f"--- бюджет {budget}, обрезано: {cut}") print(text.rstrip())токенов в рассуждении: 30--- бюджет 40, обрезано: False<think>17 * 24 = 17 * 20 + 17 * 4 = 340 + 68 = 408 . Проверю : 24 * 17 = 240 + 168 = 408 .</think>--- бюджет 12, обрезано: True<think>17 * 24 = 17 * 20 + 17 * 4 =(Время на размышление вышло — отвечаю по уже сделанным выкладкам.)</think>С настоящей моделью шаги те же: (1) сгенерировать рассуждение с max_new_tokens = budget; (2) если в выводе нет
</think>, дописать служебную фразу и закрывающий тег; (3) продолжить генерацию уже ответа. Qwen3 использует для этого
короткую английскую фразу из своего отчёта — найдите её в §4.3 и сравните поведение модели с ней и с нашей русской.
Проверь себя
Заголовок раздела «Проверь себя»- R1-Distill — простой SFT на ~800K трассах R1; 1.5B-модель решает AIME лучше GPT-4o. Маленьким моделям выгоднее учиться у большой, чем выращивать рассуждения своим RL.
- SFT на ответах учителя = прямая KL: покрывает моды и страдает от exposure bias. On-policy дистилляция — ученик генерирует, учитель оценивает каждый токен, минимизируется обратная KL.
- Qwen3: on-policy дистилляция лучше RL (74.4 против 67.6 на AIME’24) и в 10 раз дешевле; DeepSeek-V4 заменила ею весь финальный смешанный этап RL.
- Гибридное мышление —
/thinkи/no_thinkс пустым блоком мыслей; бюджет мышления обрывает рассуждение и просит ответить; V4 предлагает три уровня усилия. - Test-time compute выгоден, когда модель хотя бы иногда права; бюджет стоит подбирать под трудность.
Дальше: практикум — GRPO своими руками: мини-R1-Zero на CPU и Qwen через TRL или verl на GPU.