
Помните DFlash? В начале года о нём много шумели: способ ускорить любую LLM, не трогая саму модель. Nvidia тогда выкатила заголовки «До 15x к пропускной способности на Blackwell». Цифра весомая, звучит как революция.
Мы, конечно, решили покрутить это вручную. Для этого взяли драфтер DFlash для Gemma 4 26B, который лежит прямо в репозитории модели, прогнали на своём стенде.
Но вместо 15x получили 2,3x, и только пока на карте висит один‑единственный запрос… Если запустить 4 пользователей одновременно — ускорение исчезает, а на 8 параллельных запросах DFlash начинает проигрывать.
Сейчас расскажу, откуда берутся магические 15x и почему наши графики расходятся с вендорскими.
Матчасть: за счёт чего DFlash вообще ускоряет
Обычная LLM генерирует текст последовательно: один проход по всем весам — один токен. Для одного пользователя это дико неэффективно. Чтобы выдать один токен, GPU прогоняет через память миллиарды параметров, и упирается не в вычисления, а в скорость памяти. Арифметические ядра в это время просто курят в сторонке.
Спекулятивное декодирование (speculative decoding) эту проблему решает красиво. Маленькая «черновая» модель быстро набрасывает несколько вероятных следующих токенов, а большая модель проверяет весь этот блок за один проход. Если префикс совпал — принимаем целиком, где разошлись — обрезаем хвост. Качество не страдает, потому что распределение вероятностей на выходе остаётся тем же. Это бесплатное ускорение с точки зрения математики.
Но узкое место — сам черновик. Классические методы (типа EAGLE-3) генерируют его тоже по одному токену. Пять черновых токенов = пять маленьких проходов. DFlash предлагает заменить это блочной диффузионной моделью: она выдаёт весь блок сразу, параллельно.
![EAGLE-3 достраивает черновик по одному токену за проход; DFlash предлагает сразу весь блок за один параллельный проход диффузионной модели, а целевая модель затем проверяет его целиком. [Источник: Nvidia] EAGLE-3 достраивает черновик по одному токену за проход; DFlash предлагает сразу весь блок за один параллельный проход диффузионной модели, а целевая модель затем проверяет его целиком. [Источник: Nvidia]](https://habrastorage.org/getpro/habr/upload_files/b9f/d50/d12/b9fd50d12d77ea6b5b93413fe2eb23fc.gif)
Чтобы черновик попадал точнее, ему скармливают внутренние признаки из большой модели: скрытые состояния целевой сети прокидываются напрямую в KV‑проекции каждого слоя драфтера. Авторы называют это KV injection. Это позволяет маленькой модели не гадать с нуля, а опираться на уже посчитанный контекст.
![Архитектура DFlash: контекстные признаки из целевой модели встраиваются в KV-проекции каждого слоя драфтера, что и держит высокую долю принятых черновиков. [Источник: arXiv] Архитектура DFlash: контекстные признаки из целевой модели встраиваются в KV-проекции каждого слоя драфтера, что и держит высокую долю принятых черновиков. [Источник: arXiv]](https://habrastorage.org/r/w1560/getpro/habr/upload_files/d8b/fff/85d/d8bfff85de724e22d0fd83b499cfc3bb.png)
В нашем случае черновик — это отдельный модуль на 451 МБ, пристёгнутый к MoE‑модели на 26B параметров. У нас он угадывал продолжение примерно в четверти случаев, а средняя длина принятого блока — 2,06 токена. То есть вместо одного токена за проход получаем в среднем два. Уже не 15x, правда?
Откуда взялись 15x
Цифра настоящая, но с кучей оговорок. Nvidia получила её на gpt‑oss-120b, восьми DGX B300 и TensorRT‑LLM, и не «вообще», а в очень конкретной точке кривой Парето — там, где на каждого пользователя приходится 500–600 токенов в секунду. Это режим максимальной отзывчивости: обычное авторегрессивное декодирование там почти нежизнеспособно, батч почти пустой, карта простаивает. DFlash в этой точке реально рвёт baseline, потому что сравнивают его с заведомо неэффективным режимом.
![Заявленные 15x – это самая левая, самая требовательная к отзывчивости точка кривой Парето. При более разумной конкурентности кривые DFlash и EAGLE-3 сближаются с базовой линией. [Источник: Nvidia] Заявленные 15x – это самая левая, самая требовательная к отзывчивости точка кривой Парето. При более разумной конкурентности кривые DFlash и EAGLE-3 сближаются с базовой линией. [Источник: Nvidia]](https://habrastorage.org/r/w1560/getpro/habr/upload_files/9f6/3d0/eb4/9f63d0eb46a176e91d215cac8be5cc33.webp)
Сдвинься в нормальный режим — и множитель сдувается. В той же статье Nvidia приводит таблицу при сопоставимой конкурентности: в среднем 2,3x для gpt‑oss-120b и 2,8x для Llama 3.1 8B. На одиночном запросе и одной карте — 5,8x на математике и 4,4x на коде для Gemma-4 31B. То есть сам вендор даёт разброс от 1,8x до 15x в зависимости от того, где мерить. 15x — это самый край.
Наши замеры: суровая реальность
Мы гоняли суммарную скорость генерации на своём стенде, постепенно добавляя одновременные запросы. Базовая линия — Gemma 4 26B без спекуляции, вторая колонка — та же модель с DFlash.
Стенд: одна Nvidia RTX 6000 PRO, драйвер 610.57.04, CUDA UMD 13.3, Docker 29.7.2, llama.cpp — server‑cuda сборка 10711. Модель gemma-4-26B-A4B-it-Q4_0, KV‑кеш q4_0, 512 токенов на запрос, длина черновика --spec-draft-n-max 4.
Одновременных запросов | База, ток/с | DFlash, ток/с | Отношение |
|---|---|---|---|
1 | 180.8 | 418.0 | 2.31x |
2 | 325.8 | 519.3 | 1.59x |
3 | 440.8 | 480.3 | 1.09x |
4 | 517.3 | 522.3 | 1.01x |
6 | 674.7 | 581.5 | 0.86x |
8 | 779.4 | 538.2 | 0.69x |

Смотрим на форму кривых, а не только на соотношения. База растёт почти линейно: 181 → 326 → 441 → 517 — каждый новый запрос добавляет почти столько же токенов, сколько первый. DFlash упирается в полку сразу после первого запроса и дальше болтается в коридоре 480–580. Перелом — около 4,1 запроса. И даже левый край нашего графика вдвое ниже вендорских 5,8x на соседней модели.
Важный нюанс: проигрывает сервер целиком, а не отдельный пользователь. На 8 параллельных запросах скорость одного потока у DFlash не опускалась ниже базовой (98,8 против 97,5 ток/с на поток). Просаживается именно суммарная пропускная способность: карта тратит такты на черновики, которые выбрасываются.
Почему конкурентность убивает ускорение
Обе техники — спекуляция и батчинг — живут за счёт одного ресурса: простаивающих арифметических блоков GPU. Поэтому они не складываются, а конкурируют.
Спекуляция тратит простой на черновые токены, часть которых гарантированно пойдёт в мусор. При одном запросе это ничего не стоит — блоки всё равно простаивали. Батчинг тратит тот же простой на чужие настоящие токены. Восемь параллельных запросов гоняют веса через память один раз на всех и считают восемь полезных токенов за проход — ни один не выбрасывается.
Как только батч заполняет карту, узкое место переезжает из памяти в вычисления. И вот тогда выброшенные черновые токены перестают быть бесплатными: они отъедают такты у реальной работы. Отсюда и полка на графике, и падение ниже базовой линии.
Это не баг DFlash, это его границы применимости. Индустрия про них знает: продакшен‑стеки умеют сами отключать спекуляцию при росте конкурентности, порог часто ставят в районе 32 одновременных последовательностей.
Наш перелом наступает раньше типичных 30+ запросов, потому что железо другое: одна карта вместо восьми B300, и стек — llama.cpp вместо TensorRT‑LLM. Смысл замера не в том, что Nvidia завысила, а в том, что множитель нельзя переносить со стенда вендора на свой кластер.
Почему ускорение работает только на математике и коде
Вторая интересная деталь: ускорение сильно зависит от того, о чём спрашивать. Внятный прирост мы получили на математике и генерации кода. На свободном тексте он исчезает или уходит в минус.
Отдельный прогон: один запрос на карте, 1024 токена, черновик до 15 токенов. Третья строка — режим mtp, второй способ спекуляции, гоняли за компанию.
Режим | Математика | Код | Проза | Среднее | К базе |
|---|---|---|---|---|---|
База | 188.0 | 189.6 | 189.4 | 189.0 | – |
DFlash | 303.9 | 254.5 | 179.1 | 245.8 | 1.30x |
MTP | 211.7 | 175.0 | 143.7 | 176.8 | 0.94x |
Математика — 1,62x, код — 1,34x, проза — 0,95x. На свободном тексте DFlash уже не помогает, а мешает. У mtp вообще математика вытянула лишь 1,13x, а код и проза ушли в минус — дальше мы его не рассматривали.
Заодно эта таблица объясняет, почему здесь 1,30x, а в развёртке выше — 2,31x. Дело в длине черновика. Пятнадцать токенов мы взяли из примеров в документации, и это оказался худший вариант: те же 1024 токена на n-max=4 дают 330,6 ток/с против 245,8 на n-max=15. Чем длиннее черновик, тем больше вычислений сгорает при отказе.
![Стоимость черновика у DFlash почти не зависит от глубины драфт-модели – все токены блока считаются за один параллельный проход. У авторегрессивного EAGLE-3 каждый дополнительный слой или токен – это ещё один последовательный проход. [Источник: arXiv] Стоимость черновика у DFlash почти не зависит от глубины драфт-модели – все токены блока считаются за один параллельный проход. У авторегрессивного EAGLE-3 каждый дополнительный слой или токен – это ещё один последовательный проход. [Источник: arXiv]](https://habrastorage.org/r/w1560/getpro/habr/upload_files/ff1/040/e3d/ff1040e3df8990ccca53e1c990f0d7e0.png)
Механика простая: черновая модель угадывает продолжение тем лучше, чем меньше в нём энтропии. В математике или коде следующие токены жёстко заданы синтаксисом и шаблоном. В живой прозе на каждом шаге десятки равновероятных продолжений, черновик мажет на второй‑третьей позиции, блок обрубается — и мы платим за весь просчитанный блок ради одного‑двух принятых токенов. Русский язык добивает токенизацией: на то же слово уходит больше токенов, значит больше шансов промахнуться.
Вендорские наборы (Math500, GSM8K, HumanEval, MBPP) — это самые предсказуемые тексты, какие есть. У самой Nvidia на «писательских» задачах множитель падает до 1,8x против 2,6x на коде.
Бонус: квантованный KV‑кеш съедает 39% скорости
Пока подбирали настройки, наткнулись на вещь, к DFlash не относящуюся, но куда более дешёвую в исправлении. Мы держали KV‑кеш квантованным (--cache-type-k/v q4_0) ради длинного контекста. Замена на f16 подняла базовую линию со 189 до 263,1 ток/с — на 39%, без всякой спекуляции. На восьми параллельных запросах — 917 против 784.
Бесплатным выигрыш не бывает: f16‑кеш занимает вчетверо больше памяти. Но порядок величины показателен: прежде чем прикручивать спекуляцию, посмотри, не отдал ли ты те же 39% на квантовании кеша.
И это же — иллюстрация главного тезиса. На q4_0‑кеше лучший вариант DFlash давал 1,75x к базе, на f16 — уже 1,35x. Чем аккуратнее выжат базовый инференс, тем меньше остаётся выжать спекуляции.
Выводы
DFlash — хорошая инженерия с узкой областью применения, а не бесплатное ускорение для всех. Он окупается там, где важна скорость для одного пользователя, а не суммарная пропускная способность железа: локальный запуск на одной карте, ассистент в IDE, автодополнение кода, вызовы инструментов у агента. В этих сценариях карта действительно недогружена, и спекуляция забирает себе простой, который иначе пропал бы зря. Причём чем медленнее карта, тем спекуляция выгоднее.
Там, где на карте живёт очередь из пользователей — то есть в любом публичном сервисе — выгоднее обычный батчинг, и включённая спекуляция начинает мешать. Вывод практический и скучный: свою конфигурацию надо мерить самому, на своих задачах, своих языках и своей реальной конкурентности. Один множитель из пресс‑релиза не переносится никуда.
Что у нас
Мы этот вывод применили к себе.
В GPTunnel есть Grom 1.5 — наша собственная бесплатная модель на нашем железе.
И мы гнались там ровно за тем, что чувствует пользователь: первый токен примерно через 500 мс и до 120 токенов в секунду в потоке. Достигнуто это контролем всего стека: балансировщик разводит запросы по пулам под вес задачи, префикс диалога лежит в памяти GPU, а размер модели подобран под то железо, на котором она реально крутится.
☞ P. S. Понравилась статья? У нас в блоге на сайте таких много.

