背景
最近 DVC を用いてデータセットの管理をしているのですが、複数枚の画像を含むディレクトリをデータセットとしてDVCで管理する機会がありました。
その際に画像の名前がハッシュ化されて .dvc/cache/
ディレクトリ内に保存され、元のデータ構造とは異なるデータ構造で保存されていました。
dvc pull
をしてくると、当然元のデータ構造に戻るわけですが、どのようにして復元しているのか気になったので調べてみました。
本記事では、まずDVCで「単一ファイル」と「ディレクトリ」を管理した場合のキャッシュ・メタデータ構造の違いを整理し、それぞれがどのように管理・復元されているかを解説します。
最後に、dvc pullによるデータセットの復元方法の概要についてまとめます。
環境
バージョン
- Python: 3.11
- DVC: 3.60.1
単一ファイルを管理する場合のキャッシュとメタデータ
たとえば data/sample.txt
というファイルをDVCで管理した場合、ファイル構成は以下のようになります。
プロジェクト
├── .dvc
│ └── cache
│ └── files
│ └── md5
│ └── a1
│ └── 136e8530eeb4cfd7a7bc6cfd545382
└── data
├── sample.txt
└── sample.txt.dvc
それぞれのキャッシュやメタデータの役割について見ていきます。
対象ファイルのキャッシュ
dvc add ./data/sample.txt
を実行すると、ファイル内容のハッシュ値 (例: a1136e853...
) が計算され、 .dvc/cache/files/md5/xx/yyyy...
のようなパスでキャッシュとして保存されます。
メタデータファイル
data/
にはsample.txt.dvc
というメタデータファイルが作成され、「元のファイル名」と「ハッシュ値」などが記録されます。
outs:
- md5: a1136e8530eeb4cfd7a7bc6cfd545382
...
path: sample.txt
ディレクトリを管理する場合
data/images
ディレクトリをDVCで管理した場合、ファイル構成は以下のようになります。
プロジェクト
├── .dvc
│ └── cache
│ └── files
│ └── md5
│ ├── 01
│ │ └── af990bd0843cf55091ba1805ce51f3 # 1_001.pngのキャッシュ
│ ├── dc
│ │ └── 5449d2962d0521680b5ceef1dd0c61 # 1_002.pngのキャッシュ
│ └── 3b
│ └── 63b2858adb3fdeb149abef3325e297.dir # imagesディレクトリの構成情報(.dirファイル)
└── data
├── images
│ ├── 1_001.png
│ └── 1_002.png
└── images.dvc
それぞれのキャッシュやメタデータの役割について見ていきます。
ディレクトリ内ファイルのキャッシュ
dvc add data/images/
を実行すると、ディレクトリ内の各ファイルごとに内容からハッシュ値が生成され、それぞれ .dvc/cache/files/md5/xx/yyyy...
のようにキャッシュとして保存されます。
メタデータファイル
ディレクトリを管理する場合、DVCは主に次の2種類のメタデータファイルを生成します。
1. ディレクトリ全体の構成情報(.dirファイル)
ディレクトリ配下のすべてのファイルについて
相対パス(relpath)とハッシュ値(md5)が、JSON形式の .dir ファイルとしてキャッシュディレクトリに保存されます
例: .dvc/cache/3b/63b2858adb3fdeb149abef3325e297.dir
[
{"md5": "670e8e83847a9617eafdc3debc2caeb1", "relpath": "1/1_001.png"},
{"md5": "dc5449d2962d0521680b5ceef1dd0c61", "relpath": "1/1_002.png"}
...
]
2. ディレクトリ用の.dvcファイル(メタ情報ファイル)
data/
ディレクトリ内には、ディレクトリ全体を追跡する images.dvc
ファイルが作成され、
このファイルには、ディレクトリ全体のハッシュ値(.dirファイル) と ディレクトリのパス などが記録されます
outs:
- md5: 3b63b2858adb3fdeb149abef3325e297.dir
...
path: data
この2種類のファイルによって、「ディレクトリの論理的な構造」と「物理的なキャッシュデータ」との橋渡しが行われます。
dvc pull時のデータセットの復元
DVCの dvc pull
を実行した場合、ディレクトリ・単一ファイル問わず、.dvcファイル(または.dvcフォルダ内のメタデータ)に記録された「パス」と「ハッシュ値」の対応関係にしたがって、以下の流れで元のデータ構造が復元されます。
単一ファイルの場合
-
.dvc
ファイルからファイル名とハッシュ値を取得 - 対応するキャッシュファイル(例:
.dvc/cache/a1/136e...
)を - 元のファイル名(例:
sample.txt
)で復元
ディレクトリの場合
-
.dvc
ファイルから「対象ディレクトリのハッシュ値(.dirファイル)」を取得 - 対応する
.dir
ファイルを読み込み、全ファイルの「相対パス」と「各自のハッシュ値」を取得 - 各キャッシュファイルからデータを抽出・本来のディレクトリ階層で復元
まとめ
DVCによるデータ管理では、データ内容に基づいたハッシュ値を用いてファイルやディレクトリをキャッシュに保存し、メタデータファイルによって「元のファイル名・ディレクトリ構造」との対応関係を記録しています。
この仕組みによって、効率的なデータ管理と、dvc pull
実行時の完全な復元を両立しています。
終わりに
今回はDVCのハッシュで管理されたデータの復元方法をテーマに調べてみました。
整合性を保ちつつ効率の良いデータセットをバージョン管理する手法は、調べていて興味深かったです。
今後はこのDVCを使ってSageMaker上でトレーニングする方法についても調べたいと思います。