MAATRIX / Блог / Как установить и настроить vLLM на VPS

Как установить и настроить vLLM на VPS

Как установить и настроить vLLM на VPS

MAATRIX

Установка vLLM выглядит как одна команда pip install, а заканчивается на том, что сервер падает при старте с жалобой на KV-кэш, или молча слушает 0.0.0.0:8000 без всякой авторизации. Ниже — установка vLLM на VPS целиком: что проверить до первой команды, чем ставить в 2026 году, какие флаги решают судьбу запуска, дословные тексты ошибок первого старта и как довести всё до systemd-юнита с HTTPS.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое vLLM и когда он окупается

vLLM — это сервер инференса: он держит одну модель в видеопамяти и отдаёт ответы по OpenAI-совместимому API. Не оболочка, не чат, не менеджер моделей. Запустили процесс — получили эндпоинт POST /v1/chat/completions на порту 8000, к которому подключается любой клиент, умеющий говорить с OpenAI.

Актуальный релиз на конец августа 2026 — 0.28.0. Версия важна не из педантизма: начиная с 0.25.0 путём по умолчанию стал Model Runner V2, а легаси-реализация PagedAttention из кода удалена. Практическое следствие — половина руководств в интернете писалась под ветки 0.6–0.9 и предлагает запускать сервер как python -m vllm.entrypoints.openai.api_server с флагами вроде --use-v2-block-manager, которых больше нет. Копируете такую команду — получаете error: unrecognized arguments и полчаса недоумения.

Требования у vLLM жёсткие и проверяются до установки:

  • Видеокарта NVIDIA с compute capability 7.0 и выше — T4, V100, RTX 20xx и всё новее. На картах ниже сборка просто не запустится.
  • Python 3.10 и новее, рекомендуется 3.12. Системный Python Ubuntu 24.04 — 3.12, это подходит.
  • Драйвер NVIDIA, а вот CUDA Toolkit ставить не нужно: колёса vLLM собраны с CUDA 12.9 и тянут рантайм внутри пакета.
  • 8–10 ГБ на диске только под зависимости — PyTorch с библиотеками CUDA весит именно столько, ещё до первой модели.

Честный ограничитель: без видеокарты vLLM брать не стоит. CPU-бэкенд есть, но это путь для разработки — образ собирается отдельным Dockerfile с флагами инструкций (VLLM_CPU_AVX512, VLLM_CPU_AMXBF16), для Zen 4/Zen 5 отдельной целью vllm-openai-zen. Скорость там та же, что у любого процессорного инференса: на нашем стенде AMD EPYC 9554, 16 vCPU, модель qwen2.5:7b в Q4_K_M через Ollama даёт 7,6 токена в секунду. Это потолок CPU, и vLLM его не поднимает. На сервере без GPU ставьте Ollama — разбор различий в материале Ollama против vLLM.

vLLM окупается там, где запросов много одновременно: от десятка параллельных, одна модель на весь сервис, длинный общий системный промпт. Один пользователь и коллекция из пяти моделей — не его сценарий.

Что проверить на сервере до первой команды

Первое — драйвер. Показывать nvidia-smi должен примерно это:

$ nvidia-smi
NVIDIA-SMI 580.95.05   Driver Version: 580.95.05   CUDA Version: 13.0
+-----------------------------------------+----------------------+
| GPU  Name        Persistence-M | Memory-Usage | GPU-Util  Compute M. |
|   0  NVIDIA L4            On   |  0MiB / 23034MiB |      0%      Default |

Если вместо этого nvidia-smi: command not found или карта в выводе lspci | grep -i nvidia есть, а драйвера нет — ставьте и перезагружайтесь:

sudo apt update && sudo apt install -y ubuntu-drivers-common
sudo ubuntu-drivers install
sudo reboot

Строка CUDA Version: в шапке — это максимум, который поддерживает драйвер, а не установленный тулкит. Пока она не ниже 12.9, колёса vLLM заработают.

Второе — диск: 8–10 ГБ зависимости плюс вес модели. Qwen3 8B в BF16 — около 16 ГБ, он же в 4-битном AWQ — примерно 6 ГБ, 32B в AWQ — около 20 ГБ. Кэш Hugging Face по умолчанию ложится в ~/.cache/huggingface на системный диск; если под данные отдельный том, переопределите переменную, иначе корень кончится посреди загрузки:

sudo mkdir -p /data/hf && sudo chown vllm:vllm /data/hf
export HF_HOME=/data/hf
df -h / /data

Третье — оперативная память: веса грузятся с диска через RAM. При 16 ГБ загрузка 16-гигабайтной модели уедет в своп, старт растянется на минуты, а если свопа мало — процесс убьёт OOM-killer.

Четвёртое — токен Hugging Face. Llama, Gemma и часть других семейств закрыты лицензией, и без токена загрузка обрывается так:

OSError: You are trying to access a gated repo.
Make sure to have access to it at https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct.
401 Client Error. Cannot access gated repo for url .../resolve/main/config.json

Лечится один раз: принять лицензию на странице модели в браузере, потом hf auth login и вставить токен. Утилита с 2025 года называется hf; старый huggingface-cli работает, но ругается на устаревший синтаксис. Веса удобно скачать заранее, отдельно от запуска сервиса:

/opt/vllm/bin/hf download Qwen/Qwen3-8B
# в репозиториях Llama лежит второй комплект весов — его качать не надо:
/opt/vllm/bin/hf download meta-llama/Llama-3.1-8B-Instruct --exclude "original/*"

Пятое — фаервол, до того как что-либо поднялось: порт 8000 наружу не нужен ни на минуту.

sudo ufw allow 22/tcp
sudo ufw deny 8000/tcp
sudo ufw enable

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Установка vLLM: uv, venv или Docker

Три рабочих пути, выбирайте один и не смешивайте.

Через uv — рекомендуемый способ. Он разрешает зависимости быстрее pip и, главное, сам подбирает сборку PyTorch под ваш драйвер:

curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv /opt/vllm --python 3.12
uv pip install --python /opt/vllm/bin/python "vllm==0.28.0" --torch-backend auto

--torch-backend auto — ключевой аргумент: без него легко получить PyTorch под другую версию CUDA и потом ловить undefined symbol при импорте.

Классический venv. Работает, но медленнее и без автоподбора бэкенда:

python3 -m venv /opt/vllm
/opt/vllm/bin/pip install --upgrade pip
/opt/vllm/bin/pip install "vllm==0.28.0"

Чего делать нельзя — ставить в системный Python. Ubuntu 24.04 откажет: error: externally-managed-environment, а обход флагом --break-system-packages однажды сломает apt.

Версию фиксируйте всегда. Между минорными релизами vLLM регулярно переименовывает и выкидывает флаги; незакреплённая версия рано или поздно превращает рабочий юнит в unrecognized arguments посреди ночного обновления.

Docker. Годится, если на сервере уже живёт compose-стек. Нужен nvidia-container-toolkit, дальше:

docker run --gpus all --ipc=host \
  -v /data/hf:/root/.cache/huggingface \
  -e HF_TOKEN="$HF_TOKEN" \
  -p 127.0.0.1:8000:8000 \
  vllm/vllm-openai:v0.28.0 \
  --model Qwen/Qwen3-8B --max-model-len 8192

Два места, где спотыкаются все. Первое — --ipc=host (или --shm-size=8g): по умолчанию Docker даёт контейнеру 64 МБ разделяемой памяти, и воркер падает с Bus error при загрузке весов. Второе — публикация порта: -p 8000:8000 открывает его на всех интерфейсах в обход ufw, потому что Docker пишет правила в iptables раньше. Пишите адрес явно.

Проверка после установки:

/opt/vllm/bin/vllm --version
/opt/vllm/bin/python -c "import torch; print(torch.cuda.is_available(), torch.version.cuda)"

Вторая должна ответить True и номер версии CUDA. False — до модели дело не дойдёт, разбирайтесь с драйвером, а не с vLLM.

Первый запуск: флаги, от которых зависит всё

Минимальная рабочая команда выглядит так:

/opt/vllm/bin/vllm serve Qwen/Qwen3-8B \
  --served-model-name qwen3-8b \
  --host 127.0.0.1 --port 8000 \
  --api-key "$VLLM_API_KEY" \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 64

Каждый флаг здесь стоит не для красоты.

  • --host 127.0.0.1. По умолчанию vLLM слушает 0.0.0.0. Открытый эндпоинт — это чужие запросы на вашей карте и за ваш счёт.
  • --api-key. Единственная встроенная авторизация. Без флага любой, кто дотянулся до порта, работает с моделью без ключа. Значение генерируйте нормальное: sk-$(openssl rand -hex 24).
  • --served-model-name. Без него клиенты обязаны указывать полный путь Qwen/Qwen3-8B в поле model, включая регистр. С коротким алиасом вы потом смените модель, не трогая код приложений.
  • --max-model-len. Самый важный. По умолчанию берётся паспортное окно модели — 32 768, а у некоторых и 131 072 токена. vLLM резервирует KV-кэш так, чтобы хоть один запрос такой длины поместился, и на 24-гигабайтной карте это обычно невозможно. Ставьте честную цифру: 8192 хватает большинству чатов.
  • --gpu-memory-utilization. Доля всей видеопамяти, а не свободной. Если на карте уже висит чужой процесс, 0.90 приведёт к нехватке — смотрите nvidia-smi перед стартом.
  • --max-num-seqs. Потолок одновременных последовательностей в батче: понижение экономит память и режет пропускную способность.

Ещё три флага по обстоятельствам. --dtype half обязателен на T4 и V100 — про это ниже. --quantization awq вместе с AWQ-сборкой весов ужимает модель вчетверо и освобождает память под кэш. --tensor-parallel-size 2 раскладывает модель на две карты, но число должно нацело делить количество голов внимания: на трёх картах модель с 32 головами не запустится.

Считать KV-кэш вручную не обязательно — vLLM при старте сам печатает итог, и это самая полезная строка во всём логе:

INFO [gpu_worker.py:298] Available KV cache memory: 4.42 GiB
INFO [kv_cache_utils.py:864] GPU KV cache size: 36,192 tokens
INFO [kv_cache_utils.py:868] Maximum concurrency for 8,192 tokens per request: 4.42x

Последнее число — прямой ответ на вопрос «сколько пользователей влезет». Здесь их четверо, пятый встанет в очередь. Хотите больше — уменьшайте --max-model-len, включайте --kv-cache-dtype fp8 или переходите на квантованные веса. Формула ручного расчёта разобрана в сравнении Ollama и vLLM, но в бою удобнее эта строка.

Проверка живого сервера:

curl -s http://127.0.0.1:8000/v1/models -H "Authorization: Bearer $VLLM_API_KEY" | jq -r '.data[].id'
curl -s http://127.0.0.1:8000/v1/chat/completions \
  -H "Authorization: Bearer $VLLM_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"qwen3-8b","messages":[{"role":"user","content":"Скажи «работает»"}],"max_tokens":16}'

Эндпоинт /health отвечает без ключа и годится для мониторинга: пока он не вернул 200, модель ещё грузится.

Ошибки первого старта и их точные тексты

Почти все проблемы vLLM видны в первые полторы минуты. Вот те, что встречаются чаще прочих.

Текст в логеЧто произошло
The model's max seq len (131072) is larger than the maximum number of tokens that can be stored in KV cache (50944)не задан --max-model-len
No available memory for the cache blocks. Try increasing gpu_memory_utilizationвеса заняли карту целиком
torch.OutOfMemoryError: CUDA out of memoryна карте есть посторонний процесс
Bfloat16 is only supported on GPUs with compute capability of at least 8.0старая карта, нужен --dtype=half
RuntimeError: Found no NVIDIA driver on your systemдрайвер или проброс GPU в контейнер
Total number of attention heads (32) must be divisible by tensor parallel size (3)неверный --tensor-parallel-size

Первая строка — абсолютный лидер. Дословно она выглядит так:

ValueError: The model's max seq len (131072) is larger than the maximum number of
tokens that can be stored in KV cache (50944). Try increasing `gpu_memory_utilization`
or decreasing `max_model_len` when initializing the engine.

Совет из самой ошибки сбивает с толку: поднимать gpu_memory_utilization бессмысленно, там и так 0.90, а выше 0.95 карта начнёт падать на всплесках активаций. Правильный ход — второй: --max-model-len 8192.

Про старые карты. Дословный текст:

ValueError: Bfloat16 is only supported on GPUs with compute capability of at least 8.0.
Your Tesla T4 GPU has compute capability 7.5. You can use float16 instead by explicitly
setting the `dtype` flag in CLI, for example: --dtype=half.

То есть на T4 и V100 сервер стартует только с --dtype=half, а FP8-кэш там недоступен в принципе — это архитектурное ограничение.

Отдельная категория — когда ошибки нет вовсе. Процесс исчезает, в journalctl последняя строка про загрузку весов, а dmesg -T | grep -i oom показывает Out of memory: Killed process ... (VLLM::EngineCore): кончилась оперативная память, не видео. Вторая тихая беда — холодный старт на 40–90 секунд (веса плюс захват CUDA-графов). Под systemd это выглядит как start operation timed out. Terminating. и лечится параметром TimeoutStartSec, а не тюнингом vLLM. Сократить старт помогает --enforce-eager ценой 10–15% пропускной способности.

В продакшен: systemd, Nginx и метрики

Запуск из терминала живёт до закрытия сессии. Юнит /etc/systemd/system/vllm.service:

[Unit]
Description=vLLM OpenAI-compatible server
After=network-online.target
Wants=network-online.target

[Service]
User=vllm
Group=vllm
WorkingDirectory=/opt/vllm
EnvironmentFile=/etc/vllm/vllm.env
ExecStart=/opt/vllm/bin/vllm serve Qwen/Qwen3-8B \
  --served-model-name qwen3-8b --host 127.0.0.1 --port 8000 \
  --max-model-len 8192 --gpu-memory-utilization 0.90
Restart=on-failure
RestartSec=15
TimeoutStartSec=600
LimitNOFILE=65535
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Файл /etc/vllm/vllm.env — только KEY=value, без export и без кавычек: systemd воспримет их как часть значения, и ключ перестанет совпадать.

HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxx
HF_HOME=/data/hf
VLLM_API_KEY=sk-...

Права: chown root:vllm /etc/vllm/vllm.env и chmod 640. Оставите 600 root:root — юнит не стартует и напишет Failed to load environment files: Permission denied. Дальше sudo systemctl daemon-reload, sudo systemctl enable --now vllm и journalctl -u vllm -f.

Наружу — только через Nginx с сертификатом Let's Encrypt. Ключевая часть конфига:

location /v1/ {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;
    proxy_buffering off;
    proxy_cache off;
    proxy_read_timeout 600s;
    proxy_set_header Connection "";
}

proxy_buffering off здесь обязателен: с буферизацией Nginx копит ответ и отдаёт его целиком, и стриминг превращается в долгую паузу, а потом стену текста. proxy_read_timeout 600s спасает длинные генерации от обрыва на 60-й секунде. И не включайте auth_basic на этом location — он занимает тот же заголовок Authorization, которым клиент передаёт ключ API.

Телеметрия у vLLM встроенная, в формате Prometheus. Две метрики, за которыми стоит следить:

curl -s http://127.0.0.1:8000/metrics | grep -E 'num_requests_(running|waiting)|gpu_cache_usage'

vllm:num_requests_waiting стабильно больше нуля — очередь не рассасывается, и это уже не тюнинг, а вопрос железа. vllm:gpu_cache_usage_perc у потолка — кончается KV-кэш, помогает более короткий --max-model-len.

Нужно несколько моделей — поднимайте по юниту на порт (8000, 8001) и ставьте перед ними шлюз, например LiteLLM: он сведёт их в один эндпоинт с общими ключами и бюджетами. Человеческий интерфейс к тому же API даёт Open WebUI.

Какой сервер под vLLM брать в MAATRIX

Сразу честно: vLLM в каталоге приложений apps.maatrix.io нет — сервер приходит чистой Ubuntu 24.04, и вы ставите его по инструкции выше. В каталоге есть готовые сборки родственных сервисов: Ollama, Open WebUI, LiteLLM, AnythingLLM ставятся автоматически при заказе, доступы появляются в кабинете. Разумная схема — взять сервер с GPU, поставить vLLM руками, а обвязку вокруг него заказать готовой.

Минимум: GPU с 24 ГБ VRAM, 8 vCPU, 32 ГБ RAM, 100 ГБ NVMe. Этого хватает на восьмимиллиардную модель в BF16 с окном 8192 и примерно четырьмя одновременными диалогами. Ограничение называем прямо: полный паспортный контекст в 128 тысяч токенов сюда не поместится, а на 16 ГБ RAM загрузка весов уйдёт в своп и растянет старт на минуты.

Комфортный вариант: 48 ГБ VRAM одной картой или две по 24 с --tensor-parallel-size 2, 64 ГБ RAM, 200 ГБ NVMe. Здесь 8B живёт в BF16 с длинным контекстом и десятками параллельных запросов, а 32B в 4-битном AWQ помещается целиком. Диск берите с запасом: пара моделей и кэш Hugging Face съедают сотню гигабайт незаметно. Как соотносятся карты и задачи, разобрано в материале Выбор GPU-сервера для инференса LLM.

Локация — Великобритания, Лондон. Причина сугубо практическая: uv pip install vllm тянет 8–10 ГБ с PyPI, а веса — ещё десятки гигабайт с Hugging Face. Из России такая загрузка регулярно обрывается на середине, из Лондона идёт напрямую и на полной скорости. Плюс низкий пинг до Европы и европейская юрисдикция, если модель обрабатывает данные клиентов из ЕС. Берите RU, если персональные данные обязаны оставаться в России по 152-ФЗ, и US, если рядом держите прокси к зарубежным API. Подробнее — в разборе VPS в Великобритании для доступа к нейросетям и AI.

Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT; иностранная карта не нужна даже для лондонской площадки. Совет напоследок: не заказывайте сразу максимум. Поднимите vLLM на одной карте, снимите строку Maximum concurrency и метрику num_requests_waiting на своём реальном трафике — и увеличивайте железо по факту, а не по ощущению.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

Можно ли запустить vLLM без видеокарты?

Технически да: есть CPU-бэкенд, собираемый отдельным Dockerfile с флагами инструкций вроде VLLM_CPU_AVX512. Практически — не стоит. Процессорный инференс упирается в пропускную способность памяти: на нашем стенде AMD EPYC 9554 с 16 vCPU модель 7B в Q4 даёт 7,6 токена в секунду, и vLLM это число не улучшает. Для сервера без GPU правильный ответ — Ollama.

Почему модель на 16 ГБ не влезает в карту на 24 ГБ?

Потому что кроме весов нужен KV-кэш, а его размер задаёт --max-model-len. По умолчанию берётся паспортное окно модели — до 131 072 токенов, и на такой запрос кэша не хватит никогда. Поставьте --max-model-len 8192 и посмотрите в логе строку GPU KV cache size.

Как обновлять vLLM, чтобы не сломать прод?

Ставьте новую версию в отдельный каталог (/opt/vllm-0.29.0), запустите вручную и убедитесь, что все ваши флаги приняты — между минорными релизами их переименовывают и удаляют. Только после этого переключайте symlink и перезапускайте юнит. Апгрейд командой pip install -U vllm поверх рабочего окружения однажды даст unrecognized arguments без пути назад.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.