Разделение Prefill и Decode: ключ к ускорению LLM на GPU
Разделение фаз Prefill и Decode в больших языковых моделях (LLM) может сократить время ожидания на 20–30% и повысить пропускную способность при обработке параллельных запросов. Это достигается за счет устранения конкуренции за ресурсы GPU между этими двумя этапами генерации. Исследователи из TNG Tec

Разделение фаз Prefill и Decode в больших языковых моделях (LLM) может сократить время ожидания на 20–30% и повысить пропускную способность при обработке параллельных запросов. Это достигается за счет устранения конкуренции за ресурсы GPU между этими двумя этапами генерации. Исследователи из TNG Technology Consulting опубликовали детальный анализ и практические рекомендации, которые помогут разработчикам и инженерам MLOps оптимизировать инференс моделей в реальных приложениях.
Как работают фазы Prefill и Decode в LLM
В процессе генерации текста большая языковая модель проходит через две четко разделенные фазы. Первая фаза, Prefill, обрабатывает весь входной промпт целиком, вычисляя скрытые состояния и создавая ключи и значения для механизма внимания (attention keys/values). Эта операция является вычислительно интенсивной и требует значительного объема памяти GPU, особенно при длинных контекстах. После завершения Prefill модель переходит к фазе Decode, где генерирует выходные токены по одному, используя уже вычисленные ключи и значения. На каждом шаге Decode модель обрабатывает только один новый токен, что делает эту фазу более легкой с точки зрения вычислений, но критичной по задержкам, так как токены генерируются последовательно.
Почему параллельные запросы создают узкие места
При обслуживании нескольких пользователей или запросов одновременно, фазы Prefill и Decode разных запросов могут конкурировать за одни и те же ресурсы GPU, такие как вычислительные ядра, память и пропускная способность памяти. Если модель обрабатывает запросы в смешанном режиме, то тяжелые Prefill-операции могут задерживать легкие Decode-шаги, увеличивая время отклика для всех пользователей. Это особенно заметно в сценариях реального времени, например, в чат-ботах или ассистентах, где каждый миллисекунда имеет значение. Кроме того, неэффективное использование памяти GPU при параллельной обработке может приводить к нехватке видеопамяти (OOM) и снижению пропускной способности.
Как разделение Prefill и Decode решает проблему
Исследователи из TNG Technology Consulting предложили несколько методов разделения этих фаз. Основная идея заключается в том, чтобы обрабатывать Prefill и Decode в отдельных пакетах (batch), а не смешивать их в одном батче. Например, можно накапливать несколько Prefill-запросов и выполнять их вместе, а затем отдельно обрабатывать Decode для всех активных запросов. Такой подход позволяет более эффективно использовать вычислительные ресурсы: GPU может быть загружен однородными операциями, что уменьшает простои и переключения контекста. Дополнительно применяется динамическое планирование запросов, где приоритет отдается Decode-шагам для запросов, которые уже начали генерацию, чтобы минимизировать задержки для пользователей, ожидающих ответа.
Какие результаты показывают бенчмарки
В экспериментах, проведенных командой, использование раздельной обработки Prefill и Decode позволило снизить среднее время ожидания (latency) на 20–30% при типичной нагрузке. Пропускная способность (throughput) также увеличилась, особенно в сценариях с большим количеством параллельных запросов. Например, при 64 одновременных запросах с длиной промпта 512 токенов и генерацией 128 токенов, время до первого токена (TTFT) сократилось на 25%, а общее время генерации — на 22%. Важно отметить, что эти результаты были получены на GPU NVIDIA A100 с использованием библиотек PyTorch и Hugging Face Transformers, но авторы утверждают, что методы применимы и к другим архитектурам.
Какие модели и инструменты выиграют от этой оптимизации
Разделение фаз Prefill и Decode особенно полезно для моделей с архитектурой Transformer, таких как LLaMA, GPT, Mistral и другие. Оно также актуально для моделей, использующих механизм внимания с кэшированием ключей и значений (KV cache). Инженеры MLOps, работающие с фреймворками вроде vLLM, TensorRT-LLM или Hugging Face TGI, могут внедрить эти методы, модифицируя планировщик запросов или используя специальные бэкенды. Разработчики сервисов на основе генеративного AI, такие как чат-боты, ассистенты, системы генерации кода, увидят снижение задержек и улучшение пользовательского опыта.
Какие ограничения и неизвестные аспекты остаются
Несмотря на впечатляющие результаты, исследование имеет некоторые ограничения. Точные конфигурации оборудования (версия драйверов, CUDA, библиотек) не были раскрыты, что может затруднить воспроизведение результатов. Кроме того, методы тестировались в основном на моделях с плотной архитектурой Transformer; их применимость к моделям Mixture of Experts (MoE) или другим нестандартным архитектурам пока не подтверждена. Также остается открытым вопрос о влиянии разделения на использование памяти: хотя общая эффективность растет, в некоторых случаях может потребоваться больше памяти для хранения отдельных буферов Prefill и Decode.
Как внедрить разделение Prefill и Decode на практике
Для практического внедрения разработчикам рекомендуется начать с профилирования текущей нагрузки и выявления узких мест. Затем можно модифицировать планировщик запросов, чтобы группировать Prefill-запросы и выполнять их отдельно от Decode. Библиотеки, такие как vLLM, уже поддерживают подобные механизмы через настройки планирования. Другой подход — использовать асинхронную обработку, где Prefill выполняется в фоновом режиме, а Decode получает приоритет. Важно также настроить размер батча и таймауты, чтобы избежать голодания запросов. Тестирование на репрезентативной нагрузке поможет подобрать оптимальные параметры.
Какие альтернативные методы оптимизации LLM существуют
Помимо разделения Prefill и Decode, существуют и другие техники ускорения LLM. Например, квантование модели (int8, int4) снижает требования к памяти и ускоряет вычисления за счет потери точности. Дистилляция знаний позволяет создать меньшую модель, сохраняющую качество большой. Также популярны методы спекулятивного декодирования (speculative decoding), где маленькая модель генерирует черновик, а большая его проверяет. Однако разделение Prefill и Decode особенно эффективно в сценариях с высокой параллельной нагрузкой, где другие методы могут дать меньший выигрыш.
Заключение
Разделение фаз Prefill и Decode — это мощный, но относительно простой метод оптимизации производительности LLM, который может дать значительное ускорение без изменения архитектуры модели. Разработчики и инженеры MLOps, внедряющие LLM в продакшн, должны рассмотреть эту технику как часть своего арсенала. Дальнейшие исследования в этой области, вероятно, приведут к еще более эффективным стратегиям планирования и использования ресурсов GPU.