你的微调语料库是代码库。别再通过存储桶交付了。
在任何严肃的微调项目进入到第九个月时,你的训练语料库的作者数量可能已经超过了你的代码库。合成生成流水线编写了数百万个示例。供应商标注公司从你从未见过的劳动力那里贡献了 8 万行数据。一位工程师在上周二添加了 47 个示例,以修复他们在评估(eval)中发现的回归问题。一个抓取任务每天晚上将生产环境的追踪记录(traces)拉取到一个“补充”的 parquet 文件中。二月份有人扔进 S3 的一个 CSV 文件仍然在那里,仍然处于训练组合中,而编写该文件的人已经在三月份离职了。
现在看看你的应用程序代码仓库。每一行代码都可以追溯到具体的作者。每一次变更都经过了至少一名审核者的 PR。提交(Commits)是经过签名的。主分支(Main branch)是受保护的。合并需要第二个人参与。这里有审计日志。如果审计员询问 payment_processor.py 的第 47 行是谁写的,你可以在几秒钟内给出答案。
如果他们问产生模型 v2.3 的语料库中的第 47 个示例是谁写的,诚实的回答是“2024 年第二季度的 Mechanical Turk 批次,供应 商未知,理由缺失。”你的微调语料库是比代码库权限更高的部署表面——它直接决定了生产环境中模型的行为——而你正在通过存储桶(bucket)发布它,却通过经过审查的 PR 发布代码。威胁模型被倒置了。
投毒数学比数据质量数学更糟糕
多年来,关于训练数据的讨论一直被框架为一个质量问题:垃圾进,垃圾出,因此要仔细筛选。这种框架令人欣慰,因为质量问题是统计学上的——坏的示例会稀释好的示例,而更多好的示例会冲刷掉坏的示例。防御能力随语料库规模同步增长。
最近的投毒(poisoning)研究打破了这种直觉。2025 年 10 月,Anthropic、英国 AI 安全研究所和艾伦·图灵研究所表明,只需 250 份恶意文档就足以给大语言模型(LLM)植入后门,而且这个数量无论模型大小如何都大致保持不变——让 6 亿参数模型受损的同 250 份文档,也让参数量大 20 多倍、训练数据量大 20 多倍的 130 亿参数模型受损。在 130 亿参数的情况下,被投毒的内容仅占总训练 token 的 0.00016%。防御能力并不随语料库规模增长。质量是一个比例问题;投毒是一个绝对数量问题。
250 这个数字非常小,小到一个外包人员一个下午就能完成。它小到足以完全避开统计学上的筛选,因为没有任何质量过滤器会针对“语料库中 0.00016% 的内容看起来很奇怪”触发警报。它小到让供应商流水线中的恶意标注者可以将其夹在经过批准的每周上传中发送,且永远无法通过评估漂移(eval drift )检测到,因为后门是由特定的触发字符串锁定的,而评估套件没有理由去探测这些字符串。
这对微调的影响是直接的。如果 250 份文档就能给在数千亿 token 上训练的基础模型植入后门,那么在你的微调语料库中(总共可能有 10 万到 1000 万个示例),实现行为后门所需的比例甚至更容易达到。任何能向该语料库写入内容的人都能塑造你生产环境模型的行为。这不再是一个数据质量威胁模型,而是一个代码执行威胁模型,你应该像对待代码执行一样对待它。
已经奏效的规程,就在隔壁房间
这个问题奇怪的地方在于,防御它的规程已经部署在你的组织中了。只是它被部署在了错误的制品(artifact)上。你的应用程序代码仓库拥有:
- 强制性 PR 审查,每次变更至少有一名指定的批准人。
- 签名提交,与安全团队运营的密钥管理基础设施挂钩。
- 分支保护,防止直接推送至主分支。
- 双人规则,用于敏感路径。
- 溯源链 ——
git blame可以在几秒钟内将任何一行代码解析到具体的人和理由。 - 覆盖率要求 —— 没有测试覆盖的新代码会被标记。
- 审计日志 —— 每次合并、每次批准、每次覆盖都会被记录。
你的训练语料库则一项都没有。标注者的工具在保存时将标签推送到存储桶。工 程师将 CSV 丢进 S3 以“增强训练集”。合成生成脚本编写了由 GPT-4 创作的数百万个示例,且没有逐条记录来源。供应商的每日导出覆盖了前一天的批次。从任何有意义的衡量标准来看,语料库都是一个多作者仓库——但它却像临时文件夹一样被管理着。
修复方法不是去发明新东西,而是将你已经在代码上运行的规程移植到语料库中。每一项贡献都应该以可审查的差异(diff)形式呈现,对比先前语料库的快照,并带有指定的作者、书面理由和批准人。提交应该使用代码仓库所用的相同密钥进行签名,这样即使存储桶凭据泄露,也不等同于模型被投毒。访问权限应该分为“可以标注”(开发人员角色)和“可以合并到训练集”(维护者角色)——这种分离机制能防止单个被攻破的开发人员账户直接向生产代码推送内容。
覆盖门禁与金丝雀探针 —— 语料库层面的 CI
代码仓库在每次 PR 时都会运行 CI。CI 会捕获人类遗漏的问题:被删除的 import、损坏的测试、lint 失败。而在语料库层面,与之对应的基础设施包括两个大部分团队要么选择跳过、要么操作极不规范的环节。
第一种是 覆盖门禁 (coverage gate)。当一个语料库 PR 在领域 X 中增加了 1 万个样本时,在合并之前,评测套件必须包含针对领域 X 的留出探针 (held-out probes)。如果没有,该 PR 就会被阻止,这正如代码 PR 在新代码路径没有测试覆盖时被阻止一样。这是 机械化的过程 —— 脚本计算 diff 中每个领域的样本数,交叉对比评测套件的覆盖图,如果新领域没有探针覆盖,则检查失败。如果没有它,语料库就会在评测套件无法感知的方向上不断累积贡献,而显示为绿色的评测套件会逐渐偏离,只能测量到模型实际学习内容中越来越小的一部分。
第二种是 中毒检测金丝雀套件 (poisoning-detection canary suite)。维护一组固定的对抗性探针 —— 已知的触发字符串、已知的后门模式、以往事件的行为指纹 —— 并在每次语料库更新前后对模型进行运行。如果旨在改进领域 X 的微调同时改变了与领域 X 无关的对抗性探针上的行为,那么这就是一个值得阻止的信号。探针的运行成本很低,但设计成本很高,它们的作用就像回归测试套件对代码的支撑作用一样关键。一个通过了 100% 行为评测但触动了金丝雀探针的模型,是你的 CI 不应该允许发布的。
这两者都不是研究级的防御,而是应用于一种长期被豁免于工程规范的产物上的机械工程卫生措施。团队跳过它们的原因并不是因为它们很难,而是因为没有人将语料库视为一种需要这些措施的产物。
安全团队从未审计过的采购现状
这其中涉及到一个采购层面的问题,大多数公司的安全组织从未关注过。贡献了你 40% 微调样本的标注供应商,其运作的劳动力团队可能位于安全团队从未评估过的管辖区内。承包商池随着零工经济的常态化流失而不断更替。标注工具通过一个你组织 内没人编写、也没人审计过的 API 推送标签。供应商的内部访问控制 —— 供应商中谁能看到哪个批次、谁能在事后编辑已提交的标签、谁能向轮换名单中引入新标注员 —— 都由供应商的政策决定,而不是你的。
那个供应商对你生产模型行为的影响力,比你公司任何一名工程师都要大。如果一名工程师试图向生产代码推送恶意变更,会受到代码审查、CI、SRE 值班以及可追溯到其姓名的审计轨迹的限制。而供应商处标注了 250 个特定样本的标注员则无需面对这些。如果供应商的标注 UI 直接保存到你的训练存储桶(许多供应商确实如此),那么从 “标注员的击键” 到 “生产模型行为” 的路径,其检查点比从 “工程师的本地提交” 到 “生产代码行为” 的路径还要少。
诚实地对此进行威胁建模。向供应商索要你会向任何生产相关承包商索要的东西:SOC 2、每个提交批次的个人责任制、标签编辑的日志留存,以及当发现与特定标注员相关的质量(或更糟,中毒)问题时,你的团队能够事后撤销其贡献的能力。如果供应商无法回答这些问题,那你拥有的不是标注供应商,而是一个未经审计的针对你模型行为的写入通道。
审计师的问题,以及你无法给出的答案
受监管行业版本的对话通常始于一个具体问题:“告诉我谁编写了产生模型 v2.3 的语料库中的第 47 号样本,以及在语料库快照 47.0 到 47.1 之间发生了什么变化。” 在 2024 年 Data Provenance Initiative 对 1,858 个广泛使用的微调数据集的审计中,许可证遗漏率超过 70%,分类错误率超过 50% —— 整个领域对于其依赖的公共数据集都无法回答许可方面的问题,更不用说内部语料库了。
如果你在金融服务、医疗保健或任何模型输出涉及重大决策的受监管领域工作,这个问题即将找上你。CISA AI SBOM 指南正在将软件供应链监管推向 AI 产物。关于可验证微调 (verifiable fine-tuning) 的新兴研究 —— 例如为模型存证扩展 Sigstore 的 Atlas 框架,或将训练数据与加密证明绑定的 VFT 风格协议 —— 预示着在不久的将来,“展示该模型训练数据的监管链 (chain of custody)” 将是一项监管要求,而非可有可无的愿望清单。
能够做好准备的团队,是那些今天就将每一项语料库贡献视为经过签名、审查、具名的 PR,并附带理由、批准人和 diff 的团队。而那些在审计中失败的团队,则是当监管机构询问时,不得不承认第 47 号样本来自 “一个没有逐条样本归属信息的 2024 年第二季度 Mechanical Turk 批次” 的团队。这种回答在今天的大多数公司中是可以接受的,因为没人检查。但这种情况不会持续太久,而从简单的存储桶转向经过审查的流水线,所需的工作量是以季度而非周来计算的。
一个起点
如果你的团队在阅读本文时对上述描述深有感触,那么第一步应该是小而具体的:选择一个语料库贡献源——无论是合成数据流水线、某个供应商的批量馈送,还是内部的“工程师添加示例”路径——并在该源与训练集之间安排一名审查员。不是全部,只需一个。要求为每一批次提供理由。要求 提供针对评估套件的覆盖率说明。使用安全团队控制的密钥对该批次进行签名。与之前的快照进行 Diff 比对。拦截未通过金丝雀探针测试的合并。
在第一个月里,你会发现吞吐量成本比预期的要低,而错误检出率却比预期的要高——这正是那些习惯了直接合并到主分支的公司在初次引入代码审查时所经历的发现曲线。难点不在于工具;工具是现成的。难点在于将语料库视为一个承重的工程制品,而不是一个恰好向生产环境输送数据的草稿文件夹。一旦确立了这种思维框架,剩下的工作就只是机械化的执行了。
你的微调语料库对模型行为的影响已经比应用程序代码更直接了。像治理代码一样开始治理它吧。
- https://www.anthropic.com/research/small-samples-poison
- https://arxiv.org/abs/2510.07192
- https://arxiv.org/html/2502.19567v2
- https://arxiv.org/html/2510.16830v1
- https://www.nature.com/articles/s42256-024-00878-8
- https://arxiv.org/abs/2310.16787
- https://www.manifestcyber.com/blog/provenance-is-the-new-perimeter
- https://www.cio.com/article/4170711/cisas-ai-sbom-guidance-pushes-software-supply-chain-oversight-into-new-territory-2.html
- https://www.lakera.ai/blog/training-data-poisoning
- https://atlan.com/know/training-data-lineage-for-llms/
