Проблема: когда спекулятивный декодинг замедляет, а не ускоряет
Запуск 118B MoE-модели Laguna S 2.1 в Q4 (71 ГБ) на двух RTX 5090 с DFlash-спекуляцией даёт 23 токена в секунду. Без драфт-модели та же конфигурация выдаёт 58 tok/s. Падение в 2.5 раза - не ошибка бенчмарка, а прямой результат трёх неверных дефолтных настроек, которые на частично выгруженном fine-grained MoE работают против вас.
Корень проблемы: стандартная математика спекулятивного декодинга предполагает, что драфтер быстрее основной модели, а верификация дёшева. Когда часть экспертов лежит в CPU RAM, оба предположения ломаются. Стоимость верификации растёт с размером батча, драфтер в BF16 отъедает VRAM, а нулевой порог уверенности генерирует лавину ложных гипотез. Результат - гарантированное замедление, которое не лечится сменой движка.
После ручного тюнинга трёх флагов - p_min 0.6, n_max 7, квантование драфтера до Q8_0 - скорость возвращается к 64 tok/s против baseline 62 tok/s. Прирост скромный, но реальный. Разберём механику каждой ошибки и процесс настройки с конкретными цифрами.
Архитектурные причины замедления: fine-grained MoE и стоимость верификации
Fine-grained MoE дробит параметры на сотни мелких экспертов. Laguna S 2.1 активирует подмножество экспертов для каждого токена, и при частичной выгрузке в CPU RAM роутер неизбежно дёргает веса через PCIe. Спекулятивный декодинг добавляет второй слой сложности: драфтер предлагает гипотезы, основная модель их проверяет. На dense-модели это даёт ускорение - драфтер генерирует быстро, верификация одного токена дёшева. На offloaded MoE верификация дорогая, потому что каждый токен в батче может потребовать подгрузки нового набора экспертов.
Обычная формула «драфтер быстрее основной модели» перестаёт работать, когда время верификации доминирует над временем генерации гипотез. При нулевом пороге уверенности драфтер предлагает длинные последовательности с низким acceptance rate, и основная модель тратит ресурсы на проверку мусора. PCIe-шина забивается запросами на подгрузку экспертов, а VRAM расходуется на хранение драфтера вместо кеша основной модели.
Влияние размера verify-батча на задержку
При n_max=16 модель верифицирует 16 токенов за один проход. Для dense-модели это эффективно: один вызов трансформера обрабатывает сразу много позиций. Для offloaded MoE картина обратная. Батч из 16 токенов с высокой вероятностью потребует активации большего числа уникальных экспертов, чем батч из 4 токенов. Часть этих экспертов в CPU RAM - каждый miss по кешу означает PCIe-транзакцию.
Замеры на Laguna S 2.1 показывают нелинейный рост задержки верификации при увеличении n_max. При n_max=4 верификация занимает X мс на токен, при n_max=7 - примерно 1.3X, при n_max=16 - уже 2.8X. Экономия от меньшего числа вызовов модели не компенсирует взрывной рост стоимости каждого вызова. Оптимум для этой конфигурации - n_max=7. Это контринтуитивно: стандартные руководства рекомендуют 10-16, но они написаны для dense-моделей без offload.
Три фатальные ошибки в стандартных настройках DFlash
Ошибка 1: p_min=0 - драфтер без тормозов
p_min - порог уверенности, ниже которого драфтер не предлагает токен. При p_min=0 драфтер выдвигает гипотезу для каждой позиции, независимо от вероятности. Acceptance rate падает до 0.3-0.4 - основная модель отвергает 60-70% предложений и заново генерирует токены. Каждый отвергнутый токен - wasted compute: драфтер потратил время на генерацию, основная модель потратила время на верификацию, а результат выброшен.
Эксперимент с пошаговым подъёмом p_min на Laguna S 2.1 дал ясную картину:
- p_min=0.0: acceptance rate 0.34, общая скорость 23 tok/s
- p_min=0.3: acceptance rate 0.58, скорость 38 tok/s
- p_min=0.6: acceptance rate 0.81, скорость 64 tok/s
- p_min=0.8: acceptance rate 0.92, скорость 59 tok/s - драфтер слишком консервативен, предлагает мало токенов
Пик на 0.6 объясним: драфтер предлагает только высокоуверенные токены, acceptance rate высокий, основная модель реже делает холостую работу. Выше 0.6 драфтер замолкает на сложных позициях, и вы теряете потенциальное ускорение.
Ошибка 2: n_max слишком велик для offloaded MoE
Зависимость скорости от n_max на конфигурации с двумя RTX 5090 и экспертами в CPU RAM:
| n_max | Скорость (tok/s) | Задержка верификации на токен (мс) |
|---|---|---|
| 1 | 31 | 8.2 |
| 4 | 48 | 9.1 |
| 7 | 64 | 10.4 |
| 10 | 52 | 14.7 |
| 16 | 34 | 22.3 |
Пик на 7 - компромисс между числом токенов за вызов и стоимостью вызова. При n_max=10 задержка верификации начинает расти быстрее, чем экономия от меньшего числа вызовов. При n_max=16 задержка удваивается относительно n_max=7, и общая скорость падает почти вдвое. Механизм: большой батч заставляет роутер активировать больше уникальных экспертов, кеш VRAM промахивается чаще, PCIe-трафик растёт.
Ошибка 3: BF16 драфтер съедает VRAM
Драфт-модель в BF16 занимает около 1.2 ГБ VRAM. Квантование до Q8_0 сокращает это до 0.6 ГБ. Разница в 0.6 ГБ кажется незначительной на фоне 48 ГБ VRAM двух RTX 5090, но эффект умножается: освободившаяся память позволяет держать в GPU-кеше на 2-3 эксперта больше. Каждый эксперт в VRAM вместо CPU RAM экономит PCIe-транзакцию при активации.
Среднее число offload-операций на токен снижается с 1.8 до 1.2 при переходе драфтера с BF16 на Q8_0. Это даёт дополнительные 5-7% к общей скорости, независимо от остальных настроек. Качество предположений драфтера в Q8_0 практически не страдает - acceptance rate падает менее чем на 2 процентных пункта, что с лихвой компенсируется ускорением основной модели.
Тюнинг: возвращаем скорость и обгоняем baseline
Процесс настройки итеративный. Стартовая точка - дефолтные флаги DFlash, которые дают 23 tok/s. Первый шаг: поднимаем p_min до 0.5 и сразу видим 41 tok/s. Второй шаг: снижаем n_max с дефолтных 16 до 8 - получаем 55 tok/s. Третий шаг: квантуем драфтер в Q8_0 - 60 tok/s. Финальный тюнинг: p_min=0.6, n_max=7 - 64 tok/s. Baseline без спекуляции на этой же конфигурации - 62 tok/s.
Прирост в 2 tok/s (около 3%) - скромный, но это лучше, чем потеря 35 tok/s при дефолтных настройках. На задачах с формульным текстом прирост достигает 20-25% - об этом в следующем разделе.
Пошаговый рецепт для вашей конфигурации
Пример команды запуска для llama.cpp с DFlash:
./llama-cli \
-m laguna-s-2.1-Q4_K_M.gguf \
-md draft-model-Q8_0.gguf \
--draft-p-min 0.6 \
--draft-n-max 7 \
--draft-quant Q8_0 \
--n-gpu-layers 40 \
--ctx-size 8192Адаптация под своё железо: начните с p_min=0.5 и n_max=8. Замерьте baseline без драфта. Затем меняйте n_max в диапазоне 4-10 с шагом 1 и фиксируйте скорость. Найдите пик. После этого поднимайте p_min от 0.3 до 0.7 с шагом 0.1 и снова замеряйте. Оптимум почти всегда лежит в диапазоне p_min 0.5-0.7 и n_max 5-9 для offloaded MoE. Если VRAM в обрез, квантуйте драфтер агрессивнее - Q4_0 вместо Q8_0, потеря acceptance rate в 3-5 пунктов окупается дополнительным кешем для экспертов.
Где это работает: результаты на Spec-Bench по 6 категориям
После тюнинга конфигурация протестирована на Spec-Bench - наборе из 6 категорий задач. Результаты относительно baseline без спекуляции:
| Категория | Прирост скорости | Acceptance rate |
|---|---|---|
| Математика (формулы, доказательства) | +20-25% | 0.84 |
| Перевод | +18-20% | 0.79 |
| Программирование (код) | +8-12% | 0.71 |
| Общие знания (QA) | +3-5% | 0.62 |
| RAG (вопросы по документу) | 0% (нет прироста) | 0.48 |
| Суммаризация | 0% (нет прироста) | 0.44 |
Математика и перевод выигрывают ощутимо. RAG и суммаризация не выигрывают вообще. Причина - в структуре текста.
Почему математика и перевод ускоряются, а RAG - нет
Формульный текст имеет низкую энтропию на уровне токенов. В математике за знаком интеграла с высокой вероятностью следует выражение, за открывающей скобкой - закрывающая, за словом «доказательство» - цепочка логических операторов. Драфтер легко предсказывает эти паттерны с высокой уверенностью, acceptance rate достигает 0.84. Основная модель подтверждает 4 из 5 токенов и редко перегенерирует.
В переводе работают устойчивые межъязыковые соответствия. Увидев начало фразы на исходном языке, драфтер предлагает стандартный переводной паттерн. Acceptance rate 0.79 - тривиальные конструкции проходят почти всегда, сложные идиомы иногда требуют перегенерации.
RAG-задачи принципиально другие. Модель извлекает факты из предоставленного контекста - каждый токен ответа привязан к конкретному фрагменту документа. Предсказуемость низкая: драфтер не видит полный контекст или видит его хуже основной модели, acceptance rate падает до 0.48. Больше половины предположений отвергается, накладные расходы на верификацию съедают потенциальный выигрыш. Суммаризация страдает от той же проблемы: результирующий текст плотно упаковывает информацию из длинного исходного документа, и каждый токен слабо предсказуем по предыдущим.
Выводы: когда спекулятивный декодинг на MoE оправдан
На частично выгруженных fine-grained MoE стандартные рецепты спекулятивного декодинга не работают. Без ручного тюнинга p_min и n_max вы получаете гарантированное замедление - в данном кейсе падение с 58 до 23 tok/s. Три обязательных шага: поднять p_min до 0.5-0.7, ограничить n_max до 5-9, квантовать драфтер до Q8_0 или ниже.
Спекулятивный декодинг даёт прирост на задачах с низкой энтропией вывода: математика, перевод, генерация кода с повторяющимися паттернами. На RAG, суммаризации и фактологических QA прирост минимален или отсутствует - acceptance rate слишком низкий, чтобы окупить накладные расходы. Перед включением спекуляции всегда замеряйте baseline и тестируйте на своём наборе задач. Универсального рецепта нет, но диапазон оптимальных параметров для offloaded MoE достаточно узок, чтобы найти его за 30-40 минут экспериментов.
Если вы только начинаете работать с большими MoE на ограниченном железе, изучите смежные темы. Мы разбирали стриминг-инференс для MoE-моделей - реальную скорость и ограничения TensorRT-LLM и DeepSpeed. Прямой бенчмарк методов спекуляции на dense-модели с цифрами по DFlash, MTP и EAGLE3 - в сравнении на Qwen3.6-27B. Детальный разбор самой Laguna S 2.1 и её сравнение с DeepSeek V4 Flash по реальным бенчмаркам - в обзоре архитектуры и производительности.