はじめに
Azure Machine Learning (AML) を使うと誰でも簡単にクラウド上に機械学習環境を用意でき、モデル作成や推論用 API をスピーディに公開することができます。この AML ですが、MLOps を実現するプラットフォームとしても有用でして、Azure DevOps や GitHub Actions などの CI/CD ツールと簡単に連携することができます。今回は AML のプレビュー中の機能である外部へのイベント送信機能とその実装方法について紹介します。
AML から送信できるイベント
では早速、AML からどんなイベントを送信することができるのでしょうか。こちらに示すように、現時点では 5 つのイベントを利用することができます。ふむふむ、MLOps で使えそうですね。
イベントの種類 | 説明 |
---|---|
Microsoft.MachineLearningServices.RunCompleted | 機械学習実験の実行が完了したときに発生します |
Microsoft.MachineLearningServices.ModelRegistered | 機械学習モデルがワークスペースに登録されたときに発生します |
Microsoft.MachineLearningServices.ModelDeployed | 1 つ以上のモデルを持つ推論サービスのデプロイが完了したときに発生します |
Microsoft.MachineLearningServices.DatasetDriftDetected | 2 つのデータセットのデータ ドリフト検出ジョブが完了したときに発生します |
Microsoft.MachineLearningServices.RunStatusChanged | 実行状態が変化したときに発生します |
MLOps リファレンスアーキテクチャと今回のテーマ
この MLOps リファレンスアーキテクチャは、エンジニアが既に慣れているツールを使用して、プロジェクトのさまざまな段階をエンドツーエンドで自動化する方法を示しています。リファレンスアーキテクチャの図から、今回のテーマとなるデプロイ(リリース)パイプラインの部分を取り出したのが以下の図になります。
今回は新しいモデルが利用可能になるたびに、デプロイパイプラインがトリガーされる仕組みを実装します。AML モデルレジストリに新しく登録されるモデルは、リリース成果物として扱われます。AML と Event Grid との連携によって、以下の図のように AML ワークスペース内で発生したイベントを外部イベントハンドラに送信することができます。
ちなみにモデルのトレーニングは AML の機械学習パイプラインにて、モデルの管理は AML モデルレジストリを利用しています。
事前準備
- Azure Machine Learning ワークスペース
- Azure CLI を使用してサービスプリンシパルが作成できること
- Azure LogicApps および Azure Event Grid リソースを作成できること
Azure サブスクリプションで 一度も LogicApps/Event Grid を使用したことがない場合は、リソース プロバイダーを登録する必要があります。こちらの手順にしたがって 以下のリソースを Registered (登録済み)にしてください。
Microsoft.EventGrid
,Microsoft.Web
- Github アカウント or Azure DevOps
- AML CLI v2 の最新かつエラーの出ないバージョン(2.10.0)を利用
無料アカウントもしくは Azure Pass で Azure DevOps を使用している場合、パイプライン実行時に申請が必要となり承認に数日かかります。すでにパイプラインが実行可能な方のみ選択してください。
今回は GitHub Actions と Azure DevOps どちらでも試せるように作成しています。
1. AML から GitHub Actions のワークフローをトリガーする
1.1. Github Actions を使用したデプロイパイプライン構築
- GitHub にリポジトリを作成します。リポジトリファイルの準備のしかたは省略しますが、こちらが参考になります。
- Azure CLI を使用してサービスプリンシパルを作成し、クレデンシャル
AZURE_CREDENTIALS
を シークレットとして GitHub に保存します。 - GitHub Actions ワークフロー中で使用するリポジトリシークレット
AZURE_RESOURCE_GROUP_NAME
,AZURE_ML_WORKSPACE_NAME
も同様に登録します。 - GitHub Actions で デプロイパイプラインのワークフローを作成します。例:
name: Azure ML Trigger Deploy Pipeline on: repository_dispatch: types: [deploy_pipeline_action] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Log in with Azure uses: azure/login@v1 with: creds: '${{secrets.AZURE_CREDENTIALS}}' - name: Install ML extension for az command run: az extension add --name ml --version 2.10.0 - name: Replace modelName and modelVersion in YAML run: yq -i '.model = "azureml:${{github.event.client_payload.model_name}}:${{github.event.client_payload.model_version}}"' managed_deployment.yml - name: Trigger AML Pipeline Job run: az ml online-deployment update -f managed_deployment.yml -g ${{ secrets.AZURE_RESOURCE_GROUP_NAME }} -w ${{ secrets.AZURE_ML_WORKSPACE_NAME }}
- 作成したワークフローのトリガーは
on: repository_dispatch
イベント を使用して、外部から起動できるようにします。 -
on: repository_dispatch
イベントは、${{github.event.client_payload.model_name}}
のようにして送信されたパラメータを抽出することができます。
1.2. Logic Apps によるモデル登録トリガーの作成
- Azure Portal を開き Azure Machine Learning ワークスペースに移動し、こちらを参考にLogic Apps 連携によるイベント受信トリガーを作成します。
- Azure Machine Learning から送信される ModelRegistered イベントのデータは JSON 形式なので次のステップは「JSON の解析」アクションを作成します。JSON のスキーマには以下をコピー&ペーストします。ドキュメントにあるスキーマではうまく動きませんでした。
{"properties":{"data":{"properties":{"modelName":{"type":"string"},"modelProperties":{"properties":{"azureml.artifactPrefix":{"type":"string"},"flavors":{"type":"string"},"flavors.python_function":{"type":"string"},"flavors.sklearn":{"type":"string"},"mlflow.modelSourceUri":{"type":"string"},"model_json":{"type":"string"}},"type":"object"},"modelTags":{"properties":{},"type":"object"},"modelVersion":{"type":"string"}},"type":"object"},"dataVersion":{"type":"string"},"eventTime":{"type":"string"},"eventType":{"type":"string"},"id":{"type":"string"},"metadataVersion":{"type":"string"},"subject":{"type":"string"},"topic":{"type":"string"}},"type":"object"}
- ModelRegistered イベントの JSON データから登録されたモデル名とモデルバージョン番号を取得し、それらの値をパイプラインエンドポイントのパラメータとして指定して「リポジトリ ディスパッチ イベントを作成する」アクションを作成します。初めて作成したときは GitHub へのサインインとアプリ承認が必要です。これによって Azure Logic Apps から OAuth 経由で GitHub へアクセスすることができるようになります。
- イベント名:
deploy_pipeline_action
- イベント ペイロード: 以下の未完成の JSON をコピー&ペーストし、
modelName
とmodelVersion
は画像のように動的メニューから選択します。前のステップの「JSON の解析」アクションが JSON をパースしてくれているので、このように特定のキーを当てはめることができるようになります。
ちなみに{ "model_name": , "model_version": }
ModelRegistered
イベントはモデルのタグやプロパティ情報も取得できます。 - イベント名:
- AML でモデルを登録して動作を検証します。
- Logic Apps の実行履歴は、概要ページから確認することができます。
- 状態が「正常」であればデプロイパイプラインが起動され、パイプラインジョブが実行されます。実行履歴画面から、ステップごとに実際に流れたデータを確認することができます。以下の図では、AML から ModelRegistered イベントと共に送られてきたモデル名とモデルバージョン番号を正常に Github Actions へ送信できたことを示しています。
- Github Actions 側のデプロイパイプラインが正常に起動していることを確認します。
- Azure Machine Learning で新しいモデルがエンドポイントにデプロイされたことを確認できれば完了です。
2. AML から Azure DevOps のパイプラインをトリガーする
2.1. Azure DevOps を使用したデプロイパイプライン構築
こちらを参考にパイプラインを構築します。
- Azure Pipelines にサインインし組織を作成
- Azure Resource Manager の接続を作成。
machine-learning-connection
- Azure Repos Git リポジトリの作成(コードは GitHub ではなく、Azure Repos Git に配置します)
- 変数を作成。
RESOURCE_GROUP
,AML_WORKSPACE_NAME
- YAML パイプラインを構築。例:
trigger: none pr: none parameters: - name: "model_name" type: string displayName: "ModelName" - name: "model_version" type: number default: 0 displayName: "ModelVersion" pool: vmImage: ubuntu-latest steps: - task: AzureCLI@2 displayName: Azure CLI inputs: azureSubscription: machine-learning-connection scriptType: bash scriptLocation: inlineScript inlineScript: | az extension add --name ml --version 2.10.0 yq -i '.model = "azureml:${{parameters.model_name}}:${{parameters.model_version}}"' managed_deployment.yml az ml online-deployment update -f managed_deployment.yml -g $(RESOURCE_GROUP) -w $(AML_WORKSPACE_NAME)
-
OAuth によるサードパーティアプリケーションのアクセス許可
Azure Pipelines で構築したパイプラインは、外部サービスから REST API エンドポイントを通じてトリガーすることができます。エンドポイントにリクエスト送信する際にはユーザー名とパスワードではなく、OAuth による認証を使用します。
2.2. Logic Apps によるモデル登録トリガーの作成
こちらは「JSON の解析」アクションまでは GitHub の時と同じです。
- 新しいステップをクリックし、検索ボックスに「devops」と入力して「Azure DevOps に HTTP 要求を送信する」アクションをクリックします。
- 「Azure DevOps に HTTP 要求を送信する」アクションでは、以下のとおりに入力します。さらに下部の「Add new parameter」ドロップダウンをクリックし、「ボディ」チェックをオンにします。オンにしたら一旦キャンバス部分をクリックしてフォーカスを外します。
- 組織名: ご自分の組織名をドロップダウンから選択
- 方法:
POST
- 相対 URI:
https://dev.azure.com/{Organization}/{ProjectName}/_apis/pipelines/{PipelineID}/runs?api-version=7.0
Azure Pipelines のパイプライン管理画面から作成したパイプラインをクリックしたときの URL からマッピングします。https://dev.azure.com/{Organization}/{ProjectName}/_build?definitionId={PipelineID}&view=runs
のような対応になります。PipelineID は整数値であることに注意してください。
- 本文: 以下の未完成の JSON をコピー&ペーストし、
modelName
とmodelVersion
は画像のように動的メニューから選択します。"model_name"
はダブルクォーテーションの間にカーソルを合わせて挿入します。{ "resources": { "repositories": { "self": { "refName": "refs/heads/main" } } }, "templateParameters": { "model_name": "", "model_version": } }
- AML でモデルを登録して動作を検証します。
- Logic Apps の実行履歴は、概要ページから確認することができます。
- 状態が「正常」であればデプロイパイプラインが起動され、パイプラインジョブが実行されます。実行履歴画面から、ステップごとに実際に流れたデータを確認することができます。
- Azure Pipelines 側のデプロイパイプラインが正常に起動していることを確認します。下のようにパイプラインに送信されたパラメーターが受信できていることも確認できます。
- Azure Machine Learning で新しいモデルがエンドポイントにデプロイされたことを確認できれば完了です。
承認ゲート
今回単純化して記事を書いていますが、MLOps リファレンスアーキテクチャには、検証環境と運用環境の間に承認ゲートがあります。これは GitHub Actions や Azure DevOps でも簡単に導入することができます。
このタスクをパイプラインに導入すると、モデルのデプロイ前に人手による承認が必要になります。承認者を設定して、承認催促メールを送信することができます。
まとめ
Azure Logic Apps で繋ぐところさえうまくできれば、あとは簡単。AML イベント駆動での MLOps ライフが可能に!
あと AML CLI v2 とっても良くないですか? Python などの特定の言語に依存せず、az extension add --name ml
一発で使用可能になりますので DevOps/インフラ系エンジニアとの親和性抜群です。もちろん、Python SDK v2 でも同じ機能が使えますので、エンジニアの好みで分けてもいいかと思います。使い分けについては参考。
さいごに
Microsoft では OpenHack というイベントを開催しています。AI や Modern Data Warehouse などのワークロードごとに、数日間にわたりチームで課題を解決する非常に満足度の高いハックイベントです。これに準ずる形で MLOps をテーマにしたハッカソンやハンズオンを実施しています。AML × MLOps に興味がある方はぜひ Microsoft 担当までご一報を! ※参加にはサブスクリプションや人数などの制限がございます。