Самостоятельный хостинг LLM в продакшене с vLLM
Продвинутое4 минРедакция Innovialabs
Коротко
vLLM запускает открытые модели на ваших GPU с OpenAI-совместимым API и эффективным батчингом; это выгодно при стабильной нагрузке, требованиях к хранению данных и наличии команды для эксплуатации.
Коротко о главном
vLLM — open-source сервер инференса для больших языковых моделей. Он загружает открытую модель (Llama, Qwen, Mistral и другие) на ваши GPU и отдаёт OpenAI-совместимый HTTP API. Часто существующий код клиента работает после замены одного base URL.
Главные преимущества — PagedAttention (экономное хранение KV-кэша в памяти) и continuous batching (новые запросы подключаются к текущему батчу, а не ждут очереди). Благодаря этому одна видеокарта обслуживает много пользователей одновременно.
Свой хостинг оправдан, когда:
- данные нельзя отправлять за пределы вашей инфраструктуры;
- нагрузка высокая и достаточно ровная, чтобы GPU не простаивали;
- нужна дообученная или конкретная открытая модель;
- есть инженеры, готовые обслуживать GPU-серверы.
Как подобрать GPU
Первое ограничение — память. Грубая оценка:
- Веса = число параметров x байт на параметр. Модель 7B в FP16 (2 байта) занимает около 14 ГБ, в 8 битах — около 7 ГБ, в 4 битах — примерно 3,5-4 ГБ.
- KV-кэш растёт вместе с длиной контекста и числом одновременных запросов. Именно он ограничивает, сколько пользователей поместится сразу.
- Накладные расходы на активации и CUDA runtime.
Если модель не помещается на одну карту, vLLM делит её между несколькими GPU через tensor parallelism. Квантизованные модели (AWQ, GPTQ, FP8) требуют меньше памяти ценой некоторой потери качества — её стоит измерить на ваших задачах.
Запуск сервера
pip install vllm
vllm serve Qwen/Qwen2.5-7B-Instruct \
--max-model-len 8192 \
--gpu-memory-utilization 0.90 \
--tensor-parallel-size 1
Клиент использует обычный OpenAI SDK:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="local")
resp = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[{"role": "user", "content": "Привет"}],
)
print(resp.choices[0].message.content)
Флаги меняются от версии к версии, поэтому сверяйтесь с официальной документацией vLLM.
Пропускная способность или задержка
Эти цели тянут в разные стороны:
| Цель | Что помогает | Цена |
|---|---|---|
| Высокая пропускная способность (много токенов в секунду суммарно) | большие батчи, больше параллельных последовательностей, выше доля используемой памяти | каждый пользователь ждёт дольше |
| Низкая задержка (быстрый первый токен) | меньшие батчи, короче максимальный контекст, prefix caching для повторяющихся системных промптов | меньше пользователей на одну GPU |
Основные настройки:
--max-model-len— короткий контекст освобождает KV-кэш под больше параллельных запросов.--max-num-seqs— лимит одновременных последовательностей в батче.--gpu-memory-utilization— какую долю видеопамяти vLLM может занять.- Prefix caching — повторно использует вычисления, если у многих запросов одинаковый длинный системный промпт.
Прежде чем выбирать настройки, измерьте время до первого токена (TTFT), время на каждый выходной токен и общее число токенов в секунду под реалистичной нагрузкой.
Чек-лист для продакшена
- Ставьте vLLM за reverse proxy с аутентификацией и rate limits — сам сервер не является полноценным API-шлюзом.
- Запускайте в Docker с зафиксированными версиями модели и образа.
- Собирайте метрики (у vLLM есть Prometheus endpoint) и настройте алерты на длину очереди, память GPU и долю ошибок.
- Учитывайте холодный старт: загрузка большой модели занимает время, держите прогретые реплики.
- Предусмотрите fallback на облачный API на случай сбоев и пиков.
Свой сервер или облачный API: полная стоимость
Сравнивайте не только цену GPU с ценой за токен. Учитывайте всё:
- Стоимость GPU — платите и за работу, и за простой. Низкая загрузка делает каждый токен дорогим.
- Время инженеров — настройка, обновления, мониторинг, дежурства.
- Качество модели — открытой модели может понадобиться больше работы с промптами или дообучение, чтобы сравняться с топовым API.
- Масштабирование — облачный API выдерживает пики, а у вашего кластера фиксированный потолок.
Облачный API обычно выгоднее при неровной или небольшой нагрузке и на этапе прототипа. Свой хостинг окупается при стабильно высокой нагрузке, жёстких требованиях к месту хранения данных или потребности в своей модели.
Частые ошибки
- Подбирать GPU только по размеру весов и забывать про KV-кэш.
- Ставить максимальный контекст намного больше, чем реально присылают пользователи.
- Тестировать одним запросом вместо реалистичной параллельной нагрузки.
- Открывать порт vLLM напрямую в интернет.