让模型说人话、懂结构:OpenVINO™ GenAI 全面开启结构化输出新时代!
openlab_96bf3613
更新于 5天前
作者:武卓,AI软件布道师;杨粟,AI软件解决方案工程师
引言
AI 应用正在超越简单的文本生成阶段——开发者如今需要模型能够生成机器可读、结构化的输出,以便代码生成、API 调用或用户界面可以直接使用。这正是 Structured Output(结构化输出,SO) 发挥作用的地方:它在解码过程中对模型进行引导,使每一个生成的 token 都严格遵循预定义的模式或语法规则——无论是 JSON、SQL、XML,还是函数调用参数等。通过在生成阶段就保证结果的正确性,结构化输出消除了脆弱的后处理解析逻辑和“生成错误后重试”的循环,从而带来更安全的自动化、更快的响应时间以及更易集成的工作流程。这一能力在 智能体工作流、MCP 服务器 以及多步 AI 系统中尤为关键,因为这些场景都依赖模型与工具之间可靠的结构化数据交换,以实现实时的协调与决策。
自 OpenVINO™ 2025.3 版本起,OpenVINO™ GenAI 已内置支持结构化输出,可在 AI PC、 边缘设备等各种场景高效运行。
OpenVINO™ GenAI如何实现结构化输出
什么是 Token-Level SO(逐词级结构化输出)?
从本质上讲,Token-Level SO 确保大语言模型(LLM)生成的每一个 token 都严格遵循预定义的结构或约束——例如 JSON Schema、正则表达式或语法规则。其过程非常直观:在每一步解码时,模型会根据整个词表生成概率分布,而系统会屏蔽掉所有违反结构约束的 token,仅允许合法的 token 被采样输出。通过这种方式,模型在生成阶段就能保证语法上的正确性,同时保持极低的运行开销。这种方法高效、确定且与 OpenVINO™ GenAI 的优化流水线高度契合——它将逐词级的掩码机制直接集成到推理过程中,实现实时的、格式完全正确的结构化输出。
OpenVINO™ GenAI 通过使用XGrammar 作为底层引擎来实现这种结构化输出能力。
什么是XGrammar?
XGrammar是一个开源库,用于实现快速且灵活的结构化文本生成。它通过约束解码(constrained decoding)确保输出在结构上 100% 正确,并支持多种结构类型,如JSON、正则表达式(regex) 以及自定义上下文无关语法等。经过精心优化的 XGrammar 在 JSON 生成中实现了几乎为零的性能开销,成为当前最快的结构化生成引擎之一。它已被集成到WebLLM、vLLM 和SGLang 等多个项目中。凭借其出色的速度与可移植性,OpenVINO™ GenAI 采用 XGrammar 作为结构化输出(SO)的底层引擎,帮助开发者轻松生成格式正确、结构清晰的输出结果。
在实际应用中,启用OpenVINO™ GenAI 的结构化输出功能 有一个关键前提:OpenVINO™ 的分词器(tokenizer)必须支持词表暴露(expose vocabulary)。这一能力使解码引擎能够精确地知道哪些 token 可以在下一步出现,从而高效地应用来自 XGrammar 的约束。通过暴露完整的词表,OpenVINO 能在生成过程中执行更细粒度的 token 级掩码控制,实现逐词级的约束与基于模式的验证。
分步教程:用OpenVINO™ GenAI生成结构化输出
以下是有关如何使用 OpenVINO™ GenAI 获取结构化输出的分步指南。
第一步: 安****>
首先,克隆openvino.genai GitHub 仓库。这里面包含开始使用 OpenVINO™ GenAI进行 LLM 推理并获得结构化暑促所需的所有代码和示例。
git clone https://github.com/openvinotoolkit/openvino_genai.git
cd openvino_genai
导航到“文本生成”示例:
<your_path>\openvino.genai\samples\python\text_generation
在此文件夹中,您可以找到有关示例的重要 README.md 文件。您也可以直接从 OpenVINO™下载页面获取该文件。
现在需要准备一个 Python 虚拟环境,这是模型推理所必需的。这可以通过以下代码来完成:
python -m venv venv_export
venv_export\Scripts\activate
pip install --upgrade-strategy eager -r ../../deployment-requirements.txt
步骤2: 下载预先优化好及转换为OpenVINO™ IR格式的 LLM
在使用结构化输出解码之前,您的模型需要采用 OpenVINO™ IR 格式。您可以从 魔搭社区 OpenVINO™专区下载预转换的模型,也可以使用 optimum-cli 手动转换您最喜欢的生成式AI模型。以下是将 Qwen3-8B 转换为具有 INT4量化的 OpenVINO™ IR 格式的快速示例:
optimum-cli export openvino \
--model qwen\qwen3-8B \
--task text-generation-with-past \
--weight-format int4 \
./qwen3-8B-ov-int4 步骤3: 定义你的结构化模式(来自 Pydantic 的 JSON 模式)
结构化输出解码需要一个模式来定义允许模型生成的内容。在 OpenVINO™ GenAI 中,可以使用 Pydantic 方便地定义此模式,它会自动导出解码器可以遵循的 JSON 模式。
from typing import Literal
from pydantic import BaseModel, Field
class Person(BaseModel):
name: str = Field(pattern=r"^[A-Z][a-z]{1,20}$")
surname: str = Field(pattern=r"^[A-Z][a-z]{1,20}$")
age: int
city: Literal["Dublin", "Dubai", "Munich"]
class Car(BaseModel):
model: str = Field(pattern=r"^[A-Z][a-z]{1,20} ?[A-Z][a-z]{0,20} ?.?$")
year: int
engine_type: Literal["diesel", "petrol", "electric", "hybrid"]
class Transaction(BaseModel):
id: int = Field(ge=1000, le=10_000_000)
amount: float
currency: Literal["EUR", "PLN", "RUB", "AED", "CHF", "GBP", "USD"]
class ItemQuantities(BaseModel):
person: int = Field(ge=0, le=100)
car: int = Field(ge=0, le=100)
transaction: int = Field(ge=0, le=100)
item***ap = {"person": Person, "car": Car, "transaction": Transaction}
sy***essage = (
"You generate JSON object***ased on the user's request. You can generate JSON objects with different types of objects: person, car, transaction."
"If the user requested a different type, the JSON fields should remain zero. "
"Please note that the words 'individual', 'person', 'people', 'man', 'human', 'woman', 'citizen' are synonyms and can be used interchangeably."
"E.g. if the user wants 5 houses, then the JSON must be {\"person\": 0, \"car\": 0, \"transaction\": 0}. "
"If the user wants 3 people and 1 house, then the JSON must be {\"person\": 3, \"car\": 0, \"transaction\": 0}. "
"Make sure that the JSON contains the numbers that the user requested. If the user asks for specific attributes, like 'surname', 'model', etc., "
"ignore this information and generate JSON objects with the same fields as in the schema. "
"Please use double quotes for JSON keys and values. "
)
sy***essage_for_items = "Please try to avoid generating the same JSON object***ultiple times." 步骤4: 使用结构化输出生成(JSON 模式 + XGrammar)
现在,可以加载 OpenVINO™ 模型并运行 逐词级(token-level)结构化输出解码。
通过在生成配置中附加你的 JSON Schema(即 StructuredOutputConfig),OpenVINO™ GenAI 将在底层自动调用 XGrammar,在每一步解码时强制校验输出的合法性,从而确保生成结果始终是格式正确的 JSON。
from openvino_genai import LLMPipeline, GenerationConfig, StructuredOutputConfig
pipe = LLMPipeline(arg***odel_dir, 'GPU')
config = GenerationConfig()
config.max_new_tokens = 300
while True:
prompt = input('> ')
pipe.start_chat(sy***essage)
config.structured_output_config = StructuredOutputConfig(json_schema = json.dumps(ItemQuantitie***odel_json_schema()))
config.do_sample = False
res = json.loads(pipe.generate(prompt, config))
pipe.finish_chat()
print(f"Generated JSON with item quantities: {res}")
config.do_sample = True
config.temperature = 0.8
pipe.start_chat(sy***essage_for_items)
for item, quantity in res.items():
config.structured_output_config = StructuredOutputConfig(json_schema = json.dumps(item***ap[item].model_json_schema()))
for _ in range(quantity):
json_strs = pipe.generate(prompt, config)
print(json.loads(json_strs))
pipe.finish_chat()
最后,你可以通过以下命令运行结构化输出文本生成的示例代码:
python structured_output_generation.py model_dir
在一台Arrow-lake AI PC上, 使用Qwen3-1.7B-int4-ov 模型运行结构化输出的效果如下所示:
查看视频
自OpenVINO™ 2025.3 版本起,OpenVINO™模型服务器(OVMS) 也已支持结构化输出。详细说明可参见:https://docs.openvino.ai/2025/model-server/ovms_structured_output.html。
我们将在下一篇博客中分享如何使用OVMS 获取结构化响应,并将其应用于智能体AI的工具调用场景中。敬请期待!
小结
随着 AI 应用从聊天机器人逐步演进到多工具协作的智能体,结构化输出(SO) 已成为不可或缺的能力——开发者需要模型能够直接生成机器可读、符合预定义模式(schema)的结果,以便无缝对接代码和 API。
借助 OpenVINO™ GenAI,你现在可以“开箱即用”地获得可靠的结构化解码能力。自 2025.3 版本起,OpenVINO™ 通过 XGrammar 实现了高效的 SO 支持,确保每一次生成都快速、有效、可直接使用。无论是在 AI PC 本地运行、边缘设备上部署,还是通过 OVMS 提供服务,你都可以用几行代码轻松启用结构化输出——没有格式错误的 JSON,没有重试的麻烦,只有正确与高效,全面释放英特尔平台的潜能。
立即上手,畅享编码吧。
延伸阅读
xgrammar介绍:https://github.com/mlc-ai/xgrammar?tab=readme-ov-file
本文示例代码出处 :https://github.com/openvinotoolkit/openvino.genai/blob/master/samples/python/text_generation/structured_output_generation.py
————————————————