3、版本管理基础:Git核心概念(仓库、提交、分支、标签)在AI项目中的应用

说实话,很多做AI的工程师一开始对Git不太上心。觉得模型训练嘛,改改参数、跑跑实验,用文件夹命名就够了。我以前也这么干过——模型叫model_final_v3_真的不改了.h5,结果第二天又改了一版,变成了model_final_v3_再也不改了_v2.h5。嗯,你懂的,这种命名法迟早会翻车。

在STM32Cube.AI项目里,模型版本管理不是锦上添花,而是保命手段。一个模型从训练到量化、从评估到部署,中间可能经历几十次迭代。没有Git,你根本不知道哪个版本在板子上跑得好,哪个版本是废的。

3.1 仓库(Repository):你的项目根目录

仓库说白了就是一个文件夹,但Git会在这个文件夹里藏一个.git目录,用来记录所有历史。我习惯把每个AI项目单独建一个仓库,而不是把所有模型塞到一个大仓库里。

一个典型的STM32Cube.AI项目仓库结构长这样:

stm32_gesture_model/
├── .git/
├── datasets/          # 原始数据集
├── training/          # 训练脚本和配置
│   ├── train.py
│   ├── config.yaml
│   └── model.py
├── evaluation/        # 评估脚本和结果
│   ├── evaluate.py
│   └── results/
├── stm32_deploy/      # 部署到STM32的工程文件
│   ├── model.c
│   ├── model.h
│   └── stm32_project/
├── models/            # 模型文件(.h5, .tflite, .c)
│   ├── v1.0/
│   ├── v1.1/
│   └── v2.0/
└── README.md

这里有个关键点:不要把大型数据集直接放进Git仓库。我见过有人把几个G的图片集提交进去,结果仓库变得臃肿不堪,clone一次要半小时。正确的做法是用.gitignore忽略掉datasets/raw/这类大文件,或者用Git LFS(Large File Storage)来管理。

核心原则:仓库里只放代码、配置文件、文档和小型模型文件。原始数据集和中间产物用外部存储。

3.2 提交(Commit):记录每一次实验快照

提交就是给项目拍一张快照。每次你改了什么,Git都会记录下来,包括谁改的、什么时候改的、改了什么内容。

在AI项目里,提交的粒度很重要。我建议:

  • 每次修改模型结构或训练参数后,立即提交一次
  • 提交信息要写清楚实验目的,比如“增加BN层,学习率改为0.001”
  • 不要提交未训练完的中间结果,除非你有特殊原因

举个例子,我一般这样提交:

git add training/config.yaml training/model.py
git commit -m "实验#12: 增加Dropout(0.3),学习率从0.01降到0.001,验证集准确率提升2%"

为什么要写这么详细?因为两周后你回头看,根本想不起来当时改了啥。我曾经就吃过这个亏——翻看提交历史,全是“update model”、“fix bug”这种废话,气得我差点把电脑砸了。

我的习惯:每次提交前,先用git diff看看改了哪些文件。确认没有误改或漏改,再提交。这个习惯帮我避免过好几次灾难。

3.3 分支(Branch):并行实验的利器

分支是Git最强大的功能之一。你可以从主线上分出一条支线,在上面做实验,不影响主线。实验成功了就合并回去,失败了就删掉分支,干净利落。

在STM32Cube.AI项目里,我通常这样管理分支:

分支名称 用途 说明
main 稳定版本 已经验证过、可以部署到板子的模型
develop 开发主线 日常实验和迭代的基础分支
exp/quantization 量化实验 尝试不同的量化策略
exp/architecture 网络结构实验 修改模型结构,比如换激活函数
fix/overfitting 修复过拟合 专门用来调正则化参数

我个人习惯用exp/前缀来标识实验分支,这样一看就知道是临时性的。实验结束后,要么合并到develop,要么直接删掉。

注意:分支不是越多越好。我见过有人开了十几个分支,最后自己都分不清哪个是哪个。建议同时活跃的分支不超过3个,做完一个删一个。

3.4 标签(Tag):给关键版本打上标记

标签就像给某个提交贴一个醒目的标签。它和分支不同——标签是只读的,不能在上面继续开发。我主要用标签来标记:

  • 发布到STM32板子的模型版本(比如v1.0-deploy)
  • 关键实验节点(比如exp-12-best-acc)
  • 论文或报告中的版本(比如paper-v1-submit)

打标签很简单:

git tag -a v1.0-deploy -m "部署到STM32F746的最终版本,量化后准确率97.2%"
git push origin v1.0-deploy

为什么要用标签而不是分支?因为标签不会移动。分支会随着新提交而前进,但标签永远指向同一个点。这样你随时可以切回那个版本,重新生成模型或者对比结果。

我的经验:每次把模型部署到板子之前,一定打一个标签。这样如果板子上跑出问题,可以快速定位是哪个版本,然后回退或对比。

3.5 知识结构图:Git在AI项目中的核心逻辑

下面这张图展示了Git四个核心概念在AI项目中的关系:

Git核心概念在AI项目中的应用关系 仓库 (Repository) 项目根目录,包含代码、配置、文档 提交 (Commit) 分支 (Branch) 标签 (Tag) 记录每次实验快照 提交信息要写清楚实验目的 粒度:每次改参数或结构后提交 并行实验,互不影响 exp/前缀标识实验分支 实验结束及时合并或删除 标记关键版本(只读) 部署前必须打标签 方便回退和对比 AI项目中的Git工作流 1. 在develop分支上开发 → 2. 开exp/分支做实验 → 3. 实验成功合并回develop 4. 验证通过后合并到main → 5. 打标签发布 → 6. 清理过期分支

3.6 实战建议:AI项目的Git工作流

说了这么多理论,来点实际的。我在STM32Cube.AI项目里总结了一套工作流,你可以直接拿来用:

  1. 初始化仓库:git init,然后创建.gitignore,忽略*.h5、*.tflite、datasets/等大文件
  2. 创建develop分支:git checkout -b develop,日常开发都在这个分支上
  3. 开实验分支:git checkout -b exp/add-bn-layer,做具体实验
  4. 频繁提交:每次改完参数或代码,提交一次,写清楚实验编号和结果
  5. 合并或删除:实验成功就合并到develop,失败就删掉分支
  6. 打标签发布:验证通过后合并到main,打上v1.0-deploy标签
小技巧:在README.md里维护一个版本记录表,写上每个标签对应的模型准确率、量化方式、部署板型。这样别人(包括未来的你)一看就明白。

Git这东西,刚开始用觉得麻烦,用习惯了就离不开。尤其是做AI项目,实验多、版本杂,没有版本管理简直是自找麻烦。我建议你从今天开始,每个AI项目都用Git管起来,哪怕只是一个人做。等哪天你需要回退到三天前的版本时,你会感谢自己的。