Soup模型注册表(registry)实战:血缘追踪让每次微调可回溯
【免费下载链接】SoupFine-tune LLMs from one YAML. Layer streaming trains an 8B model on a 4 GB laptop GPU.项目地址: https://gitcode.com/GitHub_Trending/soup12/Soup
Soup 是一款「一个 YAML 就能微调大模型」的开源自研工具,支持在 4 GB 笔记本显卡上训练 8B 模型。但你微调了十几轮之后,还能说清每个模型版本来自哪份配置、哪份数据集吗?Soup 内置的模型注册表(Model Registry)为每次微调记录内容哈希、产物指纹和父子血缘,让每个模型都可回溯、可对比、可晋升上线。下面带你 5 分钟上手这套机制。
模型注册表解决什么问题 🎯
微调大模型的人大概都经历过这些场景:
- 磁盘上躺着 5 个 LoRA 权重,却分不清哪个才是效果最好的
- 三个月后想复现某次训练,找不到当时的配置和数据集
- 上线前想对比 v1 和 v2 的差异,只能靠翻聊天记录
Soup 的做法是在本地维护一个 SQLite 注册表(默认位于~/.soup/registry.db),把每一次训练运行登记为一个条目(entry):
- 内容哈希:配置 + 数据文件 + 基座模型名共同算出的 SHA-256 指纹,同配方必同哈希
- 产物清单:adapter、合并权重、GGUF、评估结果等文件各自记录 SHA-256 与大小
- 血缘指针:条目之间记录父子关系,形成一张可追溯的谱系图
整个过程不依赖任何云端服务,数据完全留在本地。
🖥️ 上图是 Soup 的 Web UI 新建训练界面:选一个模板,编辑 YAML 里的
base、data、training参数即可启动微调。训练结束后,这次运行就可以被登记进注册表。
注册表的完整设计文档见 docs/adapters-and-governance.md,源码位于 src/soup_cli/registry/。
快速上手:注册第一个微调产物 🚀
训练完成后(运行 id 形如run_202611_abc123),一条命令就能登记入册:
soup registry push --run-id run_202611_abc123 --name llama31-chat --tag v1push会自动从训练追踪器中取出这次运行的完整配置与基座模型信息,算好哈希并生成条目 ID(形如reg_20261114_9f3ab2c1d0e4)。接下来就是日常四连:
| 命令 | 作用 |
|---|---|
soup registry list --name llama31-chat --tag prod | 按名称/标签/基座/任务过滤查看条目 |
soup registry show llama31-chat-v1 | 查看完整详情:配置、产物、祖先谱系 |
soup registry search "medical reasoning" | 跨名称/基座/任务/备注全文检索 |
soup registry promote llama31-chat-v1 --tag prod | 给条目加prod标签,晋升为生产版本 |
实现都在 src/soup_cli/commands/registry.py,每个子命令就是一个独立的小函数,逻辑非常直白。
📈 上图是 Soup 的层流式(layer streaming)微调启动画面:32 层模型只需在显存中占用 2 个 113 MB 的缓冲区。这样省显存的能力,意味着你可以在低配机器上多跑几轮实验——而注册表正是帮你把这些实验「管得住」的那只手。
内容哈希:给每次微调一个唯一指纹 🔑
注册表最核心的设计是确定性哈希,实现在 src/soup_cli/registry/hashing.py:
hash_config:把配置字典序列化为「键排序」的规范 JSON 再取 SHA-256——配置项书写顺序不同,哈希依然一致hash_file:数据文件按 1 MB 分块流式读取哈希,GB 级数据集也不会撑爆内存hash_entry:把config + base_model + data_sha256组合成一个总指纹,唯一标识「这份配方 + 这批数据 + 这个基座」
两个细节很贴心:
- 数据文件按内容而非路径哈希——文件挪个位置,指纹不变
- 哈希按内容计算,所以「两次训练是否真的用了同一份数据」不再靠肉眼核对
血缘追踪:把谱系树画出来 🌳
每次登记时,条目可以指向它的「父条目」,关系类型有四种:
forked_from:从某版本分支/派生而来merged_from:由多个适配器合并而来evaluated_with:评估所用的基准promoted_from:由某个版本晋升而来
这些父子边存进registry_lineage表(见 src/soup_cli/registry/store.py),构成一张有向无环图(DAG)。写入时还会做环检测——如果这条边会让谱系「绕回自己」,直接拒绝,保证谱系永远是一棵能走到底的树。
想查看某条谱系,用一条命令即可:
soup history llama31-chat它会以树形结构打印出该名称下所有条目、各自的标签、创建时间,以及向上 5 层的祖先和向下 5 层的后代,连从注册表挂接的 adapter 分支快照(branch_ref)也会显示出来。实现在 src/soup_cli/commands/history.py。
这样一来,当线上模型出问题时,你可以沿血缘一路回溯:它由哪次合并产生?合并的父版本用了什么数据?配置又改了哪几项——每一跳都有哈希背书。
两个版本一键对比:配置差异 + 评估增量 📊
soup registry diff llama31-chat-v1 llama31-chat-v2这条命令输出两张表:
- 配置差异(config diff):把两侧 YAML 配置展开成点路径,逐项标出
added / removed / changed,比如training.lr: 2e-5 → 1e-5 - 评估增量(eval delta):自动关联两个条目 run 的评估记录,逐个 benchmark 列出左、右分数与差值
对比算法在 src/soup_cli/registry/diff.py,diff命令直接复用它。
日常管理:引用解析与删除 ⚙️
注册表在细节上做得相当「防呆」:
- 灵活引用:条目可以用完整 ID、ID 前缀、或
name:tag三种方式引用;前缀若命中多个条目会报错而不是默默选一个,避免误操作 - 晋升与清理:
promote只是加标签,不改数据;delete --yes会通过外键级联删掉关联的产物和血缘记录 - 安全:数据库文件在 POSIX 系统上自动设为
600权限;路径可用环境变量SOUP_REGISTRY_DB_PATH覆盖 - 命名规范:名称最长 128 字符、标签最长 64 字符,只允许字母数字与
_ - .,避免脏数据混入谱系
写在最后 ✨
Soup 模型注册表把「微调产物管理」这件事做成了本地化、零依赖、可审计的形态:哈希保证可复现,血缘保证可回溯,diff 保证可对比,promote 保证可治理。如果你也在频繁迭代 LoRA / 全参微调,这套机制值得直接借鉴——相关实现集中在 src/soup_cli/registry/ 与 src/soup_cli/commands/registry.py,配合 docs/adapters-and-governance.md 阅读体验更佳。
【免费下载链接】SoupFine-tune LLMs from one YAML. Layer streaming trains an 8B model on a 4 GB laptop GPU.项目地址: https://gitcode.com/GitHub_Trending/soup12/Soup
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考