Qwen-JSON:把结构化输出变成一个可训练的问题
很多模型都能在提示词里说“请只输出 JSON”,但真正把它接进程序之后,问题会立刻变得具体:字段有没有缺失,类型是不是正确,外层有没有多余文字,答案本身是不是可信。
所以结构化输出不只是提示词问题,也可以被拆成数据、奖励和评估问题。
这个公开模型是什么
我的 Freakz3z/Qwen-JSON 模型仓库 把目标集中在 JSON 结构化输出上。模型卡将它描述为 RL-Struct,并列出这些关键信息:
Base Model:Qwen/Qwen3-4B-Instruct-2507
Training:GRPO + LoRA
Tasks:JSON Recipes、GSM8K-JSON、ToolUse
License:Apache-2.0
它的基本思路是使用 GRPO 和多维奖励,让模型同时关注结构、格式、有效性、正确性和长度,而不是只依靠 constrained decoding 在推理阶段强行限制 token。
模型卡中的结果是项目页面报告的实验结果。本文不把这些数字当成我在本地重新复现过的结论。
JSON 可靠性至少有五层
一个看起来像 JSON 的字符串,距离“可用”还有很远。可以按下面的顺序检查:
1. 能否被 JSON parser 解析
2. 顶层对象和字段类型是否正确
3. 必填字段是否完整
4. 字段值是否满足任务约束
5. 最终答案是否正确且长度合理
例如:
{"name": "番茄鸡胸肉", "nutrition": "Calories: 380"}
它可能完全符合语法,但 nutrition 里的数值未必正确,也可能缺少数据集要求的其他字段。因此格式奖励只能是起点,不能代替语义评估。
为什么选择 GRPO
对于同一个 prompt,模型可以采样多条回答:
回答 A:无法解析
回答 B:JSON 可解析,但字段缺失
回答 C:结构完整,答案正确
回答 D:结构完整,但答案错误
如果验证器能给这些回答打分,就可以在组内形成相对优势,让模型提高类似 C 的回答概率。
GRPO 相比 PPO 的一个重要区别,是不必额外维护 critic 来估计 value。它不代表训练没有成本:同一个问题需要生成多条回答,奖励函数和采样策略也会直接影响训练信号。
多维奖励怎么拆
一个简单的奖励设计可以是:
JSON 可解析 -> +1
Schema 验证通过 -> +1
必填字段完整 -> +1
答案正确 -> +2
额外文本 -> -1
无意义冗长 -> -0.5
这种分层设计比直接写一个黑盒总分更容易排查问题。训练日志中应该保留每个分项,否则总 reward 上升时,很难知道模型到底学会了什么。
奖励还需要防止几个常见投机:
- 只输出固定模板,不处理问题内容
- 用冗长文字提高碰到关键词的概率
- 通过边界格式绕过解析器
- 在训练任务上高分,换一种问法就失败
页面中报告了什么
当前模型卡的性能表列出:
| 方法 | Structural Acc. | JSON Validity | Content Acc. | | --- | ---: | ---: | ---: | | GPT-3.5 Zero-shot | 45.5% | 82.1% | 88.0% | | LLaMA-3-8B SFT | 78.2% | 85.4% | 86.0% | | RL-Struct | 89.7% | 92.1% | 84.5% |
这张表很有意思的一点是:结构准确率和内容准确率不是同一个指标。一个方法可能更会输出合法结构,却没有同步提高内容正确率。
这也是我觉得结构化输出值得单独研究的原因:不能只看“能不能解析”,还要继续问“解析出来的东西有没有用”。
一条实际使用路径
模型卡提供了 Transformers、llama.cpp、vLLM、Ollama 等使用方向。对于本地测试,可以先从最小调用开始:
from transformers import pipeline
pipe = pipeline("text-generation", model="Freakz3z/Qwen-JSON")
messages = [
{"role": "user", "content": "请输出一份简单的 JSON 食谱"},
]
result = pipe(messages)
print(result)
推理时仍然应该在应用层做 JSON parse、schema validation 和失败重试。模型训练得更可靠,不等于下游程序可以取消校验。
从模型到系统
一个结构化输出模型真正接入工具调用或业务系统后,链路更接近:
用户请求
-> 模型生成
-> JSON 解析
-> Schema 校验
-> 业务规则校验
-> 执行动作或返回结果
任何一层失败,都应该有明确的 fallback,而不是把一段未经验证的文本直接传给下游系统。
对于 ToolUse 场景,还需要额外校验工具名、参数类型、权限和高风险操作。结构正确只是安全边界的一部分。
这个项目留下的问题
Qwen-JSON 这个方向仍然有几个值得继续观察的问题:
- 结构奖励变高后,内容准确率是否同步提高
- 模型能否迁移到没有见过的 schema
- 复杂嵌套 JSON 是否会让错误率重新上升
- GRPO 的采样成本和推理收益是否值得
- 结构化训练会不会损害普通对话能力
这些问题不能只靠模型卡上的一个总分回答,需要把数据、验证器、采样参数和评估集一起公开,才能判断方法是否真正稳定。
结语
Qwen-JSON 对我来说更像一个明确的实验对象:把“模型输出不稳定”拆成可以观察的结构、格式、语义和长度问题,再用 GRPO 把部分验证逻辑变成训练信号。
模型不会因为看到“只输出 JSON”就自动理解什么叫可靠。可靠性最终要落在可执行的 parser、schema、验证器和失败处理上。
参考:Freakz3z/Qwen-JSON 模型卡、DeepSeekMath 论文 和 TRL GRPOTrainer 文档。