Статья
Гибридная reasoning-модель удобна. Но нагрузку всё равно придётся разделять
Один checkpoint может отвечать и с reasoning, и без него. Но короткие ответы и длинные рассуждения по-разному нагружают inference, поэтому один endpoint ещё не означает один общий пул.
Автор — Сергей Нотевский
Опубликовано
Когда вышел Qwen3, одна из самых заметных его возможностей выглядела очень удобно: одна модель умела работать и с рассуждением, и без него. Достаточно было добавить в промпт /think или /no_think.
Сложную задачу отправляем в thinking, простой чат или извлечение данных запускаем без него. Не надо выбирать между двумя моделями, держать разные API и объяснять продуктовой команде, куда слать запрос. На словах это прекрасно.
Через несколько месяцев Qwen выпустил обновлённые модели раздельно: Instruct-2507 поддерживал только non-thinking, Thinking-2507 только thinking. Я сначала воспринял это как ответ на простой вопрос: значит, совместить два режима без потерь не получилось?
Но история оказалась интереснее. В Qwen3.5 единый thinking-переключатель вернулся. Поэтому вывод «гибридные reasoning-модели не работают» уже не выдерживает проверки. Зато никуда не делась другая проблема, которую хорошо видно в production: одна модель ещё не означает, что все её запросы стоит обслуживать одним inference-пулом.
Что изменилось в Qwen3-2507
В апрельском Qwen3 команда Alibaba специально объединила thinking и non-thinking в одном checkpoint. В техническом описании это отдельный этап обучения: к reasoning-модели добавляли способность отвечать напрямую, а затем дообучали оба режима вместе. Переключаться можно было параметром enable_thinking или командами в самом диалоге.
В июле появились отдельные Qwen3-235B-A22B-Instruct-2507 и Qwen3-235B-A22B-Thinking-2507. В карточке Instruct прямо написано, что модель поддерживает только non-thinking и больше не требует enable_thinking=False. У Thinking, соответственно, свой checkpoint и свой режим работы.
Вендорские цифры выглядят впечатляюще. На AIME25 non-thinking версия Qwen3-235B-A22B поднялась с 24,7 до 70,3 балла. Это примерно в 2,8 раза. Thinking-версия на том же бенчмарке выросла с 81,5 до 92,3.
Но приписывать весь прирост одному разделению режимов нельзя. Между релизами прошло три месяца, в карточках заявлены улучшения post-training, instruction following, знаний, работы с длинным контекстом и других возможностей. Это не контролируемый эксперимент «тот же training run, только без гибридности». И сами цифры опубликованы создателями модели, а не получены на целевой нагрузке.
Поэтому из релиза 2507 я бы вынес не доказательство провала гибридов, а более скромный вывод: команда Qwen тогда развела режимы по отдельным checkpoints и показала заметный прирост в обоих. Что именно дало этот прирост, по карточкам моделей не отделить. Уже в Qwen3.5 команда снова совместила thinking и direct response в одной модели. Стратегия обучения меняется от поколения к поколению.
Почему одна модель не означает один общий пул
Для пользователя разница между режимами выглядит как один флаг. Для inference runtime это запросы разной формы.
Простой чат, классификация, суммаризация или извлечение полей обычно требуют короткого и предсказуемого ответа. Для них особенно важны небольшой TTFT, ровная задержка и высокая пропускная способность.
Reasoning-запрос способен генерировать намного больше токенов и заметно дольше оставаться в decode. Он занимает KV cache, живёт в scheduler дольше и конкурирует за токенный бюджет батча. Если таких запросов становится много, короткие сценарии начинают ждать рядом с длинными. Средняя утилизация при этом может выглядеть прекрасно, а задержка коротких запросов уже может выйти за SLO.
Современный vLLM умеет смягчать конфликт. Chunked prefill режет длинные входы на части и совмещает их с decode. Scheduler сначала обслуживает ожидающие decode-запросы, а max_num_batched_tokens позволяет выбирать компромисс между TTFT, inter-token latency и throughput. Это полезные механизмы, но они не создают один идеальный профиль настроек для любой смеси запросов.
Маленький max_num_batched_tokens чаще помогает ITL, потому что крупные операции prefill меньше замедляют decode. Больший бюджет для некоторых профилей улучшает TTFT и общую пропускную способность. Количество одновременных последовательностей, лимиты длинного prefill и объём KV cache тоже меняют результат. Настройка, удачная для длинных reasoning-сессий, не обязана быть лучшей для быстрого чата.
Вот где для меня проходит важная граница:
Гибридность удобна как интерфейс модели. Но serving-архитектуру определяет форма нагрузки, а не наличие переключателя
/think.
Что я бы делал в production
Первый вариант: разные модели и разные пулы. Быструю Instruct-модель держим под короткие запросы, reasoning-модель под сложные задачи. Это самый явный контракт, но две модели приходится отдельно оценивать, обновлять и держать в памяти.
Второй вариант: один гибридный checkpoint, развёрнутый в двух пулах. В одном thinking выключен и настройки подобраны под быстрые ответы. В другом он включён, допускаются длинные генерации и другой latency-класс. Память под веса дублируется, зато сохраняется одна модель и изолируются разные SLO.
Третий вариант: общий пул, если нагрузка небольшая или хорошо управляемая. Для внутреннего инструмента, разработки или редких reasoning-запросов это может быть самым разумным решением. Не всякая система обязана начинаться с отдельного кластера на каждый тип запроса.
Выбор между ними подтверждается не названием модели. Нужен replay или нагрузочный профиль, который сохраняет распределение входных и выходных токенов, долю thinking-запросов, concurrency и характер прихода нагрузки. Смотрел бы как минимум на TTFT и ITL по классам запросов, длину очереди, throughput, preemption и использование KV cache. Среднее по смешанному потоку легко скрывает деградацию коротких сценариев.
Если пулов становится несколько, перед ними нужен gateway или другой слой маршрутизации. Именно там запрос получает workload-класс, ограничения на reasoning budget, timeout и fallback. Переключатель модели остаётся частью запроса, а решение о ресурсах становится частью платформы.
Когда гибрид всё-таки полезен
Гибридная модель снимает часть продуктовой сложности. Можно сохранить один контракт API, не заставлять вызывающую команду выбирать конкретный checkpoint и динамически включать reasoning там, где он действительно нужен. Для локальной разработки и умеренной нагрузки это особенно удобно.
Ещё она оставляет платформе свободу. Сегодня оба режима идут в один пул, завтра gateway разводит их по разным развёртываниям той же модели, а позже один из классов переезжает на специализированный checkpoint. Клиентский интерфейс при этом не обязан меняться.
Поэтому вопрос для меня теперь звучит не «зачем тогда гибрид?». Гибрид полезен как модельный и продуктовый интерфейс. Просто он не отменяет архитектуру serving.
Если длинные reasoning-запросы и быстрые ответы имеют разные SLO, их всё равно придётся различать, измерять и, возможно, разводить по разным машинам. Даже когда внутри лежит один и тот же checkpoint.
Источники
- Qwen3: Think Deeper, Act FasterВнешняя ссылка, откроется в новой вкладке: описание исходного гибридного режима,
enable_thinking,/thinkи/no_think. - Qwen3 Technical ReportВнешняя ссылка, откроется в новой вкладке: устройство обучения thinking и non-thinking режимов.
- Qwen3-235B-A22B-Instruct-2507Внешняя ссылка, откроется в новой вкладке: карточка non-thinking модели и опубликованные результаты.
- Qwen3-235B-A22B-Thinking-2507Внешняя ссылка, откроется в новой вкладке: карточка thinking-модели и опубликованные результаты.
- Qwen3.5-27BВнешняя ссылка, откроется в новой вкладке: пример возвращения единой модели с включаемым thinking-режимом.
- Optimization and Tuning in vLLMВнешняя ссылка, откроется в новой вкладке: chunked prefill, политика scheduler и влияние
max_num_batched_tokensна latency и throughput.