С Ollama на vLLM: когда пора переходить от локальной игрушки к серьёзному инференс-серверу
Ollama — отличная точка входа для запуска языковых моделей на своём железе, но при росте нагрузки её простота превращается в ограничение. Разбираемся, когда пора переходить на vLLM и как это сделать безболезненно.
Скорость генерации токенов на одном запросе — слабый повод для миграции. Переходить на vLLM стоит тогда, когда реальная нагрузка показывает, что простая архитектура Ollama больше не справляется с вашим сценарием использования.
Два инструмента — две разные задачи
Ollama задумывалась как максимально удобный способ запускать языковые модели локально. Короткие команды, встроенный каталог моделей, простой API — всё для того, чтобы разработчик мог за минуты начать генерировать текст, не разбираясь в тонкостях инференса.
vLLM — это другой класс инструмента. Это инференс-движок и платформа для обслуживания запросов, заточенные под высокую пропускную способность: непрерывное батчирование, эффективное управление кэшем, параллелизм на нескольких GPU, совместимость с OpenAI-совместимым API.
Снаружи оба сервера могут выглядеть похоже: оба умеют отдавать API, стримить токены, запускать квантованные модели. Разница становится очевидной только под нагрузкой — когда к серверу одновременно обращаются несколько клиентов.
Пять сигналов, что Ollama перестала справляться
Множество пользователей — и латентность скачет
Самый частый первый звоночек. Пока модель обслуживает один запрос, всё работает быстро. Стоит подключиться второму-третьему пользователю — запросы начинают ждать друг друга, время до первого токена становится непредсказуемым, а один длинный промпт «замораживает» всех остальных.
В Ollama параллельные запросы настраиваются через переменную OLLAMA_NUM_PARALLEL, но эта параллельность не бесплатна: потребление памяти растёт пропорционально числу одновременных сессий и размеру контекста. Конфигурация, стабильно работающая для одного разговора с контекстом 8K, может перестать помещаться в память при четырёх клиентах.
vLLM решает эту проблему через непрерывное батчирование (continuous batching): вместо обработки каждого запроса как изолированной задачи движок динамически добавляет и убирает последовательности из текущего батча по мере их поступления и завершения.
GPU простаивает, а запросы стоят в очереди
Очередь не равно полная загрузка видеокарты. При последовательной обработке GPU может быть занят лишь часть времени, хотя параллельные запросы могли бы вносить полезную работу в текущий шаг декодирования.
Планировщик vLLM спроектирован так, чтобы удерживать больше полезной работы в процессе выполнения. Менеджер PagedAttention управляет кэшем блоками, а непрерывное батчирование позволяет последовательностям входить и выходить из батча на лету. Результат — не обязательно меньшая латентность для каждого отдельного запроса, но заметно лучшая суммарная пропускная способность при нагрузке.
Длинные промпты замедляют время до первого токена
Ассистенты по коду с длинным контекстом, RAG-пайплайны, агентные сессии — все они могут отправлять одни и те же длинные системные промпты или повторяющиеся инструкции из документов. Обработка входных токенов (префилл) может доминировать во времени отклика.
vLLM поддерживает автоматическое кэширование префиксов: если последующий запрос начинается с тех же токенов, что и предыдущий, вычисленный кэш переиспользуется. Это полезно, когда запросы разделяют длинный системный промпт, определения инструментов, описание репозитория, few-shot-примеры или общую документацию из RAG.
При этом кэширование префиксов не ускоряет генерацию выходных токенов. Оно сокращает повторные вычисления на входе — выгода проявляется только если запросы действительно содержат идентичные начальные фрагменты.
Нужно больше одного GPU
Модель, которая не помещается на одну видеокарту — веский аргумент в пользу vLLM. Движок поддерживает тензорный параллелизм (распределение слоёв внутри одного слоя по нескольким GPU) и пайплайновый параллелизм (распределение слоёв между устройствами).
Это не делает многокарточный инференс тривиальным — пропускная способность шины, топология PCI Express, архитектура модели и накладные расходы на коммуникацию по-прежнему влияют на результат. Но vLLM даёт осознанный путь для распределённого инференса, в то время как Ollama заточена под один рабочий стол или рабочую станцию.
Нужна production-уровня наблюдаемость
Ollama отдаёт полезные поля в ответах API: время загрузки модели, время обработки промпта, число сгенерированных токенов и длительность генерации. Этого хватает для локального бенчмаркинга и логирования на стороне приложения.
vLLM предоставляет Prometheus-совместимый эндпоинт /metrics, который позволяет отслеживать объём запросов, время в очереди, задержку до первого токена, межтокеновую латентность, использование кэша, число премпшнов, пропускную способность и статусы запросов.
Когда от сервиса зависят пользователи, наблюдаемость перестаёт быть опцией. Без метрик по очередям, кэшу и латентности невозможно отличить недостаточно мощную GPU от слишком длинного контекста, плохого планирования или просто избытка одновременных запросов.
Где vLLM реально выигрывает
Главное преимущество vLLM не в том, что она генерирует один ответ быстрее. Ключевое — больше механизмов для эффективного использования дорогой памяти и вычислений GPU при обслуживании множества запросов.
Непрерывное батчирование меняет активный батч по мере прогресса запросов. Завершённые последовательности покидают батч, новые вступают, и движок старается не тратить ёмкость на уже готовые запросы. Классическое статическое батчирование работает хорошо только когда запросы примерно одинаковой длины — реальный LLM-трафик почти всегда разнородный.
PagedAttention управляет кэшем ключей и значений (KV cache) блоками, а не требует от каждой последовательности единого непрерывного выделения памяти. Это снижает фрагментацию и позволяет вместить больше одновременных сессий в тот же объём VRAM.
Кэширование префиксов переиспользует вычисления для общих начальных фрагментов запросов. Наибольшую выгоду даёт в сценариях с длинным стабильным префиксом и коротким специфичным «хвостом» каждого запроса.
Параллелизм: тензорный, пайплайновый, по данным, по эксперту, по контексту. Не каждый деплоймент нуждается во всех этих режимах, но их наличие критично, когда сервис перерастает одну видеокарту.
Широкие настройки: управление использованием памяти GPU, максимальная длина модели, лимит активных последовательностей, квантизация, типы данных кэша, спекулятивное декодирование, вызов инструментов, структурированный вывод, алиасы моделей, ключи аутентификации. Гибкость позволяет заточить сервер под конкретную нагрузку, но создаёт больше возможностей для неэффективной конфигурации.
Где Ollama по-прежнему лучше
Миграционный гайд не должен превращать Ollama во «второсортный инструмент». Для многих сценариев она остаётся оптимальным выбором.
Персональная рабочая станция. Один разработчик, чат-интерфейс, ассистент по коду, эпизодические запросы — операционные преимущества vLLM могут никогда не окупить дополнительные усилия по настройке. Ollama устанавливается за минуты, скачивает модели через встроенный реестр и скрывает массу деталей.
Коллекции GGUF-моделей. У Ollama естественный рабочий процесс вокруг GGUF: пользователи настраивают квантизации, адаптеры, шаблоны промптов под своё железо. vLLM поддерживает GGUF, но её сильная сторона — модели из Hugging Face в форматах AWQ, GPTQ, BitsAndBytes, FP8. Просто перенести GGUF-сборку из Ollama в vLLM без оценки более «родного» формата чекпоинта может сохранить неудобства миграции, не дав выигрыша в производительности.
Смешанный CPU/GPU offloading. Если модель не целиком помещается в VRAM и часть вычислений идёт на процессор — это нормальный сценарий для Ollama или llama.cpp. vLLM наиболее эффективна, когда модель и кэш целиком обслуживаются GPU.
Частое переключение моделей. Ollama делает тривиальным скачивание, запуск, остановку и переключение между десятками моделей. Деплоймент на vLLM обычно строится вокруг одной осознанно выбранной модели, которая постоянно загружена как сервис.
Минимум эксплуатации. Ollama намеренно «однозначна» в своих решениях — и это преимущество, когда никто не хочет заниматься поддержкой инференс-платформы. Если сервер обслуживает одного пользователя, латентность устраивает, а очередь пустует — миграция создаст работу, а не снимет проблему.
Не мигрируйте ради скорости генерации
Скорость генерации токенов на одном запросе — неполный бенчмарк. Два сервера могут показывать схожую пропускную способность для одиночной последовательности, но вести себя совершенно иначе при восьми одновременных клиентах.
Оценка должна измерять как минимум:
- время до первого токена
- межтокеновую латентность
- полное время отклика запроса
- пропускную способность обработки промпта
- пропускную способность генерации
- число завершённых запросов в минуту
- время ожидания в очереди
- потребление памяти GPU
- загрузку GPU
- частоту ошибок и таймаутов
Запускайте тест с одной и той же моделью, точностью, длиной контекста, набором промптов, лимитом выхода и уровнем параллелизма на обоих серверах. Иначе вы сравните не движки инференса, а упаковку модели и конфигурацию.
Планирование миграции модели
Имена моделей в Ollama не автоматически маппятся на идентификаторы vLLM. Ollama-пакет может содержать конкретную GGUF-квантизацию, шаблон промпта, стоп-токены и параметры по умолчанию.
Перед сменой сервера идентифицируйте:
- семейство и версию оригинальной модели
- базовая она или instruction-tuned
- текущую квантизацию и эффективную точность
- шаблон промпта
- настроенную длину контекста
- стоп-токены и дефолты генерации
- требования к вызову инструментов или структурированному выводу
- LoRA-адаптеры и кастомные системные промпты
Не предполагайте, что чекпоинт AWQ или FP8 будет вести себя идентично GGUF-сборке из Ollama. Миграция модели часто значительнее миграции API.
Проверьте VRAM перед запуском vLLM
То, что модель помещается в память GPU, не значит, что она обслужит нужную нагрузку. VRAM должен покрывать не только веса модели:
- веса модели
- KV-кэш
- CUDA-графы и runtime-аллокации
- временное рабочее пространство
- кэши мультимодальных процессоров (если используются)
- запас безопасности
Длинные контексты и одновременные последовательности расширяют потребность в KV-кэше. Увеличение максимальной длины контекста снижает число одновременных запросов, даже если большинство из них не используют весь лимит.
Начинайте с реалистичного значения --max-model-len вместо максимального, заявленного для модели, и не выставляйте использование памяти GPU настолько агрессивно, чтобы малейшее отклонение нагрузки вызывало out-of-memory. Стабильный сервис с чуть меньшей теоретической ёмкостью полезнее того, что падает при первом всплеске трафика.
Поэтапная миграция: не меняйте всё сразу
Замена работающего сервера в один шаг — ненужный риск. Ollama и vLLM могут работать параллельно на разных портах, пока вы валидируете новый деплоймент.
Этап 1: Воспроизведите одну модель. Выберите модель, на которую приходится основная доля запросов, и подберите максимально близкий чекпоинт в vLLM. Не начинайте с переноса всех экспериментальных моделей.
Этап 2: Проверьте поведение API. Прогоните существующие интеграционные тесты: стриминг, отмена, таймауты, вызов инструментов, некорректные запросы, переполнение контекста, параллельный доступ. Замечайте поведенческие различия, а не прячьте их за retry-логикой.
Этап 3: Установите базовый уровень. Измерьте производительность на одиночном запросе — это подтвердит корректность загрузки модели и даст точку отсчёта.
Этап 4: Добавьте реалистичную параллельность. Протестируйте число одновременных запросов, ожидаемое в нормальной работе и при пиковом всплеске, с репрезентативными промптами. Следите за очередями, кэшем, премпшнами и задержками.
Этап 5: Переведите одного клиента. Направьте некритичное приложение или небольшой процент трафика на vLLM. Сохраните Ollama как fallback, пока новый сервер не проработает стабильно.
Этап 6: Тюнинг на основе измерений. Настраивайте длину модели, использование памяти, лимит последовательностей, кэширование префиксов, параллелизм и квантизацию только после выявления конкретного ограничения. Изменение нескольких параметров одновременно делает регрессии необъяснимыми.
Чеклист перед переключением клиентов
- Целевая модель поддерживается vLLM
- Выбранный чекпоинт и квантизация помещаются в VRAM с запасом на KV-кэш
- Максимальная длина контекста соответствует реальному использованию
- Шаблон чата корректный и протестированы стоп-токены
- Стриминг работает с существующими клиентами
- Вызов инструментов и структурированный вывод проверены
- Включена аутентификация
- Сервер не торчит напрямую в интернет
- Prometheus-метрики и GPU-метрики собираются
- Нагрузочное тестирование включает реалистичную параллельность
- Существует путь отката на Ollama
Безопасность: не выставляйте сервер в открытый интернет
Ни Ollama, ни vLLM не стоит бездумно открывать наружу. Неаутентифицированный инференс-сервер — это расход дорогих GPU-ресурсов, утечка поведения модели и вектор для DDoS через сверхдлинные промпты.
vLLM умеет требовать API-ключ, но это не полноценная граница безопасности. Для удалённого доступа размещайте сервис за обратным прокси или API-шлюзом с TLS, ограничением сети, лимитами на размер запроса, rate limiting, логированием и нормальной аутентификацией.
Не мигрируйте, если:
- один-два пользователя
- запросы преимущественно последовательные
- латентность устраивает
- GGUF-управление важно
- нужен CPU-offloading
- модели меняются часто
- никто не хочет эксплуатировать дополнительную инфраструктуру
- нет измеренной проблемы с параллельностью или пропускной способностью
«Production» — не магический порог, который обесценивает Ollama. Но и не стоит держаться за неё только потому, что она проще в установке. Если пользователи регулярно ждут в очереди, повторные префиксы съедают время префилла, а бо́льшую модель нужно разместить на нескольких GPU — простой сервер может обходиться дороже в эксплуатации.
Лучшая архитектура: Ollama для разработки, vLLM для обслуживания
Часто оптимальное решение — не полная замена, а разделение ролей. Разработчики могут держать Ollama на рабочих станциях для экспериментов, тестирования GGUF-моделей и личного чата, пока общая vLLM-инстанция обслуживает стабильную модель для приложений и команды.
Такой подход снижает риски миграции: модели сначала тестируются локально, и только подходящий чекпоинт продвигается в общий vLLM-деплоймент.
Ollama сложно превзойти как инструмент для локального запуска моделей — она снимает достаточно боли конфигурации, чтобы разработчик мог сосредоточиться на модели и приложении. vLLM становится сильнее, когда сам сервер становится проблемой, которую нужно инженерить: параллельный трафик, очереди, длинные повторяющиеся префиксы, многокарточные модели, capacity planning и production-мониторинг. Не мигрируйте ради длинного списка фич — мигрируйте, когда измерения покажут, что простая модель Ollama больше не совпадает с вашей нагрузкой.