Why Version Control for AI
AI 场景的开发涉及大量迭代工作,开发人员需要在修改超参数、代码和数据的过程中优化模型性能。AI 工作流中的主要组成部分包括:
代码
- 训练代码:用于构建模型、训练和优化。
- 推理代码:用于部署和生产环境中的预测。
数据
- 包含不同类型的多模态数据(如图像、文本、音频)。数据集可能会不断更新、清洗或扩展,管理不同版本的数据尤为重要。
模型
- 包括模型结构、训练后的权重、超参数及依赖的环境配置。
版本控制确保以下关键目标:
- 可再现性:通过追踪数据、模型和代码的版本,确保结果的准确性。
- 可迭代:AI 工程师需要循环数据准备、开发、训练和评估的过程。版本控制可以追踪记录整个开发的生命周期。
- 协作:管理多人协作中的版本冲突,提高团队效率。
- 错误恢复:在代码缺陷或数据污染时,支持快速回滚和恢复。
Why Git
+ 轻量级且广泛使用的版本控制系统。
+ 大部分交互可以在本地执行
+ 与代码开发的工具链(如 CI/CD)集成良好。
- Git 将文件的版本存储为 blob。这些 blob 是经过 diff 压缩的,因此仅存储差异,不适合管理大文件和二进制数据(如数据集和模型)。
- 在数据密集型项目中,Git 仓库易膨胀且性能下降。
Why Not Git-LFS
+ Git-LFS 提供了一个解决方案,通过将旧版本的大型二进制文件存储在存储库之外的位置(远程)并用指针文件替换它。
+ 如果需要旧版本,则客户端从远程获取它。因此,如果设计者从远程拉取最新状态,他只会下载最新状态和指针文件。
- 需要额外的服务(插件)支持远程(本地)存储。
- 仅通过 HTTP 传输数据。
Why DVC
+ 将大文件与 Git 仓库分离,避免仓库过度膨胀。
+ 实现数据、模型和代码的版本绑定,确保一致性。
+ 无服务依赖,仅通过命令行交互。
- 额外的知识依赖
基本方案
Git 负责 DVC 元数据的版本管理。
DVC 负责所有数据的版本控制和外部存储。
如何实现
图示
初始化数据目录
从其他地方拷贝一个数据集并初始化版本管理
1 | # cd /dataset_dir |
git init
:初始化 git 环境(包含 .gitignore
、.git 目录
等)dvc init
:初始化 dvc 环境(包含 .dvcignore
、.dvc 目录
等)dvc add *
:将所有数据交由 dvc 版本控制
- 数据会缓存到
.dvc/cache
下 - 每个文件/文件夹会生成一个
.dvc
结尾的元数据文件dvc remote add -d dvcstore /share/dvcstore/
:添加 dvc 的远程存储(本地路径),用于在集群各处通过.dvc
元数据获取数据文件dvc push
:将 dvc 数据推送到远程存储git add .
:添加所有改动到 git 暂存区(数据文件本身已经被加入到.gitignore
中)git commit -m 'Initial commit'
:git 提交
版本控制(基于 tag)
1 | # git tag v0.1 |
find ...
把当前目录下非.dvc
结尾的非隐藏文件交给 dvc 管理版本
下载到个人目录
1 | $ git clone /share/dataset/fund_mkt_art |
切换到指定版本
1 | $ git clone /share/dataset/fund_mkt_art |
- 在目录执行
dvc install
可以配置在git checkout
之后自动跟随dvc checkout
的 git hook
下载指定版本(纯本地方案不适用)
1 | $ git clone --depth 1 --branch v0.1 /share/dataset/fund_mkt_art |
数据目录结构
1 | / |
效率测试
测试文件:
1 | -rw-r--r-- 1 root root 11G Oct 21 14:51 nvidia_pytorch_21_04_py3.sqsh |
cp
1 | # time cp nvidia_pytorch_21_04_py3.sqsh dvc_image/ |
git add
1 | # time git add . |
lfs track
1 |
dvc add
1 | # time dvc add * |
dvc push
1 | # time dvc push |
dvc pull
1 | $ time dvc pull |
已知问题
DVC
- DVC 并不能实现类似
git add .
的方式以将所有改动暂存或提交,目前只能配合find
命令处理根目录的文件并分别执行dvc add
- 当(根目录的)文件被删除时,DVC 可以追踪到变更但不会自动提交,目前需要通过
dvc status
过滤并分别执行dvc remove
- DVC 对于每个追踪的文件(仅根目录)会生成
.dvc
文件,需要在文件接口过滤,并且不好防止用户无意删除 - 远程本地存储时,权限在 root,普通用户无法 push,得单独配置私有远程存储,或改变公共目录权限
Git-LFS
- 当从 Git 下载大数据时,通常仍需要使用
git-lfs
来拉取大文件 git lfs track
类型需要维护- 纯本地兼容性差,有损坏风险
参考资料
- https://neptune.ai/blog/version-control-for-ml-models
- https://learn.microsoft.com/en-us/data-engineering/playbook/articles/data-versioning-in-ml
- https://www.linkedin.com/advice/0/how-can-you-manage-version-control-ai-programming-r5ief
- https://lakefs.io/blog/dvc-vs-git-vs-dolt-vs-lakefs/
- https://github.com/git-lfs/git-lfs/wiki/Tutorial