🐡

EC2環境でのDVC導入と最小権限IAMロールの設定方法

2024/06/18に公開

SREホールディングス株式会社でエンジニアをしています天海です。

機械学習では、データやモデルを変えて実験することが多く、過去の実験データを同じストレージ内に様々なファイル名で保存することがあります。このような方法を取ると、管理するファイル数が増加し、実験結果などのファイル管理が困難になることがあります。そこで、データ管理ツールであるData Version Control(DVC)を分析環境に導入することを検討しました。

分析環境はEC2上に構築することが多いのですが、最小限のアクセス権であるIAMロールを付与した環境を構築したいため、DVCを実際に動作させながら、データ管理に必要な最小限のアクセス権を調査しました。

DVCとは

DVCはGit管理下でデータ管理できるライブラリです。
いくつか特徴を挙げておきます。

大きなデータファイルのバージョン管理が可能

DVC の最大の特徴の一つは、大規模なデータファイルのバージョン管理が可能である点です。
GitHub では、100 MiB を超えるファイルはブロックされるという制限があります。参考
これに対し、DVC はこの制限を回避し、大容量ファイルのバージョン管理を効率的に行うことができます。

コマンドがGitに似ており、扱いやすい

DVC のコマンドは Git に非常に似ており、Git に慣れているユーザーにとっては直感的に操作できます。
例えば、データファイルのバージョン管理において以下のようなコマンドが使用されます。

  • dvc init:DVCプロジェクトを初期化
  • dvc add <filename>:ファイルを追跡
  • dvc commit:ファイルの変更をコミット
  • dvc push:リモートストレージにデータをアップロード
  • dvc pull:リモートストレージからデータをダウンロード

クラウドサービスをサポートしている

DVC は主要なクラウドストレージサービスをサポートしており、AWS S3、Azure Blob Storage、Google Cloud Storage などのクラウドサービスと連携してデータを管理できます。クラウドストレージをリモートストレージとして設定することで、データのプッシュやプルが可能です。

OSSなので、無料で利用できる

DVC はオープンソースソフトウェア(OSS)であり、無料で利用できます。これにより、コストをかけずにデータバージョン管理を導入することが可能です。

今回の構成

DVCを使用するために必要なIAMロールの権限を確認したいので、EC2とS3を使ったシンプルな構成にします。EC2には何の権限も持たないIAMロールをアタッチし、S3はバケット名のみを決めて作成したものを利用します。

初期設定

まずは、DVCをダウンロードします。ダウンロード方法を参照してください。
Pythonが使える環境であれば、pipを使って簡単にインストールできます。

pip install dvc[s3]

Gitの初期設定

まず、作業ディレクトリを作成し、Gitのリポジトリを初期化します。

mkdir work
cd work
git init

リポジトリに何もファイルがないとpushできないので、適当なテキストファイルを作成します。

touch null.txt
git add .
git commit -m "Initialize"
git push origin master

DVCの初期化

データを入れるフォルダを作成します。また、データセットを保存するoriginフォルダ、モデルを保存するmodelフォルダも作成しておきます。

mkdir data
cd data
mkdir origin
mkdir model

DVCの構築を行います。以下のコマンドを実行します。

dvc init

リモートストレージにS3を指定します。

dvc remote add -d master s3://<s3バケット名>

DVCの初期設定をGitにpushします。

git add .
git commit -m "Initialize DVC"
git push origin master

データ・モデルの追加

originフォルダにデータセットをアップロードします。
データはKaggleから適当なデータセットをダウンロードしてきました。

ダウンロード後のフォルダ構成

.
├── [   33]  data
│   ├── [    6]  model
│   └── [   39]  origin
│       ├── [  28K]  test.csv
│       └── [  60K]  train.csv
└── [    0]  null.txt

DVCにデータを追跡させます

dvc add origin/train.csv origin/test.csv
git add .
git commit -m "Add raw data to project"

権限を与えずにアップロードしてみましょう

dvc push

エラーが表示されました。当然ですが、権限を与えていないからです。

Collecting                                                                                                                                                                            |2.00 [00:00,  188entry/s]
Pushing
ERROR: unexpected error - Unable to locate credentials                                                                                                                                                          

Having any troubles? Hit us up at https://dvc.org/support, we are always happy to help!

putObjectのみを与えて再度実行してみます。

putObjectの追加後

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::<s3バケット名>"
            ]
        }
    ]
}

エラー文が変化しました。エラー文を確認すると、List権限が必要そうです。

Collecting                                                                                                                                                                            |0.00 [00:00,    ?entry/s]
Pushing
ERROR: unexpected error - Access Denied: An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied                                                                               

Having any troubles? Hit us up at https://dvc.org/support, we are always happy to help!

エラー文を調べたところ、ListBucketgetObject権限が必要そうであることがわかりました
参考ページ

ListBucketgetObjectの追加後

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject", #追加
                "s3:ListBucket" #追加
            ],
            "Resource": [
                "arn:aws:s3:::<s3バケット名>/*", #追加
                "arn:aws:s3:::<s3バケット名>"
            ]
        }
    ]
}

上記の変更を加えたところ、今度はアップロードできました。

モデル管理

データセットをリモートストレージにアップロード完了しました。
機械学習では、色々なモデルなどを作成し評価します。例えば、全ての学習データをモデルで評価した後で、外れ値を除外した学習データで学習し直したモデルを作成します。
モデルもDVCで管理してみます。最初のモデルをアップロードします。
モデルもKaggleで配布されているモデルを適当にダウンロードしてきました。

1つ目のモデルを追加後のdataフォルダ構成

.
├── [   22]  model
│   └── [ 7.3M]  first_model.pth
└── [   98]  origin
    ├── [  28K]  test.csv
    ├── [   89]  test.csv.dvc
    ├── [  60K]  train.csv
    └── [   90]  train.csv.dvc

それでは、リモートストレージにアップロードします。

dvc add ./model/first_model.pth
git add .
git commit -m "Add First Model"
dvc push

問題なくpushできたので、1つ目のモデルを削除します。

dvc remove first_model.pth.dvc
rm first_model.pth

2つ目のモデルをリモートストレージにアップロードします。

dvc add ./model/second_model.pth
git add .
git commit -m "Add Second Model"
dvc push

2つ目のモデルをアップロード後のdataフォルダ構成

.
├── [   84]  model
│   ├── [  45M]  second_model.pth
│   └── [  119]  second_model.pth.dvc
└── [   98]  origin
    ├── [  28K]  test.csv
    ├── [   89]  test.csv.dvc
    ├── [  60K]  train.csv
    └── [   90]  train.csv.dvc

何のの問題も無くアップロードできました。
最初のモデルを再現してみましょう。
git logで"Add First Model"のハッシュ値をとってきます。

git reset --hard ハッシュ値

データを更新してみましょう。
下記のコマンドで実行できます。

dvc pull

実行ログ

Collecting                                                                                                                                                                            |3.00 [00:00,  164entry/s]
Fetching
Building workspace index                                                                                                                                                              |5.00 [00:00,  663entry/s]
Comparing indexes                                                                                                                                                                    |7.00 [00:00, 1.20kentry/s]
Applying changes                                                                                                                                                                      |1.00 [00:00,   279file/s]
A       first_model.pth
D       data/model/second_model.pth
1 file added and 1 file deleted

実行後にdataフォルダ構成を確認してみます。
1つ目のモデルは再現されて、2つ目のモデルは削除されました。

1つ目のモデルを再現後のdataフォルダ構成

.
├── [   60]  model
│   ├── [ 7.3M]  first_model.pth
│   └── [  106]  first_model.pth.dvc
└── [   98]  origin
    ├── [  28K]  test.csv
    ├── [   89]  test.csv.dvc
    ├── [  60K]  train.csv
    └── [   90]  train.csv.dvc

データを管理するだけならば、最低限の権限としては下記で良さそうです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<s3バケット名>/*",
                "arn:aws:s3:::<s3バケット名>"
            ]
        }
    ]
}

必要な権限を見ればわかりますが、s3 syncの実行時に必要な権限と同じ権限です。おそらく差分のみをアップロードするために、内部的にはsyncコマンドを実行していると思われます。

まとめ

今回は、DVCを利用してEC2からS3にリモートストレージを設定し、最小限のアクセス権であるIAMロールの設定方法を調査しました。具体的には、PutObject、GetObject、およびListBucketの3つの権限のみでデータ管理を行うことができました。

DVCを使った感想としては、コマンドのみでデータを管理できるため、学習コストが低く扱いやすいと感じました。弊社では、実験管理ツールとしてMLflowを導入しているため、今後も快適な実験環境を模索していきたいと思います。

SRE Holdings 株式会社

Discussion