Параметры 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, и я тоже постараюсь написать аналогичный скрипт и поделиться им здесь.