Qwen3 与 vLLM 部署实战:从 OpenAI 兼容 API 到 Thinking 模式、工具调用与长上下文配置
【免费下载链接】Qwen1.5Qwen3 is the large language model series developed by Qwen team, Alibaba Cloud.项目地址: https://gitcode.com/GitHub_Trending/qw/Qwen1.5
Qwen3 是阿里云 Qwen 团队推出的大语言模型系列,官方文档明确推荐使用 vLLM 作为首选部署引擎之一。本文以仓库内 docs/source/deployment/vllm.md 为骨架,完整讲解如何用 vLLM 部署 Qwen3:包括环境安装、搭建 OpenAI 兼容 API 服务、控制模型的 Thinking / Non-Thinking 模式、解析推理内容与工具调用、服务 FP8/AWQ 量化模型、通过 YaRN 扩展上下文长度,以及用 Python 库做离线批量推理。读完本文,你将能独立完成 Qwen3 的生产级部署,并理解每个关键参数背后的原理。
vLLM 为什么适合部署 Qwen3
vLLM 是一个高吞吐、内存高效的 LLM 推理与服务引擎,核心特性包括:采用 PagedAttention 高效管理注意力 KV 缓存、对输入请求做连续批处理(continuous batching)、使用优化过的 CUDA 内核,从而在保持易用性的同时获得领先的服务吞吐量。Qwen3 模型(含 Instruct 与 Thinking 系列)均已在 vLLM 中得到完整支持,仓库根目录 README.md 中给出了针对不同 Qwen3 变体的推荐启动命令,并建议使用vllm>=0.9.0以获得最新特性支持。
环境安装
在一个干净的环境中,直接通过 pip 安装即可:
pip install "vllm>=0.8.5"需要注意,vLLM 预编译的发行包对torch及其 CUDA 版本有严格依赖,安装前请确认本地 CUDA 驱动与 PyTorch 版本与 vLLM 的构建要求匹配。仓库内的 examples/speed-benchmark/requirements-perf-vllm.txt 也可以作为安装依赖的参考清单。
启动 OpenAI 兼容的 API 服务
vLLM 最常用的部署方式是把模型以 OpenAI API 协议暴露为服务。默认情况下服务监听在http://localhost:8000,可通过--host与--port参数指定地址:
vllm serve Qwen/Qwen3-8B默认行为如下:
- 若模型名不是有效的本地目录,vLLM 会从 Hugging Face Hub 自动下载模型文件;
- 若想从 ModelScope 下载模型,启动前设置环境变量:
export VLLM_USE_MODELSCOPE=true这一点在仓库源码中有直接印证:examples/speed-benchmark/speed_benchmark_vllm.py在构造LLM引擎前会设置os.environ['VLLM_USE_MODELSCOPE'] = 'True'(见 speed_benchmark_vllm.py)。
多 GPU 张量并行
对超大模型或需要更高吞吐的场景,张量并行只需一个参数:
vllm serve Qwen/Qwen3-8B --tensor-parallel-size 4上面的命令将在 4 张 GPU 上做张量并行推理,请按实际显卡数量调整该值。仓库的评测脚本 eval/README.md 中给出了一个面向大模型的完整示例:用Qwen/Qwen3-235B-A22B-Instruct-2507在 8 卡上以--tensor-parallel-size 8、--enforce-eager、--trust-remote-code --served-model-name启动服务,其中--served-model-name用于自定义对外暴露的模型名。
与 Qwen3 对话:curl 与 Python 客户端
服务启动后,即可调用 OpenAI 的/v1/chat/completions接口与 Qwen3 对话。
curl 方式
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{ "model": "Qwen/Qwen3-8B", "messages": [ {"role": "user", "content": "Give me a short introduction to large language models."} ], "temperature": 0.6, "top_p": 0.95, "top_k": 20, "max_tokens": 32768 }'Python 方式
使用openaiSDK,将 API Key 与 base URL 指向 vLLM 服务即可:
from openai import OpenAI # Set OpenAI's API key and API base to use vLLM's API server. openai_api_key = "EMPTY" openai_api_base = "http://localhost:8000/v1" client = OpenAI( api_key=openai_api_key, base_url=openai_api_base, ) chat_response = client.chat.completions.create( model="Qwen/Qwen3-8B", messages=[ {"role": "user", "content": "Give me a short introduction to large language models."}, ], max_tokens=32768, temperature=0.6, top_p=0.95, extra_body={ "top_k": 20, }, ) print("Chat response:", chat_response)提示:
top_k并非 OpenAI 协议标准参数,因此在 Python SDK 中需通过extra_body传递;curl的 JSON body 中则可直接携带。仓库评测脚本 eval/generate_api_answers/utils_vllm.py 正是采用这种方式(extra_body里塞入top_k)调用 vLLM 的 OpenAI 兼容接口。
提示:vLLM 默认会使用模型文件里
generation_config.json中的采样参数。默认采样参数在 Thinking 模式下大多数情况可用,但官方建议根据你的应用场景调整采样参数,并总是显式地在 API 请求中传入采样参数。
控制 Thinking 与 Non-Thinking 模式
Qwen3 模型在回答前会先进行思考(thinking)。这一行为可以由两种开关控制:
- 硬开关(hard switch):彻底禁用思考;
- 软开关(soft switch):让模型遵循用户指令,自行决定是否思考(例如提示词里出现
/think时思考)。
通过 API 参数禁用思考(硬开关)
在 API 请求中传入chat_template_kwargs.enable_thinking=False即可关闭思考:
::::{tab-set}
:::{tab-item} curl
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{ "model": "Qwen/Qwen3-8B", "messages": [ {"role": "user", "content": "Give me a short introduction to large language models."} ], "temperature": 0.7, "top_p": 0.8, "top_k": 20, "max_tokens": 8192, "presence_penalty": 1.5, "chat_template_kwargs": {"enable_thinking": false} }':::
:::{tab-item} Python
from openai import OpenAI # Set OpenAI's API key and API base to use vLLM's API server. openai_api_key = "EMPTY" openai_api_base = "http://localhost:8000/v1" client = OpenAI( api_key=openai_api_key, base_url=openai_api_base, ) chat_response = client.chat.completions.create( model="Qwen/Qwen3-8B", messages=[ {"role": "user", "content": "Give me a short introduction to large language models."}, ], max_tokens=8192, temperature=0.7, top_p=0.8, presence_penalty=1.5, extra_body={ "top_k": 20, "chat_template_kwargs": {"enable_thinking": False}, }, ) print("Chat response:", chat_response)::::
注意:
enable_thinking参数并不是 OpenAI API 兼容协议的一部分,不同推理框架的具体实现方式可能不同。
用自定义 Chat 模板彻底禁用思考
如果要完全禁用思考(即使模型被用户用/think指令要求思考也强制不输出思考内容),可以在启动模型时使用自定义 Chat 模板:
vllm serve Qwen/Qwen3-8B --chat-template ./qwen3_nonthinking.jinja该模板位于仓库 docs/source/assets/qwen3_nonthinking.jinja。从模板源码可以看出其设计思路:它保留了 Qwen3 的 ChatML 格式(<|im_start|>/<|im_end|>)、工具调用 XML 标签(<tool_call>)与多轮对话处理逻辑,但在生成提示(add_generation_prompt分支)中不再拼接<think>\n\n</think>开头(对比默认模板会输出该段),从而从提示词层面直接阻止模型进入思考模式。
提示:官方建议为 Thinking 与 Non-Thinking 模式设置不同的采样参数(例如上例中思考模式使用
temperature=0.6, top_p=0.95,非思考模式使用temperature=0.7, top_p=0.8),以获得各自更优的输出质量。
解析思考内容(Reasoning Content)
vLLM 支持把模型生成的思考内容解析为结构化消息:
vllm serve Qwen/Qwen3-8B --enable-reasoning --reasoning-parser deepseek_r1自 vLLM 0.9.0 起,也可以使用专为 Qwen3 适配的解析器:
vllm serve Qwen/Qwen3-8B --reasoning-parser qwen3启用后,响应消息中除了原有的content字段,还会多出一个reasoning_content字段,其中包含模型生成的思考内容。
仓库根目录 README.md 中针对不同 Qwen3 变体给出了带推理解析的推荐启动方式:
# Qwen3-Thinking-2507 系列(思考模型) vllm serve Qwen/Qwen3-30B-A3B-Thinking-2507 --port 8000 --max-model-len 262144 --enable-reasoning --reasoning-parser deepseek_r1 # Qwen3 通用模型 vllm serve Qwen/Qwen3-8B --port 8000 --max-model-len 131072 --enable-reasoning --reasoning-parser qwen3注意:该特性并非 OpenAI API 兼容功能。
重要:截至 vLLM 0.8.5,
enable_thinking=False与推理内容解析不兼容。如果你需要在 API 请求中传入enable_thinking=False,应同时禁用思考内容解析;该限制已在 vLLM 0.9.0 通过qwen3推理解析器解决。
另外需要注意,vLLM 在 API 请求预处理时会丢弃所有reasoning_content字段,因此在做**多步工具调用(multi-step tool use)**时,官方建议原样传递消息内容、不要手动抽取思考内容,让 Chat 模板自行处理(见 README.md 的说明)。
解析工具调用(Function Calling / Tool Use)
vLLM 同样支持把模型生成的工具调用解析为结构化消息:
vllm serve Qwen/Qwen3-8B --enable-auto-tool-choice --tool-call-parser hermesQwen3 的tokenizer_config.json中的 Chat 模板已经内置了对 Hermes 风格工具调用的支持,因此无需额外准备。仓库的 函数调用指南 一节给出了更完整的实践(见 function_call.md):它要求vllm >= v0.8.5,同时启用自动工具选择、Hermes 工具调用解析器和推理内容解析:
vllm serve Qwen/Qwen3-8B --enable-auto-tool-choice --tool-call-parser hermes --reasoning-parser deepseek_r1调用时同样走 OpenAI 兼容接口,把tools参数一并传入:
response = client.chat.completions.create( model=model_name, messages=messages, tools=tools, temperature=0.7, top_p=0.8, max_tokens=512, extra_body={ "repetition_penalty": 1.05, "chat_template_kwargs": {"enable_thinking": False} # default to True }, )vLLM 会自动解析工具调用,返回的response.choices[0].message.tool_calls中会包含结构化后的函数名与 JSON 参数(如Function(arguments='{"location": "San Francisco, CA, USA"}', name='get_current_temperature')),可直接用于后续工具执行与结果回传。
结构化 / JSON 输出
vLLM 支持结构化/JSON 输出,可通过guided_json等参数约束模型输出格式(具体参数请参考 vLLM 官方文档中 OpenAI 兼容服务的 Extra Parameters for Chat API 部分)。此外,官方也建议在 system message 或用户提示词中显式说明期望的格式,两者结合效果更佳。
服务量化模型:FP8 与 AWQ
Qwen3 提供了两种预量化版本:FP8和AWQ。服务命令与原版模型完全一致,只需替换模型名:
# For FP8 quantized model vllm serve Qwen/Qwen3-8B-FP8 # For AWQ quantized model vllm serve Qwen/Qwen3-8B-AWQ注意:Qwen3 的 FP8 模型采用按块量化(block-wise quant),以 w8a8 方式运行,需要 NVIDIA 显卡算力 > 8.9(即 Ada Lovelace、Hopper 及更新架构)。自 vLLM v0.9.0 起,FP8 Marlin 已支持按块量化(以 w8a16 方式运行),因此 Qwen3 FP8 模型也可以在 Ampere 系列显卡上运行。
注意:部署 FP8 模型时若遇到以下错误,说明张量并行度与模型权重不匹配:
File ".../vllm/vllm/model_executor/layers/quantization/fp8.py", line 477, in create_weights raise ValueError( ValueError: The output_size of gate's and up's weight = 192 is not divisible by weight quantization block_n = 128.建议降低张量并行度,例如
--tensor-parallel-size 4;或启用专家并行,例如--tensor-parallel-size 8 --enable-expert-parallel。
上下文长度与 YaRN 扩展
Qwen3 模型预训练时的上下文长度最大为 32,768 token。要处理远超该长度的上下文,需要应用 RoPE 缩放(RoPE scaling)技术。官方验证了 YaRN(一种增强模型长度外推的技术)在长文本上的效果,而 vLLM 原生支持 YaRN:
vllm serve Qwen/Qwen3-8B --rope-scaling '{"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}' --max-model-len 131072注意:vLLM 实现的是静态 YaRN,即缩放因子不随输入长度变化,可能影响短文本上的表现。官方建议只在确有长上下文处理需求时才配置
rope_scaling,并按需修改factor。例如,若你的应用典型上下文为 65,536 token,把factor设为 2.0 更合适。
注意:
config.json中的默认max_position_embeddings为 40,960;当未指定--max-model-len时 vLLM 会使用该值。这 40,960 的分配是:为输出预留 32,768 token、为典型提示词预留 8,192 token,足以覆盖大多数短文本处理场景,并为模型思考留出空间。若平均上下文长度不超过 32,768 token,官方不建议启用 YaRN,因为它可能反而降低模型性能。
该配置与仓库 README.md 中的推荐用法一致:例如面向长上下文场景启动Qwen/Qwen3-8B时使用--max-model-len 131072。
将 vLLM 作为 Python 库使用
vLLM 也可以直接作为 Python 库调用,适合离线批量推理场景,但会缺少部分仅 API 提供的功能(例如把模型生成解析为结构化消息)。
方式一:LLM.generate(配合 transformers 分词器)
from transformers import AutoTokenizer from vllm import LLM, SamplingParams # Initialize the tokenizer tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B") # Configure the sampling parameters (for thinking mode) sampling_params = SamplingParams(temperature=0.6, top_p=0.95, top_k=20, max_tokens=32768) # Initialize the vLLM engine llm = LLM(model="Qwen/Qwen3-8B") # Prepare the input to the model prompt = "Give me a short introduction to large language models." messages = [ {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True, enable_thinking=True, # Set to False to strictly disable thinking ) # Generate outputs outputs = llm.generate([text], sampling_params) # Print the outputs. for output in outputs: prompt = output.prompt generated_text = output.outputs[0].text print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")方式二:LLM.chat(vLLM ≥ 0.9.0)
自 vLLM 0.9.0 起,也可以直接使用LLM.chat接口,原生支持chat_template_kwargs:
from vllm import LLM, SamplingParams # Configure the sampling parameters (for thinking mode) sampling_params = SamplingParams(temperature=0.6, top_p=0.95, top_k=20, max_tokens=32768) # Initialize the vLLM engine llm = LLM(model="Qwen/Qwen3-8B") # Prepare the input to the model prompt = "Give me a short introduction to large language models." messages = [ {"role": "user", "content": prompt} ] # Generate outputs outputs = llm.chat( [messages], sampling_params, chat_template_kwargs={"enable_thinking": True}, # Set to False to strictly disable thinking ) # Print the outputs. for output in outputs: prompt = output.prompt generated_text = output.outputs[0].text print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")仓库中的工程化示例
仓库 examples/speed-benchmark/speed_benchmark_vllm.py 展示了更完整的 vLLM 库级工程实践,可以印证上述用法:
- 构造
LLM引擎时传入tensor_parallel_size、gpu_memory_utilization、max_model_len、enforce_eager等参数(speed_benchmark_vllm.py); - 通过
SamplingParams显式配置temperature / top_p / top_k / repetition_penalty / presence_penalty / frequency_penalty / max_tokens(speed_benchmark_vllm.py); - 使用
AutoTokenizer构造提示词并记录真实 token 数,用llm.generate([query], sampling_params)执行推理并统计吞吐(speed_benchmark_vllm.py)。
该脚本的命令行入口也值得参考,例如--max_model_len 32768、--gpu_memory_utilization 0.9、--enforce_eager、--gpus 0,1,2,3与--use_modelscope等参数(speed_benchmark_vllm.py)。
FAQ:OOM 问题排查
部署中最常见的问题是显存不足(OOM),官方推荐关注两个参数:
--max-model-len:Qwen3 默认的max_position_embedding为 40,960,因此服务默认支持的最大序列长度也是该值,会显著抬高显存需求。把它调整到适合你场景的长度,往往能直接缓解 OOM。--gpu-memory-utilization:vLLM 会按该比例预分配GPU 显存,默认值为0.9——这也是 vLLM 服务看起来总是占用大量显存的原因。如果处于 eager 模式(默认不是),可以把该值调高以缓解 OOM;否则服务会使用 CUDA Graphs,这部分显存不受 vLLM 控制,此时应尝试调低该值。
如果上述手段仍不奏效,可以尝试--enforce-eager(关闭 CUDA Graph,代价是推理变慢),或进一步减小--max-model-len。仓库评测脚本在启动大模型服务时也显式使用了--enforce-eager(见 eval/README.md),与这里的排查建议相互印证。
总结
至此,你已经掌握了用 vLLM 部署 Qwen3 的完整路径:从 pip 安装、启动 OpenAI 兼容服务、通过 curl/Python 对话,到精细化控制 Thinking / Non-Thinking 模式、解析推理内容与工具调用、服务 FP8/AWQ 量化模型、用 YaRN 扩展上下文,以及 Python 库离线批量推理和 OOM 排查。核心要点是:显式传入采样参数、按场景区分思考与非思考模式的采样配置、仅在需要长上下文时启用 YaRN、根据显卡显存合理设置--max-model-len与--gpu-memory-utilization。结合仓库中的 README.md、函数调用指南、速度基准脚本 与 评测部署示例 等资源,你可以在此基础上继续搭建生产级推理服务。
【免费下载链接】Qwen1.5Qwen3 is the large language model series developed by Qwen team, Alibaba Cloud.项目地址: https://gitcode.com/GitHub_Trending/qw/Qwen1.5
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考