Найти в Дзене
LLM. GPT. AI.

Запуск VLLM в docker-контейнере

Работа с LLM накладывает значительные требования к вычислительным ресурсам, особенно при инференсе (выводе) на реальных данных. Для оптимизации процесса инференса были разработаны различные бэкенды, и одним из таких решений является VLLM. VLLM (Vectorized Large Language Model) — это высокопроизводительный бэкенд для инференса больших языковых моделей, разработанный с акцентом на эффективное использование памяти и вычислительных ресурсов. VLLM использует векторизацию операций и оптимизацию памяти для ускорения вывода, что делает его особенно привлекательным для приложений, где требуется высокая пропускная способность и низкая задержка. Основные особенности VLLM: VLLM используется для ускорения инференса больших языковых моделей в реальных приложениях. Это может быть полезно в следующих сценариях: Существует несколько популярных бэкендов для инференса LLM, таких как Hugging Face Transformers, FasterTransformer, ONNX Runtime и TensorRT. Давайте сравним VLLM с этими решениям
Оглавление

Работа с LLM накладывает значительные требования к вычислительным ресурсам, особенно при инференсе (выводе) на реальных данных. Для оптимизации процесса инференса были разработаны различные бэкенды, и одним из таких решений является VLLM.

Что такое VLLM?

VLLM (Vectorized Large Language Model) — это высокопроизводительный бэкенд для инференса больших языковых моделей, разработанный с акцентом на эффективное использование памяти и вычислительных ресурсов. VLLM использует векторизацию операций и оптимизацию памяти для ускорения вывода, что делает его особенно привлекательным для приложений, где требуется высокая пропускная способность и низкая задержка.

Основные особенности VLLM:

  1. Эффективное использование памяти: VLLM минимизирует объем памяти, необходимый для хранения промежуточных данных, что позволяет запускать более крупные модели на устройствах с ограниченными ресурсами.
  2. Векторизация вычислений: VLLM использует векторизованные операции для ускорения выполнения задач, что особенно важно при работе с большими объемами данных.
  3. Поддержка мультизадачности: VLLM поддерживает одновременную обработку нескольких запросов, что делает его подходящим для масштабируемых приложений.
  4. Простота интеграции: VLLM легко интегрируется с существующими стеками для работы с LLM, такими как Hugging Face Transformers.

Для чего используется VLLM?

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

  • Генерация текста: Ускорение работы моделей, таких как GPT, для создания контента в реальном времени.
  • Диалоговые системы: Обеспечение низкой задержки при обработке пользовательских запросов.
  • Масштабируемые сервисы: Поддержка высокой пропускной способности при обработке большого количества запросов.
  • Ограниченные ресурсы: Запуск крупных моделей на устройствах с ограниченной памятью и вычислительной мощностью.

Сравнение VLLM с другими бэкендами для инференса LLM

Существует несколько популярных бэкендов для инференса LLM, таких как Hugging Face Transformers, FasterTransformer, ONNX Runtime и TensorRT. Давайте сравним VLLM с этими решениями.

Основные преимущества VLLM:

  • Эффективность памяти: VLLM превосходит Hugging Face Transformers и TensorRT в этом аспекте, что делает его идеальным для запуска крупных моделей на устройствах с ограниченными ресурсами.
  • Скорость инференса: VLLM конкурирует с FasterTransformer и ONNX Runtime, предлагая высокую производительность при обработке большого количества запросов.
  • Простота интеграции: VLLM легко интегрируется с существующими инструментами, такими как Hugging Face, что упрощает его внедрение в существующие проекты.

Docker-контейнер — это легковесная, автономная и переносимая среда выполнения, которая инкапсулирует приложение со всеми его зависимостями (библиотеки, конфигурации, системные инструменты и т.д.). Контейнеры создаются на основе образов, которые представляют собой шаблоны, содержащие все необходимое для запуска приложения.

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

Docker-контейнеры удобно использовать

  1. Переносимость:
    Приложение, запущенное в Docker-контейнере, будет работать одинаково на любой системе, где установлен Docker. Это упрощает развертывание и тестирование приложений.
  2. Изоляция:
    Контейнеры изолируют приложение и его зависимости от окружающей среды, что предотвращает конфликты между библиотеками и инструментами.
  3. Простота управления зависимостями:
    Все зависимости приложения упаковываются в образ, что избавляет от необходимости вручную устанавливать и настраивать библиотеки на каждой системе.
  4. Масштабируемость:
    Docker-контейнеры легко масштабируются, что делает их идеальным решением для создания распределенных систем и микросервисов.
  5. Эффективное использование ресурсов:
    Контейнеры используют ядро хостовой ОС, что делает их более легковесными и быстрыми по сравнению с виртуальными машинами.
  6. Сообщество и экосистема:
    Docker имеет огромное сообщество и обширную экосистему, включая Docker Hub, где можно найти готовые образы для различных приложений и инструментов.

Почему Docker идеально подходит для VLLM?

  • Простота развертывания: Docker позволяет быстро развернуть VLLM в изолированной среде, не беспокоясь о конфликтах с другими библиотеками или зависимостями.
  • Переносимость: VLLM, запущенный в Docker, будет работать одинаково на любом сервере или локальной машине.
  • Масштабируемость: Docker упрощает масштабирование VLLM для обработки большого количества запросов.

Запуск VLLM через Docker

1. Использование готового Docker-образа

VLLM предоставляет официальный Docker-образ, который можно использовать для запуска сервера, совместимого с API OpenAI. Образ доступен на Docker Hub под именем vllm/vllm-openai.

Шаг 1: Загрузка Docker-образа

Для начала загрузите образ с Docker Hub:

docker pull vllm/vllm-openai:latest

Шаг 2: Запуск контейнера

После загрузки образа вы можете запустить контейнер с помощью следующей команды:

docker run --runtime nvidia --gpus all -v ~/.cache/huggingface:/root/.cache/huggingface --env "HUGGING_FACE_HUB_TOKEN=<secret>" -p 8000:8000 --ipc=host vllm/vllm-openai:latest --model mistralai/Mistral-7B-v0.1

Объяснение параметров:

  • --runtime nvidia --gpus all: Указывает, что контейнер будет использовать GPU для ускорения вычислений.
  • -v ~/.cache/huggingface:/root/.cache/huggingface: Монтирует локальный кэш Hugging Face в контейнер, чтобы избежать повторной загрузки моделей.
  • --env "HUGGING_FACE_HUB_TOKEN=<secret>": Устанавливает токен доступа к Hugging Face Hub.
  • -p 8000:8000: Пробрасывает порт 8000 контейнера на порт 8000 хоста.
  • --ipc=host: Позволяет контейнеру использовать разделяемую память хоста, что важно для работы PyTorch.
  • --model mistralai/Mistral-7B-v0.1: Указывает модель, которую нужно загрузить и использовать.

2. Сборка Docker-образа из исходного кода

Если вы хотите настроить VLLM под свои нужды, вы можете собрать Docker-образ из исходного кода.

Шаг 1: Сборка образа

Используйте предоставленный Dockerfile для сборки образа:

DOCKER_BUILDKIT=1 docker build . --target vllm-openai --tag vllm/vllm-openai

Дополнительные параметры:

  • --build-arg max_jobs=8: Устанавливает максимальное количество параллельных задач при сборке.
  • --build-arg nvcc_threads=2: Устанавливает количество потоков для NVCC (компилятора CUDA).
  • --build-arg torch_cuda_arch_list="": Если вы хотите собрать образ только для текущего типа GPU, добавьте этот аргумент.

Шаг 2: Запуск собранного образа

После успешной сборки вы можете запустить контейнер:

docker run --runtime nvidia --gpus all -v ~/.cache/huggingface:/root/.cache/huggingface -p 8000:8000 --env "HUGGING_FACE_HUB_TOKEN=<secret>" vllm/vllm-openai <args...>

3. Настройка для версий v0.4.1 и v0.4.2

Для версий v0.4.1 и v0.4.2 Docker-образы должны запускаться от имени пользователя root, так как в процессе работы требуется загрузка библиотеки, расположенной в домашнем каталоге root. Если вы запускаете контейнер от имени другого пользователя, вам нужно изменить права доступа к библиотеке и указать её путь через переменную окружения:

docker run --runtime nvidia --gpus all -v ~/.cache/huggingface:/root/.cache/huggingface -p 8000:8000 --env "HUGGING_FACE_HUB_TOKEN=<secret>" --env "VLLM_NCCL_SO_PATH=/root/.config/vllm/nccl/cu12/libnccl.so.2.18.1" vllm/vllm-openai <args...>

4. Использование Docker Compose

Для упрощения управления контейнерами можно использовать Docker Compose. Создайте файл docker-compose.yml со следующим содержимым:

-2

Запустите контейнер с помощью команды:

docker-compose up -d

5. Проверка работы

После запуска контейнера вы можете проверить, что сервер работает, отправив запрос через API:

curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "mistralai/Mistral-7B-v0.1",
"messages": [
{"role": "user", "content": "Привет, как дела?"}
]
}'

Дополнительные аргументы работы vLLM: Улучшение производительности и функциональности

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

Основные дополнительные аргументы

  1. --dtype:
    Указывает тип данных для вычислений. Поддерживаемые значения: auto, half, float16, bfloat16, float, float32.
    Пример: --dtype auto — автоматически выбирает наиболее подходящий тип данных для текущей модели.
  2. --max-model-len:
    Определяет максимальную длину контекста модели. Это полезно для моделей с ограниченной памятью.
    Пример: --max-model-len 4096 — устанавливает максимальную длину контекста в 4096 токенов.
  3. --chat-template:
    Указывает путь к файлу или строку с шаблоном чата. Этот аргумент необходим, если модель не предоставляет встроенного шаблона чата.
    Пример: --chat-template ./path-to-chat-template.jinja — использует указанный шаблон для обработки чатов.
  4. --api-key:
    Устанавливает API-ключ для сервера. Это позволяет ограничить доступ к серверу.
    Пример: --api-key token-abc123 — задает ключ доступа к серверу.
  5. --enable-auto-tool-choice:
    Включает автоматический выбор инструментов для обработки запросов.
    Пример: --enable-auto-tool-choice — позволяет модели автоматически выбирать инструменты для выполнения задач.
  6. --tool-call-parser:
    Указывает парсер инструментов. Поддерживаемые значения: mistral, hermes и другие.
    Пример: --tool-call-parser hermes — использует парсер Hermes для обработки инструментов.
  7. --quantization:
    Включает квантование модели для уменьшения использования памяти.
    Пример: --quantization bitsandbytes — использует квантование через библиотеку bitsandbytes.
  8. --gpu-memory-utilization:
    Устанавливает уровень использования GPU. Значение в диапазоне от 0 до 1.
    Пример: --gpu-memory-utilization 0.8 — использует 80% памяти GPU.
  9. --max-num-batched-tokens:
    Ограничивает максимальное количество токенов, обрабатываемых за один запрос.
    Пример: --max-num-batched-tokens 2048 — ограничивает количество токенов в одном запросе до 2048.
  10. --enable-chunked-prefill:
    Включает обработку входных данных по частям, что может улучшить производительность при работе с большими объемами данных.
    Пример: --enable-chunked-prefill — включает обработку данных по частям.

Пример использования дополнительных аргументов

Пример команды для запуска сервера с использованием нескольких дополнительных аргументов:

vllm serve NousResearch/Meta-Llama-3-8B-Instruct --dtype auto --max-model-len 4096 --chat-template ./path-to-chat-template.jinja --api-key token-abc123 --enable-auto-tool-choice --tool-call-parser hermes --quantization bitsandbytes --gpu-memory-utilization 0.8 --max-num-batched-tokens 2048 --enable-chunked-prefill

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

При работе с vLLM на системах с несколькими GPU может потребоваться увеличение объема разделяемой памяти (/dev/shm) для обеспечения стабильной работы и улучшения производительности. По умолчанию Docker выделяет только 64MB для разделяемой памяти, что может быть недостаточно для интенсивных вычислений, таких как инференс больших языковых моделей.

Зачем нужно увеличивать --shm-size при работе с несколькими GPU?

  1. Оптимизация обмена данными между GPU:
    При использовании нескольких GPU данные часто передаются через разделяемую память. Увеличение её объема до 2GB или более позволяет избежать ошибок, связанных с нехваткой памяти, и ускорить выполнение задач.
  2. Поддержка больших моделей:
    Крупные модели, такие как Mistral-7B или LLaMA-2, требуют значительного объема памяти для хранения промежуточных данных. Увеличение /dev/shm помогает избежать переполнения памяти.
  3. Улучшение стабильности:
    При интенсивной работе vLLM с большим количеством запросов увеличение разделяемой памяти снижает вероятность сбоев и повышает стабильность системы.
  4. Эффективное использование ресурсов:
    При работе с несколькими GPU разделяемая память используется для обмена данными между устройствами, что особенно важно для распределенных вычислений.

При запуске vLLM через Docker добавьте параметр --shm-size=2gb в команду docker run:

docker run --runtime nvidia --gpus all -v ~/.cache/huggingface:/root/.cache/huggingface -p 8000:8000 --ipc=host --shm-size=2gb vllm/vllm-openai:latest --model mistralai/Mistral-7B-v0.1

Этот параметр выделяет 2GB разделяемой памяти для контейнера, что обеспечивает стабильную работу vLLM, особенно при использовании нескольких GPU.