vLLM на сервере: частые ошибки и решения
На домашней машине с видеокартой vLLM поднимается одной командой, а на арендованном сервере встречает стеной: pip не находит пакет, импорт падает на undefined symbol, движок жалуется на тип устройства, а API отвечает 404 на имя модели, которую вы только что скачали. Ошибки vLLM повторяются от установки к установке и опознаются по одной строке лога. Ниже — пять слоёв отказа с точными текстами ошибок и командами проверки.
Содержание
- С чего начинать: vLLM ломается в пяти разных местах
- Установка: pip находит не то, а импорт падает на undefined symbol
- «Failed to infer device type»: vLLM на сервере без видеокарты
- Модель не скачивается: закрытый репозиторий, токен и место на диске
- Движок не стартует: KV-кэш, CUDA-графы и процесс, убитый по памяти
- API поднялся, но отвечает не то: 404, 400 и обрыв стрима
- Какой сервер брать под vLLM в MAATRIX
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →С чего начинать: vLLM ломается в пяти разных местах
«vLLM не запускается» — это пять независимых слоёв. Пока неясно, на каком вы застряли, правка вслепую тратит время.
| Симптом | Слой | Первая команда | |
|---|---|---|---|
No matching distribution found for vllm | pip и Python | python3 -V | |
undefined symbol при импорте | конфликт с torch | `pip list \ | grep torch` |
Failed to infer device type | железо, драйвер | nvidia-smi | |
GatedRepoError: 401 Client Error | загрузка весов | hf auth whoami | |
EngineCore failed to start | старт движка | journalctl -u vllm | |
{"type":"NotFoundError","code":404} | HTTP-слой | curl /v1/models |
Главная ловушка чтения логов пришла с движком V1 (умолчание с версии 0.8): инференс живёт в отдельном процессе VLLM::EngineCore, а родительский в конце печатает обобщённое:
RuntimeError: Engine core initialization failed. See root cause above.
Failed core proc(s): {}
Именно его копируют в поиск и не находят ничего: причина — выше, за десятки строк до трейсбека.
Признак успешного старта — строки Application startup complete. и Uvicorn running on http://127.0.0.1:8000. Пока их нет, curl отдаёт Connection refused: это не ошибка API, а незакончившийся старт. Эндпоинт /health даёт 200, только когда движок принял модель.
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8000/health
curl -s http://127.0.0.1:8000/v1/models | jq -r '.data[].id'
Мало деталей — VLLM_LOGGING_LEVEL=DEBUG.
Установка: pip находит не то, а импорт падает на undefined symbol
Половина обращений «vllm ошибки» — это не vLLM, а сломанное окружение Python.
Пакета под вашу версию Python нет. vLLM собирает колёса под ограниченный набор версий CPython, и слишком свежий интерпретатор или старый 3.8 дают одинаковый ответ:
ERROR: Could not find a version that satisfies the requirement vllm (from versions: none)
ERROR: No matching distribution found for vllm
Ключевое — (from versions: none): pip отсеял всё по совместимости. Ubuntu 24.04 даёт 3.12, Debian 12 — 3.11, обе подходят; экзотику лечит uv venv --python 3.12 /opt/vllm.
Установка в системный Python. На Ubuntu 24.04 и Debian 12 глобальная установка упирается в защиту дистрибутива:
error: externally-managed-environment
× This environment is externally managed
Обход флагом --break-system-packages дорог: vLLM тянет свою версию PyTorch, а apt считает torch и numpy своими — первое же apt upgrade оставит вас с нерабочим Python. Только venv:
sudo mkdir -p /opt/vllm && sudo chown $USER /opt/vllm
python3 -m venv /opt/vllm
/opt/vllm/bin/pip install -U pip
/opt/vllm/bin/pip install "vllm==0.11.0"
Версию фиксируйте явно: между минорными релизами vLLM убирает и переименовывает флаги CLI.
Конфликт с заранее поставленным torch. Сначала ставят PyTorch «под свою CUDA», потом поверх — vLLM; несовпадение вылезает при импорте:
ImportError: /opt/vllm/lib/python3.12/site-packages/vllm/_C.abi3.so: undefined symbol:
_ZN3c105ErrorC2ENS_14SourceLocationENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Символ _ZN3c105Error... — это c10::Error из PyTorch: ядро vLLM ищет в libtorch функцию, которой там нет. Подбирать версии torch дольше, чем пересоздать venv:
rm -rf /opt/vllm && python3 -m venv /opt/vllm
/opt/vllm/bin/pip install "vllm==0.11.0"
/opt/vllm/bin/python -c "import torch, vllm; print(torch.__version__, torch.version.cuda, torch.cuda.is_available())"
Ответ 2.8.0+cu128 12.8 True значит, что слой установки пройден, False указывает на драйвер. Зависимости с ядрами CUDA занимают на диске 8–10 ГБ.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать сервер«Failed to infer device type»: vLLM на сервере без видеокарты
Самая частая ошибка на VPS сбивает с толку тем, что не содержит слова GPU:
INFO [__init__.py:32] No plugins for group vllm.platform_plugins found.
INFO [__init__.py:44] Checking if TPU platform is available.
INFO [__init__.py:56] Checking if CUDA platform is available.
RuntimeError: Failed to infer device type
Перевод: vLLM перебрал платформы — CUDA, ROCm, TPU, XPU — и не нашёл ни одной. На VPS это значит буквально «видеокарты нет»: nvidia-smi должен выводить таблицу с картой и версией драйвера. Соседние случаи:
- Драйвер не загрузился или устарел.
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver— обычно после обновления ядра без пересборки DKMS.The NVIDIA driver on your system is too old (found version 11080)— колёса собраны под CUDA 12.x. - Контейнер не видит карту. В Docker
nvidia-smiработает только с--gpus allиnvidia-container-toolkitна хосте. - Карта занята. Чужой процесс на 22 ГБ из 24 — забытый Jupyter или упавший vLLM;
sudo fuser -v /dev/nvidia*покажет, кого убить.
CPU-бэкенд у vLLM есть, но он не для продакшена: готовых колёс нет, нужна сборка из исходников с VLLM_TARGET_DEVICE=cpu и gcc-12. Да и смысла мало — выигрыш vLLM держится на видеопамяти.
Без GPU берите llama.cpp или Ollama. Наш замер: AMD EPYC 9554 (16 vCPU — 8 физических ядер плюс HT), Ollama 0.33.1, qwen2.5:7b в Q4_K_M:
num_thread | Генерация, ток/с | Обработка промпта, ток/с |
|---|---|---|
| 2 | 5,7 | 12,6 |
| 4 | 7,6 | 31,0 |
| 8 | 7,6 | 61,7 |
| 16 | 7,4 | 68,0 |
| 32 | 0,35 | 10,9 |
Генерация выходит на полку уже на четырёх потоках: дальше упор в память, и 16 ядер вместо 8 скорости ответа не добавят. А 32 потока на 16 vCPU обрушивают её в двадцать раз. Там же при 16 потоках llama3.1:8b даёт 12,8 ток/с, mistral:7b — 12,1, gemma2:9b — 8,8, qwen2.5:3b — 34,1; в памяти модели занимают от 2,2 до 5,6 ГБ. Сравнение движков — в разборе Ollama против vLLM.
Модель не скачивается: закрытый репозиторий, токен и место на диске
Окружение собрано, карта видна, а vllm serve падает при загрузке весов.
Gated repo. Веса Llama, Gemma и части моделей Mistral отдаются только после принятия лицензии:
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.
huggingface_hub.errors.GatedRepoError: 401 Client Error.
Порядок: аккаунт, лицензия на странице модели (у Llama заявка одобряется не мгновенно), токен с правом чтения, hf auth login. Ловушка: интерактивный логин кладёт токен в ~/.cache/huggingface/token того пользователя, который его запускал, — сервис под systemd от другого упадёт с тем же 401. Передавайте окружением:
[Service]
User=vllm
Environment="HF_HOME=/var/lib/vllm/hf"
EnvironmentFile=/etc/vllm/vllm.env
TimeoutStartSec=600
ExecStart=/opt/vllm/bin/vllm serve meta-llama/Llama-3.1-8B-Instruct --host 127.0.0.1 --port 8000
В /etc/vllm/vllm.env — строка HF_TOKEN=hf_... без кавычек и без export: systemd примет export за часть имени переменной и напишет invalid variable name.
Кончился диск. Веса 8B в FP16 — 16 ГБ, 32B — под 65 ГБ, и всё льётся в ~/.cache/huggingface/hub. Обрыв выглядит как [Errno 28] No space left on device или как зависший процесс; переносите кэш через HF_HOME.
Обрыв соединения. Из России загрузки с HuggingFace рвутся, а ошибка приходит невнятная:
huggingface_hub.errors.LocalEntryNotFoundError: An error happened while trying to
locate the file on the Hub and we cannot find the requested files in the local cache.
Дословно — «в интернет не сходили и локально ничего нет». Качайте веса отдельным шагом:
/opt/vllm/bin/hf download meta-llama/Llama-3.1-8B-Instruct \
--local-dir /var/lib/vllm/models/llama-3.1-8b
/opt/vllm/bin/vllm serve /var/lib/vllm/models/llama-3.1-8b \
--served-model-name llama-3.1-8b --host 127.0.0.1 --port 8000
Повторный hf download продолжает с места обрыва. С британской площадки проблемы нет вовсе: HuggingFace и PyPI открываются напрямую.
Модель не того формата. Ещё две ошибки на том же шаге:
ValueError: Loading <model> requires you to execute the configuration file in that repo
on your local machine.
ValueError: Quantization method specified in the model config (awq) does not match the
quantization method specified in the `quantization` argument (gptq).
Первая — модель с собственным кодом, нужен --trust-remote-code (вы разрешаете исполнить чужой Python). Вторая — вы задали --quantization вручную; обычно флаг не нужен, vLLM определяет квантование сам.
Движок не стартует: KV-кэш, CUDA-графы и процесс, убитый по памяти
Здесь важно различать три разные нехватки памяти.
Не хватило видеопамяти под KV-кэш. Модель загрузилась, а на контекст места не осталось:
ValueError: The model's max seq len (131072) is larger than the maximum number of tokens
that can be stored in KV cache (32496). Try increasing `gpu_memory_utilization` or
decreasing `max_model_len` when initializing the engine.
Рефлекс «поднять --gpu-memory-utilization до 0.98» неверен: остаток нужен движку на активации. Правильный рычаг — --max-model-len 8192. Расчёт с формулами — в разборе vLLM не запускается из-за памяти.
Не хватило видеопамяти на самих весах:
torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 2.00 GiB. GPU 0 has a
total capacity of 23.64 GiB of which 1.21 GiB is free.
Модель в выбранной точности не влезает: берите AWQ или GPTQ вместо FP16 либо две карты с --tensor-parallel-size 2.
Кончилась оперативная память хоста. В логе vLLM ни одной ошибки, процесс исчезает, systemd рапортует код 137. Смотреть надо не туда:
sudo dmesg -T | grep -i -E 'killed process|out of memory'
Строка Out of memory: Killed process 4711 (VLLM::EngineCore) значит, что убил не vLLM, а ядро: веса при загрузке проходят через RAM, и на машине с 16 ГБ модель на 16 ГБ упрётся гарантированно.
Ещё три частых стопора:
- Долгий захват CUDA-графов. Лог замирает на
Capturing CUDA graphs— это норма, холодный старт занимает 40–90 секунд, но systemd убивает сервис на середине:Job for vllm.service failed because a timeout was exceeded. ОтсюдаTimeoutStartSec=600в юните выше;--enforce-eagerсокращает старт ценой пропускной способности. - Неделимое число голов внимания.
Total number of attention heads (32) must be divisible by tensor parallel size (3)— значение--tensor-parallel-sizeобязано быть делителем: 1, 2, 4, 8, но не 3 и не 6. - Мало разделяемой памяти в контейнере. Docker даёт
/dev/shmвсего 64 МБ, а процессы vLLM обмениваются через неё тензорами: при--tensor-parallel-size 2контейнер падает сBus error (core dumped)без трейсбека. Лечится--shm-size=8gили--ipc=host.
API поднялся, но отвечает не то: 404, 400 и обрыв стрима
Сервер слушает, /health отдаёт 200, а клиент получает ошибку. Это HTTP-слой, лечится за минуты.
404 на имя модели — частая ошибка интеграции:
{"object":"error","message":"The model `llama3` does not exist.","type":"NotFoundError","code":404}
vLLM ждёт в поле model ровно ту строку, которой запущен: полный путь meta-llama/Llama-3.1-8B-Instruct или локальный каталог. Короткие имена в стиле Ollama он не понимает — задайте псевдоним --served-model-name llama3.
401 и открытый наружу порт. Без флага --api-key vLLM не проверяет авторизацию вообще, а с --host 0.0.0.0 это открытый инференс-сервер за ваш счёт. Слушайте loopback, наружу выпускайте через Nginx с TLS:
sudo ufw allow 22/tcp
sudo ufw deny 8000/tcp
sudo ufw enable
Ключ — --api-key sk-local-$(openssl rand -hex 16). Приходит 401 при верном ключе — виноват Nginx: auth_basic использует тот же заголовок Authorization и съедает ключ клиента.
400 по длине контекста. Ответ объясняет арифметику:
This model's maximum context length is 8192 tokens. However, you requested 8500 tokens
(500 in the messages, 8000 in the completion).
В лимит входит и max_tokens ответа, поэтому клиент с прошитым max_tokens: 8000 сломается даже на крошечном промпте.
Нет шаблона чата. Базовые модели, в отличие от Instruct-версий, часто не содержат chat_template в токенизаторе:
ValueError: As of transformers v4.44, default chat template is no longer allowed,
so you must provide a chat template if the tokenizer does not define one.
Передайте шаблон Jinja флагом --chat-template или перейдите на /v1/completions. Рядом — вызов инструментов: без --enable-auto-tool-choice --tool-call-parser hermes модель вернёт JSON текстом в content, а клиент будет ждать tool_calls.
Nginx рвёт стриминг. Ответ приходит целиком после паузы, а длинная генерация обрывается на 504:
location / {
proxy_pass http://127.0.0.1:8000;
proxy_buffering off;
proxy_read_timeout 600s;
proxy_http_version 1.1;
}
Порт занят умершим не до конца процессом — uvicorn скажет [Errno 98] ... address already in use, ищите через sudo ss -ltnp | grep 8000. И следите за vllm:num_requests_waiting в /metrics: стабильно больше нуля — нехватка железа.
Какой сервер брать под vLLM в MAATRIX
Сразу честно: vLLM нет в каталоге apps.maatrix.io, автоматической установки при заказе не будет. Сервер приезжает чистым — Ubuntu 24.04 или Debian 12, — и vLLM вы ставите по второму разделу статьи. Зато в каталоге есть готовые сборки соседей по стеку: Ollama как запасной движок на CPU, LiteLLM как шлюз с ключами и бюджетами перед vLLM, AnythingLLM или Dify как интерфейс, Qdrant под векторы.
Честный минимум: GPU с 24 ГБ VRAM, 8 vCPU, 32 ГБ RAM, 100 ГБ NVMe. Граница, за которой vLLM имеет смысл: 8B в FP16 занимает 16 ГБ, остаток уходит под KV-кэш, контекст держится на 8–16 тысячах токенов. Оперативная память нужна не для счёта, а чтобы через неё прошла загрузка весов.
Комфортный вариант: 48 ГБ VRAM одной картой или две по 24 с --tensor-parallel-size 2, 16 vCPU, 64 ГБ RAM, 200–300 ГБ NVMe. Здесь 8B живёт в FP16 с длинным контекстом, 32B — в 4-битном AWQ, а на диске лежит несколько моделей: каждая весит от 5 до 65 ГБ.
Без GPU vLLM брать не надо. Для CPU-инференса хватит 8 vCPU и 16–32 ГБ RAM под Ollama: 7–13 токенов в секунду на моделях 7–9B — боту и ночной обработке документов достаточно, живому чату нет.
Локация — Великобритания, Лондон. Довод практический: с британского адреса HuggingFace, PyPI и реестры контейнеров открываются напрямую, а hf download на 16 ГБ не рвётся на середине. Плюс низкий пинг до Европы и понятная контрагентам юрисдикция. Берите US, если рядом стоит прокси к зарубежным API, и RU, если данные обязаны оставаться в России по 152-ФЗ. Подробности — в материале GPU-сервер в Великобритании для инференса LLM.
Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT; доступы появляются в личном кабинете. Совет напоследок: прежде чем заказывать GPU, снимите на своём трафике число одновременных запросов в пике. Меньше четырёх — vLLM не окупится, начните с Ollama на обычном VPS.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
vllm serve работает из консоли, а под systemd падает. Почему?
Чаще всего из-за токена HuggingFace: hf auth login кладёт его в ~/.cache/huggingface/token вашего пользователя, а сервис работает от другого и получает GatedRepoError: 401. Передавайте HF_TOKEN через EnvironmentFile и не забудьте TimeoutStartSec=600: холодный старт занимает до полутора минут.
Можно ли запустить vLLM на VPS без видеокарты?
Формально да, сборкой из исходников с VLLM_TARGET_DEVICE=cpu, но смысла нет: готовых колёс под CPU не публикуют, а выигрыш vLLM держится на видеопамяти. Берите Ollama или llama.cpp.
Как понять, чего не хватает — видеопамяти или обычной?
По источнику сообщения. CUDA out of memory и larger than the maximum number of tokens that can be stored in KV cache — это VRAM, лечится --max-model-len и квантованием. А исчезнувший без ошибок процесс — это RAM хоста: sudo dmesg -T | grep -i 'killed process' покажет VLLM::EngineCore.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.