Документация Qwen, часть 2: запуск через vLLM, SGLang и Ollama
Пересказ разделов документации Qwen о развёртывании: OpenAI-совместимый сервер в vLLM и SGLang, переключение размышления, разбор рассуждений и вызовов функций, квантованные версии, YaRN, борьба с нехваткой памяти, а также локальный запуск через Ollama и llama.cpp.
Зачем это читать
Заголовок раздела «Зачем это читать»В уроке 7.1.2 вы разобрали, как устроены движки инференса: непрерывный батчингнепрерывный батчингEN continuous batching (iteration-level scheduling)Состав батча пересматривается после каждого шага decode — закончившиеся запросы уходят, новые встают на их место. Идея системы Orca (2022), стандарт всех современных серверов., PagedAttentionPagedAttention (страничный KV-кэш)EN PagedAttentionKV-кэш хранится блоками фиксированного размера (например, по 16 токенов), а таблица блоков связывает логические позиции с физическими — как страницы виртуальной памяти в ОС. Основа vLLM., префикс-кэшпрефикс-кэш (кэширование префиксов)EN prefix cachingЕсли начало нового запроса совпадает с уже обработанным (системный промпт, история диалога), его KV-кэш берут готовым и prefill делают только для «хвоста».. Документация Qwen отвечает на практический вопрос: какими командами поднять конкретную модель так, чтобы к ней можно было обращаться кодом из урока 8.1.1, и какие подводные камни ждут именно у Qwen3 (режим размышления, разбор вызовов функций, длинный контекст).
Порядок разделов в оригинале: vLLM (рекомендуемый вариант) → SGLang → TGI, dstack, SkyPilot, OpenLLM (облачные и корпоративные варианты, для курса не нужны) → локальные: llama.cpp, Ollama, MLX-LM (только Mac), LM Studio.
Документация рекомендует vLLMvLLMEN vLLMОткрытый движок инференса LLM (UC Berkeley): PagedAttention, continuous batching, тензорный параллелизм, OpenAI-совместимый сервер (vllm serve, порт 8000). Стандарт для сервисов и генерации в RL. как основной путь: просто запустить, высокая пропускная способность, эффективное управление KV-кэшем через PagedAttention, непрерывный батчинг.
Установка
Заголовок раздела «Установка»pip install "vllm>=0.8.5" # документация советует ставить в чистое окружениеПредупреждение оригинала: готовые сборки vLLM жёстко привязаны к своей версии torch и CUDA. Если в окружении уже
стоит другой PyTorch, установка его заменит — поэтому отдельное виртуальное окружение под vLLM обязательно.
Сервер с OpenAI-совместимым API
Заголовок раздела «Сервер с OpenAI-совместимым API»vllm serve Qwen/Qwen3-8B # сервер на http://localhost:8000vllm serve Qwen/Qwen3-8B --tensor-parallel-size 4 # то же, модель разрезана на 4 GPUexport VLLM_USE_MODELSCOPE=true # качать веса с ModelScope, а не с Hugging FaceЕсли имя модели не указывает на локальную папку, vLLM скачает веса сам. Адрес и порт меняются флагами --host
и --port.
Обращаться к серверу можно curl или OpenAI SDK — тем же кодом, что к облачному API:
from openai import OpenAI
# Ключ не проверяется, но SDK требует непустую строкуclient = OpenAI(api_key="EMPTY", base_url="http://localhost:8000/v1")
resp = client.chat.completions.create( model="Qwen/Qwen3-8B", # имя, под которым vLLM поднял модель messages=[{"role": "user", "content": "Чем vLLM отличается от transformers? Два предложения."}], max_tokens=4096, temperature=0.6, top_p=0.95, # параметры режима размышления (см. часть 1) extra_body={"top_k": 20}, # top_k нет в OpenAI SDK — передаём через extra_body)print(resp.choices[0].message.content)Совет документации: vLLM по умолчанию берёт параметры выборки из generation_config.json модели, но лучше всегда
передавать их явно в каждом запросе — и разные для режима с размышлением и без.
Как выключить размышление
Заголовок раздела «Как выключить размышление»- В запросе — поле
chat_template_kwargs:extra_body={"chat_template_kwargs": {"enable_thinking": False}}. Это аргумент шаблона чата, его нет в спецификации OpenAI, и в другом движке он может называться иначе. Для режима без размышления документация советуетtemperature=0.7, top_p=0.8, top_k=20иpresence_penalty=1.5. - Мягко —
/no_thinkв сообщении пользователя (модель слушается последней такой команды). - Насовсем — запустить сервер со своим шаблоном чата, который никогда не даёт модели думать:
vllm serve Qwen/Qwen3-8B --chat-template ./qwen3_nonthinking.jinja. Файл шаблона лежит в репозитории (docs/source/assets/qwen3_nonthinking.jinja). С ним модель не думает, даже если пользователь напишет/think.
Разбор рассуждений и вызовов функций
Заголовок раздела «Разбор рассуждений и вызовов функций»Модель выдаёт один сплошной текст: <think>…</think> и ответ, а вызовы функций — как <tool_call>{…}</tool_call>.
Чтобы клиент получил всё это по полям, серверу нужны парсеры:
# рассуждение уйдёт в отдельное поле message.reasoning_content (vLLM 0.9.0+)vllm serve Qwen/Qwen3-8B --reasoning-parser qwen3
# вызовы функций — в стандартное поле message.tool_calls (формат Hermes)vllm serve Qwen/Qwen3-8B --enable-auto-tool-choice --tool-call-parser hermesФлаги можно сочетать в одной команде. Документация отмечает две тонкости:
- поле
reasoning_content— тоже не часть спецификации OpenAI, это соглашение vLLM, SGLang и DeepSeek API; - в vLLM 0.8.5 разбор рассуждений не сочетался с
enable_thinking=False(тогда был флаг--enable-reasoning --reasoning-parser deepseek_r1); с версии 0.9.0 и парсераqwen3это исправлено.
Подробный разбор вызова функций — на третьей странице путеводителя.
Структурированный вывод
Заголовок раздела «Структурированный вывод»vLLM умеет ограничивать генерацию JSON-схемой (ограниченное декодированиеограниченное декодированиеEN constrained decoding / guided decodingНа каждом шаге сэмплирования запрещаются токены, нарушающие грамматику (например, JSON-схему), — их логиты заменяются на минус бесконечность, и после softmax вероятность таких токенов равна нулю.); параметры — в документации vLLM. Документация Qwen добавляет здравый совет: всё равно описывайте нужный формат в промпте — модели так проще.
Квантованные версии
Заголовок раздела «Квантованные версии»Команда та же, меняется только имя: Qwen/Qwen3-8B-FP8 или Qwen/Qwen3-8B-AWQ.
- FP8-версии Qwen3 квантованы поблочно. Как W8A8 (8-битные веса и активации) они идут на картах с архитектурой Ada Lovelace (RTX 40xx, в том числе ваши 4080), Hopper и новее; с vLLM 0.9.0 — и на Ampere (как W8A16).
- Если при запуске FP8 на нескольких GPU вы видите ошибку вида «output_size … is not divisible by weight
quantization block_n = 128», значит, при таком числе карт слой режется на куски, не кратные блоку квантования.
Уменьшите
--tensor-parallel-sizeили (для MoE) добавьте--enable-expert-parallel.
Что такое AWQ и FP8 и почему блоки — в уроке 7.2.1.
Длинный контекст и YaRN
Заголовок раздела «Длинный контекст и YaRN»Qwen3 предобучали на последовательностях до 32 768 токенов. Для более длинного контекста документация предлагает YaRNYaRNEN YaRN (Yet another RoPE extensioN)NTK-by-parts (каждая пара частот масштабируется по числу оборотов за обучающую длину) плюс температура внимания 0.1·ln s + 1. Используется в DeepSeek-V3 и Qwen. — масштабирование RoPE (урок 5.5.1):
vllm serve Qwen/Qwen3-8B \ --rope-scaling '{"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}' \ --max-model-len 131072Что здесь написано: «растяни позиции в factor = 4 раза относительно исходных 32 768» — получается
токенов.
Три предупреждения документации:
- В vLLM YaRN статический: множитель один и тот же для любых входов, поэтому на коротких текстах качество может немного упасть. Включайте YaRN, только когда длинный контекст действительно нужен.
- Подбирайте
factorпод задачу: если типичная длина 65 536, достаточноfactor= 2. - По умолчанию
max_position_embeddingsвconfig.jsonравен 40 960 = 32 768 под ответ + 8 192 под промпт. Если ваши тексты короче 32 тыс. токенов, YaRN не нужен вовсе.
vLLM как библиотека
Заголовок раздела «vLLM как библиотека»Без сервера vLLM удобен для пакетной обработки (прогнать тысячу промптов разом):
from vllm import LLM, SamplingParams
llm = LLM(model="Qwen/Qwen3-8B") # загрузка модели и выделение KV-кэшаparams = SamplingParams(temperature=0.6, top_p=0.95, top_k=20, max_tokens=4096)
conversations = [ [{"role": "user", "content": "Сколько будет 17 * 23?"}], [{"role": "user", "content": "Назови три реки Китая."}],]# LLM.chat сам применит шаблон чата; enable_thinking передаётся так же, как в сервере (vLLM 0.9.0+)outputs = llm.chat(conversations, params, chat_template_kwargs={"enable_thinking": False})for out in outputs: print(out.outputs[0].text)В этом режиме нет разбора рассуждений и вызовов функций — их придётся выделять самим (код — в части 1).
Если не хватает памяти (FAQ)
Заголовок раздела «Если не хватает памяти (FAQ)»Документация называет два главных рычага:
--max-model-len. По умолчанию 40 960 токенов, и vLLM резервирует память так, чтобы хоть один запрос такой длины поместился. Если вам хватит 8–16 тысяч, уменьшите — освободится место.--gpu-memory-utilization(по умолчанию 0,9): доля памяти GPU, которую vLLM занимает заранее — поэтому сервер «съедает» почти всю карту. Если включены CUDA-графы (по умолчанию да), им нужна память сверх этой доли, и тогда долю надо уменьшать. Не помогло —--enforce-eager(без CUDA-графов, медленнее) или меньший--max-model-len.
SGLangSGLangEN SGLangДвижок инференса от LMSYS: RadixAttention (переиспользование общего префикса запросов), быстрый структурированный вывод, ранняя поддержка новых DeepSeek и Qwen; OpenAI-совместимый сервер на порту 30000. — второй рекомендованный движок. Всё устроено так же, отличаются команды и флаги:
| Что | vLLM | SGLang |
|---|---|---|
| установка | pip install "vllm>=0.8.5" | pip install "sglang[all]>=0.4.6.post1" |
| запуск | vllm serve Qwen/Qwen3-8B | python -m sglang.launch_server --model-path Qwen/Qwen3-8B |
| порт по умолчанию | 8000 | 30000 |
| 4 GPU | --tensor-parallel-size 4 | --tensor-parallel-size 4 (или --tp 4) |
| ModelScope | VLLM_USE_MODELSCOPE=true | SGLANG_USE_MODELSCOPE=true |
| разбор рассуждений | --reasoning-parser qwen3 | --reasoning-parser qwen3 |
| разбор вызовов функций | --enable-auto-tool-choice --tool-call-parser hermes | --tool-call-parser qwen25 |
| YaRN | --rope-scaling '{…}' --max-model-len 131072 | --json-model-override-args '{"rope_scaling":{…}}' --context-length 131072 |
Клиентский код тот же, меняется только base_url="http://localhost:30000/v1". Предупреждения про
enable_thinking=False вместе с разбором рассуждений и про статический YaRN в SGLang те же, что в vLLM.
OllamaOllamaEN OllamaПрограмма для запуска LLM одной командой (ollama run qwen3:8b): своя библиотека моделей в формате GGUF, работа на CPU и GPU, OpenAI-совместимый API на порту 11434. — самый простой способ запустить модель на своём компьютере: одна команда, готовые квантованные GGUFGGUF (формат файлов llama.cpp)EN GGUFОдин файл с весами (обычно квантованными), токенизатором, шаблоном чата и метаданными. Типы квантования — Q8_0, Q6_K, Q4_K_M и др. Используют llama.cpp, Ollama, LM Studio.-файлы.
Честное замечание: страница Ollama в документации Qwen на январь 2026 года всё ещё помечена «будет обновлено для Qwen3»
и описывает Qwen2.5 (ollama run qwen2.5:7b и т. д.). Принцип не изменился, а команды для Qwen3 — те же, что в уроках
курса:
ollama run qwen3:8b # скачает квантованную модель и откроет чат в терминалеollama pull qwen3:0.6b # только скачатьДве полезные вещи со страницы:
- В Ollama нет базовых моделей: даже если в теге нет слова instruct, это чат-модель.
- Свой GGUF-файл подключается через
Modelfile: строкаFROM путь/к/файлу.gguf, параметры (PARAMETER temperature 0.7,PARAMETER top_p 0.8,PARAMETER top_k 20,PARAMETER repeat_penalty 1.05), шаблон чатаTEMPLATE """…"""на языке шаблонов Go (в оригинале приведён полный шаблон ChatML с поддержкой инструментов) и системное сообщениеSYSTEM """…""". Затемollama create имя -f Modelfileиollama run имя.
llama.cpp
Заголовок раздела «llama.cpp»Страница о llama.cpp — самая подробная в разделе «локально». Ключевые мысли:
- llama.cpp — библиотека на C/C++ без внешних зависимостей; Ollama и LM Studio построены поверх неё. Документация
подчёркивает: «использовать llama.cpp» в смысле руководства — это запускать её готовые программы
llama-cli(чат в терминале) иllama-server(OpenAI-совместимый сервер). - Поддерживает CPU (AVX/AVX2/AVX512), Apple Silicon, NVIDIA (CUDA), AMD, Intel, Ascend и другие ускорители и умеет гибридный режим CPU+GPU: часть слоёв на видеокарте, остальное в оперативной памяти — так запускают модели больше суммарной видеопамяти.
- Qwen3 и Qwen3-MoE поддерживаются начиная со сборки
b5092. - Порядок работы: получить программы (лучше собрать самому — получите оптимизации под свой процессор), скачать модель в формате GGUF, запустить.
Подробные команды сборки с CUDA и запуска llama-server для Qwen3-8B и Qwen3-30B-A3B с выгрузкой экспертов на CPU —
в уроке 7.2.2.
🖥 На вашей машине (4× RTX 4080, 32 ГБ)
Заголовок раздела «🖥 На вашей машине (4× RTX 4080, 32 ГБ)»| Задача | Команда | Комментарий |
|---|---|---|
| чат-сервер на одну карту | CUDA_VISIBLE_DEVICES=0 vllm serve Qwen/Qwen3-8B --max-model-len 16384 --reasoning-parser qwen3 | веса ≈16 ГБ, остальное под KV-кэш |
| большая плотная модель | vllm serve Qwen/Qwen3-32B --tensor-parallel-size 4 --max-model-len 16384 | ≈66 ГБ весов, по ≈16 ГБ на карту |
| быстрая MoE | vllm serve Qwen/Qwen3-30B-A3B --tensor-parallel-size 2 --max-model-len 32768 | ≈61 ГБ весов; активны 3 млрд параметров — генерация быстрая |
| сервер для агента | vllm serve Qwen/Qwen3-8B --enable-auto-tool-choice --tool-call-parser hermes --reasoning-parser qwen3 | для практики уроков 8.3 |
| локально без Python | ollama run qwen3:8b | 4-битная модель, ≈5 ГБ |
Карты GeForce связаны только по PCIe, поэтому тензорный параллелизм обходится дороже, чем на серверных GPU
с NVLink. Если модель помещается на одну карту, четыре независимые копии (--data-parallel-size 4) часто дают
больше запросов в секунду. Это опыт из урока 7.1.2 — проверьте сами.
Что сделать руками
Заголовок раздела «Что сделать руками»- Поднимите
vllm serve Qwen/Qwen3-0.6B --reasoning-parser qwen3и задайте вопрос через OpenAI SDK. Напечатайтеresp.choices[0].message.reasoning_contentиcontentпо отдельности. - Повторите запрос с
chat_template_kwargs={"enable_thinking": False}. Сравните число токенов вresp.usage. - Запустите тот же код против Ollama (
base_url="http://localhost:11434/v1",model="qwen3:0.6b") — убедитесь, что клиентский код не меняется. - Специально вызовите нехватку памяти:
--max-model-len 40960 --gpu-memory-utilization 0.3на 8B-модели. Прочитайте ошибку и исправьте её рычагами из FAQ.
Словарик
Заголовок раздела «Словарик»| English | Русский |
|---|---|
| deployment | развёртывание |
| OpenAI-compatible API | OpenAI-совместимый API |
| tensor parallelism | тензорный параллелизм |
| reasoning parser | парсер рассуждений |
| tool call parser | парсер вызовов функций |
| structured output | структурированный вывод |
| out of memory (OOM) | нехватка памяти |