🤝

Amazon SageMaker Studio + AWS Cloud9 でファイルシステムを共有して快適な機械学習開発環境を構築する

2022/05/12に公開

みなさん、最近 sage を make していますか?

https://dic.nicovideo.jp/a/sage

今回は往年の2ちゃんねる用語の話ではなくて、Amazon Web Services (AWS) が提供している機械学習開発プラットフォーム Amazon SageMaker のお話です。

Amazon SageMaker Studio と AWS Cloud9 で EFS のストレージを共有して両者いいとこどりのいい感じの開発環境を作ろうというのがテーマです。

はじめに

SageMaker はデータサイエンティストや機械学習のエンジニアが、機械学習の開発運用プロセス全体を効率化していただくために使っていただけるような機械学習プラットフォームのマネージドサービスです。

データのラベリングや特徴量変換といったデータの準備のフェーズから、モデルの構築、トレーニング・チューニング、デプロイ・モニタリングといった、それぞれのフェーズにおいてユーザーを支援するツール群を提供しています。

これらツール群を単一のインターフェースで利用できる Amazon SageMaker Studio という統合開発環境も提供していまして、2020年11月より東京リージョンでも利用できるようになっています。

SageMaker Studio UI
SageMaker Studio の UI

SageMaker Studio の UI は上の画像のようなものであり、JupyterLab を拡張したものとなっています。

ただし、単純に JupyterLab をホスティングしたサービスではなく、SageMaker Studio の特徴としては、Jupyter の環境 (JupyterServer App) と、計算環境 (KernelGateway App) と、ストレージ (Amazon Elastic File System) が分離されています。

SageMaker Studio Architecture
*画像出典: Dive deep into Amazon SageMaker Studio Notebooks architecture

そのため、SageMaker Studio の (JupyterLabの) 画面から、実際にノートブックを実行する計算環境のインスタンスタイプや Docker コンテナを柔軟に切り替えて、その場その場で最適な環境を用いることができるという便利さがあります。

そんな素敵な SageMaker Studio、ノートブックにおける開発や SageMaker Python SDK を用いた学習ジョブの実行・モデルのデプロイなどは非常にスムーズにできるのですが、やはり Python コードをガリガリと開発したいときにはコードの補完機能デバッガーなど、もう少しリッチな機能がほしくなる方もいらっしゃるかもしれません。

そこで、SageMaker Studio はストレージが Amazon Elastic File System (EFS) で構成されていることを思い出してください!

EFS はマネージドのネットワークファイルシステムであり、SageMaker Studio だけでなく、EC2 など他の環境にマウントする[1]ことができます。

…そういえば AWS には AWS Cloud9 っていうクラウドベースの統合開発環境がありましたよね…?これ活用できるのではないでしょうか。

というわけで以下の図のような形で SageMaker Studio にアタッチされている EFS を Cloud9 にマウントする、そんな環境の構築手順を解説していきます。

sagemakerstudio-efs-cloud9
SageMaker Studio でノートブック構築、Cloud9 で Python コード開発

環境構築手順の流れ

次のような流れで進めていきます。

  1. SageMaker ドメインの作成
  2. EFS のアクセスポイントの作成
  3. Cloud9 の環境作成
  4. Cloud9 のセキュリティグループを更新
  5. Cloud9 に EFS をマウント

1. SageMaker ドメインの作成

まず、下記のドキュメントなどに従って、お好みのリージョンで SageMaker Studio の環境を作成しましょう。

こちらのドキュメントでは「クイックスタート」で環境構築する手順を示していますが、「標準セットアップ」を用いるとネットワーク設定などカスタマイズできたり、AWS SSO との連携ができたりします。

SageMaker ドメインが作成されるとユーザープロファイルや EFS が作成されます。SageMaker のコントロールパネルから「Domain ID」をコピーしてください。

そして、CloudShell や AWS CLI を設定したターミナルなどで以下のコマンド叩いてみてください。

# aws sagemaker list-domains --region <region>  # Domain ID を取得
aws sagemaker describe-domain --region <region> --domain-id d-<domain id>

以下のような出力が返ってくるはずです。

{
    "DomainArn": "arn:aws:sagemaker:<region>:<account id>:domain/d-<domain id>",
    "DomainId": "d-<domain id>",
    "DomainName": "<domain name>",
    "HomeEfsFileSystemId": "fs-<efs id>",
    ...
    "AppNetworkAccessType": "PublicInternetOnly",
    "SubnetIds": [
        "subnet-<subnet id 1>",
        "subnet-<subnet id 2>",
        "subnet-<subnet id 3>"
    ],
    "Url": "https://<domain id>.studio.<region>.sagemaker.aws",
    "VpcId": "vpc-<vpc id>"
}

HomeEfsFileSystemId が SageMaker Studio などにマウントされている EFS のファイルシステムの ID です。あとで使うのでメモしておきましょう。

クイックスタートでセットアップした場合はデフォルトの VPC (VpcId) とそれぞれの Availablity Zone に対応するサブネット (SubnetIds) に EFS のマウントターゲットが作成されます。次の図は EFS のドキュメントからの引用なので直接関係ないですが、なんとなくこの辺りのアーキテクチャーをイメージできるじゃないかと思います。


画像出典: https://docs.aws.amazon.com/ja_jp/efs/latest/ug/how-it-works.html

2. SageMaker Studio にアタッチされている EFS のユーザーID の確認

EFS をそのままマウントすると以下のようなディレクトリ構造になっています。

/
├── 200001
├── 200005
├── 200010
...
└── shared

この 200005 とかがそれぞれのユーザープロファイル用のディレクトリになっているのですが、このままだとアクセス権限の扱いが難しいので EFS のアクセスポイントを作成していきます。

これからどのユーザーにどの User ID が紐づいているのかを確認します。

まずはユーザープロファイルのリストを表示してみましょう。AWS コンソール上の SageMaker のコントロールパネルで見てもいいのですが、せっかくなので AWS CLI を使ってみます。

aws sagemaker list-user-profiles --region <region> --domain-id d-<domain id>

以下のような結果が返ってきます。

{
    "UserProfiles": [
        {
            "DomainId": "d-<domain id>",
            "UserProfileName": "<user profile name>",
            "Status": "InService",
            "CreationTime": "2022-05-12T10:22:07.069000+09:00",
            "LastModifiedTime": "2022-05-12T10:22:15.508000+09:00"
        },
	...
    ]
}

EFS のマウントを行いたいユーザープロファイルの名前 (UserProfileName) をコピーし、次のコマンドを叩いてください。

aws sagemaker describe-user-profile --region <region> --domain-id d-<domain id> --user-profile-name <user profile name>

すると、以下のような結果が返ってくるでしょう。

{
    "DomainId": "d-<domain id>",
    "UserProfileArn": "arn:aws:sagemaker:<region>:<account id>:user-profile/d-<domain id>/<user profile name>",
    "UserProfileName": "<user profile name>",
    "HomeEfsFileSystemUid": "200005",
    ...
}

この HomeEfsFileSystemUid が EFS のファイルシステム上でユーザーに割り当てられたユーザー ID です!今回は 200005 となっていますがユーザーによって異なります。この値もあとで使うのでメモしておきましょう。

3. EFS のアクセスポイントの作成

それでは EFS のアクセスポイントを作っていきましょう。AWS コンソールから EFS のダッシュボードを開き、上の工程で取得した HomeEfsFileSystemId をクリックしてください。(執筆時点から多少 UI が変わっていたとしても気にしないのがノブレス・オブリージュというものです。)

ファイルシステムの詳細画面が開いたら「Access points」タブから「Create access point」を選択してください。

次に、アクセスポイントを設定していきます。まずは「Root directory path」に / + HomeEfsFileSystemUid の値を入力します。

お好みですが「Name - optional」にユーザープロファイルの名前を書いておくと管理がしやすくなるかもしれません。

次に POSIX user の設定もしましょう。「User ID」には再び HomeEfsFileSystemUid を入力し、「Group ID」は 1001 を入力してください。

最後に一番下の「Create access point」というオレンジ色のボタンを押してください。他の設定は空のままで OK です。

後の工程で使うので、ここで作成したアクセスポイントの ID (fsap-<hash>) と EFS ファイルシステムの ID (fs-<hash>) はメモしておきましょう。

4. Cloud9 の作成

次に、汎用の統合開発環境である Cloud9 の環境構築をしていきます。公式のドキュメントなどを参考にしてください。

なお、Cloud9 作成時の「Configure settings」の画面では「Network settings (advanced)」を展開し、SageMaker ドメインと同じ VPC とサブネットを選択するよう注意してください。

Cloud9 の環境が作成されると Cloud9 のウェルカム画面が表示されます。

5. Cloud9 が動いている EC2 インスタンスのセキュリティグループを更新

次に、Cloud9 が動いている EC2 インスタンスから EFS にアクセスできるようにセキュリティグループを更新してあげます。

ウェブブラウザの別のタブで EC2 のダッシュボードを開いてください。インスタンスのリストで aws-cloud9-<cloud9 env name>-<hash> のようなインスタンスの名前の横のボックスにチェックを入れ、「Actions」→「Security」→「Change security groups」を選択してください。

次に、「Associated security groups」の検索バーをクリックすると既存のセキュリティグループのリストが表示されます。security-group-for-outbound-nfs-<sagemaker domain id> という名前のセキュリティグループがあるのでこちらを選択し、「Add security group」ボタンをクリックし、最後にオレンジ色の「Save」ボタンをクリックしてください。

6. Cloud9 に EFS をアクセスポイント経由でマウント

さて、仕上げとして、Cloud9 に SageMaker Studio と共通の EFS ファイルシステムをマウントしていきます。

まず、Cloud9 のターミナルで以下のコマンドを叩いて amazon-efs-utils をインストールしましょう。(Amazon Linux 系以外の OS でのインストール手順はこちらを参考にしてください。)

sudo yum install -y amazon-efs-utils

マウント先のディレクトリも作成しましょう。ここでは sagemaker という名前にしています。

sudo mkdir -p /mnt/sagemaker
ln -s /mnt/sagemaker ~/environment/sagemaker

長い道のりでしたが、ようやく EFS をマウントします。前の工程で作成した EFS アクセスポイントの ID (fsap-<hash>) とファイルシステムの ID (fs-<hash>) に置き換えて以下のコマンドを実行してください。

# あらかじめ amazon-efs-utils のインストールが必要
sudo mount -t efs -o tls,accesspoint=fsap-<access point id> fs-<efs id>:/ /mnt/sagemaker

これで完了です! SageMaker Studio で作成したファイルが Cloud9 で表示されることを確認してみてください(逆も然りです)。

Cloud9 再起動時に自動マウントする設定

このままでは Cloud9 を再起動したときに再度手動のマウントが必要になってしまうため、こちらのドキュメントに従って自動化しましょう。

以下のようなコマンドを叩いて /etc/fstab を更新してください。EFS のファイルシステム ID とアクセスポイントの ID は適宜置き換えてください。

sudo sh -c "cat << 'EOT' >> /etc/fstab
fs-<efs file system id> /mnt/sagemaker efs _netdev,noresvport,tls,accesspoint=fsap-<access point id> 0 0
EOT"

おわりに

いかがでしたでしょうか。EFS を SageMaker Studio と Cloud9 で同じものをマウントすることで、SageMaker Studio のノートブックでインタラクティブにデータ処理やモデル構築を行いつつ、Python スクリプトなどは Cloud9 で開発するのに便利な環境が構築できました!

慣れてくるとさらに ユーザーは別のユーザーのディレクトリを閲覧できないようにしたい などとアクセス制限について考えたくなるかもしれません。そんなときはプレミアムサポートの「IAM および EFS アクセスポイントを使用して、特定の EC2 インスタンスへのディレクトリアクセスを許可するにはどうすればよいですか?」などを参照してみてください。

IAM ロールと EFS のファイルシステムポリシーを組み合わせることでそういったアクセス制限を実現できます。

脚注
  1. EFS ファイルシステムをマウントする ↩︎

Discussion