Зачем нужен спекулятивный декодинг?
Автографционные большие языковые модели (LLM) генерируют текст токен за токеном, каждый токен ждёт завершения предыдущего. Такая последовательность не использует возможности современных GPU, а при длинных цепочках рассуждений (Chain‑of‑Thought) латентность становится основной проблемой.
Традиционное решение: спекулятивный декодинг
Классический подход предлагает «черновой» модель, которая предсказывает несколько токенов вперёд, а большая целевая модель проверяет их параллельно. При согласии токены сохраняются, иначе откатываются. Но большинство методов, включая лидера EAGLE‑3, всё равно черновик работает авто‑регрессивно, что ограничивает ускорение 2‑3×.
Что изменил DFlash?
DFlash (z‑lab, UC San Diego) заменил автогенерацию черновика блочным диффузионным моделем. Вместо одного токена за раз он генерирует сразу блок (например, 16 токенов) в одном проходе, а целевая модель проверяет весь блок параллельно.
- Скорость ускорения в исследованиях достигает более 6× (lossless) и до 15× пропускной способности на NVIDIA Blackwell при фиксированном уровне интерактивности.
- Черновой моделью выступает лёгкий пятислойный диффузионный блок (для Qwen3‑Coder — восемь слоёв), а не тяжёлый 7B‑модуль, используемый ранее.
Как работает блок‑диффузионный черновик
Диффузионные модели «очищают» блок замаскированных токенов за один проход, объединяя параллелизм с автогенеративной структурой. DFlash использует эту идею только для черновика, а проверку оставляет надёжной автогенеративной модели. Это позволяет:
- Сохранять качество: целевая модель гарантирует, что финальный вывод остаётся точным.
- Платить фиксированную стоимость черновика независимо от размера блока, что открывает возможность использовать более выразительные черновики без роста латентности.
«Целевая модель знает лучше» – ключевая идея
DFlash извлекает скрытые состояния из нескольких слоёв целевой модели, объединяет их в компактный контекстный вектор и подаёт в каждый слой черновой модели (Key‑ и Value‑проекции KV‑кеша). В отличие от EAGLE‑3, где сигнал «рвётся» уже на входных эмбеддингах, такой глубокий ввод сохраняет полезную информацию на всю глубину черновика, позволяя принимать больше токенов за один блок.
Сравнительные цифры
В оригинальной работе DFlash показывает среднее ускорение 4.86× на Qwen3‑8B (жадный декодинг, Transformers‑backend) и максимум 6.08× на наборе MATH‑500. По сравнению, EAGLE‑3 достигает лишь ~1.8‑2.0×.
Тесты NVIDIA (TensorRT‑LLM, 8 GPU Blackwell, gpt‑oss‑120b) фиксируют до 15× пропускной способности при тех же требованиях интерактивности, что примерно на 1.5× быстрее, чем EAGLE‑3.
Практические случаи применения
- Кодирующие агенты: быстрый отклик важен в интерактивных IDE. На Gemma‑4 31B DFlash даёт до 5.8× ускорения на Math500 и 5.6× на HumanEval.
- Модели рассуждения: длинные цепочки мысли (Chain‑of‑Thought) обычно занимают большую часть времени генерации. DFlash сохраняет около 4.5× ускорения на Qwen3‑4B/8B при жадном декодинге и ~3.9× при сэмплинге.
- Сервисные нагрузки: в сочетании с SGLang на GPU B200 DFlash приносит до 5.1× ускорения на Qwen3‑8B (Math500, одиночный запрос). При росте конкурентности ускорение слегка снижается, но остаётся положительным, снижая общие затраты.
Как запустить DFlash
DFlash поставляется с готовыми чекпоинтами и поддержкой популярных фреймворков – достаточно заменить конфигурацию спекулятивного декодинга.
vLLM
vllm serve Qwen/Qwen3.5-27B \
--speculative-config '{"method": "dflash", "model": "z-lab/Qwen3.5-27B-DFlash", "num_speculative_tokens": 15}' \
--attention-backend flash_attn \
--max-num-batched-tokens 32768
Transformers
from transformers import AutoModel, AutoModelForCausalLM, AutoTokenizer
draft = AutoModel.from_pretrained(
"z-lab/Qwen3-8B-DFlash-b16", trust_remote_code=True,
dtype="auto", device_map="cuda:0").eval()
target = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-8B", dtype="auto", device_map="cuda:0").eval()
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B")
messages = [{"role": "user", "content": "How many positive whole-number divisors does 196 have?"}]
input_ids = tokenizer.apply_chat_template(
messages, return_tensors="pt", add_generation_prompt=True,
enable_thinking=False).to(draft.device)
output = draft.spec_generate(
input_ids=input_ids, max_new_tokens=2048, temperature=0.0,
target=target, stop_token_ids=[tokenizer.eos_token_id])
print(tokenizer.decode(output[0], skip_special_tokens=False))
Ключевые выводы
- DFlash генерирует целый блок токенов за один проход, а не по одному.
- Контекст целевой модели инъецируется в KV‑кеш каждого слоя черновика, что масштабирует количество принимаемых токенов.
- Исследования показывают до 6.08× ускорения (single‑stream) и до 15× пропускной способности (Blackwell).
- Лёгкий пятислойный черновик заменяет тяжёлые 7B‑модели, использованные в предыдущих диффузионных методах.





















