Multi-Token Prediction приехал в llama.cpp: Qwen 3.6 разгоняется в 1.8 раза
PR #22673 с поддержкой MTP смержили в master 16 мая. На Qwen 3.6-27B декод не проседает на длинном контексте — 39-49 ток/с против 29 у обычного режима.

Три месяца люди в r/LocalLLaMA копались в спекулятивном декодировании, форках с DFlash и кастомных драфтерах. А потом в субботу, 16 мая, в master ветку llama.cpp втащили один pull request — и весь этот зоопарк стал ненужным. Multi-Token Prediction, тот самый MTP, который Qwen и DeepSeek подкладывали в свои модели последний год, теперь работает прямо из коробки. На Qwen 3.6-27B это даёт 1.8x скорости — и, что важнее, скорость не разваливается на длинном контексте.
Что произошло
Пул-реквест #22673 от пользователя am17an был открыт ещё 4 мая — почти месяц он висел в обзоре. Идея простая: модели вроде Qwen 3.6 и DeepSeek V3 уже тренируются с дополнительными «головами», которые во время основного forward-прохода предсказывают сразу несколько токенов вперёд. Эти токены потом верифицируются на следующем шаге — те, что совпали с тем, что модель и так предсказала бы, принимаются бесплатно. Никакого отдельного draft-model, как в классическом speculative decoding, не нужно.
До PR #22673 чтобы воспользоваться MTP в Qwen, приходилось либо использовать форк BeeLlama от Anbeeld, либо вручную «прививать» MTP-головы к UD-квантам Unsloth через костыли с git. Теперь это один флаг: --spec-type mtp. Модель — Qwen3.6-27B-Q4_K_M-mtp.gguf от Unsloth, головы уже внутри GGUF.
Почему именно 1.8x
Ian L. Paterson, который три месяца провёл, гоняя бенчи на одиночном RTX 3090 Ti, опубликовал детальный разбор ровно в день мержа. Цифры красноречивые. На Qwen 3.6-27B Q4_K_M обычный авторегрессивный декод даёт 29 ток/с независимо от длины ответа — это база. DFlash, до этого считавшийся лучшим решением, выдаёт 47 ток/с при коротких ответах, но проседает до 30 при длине 2000 токенов. У MTP с правильными флагами график плоский: 39-49 ток/с на любом промежутке.
| Длина ответа | Авторегрессив | DFlash | MTP |
|---|---|---|---|
| 100 токенов | 28.9 ток/с | 46.9 ток/с | 44.6 ток/с |
| 500 токенов | 29.1 ток/с | 37.0 ток/с | 39.1 ток/с |
| 1000 токенов | 29.1 ток/с | 30.2 ток/с | 44.4 ток/с |
| 2000 токенов | 29.0 ток/с | 30.1 ток/с | 48.9 ток/с |
Почему DFlash разваливается, а MTP — нет? У DFlash есть отдельная маленькая модель-драфтер, у которой свой KV-кэш. Этот кэш растёт вместе с контекстом, и в какой-то момент драфтер начинает голодать по памяти. У MTP отдельной модели нет: дополнительные головы шарят hidden state и KV-кэш с основной моделью. Никакой конкуренции за пропускную способность, никакой просадки.
Подвох с потерями
Спекулятивное декодирование при температуре 0 теоретически должно быть «бит-в-бит» идентично авторегрессивному. На практике — нет. Ian с помощниками провёл прямой тест: сгенерировал ответы авторегрессивно, потом пустил через MTP с тем же seed, посчитал Levenshtein-расстояние. На вызовах функций (tool calls) и коротких структурированных ответах всё совпало посимвольно. На свободной прозе длиннее пары сотен токенов — расхождение около 1000 символов, текстуально другое, но семантически эквивалентное.
Причина известна: даже при rejection sampling, если два токена сидят на почти равных вероятностях, малейший дрейф в логитах draft-головы перекидывает выбор на другой токен. Дальше ветвление расходится. Та же история была у DFlash, и академическая работа на arxiv описывает этот эффект на уровне внимания. Для тестов с golden output это значит одно: speculative decoding надо отключать.
Что нужно для запуска
Кому хочется попробовать прямо сейчас:
- Бинарник: llama.cpp master после 16 мая 2026, либо ветка из PR #22673 (
build-mtp). - Модель:
unsloth/Qwen3.6-27B-MTP-GGUFс Hugging Face, MTP-головы уже внутри. - Ключевые флаги:
--spec-type mtp --spec-draft-n-max 6 --spec-draft-p-min 0.75. - Память: ~20.5 GiB VRAM на RTX 3090 / 4090 (24 ГБ карты).
- Дополнительный бонус:
--reasoning-budget 256экономит ~10 секунд на запрос без видимой потери качества.
Флаг --spec-draft-p-min 0.75 тут не косметический — он отсекает заведомо плохие гипотезы драфт-голов и был добавлен в отдельном PR #22397 ещё 28 апреля. Без него MTP в первых тестах казался хуже DFlash и был отложен — с ним картина поменялась.
Кому это нужно
Локальный пользователь с одной потребительской картой — главный бенефициар. До этого, чтобы получить ускорение, нужно было либо ставить форк, либо городить связку из drafter-модели плюс target. Теперь — git pull && cmake --build && --spec-type mtp. Размер модели на диске практически не меняется: MTP-головы — это пара процентов веса.
Бизнес-кейс примерно тот же: на серверах с дешёвыми GPU это удваивает throughput на длинных ответах. Особенно выигрывает агентный сценарий — длинная цепочка рассуждений, многократные вызовы инструментов, ответы на 1500-2000 токенов. Раньше это была худшая ниша для DFlash; теперь это лучшая ниша для MTP.
Что ожидать дальше
MoE-семейство Qwen 3.6-35B-A3B пока работает с MTP неровно — на HackMD первые тесты показывали отсутствие выигрыша, потом апдейт 8 мая исправил флаги и показал +27.5%. История ещё пишется. Issue #23011 фиксирует, что на Apple Metal MTP пока медленнее базы — Metal-бэкенд требует доработки.
Но направление понятное. Если новая модель поставляется с MTP-головами в весах, и инференс-движок умеет их использовать — никаких отдельных draft-моделей в локальной инфраструктуре больше не понадобится. Это меняет и зоопарк форков, и логистику деплоя. Простота, которой не хватало спекулятивному декодированию последние два года, кажется, наконец-то приехала.

