3. 模型版本治理核心概念

在 Jetson 边缘 AI 交付中,“模型版本”经常被当成一个单一数字来管理,例如 model_v2。但真正决定一次推理结果是否可复现的,往往不是这个笼统的编号,而是背后五个彼此独立、又必须协同的版本维度:模型版本、权重版本、引擎版本、配置版本、数据版本。把它们混为一谈,就会出现“模型没换、结果却变了”或“权重没动、精度却掉了”的排障困境。本节先把五个概念拆开定义,再说明它们的关联,最后讨论语义化版本在边缘 AI 场景下应如何适配。

五个版本维度分别是什么

模型版本是最高层的语义标识,描述“这是一个什么结构、什么任务的模型”,例如 yolov8n-det、resnet50-classify。它对应网络结构、算子集合、输入输出张量定义。模型版本变化通常意味着结构或任务定义发生了变化,例如从检测改为分割、从单输入改为多输入。

权重版本是模型版本之下的一次参数快照。同一个模型结构,用不同数据集、不同训练轮次、不同超参训练,会得到不同权重。权重版本用 weights-v1.3.0 这类标识区分,它决定“同一结构下参数取哪一组”。权重文件通常是 .pt、.safetensors、.onnx 等。

引擎版本是权重在具体硬件与推理后端上编译后的产物版本。在 Jetson 上,TensorRT 会把 ONNX 或 PyTorch 权重编译成 .plan 引擎,编译过程受 TensorRT 版本、CUDA 版本、精度模式(FP32/FP16/INT8)、动态 shape profile、算子融合策略影响。因此同一份权重,在不同 JetPack 或不同精度设置下会生成不同引擎,必须单独版本化。

配置版本是推理运行时的参数集合,包括输入分辨率、归一化均值方差、置信度阈值、NMS 阈值、类别标签映射、预处理与后处理逻辑。它不改变权重数值,却直接改变输出结果。例如同一权重,置信度阈值从 0.25 调到 0.5,检出框数量会明显减少。

数据版本是训练、校准与验证所用数据的快照,包括训练集、验证集、INT8 校准集。数据版本决定权重“见过什么”,也决定精度评估“在什么分布上成立”。在边缘场景中,数据版本还常包含现场采集的补充样本。

五个版本的关联关系

这五个维度不是并列的,而是有明确的依赖方向:数据版本参与训练产出权重版本;权重版本与模型版本共同作为输入,经 TensorRT 编译产出引擎版本;引擎版本与配置版本在运行时组合,最终产生推理输出。也就是说,数据 → 权重 → 引擎 → 运行时输出是一条主链,配置版本则横向作用于运行时环节。任何一环变化,都可能改变最终结果,因此交付物必须能把这五者绑定成一个可追溯的组合。

Jetson 模型交付五版本依赖关系 数据版本 train / val / calib data-v2.1.0 权重版本 .pt / .onnx weights-v1.3.0 模型版本 结构 / 任务定义 yolov8n-det 引擎版本 TensorRT .plan engine-v1.3.0-fp16 配置版本 阈值 / 分辨率 / 标签 config-v1.3.0 运行时推理输出 检测框 / 类别 / 置信度 / 延迟 训练 编译 结构约束 运行时作用 交付绑定清单 五版本组合 = 可复现单元

为什么必须分开版本化

举一个 Jetson 上常见的排障场景。现场设备升级后,检测框数量明显减少。如果只记录“模型版本没变”,就会误判为硬件问题。实际原因可能是:权重版本从 weights-v1.2.0 换成了 weights-v1.3.0,而配置版本中的置信度阈值仍是旧的 0.25,但新权重输出分布整体偏低,导致大量框被过滤。此时需要同时核对权重版本与配置版本,而不是只看模型版本。

再比如 INT8 量化。同一份权重,用不同校准集(数据版本不同)生成的引擎,精度可能相差几个百分点。如果数据版本没有记录,就无法解释“为什么同一权重、同一引擎参数,换台设备精度不一样”。因此,五个版本必须作为一个整体绑定,形成可复现的交付单元。

语义化版本在边缘 AI 中的适配

软件工程常用的语义化版本 MAJOR.MINOR.PATCH 可以直接借用,但含义需要针对边缘 AI 重新定义。建议按以下规则适配:

版本位触发条件示例
MAJOR模型结构、输入输出张量定义、任务类型变化,或引擎不再兼容旧配置检测改分割;输入从 640 改 1280
MINOR权重更新、数据版本更新、精度模式变化,但接口与配置兼容重新训练权重;FP16 改 INT8
PATCH配置阈值微调、标签修正、后处理 bug 修复,不影响权重与引擎置信度 0.25→0.30;修正类别名

需要特别注意的是,引擎版本不能简单跟随权重版本。因为引擎还依赖 TensorRT 版本、CUDA 版本、精度模式和动态 shape 设置。推荐做法是给引擎版本附加构建标签,例如 engine-v1.3.0-fp16-tr8.6,其中 tr8.6 表示 TensorRT 8.6。这样在跨 JetPack 版本迁移时,能快速判断引擎是否需要重新编译。

在 Jetson 上,引擎 .plan 文件与 TensorRT 版本强绑定。JetPack 升级后,旧引擎通常无法直接加载,必须用对应版本的 TensorRT 重新编译。因此引擎版本号中应显式包含 TensorRT 主版本,避免“权重没变、引擎却加载失败”的误判。

版本命名与绑定示例

下面给出一个可直接参考的版本绑定清单,用于记录一次交付的完整版本组合。字段只保留边缘 AI 交付真正需要的项:

# delivery-manifest.yaml(示例)
model:        yolov8n-det          # 模型版本:结构+任务
weights:      weights-v1.3.0       # 权重版本:训练产出
data:         data-v2.1.0          # 数据版本:train/val/calib
engine:       engine-v1.3.0-fp16-tr8.6   # 引擎版本:含精度与TR版本
config:       config-v1.3.0        # 配置版本:阈值/分辨率/标签
target:       Jetson Orin NX 16GB  # 目标硬件
jetpack:      6.0                  # 运行环境
input_shape:  1x3x640x640          # 输入张量
precision:    FP16                 # 精度模式

这份清单的价值在于:任何一次现场问题,都可以先定位是哪个版本维度发生了变化。若五个版本完全一致而结果不同,才需要怀疑硬件、温度降频或驱动层问题。这样就把排障范围从“整个系统”缩小到“某个版本维度”。

版本治理的最小落地要求

对于 Jetson 边缘交付,版本治理不需要一开始就上复杂平台,但至少要满足三点:第一,五个版本维度都有独立标识,不合并成一个笼统编号;第二,每次交付产出一份绑定清单,随固件或容器镜像一起归档;第三,引擎版本必须记录 TensorRT 与精度信息,确保可重建。做到这三点,模型版本治理就从“靠记忆”变成了“靠记录”,OTA 升级时也能明确回答“这次到底换了什么”。