训练数据集快照:不可变 Manifest、血缘与可复现取数
同一个数据集名称可能在训练期间继续变化。本文用不可变成员清单、源端水位、转换摘要和派生血缘,让每次训练都能精确重放输入集合。
本文要点
- 主题聚焦:AI、大模型、DevOps
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
训练任务写着 dataset=customer-support-latest,并不能回答模型究竟读了哪些记录。对象上传可能与目录扫描并发,CDC 仍在追赶,清洗代码重新部署后结果也会改变;训练失败重跑时,即使 SQL 和随机种子相同,输入集合也可能已经不同。一般的数据版本概念只能提醒团队“要记版本”,这里要解决的是训练准入:把成员、来源、转换和撤权水位冻结成机器可验证的合同。
数据库 CDC 负责持续捕获变化,RAG 索引签名发布 负责在线查询制品。本篇不构建检索索引,也不描述浏览器缓存;它只定义训练作业能够消费的源数据快照。
Manifest 必须枚举事实而非保存查询备注
每个快照使用不可复用的 snapshotId。先对明确排除 snapshotId、签名和传输元数据的 canonical payload 求摘要,再把摘要放入外部 descriptor 与展示字段;验证器必须按同一排除规则重算,避免 manifest 自引用。清单至少固定父快照、源版本、水位、Schema、政策、转换、成员、拆分、墓碑和 benchmark 水位及用途:
{
"schema": "training.dataset.snapshot.v1",
"snapshotId": "sha256:8a91...",
"parents": ["sha256:31c0..."],
"sources": [{
"id": "tickets-eu",
"tableSnapshot": "iceberg:918337",
"cdcHighWatermark": "lsn:0/8F34A210"
}],
"tombstoneWatermark": 44192,
"benchmarkFence": 3908,
"recordSchema": "sha256:7d11...",
"selectionPolicy": "sha256:2b70...",
"transformImage": "registry/normalize@sha256:6e4f...",
"members": {"uri": "cas://sha256/91ad...", "count": 482109},
"splitPolicy": "sha256:902c...",
"purpose": "support-model-training-v3"
}
SQL 文本、目录前缀和 Git 分支都只是提示,不是成员证明。对象源必须记录不可变 version/generation 与字节摘要;表格式使用可固定的 snapshot ID,而不是稍后再次执行 WHERE updated_at < t。成员表保存稳定 sample ID、源版本、逻辑内容摘要和 split,不复制原始敏感正文到 manifest。清单按照冻结的字段顺序、Unicode 与数字规则序列化,禁止不同实现各自格式化后声称同一个摘要。
W3C PROV 的 entity、activity、agent 可以表达“哪个转换由哪个身份从哪些源生成哪个快照”;SLSA provenance 补充构建身份和环境。血缘边指向不可变摘要,derivedFrom=latest 没有审计价值。AI 供应链安全 的签名只能证明声明来自受信 builder,仍需下述集合验证证明声明属实。
冻结动作先取得一致边界
控制面先读取删除与撤权的最低水位,再对每个源取得事务快照或受支持的高水位,之后才运行选择和转换。扫描期间到达的新事件属于下一快照;比水位更早却迟到的事件使构建进入 INCOMPLETE,不能静默补进已经签名的集合。若源无法提供一致快照,就用受控增量日志重建到指定 offset,并证明 offset 连续,不能把某次成功列目录当成一致性保证。
builder 把成员清单和统计写入内容寻址 staging,逐项核对源版本仍可读取、record ID/split 唯一、墓碑与 benchmark 无命中、未知来源为零,再签 manifest。状态只能按 BUILDING -> VALIDATED -> APPROVED -> ACTIVE 前进。激活、tombstone FENCED 与 benchmark fence 推进必须竞争同一个线性一致 (tombstoneWatermark, benchmarkFence, aliasGeneration) gate,可用 SERIALIZABLE、行锁或单次条件 CAS;只有两类水位等于 manifest 且 alias generation 未变时才能切换。任一 fence 先提交,激活失败并生成新 manifest,禁止先切 alias 再异步清理。训练数据 Schema 演进 会决定同一成员能否被新 reader 正确解释。
训练 API 只接受 manifest digest。调度器在共享 gate 中检查用途、tombstone 与 benchmark 水位并取得绑定 permit,再把 digest 写入 run;worker 读取精确对象版本并回报摘要,不能解析 latest。断点恢复继续使用原 digest,数据变化就创建新 run。
用集合差分和重放验收
故障注入包括扫描中新增或删除对象、复用对象名替换内容、CDC offset 断裂、转换镜像同标签换 digest、同一 ID 出现在两个 split、成员表截断、签名后篡改清单,以及在激活读取水位后、alias CAS 前推进 tombstone。最后一种竞争只能一方提交;撤权胜出时候选停在验证态,已固定的 run 输入不变。
门禁记录源水位覆盖率、无版本对象数、血缘完整率、重复和孤儿 ID、墓碑命中数、集合差异、转换重放 hash、构建时延与未解释行数。对固定 canary 从源版本重放,成员 ID 集合必须完全相同;数值转换若允许容差,容差和比较器版本也进入报告,不能只看总行数相等。
发布先影子生成新快照,与当前版本比较新增、删除、split 迁移和分布差异,人工审批绑定 digest。活动别名通过 CAS 切换并提升 generation;回滚也追加更高 generation 指回旧 digest,不修改任何快照。训练分片原子发布 再把这个逻辑成员集合封装为可并行读取的物理文件。回滚绝不能越过最新 tombstone 水位,否则可复现会变成复活已撤权数据。
延伸阅读
Related