💬

DVC-DataVersionControl-活用

2024/04/03に公開

概要

本書は、DVC(DataVersionControl)の利用方法を説明するものです。

背景・目的

ソースコードのバージョン管理はGitが一般的ですが、
Gitはサイズが大きいバイナリデータ(以下BLOB)の管理が苦手です。
そのため、コードはGit、データはGoogleDrive、といったケースが多いのではないでしょうか?
その場合、データはコードCodeと紐づくVersion管理を行っていないので、以下のような課題があります。

  • 実験の再現ができない
  • データの在処はGitリポジトリ見てもわからない
  • Datasetのセットアップが手間

DVCとは

DVCはデータのバージョン管理を行うツールです。
Gitと一緒に使用することでデータセットやモデル等のBLOBをバージョン管理することができます。
ストレージには、GCP/Azure/AWSのストレージサービスやGoogleDrive等が利用できます。
下図は、Aさんの実験をBさんが再現する例。

環境

  • macOS Sonoma 14.4.1
  • Docker 25.0.3, build 4debf41
  • Docker Compose v2.24.5-desktop.1
  • DVC 3.49.0

範囲

DVCは、ローカル利用だけでなく、SaaSの利用形態も提供されており、SaaSではDataのVersion管理のみならず、例えばMLflowのような実験管理の機能も提供しています。
本書は、そのようなDVCの実験管理機能は範囲外とし、データのVersion管理に関してのみ扱います。

DVCのデータ管理 〜Gitとの併用〜

DVCは、Gitと併用することを前提としたソリューションです。そのため、フォルダツリー構造と、Gitコード管理への作用を知ることはとても重要です。以降、下記のフォルダツリーをベースに、DVC関連のファイルや、Gitとの関連を説明します。

  • フォルダツリー 〜DVC管理なし〜
    下記は、DVC管理を行わないツリーの例です。ソースコードやGit関連ファイルは、Gitリポジトリの管理対象ですが、inputフォルダ配下のJPEGファイルは、Gitで管理すべきでないファイル(今までバージョン管理できていなかったもの)です。

    ${PROJECT_ROOT}/
    │
    ├── .git/               # Git管理フォルダ
    ├── .gitignore          # Git管理対象から外すファイル群を記載するファイル
    │
    ├── input/              # 画像等(Git管理から外すべきもの)
    │   └── data/           #
    │       ├── image01.jpg #
    │       └── image02.jpg #
    │
    ├── source01.py         # ソースコード(Git管理対象)
    └── source02.py         #
    
  • フォルダツリー 〜DVC管理あり〜

    ${PROJECT_ROOT}/
    │
    ├── .git/
    ├── .gitignore
    │
    ├── .dvc/                   # (1)DVC管理フォルダ
    │   ├── cache/              # 
    │   ├── tmp/                # 
    │   ├── config              # 
    │   └── .gitignore          # 
    ├── .dvcignore              # (2)DVC管理対象から外すファイルパスを記載するファイル
    │
    ├── input/
    │   └── data/
    │       ├── .gitignore      # (3)データをGit管理対象から外すためのignoreファイル
    │       ├── image01.jpg     # 
    │       ├── image01.jpg.dvc # (4)画像ファイル1のハッシュが記載されるファイル
    │       ├── image02.jpg     # 
    │       └── image02.jpg.dvc # (4)画像ファイル2のハッシュが記載されるファイル
    │
    ├── source01.py
    └── source02.py
    

    上記の4種類のフォルダやファイルが、DVC管理で用いられるものです。
    それら((1)〜(4))は、DVCコマンドで自動生成、記載されます。

    • (1) DVC管理フォルダ .dvc/
      DVCの初期化コマンドで生成されるフォルダ。内部には、データを保管するストレージ情報の記載などがある。
    • (2) DVC管理対象から外すファイルパスを記載するファイル .dvcignore
      DVCコマンドで生成されるファイル。Gitの.gitignoreファイルに相当し、ユーザーが意図的にDVC管理しないファイルのパスを記載する。
    • (3) Git管理対象から外すデータのファイルパスが記載されるファイル input/data/.gitignore
      DVCコマンドで、データをDVC管理対象とした時に自動生成され、データのパスが記載される
    • (4) 画像ファイル1のハッシュが記載されるファイル input/data/image01.jpg.dvc, input/data/image02.jpg.dvc
      DVCコマンドで、データをDVC管理対象とした時に自動生成され、データのチェックサムが記載される。
      DVCは、そのチェックサムを用いて、データのバージョン管理を行う。

利用方法

本章では、GoogleDriveとGoogleCloudStorage(GCS)をデータ保存先とした場合の利用方法を説明します。

  • インストール

    • Case A. GoogleDrive
      $ pip install dvc[gdrive]
      
    • Case B. GCS
      $ pip install dvc[gs]
      
  • 初期設定
    Projectフォルダ直下で下記の操作を行う

    • DVCの初期化
      下記のコマンドを実行する

      $ dvc init
      

      ⇒ 隠しフォルダ .dvc/ が生成される。このフォルダはGitの管理対象

    • リモートストレージ設定

      • Case A. GoogleDrive

        • データ管理フォルダを作成し、FolderIDを控える
          URLの folders/以降が${FOLDER_ID}
          e.g. https://drive.google.com/drive/folders/${FOLDER_ID}
        • リモートストレージ設定
          下記のコマンドを実行する
          $ dvc remote add -d storage gdrive://${FOLDER_ID}
          
          .dvc/config にストレージ情報が書き込まれる
      • Case B. GCS

        • GCSバケットを作成し、バケット名を控える
        • リモートストレージ設定
          下記のコマンドを実行する
          $ dvc remote add -d storage gs://${BUCKET_ID}
          
          .dvc/config にストレージ情報が書き込まれる
  • Dataの追加

    $ dvc add input/data/image01.jpg
    

    これにより以下の2点が行われる

    • input/data/.gitignore をなければ生成、input/data/image01.jpg が記載される
      input/data/image01.jpgをGit管理対象外にする
    • input/data/image.jpg.dvc が生成され内部にハッシュ値が書き込まれる
      → このファイルでデータのVer管理が行われる
      ユーザーは、.dvc ファイルはGitの管理対象にする
  • Dataの更新

    $ dvc add input/data/image01.jpg
    

    これにより以下が行われる

    • input/data/image01.jpg.dvc に記載されているハッシュ値が更新される

    ユーザーは、これをgit commit, push する

  • Dataの同期 - リモートストレージにUpload

    $ dvc push
    
  • Dataの同期 - リモートストレージからDownload

    $ dvc pull
    

TIPS

  • dvc add コマンド(DVC管理ファイル群の追加/更新)で、フォルダ内一括処理できるか?
    できる。やり方は2通り

    • 個別登録〜ワイルドカードを使う〜

      $ dvc add input/data/*.jpg
      

      データ管理のファイル群は、先の例と同様。

    • フォルダ登録〜コマンド引数にフォルダを指定〜

      $ dvc add input/data
      

      この場合、データ管理のファイル群は、先の例と少し異なり、下記のようになる。

      ${PROJECT_ROOT}/
      (省略)
      ├── input/
      │   ├── .gitignore      # imageXX.jpgをGit管理から外すための.gitignore, Git管理対象
      │   ├── data/
      │   │   ├── image01.jpg # ファイル毎の .dvc ファイルは生成されない
      │   │   └── image02.jpg # 同上
      │   └── data.dvc        # フォルダ丸ごとのハッシュ値, Git管理対象
      (省略)
      

      この場合、管理形態が”フォルダ内一括管理”になるので、1つだけ更新されたとしてもdvc statusコマンドでは、
      フォルダが更新されたことは分かるが、どのファイルが更新されたかはわからない。

  • 「個別登録」と「フォルダー登録」の併用はできるか?
    できない。ファイル個別/フォルダ一括 管理形態が異なるためコマンドがエラーになる。

  • データファイルをGit管理の対象から外すのは、手作業で .gitignore ファイルに記載するのではなくdvcコマンドを使う

    • .gitignore に、*.jpg とか書かない
    • dvc addすれば、dvc管理下で自動的に.gitignoreに追加されて、
      Git管理から外れ、DVC管理になる
  • 更新されたデータを確認する
    dvc status コマンドで調べられる(※未追加のファイルはリストアップされない)

  • dvc add コマンドは何処で実行するか(データがあるフォルダで実行する必要があるか?)
    どこで実行してもよい。ファイルのハッシュ値を示す.dvcファイル(e.g. image01.jpg.dvc)は、ファイルと同じ場所に作られる

  • GoogleDrive利用時のDocker環境における注意点 (DockerNetworkが障壁に?)
    GoogleDriveの認証時、ホストのブラウザから認証を行う。
    ホストからContainerへPort 8080とその他ポートでアクセスするため、Containerをホストモードで動作させる必要がある。
    (参考: Docker-docs-ja >> ネットワーク機能の設定 » ホスト・ネットワークの使用)
    下図はdocker-compose.ymlの設定例

参考

Aidemy Tech Blog

Discussion