Промпт-инжиниринг

Ускорение вывода крупномасштабных языковых моделей: Техники для эффективного развертывания

mm
Добавьте Unite.AI в избранные источники в Google
LLM Inference Speed up

Крупномасштабные языковые модели (LLM) типа GPT-4, LLaMA и PaLM расширяют границы того, что возможно с обработкой естественного языка. Однако развертывание этих массивных моделей в производственных средах представляет значительные проблемы в плане вычислительных требований, использования памяти, задержки и стоимости. По мере того, как LLM продолжают расти в размерах и возможностях, оптимизация их производительности вывода имеет решающее значение для реальных приложений.

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

Давайте начнем с понимания, почему вывод LLM так сложен по сравнению с традиционными моделями NLP.

Проблема вывода с крупномасштабными языковыми моделями

До появления LLM обработка естественного языка полагалась на более мелкие модели, ориентированные на конкретные задачи, такие как классификация текста, распознавание именованных сущностей и анализ настроений. Хотя эти модели все еще были вычислительно интенсивными, они могли быть развернуты на скромном оборудовании и следовали относительно прямым процессам вывода.

LLM, с другой стороны, представляют собой сдвиг парадигмы. Эти модели обучаются на огромных наборах данных, используя миллиарды параметров, что позволяет им выполнять широкий спектр языковых задач с замечательной профессиональностью. Однако эта сила имеет свою цену – значительно возросшие вычислительные требования как во время обучения, так и во время вывода.

Одной из ключевых проблем является автoregressивная природа генерации текста с помощью LLM. Чтобы произвести текст, похожий на человеческий, эти модели предсказывают один токен (слово или подслово) за раз, причем каждый новый токен зависит от предыдущего сгенерированного вывода. Эта последовательная зависимость предотвращает эффективную параллелизацию и приводит к вычислительным требованиям, которые растут полиномиально с длиной последовательности.

Кроме того, LLM часто требуют длинных входных последовательностей (промптов), чтобы установить необходимый контекст для высококачественной генерации текста. Более длинные длины входных последовательностей требуют больше памяти для хранения промежуточных состояний и матриц внимания, что еще больше напрягает ресурсы оборудования.

С этими уникальными проблемами традиционные методы оптимизации, такие как квантование и статические вычислительные графы, могут оказаться недостаточными, с трудностями в поддержании производительности LLM, одновременно обеспечивая значительные ускорения. Давайте погрузимся в некоторые из ключевых стратегий, специально разработанных для ускорения вывода LLM.

Техники числовой точности

From 32-Bit to 16-Bit Precision

From 32-Bit to 16-Bit Precision

Одним из путей для ускорения вывода LLM является использование уменьшенной числовой точности для весов модели и активаций. Современные фреймворки глубокого обучения, такие как PyTorch и TensorFlow, обычно используют точность 32-битных чисел с плавающей запятой (FP32) по умолчанию. Однако исследования показали, что LLM могут часто сохранять высокую точность даже при работе на более низких точностях, таких как 16-битные (FP16), 8-битные целые числа (INT8) или даже 4-битные целые числа (INT4).

Уменьшение числовой точности предлагает несколько преимуществ:

  • Уменьшенный объем памяти: Представления с более низкой точностью требуют меньше памяти, что позволяет разместить более крупные модели или пакеты в рамках одних и тех же ограничений оборудования.
  • Быстрее вычисления: Многие современные ЦП и ГП обеспечивают специализированные инструкции и аппаратное ускорение для арифметики с более низкой точностью, что позволяет добиться значительных ускорений.
  • Улучшенная энергоэффективность: С меньшими требованиями к памяти и более быстрыми вычислениями вывод с более низкой точностью может переводиться в снижение энергопотребления – важное преимущество для развертывания на краю и мобильных устройствах.

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

Существует два основных подхода к квантованию LLM:

Пост-обучение квантования (PTQ): В этом методе LLM сначала обучается с использованием стандартной точности FP32. После обучения веса модели квантуется (преобразуются) в представление с более низкой точностью, такое как INT8 или INT4. PTQ прост в реализации, но может привести к большим потерям точности.

Квантование-осведомленное обучение (QAT): С QAT процесс квантования имитируется во время фазы обучения. Это позволяет модели учиться компенсировать ошибки квантования, минимизируя ухудшение точности, когда окончательная квантованная модель развертывается. QAT более сложен, но часто дает лучшие результаты по сравнению с PTQ.

Для практического применения можно использовать предварительно квантованные модели, доступные на платформах, таких как Hugging Face, которая размещает разнообразные модели, оптимизированные с помощью различных методов квантования. Например, если желательно модель, квантованная с помощью Auto-GPTQ, пользователи могут легко загрузить ее, используя библиотеку трансформеров Hugging Face. Кроме того, для квантования модели можно использовать инструменты, такие как AutoGPTQ, которые интегрируются без проблем с существующими библиотеками для эффективного сжатия модели.

Вот пример загрузки предварительно квантованной модели Llama-2-7b, используя библиотеку трансформеров Hugging Face:

from transformers import AutoModelForCausalLM, AutoTokenizer

<p>model_id = "TheBloke/Llama-2-7b-Chat-GPTQ"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)
And для пользовательской квантовации можно следовать этим шагам, используя инструментарий AutoGPTQ:</p>

<p>from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig</p>

<p>model_id = "llama-2-7b-original"
tokenizer = AutoTokenizer.from_pretrained(model_id)
quantization_config = GPTQConfig(bits=4, dataset="your-dataset", tokenizer=tokenizer)
model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=quantization_config)</p>

Помните, что квантование может потребовать пост-квантования тонкой настройки или инженерии промптов, чтобы сохранить качество модели. Для новой квантования вы можете внести свой вклад в сообщество, отправив свои квантованные модели на платформы, такие как Hugging Face.

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

 

Алгоритм Flash Attention

Механизм многоголового внимания является ключевым компонентом трансформерных LLM, что позволяет модели захватить длинные зависимости и контекстуализированные представления. Однако эта операция внимания вычислительно неэффективна для автoregressивной генерации текста, поскольку она требует повторного вычисления многих одних и тех же значений для каждого нового токена.

Алгоритм Flash Attention, представленный в статье FlashAttention, обеспечивает более памяти-эффективный и параллелизированный подход к операции внимания. Вместо повторного вычисления значений внимания для каждого токена Flash Attention кэширует и повторно использует промежуточные матрицы ключей/значений, избегая избыточных вычислений.

Эта оптимизация не только снижает вычислительную нагрузку, но и улучшает шаблоны доступа к памяти, что приводит к лучшему использованию пропускной способности памяти ГП и параллелизма.

Хотя детали Flash Attention довольно сложны, общая идея состоит в том, чтобы разложить операцию внимания на две фазы:

  1. Префиксная суммарная вложенность: Эта фаза вычисляет и кэширует вложенности ключей/значений для всех входных токенов, что позволяет эффективно повторно использовать их во время генерации.
  2. Каузальное внимание: Сама операция внимания, теперь оптимизированная для использования закэшированных вложенных ключей/значений из первой фазы.

Разделив эти фазы, Flash Attention может воспользоваться высокопараллельными операциями ГП, что значительно ускоряет операцию внимания в выводе LLM.

Вот краткая концептуальная иллюстрация реализации Flash Attention с LLM:

from transformers import AutoModelForCausalLM
import torch
from flash_attention import flash_attention

<p># Загрузка LLM, такой как OctoCoder
model = AutoModelForCausalLM.from_pretrained("bigcode/octocoder")</p>

<p># Пример системного промпта, который направляет модель на то, чтобы стать лучшим помощником по программированию
system_prompt = "..."</p>

<p># Подготовка более длинного входа с системным промптом
long_prompt = system_prompt + "Вопрос: Напишите функцию на Python, которая преобразует байты в гигабайты."</p>

<p># Преобразование модели для оптимизации Flash Attention
model.to_bettertransformer()</p>

<p># Запуск модели с Flash Attention
start_time = time.time()
with torch.backends.cuda.sdp_kernel(enable_flash=True):
result = model.generate(long_prompt, max_new_tokens=60)
print(f"Сгенерировано за {time.time() - start_time} секунд.")

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

Обрезка LLM

Обрезка LLM – это техника, которая уменьшает размер модели, сохраняя при этом ее функциональность. Она использует оценщик важности весов, основанный на аппроксимациях матрицы Гесса. При обрезке менее важные группы весов удаляются, а затем модель дообучается для восстановления точности. Пакет LLM-Pruner предлагает скрипты для обрезки с поддержкой различных стратегий. Обрезка включает в себя обнаружение зависимостей, оценку вклада групп и этап восстановления, включающий краткое пост-обучение.

Вот упрощенный пример кода на Python, демонстрирующий использование LLM-Pruner для модели LLaMa:

from transformers import AutoModelForSequenceClassification
from pruning import LLMPruner

<p># Загрузка предварительно обученной модели LLaMa
model = AutoModelForSequenceClassification.from_pretrained("llama-base")</p>

<p># Инициализация обрезчика с желаемой конфигурацией
pruner = LLMPruner(
model,
pruning_ratio=0.25,
block_mlp_layers=(4, 30),
block_attention_layers=(4, 30),
pruner_type='taylor'
)</p>

<p># Выполнение обрезки
pruned_model = pruner.prune()</p>

<p># Дообучение обрезанной модели
pruned_model.fine_tune(training_data)

Этот кодовый набросок представляет собой загрузку предварительно обученной модели LLaMa, настройку обрезчика с конкретными конфигурациями (например, какие слои обрезать и тип обрезчика), выполнение процесса обрезки и, наконец, дообучение обрезанной модели.

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

Архитектурные инновации для эффективной генерации текста

Архитектура трансформера, хотя и очень эффективна для задач моделирования языка, была разработана как универсальная последовательность-последовательность-модель. Когда развертывание LLM для задач генерации текста с длинными контекстами ввода, исследователи обнаружили, что более специализированные архитектуры могут значительно улучшить эффективность вывода без жертвования качеством.

Вот некоторые из ключевых архитектурных инноваций, которые позволяют более быстрому выводу LLM:

Alibi: Архитектура Alibi, представленная в статье PAL-Instruction, отделяет моделирование длинного контекста ввода от процесса генерации текста. Она использует сжатое представление контекста ввода (алibi), чтобы инициализировать процесс генерации, избегая необходимости повторной обработки полной входной последовательности во время автoregressивной генерации.

Ротари-вложения: Вместо использования стандартных позиционных вложений техника ротари-вложений использует матрицы вращения для более эффективного кодирования позиционной информации. Этот подход показал улучшение производительности и возможность обработки более длинных входных последовательностей.

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

Multiquery attention

Multiquery attention

Групповое запрос-внимание (GQA): Расширяя MQA, GQA группирует выходные последовательности в кластеры и вычисляет внимание совместно для каждого кластера. Этот подход еще больше снижает вычислительные требования, сохраняя при этом высокое качество генерации текста.

Хотя эти архитектурные инновации еще находятся в активной разработке, они продемонстрировали впечатляющие ускорения для задач вывода LLM, особенно при комбинации с техниками, такими как Flash Attention и оптимизацией числовой точности.

Реальные соображения развертывания

За пределами основных алгоритмов и архитектур существует несколько практических соображений и компромиссов, которые необходимо учитывать при развертывании LLM в производственных средах:

Аппаратное ускорение: Хотя ЦП могут обрабатывать вывод LLM, ГП и другие ускорители, такие как ТПУ Google (GOOGL ), имеют решающее значение для достижения высокой пропускной способности и низкой задержки. Выбор правильного оборудования и оптимизация использования памяти имеют важное значение.

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

Квантование vs. качество компромисс: Степень квантования (8-бит, 4-бит и т. д.) напрямую повлияет на скорость вывода и использование памяти, но также повлияет на качество вывода. Этот компромисс должен быть тщательно оценен для каждого случая использования.

Дистилляция модели: Альтернативой квантованию является дистилляция модели, которая может сжать крупные LLM в более мелкие и эффективные модели-студенты, сохраняя при этом высокую точность.

Кэширование и оптимизированные среды выполнения: Оптимизированные среды выполнения глубокого обучения, такие как NVIDIA TensorRT, и фреймворки, разработанные для обслуживания LLM (например, Composable Inference Suite от MosaicML), могут обеспечить значительные улучшения производительности с помощью техник, таких как слияние операторов, оптимизация ядер и умные стратегии кэширования.

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

Заключение

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

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

Взглянув вперед, мы можем ожидать продолжения исследований и разработок в этой области, стимулируемых неутолимым спросом на более мощные и доступные LLM. От аппаратного ускорения и сжатия модели до совершенно новых архитектур поиск эффективного вывода LLM остается захватывающим фронтиром в области обработки естественного языка и искусственного интеллекта.

Я провел последние пять лет, погружаясь в увлекательный мир машинного обучения и глубокого обучения. Моя страсть и экспертиза привели меня к участию в более чем 50 различных проектах программной инженерии, с особым акцентом на ИИ/МО. Мое непрекращающееся любопытство также привело меня к обработке естественного языка, области, которую я с нетерпением жду возможности изучить дальше.