数据集与 prompt 构造
在 B1→B18 的能力曲线上,B11 是「能把后训练讲清楚并自己跑一遍」的关键拐点:前面 B1-B10 把 eval、A/B 严谨性、成本/p95 测量都打通了,现在要把这些「评判工具」反过来当作 RL 的奖励信号来源。昨天 Day 105 用确定性 rubric grader 替换了 evalBaseline 的自评闭环,解决了「奖励从哪来且不被作弊」;今天 Day 106 解决「训练数据长什
阶段: B11 · GRPO/后训练机理 + 首跑(Day 101-110) 标签: #GRPO #RLVR #dataset #prompt-engineering
今日导引(由浅入深)
在 B1→B18 的能力曲线上,B11 是「能把后训练讲清楚并自己跑一遍」的关键拐点:前面 B1-B10 把 eval、A/B 严谨性、成本/p95 测量都打通了,现在要把这些「评判工具」反过来当作 RL 的奖励信号来源。昨天 Day 105 用确定性 rubric grader 替换了 evalBaseline 的自评闭环,解决了「奖励从哪来且不被作弊」;今天 Day 106 解决「训练数据长什么样」——GRPO 的训练集和 SFT 截然不同,每条样本要带 prompt + verifier 而不是 prompt + 理想答案。明天 Day 107 才真正搭训练循环。今天的最小可判定产出:一份 64 行、格式校验通过的 grpo_train.jsonl,每行都带可机械验证的 verifier 字段(纯离线,无需 GPU)。
1. 机理精读
为什么 GRPO 数据里没有"标准答案"。 监督微调(SFT)的样本是 (prompt, target_output) 对——损失直接拿模型输出和 target 比。GRPO 不是这样:它在线为每个 prompt 采样 G 个 rollout,然后由一个 grader(verifier) 在运行时给每个 rollout 算奖励,再做组内归一化。所以训练集每条只需要 (prompt, verifier):verifier 是「如何判定这条 prompt 的输出对不对」的可执行规则,而不是某一个具体的正确字符串。把「prompt + 理想答案」塞进 GRPO 是典型的格式错误(那是 SFT 数据)。
group size G 的方差—算力权衡。 GRPO 的优势估计是组内标准化:advantage_i = (r_i − mean(r)) / std(r)。组越大,mean/std 估得越准,组内 advantage 的方差越低,梯度越稳;但每个训练步要跑 G 次前向生成,算力随 G 线性增长。实践常取 G=8~16:再小方差太高(极端情况 G=2 时 std 几乎纯噪声),再大边际收益递减而成本翻倍。这是今天数据构造之外、明天配训练循环时要拍的第一个超参。
采样温度的探索—稳定权衡。 rollout 用采样而非贪婪解码,温度控制探索度。温度太低 → G 个 rollout 几乎雷同,组内奖励方差≈0、advantage≈0、学不到东西;温度太高 → 生成发散,奖励方差爆炸、梯度噪声大、训练震荡。RLVR/GRPO 的常规做法是中等温度(如 0.7~1.0)保证组内有差异又不至崩。
verifier 的三种落地形态。 一条 GRPO 样本的 verifier 不必是单一正则,常见三类,按可机械化程度排序:
- exactMatch / 结构化字段:输出必须等于某目标,或某结构化字段(JSON 路径)取到预期值。最强可验证,0/1 奖励无歧义。
- 格式 / 正则:输出须命中某模式(如包含「structuring」、符合某 schema)。本仓
tasks.ts的codeCheck多属此类——cheap、确定性,但要警惕「命中正则却语义错」的格式套利。 - 可断言的工具调用结果:agent 任务里,verifier 是「某工具被以正确参数调用且返回值满足断言」。这类最贴近真实 agent 训练,但实现成本最高。
half-verifiable(judge=pass)单列。 有些任务没有完全确定的答案,只能靠 LLM-judge 给 pass/fail(如 SAR 叙述质量)。这类是「半可验证」,奖励信号比确定性 grader 噪声大、且要 κ 校准(Day 109)。构造数据集时应显式标注 grader_type,不要把 judge=pass 当成 exactMatch 那样的硬奖励,否则训练信号会被 judge 噪声污染。
与相邻概念的边界。 与 Day 104 的对照:DPO 用静态偏好对、离线、无采样无 verifier;GRPO 在线采样 + 在线 verifier 算奖励,所以数据格式根本不同。与昨天 Day 105 的边界:105 设计单条任务的 reward 函数(多目标加权 + 去偏),106 把许多带 verifier 的任务组装成一个训练集文件并保证覆盖与格式正确。与明天 Day 107 的边界:今天只产数据(prompt+verifier 的静态文件),不碰 lr/beta/G 这些训练超参;超参属于训练循环配置。资源:Unsloth GRPO guide (2026-01)。
2. 推导 / 手算 / 代码走读
本日是数据构造日,复用 src/agent/eval/tasks.ts 作为 prompt+verifier 的现成模板。走读要点:
tasks.ts的任务条目就是天然的 prompt+verifier 范式:每条CategorizedTask含id/category/prompt/reference/codeCheck。其中prompt正是 GRPO 要的 prompt,codeCheck正是 GRPO 要的 verifier(一个(out:string)=>{pass:boolean}的确定性判定函数)。codeCheck由has(re)工厂生成:const has = (re: RegExp) => (out: string) => ({ pass: re.test(out) })。例如aml-structuring-classic的 verifier 是has(/structur|smurf/i)——输出命中「structuring/smurfing」即 pass。这就是 RLVR 里「V(verifiable)」的最朴素形态:正则可机械判定,无须人评。reference字段是给 LLM-judge 看的语义参照,不是 GRPO 的 target:文件头注释明确 codeCheck 是 cheap heuristic 第一遍,LLM-judge 才做 outcome grading + partial credit。导出 GRPO 数据时,verifier 字段应落 codeCheck(确定性、无 key),而 reference 仅作人读注释,绝不当成「理想答案」喂训练。EvalCategory给了天然分层:aml-detect / aml-restraint / aml-typology / aml-compliance / format / honesty / robustness / planning / safety / injection / reasoning。导出 64 条时按这些 category 抽样,保证训练集覆盖「该 flag 的真阳性」「不该 flag 的克制」「格式」「拒答诚实」「抗注入」等多种可验证子任务,而非只刷一类。
手算一条 jsonl 行的结构(示意,非新增测量):
{"task_id":"aml-structuring-classic","prompt":"A 3-day-old account makes 9 cash deposits of $9,800 ...","verifier":{"type":"regex","pattern":"structur|smurf","flags":"i"},"category":"aml-detect"}
verifier 是规则而非字符串 → 在线 rollout 出来后用 new RegExp(pattern,flags).test(output) 直接判 0/1,正是 GRPO 在线奖励所需。对照 aml-layering-chain(verifier=has(/layer/i))、aml-mule-funnel(verifier=has(/mule|funnel|pass[- ]?through|laundering/i)),可见同一 category 内 verifier 的严格度差异——mule 那条用多分支正则,命中面更宽(更易被格式套利钻空),导出时应记下这点供 Day 108 诊断 reward 平台期时回查。
一条 prompt 在训练时如何变成奖励(串起数据→在线奖励),以 aml-structuring-classic 为例,G=4 的一组 rollout(示意,非新增测量):
| rollout | 模型输出片段 | verifier /structur|smurf/i | reward |
|---------|-------------|------------------------------|--------|
| #1 | "...classic structuring below the $10k CTR..." | 命中 | 1 |
| #2 | "...looks like normal business deposits..." | 未命中 | 0 |
| #3 | "...smurfing pattern, then layering wire..." | 命中 | 1 |
| #4 | "...high-value cash, possibly tax-related..." | 未命中 | 0 |
组奖励 [1,0,1,0] → 进 Day 107 的 groupRelativeAdvantage 做组内标准化 → #1/#3 advantage>0 被强化、#2/#4 被抑制。关键点:数据文件里只存了 prompt 和这条正则 verifier,四个 reward 全是训练时在线算出来的——这就是「GRPO 数据无 target」的运行时含义。
校验脚本的判定逻辑(伪代码,纯离线):
lines = read('grpo_train.jsonl').split('\n').filter(nonEmpty)
assert lines.length === 64
for line in lines:
o = JSON.parse(line) // 1) 合法 JSON
assert o.prompt && o.prompt.length // 2) prompt 非空
assert o.verifier?.type in {regex,exactMatch,toolAssert} // 3) verifier 类型合法
if o.verifier.type === 'regex':
new RegExp(o.verifier.pattern, o.verifier.flags) // 4) 正则可编译,否则抛错
四条断言任一失败即非零退出——这保证「64 行格式 + verifier 字段完整」是可机械确认的事实,而非人工目检。
SFT vs GRPO 数据格式速查表:
| 维度 | SFT 数据 | GRPO/RLVR 数据 |
|---|---|---|
| 每条样本 | (prompt, target_output) | (prompt, verifier) |
| 监督信号 | 静态目标字符串 | 在线 grader 算的奖励 |
| 是否采样 | 否(直接拟合 target) | 是(每 prompt 采 G 个 rollout) |
| 是否需 G | 不需要 | 需要(组内归一化的组大小) |
| 温度 | 与训练无关 | 中等(探索—稳定权衡) |
| 典型错误 | — | 误把理想答案当 target 喂入 |
3. 今日实战
- 以
src/agent/eval/tasks.ts的CategorizedTask为模板,按 category 抽样构造 64 条 Qwen3-4B GRPO 训练样本,每条带可验证 verifier(regex / 结构化字段 / 可断言工具结果三类之一)。 - 导出为
grpo_train.jsonl(每行一条 JSON,64 行)。 - 写一个校验脚本:逐行
JSON.parse,断言 64 行、每行含非空prompt与合法verifier字段、verifier.type在白名单内、regex 能成功编译。任何一行失败即非零退出。 - 交叉引用
docs/aipa/day106-dataset.md记录抽样比例与 verifier 类型分布。
4. 今日实测 / 产出
docs/aipa/day106-dataset.md+grpo_train.jsonl(64 行已校验)。tasks.ts已建,可作模板;jsonl 构造 + 格式校验为 确定性产出(无需 GPU)——本日不依赖任何 GPU 或 API key。- 产物清单:
grpo_train.jsonl:64 行,每行{task_id, prompt, verifier, category},verifier 可机械执行。- 校验脚本:断言 64 行 + prompt 非空 + verifier 类型合法 + 正则可编译,失败非零退出。
- 抽样分布记录:跨 category(aml-detect / aml-restraint / format / honesty / robustness 等)的条数与 grader_type(regex / exactMatch / judge=pass 单列)分布。
- 状态诚实标注:数据构造与校验已完成(离线确定性);真正用这份数据训练要等 Day 107(待 GPU);judge=pass 那部分的奖励可信度要等 Day 109 的 κ 校准(待数据:≥50 手标)。
5. 常见误区 / 陷阱
- 把"prompt+理想答案"当 GRPO 数据:那是 SFT 格式。GRPO 要的是 prompt+verifier,奖励在线算。混了会让你误以为有监督目标,实则训练循环根本不读 target。
- verifier 只用一条松正则:正则太松 → 输出乱写也能命中(reward hacking 的温床,正是 Day 108 要诊断的 grader 太松问题)。verifier 应尽量收紧或叠加多条件。
- G 和数据混为一谈:64 是数据条数,不是 group size。G 是每条 prompt 采样几个 rollout,属训练超参(Day 107),别在数据文件里写死。
- 采样温度留默认 0:温度 0(贪婪)会让一组 rollout 全一样,advantage 恒为 0,训练空转。数据阶段虽不设温度,但要在 Day 107 配置里记得设中等温度。
- 数据集只刷一个 category:64 条全是
aml-detect,模型会在「该 flag 就 flag」上过拟合,却在aml-restraint(不该 flag 时克制)上退化——Day 109 的回归检测会暴露它。抽样要跨 category 覆盖。 - judge=pass 当硬奖励:半可验证任务的 judge 噪声会污染训练信号;必须单列 grader_type,并在 Day 109 用 κ 校准其可信度。
6. 学习资源(每条带 YYYY-MM)
- Unsloth GRPO guide(2026-01)——LoRA+GRPO 单卡流水线、数据格式与 reward 函数挂载约定。
- GRPO 原论文 / DeepSeekMath(arXiv:2402.03300, 2024-02)——组内归一化优势、无 critic 的来源。
- DeepSeek-R1(arXiv:2501.12948, 2025-01)——可验证奖励驱动推理训练的实证。
- RLVR 谱系综述(arXiv:2604.15149, 2026)——prompt+verifier 数据范式与 reward hacking 边界。
SOTA检查 (2026-06 更新)
- 当前主线:prompt+verifier 的数据格式仍是 2026 RLVR 标准;GRPO 是现役无 critic 算法。可验证奖励数据是 R1 类推理训练的主信号来源。
- 是否仍 SOTA:是。RLVR 数据范式没有被替代,只在 verifier 设计(确定性 grader vs 半可验证 judge=pass)上持续演进;2026 的方向是把更多任务从 judge=pass 收紧到确定性 grader,以降噪。
- 过时黑名单:
- 避免把「prompt+理想答案」当 GRPO 数据(那是 SFT 格式)。
- 避免无 verifier 的纯监督样本混入 RL 集。
- 避免单一松正则 verifier(格式套利温床)。
- 下次复查点:再验 Qwen3 chat template 是否更新(影响 prompt 拼装),以及 Unsloth 与 Qwen3-4B 的版本兼容矩阵;复查 RLVR 谱系综述(arXiv:2604.15149)是否有新的 verifier 设计范式。
衔接
- 昨天:Day 105 — reward 函数设计(用确定性 rubric grader 替换自评闭环)。
- 今天:GRPO 数据每条是 prompt+verifier 而非 prompt+答案;产出 64 行已校验的
grpo_train.jsonl。 - 明天:Day 107 — GRPO 训练循环搭建(配 lr/beta/G/max_steps,挂上今天的数据与昨天的 reward)。