Пять способов ускорить локальный инференс MoE-модели: один я написал сам. llm.. llm. moe.. llm. moe. Open source.. llm. moe. Open source. prefix caching.. llm. moe. Open source. prefix caching. strata.. llm. moe. Open source. prefix caching. strata. инференс.. llm. moe. Open source. prefix caching. strata. инференс. искусственный интеллект.. llm. moe. Open source. prefix caching. strata. инференс. искусственный интеллект. Машинное обучение.. llm. moe. Open source. prefix caching. strata. инференс. искусственный интеллект. Машинное обучение. оптимизация.

В предыдущей статье я разбирался, какие эксперты реально живут в VRAM у Strata, пока она крутит Qwen3.8-Flash-Next на GTX 1070. На этот раз – короче и практичнее: несколько конкретных приёмов ускорения, которые стоит проверить, если вы гоняете большую MoE-модель на домашнем железе. Один из них – патч, который я написал и прогнал сам, с цифрами “было/стало” на реальном движке. Остальные – то, что уже работает в Strata “из коробки”, просто не всегда включено и не всегда замечено.

1. Спекулятивное декодирование (MTP/drafting)

Идея старая (ещё с speculative decoding для dense-моделей): маленький “черновой” слой предсказывает несколько токенов вперёд, большая модель проверяет их все за один проход вместо одного токена за раз. Если угадал – считаем сразу несколько токенов по цене одного forward pass.

В Strata это --spec N --mtp <путь>: за одно окно верификации проверяется до N предложенных токенов. Цена – чуть VRAM под черновой слой и буферы, выгода – чаще 1.3-1.6x к скорости генерации, когда черновик угадывает хорошо (код и повторяющиеся паттерны – угадывает отлично, свободная проза – похуже). Включается почти бесплатно, если черновая модель уже скачана.

2. KV-кэш в RAM, а не в VRAM (–kv-resident)

На картах, где VRAM в дефиците (как у меня – 8 GB), обычный путь – ужимать контекст или квант. Но есть менее очевидный рычаг: --kv-resident N держит в VRAM только скользящее окно внимания (N токенов), а весь KV-кэш целиком утекает в pinned RAM.

Выигрыш не в скорости самого внимания – а в том, что освобождённая VRAM достаётся кэшу экспертов. Для MoE это обычно выгоднее: лишний гигабайт под резидентные эксперты снижает долю обращений к CPU/PCIe чаще, чем экономия на KV ускоряет attention. Проверяется легко – смотрите в логе долю expert cache N% hit до и после.

3. Батчинг нескольких запросов в одно окно (–batch/–parallel)

Если вы обслуживаете больше одного пользователя (или просто гоняете несколько параллельных агентов), --batch N – это continuous batching по сути: несколько разговоров декодируются в общих окнах верификации, так что общие веса (dense-слои, общий эксперт) читаются один раз на все, а не по разу на каждого.

На одной карте выигрыш в основном не в throughput на одного пользователя (он чуть падает из-за долей cache), а в том, что никто не ждёт в очереди, пока обслуживается другой. На нескольких GPU с layer-split цифры куда интересней – в docs/BATCHING.md у Strata разложено по полочкам, вплоть до того, сколько слотов стоит VRAM и когда --batch-groups важнее serial-режима.

4. Адаптивная резидентность экспертов

Это основная фишка Strata, про которую – вся предыдущая статья: кэш экспертов не статичен, он сам перекладывает веса между VRAM/RAM/SSD по частоте обращений, причём делает это прямо во время батч-окон, не останавливая генерацию (--adapt-every, --adapt-swaps). В этой статье не повторяю детали – но если вы ещё не включили адаптацию и сидите на статичном профиле экспертов, это первое, что стоит проверить: разница между “застывшим” и “живым” кэшем на моём железе была от 1.5x до 2x в зависимости от того, насколько однороден поток промптов.

5. Автоматическое обнаружение общего префикса – то, что я добавил сам

Вот тут я встал в тупик с хорошим вопросом: а что если клиент – обычный OpenAI-совместимый чат-бот и вообще не знает про strata_prefix?

У Strata уже есть механизм: клиент может явно пометить, где в промпте кончается общая часть (strata_prefix: {"tokens": N}), и движок запинивает чекпоинт на этой границе – следующий запрос с тем же началом не перечитывает её заново. Работает отлично, но требует, чтобы клиент сам это посчитал и прислал. На практике это почти никто не делает – ни агентные фреймворки, ни простые чат-клиенты.

Я добавил небольшой слой на стороне сервера (STRATA_AUTO_PREFIX=1, по умолчанию выключено): он держит radix-trie по id токенов недавно принятых промптов и бюджет на количество одновременных “пинов” (каждый пин – это VRAM, отнятая у кэша экспертов, бесплатных пинов не бывает). Когда приходит новый запрос без явного strata_prefix, сервер сам ищет совпадение и подставляет границу – движок не видит разницы между “клиент сказал” и “сервер догадался”.

Проверил на реальном движке (Strata 0.2.12, build 0.1.58, одна GTX 1070 8 GB, Qwen3.8-Flash-Next UD-IQ4_XS), два клиента с одним длинным общим документом, никто не шлёт strata_prefix вручную:

STRATA_AUTO_PREFIX выключен

STRATA_AUTO_PREFIX=1

медиана перечитанных токенов

886

468

медиана токенов из кэша

0

413

медиана времени до первого токена

13.3 с

6.1 с

Как и обязательные для апстрима before/after на одном железе – это не “похоже на x2”, это два прогона одного и того же бенчмарка на одной машине, отличается только одна переменная среды.

Код – в ветке DmNep/Strata@auto-prefix-cache, тесты (22 кейса на mock-движке + полный regression-прогон 451 существующих тестов) там же. Предложил фичу мейнтейнерам апстрима как issue, не PR – у них в CONTRIBUTING.md чётко написано: для нетривиальных фич сначала согласовать scope, а не сразу тащить код. Обсуждение – Niko1221/Strata#5808.

Итого

Из пяти способов четыре уже есть в Strata и просто ждут, чтобы их включили; пятый – моя добавка сверху, по мотивам того, что реальные клиенты обычно не знают о таких механизмах и их нужно обнаруживать автоматически. Если у вас MoE-модель на скромной карте – начните с проверки --kv-resident и --spec/--mtp, это обычно самый быстрый выигрыш без переписывания ни строчки кода.

Автор: DmNep

Источник