Настройка vLLM для максимальной производительности

Источник

Параметры vLLM Engine, которые мы будем обсуждать:

  • max-num-batched-tokens
  • max-model-len
  • gpu-memory-utilization
  • enable-prefix-caching
  • enable-chunked-prefill
  • enforce-eager

max-model-len:

TL;DR в соответствии с максимальным количеством используемых токенов (ввод + вывод)

  • По умолчанию максимальная длина модели равна максимальной длине контекста используемой вами модели. Например, для модели llama 3 8B instruct она будет равна 8192.
  • Если вы можете определить максимальную длину контекста для вашего случая использования и если она меньше максимальной длины контекста вашей модели, лучше установить для этого параметра такое значение.
  • Это не только предотвратит ошибку нехватки памяти при загрузке или использовании модели, но и поможет настроить другие параметры, такие как max-num-batched-tokens и gpu-memory-utilization.
  • Значение включает в себя количество входных и выходных токенов, поэтому, если в вашем случае общее количество токенов не превышает, скажем, 2046, установите для этого параметра такое значение.

max-num-batched-tokens:

TL;DR начните с max-model-len, затем попробуйте удвоить это значение: max-model-len*2, затем *3… пока не получите ошибку нехватки памяти или предупреждение о вытеснении. Выберите значение, которое обеспечивает хорошую производительность. Если вы используете enable-chunked-prefill, начните с меньшего значения, например 128, и попробуйте разные значения. См. пояснения ниже.

  • Обратите внимание, что этот параметр обозначает количество токенов, а не размер пакета.
  • Каждый запрос должен пройти этап предварительного заполнения (вычисление значения KV для входных токенов и распределение их по блокам кэша KV), а затем этап декодирования, на котором происходит рекурсивное прямое вычисление для получения токенов по одному.
  • Таким образом, минимальное значение этого параметра равно максимальной длине модели, которую вы установили для предварительного заполнения (если только вы не используете chunked-prefill, подробнее об этом позже).
  • Чем больше токенов в пакете, тем больше предварительных заполнений, а значит, первый токен будет сгенерирован быстрее. Планировщик vLLM по умолчанию предпочитает предварительные заполнения.
  • Таким образом, большой размер пакета может помочь повысить пропускную способность, но это работает не во всех случаях, поскольку пропускная способность и задержка также зависят от соотношения вычислительных ресурсов и памяти графического процессора (подробнее об этом в разделе chunked-prefill), и, как правило, предварительные заполнения требуют больших вычислительных ресурсов, поэтому они быстро достигают максимального количества токенов в пакете, которое мы можем сохранить.
  • Поэтому лучше начать со значения max-model-len, попробовать увеличить его вдвое и посмотреть, как изменится производительность, пока не возникнет ошибка нехватки памяти или предупреждение о вытеснении, как указано здесь, чтобы выбрать правильное количество токенов в пакете. Затем попробуйте применить эту теорию, чтобы понять, как работает ваша система.

включить кэширование префиксов:

Вкратце включите его, если только вы не используете enable-chunked-prefill

  • Он кэширует вычисленные значения KV для дальнейшего использования, что позволяет сэкономить много времени.
  • Если большая часть вашего запроса остается неизменной при вводе данных, то вы заметите более значительное повышение производительности по сравнению с настройкой, в которой очень малая часть токенов в запросе остается неизменной.
  • Если используется параметр enable-chunked-prefill, то этот параметр недопустим (на момент публикации этого поста)

использование-графической-памяти:

TL;DR чем больше, тем лучше, если только не возникнет ошибка нехватки памяти. По умолчанию 0,9

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

enforce-eager:

TL;DR если не хватает памяти, включите эту функцию

  • При использовании не будет создаваться граф CUDA, что может повлиять на производительность, но позволит сэкономить память, которая потребовалась бы для графа.
  • При некоторых настройках граф CUDA не окажет существенного влияния на производительность, а сэкономленная память может быть полезна для увеличения значений вышеуказанных параметров, таких как gpu-memory-utilization, max-num-batched-tokens и т. д.

enable-chunked-prefill:

TL;DR попробуйте включить эту функцию и использовать пакетные токены, начиная со значения 128 и постепенно увеличивая его. Сравните с настройкой без этого параметра. Подробнее см. ниже.

  • Этап декодирования менее требователен к вычислительным ресурсам по сравнению с предварительным заполнением (умножение вектора на матрицу вместо умножения матрицы на матрицу), но более требователен к памяти, так как ему необходимо считывать вычисленные значения KV.
  • Если вы хотите узнать больше, обратитесь к этой статье и этой странице vLLM.
  • Как уже говорилось, по умолчанию планировщик vLLM отдает предпочтение предварительному заполнению, которое требует вычислительных ресурсов, а во время декодирования память становится узким местом, не позволяющим в полной мере использовать декодирование с низкими вычислительными ресурсами и высокой потребностью в памяти, так как требуется считывание значений KV.
  • Chunk prefill разбивает этап prefill на фрагменты, что позволяет уменьшить количество токенов в пакете и сначала сформировать пакет, собрав запросы на декодирование и добавив запрос на разбиение на фрагменты для prefill, чтобы эффективно использовать ресурсы графического процессора, комбинируя как ресурсоёмкое разбиение на фрагменты для prefill, так и достаточное количество запросов на декодирование с низкой ресурсоёмкостью, но высокой потребностью в памяти.
  • Снова попробуйте включить эту функцию и использовать небольшое максимальное количество токенов в пакете, например 128, и увеличивать его, пока не получите требуемые показатели пропускной способности и задержки.
  • Этот метод может помочь сократить задержку между токенами, поскольку декодирование имеет приоритет из-за небольшого размера пакета (что снижает нагрузку на память), но может повлиять на пропускную способность, поэтому необходимо попробовать разные размеры пакетов, а также сравнить результаты, когда этот параметр не используется.

Пример:

  • Мы будем использовать vLLM api точек входа вместо сервера, совместимого с openai
  • Чтобы запустить сервер без предварительного заполнения фрагментами, можно использовать следующий пример:
python3 -m vllm.entrypoints.api_server — model MaziyarPanahi/Meta-Llama-3–8B-Instruct-GPTQ — gpu-memory-utilization 0.95 — port 5000 — dtype half — enforce-eager — max-model-len 4096 — max-num-batched-tokens 8192 — enable-prefix-caching
  • Если включена функция предварительного заполнения, команда может выглядеть так:
python3 -m vllm.entrypoints.api_server — model MaziyarPanahi/Meta-Llama-3–8B-Instruct-GPTQ — gpu-memory-utilization 0.95 — port 5000 — dtype half — enforce-eager — max-model-len 4096 — max-num-batched-tokens 256 — enable-chunked-prefill
  • Отправьте запрос на указанную выше конечную точку сервера, чтобы проверить производительность при различных параметрах.
  • Проведите бенчмарк с помощью скриптов, предоставленных vLLM, и я тоже постараюсь написать аналогичный скрипт и поделиться им здесь.

От автора