「Amazon SageMaker Model Registry、HashiCorp Terraform、GitHub、およびJenkins CI/CDを使用して、マルチ環境設定でのパイプラインの促進を行う」
「Amazon SageMaker Model Registry、HashiCorp Terraform、GitHub、およびJenkins CI/CDを駆使して、マルチ環境設定パイプラインの効率化を図る方法」
機械学習オペレーション(MLOps)プラットフォームを人工知能(AI)と機械学習(ML)の進化が速いランドスケープで組織のために構築することは、データサイエンスの実験と展開の間のギャップをシームレスに埋めることが重要です。同時に、モデルのパフォーマンス、セキュリティ、コンプライアンスの要件を満たす必要があります。
規制およびコンプライアンスの要件を満たすため、このようなプラットフォームを設計する際の主な要件は以下の通りです:
- データドリフトの対処
- モデルのパフォーマンスの監視
- モデルの自動再トレーニングのサポート
- モデルの承認プロセスの提供
- モデルを安全な環境に保つ
この記事では、AWSのサービスとサードパーティのツールセットの組み合わせを使用して、これらのニーズに対応するためのMLOpsフレームワークを作成する方法を紹介します。このソリューションには、Amazon SageMaker Model Monitor、SageMaker Model Registry、Amazon SageMaker、Amazon EventBridge、Amazon Simple Notification Service(S3)、HashiCorp Terraform、GitHub、Jenkins CI/CDを使用した、マルチ環境構成、自動モデル再トレーニング、バッチ推論、モニタリングが含まれます。我々は、公開されているUCI乳房マンモグラフィー質量データセットを使用して、XGBoostアルゴリズムで訓練された乳房の腫瘤の重症度(良性または悪性)を予測するモデルを構築し、MLOpsフレームワークを使用して展開します。詳しい手順とコードはGitHubのリポジトリで入手できます。
ソリューション概要
以下のアーキテクチャダイアグラムは、以下の主要なコンポーネントを備えたMLOpsフレームワークの概要を示しています:
- 「Azure OpenAI Studioを使用したNL2SQLシステムのセットアップ方法」
- 「組織のためのカスタマイズされたコーディングパートナー」
- 言語を使って、ロボットが広範な世界をより理解するために
- マルチアカウント戦略 – AWS Well-Architectedのベストプラクティスに従って、2つの異なる環境(devとprod)を2つの異なるAWSアカウントに設定し、中央モデルレジストリには3番目のアカウントが設定されています:
- Dev環境 – モデルが上位環境に昇格する前に、モデル開発、モデルトレーニング、MLパイプライン(トレーニングおよび推論)のテストを許可するように設定されたAmazon SageMaker Studioドメインが設定されている場所です。
- Prod環境 – DevからのMLパイプラインが最初のステップとして昇格し、定期的にスケジュールされて監視されます。
- 中央モデルレジストリ – Amazon SageMaker Model Registryは、dev環境とprod環境で生成されたモデルバージョンを追跡するために別のAWSアカウントに設定されています。
- CI/CDおよびソースコントロール – 環境間でのMLパイプラインの展開は、Jenkinsを使用したCI/CDの設定を通じて行われます。バージョン管理はGitHubを介して行われます。対応する環境のgitブランチにマージされたコード変更は、対象環境に適切な変更を行うCI/CDワークフローをトリガーします。
- モデルモニタリングを伴うバッチ推論 – Amazon SageMaker Pipelinesで構築された推論パイプラインは、定期的に実行され、SageMakerモデルモニターを使用してデータドリフトを検出するモデルモニタリングとともに予測を生成します。
- 自動トレーニングメカニズム – SageMaker Pipelinesで構築されたトレーニングパイプラインは、推論パイプラインでデータドリフトが検出された場合にトリガーされます。トレーニングが完了した後、モデルは中央モデルレジストリに登録され、モデル承認者によって承認されます。承認されると、更新されたモデルバージョンが推論パイプラインを通じて予測を生成するために使用されます。
- インフラストラクチャのコード化 – HashiCorp Terraformを使用して作成されたインフラストラクチャのコード(IaC)は、EventBridgeとの推論パイプラインのスケジューリング、EventBridgeルールに基づくトレーニングパイプラインのトリガー、Amazon Simple Notification Service(Amazon SNS)トピックを使用した通知がサポートされます。
MLOpsのワークフローは以下のステップから成り立っています:
- 開発アカウントでSageMaker Studioのドメインにアクセスし、GitHubリポジトリをクローンし、提供されたサンプルモデルを使用してモデル開発のプロセスを進め、トレーニングおよび推論のパイプラインを生成します。
- 開発アカウントでトレーニングパイプラインを実行し、トレーニングされたモデルバージョンのモデルアーティファクトを生成し、中央モデルレジストリアカウントのSageMaker Model Registryに登録します。
- 中央モデルレジストリアカウントのSageMaker Model Registryでモデルを承認します。
- GitHubリポジトリのフィーチャーブランチにコード(トレーニングおよび推論パイプライン、およびEventBridgeスケジュール、EventBridgeルール、SNSトピックを作成するためのTerraform IaCコード)をプッシュします。コードをGitHubリポジトリのメインブランチにマージするためにプルリクエストを作成します。
- GitHubリポジトリと設定されているJenkins CI/CDパイプラインをトリガーします。CI/CDパイプラインは、プロダクションアカウントにコードをデプロイし、EventBridgeスケジュール、EventBridgeルール、SNSトピックをプロビジョニングするためのTerraformコードを作成します。
- 推論パイプラインは毎日実行され、トレーニングパイプラインは推論パイプラインからデータドリフトが検出された場合に実行されるように設定されています。
- トレーニングパイプラインまたは推論パイプラインに障害が発生した場合、SNSトピックを介して通知が送信されます。
前提条件
このソリューションを実装するためには、以下の前提条件が必要です:
- 3つのAWSアカウント(開発、プロダクション、および中央モデルレジストリアカウント)
- 各AWSアカウントにSageMaker Studioドメインがセットアップされていること(セットアップ手順については、Amazon SageMaker Studioへのオンボードを参照するか、以下のビデオをご覧ください: Amazon SageMaker Studioへのスピーディーなオンボード)
- 管理特権を持つAWSにインストールされたJenkins(Jenkins 2.401.1を使用)
- JenkinsサーバーにインストールされているTerraformバージョン1.5.5以上
この記事では、このソリューションを展開するためにus-east-1
リージョンで作業します。
devおよびprodアカウントでKMSキーをプロビジョニングする
最初のステップは、開発アカウントとプロダクションアカウントでAWS Key Management Service(AWS KMS)キーを作成することです。
開発アカウントでKMSキーを作成し、プロダクションアカウントにアクセス権限を付与する
以下の手順で開発アカウントでKMSキーを作成します:
- AWS KMSコンソールで、ナビゲーションペインでカスタマーマネージドキーを選択します。
- キーの作成を選択します。
- キータイプで対称を選択します。
- キーの使用方法で暗号化および復号化を選択します。
- 次へを選択します。
- プロダクションアカウントへのアクセス権限を与えるために、開発アカウントで作成されたKMSキーにプロダクションアカウントの番号を入力します。これは必須のステップであり、モデルを初めて開発アカウントでトレーニングする際に、モデルアーティファクトはS3バケットに書き込まれる前にKMSキーで暗号化されます。プロダクションアカウントはモデルアーティファクトを復号化して推論パイプラインを実行するためにKMSキーにアクセスする必要があります。
- 次へを選択し、キーの作成を完了します。
キーがプロビジョニングされると、AWS KMSコンソールで表示されるはずです。
プロダクションアカウントでKMSキーを作成する
前のセクションと同じ手順で、プロダクションアカウントでカスタマーマネージドのKMSキーを作成してください。KMSキーを別のアカウントと共有する手順はスキップできます。
セントラルモデルレジストリアカウントでモデルアーティファクトのS3バケットを設定する
セントラルモデルレジストリアカウントで、名前付け規則の一部として文字列sagemaker
を含む任意のS3バケットを作成し、S3バケットのバケットポリシーを更新して、開発アカウントとプロダクションアカウントの両方からS3バケットへのモデルアーティファクトの読み書き権限を与えてください。
以下のコードは、S3バケットのバケットポリシーの更新です:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AddPerm", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<開発アカウントID>:root" }, "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectVersion" ], "Resource": "arn:aws:s3:::<セントラルモデルレジストリアカウントのS3バケット>/*" }, { "Sid": "AddPerm1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<開発アカウントID>:root" }, "Action": "s3:ListBucket", "Resource": [ "arn:aws:s3:::<セントラルモデルレジストリアカウントのS3バケット>", "arn:aws:s3:::<セントラルモデルレジストリアカウントのS3バケット>/*" ] }, { "Sid": "AddPerm2", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<プロダクションアカウントID>:root" }, "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectVersion" ], "Resource": "arn:aws:s3:::<セントラルモデルレジストリアカウントのS3バケット>/*" }, { "Sid": "AddPerm3", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<プロダクションアカウントID>:root" }, "Action": "s3:ListBucket", "Resource": [ "arn:aws:s3:::<セントラルモデルレジストリアカウントのS3バケット>", "arn:aws:s3:::<セントラルモデルレジストリアカウントのS3バケット>/*" ] } ]}
AWSアカウントでIAMロールを設定する
次のステップは、AWSアカウントでのAWS Identity and Access Management (IAM) ロールの設定です。これらのロールには、AWS Lambda、SageMaker、およびJenkinsへの権限が含まれます。
Lambda実行ロール
開発アカウントとプロダクションアカウントでLambda実行ロールを設定し、SageMakerパイプラインのLambdaステップの一部として実行されるLambda関数の実行に使用されます。このステップでは、推論パイプラインから最新の承認済みモデルを取得し、それを使用して推論が生成されます。開発アカウントとプロダクションアカウントで、arn:aws:iam::<アカウントID>:role/lambda-sagemaker-role
という命名規則のIAMロールを作成し、以下のIAMポリシーをアタッチしてください:
-
ポリシー1 –
cross-account-model-registry-access
という名前のインラインポリシーを作成して、モデルレジストリにアクセスできるようにしましょう。このポリシーは、中央アカウントのモデルパッケージに対するアクセス権を与えます:{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "sagemaker:ListModelPackages", "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package/mammo-severity-model-package/*" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": "sagemaker:DescribeModelPackageGroup", "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package-group/mammo-severity-model-package" } ]}
-
ポリシー2 – AmazonSageMakerFullAccessをアタッチします。これは、SageMakerへの完全なアクセス権限を与えるAWSの管理ポリシーです。それに加えて、AWS Application Auto Scaling、Amazon S3、Amazon Elastic Container Registry(Amazon ECR)、およびAmazon CloudWatch Logsに関連するサービスへの選択的なアクセス権も提供されます。
-
ポリシー3 – AWSLambda_FullAccessをアタッチします。これは、LambdaおよびLambdaコンソールの機能、および関連するAWSサービスへの完全なアクセス権を与えるAWSの管理ポリシーです。
-
ポリシー4 – IAMロールのための以下のIAM信頼ポリシーを使用します:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com", "sagemaker.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ]}
SageMaker実行ロール
開発アカウントと本番アカウントのSageMaker Studioドメインごとに関連する実行ロールがあります。この実行ロールは、SageMaker Studioドメイン内でのトレーニングジョブ、処理ジョブなどの実行に使用されます。この実行ロールは、ドメイン詳細ページのドメイン設定タブで確認できます。以下のスクリーンショットに示されています。
以下のポリシーを両方のアカウントのSageMaker実行ロールに追加してください。
-
ポリシー1 –
cross-account-model-artifacts-s3-bucket-access
という名前のインラインポリシーを作成して、中央モデルレジストリアカウントのS3バケットへのアクセス権を与えましょう。このバケットにはモデルアーティファクトが保存されています:{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion" ], "Resource": "arn:aws:s3:::<s3-bucket-in-central-model-registry-account>/*" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::<s3-bucket-in-central-model-registry-account>", "arn:aws:s3:::<s3-bucket-in-central-model-registry-account>/*" ] } ]}
-
ポリシー2 –
cross-account-model-registry-access
という名前のインラインポリシーを作成して、中央モデルレジストリアカウントのモデルパッケージへのアクセス権を与えましょう:{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "sagemaker:CreateModelPackageGroup", "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package-group/mammo-severity-model-package" } ]}
-
ポリシー3 –
kms-key-access-policy
という名前のインラインポリシーを作成して、前のステップで作成したKMSキーへのアクセス権を与えましょう。ポリシーが作成されるアカウントIDと、そのアカウントで作成されたKMSキーIDを指定してください。{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowUseOfKeyInThisAccount", "Effect": "Allow", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "arn:aws:kms:us-east-1:<account-id>:key/<kms-key-id>" } ]}
-
ポリシー4 – AmazonSageMakerFullAccessをアタッチします。これは、SageMakerへの完全なアクセス権限を与えるAWSの管理ポリシーです。関連するサービスへの選択的なアクセス権も提供されます。
-
ポリシー5 – AWSLambda_FullAccessをアタッチします。これは、LambdaおよびLambdaコンソールの機能、および関連するAWSサービスへの完全なアクセス権を与えるAWSの管理ポリシーです。
-
ポリシー6 – CloudWatchEventsFullAccessをアタッチします。これは、CloudWatch Eventsへの完全なアクセス権限を与えるAWSの管理ポリシーです。
-
ポリシ
クロスアカウントジェンキンスロール
プロダクトアカウントに「cross-account-jenkins-role」というIAMロールを設定します。これは、ジェンキンスがプロダクトアカウントにMLパイプラインとそれに対応するインフラストラクチャをデプロイするために使用します。
次の管理型IAMポリシーをロールに追加してください:
CloudWatchFullAccess
AmazonS3FullAccess
AmazonSNSFullAccess
AmazonSageMakerFullAccess
AmazonEventBridgeFullAccess
AWSLambda_FullAccess
ロールの信頼関係を更新して、JenkinsサーバーをホストしているAWSアカウントに権限を与えます:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com", "AWS": "arn:aws:iam::<jenkinsアカウントID>:root" }, "Action": "sts:AssumeRole", "Condition": {} } ]}
Jenkinsサーバーに関連付けられたIAMロールの権限を更新
AWS上でJenkinsが設定されていると仮定し、Jenkinsに関連付けられたIAMロールを更新して、以下のポリシーを追加します。これにより、Jenkinsがプロダクトアカウントにリソースをデプロイするためのアクセス権が与えられます:
-
ポリシー1 –
assume-production-role-policy
という名前の以下のインラインポリシーを作成してください:{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::<プロダクトアカウントID>:role/cross-account-jenkins-role" } ]}
-
ポリシー2 –
CloudWatchFullAccess
という管理型IAMポリシーをアタッチしてください。
中央モデルレジストリアカウントでモデルパッケージグループを設定する
中央モデルレジストリアカウントのSageMaker Studioドメインから、以下のコードスニペットを使用して「mammo-severity-model-package」という名前のモデルパッケージグループを作成してください(Jupyter Notebookで実行できます):
import boto3 model_package_group_name = "mammo-severity-model-package"sm_client = boto3.Session().client("sagemaker")create_model_package_group_response = sm_client.create_model_package_group( ModelPackageGroupName=model_package_group_name, ModelPackageGroupDescription="クロスアカウント用の乳房重症度モデルのモデルパッケージグループ",)print('ModelPackageGroup Arn : {}'.format(create_model_package_group_response['ModelPackageGroupArn']))
開発アカウントとプロダクトアカウントのIAMロールに対するモデルパッケージへのアクセスを設定する
開発アカウントとプロダクトアカウントで作成されたSageMaker実行ロールが、中央モデルレジストリの「mammo-severity-model-package」にモデルバージョンを登録できるようにアクセスを設定します。中央モデルレジストリアカウントのSageMaker Studioドメインで、以下のコードをJupyter Notebookで実行してください:
import json import boto3 model_package_group_name = "mammo-severity-model-package"# ポリシーをJSON辞書から文字列に変換するmodel_package_group_policy = dict({ "Version": "2012-10-17", "Statement": [ { "Sid": "AddPermModelPackageGroupCrossAccount", "Effect": "Allow", "Principal": { "AWS": ["arn:aws:iam::<dev-account-id>:root", "arn:aws:iam::<prod-account-id>:root"] }, "Action": [ "sagemaker:DescribeModelPackageGroup" ], "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account>:model-package-group/mammo-severity-model-package" }, { "Sid": "AddPermModelPackageVersionCrossAccount", "Effect": "Allow", "Principal": { "AWS": ["arn:aws:iam::<dev-account-id>:root", "arn:aws:iam::<prod-account-id>:root"] }, "Action": [ "sagemaker:DescribeModelPackage", "sagemaker:ListModelPackages", "sagemaker:UpdateModelPackage", "sagemaker:CreateModelPackage", "sagemaker:CreateModel" ], "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account>:model-package/mammo-severity-model-package/*" } ]})model_package_group_policy = json.dumps(model_package_group_policy)# ポリシーをモデルパッケージグループに追加するsm_client = boto3.Session().client("sagemaker")response = sm_client.put_model_package_group_policy( ModelPackageGroupName = model_package_group_name, ResourcePolicy = model_package_group_policy)
Jenkinsのセットアップ
このセクションでは、Jenkinsを設定して、Jenkins CI/CDパイプラインを介して本番アカウントでMLパイプラインと対応するTerraformインフラストラクチャを作成します。
- CloudWatchコンソールで、
jenkins-log
という名前のロググループを作成し、JenkinsがCI/CDパイプラインからログをプッシュするための本番アカウントに作成します。ロググループは、Jenkinsサーバーが設定されているリージョンと同じリージョンに作成される必要があります。 - Jenkinsサーバーに以下のプラグインをインストールします:
- JenkinsでクロスアカウントのIAMロール(
cross-account-jenkins-role
)を使用してAWSの認証情報を設定します。このIAMロールは、本番アカウントに設定されています。 - システム設定で、AWSを選択します。
- 先に作成した認証情報とCloudWatchロググループを入力します。
- Jenkins内でGitHubの認証情報を設定します。
- Jenkinsで新しいプロジェクトを作成します。
- プロジェクト名を入力し、Pipelineを選択します。
- Generalタブで、GitHubプロジェクトを選択し、フォークされたGitHubリポジトリのURLを入力します。
- This project is parameterizedを選択します。
- Add Parameterメニューで、String Parameterを選択します。
- Nameには
prodAccount
を入力します。 - Default Valueには本番アカウントのIDを入力します。
- Advanced Project Optionsで、Definitionを選択し、Pipeline script from SCMを選択します。
- SCMにはGitを選択します。
- Repository URLには、フォークされたGitHubリポジトリのURLを入力します。
- Credentialsには、Jenkinsに保存されているGitHubの認証情報を入力します。
- Branches to buildセクションには
main
を入力し、CI/CDパイプラインがトリガされるものとします。 - Script Pathには
Jenkinsfile
を入力します。 - Saveを選択します。
Jenkinsパイプラインは、ダッシュボードに作成され、表示される必要があります。
S3バケットのプロビジョニング、データの収集と準備
次の手順を完了して、S3バケットとデータをセットアップします:
-
devアカウントおよびprodアカウントの両方に、データセットおよびモデルの成果物を保存するためのバケット名に
sagemaker
という文字列を含むS3バケットを作成します。 -
prodアカウント内で、Terraformの状態を維持するためのS3バケットをセットアップします。
-
公開されているUCI乳房画像乳腺腫瘍マススクリーニングデータセットを、前述で作成したdevアカウントのS3バケットにダウンロードして保存します。
-
devアカウントのSageMaker Studioドメイン内のGitHubリポジトリをフォークしてクローンします。リポジトリには次のフォルダ構造があります:
- /environments – prod環境の設定スクリプト
- /mlops-infra – Terraformコードを使用してAWSサービスをデプロイするためのコード
- /pipelines – SageMakerパイプラインコンポーネントのコード
- Jenkinsfile – Jenkins CI/CDパイプラインをデプロイするためのスクリプト
- setup.py – 必要なPythonモジュールをインストールし、run-pipelineコマンドを作成するために必要です
- mammography-severity-modeling.ipynb – MLワークフローを作成および実行するためのノートブック
-
クローンしたGitHubリポジトリフォルダ内にdataという名前のフォルダを作成し、公開されているUCI乳房画像乳腺腫瘍マススクリーニングデータセットのコピーを保存します。
-
Jupyterノートブックの
mammography-severity-modeling.ipynb
に従ってください。 -
以下のコードをノートブックで実行して、データセットを前処理し、devアカウントのS3バケットにアップロードします:
import boto3 import sagemaker import numpy as np import pandas as pd from sklearn.compose import ColumnTransformer from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler, OneHotEncoder # リソースが作成された値に置き換える default_bucket = "<s3-bucket-in-dev-account>" model_artifacts_bucket = "<s3-bucket-in-central-model-registry-account>" region = "us-east-1" model_name = "mammography-severity-model" role = sagemaker.get_execution_role() lambda_role = "arn:aws:iam::<dev-account-id>:role/lambda-sagemaker-role" kms_key = "arn:aws:kms:us-east-1:<dev-account-id>:key/<kms-key-id-in-dev-account>" model_package_group_name="arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package-group/mammo-severity-model-package" feature_columns_names = [ 'BIRADS', 'Age', 'Shape', 'Margin', 'Density', ] feature_columns_dtype = { 'BIRADS': np.float64, 'Age': np.float64, 'Shape': np.float64, 'Margin': np.float64, 'Density': np.float64, } # 生データセットを読み込む mammographic_data = pd.read_csv("data/mammographic_masses.data",header=None) # バッチデータと生データにデータを分割する batch_df =mammographic_data.sample(frac=0.05,random_state=200) raw_df =mammographic_data.drop(batch_df.index) # モデルを初期訓練するために、生データの一部を使い、その他のデータはモデルの再トレーニング時に利用する train_dataset_part2 =raw_df.sample(frac=0.1,random_state=200) train_dataset_part1 =raw_df.drop(train_dataset_part2.index) # 訓練データセットを保存する train_dataset_part1.to_csv("data/mammo-train-dataset-part1.csv",index=False) train_dataset_part2.to_csv("data/mammo-train-dataset-part2.csv",index=False) # バッチデータセットからラベルカラムを削除する batch_df.drop(5,axis=1,inplace=True) # バッチデータを前処理する def preprocess_batch_data(feature_columns_names,feature_columns_dtype,batch_df): batch_df.replace("?", "NaN", inplace = True) batch_df.columns = feature_columns_names batch_df = batch_df.astype(feature_columns_dtype) numeric_transformer = Pipeline( steps=[("imputer", SimpleImputer(strategy="median"))] ) numeric_features = list(feature_columns_names) preprocess = ColumnTransformer( transformers=[ ("num", numeric_transformer, numeric_features) ] ) batch_df = preprocess.fit_transform(batch_df) return batch_df # バッチデータセットを前処理して保存する batch_df = preprocess_batch_data(feature_columns_names,feature_columns_dtype,batch_df) pd.DataFrame(batch_df).to_csv("data/mammo-batch-dataset.csv", header=False, index=False) # バッチデータセットに欠損値を導入する batch_modified_df.replace("?", "NaN", inplace = True) batch_modified_df.columns = feature_columns_names batch_modified_df = batch_modified_df.astype(feature_columns_dtype) # 欠損値を導入したバッチデータセットを保存する batch_modified_df.to_csv("data/mammo-batch-dataset-outliers.csv",index=False)
以下のコードは、次のデータセットを生成します:
-
- data/ mammo-train-dataset-part1.csv – モデルの最初のバージョンのトレーニングに使用されます。
- data/ mammo-train-dataset-part2.csv – mammo-train-dataset-part1.csvデータセットと共に、モデルの2番目のバージョンのトレーニングに使用されます。
- data/mammo-batch-dataset.csv – 推論を生成するために使用されます。
- data/mammo-batch-dataset-outliers.csv – 推論パイプラインを失敗させるためにデータセットに外れ値を導入します。これにより、モデルの自動再トレーニングのトリガーパターンをテストできます。
-
データセット
mammo-train-dataset-part1.csv
をプレフィックスmammography-severity-model/train-dataset
の下にアップロードし、データセットmammo-batch-dataset.csv
とmammo-batch-dataset-outliers.csv
を dev アカウントで作成した S3 バケットのプレフィックスmammography-severity-model/batch-dataset
にアップロードします:import boto3s3_client = boto3.resource('s3')s3_client.Bucket(default_bucket).upload_file("data/mammo-train-dataset-part1.csv","mammography-severity-model/data/train-dataset/mammo-train-dataset-part1.csv")s3_client.Bucket(default_bucket).upload_file("data/mammo-batch-dataset.csv","mammography-severity-model/data/batch-dataset/mammo-batch-dataset.csv")s3_client.Bucket(default_bucket).upload_file("data/mammo-batch-dataset-outliers.csv","mammography-severity-model/data/batch-dataset/mammo-batch-dataset-outliers.csv")
-
データセット
mammo-train-dataset-part1.csv
とmammo-train-dataset-part2.csv
を、Amazon S3 コンソールを介して prod アカウントで作成した S3 バケットのプレフィックスmammography-severity-model/train-dataset
にアップロードします。 -
データセット
mammo-batch-dataset.csv
とmammo-batch-dataset-outliers.csv
を prod アカウントの S3 バケットのプレフィックスmammography-severity-model/batch-dataset
にアップロードします。
トレーニングパイプラインを実行する
<project-name>/pipelines/train
の下には、次のPythonスクリプトがあります:- scripts/raw_preprocess.py – 特徴エンジニアリングのためにSageMaker Processingと統合します
- scripts/evaluate_model.py – モデルのメトリクス計算を許可します。この場合は
auc_score
- train_pipeline.py – モデルのトレーニングパイプラインのコードを含んでいます
次の手順を完了します:
-
スクリプトをAmazon S3にアップロードします:
import boto3s3_client = boto3.resource('s3')s3_client.Bucket(default_bucket).upload_file("pipelines/train/scripts/raw_preprocess.py","mammography-severity-model/scripts/raw_preprocess.py")s3_client.Bucket(default_bucket).upload_file("pipelines/train/scripts/evaluate_model.py","mammography-severity-model/scripts/evaluate_model.py")
-
トレーニングパイプラインのインスタンスを取得します:
from pipelines.train.train_pipeline import get_pipelinetrain_pipeline = get_pipeline( region=region, role=role, default_bucket=default_bucket, model_artifacts_bucket=model_artifacts_bucket, model_name = model_name, kms_key = kms_key, model_package_group_name= model_package_group_name, pipeline_name="mammo-severity-train-pipeline", base_job_prefix="mammo-severity", )train_pipeline.definition()
-
トレーニングパイプラインを提出して実行します:
train_pipeline.upsert(role_arn=role)train_execution = train_pipeline.start()
以下の図は、トレーニングパイプラインの成功した実行を示しています。パイプラインの最終ステップでは、モデルを中央のモデルレジストリアカウントに登録します。
モデルを中央のモデルレジストリで承認する
中央のモデルレジストリアカウントにログインし、SageMaker Studioドメイン内のSageMakerモデルレジストリにアクセスします。モデルのバージョンのステータスを「承認済み」に変更します。
承認されると、モデルのバージョンのステータスが変わるはずです。
推論パイプラインを実行する(オプション)
このステップは必須ではありませんが、開発アカウントで推論パイプラインを実行して予測を生成することができます。
<project-name>/pipelines/inference
の下に、次のPythonスクリプトが表示されます:- scripts/lambda_helper.py – SageMakerパイプラインのLambdaステップを使用して、中央のモデルレジストリアカウントから最新の承認されたモデルバージョンを取得します。
- inference_pipeline.py – モデル推論パイプラインのコードを含みます。
以下の手順を完了してください:
-
スクリプトをS3バケットにアップロードします:
import boto3s3_client = boto3.resource('s3')s3_client.Bucket(default_bucket).upload_file("pipelines/inference/scripts/lambda_helper.py","mammography-severity-model/scripts/lambda_helper.py")
-
通常のバッチデータセットを使用して推論パイプラインインスタンスを取得します:
from pipelines.inference.inference_pipeline import get_pipelineinference_pipeline = get_pipeline( region=region, role=role, lambda_role = lambda_role, default_bucket=default_bucket, kms_key=kms_key, model_name = model_name, model_package_group_name= model_package_group_name, pipeline_name="mammo-severity-inference-pipeline", batch_dataset_filename = "mammo-batch-dataset" )
-
推論パイプラインを提出して実行します:
inference_pipeline.upsert(role_arn=role)inference_execution = inference_pipeline.start()
以下の図は、推論パイプラインの成功した実行を示しています。パイプラインの最終ステップでは、予測を生成してそれらをS3バケットに保存します。バッチトランスフォームジョブへの入力を監視するためにMonitorBatchTransformStepを使用します。外れ値がある場合、推論パイプラインは失敗状態になります。
Jenkinsパイプラインを実行する
environment/
フォルダは、プロダクションアカウントの設定スクリプトを含んでいます。以下の手順を完了してJenkinsパイプラインをトリガーします:-
前の手順で作成したリソースに基づいて、
prod.tfvars.json
の設定スクリプトを更新します:{ "env_group": "prod", "aws_region": "us-east-1", "event_bus_name": "default", "pipelines_alert_topic_name": "mammography-model-notification", "email":"[email protected]", "lambda_role":"arn:aws:iam::<prod-account-id>:role/lambda-sagemaker-role", "default_bucket":"<s3-bucket-in-prod-account>", "model_artifacts_bucket": "<s3-bucket-in-central-model-registry-account>", "kms_key": "arn:aws:kms:us-east-1:<prod-account-id>:key/<kms-key-id-in-prod-account>", "model_name": "mammography-severity-model", "model_package_group_name":"arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package-group/mammo-severity-model-package", "train_pipeline_name":"mammo-severity-train-pipeline", "inference_pipeline_name":"mammo-severity-inference-pipeline", "batch_dataset_filename":"mammo-batch-dataset", "terraform_state_bucket":"<s3-bucket-terraform-state-in-prod-account>", "train_pipeline": { "name": "mammo-severity-train-pipeline", "arn": "arn:aws:sagemaker:us-east-1:<prod-account-id>:pipeline/mammo-severity-train-pipeline", "role_arn": "arn:aws:iam::<prod-account-id>:role/service-role/<sagemaker-execution-role-in-prod-account>" }, "inference_pipeline": { "name": "mammo-severity-inference-pipeline", "arn": "arn:aws:sagemaker:us-east-1:<prod-account-id>:pipeline/mammo-severity-inference-pipeline", "cron_schedule": "cron(0 23 * * ? *)", "role_arn": "arn:aws:iam::<prod-account-id>:role/service-role/<sagemaker-execution-role-in-prod-account>" }}
-
更新後、コードをフォークされたGitHubリポジトリにプッシュし、コードをメインブランチにマージします。
-
Jenkins UIに移動し、「パラメータ付きでビルド」を選択し、前の手順で作成したCI/CDパイプラインをトリガーします。
ビルドが完了し、成功した場合、prodアカウントにログインして、SageMaker Studioドメイン内のトレーニングと推論パイプラインを表示することができます。
さらに、prodアカウントのEventBridgeコンソールには3つのEventBridgeルールが表示されます:
- 推論パイプラインのスケジュール
- トレーニングパイプラインの失敗通知を送信
- 推論パイプラインがトレーニングパイプラインをトリガーできない場合、通知を送信する
最後に、Amazon SNSコンソールにはメールを通じて通知を送信するSNS通知トピックが表示されます。これらの通知メールの受け入れを確認するためのメールが届きます。
外れ値のないバッチデータセットを使用して推論パイプラインをテストする
推論パイプラインがprodアカウントで期待どおりに動作しているかをテストするために、外れ値のないバッチデータセットを使用してprodアカウントにログインし、推論パイプラインをトリガーすることができます。
prodアカウントのSageMaker Studioドメイン内のSageMaker Pipelinesコンソールを介してパイプラインを実行します。ここで、
transform_input
は外れ値のないデータセットのS3 URI(s3://<s3-bucket-in-prod-account>/mammography-severity-model/data/mammo-batch-dataset.csv
)になります。推論パイプラインは成功し、予測結果をS3バケットに書き込みます。
外れ値を含むバッチデータセットを使用して推論パイプラインをテストする
自動再学習機構が期待どおりに機能しているかを確認するために、外れ値を含むバッチデータセットを使用して推論パイプラインを実行できます。
prodアカウントのSageMaker Studioドメイン内のSageMaker Pipelinesコンソールを介してパイプラインを実行します。ここで、
transform_input
は外れ値を含むデータセットのS3 URI(s3://<s3-bucket-in-prod-account>/mammography-severity-model/data/mammo-batch-dataset-outliers.csv
)になります。推論パイプラインは期待どおりに失敗し、EventBridgeルールがトリガーされ、それによってトレーニングパイプラインがトリガーされます。
数分後に、SageMaker Pipelinesコンソールで新しいトレーニングパイプラインの実行が表示され、S3バケットにアップロードされた2つの異なるトレーニングデータセット(
mammo-train-dataset-part1.csv
とmammo-train-dataset-part2.csv
)が取り込まれ、モデルの再学習が行われます。SNSトピックに登録したメールアドレスに通知も届きます。
更新されたモデルバージョンを使用するには、中央モデルレジストリアカウントにログインし、モデルバージョンを承認する必要があります。承認されたモデルバージョンは、予定されたEventBridgeルールを介してトリガーされた推論パイプラインの次回実行時に取り込まれます。
トレーニングパイプラインと推論パイプラインは静的なデータセットURLを使用していますが、実際のシナリオで更新されたデータセットを使用してモデルの再学習と予測を行うために、データセットのURLを動的な変数としてトレーニングパイプラインと推論パイプラインに渡すこともできます。
クリーンアップ
将来的な料金が発生しないよう、以下の手順を完了してください:
- AWSアカウント全体でSageMaker Studioドメインを削除してください。
- SageMaker以外で作成されたすべてのリソース(S3バケット、IAMロール、EventBridgeルール、Terraformを使用してプロダクトアカウントに設定されたSNSトピック)を削除してください。
- AWSコマンドラインインターフェース(AWS CLI)を使用して、アカウント間で作成されたSageMakerパイプラインを削除してください。
結論
組織はしばしば、企業全体のツールセットに合わせて異なる機能領域やチーム間での協力を可能にする必要があります。この協力により、MLOpsプラットフォームはビジネスの変化に適応し、チーム全体でMLの導入を加速させることができます。この記事では、Amazon SageMaker Model Monitorを使用した自動モデル再学習、バッチ推論、監視、SageMaker Model Registryを使用したモデルバージョニング、CI/CDパイプラインを介した環境間でのMLコードおよびパイプラインの促進を可能にする、マルチ環境セットアップでのMLOpsフレームワークの作成方法を説明しました。このソリューションはAWSのサービスとサードパーティのツールセットの組み合わせを使用して展示しました。このソリューションの実装手順については、GitHubリポジトリを参照してください。また、独自のデータソースやモデリングフレームワークを組み込むことで、このソリューションを拡張することもできます。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles