Transformers 模型集成契约:用缩小模型拦住回归

Transformers 的测试套件规模很大:主分支有 88,000+ CPU 测试,每日另有 200,000+ GPU 测试。但等定时跑完发现回归,bug 往往已经进了 main。2026 年 7 月 30 日,Transformers 为 T5 启用了 PyTorch 的 scaled dot-product attention(SDPA),副作用是 UMT5 的 decoder 能注意到未来 token——训练时相当于偷看答案。没有崩溃,这个 bug 在 main 里待了近两个月。事后重放提交时,一个跑在 CPU 上的小型 UMT5 模型在每个相关提交上都标记了它。这篇文章讲的就是这种小型模型和围绕它设计的测试标准。

核心方案是 Model Integration Contracts(MIC):把真实 checkpoint 缩成一个 fixture,然后跑“快速集成测试”。fixture 用真实 checkpoint 的配置生成,层数更少、宽度更窄,但保留每一种层类型,tokenizer 和 processor 文件原样不变。UMT5 fixture 权重只有 66 MB,源 checkpoint 是 1,227 MB。这也能覆盖超大模型——有些模型塞不进标准 GPU runner,但 fixture 可以在 CPU 上跑。

MIC 由三部分组成:fixture(发布一次并固定版本)、usage path(一个可运行的 Markdown 示例,比如生成文本或跑一步训练)、baselines(跑该示例时记录的输出,由人工审核)。契约成立的条件是:在 fixture 上运行 usage path 仍能得到 baselines。契约覆盖一个架构和一条使用路径,而不是单一 checkpoint;兼容的 checkpoint 可以共享 fixture,各自保留期望结果。所有 MIC 发布在 huggingface-mic。例如 SmolLM 契约会用提示词 The capital of France is 做生成,比较 token ID,还比较训练 loss、检查梯度是否有限,并验证 optimizer 更新权重。Hub 上的 fleet dataset 把每个 MIC 固定到冻结 revision 和记录 baselines 时的包版本,方便复现。

在 PR 上,根据改动文件挑选 MIC。重放五个月提交的结果是:小型 UMT5 fixture 从 7 月 30 日引入到 9 月 28 日修复,每次都标记出回归。label log-probabilities 与审核过的 baseline 相差 1.22,训练 loss 相差约 0.20。关键细节是契约走 SDPA 这个默认 attention 路径;只跑 eager attention 变体就会漏掉。之后在 CI 的 proof 分支上还原修复,检查以相同的差异失败,选中的 T5 契约 runner 步骤在 CPU 上耗时 13.4 秒(不含 setup)。

模型怎么缩小?最初的配方只是缩小维度、减少层数,但对混合架构不够——比如两层都是 sliding attention 时,full-attention 层会消失。现在有四步:一是从真实 checkpoint 缩小配置,包括隐藏尺寸、注意力头数和深度,保留不同的层类型(sliding/full attention、dense/MoE 混合),部分架构需要额外规则,并参考 test_modeling_.py 里的 ModelTester 手选的尺寸;二是保持预处理不变,词表、特殊 token、输入维度不变,tokenizer 和 processor 文件逐字节复制;三是构建并验证权重,先用固定种子的随机权重,改变输入看模型是否有响应,不行就在契约的小批量示例上训练,再重载检查输出、loss 和梯度是否有限,失败就拒绝;四是冻结并记录,保存权重并在已知良好的版本上测可复现输出,人工审核各平台和精度的 baselines 后发布固定快照。另外要保持原始权重文件格式,否则会跳过用户加载真实 checkpoint 时的转换代码。Llama 4 Scout 的收缩报告显示,108.6B 参数变成 44.7M,vision 栈从 34 层到 2 层,language 栈从 48 层到 4 层,保留被检查的层类型和 MoE 路由风格。

构建 MIC 也用了 agent。CLI 叫 tmic,LLM 起草 usage code 和 manifest,CPU/GPU 运行测量候选 baselines。LLM 只起草,不审批;期望结果的改动需要人工审核。tmic 可以在一台机器上本地草拟契约、构建 fixture 并记录 baselines,每步要求审核,上传前停止。遇到 edge case 时,团队修的是通用 recipe 而不是单个 fixture。已发布模型和剩余缺口在 coverage space。

随机权重 vs 过拟合:用随机权重的 Whisper fixture 对音频变化几乎没反应,于是团队在几个音调上配上 red、green 等词做了过拟合,目的不是语音识别,只是让音频变化在输出中可见。在注入故障实验中,随机权重抓到 18/24,过拟合抓到 24/24。但这是合成故障,且尚未发现只被过拟合版本抓到的真实回归;两个版本都漏掉了一个真实 Whisper checkpoint 才能暴露的 assisted-decoding bug。所以当前策略是:随机权重能通过检查就用随机,需要更高敏感性或可读答案时用过拟合。训练只要几秒,但多一个可能不收敛的步骤,也多一份维护。

截至 2026 年 11 月 1 日,Transformers CI 的 MIC 任务只报告失败,不阻塞 PR。是否应该阻塞取决于尚未测量的东西:在 PR 上实际抓到多少真实 bug?误报率多高?baseline 审核要花多少人力?未知的还有多少 bug 只会在真实权重下出现,以及过拟合是否真能抓到随机权重漏掉的真实 bug。覆盖范围仍不完整。当回归漏过时,可以补上缺失的 usage path 并在坏版本和修复版本上重放。未来想把原始 Hub 模型页面链接到对应 MIC,让开发者或 agent 使用 checkpoint 时能从一个已经测试过的示例、环境和期望输出出发。

Transformers Model Integration Contracts

查看原文