概要
本記事はAzure Machine LearningワークスペースをCLIv2を使って操作するチュートリアルの第3弾です。
使い方を習得すれば自動化パイプラインを自身で構築できるようになります。
やりたいこと
前回の記事でデプロイまでを行いました。
ここまでで学習からデプロイまで一通りの手順を実施できたため、ここから自動化の仕組みを構築していきます。
引き続きCLIv2を使用して学習パイプラインを構築する方法を紹介します。
準備
初回の記事はこちらをご参照ください。
入門編1、2が完了している前提で自動化パイプラインの構築を進めていきます。
blog.jbs.co.jp
Azure CLI 拡張機能(CLIv2)による学習パイプラインの作成
全体像
学習を定期的なスケジュールで実行します。
タイタニック号のデータセットが今後新規に追加・更新されることがありませんが、実際にビジネスで使用されるデータは日々増えていくことが想定されます。 データセットが定期的に更新される場合は、データドリフトの問題からモデルが古くなって精度が落ちていくことが考えられます。また単純に多くのデータから学習を行う方が精度が良くなる可能性もあります。
そのため、新規データセットからモデルを作成して推論エンドポイントを更新し続けることが一つの重要なポイントになります。
これらの背景から、限られたエンジニアの労力を最小限にするために学習を定期実行し続ける自動化基盤の構築を行います。
実運用においてはモデルの精度を計測してAzure Machine Learningワークスペースに登録・デプロイするかどうかを判定する仕組みを組み込んだり、モデル作成に使用するデータをどう選択するかなどを考慮する必要がありますが、今回は単純化のために最小構成での例を示していきます。
前提
事前準備が必要なスクリプト
学習には以下のスクリプトを使用します。
- scripts/train.py
CLIv2のバージョンアップ
CLIv2を使用してスケジューリング実行を定義するためには、v2.10.0以上のCLIv2バージョンが必要になります。 github.com
バージョン変更は以下のコマンドを参考にしてください。 本記事よりバージョン2.11.0を使用します。(前回以降の記事についてもバージョン2.11.0で実行可能です)
az extension remove -n azure-cli-ml az extension remove -n ml az extension add --name ml --version 2.11.0
モデル登録用のスクリプト
学習後にモデルを登録する必要があります。
前回の記事ではコマンドによって学習済みモデルのダウンロード→Azure Machine Learningワークスペースへの登録を行いました。
今回は自動で登録を行いたいので、後述する自動化モジュールに組み込むためのモデル登録用Pythonスクリプトを用意します。
scripts/register.py
import argparse import mlflow from mlflow.pyfunc import load_model from mlflow.tracking import MlflowClient def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--model_name', type=str, help='Name under which model will be registered') parser.add_argument('--model_path', type=str, help='Model directory') args, _ = parser.parse_known_args() return args def main(): args = parse_args() model_name = args.model_name model_path = args.model_path mlflow.set_tag("model_name", model_name) mlflow.set_tag("model_path", model_path) # Load model from model_path model = load_model(model_path + "/models") modelreg = mlflow.sklearn.log_model( sk_model=model, artifact_path="models", registered_model_name=model_name ) client = MlflowClient() model_info = client.get_registered_model(model_name) model_version = model_info.latest_versions[0].version print(model_info) print(model_version) print("Model registered!") if __name__ == "__main__": main()
引数によってAzure Machine Learningワークスペースに登録するモデル名と、実際のモデルファイルのパスを読み込みます。
モデルファイルのパスには、入門編2の「モデルのダウンロード」で示したartifactsフォルダを指定します。
学習&モデル登録パイプラインの設定
パイプラインで以下の流れを作成します。
- train.pyを実行して、データセットからモデルを作成する
- register.pyを実行して、作成したモデルをワークスペースに登録する
パイプラインジョブの作成には新しくyamlファイルを作成します。
training_pipeline_job.yml
$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json type: pipeline display_name: training_titanic_pipeline compute: azureml:cpu-cluster jobs: train_job: code: ./scripts command: >- python train.py --input_data ${{inputs.titanic_data}} --output_dir ${{outputs.outputs}} environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest inputs: titanic_data: type: uri_file path: azureml:titanic_train_dataset@latest mlflow_exp_name: train-titanic outputs: outputs: register_job: code: ./scripts command: >- python register.py --model_name titanic-model --model_path ${{inputs.input}} environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest inputs: input: ${{parent.jobs.train_job.outputs.outputs}}
train.pyによってartifactsフォルダの中身を作成していますが、作成したフォルダのパスをoutputs.outputsで生成し、parent.jobs.train_job.outputs.outputsでregister_jobに渡しています。
上の例では2つのジョブを定義していますが、間に作成したモデルの精度を判定するジョブを挟めば、不必要なモデルの登録を防ぐことができます。
作成したパイプラインジョブは、以下のコマンドで単に実行できます。
az ml job create --file training_pipeline_job.yml
実行後にワークスペースの「パイプライン」項目で、設定したジョブを視覚的に確認することができます。
今回はデータセットを読み込み、学習→モデル登録の順序をyamlファイルで定義したので、その形が表現されています。分岐を作成したり複数のデータセットを読み込んだ場合も、自動で見やすい形に調整して表示してくれます。
スケジューリング実行
パイプラインジョブを定期実行することができます。
learn.microsoft.com
以下の例ではCRON式で実行時刻を定義します。
これによって学習ジョブが定期的に実行され、常に最新のデータで学習したモデルを得ることができます。
(以下の例では1時間ごと、毎時0分に学習が定期実行されます)
pipeline_training.yml
$schema: https://azuremlschemas.azureedge.net/latest/schedule.schema.json name: simple_cron_job_schedule display_name: Simple cron job schedule description: a simple hourly cron job schedule trigger: type: cron expression: "0 * * * *" time_zone: "Tokyo Standard Time" # optional - default will be UTC create_job: ./training_pipeline_job.yml
スケジュールによる実行を作成します。
az ml schedule create --file pipeline_training.yml --no-wait
スケジュールによる実行を無効化するには、以下のコマンドを実行します。
az ml schedule disable -n simple_cron_job_schedule --no-wait
おわりに
今回はCLIv2を使って学習を自動化する方法について示しました。
実際には局所解や収束しないなどの原因で精度が低くなったモデルを登録しない工夫が必要となり、また学習とテストでデータセットを事前に分けておくなどといった構成が必要になります。
目的に応じてスクリプトの構成を変更してください。
推論エンドポイントの自動デプロイについては次回、最終回の記事で紹介します。
本記事の続きはこちらをご覧ください。