DVC 使用案例(六):数据注册表

920 阅读4分钟

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

DVC 存储库的主要用途之一是数据和模型文件的版本控制。DVC 还支持这些数据制品跨项目复用。这意味着您的项目可以依赖于来自其他 DVC 存储库的数据,就像一个用于数据科学的包管理系统一样。

数据管理中间件

我们可以构建一个专用于数据集(或数据特征、ML 模型等)版本控制的 DVC 项目。

GIT 远程仓库中具有它跟踪的数据的所有元数据和更改历史记录。我们可以看到谁在何时更改了什么,并使用pull请求来更新数据,就像我们使用代码一样。这就是我们所说的数据注册表——机器学习项目和云存储之间的数据管理中间件。

数据注册表的优势:

  • 可重用性:使用简单的 CLI(dvc getdvc import 命令,类似于 pip 等软件包管理系统)重现和组织特征仓库(Feature Store)。
  • 持久性:由 DVC 注册表跟踪的远程存储(例如:S3 存储桶)提高了数据安全性。 例如,某人删除或改写 ML 模型的可能性较小。
  • 存储优化:将多个项目共享的数据集中在一个位置。 这简化了数据管理并优化了空间需求。
  • 数据即代码(管理数据就像管理代码一样):为您的数据和模型生命周期利用 Git 工作流,例如,提交、分支、拉取请求、审查(review),甚至 CI/CD。
  • 安全性:注册表可以设置使用只读远程存储(例如:HTTP 服务器)。

建立数据注册表

向注册表添加数据集非常简单,只需将数据文件或目录放在工作区内,并使用dvc add跟踪即可。 可以使用替换实际数据的 .dvc 文件(例如,下面的 music/songs.dvc文件)遵循常规的 Git 工作流程。 这使得团队可以在与源代码相同的级别上进行数据协作:

这个样本数据集真实存在,请预先下载,下载完成之后,执行如下操作:


$ mkdir -p music/songs
$ cp ~/Downloads/millionsongsubset_full music/songs

$ dvc add music/songs/

$ git add music/songs.dvc music/.gitignore
$ git commit -m "Track 1.8 GB 10,000 song dataset in music/"

实际数据存储在项目的缓存中,并且可以推送到一个或多个远程存储位置,以便其他人可以从其他位置访问注册表。

$ dvc remote add -d myremote s3://mybucket/dvcstore
$ dvc push

将 DVC 存储库组织到数据注册表中的一种好方法是使用目录对类似数据进行分组,例如:images/natural-language/

比如,我们的数据集注册表具有 get-started/use-cases/ 等目录,与该网站的部分内容相匹配。

使用数据注册表

使用数据注册表中的制品的主要方法是 dvc importdvc get 命令,以及 Python API dvc.api。 首先,我们可能想探索它的内容。

列出数据

要探索 DVC 存储库的内容以搜索合适的数据,请使用 dvc list 命令(类似于 ls 命令和第三方工具,如:aws s3 ls):

$ dvc list -R https://github.com/iterative/dataset-registry

.gitignore
README.md
get-started/.gitignore
get-started/data.xml
get-started/data.xml.dvc
images/.gitignore
images/dvc-logo-outlines.png
...

上面的命令列出了 Git 跟踪的文件和 DVC 跟踪的数据(或模型等)。

数据下载到工作目录

dvc get 类似于使用 wget (HTTP)、aws s3 cp (S3) 等直接下载工具。要从 DVC 存储库中获取数据集,我们可以运行以下命令:

$ dvc get https://github.com/example/registry music/songs

这将从项目的默认远程数据存储仓库下载music/songs,并将其放置在当前工作目录中。

数据导入到工作流程

dvc import 使用与 dvc get相同的语法:

$ dvc import https://github.com/example/registry images/faces

该命令除了下载数据外,导入还会保存本地项目对数据源(注册表存储仓库)的依赖关系的信息。 这是通过生成特殊的导入 .dvc 文件(包含元数据信息)来实现的。

每当注册表中的数据集发生更改时,我们都可以使用 dvc update 更新数据:

dvc update faces.dvc

这会根据源代码库中最新的提交下载新的和更改的文件,并删除已删除的文件;同时,它也会相应地更新 .dvc 文件。

注意:

dvc getdvc importdvc update 有一个 --rev 参数选项,用于从源存储库的特定的提交下载数据。

使用 Python 代码下载 DVC 数据

我们的 Python API 包含在与 DVC 一起安装的 dvc 包中,包括从外部 DVC 项目加载和直接流式传输数据的开放函数:

import dvc.api.open

model_path = 'model.pkl'
repo_url = 'https://github.com/example/registry'

with dvc.api.open(model_path, repo_url) as fd:
    model = pickle.load(fd)
    # ... Use the model!

这会将 model.pkl 作为文件描述符打开。 此示例演示了一种简单的 ML 模型部署方法,但它可以扩展到更高级的场景,例如:一个model zoo

除此之外,也可以参考 dvc.api.read()dvc.api.get_url() 函数。

更新数据注册表

数据集会不断更新,DVC 很容易应对它。只需更改注册表中的数据。通过再次运行 dvc add 来应用更新即可。

$ cp 1000/more/images/* music/songs/

$ dvc add music/songs/

DVC 修改相应的 .dvc 文件以体现更改,这会被 Git 收集:

$ git status

...
	modified:   music/songs.dvc
        
$ git commit -am "Add 1,000 more songs to music/ dataset."

对多个数据集重复这个过程可以形成一个健壮的注册表。结果基本上是一个库版本化一组元文件。

我们来看一个例子:

$ tree --filelimit=10
.
├── images
│   ├── .gitignore
│   ├── cats-dogs [2800 entries]  # Listed in .gitignore
│   ├── faces [10000 entries]     # Listed in .gitignore
│   ├── cats-dogs.dvc
│   └── faces.dvc
├── music
│   ├── .gitignore
│   ├── songs [11000 entries]     # Listed in .gitignore
│   └── songs.dvc
├── text
...

不要忘了使用dvc push将数据更改推送到远程存储 ,这样其他人就可以获得这些更改了!

$ dvc push