DVC 使用指南:项目结构中dvc.yaml文件详解

1,708 阅读3分钟

这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战

您可以通过在一个或多个 dvc.yaml 文件(或流水线文件)中定义各个阶段(Stage)来构建数据科学或机器学习流水线(Pipeline)。 Stage 相互连接时形成 Pipeline (形成依赖关系图,具体请见: dvc dag)。

注意:命令 dvc stage 可用于创建和列出 Stage 。

dvc.yaml 文件可以使用 Git 进行版本控制。

这些文件使用 YAML 1.2 文件格式。 我们鼓励您熟悉它,以便您可以自己修改、编写或生成 Stage 和 Pipeline。

阶段(Stages)

stages 列表包含一个或多个用户定义的 stages。 这是一个名为 transpose 的简单 stages:

stages:
  transpose:
    cmd: ./trans.r rows.txt > columns.txt
    deps:
      - rows.txt
    outs:
      - columns.txt

另请参阅 dvc stage add,一个用于在 dvc.yaml 中编写 Stage 的辅助命令。

Stage 中最重要的部分是它执行的终端命令(cmd 字段)。 这就是 DVC 在 Stage 再现时运行的内容(请参阅 dvc repro)。

如果命令读取输入文件,则这些文件(或它们的目录位置)可以定义为依赖项(deps)。 DVC 会检查它们是否已经改变来决定该 Stage 是否需要重新执行(请参阅 dvc status))。

如果它写入文件或目录,则可以将它们定义为输出(outs)。 DVC 将继续跟踪它们(类似于使用 dvc add)。

请参阅完整的 Stage 条目规范

参数依赖(Parameter dependencies)

Parameters是一种特殊类型的 Stage 依赖。 它们由一个 name/value 对组成,可在 YAML、JSON、TOML 或 Python 参数文件(默认为 params.yaml)中发现。 具体示例如下:

stages:
  preprocess:
    cmd: bin/cleanup raw.txt clean.txt
    deps:
      - raw.txt
    params:
      - threshold
      - passes
    outs:
      - clean.txt

这允许多个 Stage 依赖于共享结构化文件的值(可以直接使用 Git 对其进行版本控制)。 另请参见 dvc params diff

指标和图表输出

常见的输出一样,指标和图表文件由 Stage 的 cmd 生成。 但是,它们的目的是不同的。 通常,它们包含用于评估流水线流程的元数据。 具体示例如下:

stages:
  build:
    cmd: python train.py
    deps:
      - features.csv
    outs:
      - model.pt
    metrics:
      - accuracy.txt:
          cache: false
    plots:
      - auc.json:
          cache: false

其中,cache: false 在这里是特有的,因为它们足够小,可以让 Git 直接进行版本控制。

dvc metricsdvc plots命令可帮助您显示和比较指标和图表。

模板(Templating)-DVC 2.0

这是 DVC 2.0 中的新功能(具体请参见 dvc version

dvc.yaml 支持模板(Templating)格式以在 YAML 结构中插入来自不同来源的值。 这些来源可以是 parameters filesdvc.yaml 中定义的 vars

请注意,此参数化功能仅支持通过手动编辑 dvc.yaml ,并且与 dvc run 不兼容。

假设我们有一个params.yaml(默认参数文件)具有以下的内容:

models:
  us:
    threshold: 10
    filename: 'model-us.hdf5'

这些值可以在 dvc.yaml 中的任何位置使用 ${} 替换表达式:

stages:
  build-us:
    cmd: >-
      python train.py
      --thresh ${models.us.threshold}
      --out ${models.us.filename}
    outs:
      - ${models.us.filename}:
          cache: true

DVC 将跟踪 ${} 中使用的简单参数值(数字、字符串等)(它们将由 dvc params diff 列出)。

或者,可以将替换值列为顶级 vars,如下所示:

vars:
  - models:
      us:
        threshold: 10
  - desc: 'Reusable description'

stages:
  build-us:
    desc: ${desc}
    cmd: python train.py --thresh ${models.us.threshold}

请注意,来自 vars 的值不会像参数一样被跟踪。

要加载其他参数文件,请按所需顺序将它们列在顶部的 vars 中,例如:

如果有的话,参数文件路径将根据 wdir 进行评估。

vars:
  - params.json
  - myvar: 'value'
  - config/myapp.yaml

请注意,默认的params.yaml文件总是首先加载(如果存在的话)。

还可以使用 : 冒号指定要从其他参数文件中包含的内容:

vars:
  - params.json:clean,feats

stages:
  featurize:
    cmd: ${feats.exec}
    deps:
      - ${clean.filename}
    outs:
      - ${feats.dirname}

还支持 Stage 特有的值,带有内部 vars。 您还可以在本地加载其他参数文件。 例如:

stages:
  build-us:
    vars:
      - params.json:build
      - model:
          filename: 'model-us.hdf5'
    cmd: python train.py ${build.epochs} --out ${model.filename}
    outs:
      - ${model.filename}

DVC 会尽可能在每个范围内合并来自 params 文件和 vars 的值。 例如,{"grp": {"a": 1}}{"grp": {"b": 2}} 合并,但不与{"grp": {"a": 7}}

⚠️ 本地vars的已知限制:

  • wdir 不能使用本地 vars 中的值,因为 DVC 首先使用工作目录(从 vars 中列出的 params 文件加载任何值)。
  • 目前,foreach 也与本地vars 不兼容。

替换表达式支持以下形式:

${param} # Simple
${param.key} # Nested values through . (period)
${param.list[0]} # List elements via index in [] (square brackets)

要在 dvc.yaml 中按字面意思使用表达式(即 DVC 不会将其替换为值),请使用反斜杠对其进行转义,例如 \${....

foreach 阶段-DVC 2.0

这是 DVC 2.0 中的新功能(具体请参见 dvc version

您可以使用以下语法在单个 dvc.yaml 条目中定义多个 Stage 。 一个 foreach 元素接受一个列表或字典,其中包含要迭代的值,而 do 包含常规 Stage 字段(cmdouts等)。

这是一个简单的例子:

stages:
  cleanups:
    foreach: # List of simple values
      - raw1
      - labels1
      - raw2
    do:
      cmd: clean.py "${item}"
      outs:
        - ${item}.cln

dvc repro 时,列表中的每个 item 都会通过替换表达式${item}中的值来展开到自己的 Stage 。item 的值附加到每个 Stage 名称后的@,其格式为:stage名@item的值foreach 语法生成的最终的 Stage 保存到 dvc.lock,如下所示:

schema: '2.0'
stages:
  cleanups@labels1:
    cmd: clean.py "labels1"
    outs:
      - path: labels1.cln
  cleanups@raw1:
    cmd: clean.py "raw1"
    outs:
      - path: raw1.cln
  cleanups@raw2:
    cmd: clean.py "raw2"
    outs:
      - path: raw2.cln

对于包含复杂值的列表(例如字典),替换表达式可以使用${item.key} 形式。 Stage 名称将附加一个从零开始的索引。 例如:

stages:
  train:
    foreach:
      - epochs: 3
        thresh: 10
      - epochs: 10
        thresh: 15
    do:
      cmd: python train.py ${item.epochs} ${item.thresh}

dvc.lock文件如下所示:

# dvc.lock
schema: '2.0'
stages:
  train@0:
    cmd: python train.py 3 10
  train@1:
    cmd: python train.py 10 15

DVC 还可以对直接提供给 foreach 的字典进行迭代,从而产生两个可用的替换表达式:${key}${item}。 前者用于 Stage 名称:

stages:
  build:
    foreach:
      uk:
        epochs: 3
        thresh: 10
      us:
        epochs: 10
        thresh: 15
    do:
      cmd: python train.py '${key}' ${item.epochs} ${item.thresh}
      outs:
        - model-${key}.hdfs

dvc.lock文件如下所示:

# dvc.lock
schema: '2.0'
stages:
  build@uk:
    cmd: python train.py 'uk' 3 10
    outs:
      - path: model-uk.hdfs
        md5: 17b3d1efc339b416c4b5615b1ce1b97e
  build@us: ...

重要的是,来自 参数文件 的字典也可以用于foreach阶段:

stages:
  mystages:
    foreach: ${myobject} # From params.yaml
    do:
      cmd: ./script.py ${key} ${item.prop1}
      outs:
        - ${item.prop2}

注意,此功能目前与 模板 不兼容。

Stage 条目

这些是每个Stage接受的字段:

字段描述
cmd(必须的) Stage 执行的一个或多个命令(可能包含单个值或列表)。 命令按顺序执行,直到所有命令都完成或其中一个失败(请参阅 dvc repro)。
wdirstage命令要在其进行运行的工作目录(相对于文件的位置)。其他字段中的任何路径也基于此工作目录。默认为.(文件的位置)。
deps此 Stage 的依赖路径列表(相对于wdir)。
outs此 Stage 的输出路径列表(相对于wdir)。 这些可以包含某些可选的 子字段
params要从params.yaml(在wdir中)跟踪的参数依赖键(字段名称)列表。 该列表还可能包含其他参数文件名,以及要在他们之中进行跟踪的参数名称的子列表。
metrics指标文件 列表,以及是否缓存此指标文件(默认情况下为true)(可选)。 请参阅 dvc run--metrics-no-cache(-M) 选项。
plots图表指标 列表,以及可选的默认配置(匹配 dvc plots modify命令参数选项的子字段),以及此图表文件是否被缓存(默认为 true)。 请参阅 dvc run--plots-no-cache 参数选项。
frozen这个阶段是否因重现而冻结
always_changed此阶段是否被 dvc status 和 dvc repro等命令视为已更改。 默认 为false
meta(可选的) 可以使用此字段手动添加任意元数据。 支持任何 YAML 内容。 meta 内容被 DVC 忽略,但它们对于直接读取或写入 .dvc 文件的用户进程可能有意义。
desc(可选的) 此 Stage 的用户描述。 这不会影响任何 DVC 操作。
live(可选的) Dvclive 配置字段

dvc.yaml 文件也支持 # 号注释 ,如:# the comments is demo

请注意,我们维护一个 dvc.yaml schema  可供 VSCode 或  PyCharm 等编辑器使用,目的是为了启用自动语法验证和自动完成。

请参阅如何合并冲突

输出(output)子字段

其中包括 .dvc 文件 output 条目 中的部分字段。

字段描述
cache是否缓存此文件或目录(默认为true)。 请参阅 dvc add--no-commit 选项参数。
remote(可选的) 用于pushing/fetching的远程存储的名称。
persistdvc repro 运行时是否应保留输出文件/目录(默认为falsedvc repro 启动时会删除输出
checkpoint(可选的) 设置为 true 让 DVC 知道此输出与 checkpoint 实验 相关联。 这些输出将恢复到它们在 dvc exp run 处的最后一个缓存版本,并且在 Stage 执行期间也“持久化”。
desc(可选的) 此输出的用户描述。 这不会影响任何 DVC 操作。

⚠️ 请注意,使用 dvc.yaml 中的 checkpoint 字段与 dvc repro不兼容。

dvc.lock 文件

避免编辑这些文件。 DVC 将为您创建和更新它们。

为了记录流水线的状态并帮助跟踪其输出,DVC 对于每个 dvc.yaml 将维护一个 dvc.lock  文件。 他们的目的包括:

  • 当 Stage 定义或其依赖关系发生变化时,允许 DVC 检测。此类状况将使 Stage 无效,需要对其进行重新生产(参见 dvc status)。
  • 跟踪流水线的中间和最终输出---类似于 .dvc 文件。
  • 需要多个 DVC 命令才能运行,例如: dvc checkoutdvc get

具体示例如下:

schema: '2.0'
stages:
  features:
    cmd: jupyter nbconvert --execute featurize.ipynb
    deps:
      - path: data/clean
        md5: d8b874c5fa18c32b2d67f73606a1be60
    params:
      params.yaml:
        levels.no: 5
    outs:
      - path: features
        md5: 2119f7661d49546288b73b5730d76485
        size: 154683
      - path: performance.json
        md5: ea46c1139d771bfeba7942d1fbb5981e
        size: 975
      - path: logs.csv
        md5: f99aac37e383b422adc76f5f1fb45004
        size: 695947

dvc.lock 中再次列出了 Stage ,以便了解它们的定义是否在 dvc.yaml中发生了变化。

常规的依赖项和所有形式的输出项(包括 metricsplots 文件)也在 dvc.lock 中,包括一个内容哈希字段(md5etagchecksum)。

每个参数文件名下也列出了完整的参数依赖项(包括键和值)(在params下)。 templated dvc.yaml 文件,实际值写入了dvc.lock(没有${}表达式)。

至于 foreach 阶段,扩展了各个 Stage(不保留foreach 结构)。