【DeepSeek部署】vllm部署deepseek,推理过程和答案分开。

模型推理输出

vLLM 支持如 DeepSeek R1 等推理模型,这些模型设计用于生成包含推理步骤和最终结论的输出。

推理模型会在输出中返回额外的 reasoning_content 字段,该字段包含导致最终结论的推理步骤。其他模型的输出中不存在此字段。

支持的模型

vLLM 当前支持以下推理模型:

快速开始

要使用推理模型,需要在向聊天补全接口发送请求时指定 --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_outputstool_calling功能不兼容
  • 并非所有模型都支持推理内容,请查看模型文档确认是否支持