← На главную

Опубликовано

EAGLE-3 на 4060: acceptance 0.17 при любой квантизации - домен решает, не битрейт

Автор: Гусев Николай [портфолио]

Обновлено

Темы: llm, benchmarks, inference, speculative-decoding

Автор: Гусев Николай. Серия про спекулятивное декодирование на 8 ГБ: часть 1, часть 2 - DFlash, часть 4 - 96K и Lucebox.

EAGLE-3 - самый цитируемый метод спекулятивного декодирования последних двух лет. Заявления: acceptance 0.80-0.88, ускорение до 5×. На моём стенде он работает в минус, и разбор этого провала дал больше понимания, чем любой из удачных замеров серии.

Что я собирал

Схема EAGLE-3: отдельная лёгкая голова предсказывает скрытые состояния таргета, таргет верифицирует дерево драфта за один проход. Голову взял готовую - AngelSlim выкладывал её под Qwen3-4B, официальный рецепт конвертации в GGUF описан, ллama.cpp метод поддерживает.

Первая матрица: acceptance 0.03-0.09 на R2-корпусе, 0.69× скорости серийно. Не «не ускорилось» - замедлилось. При заявленных выше 0.80 это разница не в настройках, а в чём-то фундаментальном.

Исключаем квантизацию

Первая гипотеза - Q4_K_M таргет. Голова EAGLE-3 обучена на скрытых состояниях full-precision весов; квантованный таргет даёт другие распределения активаций, голова ломается.

Проверка: тот же прогон на Q8_0. Результат - acceptance 0.17 против 0.18 на Q4_K_M. Разница в пределах шума.

Квантизация исключена. Это важный негативный результат: «поставьте Q8 и заработает» - не работает. Дальше остаются две гипотезы: несоответствие головы ревизии весов (AngelSlim тренировал голову не на моём коммите Qwen3-4B, формат захвата скрытых состояний мог отличаться) и домен.

Домен: независимое подтверждение

С ревизией всё сложно - проверить её, не тренируя голову заново, нельзя. А вот домен за меня измерил независимый экспериментатор: dmagog прогнал EAGLE-3 на Qwen3 через полный цикл на Kaggle T4, замерив по частям и по доменам, код выложен под Apache-2.0.

НаборДлина принятияУскорение
HumanEval (код)3.822.56×
GSM8K3.682.50×
Alpaca3.192.15×
MT-Bench2.911.97×
Русскоязычный1.380.95×

Одна и та же голова, одна и та же схема: на английском коде 2.56×, на русском - замедление. Это ровно моя картина: мой корпус - русский docs/tool/route, результат 0.69×. «Acceptance 80-90%, до 5×» из популярных обзоров относятся к английскому коду и длинной генерации - там цифры честные, просто они не про ваш случай, если ваш случай - документы на русском.

Бонус-наблюдение из того же прогона: увеличение глубины дерева скорость ухудшает. Черновик угадывает одинаково редко на всех глубинах, меняется только цена проверки. Точная копия моего n_max-sweep для DFlash: acceptance падает с 0.43 до 0.18 при росте окна, а принятых токенов на шаг - константа.

Как голова должна совпадать с таргетом

EAGLE-3 - не просто маленькая модель рядом с большой. Голова учится предсказывать скрытые состояния конкретного таргета. Для неё важны архитектура, порядок и формат скрытых состояний, токенизатор, специальный chat template и часто конкретная ревизия весов.

Поэтому рабочая связка выглядит не как «любой Qwen плюс любая EAGLE-голова», а примерно так:

target weights + tokenizer + hidden-state interface
                         |
                    EAGLE head
                         |
                 tree verification

Если голова обучалась на другой ревизии, конвертация в GGUF может пройти успешно, сервер может загрузить все tensors, а acceptance всё равно окажется почти нулевым. Загрузка файла доказывает совместимость формата, но не совместимость распределений скрытых состояний.

Наши подготовительные проверки поэтому включали не только наличие файла головы: проверялись архитектура GGUF, имена tensors, размерности, target tokenizer и фактические счётчики draft_n/draft_n_accepted. «Сервер стартовал» не считалось доказательством, что EAGLE работает.

Что проверили на практике

Первая матрица была короткой, но решающей: один и тот же корпус и две версии таргета. На Q4_K_M acceptance оказался около 0.18, на Q8_0 - около 0.17. Если бы главным виновником была квантизация таргета, переход на Q8 должен был заметно восстановить согласованность головы. Этого не произошло.

Q4_K_M target -> acceptance ~0.18
Q8_0   target -> acceptance ~0.17

Квантизацию мы не «доказали невиновной вообще», но для этой связки она перестала быть достаточным объяснением. Корректная формулировка статьи: Q4 против Q8 не объясняет наблюдаемый провал.

Следующий эксперимент, который мог бы подтвердить ревизионную гипотезу, - получить голову, обученную на точно той же ревизии, или переобучить её. Локально это не закрывается: разумная тренировка требует GPU-класса около 24 ГБ. Поэтому R2b-6 оставлен как честный reopen, а не как выдуманный положительный результат.

Почему рекламная цифра может быть правдивой и бесполезной

У EAGLE-3 есть положительные сценарии. В независимом воспроизведении на Qwen3 на Kaggle T4 кодовый HumanEval дал ускорение 2.56×, а русскоязычный набор - 0.95×. Это не противоречие: драфтер может хорошо продолжать один домен и плохо другой.

Копируемая форма такого замера должна фиксировать метод и набор. Для этой серии реальный воспроизводимый entrypoint - не выдуманный benchmark.py, а матричный раннер из материалов эксперимента:

git clone https://github.com/NikolayGusev-astra/poc-node-utilization.git
cd poc-node-utilization
python validation-v3/run_spec_matrix.py --group qwen3-4b --reps 3

Он запускает baseline, DFlash и EAGLE-3 на группе Qwen3-4B, сохраняет команды, свойства сервера, GPU-сэмплы и JSON-результаты в measurements/v7-spec-matrix/. Полный файл: run_spec_matrix.py. Для другой машины нужно проверить пути к движку и GGUF в run_config.json; скрипт не скачивает модель и не включает бинарники в репозиторий.

Матрица из четырёх прогонов

run_spec_matrix.py --group qwen3-4b гоняет baseline (драфт выключён), DFlash и EAGLE-3 на одном и том же таргете Qwen3-4B-Q4_K_M, с теми же задачами, повторами и seed. Таргет один и тот же, меняется только режим спекуляции, поэтому разница в пропускной способности это чистый эффект метода, а не разная модель. Команды, свойства сервера, GPU-сэмплы и JSON-результаты лежат в measurements/v7-spec-matrix/ четырьмя сессиями по полному набору ячеек.

РежимЗапусковКорректных/минОтношение к baselineAcceptance драфта
baseline (draft off)2045.11.00×-
DFlash1636.20.80×0.105
EAGLE-31628.90.64×0.047
DFlash drift-версия417.40.39×0.202

Baseline отдаёт 45 корректных задач в минуту. DFlash на этом смешанном корпусе (русские документы, tool-вызовы, маршрутизация) - 36.2, то есть 0.80×, то есть медленнее голого таргета. EAGLE-3 - 28.9, 0.64×, а acceptance драфта 0.047: из всех предложенных блоков таргет принимает целиком меньше пяти процентов. Это не «не ускорилось» - это сознательное замедление, потому что каждый принятый блок дороже проверки дерева глубины 8.

Вторая и третья колонки вместе это то, что обычно не показывают в обзорах. Acceptance 0.047 для EAGLE-3 против 0.105 для DFlash означает: более «бумажный» драфтер здесь даёт меньше принятых блоков, потому что его дерево глубже и дороже верифицируется. Высокий acceptance сам по себе не означает ускорение; ускорение означает отношение корректных минут к цене проверки. Это прямо объясняет, почему в первой строке EAGLE-3 медленнее baseline, даже если драфтер предлагает токены почти бесплатно.

Отдельного разбора стоит четвёртая строка таблицы. Drift-версия DFlash показывает acceptance 0.202, вдвое выше обычного DFlash, и при этом худшую скорость серии, 0.39×. Это самый чистый аргумент против культа acceptance: драфтер стал угадывать чаще, а серия ускорилась хуже всех, потому что выросла цена самого предложения блока. Смотреть только на длину принятия и делать из неё вывод об ускорении - та же ошибка, что цитировать 0.80 без указания домена.

Как считается acceptance в этой матрице. В результатах каждого прогона лежат два счётчика: draft_n, сколько блоков предложено, и draft_n_accepted, сколько принято целиком. Цифра в таблице - блок-левел, отношение второго счётчика к первому. Токен-левел будет выше: частично принятый блок тоже экономит проходы. Поэтому мои 0.047 нельзя напрямую ставить рядом с обзорными 0.80 - методики счёта разные. Уровень счёта надо фиксировать вместе с цифрой, иначе сравнение бессмысленно.

Эта таблица сходится с тем, что написано выше: acceptance 0.047 попадает в заявленный диапазон 0.03-0.09 для первой матрицы, а 0.64× рядом с заявленными 0.69×. Разные прогоны давали небольшие колебания, но оба результата далеко ниже обзорных 0.80. n_max здесь не случайность: для EAGLE-3 он зафиксирован на 8, для DFlash на 15, и именно глубина дерева делает проверку EAGLE-3 дороже baseline.

Для более короткой проверки одной головы можно использовать тот же контракт: один frozen-корпус, temperature=0, фиксированный seed, три повтора, одинаковый target без EAGLE и с --spec-type draft-eagle3. Результат нельзя переносить между Qwen3 и Qwen3.5: в материалах отдельно зафиксировано, что готовой головы EAGLE-3 под Qwen3.5-4B не было.

Сравнивать результаты без dataset, языка, длины ответа и глубины дерева - всё равно что сравнивать автомобили по максимальной скорости, не указывая, на трассе это было или в пробке.

Для серии это дало простой практический вывод. EAGLE-3 из роутера методов выпадает полностью: на русском корпусе он не ускоряет ни один класс задач, а цена прогона матрицы - вечер GPU-времени. В формуле из первой части (MTP всегда, DFlash на детерминированный код, PFlash на длинные контексты) для него слота нет. Голова остаётся на диске и в материалах: если появится релиз таргета, для которого под него выложат голову с совпадающей ревизией, матрица прогоняется заново одной командой из предыдущего раздела.

Чек-лист совместимости головы и таргета

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

  1. Имена и размерности tensors в GGUF головы против таргета: размер скрытого состояния обязан совпадать.
  2. Токенизатор и chat template: если таргет переобучал спецтокены, голова со старой разметкой будет систематически сдвигать предсказания.
  3. Ревизия весов: у головы в карточке указан исходный коммит таргета, сверять со своим GGUF.
  4. Счётчики draft_n и draft_n_accepted на живом сервере: нулевые предложения означают, что контур не завёлся, а не что домен плохой.
  5. Baseline без драфта на том же корпусе: без него 0.64× неоткуда взять.

У меня зелёными оказались четыре из пяти: архитектура, tensors, токенизатор и счётчики сходились, а ревизию проверить было нечем. Если пять из пяти зелёные, а acceptance всё равно на уровне сотых, тогда диагноз домен или ревизия становится обоснованным. Это граница, до которой дошёл стенд, и дальше неё без второго GPU идти нечем.

Что нужно, чтобы EAGLE-3 ожил

  1. Голова, натренированная ровно под вашу ревизию таргета. SpecForge, тренировочный сет, 24 ГБ VRAM на разумном батче - мой 8-гигабайтный стенд это не тянет, ветка задокументирована как reopen.
  2. Английский код или близкий домен. На русском NL EAGLE-3 не даёт ничего при любой голове - это свойство метода, а не баг сборки.
  3. Глубина дерева - минимально достаточная. Больше - хуже.

Вывод

Провал EAGLE-3 на моём стенде - не кривые руки и не квантизация. Это два независимых фактора: домен (русский NL - метод работает в минус, подтверждено сторонним воспроизведением) и, вероятно, ревизия головы (гипотеза - проверить без ретрейна нельзя, и я это честно пишу). Урок шире конкретного метода: цитируя «до 5×», всегда спрашивайте, на каком языке и каком домене.