@akshay_pachaar: https://x.com/akshay_pachaar/status/2064700531600458093
摘要
本文介绍了如何使用GRPO微调LLM(Qwen3-8B)以实现可靠的JSON结构化输出,将模式准确率从62%提升至82%,超越了GPT-4.1的58%。
查看缓存全文
缓存时间: 2026/06/10 13:50
训练LLM生成可靠的结构化输出
你向语言模型请求JSON,大多数时候它都能正常工作。但偶尔,某次响应会出错。数字变成了字符串,或者模型把JSON包裹在解释性文本里,导致解析器崩溃。这个微小失败率就是问题的全部。输出将用于函数调用或数据库写入,看起来像有效JSON和实际是有效JSON是两码事。下游代码只有在其崩溃时才知道它接收到了什么。这就是结构化输出的含义:模型返回的形状固定且匹配模式的数据,而不是恰好读起来正确的自由文本。如今,智能体、工具调用和数据管道都依赖于此。模型是为代码运行而写,而非给人阅读。实现可靠的结构化输出很困难,通常的答案是给模型更多东西:你添加示例、收紧提示、在正确输出上微调。这有点帮助,然后停滞。瓶颈从来不是数据量,而是目标。DeepSeek-R1展示了一条绕过此问题的路径。训练一个强模型过去需要标注管道、偏好对和一整支标注团队。DeepSeek用一个Python函数取代了这一切,该函数检查答案是否正确。如果你能用代码定义正确性,就不需要其他东西。这就是GRPO背后的理念。模型不再从示例中学习,而是从你编写的奖励函数中学习。对于每个提示,它生成一些候选答案。奖励函数对它们打分,模型被推向分数更高的答案。
GRPO逐步详解:从数据准备到响应生成、奖励计算和损失计算
(此处应有图解,但原文无图)
在本教程中,我将用GRPO微调Qwen3-8B以进行JSON提取。循环从本地笔记本驱动,模型在远程H200上训练。奖励函数只做一件事:检查每个输出是否能解析并匹配模式。整个循环由本地Python进程驱动,而采样和梯度步骤在远程H200上运行。
模式有效的输出从基础模型的62%提升到训练后的82%,超过了同一评估集上GPT-4.1的58%。在开始构建之前,先了解为什么显而易见的方法会停滞,这有助于理解后续所有内容为何有效。
为什么SFT会遇到天花板
SFT通过复制示例来学习。向它展示正确的补全,它就能产生看起来像它们的输出。但看起来像有效JSON和实际是有效JSON是不同的目标。SFT只追逐前者。在token级别,一个有错误字段类型的补全的分数几乎与合法补全相同。更多数据可将模式准确率提升到天花板,然后停滞。
损失是按token衡量的。一个有一个字段类型错误的补全的分数几乎与完美补全相同。所以你添加更多示例。数字上升,然后变平,因为限制是目标,而不是数据。
针对正确性而非示例进行训练
一旦看到问题,修复方法就很明确:你用代码定义正确,并直接针对该定义训练模型。这就是GRPO所做的。它用奖励函数取代了标注示例。对于每个提示,模型会生成一小批答案,通常是4到8个。你的奖励函数对每个答案打分。
分数在组内进行归一化。然后更新会强化那些得分高于组平均值的答案。这样,模型总是在比较自己的输出之间的相对优劣。它学习的是对你任务来说“更正确”意味着什么,而不是“更像示例”意味着什么。
下面是奖励函数如何为同一提示的三个不同输出打分:
- 不能解析为JSON的输出得0分。
- 能解析但不符合模式的输出得0.5分。
- 能解析且匹配模式的输出得1.0分。 那个0.5分非常关键,它在训练早期保持了有效结构这一信号。没有它,有效JSON但字段类型错误的输出将得0分,与完全垃圾的输出相同。模型将损失一个重要信号:有效的结构已经是进步。0.5分给了训练一个努力的方向。
为什么GRPO需要真正的基础设施
GRPO比SFT更重。在一个8B模型上,它需要H200并且运行数小时。每一步,它都要为每个提示生成多个补全,对它们全部打分,然后更新权重。这在整个数据集上重复多次。这不是你可以在笔记本电脑上运行的东西。
还有一个SFT从未有的时序问题。在rollout期间,模型从其当前权重采样答案。在训练期间,这些相同的权重在不断变化。不同步的话,推理部署会落后于训练器,rollout会从过时权重采样。Fireworks在每一步之后重新同步,因此补全始终来自当前模型。
如果推理端和训练端不同步,你会从过时模型采样,并在当前模型永远不会给出的答案上训练。这是大多数自定义强化学习设置失败的地方。Fireworks的训练API处理了这两方面。你在自己的机器上用Python编写训练逻辑,他们的基础设施完成其余工作:配置GPU、运行前向和反向传播、保存检查点,并在每一步后重新同步推理部署。
设置分三步:编写奖励函数、上传数据集、配置运行。让我们逐一进行。
构建训练循环
Fireworks在其训练API文档中记录了完整设置,包括rl_loop,这个配方为你运行整个GRPO循环。克隆cookbook并安装训练依赖。
第一步:编写奖励函数
这是唯一定义你任务的地方。模式定义了正确输出应该是什么样子,而score()函数检查每个补全是否匹配。对于发票提取,我从原始文本中提取四个字段:vendor、date、amount和currency。jsonschema在一次调用中处理类型检查、必填字段和任何嵌套规则。对于不同任务,比如SQL或工具调用格式,你换用新模式。score()函数保持不变。
第二步:准备数据集
GRPO不需要标注输出。数据集仅仅是你在生产中会发送的提示。模型在训练过程中自己编写补全,score()随着它们生成而打分。我使用了200个训练提示,涵盖不同的供应商名称、日期格式、金额风格和货币代码。我还预留了50个评估提示,模型从未在这些提示上训练。这里多样性比体积更重要。所有提示都相似会产生一个在面对真实发票变化时崩溃的模型。上传数据集,并等待状态变为READY后训练作业才能使用它。
第三步:配置并运行循环
rl_loop运行整个过程:配置训练器、调度rollout、同步权重,并在运行完成后清理。你通过包装score()函数并将其赋值给rl_loop.reward_fn来连接它。包装器获取补全和数据集行,因此如果需要,你可以访问真实元数据。
以下是一些值得注意的设置:
dataset指向你在第二步上传的dataset_id。Fireworks直接从其存储拉取。completions_per_prompt=4设置GRPO的组大小。生产运行通常使用8到16,这会在每个步骤提供更多信号,但计算成本更高。这里4就足够了。奖励函数足够明确,即使小群体也能显示答案之间的实际差异。weight_sync_interval=1在每一步后重新同步推理部署。这保证rollout从正在训练的确切模型采样。生产运行通常设置为4或8以加快速度。对于200步的短运行,1提供了最紧密的反馈循环,这正是你想要的。- 一个Qwen3的特性需要处理。它默认启用思维模式,并在答案前添加
...块。在评估时通过content.split("")[-1].strip()去除它们。在训练时通过在系统提示中添加/no-think来抑制它们。否则奖励函数会读取推理文本而不是JSON,将所有内容得分为0。
保留评估集上的结果
基础Qwen3-8B在50个保留提示上达到了62%的模式有效性。经过Fireworks H200上的GRPO训练后,微调后的模型达到了82%,超过了同一评估集上GPT-4.1的58%。
以下是基础模型在模型从未训练过的50个提示上的基线运行。基础模型达到了62%的模式有效性,即50个保留提示中的31个。
以下是训练后的相同评估结果:训练后,同一评估达到82%,即50个中的41个,比基础模型提升了20个百分点。
训练后的模型运行在Fireworks的无服务器端点上,每token成本仅为GPT-4.1的一小部分。延迟也更低,因为输出短且可预测。真正的差异体现在混乱输入上。提示式通用模型开始出错,而训练后的模型保持稳定,因为它学习的是约束而非示例。
什么可以迁移到你的任务
这种模式适用于任何你可以用代码检查正确性的任务:必须能解析的SQL、必须匹配形状的API响应、工具调用、必须通过检查器的代码。如果你能对输出打分,你就可以训练模型去追逐那个分数。DeepSeek-R1在前沿规模上证明的道理同样适用于你自己的小任务。你得到的模型练习了你对“正确”的定义,而非记忆它的示例。在它从未见过的输入上,这种差异才是持久的。
完整代码在下面的仓库中,包括奖励函数、训练配置、数据集构建器和评估脚本。
训练API文档 → (链接) 微调代码 → (链接)(别忘了点星🌟)
感谢阅读,并感谢Fireworks对本篇文章的合作支持。
相似文章
多模块 GRPO:组合策略梯度与提示优化的语言模型程序方法
本文提出 mmGRPO,一种多模块扩展的群体相对策略优化(GRPO)方法,通过优化语言模型调用和提示来提升模块化 AI 系统的准确率。实验表明,该方法在各类任务上平均带来 11% 的准确率提升,并在 DSPy 中提供了开源实现。
@akshay_pachaar: 从头开始训练你自己的LLM。这个仓库从头构建了一个GPT风格的Transformer,完全不用高级库…
一个从零开始构建GPT风格Transformer的仓库,不使用高级库,涵盖了从数据预处理到生成的整个过程,并包括SFT和RLHF的指南。
@reach_vb: GPT-5.5 为 Omarchy 4 分支生成了 3 万行 QML 代码,并精准完成了微妙的智能体推理!!
OpenAI 的 GPT-5.5 模型在复杂的智能体任务和代码生成方面显示出显著改进,超越了先前版本以及如 Claude Opus 等竞争模型。
@RuiTheBaker: GPT 5.5级别的排名,但快27倍?!@mixedbreadai
根据早期结果,Mixedbread 的重排序器在 OBLIQ-bench 上达到了 GPT 5.5 级别性能,同时速度快 27 倍。
@lucastech: 真的很酷,看到gpt-oss-20b与我测试过的所有其他模型相比有多大的不同,每种量化都显著…
GPT-OSS-20B模型在量化过程中展现出显著的智能提升,同时保持相似大小,与其他模型不同。