3. 版本治理基础模型

在设备边缘AI的远程更新场景中,版本治理首先要解决一个基础问题:当一台边缘设备同时承载固件、推理运行时、AI模型和配置数据时,我们如何用一套可比较、可追溯、可自动判断的标识体系来描述“这台设备现在是什么状态”。如果版本标识设计不当,远程更新系统就无法可靠地回答“是否需要更新”“能否回滚”“更新后模型与固件是否兼容”这三个关键问题。

语义化版本:表达兼容性契约,而非简单编号

语义化版本(Semantic Versioning,简称 SemVer)的核心约定是 MAJOR.MINOR.PATCH 三段式数字,其含义不是“第几个版本”,而是兼容性承诺:

  • MAJOR:不兼容的接口或行为变更。例如模型输入张量从 [1,3,224,224] 变为 [1,3,256,256],或固件升级后旧版模型无法加载。
  • MINOR:向后兼容的功能新增。例如固件新增了 NPU 算子支持,但旧模型仍可正常运行。
  • PATCH:向后兼容的问题修复。例如修复了某类输入下的数值溢出,接口与行为契约不变。

在边缘AI场景中,语义化版本的价值在于:设备端更新代理可以仅凭版本号比较,就初步判断“这次更新是否可能破坏现有模型或配置”,从而决定是否需要进入更严格的兼容性检查流程。

构建元数据:区分“同一版本的不同构建”

语义化版本允许附加构建元数据,格式为 + 后缀,例如 2.4.1+20240612.3。构建元数据不参与版本优先级比较,它只用于标识同一语义版本下的不同构建产物。在边缘AI更新中,构建元数据通常承载:

  • 构建时间戳或流水线编号,用于追溯具体产物;
  • 目标硬件平台标识,例如 +rk3588、+jetson-orin;
  • 量化方式或编译选项,例如 +int8、+fp16。

这意味着 2.4.1+int8 与 2.4.1+fp16 在语义化版本比较中是“同一版本”,但它们是两个不同的二进制产物,更新系统必须根据设备实际硬件与运行时能力选择正确的构建。

模型版本与固件版本的关系:两条独立但需协同的版本线

固件版本描述设备基础软件栈(内核、驱动、推理运行时、更新代理)的状态;模型版本描述AI模型文件及其预处理/后处理配置的状态。二者独立演进,但存在明确的兼容性约束。常见的关系模式有三种:

  • 固件约束模型:固件版本声明其支持的模型版本范围,例如固件 3.2.0 支持模型 >=1.8.0 <2.0.0。设备端在下载模型前先校验该范围。
  • 模型声明依赖:模型包内附带 requires_firmware 字段,例如 "requires_firmware": ">=3.2.0",更新代理据此判断当前固件是否满足。
  • 联合版本清单:云端维护一张兼容性矩阵,设备上报固件版本与模型版本后,由云端返回可用的更新组合。

无论采用哪种模式,关键原则是:模型版本与固件版本不能各自为政,必须有一方或双方显式声明兼容边界。否则远程更新可能把设备推入“固件太旧无法加载新模型”或“新固件不再支持旧模型”的不可用状态。

版本标识在边缘设备上的落地方式

版本标识不能只存在于云端数据库,它必须落到设备本地可读、可校验、可上报的位置。一个可操作的落地结构通常包含以下层次:

  • 固件版本:写入只读分区或启动参数,例如 /etc/device/firmware_version,内容为 3.2.0+rk3588。
  • 模型版本:随模型包一起部署,存放在模型目录的 manifest.json 中,包含 model_version、build_metadata、requires_firmware、input_shape、quantization 等字段。
  • 运行时版本:推理运行时(如 ONNX Runtime、TensorRT、RKNN)的版本单独记录,因为它同样影响模型能否加载。
  • 配置版本:预处理参数、阈值、标签映射等配置单独版本化,避免“模型换了但配置没换”导致的静默错误。

设备端更新代理在启动或收到更新指令时,应执行一次版本状态采集,将上述四类版本组合成一个设备版本指纹,上报云端。云端据此判断是否需要下发更新、下发哪个构建、以及更新后是否需要重启或重新加载模型。

边缘设备版本标识落地结构 边缘设备本地 固件版本 /etc/device/firmware_version 3.2.0+rk3588 模型版本 manifest.json model_version: 1.9.2+int8 推理运行时版本 rknn_runtime: 1.6.0 onnxruntime: 1.17.1 配置版本 preprocess: v4 labels: v2 设备版本指纹(上报云端) fw=3.2.0+rk3588 | model=1.9.2+int8 | rt=1.6.0 | cfg=v4 兼容性校验 requires_firmware >=3.2.0 → 满足;input_shape 匹配 → 通过 云端版本治理 版本清单 固件 3.2.0 / 3.3.0 模型 1.9.2 / 2.0.0 兼容性矩阵 fw 3.2.0 → model <2.0.0 fw 3.3.0 → model >=2.0.0 更新决策 下发模型 2.0.0+int8 要求固件 ≥3.3.0 回滚策略 保留上一版本指纹 失败时恢复 fw+model 组合 上报指纹 下发更新指令

一个可执行的版本标识示例

以下是一个模型包 manifest.json 的示例结构,字段均为教学示例,用于说明版本标识如何落地:

{
  "model_name": "defect_detector",
  "model_version": "1.9.2",
  "build_metadata": "int8.rk3588.20240612",
  "requires_firmware": ">=3.2.0 <4.0.0",
  "requires_runtime": "rknn_runtime>=1.6.0",
  "input_shape": [1, 3, 224, 224],
  "quantization": "int8",
  "preprocess_version": "v4",
  "labels_version": "v2",
  "sha256": "a3f1...e9c2"
}

设备端更新代理读取该文件后,依次校验:固件版本是否满足 requires_firmware、运行时版本是否满足 requires_runtime、输入尺寸是否与当前预处理配置一致、SHA-256 是否与下载产物匹配。只有全部通过,才允许替换当前模型并重新加载推理会话。

实践建议:版本标识应遵循“可比较、可追溯、可校验”三原则。可比较指语义化版本三段式必须严格递增;可追溯指构建元数据能定位到具体流水线产物;可校验指每个版本标识都应有对应的哈希或签名,防止版本号被篡改而内容被替换。
常见误区:把模型版本直接等同于固件版本,或只更新模型文件而不更新 manifest.json 中的依赖声明。这会导致设备在下次重启或重新加载时,因版本校验失败而拒绝加载模型,表现为“更新成功但推理不可用”。

总结来说,版本治理基础模型的核心不是“给每个东西编个号”,而是建立一套分层的、带兼容性语义的、设备本地可校验的标识体系。语义化版本负责表达兼容性契约,构建元数据负责区分同版本不同构建,模型版本与固件版本通过显式依赖声明协同演进,最终以设备版本指纹的形式在边缘设备上落地,为远程更新提供可靠的判断依据。