更新时间:2025-08-27 GMT+08:00
分享

Structured Outputs

什么是Structured Outputs

Structured Outputs是指在大模型请求中通过用户给定的指定格式信息(如json格式,sql格式),生成严格符合格式要求的相关文本。guided decoding相关特性可以支持用户给定格式的文本生成

什么是guided-decoding

Guided Decoding是一种用于生成文本的策略,通过提供额外的上下文或约束,来引导模型生成更符合预期的结果。

比如使用openai启动服务,通过配置guided_json参数使用JSON Schema的架构来举例。

JSON Schema使用专门的关键字来描述数据结构,例如标题title、 类型type、属性properties,必须属性required 、定义definitions等,JSON Schema通过定义对象属性、类型、格式的方式来引导模型生成一个包含用户信息的JSON对象。

其优势主要如下:

  • 上下文引导:通过提供特定的格式规范模板,模型可以更好地理解每个字段生成内容的属性并过滤无关信息。
  • 约束生成:可以设定某些限制条件,如关键词、主题或风格,使生成的内容更加一致和相关。
  • 提高质量:通过引导,生成的文本通常严格符合用户指定格式要求,逻辑严密严谨性强。

实现原理

通过将用户给定的内容格式模板(json schema,CFG语言,正则表达式等)转换为FSM,对于输出tokens进行引导和过滤。通过FSM各状态之间的转移规则限定格式化输出中每个字段的内容,通过概率干预的方式排除不符合条件的tokens,从而规范化生成文本

图1 实现原理

如上图,首先模型引擎会读取用户给定的格式信息以及限定条件,例如年龄字段以及其对应值的格式,大模型会将这部分信息转换为FSM。在decode阶段中,若当前生成的token为age,则大模型会根据状态机状态转移规则自动过滤掉不符合条件的格式,如字母,字符等。保证下一个输出为数字

离线推理使用Guided Decoding

离线推理,要使用guided-decoding,需要通过SamplingParams类中的GuidedDecodingParams进行配置。

下面是一种离线使用方式示例:
from vllm import LLM, SamplingParams
from vllm.sampling_params import GuidedDecodingParams

MODEL_NAME = ${MODEL_NAME}
llm = LLM(model=MODEL_NAME)

guided_decoding_params = GuidedDecodingParams(choice=["Positive", "Negative"])
sampling_params = SamplingParams(guided_decoding=guided_decoding_params)
outputs = llm.generate(
    prompts="Classify this sentiment: vLLM is wonderful!",
    sampling_params=sampling_params,
)
print(outputs[0].outputs[0].text)

MODEL_NAME表示对应模型路径。

启动参数说明

表1 启动参数说明

参数名称

类型

取值范围

参数描述

--guided-decoding-backend

str

{xgrammar}

开启引导生成特性。

目前引导生成特性仅支持xgrammar后端

在线推理使用Guided Decoding

启动推理服务请参考启动推理服务(大语言模型)章节,需新增一个启动参数

在线推理使用Guided Decoding时,在发送的请求中包含上述guided_json架构,具体示例可参考以下代码。
curl -X POST http://${docker_ip}:8080/v1/completions \
-H "Content-Type: application/json" \
-d '{
    "model": "${container_model_path}",
    "prompt": "Meet our valorous character, named Knight, who has reached the age of 32. Clad in impenetrable plate armor, Knight is well-prepared for any battle. Armed with a trusty sword and boasting a strength score of 90, this character stands as a formidable warrior on the field.Please provide details for this character, including their Name, Age, preferred Armor, Weapon, and Strength",
    "max_tokens": 200,
    "temperature": 0,
    "guided_json": "{\"title\": \"Character\", \"type\": \"object\", \"properties\": {\"name\": {\"title\": \"Name\", \"maxLength\": 10, \"type\": \"string\"}, \"age\": {\"title\": \"Age\", \"type\": \"integer\"}, \"armor\": {\"$ref\": \"#/definitions/Armor\"}, \"weapon\": {\"$ref\": \"#/definitions/Weapon\"}, \"strength\": {\"title\": \"Strength\", \"type\": \"integer\"}}, \"required\": [\"name\", \"age\", \"armor\", \"weapon\", \"strength\"], \"definitions\": {\"Armor\": {\"title\": \"Armor\", \"description\": \"An enumeration.\", \"enum\": [\"leather\", \"chainmail\", \"plate\"], \"type\": \"string\"}, \"Weapon\": {\"title\": \"Weapon\", \"description\": \"An enumeration.\", \"enum\": [\"sword\", \"axe\", \"mace\", \"spear\", \"bow\", \"crossbow\"], \"type\": \"string\"}}}"
}'

相关文档