跳转到内容

DVC — 数据版本管理

待复核

DVC(Data Version Control)是一个把 Git 的版本管理思路搬到「数据 / 模型 / pipeline」上的命令行工具。

日常类比:你有一个写论文的文件夹,文档可以丢进 Git,但里面那个 50GB 的实验数据 Git 接不住。DVC 的做法是——在 Git 里只放一张「领货单」(写明这份数据的 hash 和它存在哪个仓库),真数据放远端(S3、Google Drive、自建磁盘都行)。Git 还是那个 Git,体积没炸;但你 git checkout 到任何一个旧 commit,都能用 dvc pull 把那一刻对应的数据精确拉回来。

一句话:Git 管代码 + 一张领货单,DVC 凭领货单把对应版本的数据拉回来

不用 DVC 的 ML 项目最常见的几种崩溃:

  • 「上周那个 92% 的模型怎么复现?」—— 代码在,数据不知道是哪一版
  • 「我 pull 了你的代码,跑出来的指标完全不对」—— 数据集对不上
  • 「Git LFS 顶不住 100GB 训练集」—— LFS 只解决文件存储,不解决 pipeline

DVC 把这些问题统一成一个工作流:代码、数据、实验指标都进 Git diff,整个项目变成可版本化、可复现、可团队协作的资产。这就是它叫自己 「Git for data」 的原因。

DVC 主要做四件事,一件比一件抽象:

  1. 数据当文件管dvc add data.csv 生成一个 data.csv.dvc 占位文件(写明 hash + 大小),原文件被 .gitignore,hash 进 Git。git diff 能看出「数据变了」。
  2. 远端存储dvc remote add -d storage s3://... 配好后,dvc push 把数据传到 S3,dvc pull 拉回来。命令模仿 git push/pull,心智模型一致。
  3. Pipeline 描述:在 dvc.yaml 里写每个 stage 的 cmd(怎么跑)、deps(依赖什么)、outs(产出什么),DVC 自动构造成 DAG。
  4. 只重跑变了的部分dvc repro 检查 hash,输入没变的 stage 直接跳过——和 make / bazel 一个思路,但是面向 ML 的数据流。

更进一步,dvc exp run 每次跑都自动记录 params.yaml(参数)和 metrics.json(指标),可以列出实验表、对比不同跑法的 diff。

工作目录的物理结构大致是:

  • .dvc/ 配置 + 本地 cache(hash 寻址,类似 .git/objects
  • data/raw.csv.dvc 占位文件(进 Git)
  • data/raw.csv 真数据(被 .gitignore,由 cache 软链或硬链而来)
  • 远端 S3 / GCS / OSS / 本地磁盘 = 共享版本的 cache

案例 1:最小工作流(5 行命令)

Section titled “案例 1:最小工作流(5 行命令)”
Terminal window
git init && dvc init
dvc add data/raw.csv # 生成 data/raw.csv.dvc 这个占位文件
git add data/raw.csv.dvc .gitignore
git commit -m "track raw data"
dvc remote add -d storage s3://my-bucket/dvcstore
dvc push # 数据上 S3

队友拿到这个仓库:

Terminal window
git clone <repo> && dvc pull # Git 拿代码 + 占位符,DVC 凭占位符拉回数据

dvc.yaml

stages:
prepare:
cmd: python src/prep.py data/raw.csv data/clean.csv
deps: [src/prep.py, data/raw.csv]
outs: [data/clean.csv]
train:
cmd: python src/train.py data/clean.csv model.pkl
deps: [src/train.py, data/clean.csv]
outs: [model.pkl]
metrics: [metrics.json]

跑一遍:dvc repro。改了 prep.py → prepare 重跑、train 跟着重跑;只改了 train.py → prepare 跳过,只 train 重跑。

Terminal window
dvc exp run --set-param train.lr=0.01
dvc exp run --set-param train.lr=0.001
dvc exp show # 列出两次实验的参数 + 指标对照表

每个实验对应一个临时 commit(Git 内的 ref,不污染主线),效果好的可以 dvc exp apply <id> 落到主分支,普通的 dvc exp gc 一键回收。

.github/workflows/ml.yml 里调 CML:

- run: dvc pull
- run: dvc repro
- run: cml comment create metrics.json # PR 评论里贴出指标 + 图

这样每个 PR 都自动跑一遍训练,把指标 / 曲线贴回评论区,code review 时数据和代码一起被审。

  1. Git 不熟会更晕:DVC 是 Git 的扩展不是替代,要先理解 add / commit / branch / checkout 的心智模型。
  2. 超大文件 push 慢:几十 GB 单文件传 S3 要分块上传,看 dvc remote modify 配并发。
  3. Windows 下 symlink 不稳:默认 cache 用 reflink/symlink,Windows 退化成 copy 会占双倍磁盘。dvc config cache.type copy 显式声明更可控。
  4. 改了 pipeline / 数据指针忘进 Gitdvc.yaml(pipeline)和 *.dvc(数据占位/领货单)都要 git add + commit。只改本地不提交,队友 checkout 后会拿到旧指针,或你自己换分支后 dvc repro 对不上。
  5. 手动改 .dvc 里的 hash:会让 dvc pull 找不到数据。这文件只能由 dvc add / dvc commit 生成,不能手编辑。

适用

  • ML 项目里数据集 / 模型权重要打版本(v1 / v2 / 加清洗后的 v3)
  • 数据预处理 pipeline 要复现——队友 git pull 后跑 dvc repro 拿一致结果
  • 中小团队,数据存私有 S3 / OSS,代码 + hash 走 Git,权限分层
  • 想把 ML 跑进 CI(搭配同公司的 CML,PR 自动跑实验贴报告)

不适用

  • 完全数据湖规模(PB 级别)→ 用 LakeFS / Delta Lake
  • 偏「实验追踪 + 模型注册」、不在乎数据 hash → 用 MLflow / Weights & Biases
  • 重量级 ML 平台(要 K8s 原生 pipeline + 多租户)→ 用 Pachyderm / Kubeflow
  • 纯文本仓库(无大文件)→ Git 就够
  • 2017 年:Dmitry Petrov 在 Microsoft 做 ML 项目时痛感「数据复现」无解,写出 DVC 雏形(同年 5 月公开 beta)。
  • 2018 年:与 Ivan Shcheklein 成立 Iterative.ai,把 DVC 定位成「Git for ML」。
  • 2020 年:DVC 1.0;之后陆续加强 dvc.yaml pipeline、dvc exp 实验追踪,并推出 CML(CI 里贴指标)。
  • 2024 年前后:GitHub 约 14k+ star;DVC / CML / MLEM / Studio 组成 Iterative 的「GitOps for ML」矩阵。
  • 2025 年末:lakeFS(Treeverse)宣布收购 DVC,项目继续开源演进。
  1. 占位符 + 远端这套思路通用:不光数据,模型权重、Notebook 中间产物都能这么管。本质是把「内容」和「位置」解耦——Git 管位置(hash),存储看场景换。
  2. DAG + hash 让「只重跑变了的部分」变得自然——和 make / bazel / nix 是一脉相承的工程美学。区别只是节点装的是数据集而不是 .o 文件。
  3. diff 友好才能进 code review:参数 / 指标 / 数据 hash 都做成可 diff 的小文本,PR 才能审。这条对所有「想被纳入 Git 流程」的工具都成立。
  4. 工具不替代 Git,要长在 Git 上:DVC 的所有命令都和 Git 同形(add / push / pull / checkout),学习曲线大幅降低。同样思路在 Nix flake、Pulumi、Terraform 也能看到。
  • 官方文档:dvc.org/doc(Get Started 半小时能跑通 add/push/pull)
  • 仓库:iterative/dvc(现由 lakeFS/Treeverse 继续维护)
  • CML:cml.dev —— 和案例 4 配套的 CI 报告工具
  • 对比阅读:Git LFS 文档 —— 看清「只存大文件」和「pipeline + 复现」差在哪
  • mlflow —— 实验追踪侧重点不同,常和 DVC 搭配
  • lakefs —— 数据湖层级的 Git 抽象,规模更大时的下一家
  • airflow —— 通用任务编排,DAG 思路同源但不管数据 hash
  • mlflow —— 实验追踪侧重,和 DVC 经常搭配
  • lakefs —— 数据湖层级的 Git 抽象,规模更大
  • git-lfs —— 只解决大文件存储,DVC 的最小子集
  • clearml —— ClearML — 实验跟踪 + 远程执行 + 数据管理三合一
  • label-studio —— Label Studio — 文本图像音视频时序通吃的标注王者
  • mlflow —— MLflow — 端到端 ML 生命周期