Connect with us

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

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

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

mm
LLM Inference Speed up

Крупные языковые модели (LLM) như 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

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

from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig

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)

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

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

 

Алгоритм Flash Attention

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

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

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

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

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

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

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

from transformers import AutoModelForCausalLM
import torch
from flash_attention import flash_attention

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

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

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

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

# Запуск модели с 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

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

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

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

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

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

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

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

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

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

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

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

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

Многозапросное внимание

Многозапросное внимание

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

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

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

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

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

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

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

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

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

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

Заключение

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

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

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

Я провел последние пять лет, погружаясь в увлекательный мир Machine Learning и Deep Learning. Моя страсть и экспертиза привели меня к участию в более чем 50 различных проектах по разработке программного обеспечения, с особым акцентом на AI/ML. Мое непрекращающееся любопытство также привело меня к Natural Language Processing, области, которую я с нетерпением жду возможности изучить более подробно.