4. 模型版本命名与语义化版本
在医学影像 AI 项目中,一个模型文件往往同时牵涉数据版本、训练配置、权重、推理代码和评估结果。如果版本号只写成 model_final.pth、best_model_v2.pt,几个月后即使拿到文件,也很难判断它是在哪批数据上训练、对应哪套预处理、能否直接用于某个临床研究。版本命名要解决的核心问题不是“好看”,而是可追溯:从版本号能定位到数据、代码、配置和评估结论,从评估结论能反查回具体权重。
本节采用语义化版本(Semantic Versioning,SemVer)作为主干,形式为 MAJOR.MINOR.PATCH,并针对医学影像模型扩展出“数据—任务—模型”三段式命名。先给出一个可直接使用的命名模板:
{task}-{modality}-{anatomy}-v{MAJOR}.{MINOR}.{PATCH}+{data}-{code}
示例:
seg-mri-prostate-v2.1.0+ds2024q3-c7f3a1
det-ct-lungnodule-v1.3.2+ds2024q2-b91d0e
cls-cxr-pneumonia-v1.0.0+ds2024q1-a4c8f2
其中 task 取 seg/det/cls,modality 取 ct/mri/cxr/us 等,anatomy 为解剖部位或病灶名,+ 后为构建元数据(build metadata),分别指向数据集快照与代码提交。这样,版本号本身就能回答“这是什么任务、什么模态、什么部位、第几代、基于哪批数据与哪次代码”。
MAJOR / MINOR / PATCH 在医学影像模型中的判定规则
通用 SemVer 的“不兼容 API 变更”在模型语境下需要重新定义。对分割、检测、分类模型,建议按以下规则判定:
- MAJOR:输出语义或接口发生不兼容变化。例如分割标签体系从 3 类改为 5 类、检测框类别定义改变、分类输出从二分类改为多分类;或输入通道数、体素间距约定、方向编码(如 RAS/LPS)改变,导致旧推理代码无法直接加载。
- MINOR:向后兼容的能力增强。例如在原有类别基础上增加一个不影响旧类别的子类、加入新的数据增强、替换骨干网络但保持输入输出张量形状与标签映射不变、在同一数据集上显著提升 Dice 或 mAP。
- PATCH:不改变接口与语义的修复。例如修正预处理中的窗宽窗位、修复某序列方向翻转 bug、重新导出 ONNX 但权重数值等价、更新推理阈值默认值。
需要特别强调:数据版本变化不一定升 MAJOR。若数据仅做清洗、去重、修正标注错误,且标签体系与评估口径不变,通常升 PATCH 或 MINOR;若数据导致标签定义变化,则必须升 MAJOR。判断依据是“旧版本的下游消费者是否还能无修改地使用”。
可追溯版本号的结构与数据流
下图展示一个医学影像分割模型从数据快照、训练配置、权重到发布版本的追溯链。版本号不是孤立字符串,而是挂在制品上的标签,向上游指向数据与代码,向下游指向评估报告与部署实例。
图中左侧三类输入(数据快照、代码提交、训练配置)共同决定中间权重制品;权重制品经评估后生成报告,再以同一版本号发布为推理实例。右侧规则表说明版本号何时进位。这样,任何一个发布实例都能沿箭头反向定位到数据与代码。
实际落地:版本号生成与校验
在工程实现上,建议把版本号写入模型文件的元数据,而不是只放在文件名。以 PyTorch 为例,保存时附带版本字典:
ckpt = {
"state_dict": model.state_dict(),
"version": "2.1.0",
"build": {"data": "ds2024q3", "code": "c7f3a1"},
"task": "seg", "modality": "mri", "anatomy": "prostate",
"label_map": {0: "background", 1: "prostate"},
"spacing": [0.5, 0.5, 3.0],
"orientation": "RAS"
}
torch.save(ckpt, "seg-mri-prostate-v2.1.0+ds2024q3-c7f3a1.pth")
加载时先校验 label_map 与 orientation 是否与当前推理管线一致,不一致则拒绝加载或触发坐标转换。这一步能避免“权重能加载但结果整体翻转”的隐蔽错误。对于检测模型,还应记录 anchor 配置与 NMS 阈值;分类模型记录类别顺序与输入归一化参数。
+ 后元数据不参与优先级比较,因此 v2.1.0+ds2024q3 与 v2.1.0+ds2024q4 在 SemVer 意义上属于同一版本。若数据变化会改变模型行为,应通过 MINOR 或 PATCH 体现,而不是只改构建元数据。常见错误与检查清单
- 用日期当版本号(如
20240601),无法表达兼容性变化;日期可作为构建元数据,不作为主版本。 - 只升 PATCH 却改了标签类别数,导致下游分割结果类别错位。
- 同一版本号对应多个权重文件,破坏“版本号—制品”一一对应。
- 评估报告未记录版本号,无法判断指标属于哪次训练。
- 发布镜像标签与模型版本号不一致,回滚时无法定位。
建议在 CI 中加入版本校验:提交训练配置时自动读取 label_map 与上一 MAJOR 版本对比,若类别集合变化则强制要求升 MAJOR;导出 ONNX 时校验输入输出形状与版本号声明的接口一致。这样,版本号才真正成为医学影像模型可追溯、可回滚、可审计的工程标识,而不仅是文件名后缀。