Почему MTP — не маркетинг, а математика
Если вы когда-нибудь запускали локального агента для кодинга на 24 ГБ видеокарте, вы знаете это чувство. Модель что-то обдумывает, вы смотрите на пульсирующий курсор, и секунды тянутся вечность. 27B параметров — это не шутка. Особенно когда контекст 262k токенов, а каждый вызов генерации — это целая эпопея.
В Qwen 3.6 27B (релиз марта 2026) инженеры Alibaba встроили механизм Multi-Token Prediction (MTP). Идея дерзкая: вместо того чтобы гадать по одному токену, модель предсказывает сразу целый пакет — например, 5 токенов за один forward pass. На бумаге ускорение должно быть 5x. На практике — 2.5x. Но и это переводит агента из категории «терпеливо жду» в «вот тебе ответ, работай».
В отличие от классического speculative decoding, где нужен отдельный драфт-модель (маленькая и быстрая), MTP использует дополнительную голову на выходе самой большой модели. Она обучается совместно с основным языковым модулем. Поэтому нет лишних гигабайтов на диске и дополнительного расхода VRAM. Только голова — она весит пренебрежимо мало.
Важно: MTP в Qwen 3.6 работает только при инференсе через библиотеки, которые поддерживают speculative decoding. На текущий момент — это llama.cpp (ветка с PR #5678, слитая в main в апреле 2026) и vLLM (начиная с версии 0.7.3). Для mlx-lm поддержка пока экспериментальная.
Что нужно, чтобы MTP заработал
| Компонент | Минимальные требования | Рекомендация |
|---|---|---|
| GPU | 24 ГБ VRAM (3090/4090) | 48 ГБ (A6000, 2x3090 или 5090) |
| RAM | 32 ГБ | 64 ГБ для 262k контекста |
| Модель | Qwen 3.6 27B (оригинальные веса) | GGUF Q4_K_M (рекомендуемый баланс скорости и качества) |
| Фреймворк | llama.cpp от 06.05.2026 | Сборка с поддержкой CUDA и MTP |
Обратите внимание: 48 ГБ VRAM — это не жесткое требование, а граница, за которой MTP раскрывается полностью. На 24 ГБ вы тоже получите ускорение, но контекст придется ограничить до 32k, иначе не влезет кэш KV-кэша.
Пошаговая настройка
Давайте слепим работающего агента с нуля. Я предполагаю, что у вас Linux или WSL2 с CUDA 12.4+, Python 3.11 и Git.
1Скачать модель и конвертировать в GGUF
Оригинальные веса Qwen 3.6 27B занимают около 54 ГБ в float16. Нам нужно квантование. Лучше всего — Q4_K_M: даёт 16.5 ГБ, качество практически не теряется.
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
mkdir build && cd build
cmake .. -DLLAMA_CUDA=ON
make -j$(nproc)
# Скачиваем оригинальные веса (пример через huggingface-cli)
huggingface-cli download Qwen/Qwen3.6-27B --local-dir ./qwen3.6-27b
# Конвертируем в GGUF (ключ --mtp обязателен!)
python ../convert-hf-to-gguf.py ./qwen3.6-27b --outfile qwen3.6-27b-q4_k_m.gguf --outtype q4_k_m --mtp
Флаг --mtp заставляет конвертер вытащить MTP-голову и сохранить её как отдельный файл (внутри того же GGUF). Если его не указать, модель будет обычной — без ускорения.
Грабли: В первых билдах llama.cpp (февраль 2026) chat template для Qwen 3.6 был сломан — модель начинала циклически повторять последнюю строку. Фикс пришёл в виде обновления токенизатора в середине апреля. Убедитесь, что ваш билд llama.cpp не старше 25 апреля 2026.
2Запуск с MTP в llama.cpp
./main -m qwen3.6-27b-q4_k_m.gguf \
--mtp 5 \
--ctx-size 262144 \
--n-gpu-layers 99 \
--temp 0.2 \
--repeat-penalty 1.1 \
--prompt "<|system|>You are a coding agent...<|user|>Write a Python function to merge k sorted lists<|assistant|>"
Ключевые флаги:
--mtp 5— число токенов, которые предсказываются за раз. 5 — оптимум, 7 даёт ещё +10% скорости, но может деградировать качество на коротких генерациях.--ctx-size 262144— полный контекст. На 48 ГБ VRAM работает стабильно, на 24 ГБ потребует--ctx-size 65536.--n-gpu-layers 99— оффлоадить все слои на GPU.
При первом запуске вы увидите в логах что-то вроде MTP: enabled, draft tokens = 5. Если его нет — значит, GGUF собран без MTP-головы.
3Интеграция с агентом (llama-cpp-python)
Для локального кодинг-агента удобнее использовать Python-обёртку. В последних версиях llama-cpp-python (0.3.6+) есть поддержка MTP через аргумент mtp.
from llama_cpp import Llama
llm = Llama(
model_path="qwen3.6-27b-q4_k_m.gguf",
n_ctx=262144,
n_gpu_layers=99,
mtp=5, # Включаем MTP
verbose=True
)
output = llm(
"<|system|>You are a coding expert...<|user|>Explain the CAP theorem<|assistant|>",
max_tokens=2048,
temperature=0.2,
stop=["<|im_end|>", ""]
)
print(output["choices"][0]["text"])
Замер скорости: на RTX 4090 (24 ГБ) с Q4_K_M и MTP=5 получаем 45-50 токенов/с против 18-20 токенов/с без MTP. Разница — 2.5x. Причём на 48 ГБ (A6000) скорость доходит до 70 токенов/с за счёт большего batch size.
Грабли, которые я собрал за месяц
1. Chat template — проклятие Qwen. Если не обновить токенизатор до версии апреля 2026, модель на каждом втором ответе зацикливается. Симптом: после корректного ответа начинает повторять последнюю фразу. Решение — встроить правильный шаблон в GGUF при конвертации или использовать флаг --chat-template qwen3.
2. MTP не ускоряет короткие запросы. Если ваш промпт меньше 512 токенов, overhead от обработки нескольких гипотез больше, чем выигрыш. Для интерактивного чата (короткие вопросы-ответы) MTP лучше отключить (--mtp 0). Для кодинг-агента, который сначала загружает 10k токенов контекста, а потом генерирует 2000 токенов — MTP обязателен.
3. Не используйте Q2 или Q3 квантования с MTP. Деградация качества на многотокенной генерации накапливается, и модель начинает выдавать бессмыслицу. Q4_K_M — нижняя граница. Q5_K_M даёт ещё +5% качества, но съедает 2 ГБ VRAM.
4. Драфт-модели не нужны. Встречал попытки запустить MTP вместе с классическим speculative decoding (маленькая модель + большая). Это не имеет смысла: MTP уже использует встроенный драфтер внутри головы. Комбинирование только замедлит.
Если вам кажется, что MTP — это магия, почитайте как тот же подход реализован в mlx-lm для Apple Silicon. Там ускорение скромнее — 1.5x, но принцип тот же.
Почему именно 2.5x, а не 5x
Честно? Потому что голова MTP — это дополнительное вычисление. Вы не просто предсказываете 5 токенов даром, вы тратите compute на их проверку. Если draft-голова ошибается (а она ошибается часто), приходится делать rollback и пересчитывать. На практике соотношение принятых токенов (acceptance rate) для Qwen 3.6 — около 70-80%. То есть из 5 предсказанных токенов принимается 4. Это и даёт 4x скорость на идеальной математике, а с учётом накладных расходов — 2.5x.
Лучшие результаты — на кодовых задачах с чёткой структурой (функции, SQL, конфиги). Худшие — на свободном тексте с неожиданными поворотами. Если ваш агент постоянно пишет креативные письма — MTP не спасёт. Если он генерирует boilerplate — ускорение будет близко к 3x.
Сравните с настройкой Qwen 3.5 27B через vLLM — там другой подход, но MTP тоже даёт прирост, хоть и меньший из-за overhead фреймворка.
А что насчёт 48 ГБ VRAM
48 ГБ — это sweet spot. Вы можете держать полный 262k контекст в KV-кэше (Q4-квантование) и одновременно запускать MTP с batch size = 8. Это даёт ещё +20% скорости за счёт лучшей утилизации GPU. На 3090 с 24 ГБ придётся урезать контекст до 48k, иначе KV-кэш не поместится. Результат — 1.5x ускорение вместо 2.5x.
Если у вас 48 ГБ, но вы хотите выжать максимум, рассмотрите --mtp 7 и --batch-size 512. На A6000 я получал 85 токенов/с.
Быстрый чеклист перед запуском
- llama.cpp собран после 25 апреля 2026 (PR #5678)
- GGUF конвертирован с флагом
--mtp - Chat template соответствует Qwen 3.6 (исправлен токенизатор)
- Квантование Q4_K_M или выше
- Для коротких сессий — отключить MTP
- VRAM: хотя бы 24 ГБ (желательно 48 ГБ)
Помните: MTP даёт выигрыш только при достаточно длинных промптах (больше 512 токенов). Для коротких запросов overhead перевешивает. Проектируйте архитектуру агента так, чтобы большие контексты обрабатывались через MTP, а быстрые уточнения — без него.