4. 模型版本管理与代码仓库

在精算模型的生产部署中,真正棘手的往往不是“模型能不能跑”,而是“这次跑出来的结果,到底是哪一版模型、哪一版参数、哪一版数据算出来的”。模型版本管理要解决的核心问题,就是让每一次生产运行都可追溯、可复现、可回滚。Git 负责代码与配置的版本化,标签与发布包负责固化可交付的稳定版本,而模型资产版本化则把模型文件、参数集、校准结果等非代码产物纳入同一套治理体系。

核心原理:代码版本与资产版本必须解耦又关联

精算模型通常由三部分组成:代码逻辑(如现金流引擎、准备金计算模块)、配置与参数(假设表、利率曲线、死亡率表)、模型资产(训练好的模型文件、校准系数、中间结果)。代码适合用 Git 管理,因为它是文本、可 diff、可合并;而模型资产往往是二进制大文件,直接塞进 Git 会导致仓库膨胀、克隆缓慢。因此实践中采用“代码进 Git,资产进制品库,用版本号与哈希关联”的双轨策略。

关键原则有三条:第一,任何一次生产运行都必须能定位到唯一的代码提交(commit SHA);第二,任何一次生产运行都必须能定位到唯一的资产版本(资产 ID 或内容哈希);第三,发布包是代码与资产的绑定快照,一旦发布不可篡改,只能新增版本。

代码仓库与模型资产版本化关联结构 Git 代码仓库 main / release / feature commit SHA: a1b2c3d tag: v2.3.0 配置: assumptions.yaml 模型资产库 model.pkl / .h5 / .onnx 资产ID: asset-2024-0912 内容哈希: sha256:9f3e... 校准系数 / 中间结果 发布包 Release release-v2.3.0.tar.gz 含代码 + 资产清单 manifest.json 签名与校验和 生产运行追溯链 运行记录 run-id: R20240912 代码版本 commit a1b2c3d 资产版本 asset-2024-0912 发布包 release-v2.3.0

方法流程:分支策略、标签与发布包

分支策略的选择取决于团队规模与发布节奏。对于精算模型生产,推荐采用主干保护 + 发布分支 + 特性分支的简化 Git Flow:

  • main:始终对应生产可用状态,只接受经过评审的合并,禁止直接推送。
  • release/*:从 main 切出,用于发布前的冻结与回归测试,只接受缺陷修复。
  • feature/*:每个模型改动或假设调整独立分支,完成后通过 Pull Request 合并。
  • hotfix/*:生产紧急修复,从对应 tag 切出,修复后同时合并回 main 与 release。

标签(tag)是版本管理的锚点。每次发布必须打语义化版本标签,格式为 v主版本.次版本.修订号,例如 v2.3.0。标签一旦推送不应删除或移动,否则追溯链断裂。发布包则是在标签基础上构建的不可变制品,包含代码、依赖清单、资产引用和校验和。

# 创建发布分支并冻结
git checkout -b release/v2.3.0 main
git push origin release/v2.3.0

# 发布前打标签(附注标签,含发布说明)
git tag -a v2.3.0 -m "Release 2.3.0: 更新退保率假设与准备金引擎"
git push origin v2.3.0

# 构建发布包,生成 manifest
python build_release.py --tag v2.3.0 --asset-id asset-2024-0912 \
  --output dist/release-v2.3.0.tar.gz

# manifest.json 示例
{
  "release": "v2.3.0",
  "commit": "a1b2c3d4e5f6",
  "asset_id": "asset-2024-0912",
  "asset_hash": "sha256:9f3e...",
  "built_at": "2024-09-12T10:30:00Z",
  "checksum": "sha256:7c1a..."
}
建议在 CI 流水线中自动校验:发布包的 commit SHA 必须与 tag 指向一致,资产哈希必须与资产库记录一致,任一不一致则阻断发布。

案例场景:季度准备金重跑的版本追溯

某寿险公司每季度需重跑准备金模型。某次监管问询要求解释“为何 Q2 与 Q1 的某险种准备金差异达 3.2%”。团队通过运行记录中的 run-id 反查:Q1 使用 release-v2.2.0(commit b7c8d9e,资产 asset-2024-0301),Q2 使用 release-v2.3.0(commit a1b2c3d,资产 asset-2024-0912)。进一步 diff 发现,Q2 更新了退保率假设表并重新校准了资产文件。由于版本链完整,团队在半天内完成了差异归因,而非数周的人工排查。

这个案例说明:版本管理的价值不在平时,而在被质疑、被审计、需要回滚的时刻。如果当时没有标签和资产哈希,差异归因将变成一场灾难。

误区与复盘

常见误区 后果 正确做法
模型文件直接提交到 Git 仓库膨胀、克隆缓慢、冲突无法合并 资产进制品库,Git 只存引用与哈希
用分支名代替标签发布 分支移动后无法复现历史版本 每次发布打不可变 tag
发布包构建后修改内容 追溯链断裂,审计不通过 发布包不可变,变更须新版本
资产版本与代码版本无关联记录 无法定位生产结果来源 manifest 中绑定 commit 与 asset_id
标签命名随意(如 fix、final) 版本语义混乱,难以比较 统一语义化版本规范
回滚不是“把代码切回旧分支”那么简单。回滚必须同时回滚代码、资产与配置,并验证三者组合的兼容性。建议在发布包中内置回滚脚本与依赖锁定文件,确保回滚可一键执行且结果可复现。

总结来说,精算模型生产部署的版本管理,本质是建立一条从运行记录到代码提交、到资产版本、到发布包的完整证据链。Git 提供代码的版本能力,标签提供不可变的发布锚点,发布包提供可交付的绑定快照,而模型资产版本化则补齐了非代码产物的治理缺口。四者协同,才能让模型生产从“能跑”走向“可信、可审、可回滚”。