模型推理输出
vLLM 支持如 DeepSeek R1 等推理模型,这些模型设计用于生成包含推理步骤和最终结论的输出。
推理模型会在输出中返回额外的 reasoning_content
字段,该字段包含导致最终结论的推理步骤。其他模型的输出中不存在此字段。
支持的模型
vLLM 当前支持以下推理模型:
- DeepSeek R1 系列 (
deepseek_r1
,会查找<think> ... </think>
标签)
快速开始
要使用推理模型,需要在向聊天补全接口发送请求时指定 --enable-reasoning
和 --reasoning-parser
参数。--reasoning-parser
参数指定用于从模型输出中提取推理内容的解析器。
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B \
--enable-reasoning --reasoning-parser deepseek_r1
接下来向模型发送请求,响应中将包含推理内容。
from openai import OpenAI
# 修改 OpenAI 的 API key 和 API base 以使用 vLLM 的 API 服务
openai_api_key = "EMPTY"
openai_api_base = "http://localhost:8000/v1"
client = OpenAI(
api_key=openai_api_key,
base_url=openai_api_base,
)
models = client.models.list()
model = models.data[0].id
# 第1轮
messages = [{
"role": "user", "content": "9.11和9.8,哪个更大?"}]
response = client.chat.completions.create(model=model, messages=messages)
reasoning_content = response.choices[0].message.reasoning_content
content = response.choices[0].message.content
print("推理内容:", reasoning_content)
print("内容:", content)
reasoning_content
字段包含导致最终结论的推理步骤,而 content
字段包含最终结论。
流式聊天补全
推理模型也支持流式聊天补全。reasoning_content
字段可在聊天补全响应块的 delta
字段中获取。
{
"id": "chatcmpl-123",
"object": "chat.completion.chunk",
"created": 1694268190,
"model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B",
"system_fingerprint": "fp_44709d6fcb",
"choices": [
{
"index": 0,
"delta": {
"role": "assistant",
"reasoning_content": "是",
},
"logprobs": null,
"finish_reason": null
}
]
}
请注意该功能与 OpenAI Python 客户端库不兼容。您可以使用 requests
库来发送流式请求。
如何支持新的推理模型
您可以参照 vllm/entrypoints/openai/reasoning_parsers/deepseek_r1_reasoning_parser.py
添加新的 ReasoningParser
。
# 导入所需包
from vllm.entrypoints.openai.reasoning_parsers.abs_reasoning_parsers import (
ReasoningParser, ReasoningParserManager)
from vllm.entrypoints.openai.protocol import (ChatCompletionRequest,
DeltaMessage)
# 定义推理解析器并注册到vllm
# register_module中的名称列表可用于--reasoning-parser参数
@ReasoningParserManager.register_module(["example"])
class ExampleParser(ReasoningParser):
def __init__(self, tokenizer: AnyTokenizer):
super().__init__(tokenizer)
def extract_reasoning_content_streaming(
self,
previous_text: str,
current_text: str,
delta_text: str,
previous_token_ids: Sequence[int],
current_token_ids: Sequence[int],
delta_token_ids: Sequence[int],
) -> Union[DeltaMessage, None]:
"""
需要实现的实例方法,用于从未完成的响应中提取推理内容;
适用于处理流式推理调用。必须是实例方法,因为它需要状态信息:
当前token/差异,以及之前已解析提取的信息(参见构造函数)
"""
def extract_reasoning_content(
self, model_output: str, request: ChatCompletionRequest
) -> Tuple[Optional[str], Optional[str]]:
"""
从完整的模型生成字符串中提取推理内容。
用于非流式响应,即在发送给客户端前已获得完整模型响应。
参数:
model_output: str
要从中提取推理内容的模型生成字符串
request: ChatCompletionRequest
用于生成model_output的请求对象
返回:
Tuple[Optional[str], Optional[str]]
包含推理内容和内容的元组
"""
定义推理解析器后,您可以在调用聊天补全接口时通过 --reasoning-parser
参数来使用它。
vllm serve <模型标签> \
--enable-reasoning --reasoning-parser example
限制
- 推理内容仅在在线服务的聊天补全接口(
/v1/chat/completions
)中可用 - 与
structured_outputs
和tool_calling
功能不兼容 - 并非所有模型都支持推理内容,请查看模型文档确认是否支持