vLLM¶
我们建议您在部署 Qwen 时尝试使用 vLLM。它易于使用,且具有最先进的服务吞吐量、高效的注意力键值内存管理(通过PagedAttention实现)、连续批处理输入请求、优化的CUDA内核等功能。要了解更多关于vLLM的信息,请参阅 论文 和 文档。
环境配置¶
默认情况下,你可以通过 pip 在新环境中安装 vllm :
pip install "vllm>=0.8.5"
请留意预构建的vllm对torch和其CUDA版本有强依赖。请查看vLLM官方文档中的注意事项以获取有关安装的帮助。
API 服务¶
借助vLLM,构建一个与OpenAI API兼容的API服务十分简便,该服务可以作为实现OpenAI API协议的服务器进行部署。默认情况下,它将在 http://localhost:8000 启动服务器。您可以通过 --host 和 --port 参数来自定义地址。请按照以下所示运行命令:
vllm serve Qwen/Qwen3-8B
默认情况下,如果模型未指向有效的本地目录,它将从 Hugging Face Hub 下载模型文件。要从 ModelScope 下载模型,请在运行上述命令之前设置以下内容:
export VLLM_USE_MODELSCOPE=true
对于使用张量并行的分布式推理,操作非常简单:
vllm serve Qwen/Qwen3-8B --tensor-parallel-size 4
上述命令将在 4 块 GPU 上使用张量并行。您应根据需求调整 GPU 的数量。
基本用法¶
然后,您可以利用 create chat interface 来与Qwen进行对话:
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
}'
或者您可以如下面所示使用 openai Python SDK中的 API 客户端:
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)
小技巧
vllm 将使用模型文件中 generation_config.json 的采样参数。
虽然默认的采样参数在大多数情况下适用于思考模式,但建议根据您的应用调整采样参数,并始终将采样参数传递给 API。
思考与非思考模式¶
Qwen3 模型会在回复前进行思考。这种行为可以通过硬开关(完全禁用思考)或软开关(模型遵循用户关于是否应该思考的指令)来控制。
硬开关在 vLLM 中可以通过以下 API 调用配置使用。要禁用思考,请使用
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}
}'
或者您可以如下面所示使用 openai Python SDK中的 API 客户端:
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定义的参数,具体传入方式可能因推理框架不同而不同。
小技巧
要完全禁用思考,您可以在启动模型时使用自定义聊天模板:
vllm serve Qwen/Qwen3-8B --chat-template ./qwen3_nonthinking.jinja
该聊天模板会阻止模型生成思考内容,即使用户通过 /think 指示模型这样做。
小技巧
建议为思考模式和非思考模式分别设置不同的采样参数。
解析思考内容¶
vLLM 支持将模型生成的思考内容解析为结构化消息:
vllm serve Qwen/Qwen3-8B --enable-reasoning --reasoning-parser deepseek_r1
自 vLLM 0.9.0 版本,也可以使用
vllm serve Qwen/Qwen3-8B --reasoning-parser qwen3
响应消息除了包含 content 字段外,还会有一个名为 reasoning_content 的字段,其中包含模型生成的思考内容。
备注
请注意,此功能与 OpenAI API 规范不一致。
重要
在 vLLM 0.8.5 版本中,enable_thinking=False 与此功能不兼容。如果需要向 API 传递 enable_thinking=False,则应禁用解析思考内容。此问题已在 vLLM 0.9.0 中通过 qwen3 思考解析器得到解决。
解析工具调用¶
vLLM 支持将模型生成的工具调用内容解析为结构化消息:
vllm serve Qwen/Qwen3-8B --enable-auto-tool-choice --tool-call-parser hermes
详细信息,请参阅函数调用的指南。
结构化/JSON输出¶
vLLM 支持结构化/JSON 输出。请参照vLLM文档了解 guided_json 参数。此外,也建议在系统消息或用户提示中指示模型生成特定格式,避免仅依赖于推理参数配置。
部署量化模型¶
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) 量化,该功能支持在 compute capability > 8.9 的 NVIDIA GPU 上运行,即 Ada Lovelace、Hopper 及更新的 GPU,并以 w8a8 方式运行。
从 vLLM v0.9.0 开始,FP8 Marlin 已支持分块量化(以 w8a16 方式运行),您还可以在 Ampere 显卡上运行 Qwen3 FP8 模型。
备注
如果在部署 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。
上下文长度¶
Qwen3 模型在预训练中的上下文长度最长为 32,768 个 token。为了处理显著超过 32,768 个 token 的上下文长度,应应用 RoPE 缩放技术。我们已经验证了 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。
备注
如果未指定 --max-model-len,config.json 中的默认 max_position_embeddings 被设置为 40,960,vLLM 将使用该值。此分配包括为输出保留 32,768 个 token,为典型提示保留 8,192 个 token,这足以应对大多数涉及短文本处理的场景,并为模型思考留出充足空间。如果平均上下文长度不超过 32,768 个 token,我们不建议在此场景中启用 YaRN,因为这可能会降低模型性能。
Python 库使用¶
vLLM 也可以直接用作 Python 库,这对离线批量推理非常方便,但缺少一些仅限 API 的功能,例如将模型生成解析为结构化消息。
以下展示了将 vLLM 用作库的基本用法:
from transformers import AutoTokenizer
from vllm import LLM, SamplingParams
# Initialize the tokenizer
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B")
# Configurae 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}")
自 vLLM v0.9.0 开始,LLM.chat 支持 chat_template_kwargs 参数,因而也可以使用以下方法:
from vllm import LLM, SamplingParams
# Configurae 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}")
常见问题解答¶
您可能会遇到令人烦恼的OOM(内存溢出)问题。我们推荐您尝试两个参数进行修复。
第一个参数是
--max-model-len。我们提供的默认最大位置嵌入(max_position_embedding)为 40960 ,因此服务时的最大长度也是这个值,这会导致更高的内存需求。将此值适当减小通常有助于解决OOM问题。另一个您可以关注的参数是
--gpu-memory-utilization。 vLLM将预分配该参数指定比例的显存。默认情况下,该值为0.9。这也是为什么您发现一个vLLM服务总是占用大量内存的原因。如果你使用了eager模式(默认不是),您可以将其调高以应对OOM问题。反之,vLLM会使用CUDA Graphs,而CUDA Graphs会额外占用不受vLLM管理的显存;此时,您应当尝试降低--gpu-memory-utilization。如果还是无法解决,可以尝试--enforce-eager(这会影响推理效率)或缩小--max-model-len。
有关 vLLM 的更多使用指南,请参阅 vLLM 的Qwen3 使用指南。