# Как параллельное декодирование ускоряет авторегрессионные модели в 7 раз

Источник: https://www.youtube.com/watch?v=3Tqp_B2G6u0
Канал: Yannic Kilcher
Опубликовано: 06.05.2019

---

В новом видеоролике популярный исследователь искусственного интеллекта Янник Килхер (Yannic Kilcher) разбирает свежую инженерную работу авторов из Калифорнийского университета в Беркли и Google Brain. Исследование под названием «Blockwise Parallel Decoding for Deep Autoregressive Models» предлагает изящный алгоритмический трюк, способный радикально ускорить генерацию контента глубокими нейросетями. Предложенный метод блочного параллельного декодирования позволяет преодолеть фундаментальное ограничение современных языковых моделей — их исключительно последовательную природу.

## 🕒 Проблема последовательного декодирования: почему ИИ думает медленно
[[JUMP:00:00]]

Глубокие генеративные нейросети, включая современные языковые модели, по своей сути являются авторегрессионными. Это значит, что для предсказания каждого следующего слова (или токена) модель обязана опираться на весь предыдущий контекст. Формально задача сводится к вычислению распределения вероятностей для следующего элемента последовательности $W_{t+1}$ на основе уже сгенерированных элементов $W_{\le t}$.

Например, получив фразу «кошка сидит на...», модель оценивает вероятности всех слов из своего словаря, чтобы выбрать наиболее подходящее продолжение. Процесс генерации текста выглядит так:

* Модель генерирует одно слово.
* Это слово добавляется в конец исходной фразы.
* Обновленная строка снова подается на вход модели для генерации следующего слова.



Такой итеративный подход порождает критическую проблему производительности. Процесс вычислений становится строго последовательным: чтобы сгенерировать текст длиной $M$ токенов, системе необходимо выполнить ровно $M$ последовательных проходов через нейросеть, дожидаясь результатов предыдущего шага. 

В режиме инференса (генерации ответов пользователю) это полностью исключает возможность параллельных вычислений на видеокартах, которые эффективны только при обработке больших массивов данных за раз. При этом во время обучения моделей такой проблемы нет: весь тренировочный корпус разбивается на фрагменты и загружается в память параллельно в виде гигантских матриц. При генерации же модель зажата в тиски собственного авторегрессионного алгоритма.

## 🚀 Блочное параллельное декодирование: заглядывая в будущее
[[JUMP:07:01]]

Стандартный подход к генерации называется жадным декодированием (greedy decoding) — на каждом шаге выбирается слово с максимальной логарифмической вероятностью. В задачах машинного перевода модель принимает на вход исходное предложение на одном языке и поочередно генерирует слова на другом. Чтобы разорвать этот замкнутый круг, авторы исследования (Митчелл Стерн, Ноам Шазир и Якоб Ушкурейт) задались вопросом: что если модель будет предсказывать не только следующее слово, но и позиции, находящиеся на два, три или более шагов впереди?

Идея кажется очевидной, но сталкивается с серьезным препятствием. Если предсказывать токены на несколько позиций вперед одновременно, они будут вычисляться независимо друг от друга, опираясь только на старый контекст. Нейросеть на шаге $t+2$ не знает, что именно выберет подсистема на шаге $t+1$. Из-за отсутствия связности между параллельно предсказанными словами качество текста резко падает.

Для преодоления этого барьера инженеры предложили оригинальный компромисс:

* Модель одновременно генерирует цепочки предсказаний на несколько шагов вперед.
* Вместо одного жесткого варианта создается целый пул из множества независимых предложений-кандидатов (например, до 100 вариантов параллельно).
* Эти варианты рассматриваются не как финальный текст, а как гипотезы или «подсказки» для верификации.

## 🔍 Верификация и принятие решений: как отсеять брак
[[JUMP:10:53]]

После того как пул гипотез сформирован, в дело вступает этап верификации (verify). Другая часть алгоритма — или та же самая языковая модель, работающая в режиме оценки, — проверяет все предложенные цепочки токенов параллельно. Поскольку авторегрессионные модели по своей природе вычисляют вероятности последовательностей, им не составляет труда быстро оценить готовые цепочки в пакетном режиме.

Цель этапа верификации — найти среди предложенных гипотез ту, которая точнее всего соответствует результату, который выдала бы модель при медленном, пошаговом жадном декодировании. Если такая цепочка обнаруживается в пуле предложений, система принимает её целиком и совершает мгновенный прыжок на несколько токенов вперед, обеспечивая существенное ускорение работы. В худшем случае, если ни одна гипотеза не подтвердилась, алгоритм просто использует стандартное одиночное предсказание на один шаг вперед, которое вычисляется в любом случае. Таким образом, производительность метода в худшем сценарии равна скорости обычного жадного декодирования, а в лучшем — превосходит её в разы.

Янник Килхер иллюстрирует процесс верификации на наглядном примере. Предположим, модель сгенерировала гипотезу из трех слов: «in the bus» (в автобусе). Проверяющий алгоритм оценивает первый шаг и подтверждает, что слово «in» является наиболее вероятным (ArgMax). Затем он оценивает второй шаг и соглашается, что после «in» должно идти «the». Однако на третьем шаге выясняется, что с точки зрения строгой логики модели после «in the» должно идти слово «car» (машина), а не «bus». В этом случае алгоритм действует гибко:

1.  Часть предложения «in the» принимается как абсолютно верная и сохраняется.
2.  Ошибочное слово «bus» отбрасывается.
3.  На следующем цикле генерация продолжается уже с позиции после «the».

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

## 🛠️ Архитектурные изменения: как устроен трансформер нового типа
[[JUMP:15:28]]

Чтобы оптимизировать этот процесс и избавиться от лишних вычислительных циклов, авторы объединили этап верификации текущих гипотез с предсказанием будущих токенов. Каждый раз при выполнении операций модель генерирует распределение вероятностей сразу для нескольких последующих позиций. Когда алгоритм принимает одобренный префикс гипотезы, предсказания для следующих за ним позиций уже вычислены, и их можно мгновенно направить в работу без повторного запуска сети.



С технической точки зрения архитектура основана на классическом Трансформере, но имеет важное отличие в выходных слоях. Внизу находится огромная стандартная нейросеть, формирующая базовое представление данных. В обычной модели это представление проецируется на выходной слой словаря (P-layer) для оценки вероятности следующего слова. В модифицированной архитектуре авторы разветвляют выходной сигнал на несколько каналов (например, три), выполняя следующие шаги:

* Внедряется дополнительный скрытый полносвязный слой (hidden feed-forward layer) с фиксированным размером.
* Добавляются сквозные связи (skip connections), которые передают сигнал напрямую с нижних уровней нейросети и суммируют его с результатами скрытого слоя.
* Полученные независимые сигналы ($p_1, p_2, p_3$) параллельно проецируются на словарь, предсказывая токены на один, два и три шага вперед соответственно.

Поскольку между выходными предсказаниями $p_1$ и $p_2$ нет обратной связи, они рассчитываются одновременно. Это экономит время, хотя и приводит к потере взаимной зависимости токенов на этапе первичного предсказания, которая затем компенсируется верификацией.

## 📈 Результаты тестов: ускорение до 7x без потери качества
[[JUMP:19:32]]

Для тех сценариев, где строгая идентичность исходной модели не требуется, авторы предусмотрели возможность пожертвовать точностью ради колоссального прироста скорости. Вместо жесткого требования совпадения с абсолютным максимумом (ArgMax) они ввели две метрики смягчения: принятие гипотезы, если она входит в топ-K наиболее вероятных вариантов, или если её отклонение от идеала укладывается в заданную небольшую величину эпсилон ($\epsilon$). Это позволяет существенно чаще одобрять сгенерированные блоки токенов. Дополнительно применялись методы тонкой настройки (fine-tuning) и дистилляции знаний (knowledge distillation), когда целевая блочная модель обучается на подсказках от более крупной «учительской» сети.

В ходе экспериментов были зафиксированы впечатляющие результаты. В задаче машинного перевода (датасет WMT 2014 English-German) базовая модель имела оценку качества BLEU равную 26. Применение блочного параллельного декодирования показало следующие результаты:

* **Чистое ускорение:** Скорость генерации выросла почти в 2 раза при полном сохранении исходного качества BLEU.
* **Компромиссный режим:** При незначительном снижении метрики BLEU скорость выросла в 3 раза.
* **Максимальный буст:** Использование дистилляции знаний и тонкой настройки позволило добиться ускорения до 5 раз практически без просадки качества перевода.

Еще более ошеломляющие цифры метод продемонстрировал в задаче повышения разрешения изображений (image super-resolution). Когда авторы разрешили погрешность $\epsilon = 2$ (что составляет менее 1% ошибки для диапазона яркости пикселей от 0 до 255), скорость работы алгоритма увеличилась в 7 раз. При размере блока $K=4$ средний размер принимаемого фрагмента составил 3,75 токена. Это означает, что предложенные моделью гипотезы одобрялись верификатором практически в полном объеме на каждом шаге вычислений.

Янник Килхер подчеркивает, что исследование демонстрирует реальный прирост физического времени выполнения (wall-clock time speedup), превышающий 3x в переводе и 4x в обработке изображений. По его мнению, этот элегантный инженерный прием представляет огромную ценность для оптимизации высоконагруженных промышленных ИИ-систем (production systems), где скорость инференса напрямую конвертируется в экономию дорогостоящих вычислительных ресурсов.