Перейти к содержанию
Публикация AiManual

Оптимизация локального инференса MoE-моделей в llama.cpp: патчи, бенчмарки и что реально ускоряется на RTX 4080

Многочасовой эксперимент по ускорению MoE-инференса в llama.cpp без изменения весов: где патчи дают прирост на RTX 4080, какие регрессии и компромиссы нашлись и

Коротко

Что будет в материале

  1. 01

    Что именно проверяли: MoE-инференс в llama.cpp без изменения весов

  2. 02

    Что реально ускоряется: prompt processing и редактирование кода

  3. 03

    Где оптимизация проигрывает: регрессии и компромиссы

  4. 04

    Качество вывода: что показывают проверки корректности и чего они не доказывают

Ускорение локального MoE-инференса в llama.cpp дало измеримый результат: заметный прирост на обработке промптов и на задачах редактирования исходного кода, при неизменных весах и квантовании модели. Автор разбора потратил на эксперименты несколько часов и проводил их с помощью агента Astra.

Тестовая конфигурация: RTX 4080 с 16 ГБ VRAM, Ryzen 9 5900X и 64 ГБ DDR4. В экспериментах участвовали две MoE-модели, Qwen3.6-35B-A3B и Qwen3.8 Flash-Next. Цель формулировалась просто: поднять производительность, не потеряв качество вывода. Исходные патчи, сводки бенчмарков и руководства по воспроизведению опубликованы в открытом репозитории Abzolute1/llama-cpp-optimization-lab.

Границы доказанного обозначены сразу. Тесты включают проверки корректности, но не доказывают, что качество осталось неизменным на всех типах задач. Портативная сборка с нуля ещё не прошла сквозную валидацию. Автор прямо приглашает к независимому воспроизведению, особенно на другом железе, и не выдаёт свои цифры за универсальные. Если ваши задачи далеки от prompt processing и правки кода, рассчитывать на большой выигрыш не стоит.

Что именно проверяли: MoE-инференс в llama.cpp без изменения весов

Почему MoE-модели - отдельная история для локального запуска

В MoE-архитектуре на каждый токен активируется лишь часть экспертов, а не вся сеть целиком. Модель может содержать десятки миллиардов параметров, но вычислений на один токен тратить меньше, чем плотная модель сопоставимого размера. Суффикс A3B в имени Qwen3.6-35B-A3B как раз про это: общее число параметров около 35B, активных заметно меньше.

Для локального запуска такое устройство смещает узкое место. Чистые FLOPs перестают быть главным ограничением, зато растёт вес памяти, батчинга и эффективности prompt processing. Веса всех экспертов всё равно лежат в VRAM или оперативной памяти, даже если в конкретном токене работает их малая доля. На карте с 16 ГБ это ключевой момент: считать модель будет быстро, а вот поместить её целиком может не получиться.

Как соотносятся prefill и decode в MoE-моделях и почему эти две фазы ведут себя по-разному, подробно разбирается в материале про Qwen3.8-Next на Mac M5 Air: там же про 3-битную квантизацию и разницу между обработкой промпта и генерацией по одному токену.

Что было зафиксировано до оптимизации: базовые метрики

Схема сравнения стандартная для таких работ: baseline-прогон llama.cpp и пропатченная сборка на тех же моделях, том же железе и одинаковых промптах. Без baseline любой прирост превращается в гадание, поэтому в исследовании сначала фиксировались исходные значения, а уже потом накатывались изменения.

Конкретные tok/s и полные таблицы лежат в репозитории автора. В статье полезнее качественная картина, потому что она переносится на другое железо лучше, чем абсолютные числа: прирост концентрируется в обработке промптов и правке кода, часть нагрузок остаётся нейтральной, а отдельные сценарии уходят в минус. Именно этот расклад и стоит проверять на своей конфигурации.

Что реально ускоряется: prompt processing и редактирование кода

Prompt processing: почему длинный контекст выигрывает больше всего

Prefill обрабатывает весь промпт параллельно, целыми батчами токенов. Оптимизации, которые автор внёс в llama.cpp, работают именно с этой фазой: они лучше раскладывают батчи и эффективнее используют память. Чем длиннее вход, тем больше разница между baseline и пропатченной сборкой.

Отсюда практические сценарии, где эффект заметен: анализ большого файла или репозитория, вставка RAG-контекста на десятки тысяч токенов, длинные системные инструкции. На коротком промпте в пару сотен токенов оптимизировать почти нечего, и выигрыш будет близок к нулю.

Редактирование исходного кода: где патчи дают практическую пользу

Source-code editing - второй сценарий с существенным приростом. Логика простая: модель получает один крупный файл или несколько связанных файлов, а на выходе отдаёт diff или патч. Такая задача упирается в prefill не меньше, чем в генерацию, поэтому оптимизации обработки промптов дают здесь реальный эффект.

Для code-assist это означает более быструю реакцию на запросы вида «перепиши этот модуль», «найди причину падения в этом файле», «собери исправление по логу ошибки». Ограничение тоже стоит держать в голове: корректность на code-задачах проверялась, но неизменность качества на всех типах задач не доказана, поэтому собственный прогон на своих репозиториях обязателен.

Отдельно про генерацию токенов. Decode работает по одному токену за шаг, и оптимизации под параллельный prefill сюда почти не переносятся. Если ваш сценарий - длинный свободный чат с короткими репликами, ощутимого ускорения ждать не стоит.

Где оптимизация проигрывает: регрессии и компромиссы

Регрессии в эксперименте зафиксированы, и они задокументированы вместе с результатами. Это нормальная цена за ускорение prefill: чем агрессивнее раскладка батчей и работа с памятью, тем выше шансы, что на другой нагрузке конфигурация окажется хуже baseline.

Похожие эффекты встречаются и за пределами этого исследования. В разборе DeepSeek-V4-Flash на одном B300 видно, как MoE-ядро отказывает без expert parallel, а производительность проседает в насыщенном батче. Вывод один: MoE-нагрузки чувствительны к режиму батчинга, и настройка, выигрышная на одном профиле запросов, проигрывает на другом.

VRAM и память: чем приходится платить

Оптимизации prompt processing часто требуют больше промежуточных буферов. Пиковое потребление VRAM при этом растёт, и на 16 ГБ это критично именно при длинном контексте, где выигрыш максимален. Практический минимум: держать открытым мониторинг вроде nvidia-smi и подбирать длину контекста и размер батча так, чтобы оставался запас.

Память распределяется между весами, KV-кэшем и буферами активаций, и KV-кэш растёт линейно с длиной контекста. Как эти составляющие влияют на выбор модели и стоимость инференса, разобрано в отдельном материале про контекстное окно, KV-cache и VRAM. Универсальных цифр для «сколько ставить» нет: они зависят от квантизации и профиля задач.

Когда патчи лучше не применять

  • Короткие промпты и чат с малым контекстом: оптимизировать нечего.
  • Сценарии, где критична максимальная скорость генерации токенов, а не prefill.
  • Конфигурации с малым запасом VRAM, где лишние буферы ведут к OOM.
  • Продакшн без возможности быстро откатиться на baseline.

Рабочий порядок действий простой: сначала baseline, потом патч, потом сравнение на своих промптах. Включать патчи вслепую и удивляться регрессии - самый быстрый способ разочароваться в идее.

Качество вывода: что показывают проверки корректности и чего они не доказывают

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

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

Как самостоятельно проверить деградацию на своих задачах

  1. Соберите 10-20 типовых промптов из своей реальной работы, включая хотя бы пару длинных и пару code-задач.
  2. Зафиксируйте параметры: temperature, seed, длина контекста, квантизация, версия сборки.
  3. Прогоните набор на baseline и на пропатченной сборке.
  4. Сравните выходы через diff или ручную вычитку, отдельно оценивая code-задачи и длинный контекст.
  5. Записывайте рядом tok/s и субъективную оценку качества, чтобы видеть, где именно прирост окупается.

Такой прогон даёт практический sanity check, а не статистическую значимость. Для большинства домашних сценариев этого достаточно: явная деградация на ваших промптах видна сразу.

Как воспроизвести: патчи, сборка и бенчмарки из репозитория

Точка входа - открытый репозиторий Abzolute1/llama-cpp-optimization-lab, где лежат исходные патчи, сводки бенчмарков и руководства по воспроизведению. Маршрут выглядит так: взять исходники llama.cpp, применить патчи, собрать с поддержкой CUDA, скачать Qwen MoE-модель в подходящем квантовании, прогнать baseline и пропатченную сборку на одинаковых промптах.

Важная оговорка: портативная сборка с нуля пока не прошла сквозную валидацию. Подавать её как готовое решение в один клик нельзя, часть шагов придётся проверять и отлаживать самостоятельно. Результаты также зависят от версии llama.cpp и от железа.

Сборка llama.cpp с патчами: на что смотреть

Версия llama.cpp и версия патчей должны совпадать: расхождение в коммитах даёт конфликты при применении и непредсказуемое поведение. Сборку под CUDA проверяйте на этапе конфигурации, а после сборки убедитесь, что патчи применились без откатов. Зафиксируйте хеш коммита, иначе воспроизвести замеры через неделю будет невозможно.

Методика бенчмарков: что и как мерить

Сравнимые цифры получаются при одинаковых моделях, квантовании, длине контекста и seed. GPU стоит прогреть, а замеры повторить несколько раз и смотреть не на лучший, а на устойчивый результат. Метрики нужны раздельные: отдельно prompt processing, отдельно генерация токенов. Иначе ускорение prefill легко спутать с общим ускорением инференса.

Хороший пример честного разделения этих фаз и методики сравнения нескольких рантаймов описан в разборе про Qwen 3.8 27B на одной RTX 5090: там показано, почему prefill и decode нужно мерить по отдельности и как не перепутать эффект от кэша с эффектом от самих изменений.

Запуск Qwen MoE локально в llama.cpp: базовый маршрут до патчей

До экспериментов с патчами модель должна просто работать в llama.cpp. Выберите квантование под свои 16 ГБ VRAM, скачайте Qwen3.6-35B-A3B или Qwen3.8 Flash-Next, запустите и замерьте baseline на своих промптах. Без этой точки отсчёта патчи бессмысленны: вы не поймёте, помогли они или навредили.

При нехватке VRAM MoE-модель может частично выгружаться в оперативную память. Скорость при этом падает заметно, и часть прироста от оптимизаций просто съедается обменом с RAM. Поэтому первый шаг - подобрать конфигурацию, которая стабильно держится в памяти.

Сколько VRAM нужно и что делать с 16 ГБ

Итоговое потребление зависит от квантования, длины контекста и размера KV-кэша. На 16 ГБ почти всегда приходится выбирать компромисс: агрессивнее квантизация или короче контекст. MoE-архитектура снижает вычислительную нагрузку, но веса всех экспертов всё равно занимают память, и это ограничение никуда не уходит.

Практичный старт: умеренный контекст, мониторинг VRAM в отдельном окне, постепенное увеличение длины до появления первых признаков нехватки памяти. Дальше можно экспериментировать с квантованием и только после этого переходить к патчам.

Что это значит для владельца RTX 4080 и кому стоит пробовать

Результаты получены на конкретной связке: RTX 4080, Ryzen 9 5900X, 64 ГБ DDR4, две Qwen MoE-модели. На другом железе абсолютные цифры будут другими, а соотношение между нагрузками вполне может сохраниться: prefill и code-editing выигрывают, короткий чат и decode почти нет.

Кому патчи дадут максимум, а кому - нет

Стоит пробовать, если вы работаете с длинным контекстом, гоняете RAG или агентов, активно используете code-assist и готовы тестировать, сравнивать и откатывать сборку при регрессиях. Сюда же попадают те, кто уже собирал llama.cpp из исходников и понимает, что такое версия коммита и флаги CUDA.

Пробовать не стоит, если ваши сценарии - короткий чат, если VRAM уже под завязку, если важнее всего скорость генерации токенов или если сборка идёт в продакшн без возможности валидации. В этих случаях оптимизации под prompt processing не окупят возни.

Как присоединиться к независимому воспроизведению

Портативная сборка с нуля ещё не прошла сквозную валидацию, поэтому прогоны на другом железе особенно ценны. Формат вклада простой: воспроизвести бенчмарки, зафиксировать конфигурацию и версию llama.cpp, указать квантование, привести отдельные цифры для prompt processing и генерации и сообщить о расхождениях с результатами автора. Точка входа - репозиторий Abzolute1/llama-cpp-optimization-lab, где лежат патчи и руководства.

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

Подписаться на канал