- BrainTools - https://www.braintools.ru -
Вступление [1]
Что такое vLLM [4]
Стартовые опции [14]
dtype [16]
gpuMemoryUtilization [17]
maxModelLen [18]
enablePrefixCaching [19]
enableChunkedPrefill [20]
maxNumSeqs [22]
Speculative Decoding [29]
Итоги [33]
Меня зовут Андросов Михаил, я работаю в компании Сибинтек-Софт [34] в роли MLOps-инженера и развиваю высокопроизводительный инференс-сервис (LLMaaS). В этой статье я покажу, с чего проще всего начать работу с vLLM и какие базовые возможности стоит включить в первую очередь.
Наверняка вы сталкивались с ситуацией, когда сложно начать работу с новым, пусть и популярным, продуктом. Особенно если он предоставляет богатый функционал.
Речь пойдёт про vLLM [35] и его обвязку — vLLM Production Stack [36].
Я решил начать цикл статей, в котором буду постепенно разбирать возможности vLLM и компонентов vLLM Production Stack.
Данная статья посвящена базовым возможностям, запуску инференса и параметрам, которые легко и просто конфигурируются.
Все примеры и наблюдения в статье получены на следующем окружении:
2 bare-metal сервера с 8 GPU NVIDIA H200 141 GB каждый.
Astra Linux SE 8.
Kubernetes 1.30.
vLLM 0.17.0.
vLLM Production Stack 0.1.10.
В статье будет много примеров с переменными окружения, PVC, дополнительными аргументами и другими настройками. Чтобы не раздувать YAML-манифесты, я не буду повторять [37] одни и те же поля в каждом примере. Поэтому часть опций может присутствовать в полном манифесте, даже если в конкретном фрагменте я её не показываю.
Если какие-то моменты будут конфликтовать друг с другом, я буду на это отдельно указывать.
Также в статье не будет показано, как устанавливать базовые компоненты: драйверы, Kubernetes, Nvidia Device Plugin, Helm и т.п.
vLLM — это open-source движок и сервер для высокопроизводительного инференса LLM. Он поднимает OpenAI-совместимое API и поддерживает не только /v1/completions и /v1/chat/completions, но и Embeddings, Tokenizer, Pooling, Score, Re-rank, а также audio/transcriptions и audio/translations для совместимых моделей. Производительность достигается за счёт эффективной работы с KV-cache, динамического batching’а и других оптимизаций планировщика. Запуск возможен как на GPU, так и на CPU. vLLM подходит как для простого запуска одной модели, так и для production-сценариев.
vLLM Production Stack [36] — это готовая Kubernetes-обвязка вокруг vLLM. Он поднимает группу vLLM-инстансов и роутер перед ними, а также даёт базу для маршрутизации запросов, наблюдаемости и масштабирования.
Один из первых практических вопросов при работе с vLLM — поддерживается ли нужная вам модель. Особенно это актуально для новых релизов и нестандартных архитектур.
Поэтому рекомендую всегда проверять какие модели поддерживаются [38] и просматривать рекомендации по развёртыванию той или иной модели [39].
Если модель вышла совсем недавно и очень хочется её запустить, пробуйте стартовать с образом nightly [40]. Разработка vLLM идёт хорошими темпами, и сообщество старается быстро добавлять поддержку новых моделей.
Начнем с самых практических сценариев: от базового запуска текстовой модели до включения tool calling, мультимодальности и CPU-режима.
По умолчанию vLLM пытается скачать модель напрямую с Hugging Face [41]. Если в вашем контуре нет интернета, модель нужно заранее скачать, перенести на сервер и примонтировать в контейнер через PV/PVC.
extraVolumeMounts:
- mountPath: /models/Qwen3-8B
name: model
readOnly: true
extraVolumes:
- name: model
persistentVolumeClaim:
claimName: pvc-qwen3-8b
Для первого демонстрационного запуска возьму Qwen3-8B [42]. — это удобная модель, чтобы показать базовый сценарий использования – локальное монтирование, запуск vLLM и первый запрос через OpenAI-совместимый API.
servingEngineSpec:
enableEngine: true
modelSpec:
- name: qwen3-8b
repository: vllm-openai
tag: v0.17.0
env:
- name: HF_HUB_OFFLINE
value: "1"
modelURL: /models/Qwen3-8B
extraVolumeMounts:
- mountPath: /models/Qwen3-8B
name: model
readOnly: true
extraVolumes:
- name: model
persistentVolumeClaim:
claimName: pvc-qwen3-8b
replicaCount: 1
requestCPU: 8
requestGPU: 1
requestMemory: 16Gi
vllmConfig:
extraArgs:
- --served-model-name
- Qwen/Qwen3-8B
gpuMemoryUtilization: 0.98
Пояснение по переменной HF_HUB_OFFLINE: при значении
"1"попыток обращения к Hugging Face не будет вовсе.
После запуска Helm-чарта vLLM Production Stack, дожидаемся когда модель будет запущена.
Любым удобным способом пробросьте порт до Service инференса, например:
kubectl port-forward svc/vllm-production-stack-qwen3-8b-engine-service 9191:9191
Теперь можно выполнить первый запрос и убедиться, что модель отвечает.
curl -N http://localhost:9191/v1/chat/completions
-H "Content-Type: application/json"
--data-raw '{
"model": "Qwen/Qwen3-8B",
"messages": [
{ "role": "user", "content": "Напиши: Привет!" }
]
}'
Qwen3-8B — это модель с режимом размышления, поэтому в ответе можно наблюдать блок <think></think>.
Все доступные OpenAI-совместимые эндпоинты указаны на официальном сайте [43].
Для поддержки вызова инструментов недостаточно того, что модель умеет это на уровне обучения [44]. В vLLM нужно дополнительно включить server-side опции: автоматический выбор инструмента и parser, который умеет разбирать формат tool call именно для вашей модели.
Например, для Qwen3.5-35B-A3B [45] это делается так:
extraArgs:
...
- --enable-auto-tool-choice
- --tool-call-parser
- qwen3_coder
Если этого не сделать и пытаться использовать модель в агентских сценариях, вы получите ошибку [46]:
Подробнее можно ознакомиться в официальной документации vLLM по Tool Calling [47].
Для рассуждающих моделей поведение [48] можно задавать не только в клиентском запросе, но и на уровне сервера через --default-chat-template-kwargs. Если клиент передаст chat_template_kwargs, то значения из запроса переопределят значения, заданные при старте сервера.
extraArgs:
...
- --default-chat-template-kwargs
- '{"enable_thinking": false}'
Если клиент передаст chat_template_kwargs.enable_thinking=true, размышление включится именно для этого запроса. Значение, заданное при старте vLLM, будет переопределено.
Важно помнить, что эта опция работает не для всех моделей одинаково. Например, для DeepSeek параметр будет выглядеть иначе:
--default-chat-template-kwargs '{"thinking": false}'
Для запуска мультимодальных моделей необходимо собирать собственный образ vLLM поверх базового vllm/vllm-openai. Причина в том, что официальные образы не включают часть необязательных зависимостей.
Добавить нужные зависимости довольно просто:
FROM vllm/vllm-openai:v0.17.0
RUN uv pip install --system "vllm==0.17.0" &&
uv pip install --system "vllm==0.17.0"
Для мультимодальных моделей нужно отдельно задавать tensorParallelSize, а при необходимости — увеличивать shmSize, потому что стандартных 20 GiB может быть недостаточно. Это требуется, чтобы в /dev/shm хватало места под mm_processor_cache — кэш промежуточной обработки изображений и других мультимодальных данных. Без этого кэша модель либо работает нестабильно, либо вообще падает: если tensorParallelSize не указан, доступной разделяемой памяти [49] обычно не хватает, и экземпляр модели упадет уже на первом запросе.
shmSize: "32Gi"
vllmConfig:
...
extraArgs:
...
tensorParallelSize: 1
В официальном репозитории vLLM есть Python-скрипт [50], который показывает, как выполнять запросы к мультимодальным моделям.
Также для таких моделей часто приходится задавать дополнительные аргументы при старте vLLM. Например, для Qwen3-Omni-30B [51] можно использовать параметр limit_mm_per_prompt, который задаёт максимальное количество данных каждого типа, разрешённое в одном сообщении.
Что бы учитывать эти и другие нюансы, всегда проверяйте vLLM Recipes [52] и репозитории моделей.
Не всем моделям нужна GPU. Для embedding-моделей и небольших вспомогательных сервисов запуск на CPU может быть проще и дешевле в эксплуатации. Для этого у vLLM есть отдельный CPU backend и CPU-образы [53].
Проведу демонстрацию запуска модели Qwen3-Embedding-0.6B на CPU:
- name: qwen3-embedding-06b
env:
- name: VLLM_CPU_KVCACHE_SPACE
value: "48"
...
vllmConfig:
extraArgs:
- --served-model-name
- Qwen3-Embedding-0.6B
Обязательно укажите переменную VLLM_CPU_KVCACHE_SPACE под KV-кэш и берите память с запасом.
В логах можно увидеть, что образ стартует на CPU и выделяет место под KV-кэш.
Ниже — стартовые опции vLLM, которые сильнее всего влияют на память, параллелизм и поведение [54] сервера.
Для удобства сначала соберу ключевые параметры в одну таблицу, а ниже коротко разберу каждый из них.
|
Параметр |
Что делает |
Когда особенно важен |
|---|---|---|
|
|
Разрешает переиспользование уже посчитанного KV-кэша для общего префикса |
Когда у запросов часто совпадает начало промпта |
|
|
Разбивает длинный prefill на части и позволяет лучше смешивать его с decode |
При длинных входах и смешанной нагрузке |
|
|
Ограничивает максимальную длину контекста в токенах |
Когда нужен длинный контекст или нужно экономить память |
|
|
Определяет тип чисел, в котором хранятся веса и выполняется часть вычислений |
Когда нужно явно зафиксировать точность |
|
|
Разбивает модель на несколько GPU |
Когда модель не помещается на одну GPU |
|
|
Ограничивает количество последовательностей, которые vLLM держит в активной пачке |
При тюнинге параллелизма и задержек |
|
|
Ограничивает долю VRAM, которую vLLM может использовать |
Почти всегда при запуске модели |
dtype [55] — это тип чисел, в котором vLLM будет хранить веса и считать активации, то есть фактически точность вычислений.
По умолчанию используется auto, который выбирает FP16 или BF16 в зависимости от того, в какой точности модель была сохранена. Обычно я рекомендую этот параметр явно не задавать и оставлять значение по умолчанию.
gpuMemoryUtilization [56] — это доля VRAM, которую vLLM может занять под инференс модели и KV-кэш.
Большее значение означает больше KV-кэша и выше потенциальный параллелизм, но также выше риск OOM. Меньшее значение безопаснее, но может снизить пропускную способность.
Чем меньше модель, тем больше памяти обычно можно отдавать под vLLM:
Модели 2B–8B — 0.98
Модели 30B–80B — 0.97
Модели 80B–140B — 0.96
Модели около 700B — 0.90
Это мои личные наблюдения, и в вашей ситуации цифры могут отличаться.
maxModelLen — это максимальная длина контекста, с которой запускается vLLM. Этот параметр напрямую влияет на потребление памяти под KV-кэш.
В репозитории модели в файле config.json есть поле max_position_embeddings — это максимальная длина контекста в токенах, которую поддерживает модель.
Для модели Qwen3-8B [42] максимальное значение maxModelLen будет 40960.
Иногда это значение можно расширить, но только если модель поддерживает RoPE Scaling.
RoPE scaling — это приём увеличения длины контекста на инференсе за счёт масштабирования rotary positional embeddings, то есть изменения частот позиционного кодирования без переобучения модели. В vLLM это включается параметром --rope-scaling.
Проверяйте репозиторий модели на Hugging Face: там обычно указывают, можно ли включать --rope-scaling.
Покажу, как это работает на примере Qwen3-8B [42]:
- name: qwen3-8b
env:
- name: VLLM_ALLOW_LONG_MAX_MODEL_LEN
value: "1"
...
vllmConfig:
extraArgs:
- --served-model-name
- Qwen/Qwen3-8B
- --hf-overrides
- '{"rope_scaling":{"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}}'
maxModelLen: 131072
По логам можно увидеть, что контекст увеличен до 131072 токенов.
Если не указать правильный
maxModelLen, vLLM завершится с ошибкой.
И помните: увеличение контекста через scaling не гарантирует сохранение качества на исходном уровне. Чем дальше вы уходите от штатного контекстного окна модели, тем важнее отдельно проверять качество на своих сценариях.
enablePrefixCaching [57] — полезен на повторяющихся запросах, где у многих обращений совпадает начало промпта: system prompt, шаблон RAG, история диалога или общий длинный контекст. В этом случае движок переиспользует уже посчитанный KV-кэш для общего префикса, снижая стоимость prefill-фазы, уменьшая TTFT и повышая общую пропускную способность.
В некоторых режимах работы этот параметр имеет смысл отключать.
enableChunkedPrefill [58] — полезен при длинных входных запросах. Вместо того чтобы прогонять весь prefill одним большим куском, движок режет его на части и может перемешивать их с decode-запросами. Это помогает лучше балансировать нагрузку между prefill и decode.
Рекомендуется включать его всегда, когда это возможно.
Эти оптимизации важны не всегда. Например, для Embedding и Reranker моделей отключенные enablePrefixCaching и enableChunkedPrefill обычно не являются проблемой: эти оптимизации ориентированы в первую очередь на генеративные сценарии.
maxNumSeqs [59] — это максимум последовательностей, которые vLLM может обработать за одну итерацию.
Проще говоря, это то количество клиентских запросов, которое движок попытается держать в активной пачке на одном шаге. Большее значение означает больше параллелизма, но и более сильное давление на память и кэш, а также рост хвостовой задержки.
Здесь нет универсальных рекомендаций. Сначала нужно подобрать модель, понять её сценарий работы — обработка документов, кодогенерация и т.д. — и уже потом подбирать значение с помощью нагрузочных тестов.
–max-num-batched-tokens [60] — это максимум токенов суммарно по всем активным запросам, которые vLLM может обработать за одну итерацию.
Это то, насколько большую пачку токенов можно собрать за один шаг. Если увеличить значение, vLLM сможет сильнее объединять запросы в батч, обычно лучше загружая GPU, но требования к памяти также вырастут.
Здесь тоже нет универсальных рекомендаций. Без тестов идеальное значение не подобрать. На старте можно оставить дефолт, а уже затем пытаться выжимать максимум из конкретного сценария.
Для подбора этих параметров в репозитории vLLM есть отдельный скрипт auto-tune [61], который позволяет подобрать эти значения под конкретную модель.
Сначала скрипт подбирает устойчивое gpu_memory_utilization, снижая его при OOM, затем перебирает комбинации maxNumSeqs × max-num-batched-tokens и выбирает лучшую по пропускной способности с учётом лимита по задержке, если он задан.
Единственный недостаток — нужно подготовить образ под этот скрипт, потому что он рассчитан на запуск из репозитория.
Многие модели выкладывают с более компактными весами FP8. Если у вас видеокарты NVIDIA серии Hopper и новее, рекомендую в первую очередь смотреть именно на такие варианты: это увеличивает бюджет KV-кэша и часто даёт рост производительности инференса.
Проведу эксперимент и запущу по одному экземпляру модели Qwen3.5-35B-A3B: с обычными весами BF16 [62] и с квантованными весами FP8 [63].
Даже по размеру файлов видно разницу: BF16-версия весит 71.9 GB, а FP8 — 37.5 GB.
При запуске я также укажу опцию --kv-cache-dtype fp8, чтобы KV-кэш тоже был в FP8.
# Модель в FP8 + KV-кэш в FP8
- name: qwen35-35b-a3b
modelURL: /models/Qwen3.5-35B-A3B-FP8
replicaCount: 1
repository: vllm-openai
tag: v0.17.0
requestCPU: 8
requestGPU: 1
requestMemory: 32Gi
vllmConfig:
gpuMemoryUtilization: 0.97
extraArgs:
- --kv-cache-dtype
- fp8
# Модель в BF16 + KV-кэш по умолчанию
- name: qwen35-35b-a3b-bf16
modelURL: /models/Qwen3.5-35B-A3B
replicaCount: 1
repository: vllm-openai
requestCPU: 8
requestGPU: 1
requestMemory: 32Gi
tag: v0.17.0
vllmConfig:
gpuMemoryUtilization: 0.97
Доступность KV-кэша при запуске модели в BF16:
Доступность KV-кэша при запуске модели в FP8:
В моём тесте доступный бюджет KV-кэша вырос почти в 3 раза за счёт более компактных весов и FP8 KV-кэша.
Кроме этого, производительность инференса у FP8-модели оказалась выше, чем у BF16.
Вот тест, сделанный с помощью GuideLLM с одинаковыми параметрами (synchronous, prompt_tokens=256, output_tokens=128):
Тест модели в BF16
Тест модели в FP8
Видно, что производительность немного выше.
Может возникнуть ситуация, когда требуется запустить большую модель, а она либо не помещается на одну GPU, либо помещается, но оставляет слишком мало места под KV-кэш.
В таком случае поможет режим Tensor Parallelism. В нём слои модели разбиваются на части, которые обрабатываются несколькими GPU одновременно. Это позволяет запускать модели, превышающие объём памяти одного GPU, и получать более высокую пропускную способность.
Для начала покажу на примере модели Qwen3.5-122B-A10B-FP8 [64], что она формально влезает в одну GPU, но почти без запаса:
- name: qwen35-122b-fp8
...
vllmConfig:
extraArgs:
- --served-model-name
- Qwen3.5-122B-A10B-FP8
- --kv-cache-dtype
- fp8
tensorParallelSize: 1
После старта vLLM видно, что под KV-кэш доступно всего около 7 GB памяти.
Результаты тестирования с помощью GuideLLM: 1 минута на каждый этап, промпты из датасета cnn_dailymail.
Также я провёл такое же тестирование на двух экземплярах по одной GPU каждый:
А теперь запущу один экземпляр, но в режиме TP=2 на двух GPU:
- name: qwen35-122b-fp8
...
vllmConfig:
extraArgs:
- --served-model-name
- Qwen3.5-122B-A10B-FP8
tensorParallelSize: 2
По логам видно, что теперь запас KV-cache стал значительно больше.
И результаты тестирования в таком режиме показывают заметный рост производительности, даже по сравнению с двумя отдельными экземплярами:
Важное уточнение: для Tensor Parallel нужны две свободные GPU на одном узле.
Разделить модель на две GPU, находящиеся на разных узлах, тоже можно, но это уже тема для следующей части.
Что делать, если второго GPU нет, а памяти немного не хватает? Может помочь опция --cpu-offload-gb, которая позволяет расширить VRAM за счёт RAM. Часть весов будет размещена в VRAM, часть — в RAM.
- name: qwen35-122b-fp8
...
vllmConfig:
extraArgs:
...
- --cpu-offload-gb
- "24"
Часть весов модели теперь в RAM, благодаря этому KV-кэш стал больше
Важно понимать, что такой режим работы будет медленнее, чем если бы вся модель помещалась на GPU целиком.
Одна из важных возможностей экосистемы vLLM — выгрузка и переиспользование KV-кэша через внешние коннекторы. В production-сценариях это особенно полезно на повторяющихся или частично повторяющихся входах: можно не пересчитывать уже известный префикс заново, а доставать KV-кэш из внешнего слоя кэширования.
На практике это в первую очередь помогает снижать стоимость prefill-фазы и улучшать TTFT там, где есть повторное использование контекста.
В экосистеме vLLM и связанных сценариях встречаются разные механизмы передачи KV-кэша: LMCache, NIXL, SharedStorage, а также P2P/NCCL-сценарии для межпроцессного обмена. В этой статье я рассматриваю только самый простой вариант, который уже встроен в vLLM Production Stack, — LMCache.
Включается это довольно просто:
- name: qwen3-8b
env:
- name: LMCACHE_TRACK_USAGE
value: "false"
lmcacheConfig:
cpuOffloadingBufferSize: "512"
enabled: true
...
vllmConfig:
extraArgs:
- --served-model-name
- Qwen/Qwen3-8B
Переменная LMCACHE_TRACK_USAGE управляет отправкой статистики использования KV-кэша на внешний сервер.
Внутри логов vLLM можно увидеть, что LMCache успешно запустился.
Если погреть кэш, выполнив множество запросов, можно увидеть попадание в KV-кэш.
У LMCache есть и более тонкая настройка, но её я рассмотрю в следующей части статьи.
Важно помнить, что выгрузка KV-кэша стабильно работает, прежде всего, на transformer-моделях. Для гибридных моделей поддержка может быть ограниченной (на версию vLLM 0.17.0)
Speculative Decoding [65] — это техника ускорения генерации, при которой рядом с основной моделью работает более быстрый «черновик»: он заранее предлагает несколько следующих токенов, а большая модель затем проверяет их за один проход. Если догадки оказываются верными, часть токенов принимается сразу пачкой, за счёт чего ускоряется decode.
В vLLM это особенно полезно там, где узкое место — именно decode, а не prefill. Speculative decoding не всегда означает запуск второй модели рядом. Иногда это встроенный в архитектуру способ предсказывать несколько токенов вперёд (MTP).
Всегда внимательно проверяйте vLLM Recipes [66] или README конкретной модели.
Для Qwen3.5 может быть как минимум два варианта настройки. Например, способ из README [45] репозитория модели:
- name: qwen35-35b-a3b-fp8
...
vllmConfig:
extraArgs:
...
- --speculative-config.method
- qwen3_next_mtp
- --speculative-config.num_speculative_tokens
- "2"
Или способ из рекомендаций vLLM [66]:
- name: qwen35-35b-a3b-fp8
...
vllmConfig:
extraArgs:
...
- --speculative-config.method
- mtp
- --speculative-config.num_speculative_tokens
- "1"
Оба способа рабочие. Всегда пробуйте доступные варианты, подбирайте их под свои сценарии и проверяйте нагрузочными тестами.
В логах модели можно увидеть метрики Speculative Decoding, в том числе сколько токенов в итоге было принято.
При старте больших моделей увеличьте startupProbe. По умолчанию пробы ждут около 10 минут, после чего pod будет перезапущен.
Для огромных моделей этого точно не хватит. Например, для GLM-5 [67] с 744B параметров старт может занимать заметно больше времени.
servingEngineSpec:
startupProbe:
failureThreshold: 180
initialDelaySeconds: 30
periodSeconds: 10
strategy:
type: Recreate
Также имеет смысл указать strategy.type=Recreate, чтобы при перезапусках модели старая копия сначала корректно завершала работу, а уже потом поднималась новая. Если свободных GPU много, это ограничение можно не использовать.
При старте vLLM выполняет компиляцию и прогрев ряда внутренних компонентов, из-за чего запуск больших моделей может занимать десятки минут.
На примере GLM-5:
В случае GLM-5 самые долгие этапы были такими:
Чтение весов модели с диска в память GPU — около 1.5 минут.
JIT-компиляция CUDA-ядер и оптимизация вычислительного графа под конкретную архитектуру GPU — около 5 минут.
DeepGEMM Warmup — около 9.5 минут: прогрев GEMM-операций с автотюнингом и кэшированием скомпилированных ядер.
Чтобы ускорить запуск, нужно закэшировать результаты компиляции. Для этого достаточно создать PVC и смонтировать его в каталог /root/.cache/vllm:
modelSpec:
- annotations:
model: glm-5
extraVolumeMounts:
- mountPath: /root/.cache/vllm
name: vllm-cache
extraVolumes:
- name: vllm-cache
persistentVolumeClaim:
claimName: pvc-glm-5-cache
...
После первого запуска, записи кэшей и повторного перезапуска экземпляра можно увидеть серьёзный прирост по скорости: теперь от старта до готовности к работе проходит около 5 минут.
Ниже собрал ссылки, которые удобно держать под рукой при работе с vLLM и Production Stack.
Примеры можно посмотреть в репозитории Production Stack:
https://github.com/vllm-project/production-stack/tree/main/tutorials/assets [68]
Часть примеров придётся адаптировать под конкретную версию стека и вашу инфраструктуру.
Если нужен список поддерживаемых OpenAI-совместимых эндпоинтов и примеры запросов:
https://docs.vllm.ai/en/latest/serving/openai_compatible_server/ [69]
Проверить, поддерживается ли нужная модель, можно здесь:
https://docs.vllm.ai/en/latest/models/supported_models/ [70]
Практические рекомендации по запуску конкретных моделей и сценариев:
https://docs.vllm.ai/projects/recipes/ [52]
Про все аргументы, которые можно указать при старте vLLM, можно почитать в официальной документации:
https://docs.vllm.ai/en/stable/configuration/engine_args/ [71]
Отдельный раздел документации по оптимизациям и настройке производительности:
https://docs.vllm.ai/en/stable/configuration/optimization/ [72]
Документация по поддержке вызова инструментов:
https://docs.vllm.ai/en/latest/features/tool_calling/ [47]
Документация по reasoning-моделям, thinking/non-thinking-режимам и chat_template_kwargs:
https://docs.vllm.ai/en/stable/features/reasoning_outputs/ [73]
Документация по speculative decoding:
https://docs.vllm.ai/en/latest/features/speculative_decoding/ [65]
Документация по квантованному KV-кэшу:
https://docs.vllm.ai/en/latest/features/quantization/quantized_kvcache/ [74]
Документация по CPU-режиму:
https://docs.vllm.ai/en/stable/getting_started/installation/cpu/ [75]
Отдельный tutorial по offloading KV-кэша в Production Stack:
https://github.com/vllm-project/production-stack/blob/main/tutorials/05-offload-kv-cache.md [76]
В репозитории есть коллекция примеров запросов, оформленных как Python-скрипты:
https://github.com/vllm-project/vllm/tree/main/examples/online_serving [77]
Если вы ждёте какой-то новый функционал, отслеживать изменения в nightly-сборках можно через отдельный репозиторий vLLM Daily:
https://github.com/vllm-project/vllm-daily/tree/main [78]
В этой части я разобрал базовые возможности самого vLLM, с которых проще всего начать практическую работу: первый запуск модели, ключевые стартовые параметры, tool calling, thinking/non-thinking-режимы, мультимодальные и CPU-сценарии, а также несколько важных оптимизаций — FP8, Tensor Parallelism, KV-cache offloading и Speculative decoding.
Если кратко, то уже на уровне самого vLLM можно получить довольно гибкий и производительный inference-сервер, даже без погружения в более сложные компоненты production-стека.
Во второй части я перейду к возможностям уже самого vLLM Production Stack: разберу LMStack Router и его режимы работы, LMStack Cache Server, использование Ray и другие компоненты, которые становятся важны, когда нужно строить более полноценную production-платформу вокруг vLLM.
Автор: Bambarambambum
Источник [79]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/27861
URLs in this post:
[1] Вступление: #intro
[2] Тестовое окружение: #test-env
[3] Как устроены примеры в статье: #examples
[4] Что такое vLLM: #what-is-vllm
[5] vLLM Production Stack: #prod-stack
[6] Какие модели можно запустить: #supported-models
[7] Запуск моделей в разных режимах: #modes
[8] Скачивание модели: #model-download
[9] Запуск Qwen3-8B: #qwen3-8b
[10] Включение вызова инструментов (tool-calling): #tool-calling
[11] Режимы thinking и non-thinking: #thinking-mode
[12] Запуск мультимодальных моделей: #multimodal
[13] Запуск моделей на CPU: #cpu-serving
[14] Стартовые опции: #startup-options
[15] Таблица основных параметров: #main-params
[16] dtype: #dtype
[17] gpuMemoryUtilization: #gpu-mem-util
[18] maxModelLen: #max-model-len
[19] enablePrefixCaching: #prefix-caching
[20] enableChunkedPrefill: #chunked-prefill
[21] Когда эти оптимизации не так важны: #when-not-important
[22] maxNumSeqs: #max-num-seqs
[23] –max-num-batched-tokens: #max-batched-tokens
[24] Что может помочь подобрать эти значения: #tuning
[25] Запуск модели с квантизацией FP8: #fp8
[26] Запуск большой модели на нескольких GPU: #multi-gpu
[27] Запуск большой модели на одной GPU: #single-gpu
[28] Запуск модели с KV-кэш offloading: #kv-offloading
[29] Speculative Decoding: #speculative-decoding
[30] Особенности запуска больших моделей: #large-models
[31] Кэш компиляции при старте: #startup-cache
[32] Полезные ссылки (Справочник): #links
[33] Итоги: #final
[34] Сибинтек-Софт: https://sibintek-soft.ru/
[35] vLLM: https://github.com/vllm-project/vllm
[36] vLLM Production Stack: https://github.com/vllm-project/production-stack
[37] повторять: http://www.braintools.ru/article/4012
[38] какие модели поддерживаются: https://docs.vllm.ai/en/latest/models/supported_models/#list-of-text-only-language-models
[39] просматривать рекомендации по развёртыванию той или иной модели: https://docs.vllm.ai/projects/recipes/en/latest/index.html
[40] образом nightly: https://hub.docker.com/layers/vllm/vllm-openai/nightly/images/sha256-a37e8dfa5d5b5abe9b80e119e608352f47afd56510434b869eb4d219895b1a79
[41] Hugging Face: https://huggingface.co/
[42] Qwen3-8B: https://huggingface.co/Qwen/Qwen3-8B
[43] указаны на официальном сайте: https://docs.vllm.ai/en/latest/serving/openai_compatible_server/#supported-apis
[44] обучения: http://www.braintools.ru/article/5125
[45] Qwen3.5-35B-A3B: https://huggingface.co/Qwen/Qwen3.5-35B-A3B
[46] ошибку: http://www.braintools.ru/article/4192
[47] официальной документации vLLM по Tool Calling: https://docs.vllm.ai/en/latest/features/tool_calling/
[48] поведение: http://www.braintools.ru/article/9372
[49] памяти: http://www.braintools.ru/article/4140
[50] есть Python-скрипт: https://github.com/vllm-project/vllm/blob/main/examples/online_serving/openai_chat_completion_client_for_multimodal.py
[51] Qwen3-Omni-30B: https://huggingface.co/Qwen/Qwen3-Omni-30B-A3B-Instruct
[52] vLLM Recipes: https://docs.vllm.ai/projects/recipes/
[53] CPU-образы: https://hub.docker.com/r/vllm/vllm-openai-cpu
[54] поведение: http://www.braintools.ru/article/5593
[55] dtype: https://docs.vllm.ai/en/stable/configuration/engine_args/#-dtype
[56] gpuMemoryUtilization: https://docs.vllm.ai/en/stable/configuration/engine_args/#-gpu-memory-utilization
[57] enablePrefixCaching: https://docs.vllm.ai/en/stable/configuration/engine_args/#-enable-prefix-caching-no-enable-prefix-caching
[58] enableChunkedPrefill: https://docs.vllm.ai/en/stable/configuration/engine_args/#-enable-chunked-prefill-no-enable-chunked-prefill
[59] maxNumSeqs: https://docs.vllm.ai/en/stable/configuration/engine_args/#-max-num-seqs
[60] –max-num-batched-tokens: https://docs.vllm.ai/en/stable/configuration/engine_args/#-max-num-batched-tokens
[61] Для подбора этих параметров в репозитории vLLM есть отдельный скрипт auto-tune: https://github.com/vllm-project/vllm/blob/main/benchmarks/auto_tune/auto_tune.sh
[62] с обычными весами BF16: https://huggingface.co/Qwen/Qwen3.5-35B-A3B/tree/main
[63] с квантованными весами FP8: https://huggingface.co/Qwen/Qwen3.5-35B-A3B-FP8/tree/main
[64] Qwen3.5-122B-A10B-FP8: https://huggingface.co/Qwen/Qwen3.5-122B-A10B-FP8
[65] Speculative Decoding: https://docs.vllm.ai/en/latest/features/speculative_decoding/
[66] vLLM Recipes: https://docs.vllm.ai/projects/recipes/en/latest/Qwen/Qwen3.5.html#latency-focused-serving
[67] GLM-5: https://huggingface.co/zai-org/GLM-5-FP8
[68] https://github.com/vllm-project/production-stack/tree/main/tutorials/assets: https://github.com/vllm-project/production-stack/tree/main/tutorials/assets
[69] https://docs.vllm.ai/en/latest/serving/openai_compatible_server/: https://docs.vllm.ai/en/latest/serving/openai_compatible_server/
[70] https://docs.vllm.ai/en/latest/models/supported_models/: https://docs.vllm.ai/en/latest/models/supported_models/
[71] https://docs.vllm.ai/en/stable/configuration/engine_args/: https://docs.vllm.ai/en/stable/configuration/engine_args/
[72] https://docs.vllm.ai/en/stable/configuration/optimization/: https://docs.vllm.ai/en/stable/configuration/optimization/
[73] https://docs.vllm.ai/en/stable/features/reasoning_outputs/: https://docs.vllm.ai/en/stable/features/reasoning_outputs/
[74] https://docs.vllm.ai/en/latest/features/quantization/quantized_kvcache/: https://docs.vllm.ai/en/latest/features/quantization/quantized_kvcache/
[75] https://docs.vllm.ai/en/stable/getting_started/installation/cpu/: https://docs.vllm.ai/en/stable/getting_started/installation/cpu/
[76] https://github.com/vllm-project/production-stack/blob/main/tutorials/05-offload-kv-cache.md: https://github.com/vllm-project/production-stack/blob/main/tutorials/05-offload-kv-cache.md
[77] https://github.com/vllm-project/vllm/tree/main/examples/online_serving: https://github.com/vllm-project/vllm/tree/main/examples/online_serving
[78] https://github.com/vllm-project/vllm-daily/tree/main: https://github.com/vllm-project/vllm-daily/tree/main
[79] Источник: https://habr.com/ru/articles/1016062/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1016062
Нажмите здесь для печати.