修改共享代码
大多数贡献永远不会碰到共享代码:新方法是一个插件,结果是数据。有些改动确实需要修改共享代码,例如加速某个公共模块或修复 bug。 由于已发布的结果是用这些代码训练出来的,这类改动要走更严格的流程。
1. 先讨论
Section titled “1. 先讨论”开一个 issue,说明为什么这个改动不能通过插件 hook 实现。如果问题在于缺少某个 hook,维护者会添加这个 hook。外部贡献者对训练契约(协议、成本账本、评测、训练器或数据管线)的修改,
在维护者同意并给 pull request 打上 core-approved 标签之前,会被 CI 拒绝。
2. CI 会做什么
Section titled “2. CI 会做什么”python -m nexttransformer.checks.changes列出指纹覆盖的文件发生变化的已发布方法,pull request 会被打上needs-audit标签。- 只要某个已发布方法的证明与其代码不再一致,
python -m nexttransformer.protocol.fingerprint就会失败。在维护者重新审计受影响的方法之前,这项检查一直是红色。
3. 两类改动
Section titled “3. 两类改动”让每个已发布方法保持不变的改动(重构、加速、不影响数值的修复)需要两项检查:
- 逐位比对。
python -m nexttransformer.checks.golden --base origin/main在基础分支和 pull request 上分别以调试尺寸构建每个方法, 各运行一次前向和反向,比较损失、每个参数和梯度、参数名以及模型哈希。所有内容都必须完全相同。这覆盖了 CPU 代码路径;只在 GPU 上运行的 kernel 的改动还需要一次有界的 GPU 检查。 - 全量审计。 维护者运行 Full audit 工作流,用证明所记录的 PyTorch 构建重新审计受影响的方法,并把每个算子计数与已有证明比较。 只有源码指纹可以改变。之后维护者把重新生成的证明提交到该 pull request 并合并。
改变已发布方法的数值或算力的改动不能作为普通 pull request 合并:已发布的运行是用旧行为训练的,仓库必须仍能复现它们。 这样的改动要么成为方法的新版本(新的方法 id 或配置开关,旧版本保持不变),要么由维护者主导修复并在受影响的结果上加注,要么在改变契约时成为新的协议版本。