Зачем vLLM
Если вы уже пробовали гонять модель через transformers напрямую или через Ollama, то знаете проблему: при параллельных запросах производительность падает почти линейно — каждый запрос ждёт своей очереди. vLLM решает это на уровне движка инференса: непрерывное батчирование (continuous batching) и PagedAttention для KV-кэша позволяют обслуживать десятки одновременных запросов без деградации, близкой к линейной. Для сценария "поднять внутренний LLM-сервер для нескольких сотрудников или интеграции с 1С" это разница между рабочим решением и тем, что падает под нагрузкой на третьем одновременном запросе.
В этом руководстве — установка и настройка vLLM для запуска больших языковых моделей на связке из двух разных видеокарт: RTX 3090 (Ampere, 24 ГБ) и Tesla V100 (Volta, 16/32 ГБ). Разберём тензорный параллелизм на разнородном железе, актуальные команды установки и известные проблемы совместимости, которые всплывают именно на такой связке.
Шаг 1. Подготовка окружения
Перед установкой убедитесь, что:
- На обеих видеокартах установлены актуальные драйверы NVIDIA (для RTX 3090 и Tesla V100 в одной системе — драйвер должен официально поддерживать обе архитектуры, актуальные ветки делают это без проблем).
- Установлен CUDA Toolkit — актуальные сборки vLLM собираются под CUDA 12.9 по умолчанию, есть готовые wheels под CUDA 12.8 и 13.0.
- В системе есть Python 3.10+ (рекомендуется 3.12+) и pip или uv.
Шаг 2. Установка vLLM
Рекомендуемый способ — через uv, он сам подбирает совместимую сборку PyTorch под вашу CUDA:
uv pip install vllm --torch-backend auto
Через обычный pip (с явным указанием индекса под нужную версию CUDA):
pip install vllm --extra-index-url https://download.pytorch.org/whl/cu129
Ставьте vLLM в отдельное чистое окружение (venv/conda) — версии CUDA и PyTorch, зашитые в бинарники, конфликтуют с другими проектами на той же машине.
Шаг 3. Настройка для мульти-GPU
Для распределения модели по обеим видеокартам используется параметр --tensor-parallel-size:
vllm serve /path/to/your/model \
--tensor-parallel-size 2 \
--dtype half
Флаг --dtype half здесь обязателен, а не опционален — см. следующий раздел, почему.
Шаг 4. Проверка работы
После запуска сервера проверьте его через OpenAI-совместимый API:
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "your-model", "messages": [{"role": "user", "content": "Hello"}]}'
Особенности связки RTX 3090 + Tesla V100
RTX 3090 — это Ampere с compute capability 8.6, Tesla V100 — Volta с compute capability 7.0. Разница в архитектурах создаёт две реальные проблемы, которые стоит знать заранее, а не ловить в 2 часа ночи на проде.
- Bfloat16 не работает на V100. vLLM по умолчанию пытается использовать
bfloat16, а он поддерживается только начиная с compute capability 8.0. На V100 вы получитеValueError: Bfloat16 is only supported on GPUs with compute capability of at least 8.0. Решение — явно указывать--dtype half(float16), как в примере выше. RTX 3090 float16 тоже прекрасно тянет, так что для смешанной пары это универсальный выбор. - Неверное определение GPU при смешанном парке. Известный баг (vllm-project/vllm issue #6213): при нескольких разных типах GPU в системе воркер иногда проверяет compute capability по GPU с рангом 0, а не по тому устройству, на котором реально исполняется процесс. В логах это выглядит так, будто ошибка про "не ту" карту. Если ловите противоречивую ошибку про compute capability — проверьте порядок через
CUDA_VISIBLE_DEVICESи убедитесь, что--dtype halfпрописан явно, а не полагайтесь на автоопределение. - vLLM 0.20+ полностью убрал поддержку Volta (sm_70). Начиная с релиза 0.20.0 минимальная версия CUDA/PyTorch в зависимостях выросла (CUDA 13.0.2, PyTorch 2.11), а сборки перестали включать таргет sm_70 — то есть Tesla V100 в связке просто не заведётся ни с каким
--dtype. Если в системе есть V100, нужно осознанно закрепить версию:pip install "vllm<0.19"(последние сборки с 0.18.x ещё собираются под sm_70). Планируете апгрейд vLLM — сначала проверьте changelog на предмет sm_70 в списке архитектур.
Если вы уже собрали такую связку и упёрлись в проблемы на уровне PyTorch/драйверов (не только vLLM) — отдельный разбор в статье «Как собрать монстр GPU: RTX 3090 + Tesla V100 и проблемы с PyTorch».
Когда вместо этого использовать llama.cpp
vLLM — не универсальный ответ. Он оптимизирован под высокий throughput при множестве параллельных запросов (continuous batching, PagedAttention), и это стоит памяти и сложности запуска. Если у вас другой профиль нагрузки, llama.cpp зачастую практичнее:
- Один пользователь, один поток запросов. Для локального ассистента разработчика или одного бота без параллельной нагрузки преимущества батчирования vLLM просто не реализуются — а накладные расходы (отдельное окружение, VRAM под KV-кэш с запасом) остаются.
- Нужны квантованные GGUF-модели. llama.cpp — нативная среда для GGUF (Q4_K_M, Q5_K_M и т.д.), с которой модель 7B умещается в 4 ГБ VRAM почти без потери качества. vLLM тоже научился читать GGUF, но поддержка экспериментальная и не так отполирована.
- Слабое или нестандартное железо. llama.cpp — чистый C++ без внешних зависимостей, работает на CPU, Apple Metal, AMD ROCm и на связках карт, которые vLLM отказывается признавать совместимыми (в том числе на одиночной Tesla V100 без плясок с версиями).
- Простой деплой без Python-окружения. Один бинарник вместо venv с зафиксированными версиями CUDA/PyTorch — меньше точек отказа при переносе на другую машину.
Если ваш сценарий — сервис с несколькими одновременными пользователями и запасом VRAM под тензорный параллелизм (как раз связка RTX 3090 + Tesla V100 из этого гайда) — оставайтесь на vLLM. Для персонального инференса или ограниченного железа — llama.cpp почти всегда проще и дешевле по ресурсам.
Бенчмарки: сколько это даёт на практике
Цифры сильно зависят от модели, квантования и длины контекста, поэтому вместо "средней температуры по больнице" — таблица с ориентирами и ссылками на полные замеры:
| Сравнение | Что показывает | Подробности |
|---|---|---|
| llama.cpp vs vLLM, тест скорости под нагрузкой | Разрыв в throughput при росте числа параллельных запросов — где llama.cpp ещё держится, а где vLLM уходит в отрыв | Llama vs vllm: какой LLM inference быстрее? |
| RTX 3090 vs 2×RTX 5060 Ti для инференса | Что выгоднее по цене/VRAM/токенам в секунду для локального инференса — одна карта побольше или две поменьше | RTX 3090 vs 2x RTX 5060 Ti: какой GPU выбрать |
| Qwen 3.6 27B MTP на связке из этого гайда | Практический пример модели с multi-token prediction, которую есть смысл гонять именно на тензорном параллелизме | Qwen 3.6 27B MTP |
Локальные LLM в интеграции с 1С
Разворачивать свой инференс-сервер имеет смысл не ради упражнения, а когда данные не должны уходить во внешний API — типичный случай для интеграций с 1С, где в диалог с моделью попадают номенклатура, цены и внутренняя переписка. На курсе «Нейросети и ChatGPT для 1С» есть отдельный модуль про локальные LLM: как выбрать модель под задачу, поднять инференс на своём железе (в том числе на связках карт вроде описанной здесь) и подключить его к 1С через обычный HTTP-запрос вместо OpenAI API.
Видео-руководство
Для более подробного объяснения всех шагов см. видео:
Заключение
vLLM на связке RTX 3090 + Tesla V100 — рабочий вариант, но с оговорками: --dtype half обязателен, а не опционален, а с версии 0.20 придётся сознательно закрепляться на vLLM <0.19, если V100 остаётся в системе. Если ваш профиль нагрузки — один пользователь без параллельных запросов или ограниченная память, посмотрите в сторону llama.cpp и GGUF — это часто быстрее по времени внедрения и не требует борьбы с compute capability. Реальные цифры throughput и выбор железа — в таблице бенчмарков выше.
