Обзор вывода Большой языковой модели (LLM), ее значимость, проблемы и формулировки ключевых проблем.
Большие языковые модели (LLM) произвели революцию в области обработки естественного языка (NLP), обеспечив широкий спектр приложений: от чат-ботов и агентов ИИ до генерации кода и контента. Однако развертывание LLM в реальных сценариях часто сталкивается с проблемами, связанными с задержкой, потреблением ресурсов и масштабируемостью.
В этой серии постов в блоге мы рассмотрим различные методы оптимизации для вывода LLM. Мы погрузимся в стратегии сокращения задержек, объема памяти и вычислительных затрат, от механизмов кэширования до аппаратных ускорений и квантования моделей.
В этой статье мы дадим краткий обзор вывода LLM, его важности и связанных с ним проблем. Мы также обрисуем ключевые формулировки проблем, которые будут направлять наше исследование методов оптимизации.
Вывод модели относится к процессу использования обученной модели машинного обучения для составления прогнозов или генерации выходных данных на основе новых входных данных. В контексте LLM вывод включает обработку текстового ввода и генерацию связного и контекстно-релевантного текстового вывода.
Модель обучается только один раз или периодически, в то время как вывод происходит гораздо чаще, вероятно, тысячи раз в секунду в производственных средах.
Оптимизация вывода имеет важное значение для обеспечения эффективного развертывания LLM в реальных приложениях. Цель состоит в том, чтобы минимизировать задержку (время, необходимое для генерации ответа), сократить потребление ресурсов (ЦП, ГП, память) и улучшить масштабируемость (способность справляться с растущими нагрузками).
Например, GPT-3 (с 175 миллиардами параметров) требует значительных вычислительных ресурсов для вывода. Оптимизации могут сократить время отклика с 1–2 секунд до миллисекунд, делая LLM более практичными для интерактивных приложений.
Архитектура трансформатора, использующая механизмы внимания, стала основой для большинства современных LLM. Эта архитектура включает позиционные кодировки, многоголовое самовнимание, нейронные сети прямого распространения и нормализацию слоев. Трансформаторы обычно подразделяются на три основных типа:
Модели кодировщика-декодера (например, T5) были оригинальной архитектурой, представленной в статье «Внимание — все, что вам нужно». Эти модели предназначены для задач, требующих как понимания, так и генерации, таких как перевод и резюмирование. Они обрабатывают входную последовательность с помощью кодировщика, а затем генерируют выходную последовательность с помощью декодера.
Поскольку модели, содержащие только декодер, являются наиболее распространенной архитектурой LLM для задач авторегрессии, в этой серии статей основное внимание будет уделено методам оптимизации, предназначенным специально для этого типа моделей.
Механизм внимания является ключевым компонентом архитектуры преобразователя, который позволяет модели фокусироваться на различных частях входной последовательности при генерации выходных данных. Он вычисляет взвешенную сумму входных представлений, где веса определяются релевантностью каждого входного токена для текущего генерируемого выходного токена. Этот механизм позволяет модели фиксировать зависимости между токенами, независимо от их расстояния во входной последовательности.
Механизм внимания может быть вычислительно затратным, особенно для длинных входных последовательностей, поскольку он требует расчета парных взаимодействий между всеми токенами (сложность O(n^2)
). Давайте рассмотрим его более подробно пошагово:
Представление входных данных : каждый токен во входной последовательности представляется в виде вектора, обычно с использованием вложений.
Векторы запроса, ключа, значения : для каждого токена вычисляются три вектора: вектор запроса ( Q_i
), вектор ключа ( K_i
) и вектор значения ( V_i
). Эти векторы выводятся из входных представлений с использованием изученных линейных преобразований.
Оценки внимания : Оценки внимания вычисляются путем взятия скалярного произведения вектора запроса текущего токена с ключевыми векторами всех предыдущих токенов во входной последовательности. Это приводит к оценке, которая указывает, насколько много внимания следует уделять каждому токену.
Нормализация Softmax : затем оценки внимания нормализуются с помощью функции Softmax для получения весов внимания, которые в сумме дают 1.
Взвешенная сумма : Наконец, выходное представление для текущего токена вычисляется как взвешенная сумма векторов значений с использованием весов внимания.
Многоголовое внимание — это расширение механизма внимания, которое позволяет модели совместно уделять внимание информации из разных подпространств представления в разных позициях. Вместо того, чтобы иметь один набор весов внимания, многоголовое внимание вычисляет несколько наборов оценок внимания параллельно, каждый со своими собственными выученными линейными преобразованиями.
Выходные данные этих головок внимания затем объединяются и линейно преобразуются для получения окончательного выходного представления.
Этот механизм расширяет возможности модели по учету разнообразных взаимосвязей и зависимостей во входных данных, что приводит к повышению производительности при выполнении различных задач обработки естественного языка.
Понимая LLM и архитектуру преобразователя, давайте обрисуем процесс вычисления вывода. Вывод генерирует следующие $n$ токенов для заданной входной последовательности и может быть разбит на два этапа:
Этап предварительного заполнения : на этом этапе выполняется прямой проход через модель для входной последовательности, и для каждого токена вычисляются представления ключей и значений. Эти представления сохраняются для последующего использования на этапе декодирования в кэше KV. Представления всех токенов в каждом слое вычисляются параллельно.
Этап декодирования : на этом этапе модель генерирует выходные токены по одному за раз авторегрессивным способом. Для каждого токена модель извлекает представления ключей и значений из кэша KV, сохраненного на этапе предварительного заполнения, вместе с представлением запроса текущего входного токена для вычисления следующего токена в последовательности.
Этот процесс продолжается до тех пор, пока не будет выполнен критерий остановки (например, достижение максимальной длины или генерация токена конца последовательности). Новые представления ключей и значений сохраняются в кэше KV для последующих токенов. На этом этапе также применяется стратегия выборки токенов для определения следующего токена для генерации (например, жадный поиск, лучевой поиск, выборка top-k).
Для префикса длиной L , размера вложения d и модели с h головками и n слоями сложность вычисления вывода можно проанализировать следующим образом:
Этап предварительного заполнения : На этапе предварительного заполнения мы вычисляем начальное представление для всех токенов на входе. Сложность здесь:
Здесь:
O(Ln .d^2)
: представляет собой вычисление прямой связи, которое обрабатывает каждый токен независимо по слоям. Это масштабируется линейно как с длиной последовательности L, так и с числом слоев n .
Второй член O(L^2. nh d)
: представляет стоимость механизма внимания. Здесь каждый токен взаимодействует с каждым другим токеном, что приводит к сложности L^2
для расчета внимания на слой. Сложность растет квадратично с длиной последовательности, что может стать основным узким местом для длинных последовательностей.
Стадия декодирования : Стадия декодирования — это авторегрессионная часть, сложность которой составляет:
Здесь:
Вычисление прямой связи : для каждого сгенерированного токена мы выполняем операции прямой связи в каждом слое. Поскольку это делается для одного токена за раз (а не для всей последовательности), сложность на токен составляет: O(nd^2)
.
Вычисление внимания с кэшированием : каждый новый токен взаимодействует с существующей последовательностью посредством внимания, используя ранее вычисленные пары ключ-значение. Для каждого сгенерированного токена это вычисление внимания пропорционально длине последовательности L, что дает: O(Lnd .h)
Как мы видим, сложность вычисления вывода зависит от длины входной последовательности ( L ), количества слоев ( n ), количества головок внимания ( h ) и размера встраивания ( d ). Эта сложность может стать узким местом в приложениях реального времени, особенно при работе с длинными входными последовательностями и/или большими моделями.
Кэширование KV является важнейшим методом оптимизации для вывода LLM, особенно на этапе декодирования. Сохраняя представления ключей и значений, вычисленные на этапе предварительного заполнения, модель может избежать избыточных вычислений для ранее обработанных токенов.
Это значительно снижает вычислительные затраты и задержку во время вывода, поскольку модели необходимо вычислить только оценки внимания для нового генерируемого токена, а не пересчитывать представления ключей и значений для всех токенов во входной последовательности.
Это делает стоимость линейной по отношению к количеству сгенерированных токенов, а не квадратичной по отношению к длине входных данных.
Однако кэширование KV требует дополнительной памяти для хранения представлений ключей и значений, что может стать компромиссом в средах с ограниченными ресурсами.
Рассчитаем требования к памяти для модели LLaMA 7B.
d_model
): 4096d_head
): 32d_head
): 128 (4096/32) Размер ключа на токен = d_head × num_heads
= 128 × 32 = 4096 элементов
Размер значения на токен = d_head × num_heads
= 128 × 32 = 4096 элементов
Общее количество элементов на токен на слой = 4096 + 4096 = 8192 элемента
Элементов на слой = L × 8192 = 2048 × 8192 = 16 777 216 элементов
Память на слой (в байтах) = 16 777 216 × 2 = 33 554 432 байта = 33,55 МБ
Таким образом, общее требование к памяти: 14 ГБ (веса модели) + 1-2 ГБ (издержки) + 1073,6 МБ (кэш KV) = 15-16 ГБ . Этот расчет дает нам оценку требований к памяти для модели LLaMA 7B во время вывода. LLaMA 7B относительно невелика по сравнению с такими моделями, как GPT-3 (175 миллиардов параметров), которым потребовалось бы значительно больше памяти как для весов модели, так и для кэша KV.
Кроме того, при масштабировании до $m$ одновременных пользователей требования к ресурсам будут в $m$ раз выше. Таким образом, методы оптимизации имеют решающее значение для развертывания больших моделей в средах с ограниченными ресурсами.
При оценке эффективности методов оптимизации вывода можно учитывать несколько показателей:
Задержка предварительного заполнения : время, необходимое для выполнения этапа предварительного заполнения вывода, также называемое задержкой времени до первого токена (TTFT). Эта метрика имеет решающее значение для интерактивных приложений, где пользователи ожидают быстрых ответов. На эту метрику могут влиять такие факторы, как размер модели, длина ввода и возможности оборудования.
Задержка декодирования : время, необходимое для генерации каждого последующего токена после этапа предварительного заполнения, также называемое задержкой между токенами (ITL). Эта метрика важна для измерения отзывчивости модели во время генерации текста. Для таких приложений, как чат-боты, низкий ITL хорош, но быстрее не всегда лучше, так как 6-8 токенов в секунду часто достаточно для человеческого взаимодействия. Факторы, влияющие на это, включают размер кэша KV, стратегию выборки и оборудование.
End-to-End Latency : Общее время, прошедшее от получения ввода до генерации окончательного вывода. Эта метрика необходима для понимания общей производительности процесса вывода и зависит от предварительного заполнения, декодирования и других компонентных задержек (например, анализа JSON). Факторы, влияющие на это, включают размер модели, длину ввода и аппаратное обеспечение, а также эффективность всего конвейера.
Максимальная скорость запросов, также известная как QPS (запросы в секунду) : количество запросов на вывод, которые могут быть обработаны в секунду. Эта метрика имеет решающее значение для оценки масштабируемости модели в производственных средах. Такие факторы, как размер модели, оборудование и методы оптимизации, могут влиять на QPS. Например, если 15 QPS обслуживается при задержке P90 через 1 GPU, то для обслуживания 300 QPS потребуется 20 GPU. Влияющие факторы включают аппаратные ресурсы, балансировку нагрузки и методы оптимизации.
FLOPS (операций с плавающей точкой в секунду) : количество операций с плавающей точкой, которые модель может выполнить за секунду. Эта метрика полезна для понимания вычислительной стоимости вывода и может использоваться для сравнения эффективности различных моделей и методов оптимизации. Влияющие факторы включают архитектуру модели, аппаратное обеспечение и методы оптимизации.
Мы рассмотрим все эти оптимизации в следующих публикациях серии.
Оптимизация системы : Оптимизация базовой аппаратной и программной инфраструктуры, например, использование специализированного оборудования (например, TPU, GPU) или оптимизация программного стека (например, использование эффективных библиотек и фреймворков). Ее можно разбить на:
Управление памятью : эффективное управление использованием памяти для снижения накладных расходов и повышения производительности.
Эффективные вычисления : использование параллелизма и оптимизация вычислений для сокращения задержек.
Пакетирование : одновременная обработка нескольких запросов для повышения пропускной способности.
Планирование : эффективное планирование задач для максимального использования ресурсов.
Сжатие моделей : такие методы, как квантование, обрезка и дистилляция, можно использовать для уменьшения размера модели и повышения скорости вывода без существенного снижения производительности.
Оптимизация алгоритмов : улучшение алгоритмов, используемых для вывода, например, использование более эффективных стратегий выборки или оптимизация механизма внимания. Например, спекулятивное декодирование, которое позволяет модели генерировать несколько токенов параллельно, может значительно сократить задержку декодирования.
В этом посте мы представили обзор вывода LLM, его важности и связанных с ним проблем. Мы также изложили ключевые формулировки проблем, которые будут направлять наше исследование методов оптимизации в последующих постах.
Понимая тонкости вывода LLM и факторы, влияющие на его производительность, мы можем лучше оценить значимость методов оптимизации в повышении практичности LLM для реальных приложений. В следующем посте мы более подробно рассмотрим конкретные методы оптимизации и их реализацию, сосредоточившись на сокращении задержки и потребления ресурсов при сохранении производительности модели.