每一轮强化学习喂哪些题,要写成可对比的配置才谈得上复现

一、数据选择是训练的一个自由度,不是清洗的附属步骤
一道题起初难、练一段之后能稳定答对,这件事把一层关系挑明了:同一批题按不同顺序、不同配比喂进去,得到的能力曲线并不相同。换句话说,练什么、怎么练这一层的取值空间,本身就是训练结果的一个自变量。既然是自变量,它就不属于数据清洗的附属步骤,而属于训练配置的一部分。有高校团队把这层数据策略做成开源工具,理由很直接:策略不写出来,不同实验之间就没法比。这句话对做交付的人同样成立,只是主语要换成这一版和上一版。
把它升格到超参数一级,带来的第一个变化是归因顺序。过去结果坏了先查模型与奖励,现在要先把策略这一栏拿掉再判断。第二个变化是文档要求:一个不能被人读出来的策略,等于一个不可比较的策略。
二、四个能各自独立的自由度
| 自由度 | 具体要定的量 | 通常被怎么混掉 |
|---|---|---|
| 选哪些题 | 题池的准入条件、排除条件、按来源与类别的分层比例 | 当成清洗的副产品,排除时不留记录 |
| 按什么难度分布 | 每轮里各难度档占多大比例,难度档由什么判据给出 | 与顺序合在一起调 |
| 什么顺序 | 从易到难、从难到易、按当前通过率滚动、按类别轮转 | 写成随机打乱之后就不再追问 |
| 每题采样几条轨迹 | 单题在本轮的采样条数与该题占用的预算 | 与整体预算混成一个数 |
四个自由度混在一起调,就永远归不了因。这一节要落的结论很窄:任何一个被改动时,另外三个必须能保持不变,所以它们必须分别可配置、分别可记录。做不到分别可配置,后面所有对比都只能算观察。
这四个量之间还会互相折算。把参与的题目数压下去、每题的采样条数提上来,总预算看着没变,训练过程却完全不同:前者是在窄空间里深挖,后者是在宽空间里粗扫。这类折算常被当成等价调整,出了问题又谁都没记在账上。所以每个自由度除了能单独配置,还要能在一次运行里被单独读回来;报告结果时把参与的题目数、每题采样条数与实际消耗一并给出,缺任何一项,曲线就没有可以对照的对象。
三、把策略写成配置:四列与一组可重放坐标
最小写法四列就够:策略名、版本、参数、生效区间。策略名要稳定,同一份策略的每次调整升版本号而不是改名。参数这一列要写成能读回来的具体量,不是一段说明文字。生效区间按训练步或轮次边界给,不按自然时间给,否则同一份配置在不同节奏的作业上含义不同。
可重放的坐标比这四列大一圈:策略名与版本、参数、生效区间,再加随机种子、模型版本、奖励定义。七项里缺任何一项,重跑出来的都不是同一次实验。实践中最常被省掉的是生效区间,因为第一次跑的时候看起来没必要——一个策略从第一步用到最后一步,写不写都一样。问题出在换策略的那一次运行上:没有区间,就没人能确定曲线上的哪一段是谁做出来的。
四、对比公平要固定的是五件事
一份策略相对另一份有效,前提是差异只来自策略本身。要固定五项:同一预训练起点、同一批题池、同一预算、同一奖励定义、同一采样数。
- 预训练起点不同,比的是两个模型,不是两个策略。
- 题池不同,即使题目总数一样,重叠部分的难度构成也可能完全不同。
- 预算不同,落后的那一个可能只是算力少,这是把课程效果说错的最常见来源。
- 奖励定义不同,策略只是换了被强化的行为,曲线变化与选哪些题无关。
- 采样数不同,通过率的估计精度就不同,看着的差距可能全在噪声里。
采样预算要双报:本轮参与的题目数量,以及每题的采样条数。只报其中一个就会误导判断。题少而每题采样多,曲线看起来收敛快,但覆盖窄;两个维度一起给,才知道这条曲线是在什么形状的空间上得到的。
五、难度是动态量,分桶判据有两种
用训练开始前打好的静态难度桶去做课程,会越训越偏:桶里渐渐全是已经被答对的题,暂时做不了的题一直沉在最难那一档,永远轮不到。原因是难度不是题目的固有属性,而是题目与当前模型之间的关系。
可用的判据有两种。一种按模型当前通过率滚动更新,贴着真实能力,代价是同一道题在不同时刻属于不同档,跨时刻的对比要额外记账。另一种按题目自身特征分桶,比如题目长度、所需步骤数、要用到的工具种类,稳定可比,代价是它衡量的其实是复杂度而不是难度。两种都成立,但必须承认它们不是一回事,也不能在同一次比较里混用——一旦混用,两边的曲线就不再描述同一个量。
滚动分桶有两个陷阱。更新太频繁,题目在档之间来回跳,策略跟着震荡,看上去像课程不起作用;更新太慢,被答对的题长期占着名额,一批题沉底到训练结束。这两处没有可以直接抄的数值,只能在自己的题池规模与单轮时长上定一个可复核的节奏,并且把节奏本身写进配置,让它成为被比较的对象而不是隐含前提。
滚动更新还带一条记录要求:每个时刻的档位归属要落库,边界时刻也要记,不能只留最后一版。事后重算一次课程曲线,靠的就是这份分档历史;只存最终版,等于把课程变成一件只在当时有效、之后再没人能核对的事。同一条要求也适用于排除清单——某一轮被移出题池的题目,要能在曲线上找到它被移走的那个边界。
六、三张表分离、落快照、连排除理由一起存
工程上最省事的三件做法:题池、策略、预算三张表分离,各自有版本,谁引用谁写在字段里,而不是把题目清单抄进策略文本;每次运行落一份策略快照,把当时生效的配置原样存下且不可事后修改,配置被改是常态,没有快照就没法解释历史结果;被排除的题与排除理由一起存下来。
第三件的价值要到事后才显现。复盘时最难回答的往往不是当时用了哪批题,而是为什么排除了那批题;没有排除记录,就无法向客户解释为什么这一版比上一版贵。排除理由要写成可判定的类别——题目本身有歧义、答案不可验证、与已有题目重复、超出本轮预算——而不是备注栏里的一句话。
这份记录同时也是对外的材料。要说清一次训练为什么更贵,可拆解的方向只有三个:参与的题目更多、每题采样更重,还是策略本身迭代了更多轮。三个方向都能从快照与三张表里读回来,读不回来就只能报一个总价,而总价在任何一次比价里都站不住。
失败复盘要有固定顺序,倒着做最浪费时间:先看策略配置是否变化,包括版本与生效区间;再看题池版本,重点看排除清单的变动;再看奖励定义与判定口径;最后才怀疑模型本身。多数归因错误来自一上来就动第四项。
这套做法不只有做强化学习才用得上。评测集、微调数据、提示词模板同样是交付链路里的自由度,同样要版本化,同样要附排除清单。洹拓内部留了一条判据:一个实验如果换个人重跑、要问三个问题才能把配置对齐,那就说明策略没有被写成配置,只是被记在某个人脑子里。