W02 · S08—S14 · 总 Day 98—104
制品版本:回滚的对象不是一个模型名
用内容指纹和发布指针连接模型、Prompt、数据与策略。
作者准备的学习示例 · 不计真实学习进度 · 不代表生产 / GPU / 真机结果
核心问题
模型权重没变,系统回答却变了。可能是 Prompt、检索索引、分词器、工具参数、策略或预处理变了。只记录 model-v1 无法充分说明系统行为,也无法明确该恢复哪一组依赖。
对应 S08~S14。本周把“保存文件”推进到“识别一次运行使用的整组内容”。
1. 内容身份与发布指针是两种东西
内容身份描述字节或规范化值是否相同;发布指针描述当前选择哪个版本。前者应稳定,后者允许受控变更。一个 manifest 引用模型、数据、Prompt、策略等对象,它本身也可以得到一个指纹。
本例用 SHA-256 对规范化 JSON 做散列。键顺序先排序,数组顺序保留。因此 {a:1,b:2} 与 {b:2,a:1} 指纹相同,而调换数组元素会改变指纹。规范化仅覆盖这份示例使用的有限 JSON 值,不宣称实现 RFC 8785 或跨语言签名标准。
特别注意:manifest 中写 model: toy-rules-v1 只是在散列这个名字,不是在验证真实权重。真实制品链还要记录模型文件内容 hash、不可变地址、依赖版本和获取方式,并验证引用对象没有被覆盖。
2. 运行并追踪三次选择
npm run learning:p2 -- w02
v1 和 v2 只有 Prompt 文本不同。promptChangesBundle 应为 true;sameContentDifferentKeyOrder 应为 true。snapshots 存的是两份 manifest 字符串,releaseHistory 按 v1 → v2 → v1 记录选择。最后的 restored 恢复为旧 Prompt。
这展示“指针切回旧内容”的机制,不是线上发布。快照在内存里,进程退出就消失;没有模型被加载,没有正在处理的请求,也没有数据库 schema 迁移。因此不能从这个输出推断线上回滚一定安全。
3. 回滚为什么比恢复旧代码复杂
设新版本生成了不同结构的缓存或持久状态。即使旧代码、模型和 Prompt 都找回来,旧读取器可能不能理解新状态。需要分别考虑静态制品、可变数据、进行中的请求以及已经发生的外部副作用。
| 对象 | 本例做了什么 | 真实系统还要考虑什么 |
|---|---|---|
| Manifest | 内容指纹与字符串快照 | 来源、签名、保留期、依赖可获取性 |
| 发布指针 | 三次选择记录 | 并发更新、流量切换、观察窗口 |
| 运行状态 | 未实现 | 旧版能否读取新版 checkpoint |
| 副作用 | 未实现 | 已发送的通知或已执行的动作不能靠换指针撤回 |
散列说明内容身份,不说明内容正确、安全、合法或来自可信作者。版本管理是解释与恢复的条件之一,不是质量证明。
4. 轻量修改
只修改 policy,观察 bundle 是否变化;再把字段顺序调整,观察身份是否稳定。随后在纸上增加 indexSnapshot:如果只回滚模型、不回滚检索索引,回答会不会恢复?把答案限定为你的场景,不给普遍保证。
可选延伸:给发布指针加 expectedPreviousId,讨论为什么比较并交换能发现两个发布者竞争。无需建设 registry 服务。
5. 专业阅读与下一阶段联系
- MLflow Model Registry:阅读版本、alias 与 lineage 的区别,对照“不可变内容”和“可变引用”。这里没有安装或实现 MLflow。
- FSDL 2022:选 Experiment Management,把实验输入、运行信息和输出制品分开记录。
后续研究需要固定的不只是随机种子,还有数据、实现、环境与比较条件。具身任务还会引入相机标定、控制频率、仿真器与场景版本。本周建立“完整上下文共同决定结果”的直觉,不声称消除了随机性或硬件差异。
简短笔记可以写:本系统最容易漏掉的一个依赖;它改变时旧结果为何不可复现;恢复时还需要哪种状态信息。