LFM2.5-350M GRPO 微调将 IFStruct 得分提升至 29.7%
TL;DR
仅用 100 步和约 500 个样本对 3.5 亿参数的 LFM2.5 模型进行分组相对策略优化(GRPO)微调,即可将其 IFStruct 结构化输出合规率从 22.6% 提升至 29.7%,提升了 7.1 个百分点,显著缩小了与更大模型之间的差距。
为什么结构化输出合规性至关重要
结构化输出——返回语法正确且符合指定模式的数据——是将大语言模型集成到下游系统中的前提条件。衡量原始推理能力的基准往往忽略了这一要求;IFStruct 专门衡量模式遵循情况,因此成为现实部署可行性的可靠代理。
"模型是否能可靠地返回请求格式和结构下有效的、可解析的输出——即模式合规性——往往是决定其能否被集成到下游系统中的关键因素。" – Hugging Face 博客
LFM2.5‑350M 的基线评估
- 模型:
LiquidAI/LFM2.5-350M(GGUF BF16),通过llama.cpp提供服务。 - 环境:使用免费层级的 Colab/Kaggle GPU 提供服务;评估在一台 MacBook Pro(Apple M5 Max,36 GB)上使用 IFStruct 评估器完成。
- 结果:总体通过率为 22.6%(2000 个样本中通过 452 个)。详细分解如下:
- JSON:18.0%
- YAML:27.2%
- 包装键:28.5%
- 纯列表:16.6%
- 常见错误:缺少必填字段、项目数量错误、类型不匹配以及未闭合的代码块。
这些数据与原始 IFStruct 发布时报告的 21.1% 非常接近,确认了基线的可靠性。
GRPO 微调流程
整个工作流已作为公共笔记本发布在 GitHub 上,可在免费层级 GPU 上运行。
训练数据
- 来源:
nvidia/Nemotron-RL-instruction_following-structured_outputs(约 500 个样本)。 - 增强:
- 40% 的提示添加了“将输出包含在 fenced 代码块中”的指令,教会模型遵守格式要求。
- 20% 被转换为顶层数组任务,鼓励生成正确的纯列表并符合项目数量要求。
模型与 LoRA 适配器
lora_config = LoraConfig(
r=16,
lora_alpha=32,
bias="none",
task_type="CAUSAL_LM",
target_modules=[
"q_proj", "k_proj", "v_proj", "out_proj", "in_proj",
"w1", "w2", "w3",
],
)
- 训练约 600 万个参数(约占 3.5 亿模型的 1.66%)。
奖励函数
三个标量奖励(0–1)评估结构正确性:
- json_format_reward – 解析输出并检查请求格式(fenced 与原始);完全符合格式得满分,格式错误但可解析得 0.2 分,无法解析得 0 分。
- field_count_reward – 比较顶层字段数量与预期数量;不匹配时线性衰减。
- schema_validation_reward – 根据提供的 JSON Schema 进行验证,对缺失必填键和约束违规进行惩罚。
组合奖励为加权和,权重为 reward_weights = [1.0, 0.5, 2.0]。
训练配置
training_args = GRPOConfig(
output_dir="./outputs/lfm25-350m-nemotron-schema-grpo",
learning_rate=5e-5,
max_steps=100,
warmup_steps=10,
num_generations=8,
per_device_train_batch_size=4,
gradient_accumulation_steps=8,
steps_per_generation=2,
max_completion_length=1024,
mask_truncated_completions=False,
temperature=1.1,
beta=0.01,
reward_weights=[1.0, 0.5, 2.0],
logging_steps=1,
save_steps=100,
)
- 100 次优化步骤,每组提示生成 8 个完成结果,KL 惩罚项较小(
beta=0.01)。 - 在 16 GB GPU 上训练时间不到一小时即可完成。
合并 LoRA
训练完成后,将 LoRA 适配器合并回基础权重,并保存为单个检查点,可直接转换为 GGUF 格式用于 llama.cpp 服务。
微调后的 IFStruct 结果
- 模型:合并的 GRPO 微调检查点转换为 BF16 GGUF 格式。
- 服务:与基线使用相同的
llama.cpp参数,仅更换别名和端口。 - 结果:总体通过率为 29.7%(2000 个样本中通过 594 个)。
- JSON:31.9%(↑13.9 个百分点)
- YAML:27.5%(↑0.3 个百分点)
- 包装键:29.7%(↑1.2 个百分点)
- 纯列表:29.7%(↑13.1 个百分点)
- 错误分布变化:缺少字段的错误减少,但仍存在显著的类型不匹配和多余字段问题。
| 指标 | 基线 | GRPO 微调后 | Δ |
|---|---|---|---|
| 总体 | 22.6% | 29.7% | +7.1 |
| JSON | 18.0% | 31.9% | +13.9 |
| YAML | 27.2% | 27.5% | +0.3 |
| 包装键 | 28.5% | 29.7% | +1.2 |
| 纯列表 | 16.6% | 29.7% | +13.1 |
提升集中在奖励信号所针对的方面——JSON 格式和纯列表生成——证实了 GRPO 方法的有效性。
含义与启示
- 成本效益高 – 仅用约 500 个样本进行 100 步 GRPO 运行,成本低于一次免费层级 Colab 会话,却实现了结构化输出合规性 7 个百分点的绝对提升。
- 模型规模对齐 – 微调后的 3500 万参数模型性能接近 20 亿参数模型(Qwen3.5‑2B 在 IFStruct 上得分为 33.15%),同时仍显著更小且运行成本更低。
- 奖励设计至关重要 – 对格式、字段数量和模式验证的显式奖励直接转化为目标输出形式的更高通过率。
- 可复现性 – 所有脚本、数据链接和转换步骤均公开可用,使研究人员能够复现或扩展实验,适用于其他模型或数据集。
如何复现
- 按博客所述安装
uv、llama.cpp和 IFStruct 评估脚本。 - 克隆笔记本仓库,使用提供的
GRPOConfig运行 GRPO 微调单元格。 - 合并 LoRA 适配器,将检查点转换为 GGUF 格式,并使用
llama-server提供服务。 - 对已服务的端点执行 IFStruct 评估器。
所有命令和 URL 均在原始 Hugging Face 博文中逐字复现。
局限性
- 训练数据(约 500 个样本)仅为大规模 RLHF 所用数据的极小部分,因此提升很快趋于饱和。
- YAML 输出的改进较为有限,表明当前奖励权重更偏向 JSON 格式。
- 该基准仍反映的是合成任务;真实世界集成可能暴露更多边缘情况。
未来方向
- 扩展训练集,加入更多样化的模式和格式(如 XML、CSV),以提升合规性广度。
- 尝试不同的奖励权重或增加额外约束(如逻辑一致性)。
- 将相同的 GRPO 流程应用于其他紧凑模型(如 2000 万参数变体),以评估可扩展性。
参考资料
- 模型:
LiquidAI/LFM2.5-350M– https://huggingface.co/LiquidAI/LFM2.5-350M - 基准:IFStruct v1.0 – https://huggingface.co/datasets/LiquidAI/ifstruct-v1.0
- 训练数据:
nvidia/Nemotron-RL-instruction_following-structured_outputs - GRPO 实现:TRL 库 – https://huggingface.co/docs/trl/en/index
- 完整笔记本:https://github.com/Liquid4All/cookbook/blob/main/finetuning/notebooks/grpo_with_trl_ifstruct.ipynb
- 原始 IFStruct 博客:https://www.liquid.ai/blog/ifstruct-v1.0