定义管道
管道代表你希望可靠地 重现 的数据工作流——以确保结果的一致性。典型的管道流程包括:
-
获取项目的初始数据需求,并使用
dvc add
或dvc import
进行跟踪(参见 数据版本控制)。这会将数据缓存并生成.dvc
文件。 -
在
dvc.yaml
文件中定义管道的 阶段(稍后详细介绍)。示例结构如下:stages: prepare: ... # stage 1 definition train: ... # stage 2 definition evaluate: ... # stage 3 definition
我们将这种基于文件的定义称为代码化(此处为 YAML 格式)。它还有一个额外的好处:可以让你在标准的 Git 工作流(以及 GitOps)上开发管道。
每个阶段通常会接收一些数据并运行某些代码,产生输出(例如一个机器学习模型)。通过使这些阶段相互依赖,就形成了管道,即一个阶段的输出成为另一个阶段的输入,依此类推。从技术上讲,这被称为依赖图(DAG)。
请注意,虽然每个管道都是一个图,但这并不意味着只能有一个 dvc.yaml
文件。DVC 会检查整个 项目 目录树,并验证所有此类文件以查找其中定义的阶段,重建所有可能存在的管道。
DVC 在内部将管道表示为一种图结构,其中节点是阶段,边是有向依赖关系(例如 A 在 B 之前)。为了使 DVC 能够运行管道,其拓扑必须是无环的——因为执行循环(例如 A -> B -> C -> A …)将会无限进行下去。关于 DAG 的更多内容。
使用 dvc dag
来可视化(或导出)这些图。
阶段
参见阶段条目的完整 规范。
每个阶段封装了一个可执行的 shell 命令,并指定了基于文件的 依赖项 以及 输出。来看一个示例阶段:它依赖于要运行的脚本文件和原始数据输入(理想情况下该数据已由 DVC 跟踪):
stages:
prepare:
cmd: source src/cleanup.sh
deps:
- src/cleanup.sh
- data/raw
outs:
- data/clean.csv
这些示例中我们使用的是 GNU/Linux,但也可以使用 Windows 或其他 shell。
除了手动编写 dvc.yaml
文件(推荐方式)外,还可以使用 dvc stage add
命令来创建阶段——这是一种有限的命令行接口,用于设置管道。让我们用这种方式添加另一个阶段,并查看生成的 dvc.yaml
:
$ dvc stage add --name train \
--deps src/model.py \
--deps data/clean.csv \
--outs data/predict.dat \
python src/model.py data/clean.csv
stages:
prepare:
...
outs:
- data/clean.csv
train:
cmd: python src/model.py data/model.csv
deps:
- src/model.py
- data/clean.csv
outs:
- data/predict.dat
使用 dvc stage add
的一个优点是它会验证所提供参数的有效性(否则阶段定义直到执行时才会被检查)。缺点是某些高级功能(如 模板)无法通过此方式使用。
注意,新的 train
阶段依赖于 prepare
阶段的输出(data/clean.csv
),从而形成了管道(DAG)。
阶段的执行顺序将完全由有向无环图(DAG)决定,而不是由 dvc.yaml
中阶段出现的顺序决定。
简单依赖项
阶段依赖项有多种类型。简单依赖项是指被阶段命令用作输入的文件或目录。当其内容发生更改时,DVC 会“使该阶段失效”——即知道需要重新运行该阶段(参见 dvc status
)。这反过来可能引发连锁反应,导致后续的 流水线 阶段也被重新执行。
DVC 计算文件/目录内容的哈希值,并与之前的版本进行比较。这是与传统的构建工具(如 make
)相比的一个显著机制差异。
文件系统级别的依赖项在 dvc.yaml
阶段的 deps
字段中定义;或者,也可以使用 dvc stage add
命令的 --deps
(-d
) 选项来定义(参见上一节的示例)。
参数依赖项
另一种更细粒度的依赖类型是参数(dvc.yaml
中的 params
字段),在机器学习中也称为超参数(hyperparameters)。这些是你代码中用于调整数据处理过程或以其他方式影响阶段执行的任何值。例如,训练一个 神经网络 通常需要指定 批量大小 和 训练轮数 等值。
与其将参数值硬编码在代码中,不如让代码从结构化文件(例如 YAML 格式)中读取它们。DVC 可以跟踪支持的 参数文件(默认为 params.yaml
)中的任意键值对。参数属于细粒度依赖项,因为只有当参数文件的相应部分发生变化时,DVC 才会使相关阶段失效。
stages:
train:
cmd: ...
deps: ...
params: # from params.yaml
- learning_rate
- nn.epochs
- nn.batch_size
outs: ...
参见 更多细节 了解此语法。
使用 dvc params diff
来比较项目不同版本之间的参数。
输出结果
阶段输出是由 流水线 写入的文件(或目录),例如机器学习模型和中间产物。这些文件会被 DVC 自动 缓存,并通过 dvc.lock
文件(或 .dvc
文件,参见 dvc add
)进行追踪。
输出可以作为后续阶段的依赖项(如前所述)。因此,当它们发生变化时,DVC 可能也需要重新生成下游阶段(此过程由系统自动处理)。
DVC 还可以跟踪 指标 和 图表 文件,这些文件可选择性地作为阶段输出添加,或者甚至可以在 dvc.yaml
中设置 cache: false
后添加,因为它们通常足够小,可以直接存储在 Git 中。