Azure Machine Learning Inference HTTP Serverを使って推論スクリプトをローカルで実行する
はじめに
Azure Machine Learning inference HTTP server (推論HTTPサーバー)を使うことで、ローカル上で推論 (スコアリング)スクリプトの実行・デバッグを簡単に行えます。ローカルエンドポイントでのデバッグより遥かに簡単に行えるものの、ローカルエンドポイントに比べてあまり知られていないためまとめました。ドキュメント上にダミースクリプトでの実行例しかなかったため (2022/12/13現在)、ダミースクリプトの例と共に、実際のサンプルモデル/スクリプト/環境を扱った例を追加しました。
ドキュメント:Azure Machine Learning 推論 HTTP サーバー - Azure Machine Learning | Microsoft Learn
[2023/03/30追記]
本記事のサンプルモデル/スクリプト/環境を使用した例と同等のセクションを製品ドキュメント側に記載いたしました。より最新かつ包括的な内容はドキュメントを参照頂ければと思います。
Azure Machine Learning inference HTTP server (推論HTTPサーバー) とは
Azure Machine Learning inference HTTP server (推論HTTPサーバー)は、機械学習モデルのスコアリングスクリプトをHTTPエンドポイントとして公開し、Flaskサーバのコードと依存関係を単一のパッケージにラップしたPythonパッケージです。Azure Machine Learning でモデルをデプロイする際に使用する 推論用の事前構築済み Docker イメージ に含まれています。このパッケージ単体で使用することで、ローカルな開発環境で簡単に入力スクリプト(score.py
)を検証することができます。スコアリングスクリプトに問題がある場合、サーバーはエラーを返すので、デバッグに活用できます。
オンラインエンドポイントのローカルでのデバッグ
エンドポイントをクラウドにデプロイする前にローカルでデバッグすることで、コードや設定のエラーを早期に発見することができます。エンドポイントをローカルでデバッグするには、さまざまなオプションがあります。
- Azure Machine Learning inference HTTP server (推論HTTPサーバー)
- ローカルエンドポイント
本記事は、Azure Machine Learning inference HTTP serverを対象にしています。
ドキュメント上に比較表が掲載されています。
シナリオ | Inference HTTP Server | ローカルエンドポイント |
---|---|---|
Docker イメージの再構築なしで、ローカルの Python 環境を更新 | Yes | No |
スコアリングスクリプトの更新 | Yes | Yes |
デプロイメント設定(デプロイメント、環境、コード、モデル)の更新 | No | Yes |
VSCode でのデバッグ連携 | Yes | Yes |
推論 HTTP サーバをローカルで実行することにより、デプロイメント コンテナの設定に影響されることなく、スコアリング スクリプトのデバッグに集中することができます。
前提条件
- AzureML の使用経験
- Python >=3.7
- Anaconda インストール済み
スコアリングスクリプトの推論サーバでのデバッグ
ダミーのスコアリングスクリプトでサーバーの挙動を理解する
(ドキュメントの内容ベースのセクションです)
-
ファイルを格納するディレクトリを作成します。
mkdir server_quickstart cd server_quickstart
-
パッケージの競合を避けるため、仮想環境を作成することが推奨されます。
virtualenv myenv source myenv/bin/activate
-
pypiから
azureml-inference-server-http
パッケージをインストールします。python -m pip install azureml-inference-server-http
-
エントリースクリプト(
score.py
)を作成します。以下の例では、基本的なエントリースクリプトを作成しています。こいつはどんな入力があっても{"message":"Hello, World!"}
と返します。echo ' import time def init(): time.sleep(1) def run(input_data): return {"message":"Hello, World!"} ' > score.py
-
推論サーバー (
azmlinfsrv
) を起動し、エントリースクリプトとしてscore.py
を設定します。azmlinfsrv --entry_script score.py
-
curl
を使ってサーバーにスコアリングリクエストを送ります。curl -p 127.0.0.1:5001/score
サーバーからこのような応答があります。
{"message": "Hello, World!}
このように、推論サーバーを使用することで、ローカル上でscore.pyの動作確認を簡単に行うことができました。
サンプルモデル/スクリプト/環境を使用した例
ここでは、サンプルのリポジトリにある サンプルファイル (モデル/スクリプト/環境) を使って、ローカルで推論サーバーを実行します。サンプルファイルは、機械学習モデルをオンライン エンドポイントにデプロイするのドキュメントでも使用されています。
-
サンプルリポジトリをクローンします。
git clone --depth 1 https://github.com/Azure/azureml-examples cd azureml-examples/cli/endpoints/online/model-1/
-
condaで仮想環境を作成しアクティベートします。
今回、azureml-inference-server-http
パッケージは下記conda.yml
内のazureml-defaults
パッケージの依存ライブラリに含まれているため、自動的にインストールされます。# Create the environment from the YAML file conda env create --name model-env -f ./environment/conda.yml # Activate the new environment conda activate model-env
-
スコアリングスクリプトの内容は下記になっています。
ファイル:azureml-examples/score.py at main · Azure/azureml-examplesimport os import logging import json import numpy import joblib def init(): """ This function is called when the container is initialized/started, typically after create/update of the deployment. You can write the logic here to perform init operations like caching the model in memory """ global model # AZUREML_MODEL_DIR is an environment variable created during deployment. # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION) # Please provide your model's folder name if there is one model_path = os.path.join( os.getenv("AZUREML_MODEL_DIR"), "model/sklearn_regression_model.pkl" ) # deserialize the model file back into a sklearn model model = joblib.load(model_path) logging.info("Init complete") def run(raw_data): """ This function is called for every invocation of the endpoint to perform the actual scoring/prediction. In the example we extract the data from the json input and call the scikit-learn model's predict() method and return the result back """ logging.info("model 1: request received") data = json.loads(raw_data)["data"] data = numpy.array(data) result = model.predict(data) logging.info("Request processed") return result.tolist()
-
スコアリングスクリプトとモデルファイルを指定して推論サーバーを起動します。
指定されたモデルディレクトリ(model_dir
パラメーター)はAZUREML_MODEL_DIR
変数として定義され、スコアリングスクリプトの中で取得されます。
今回の場合、スコアリングスクリプト内のパス指定部分でサブディレクトリがmodel/sklearn_regression_model.pkl
との形で指定されているので、引数ではカレントディレクトリ (./
) を指定します。azmlinfsrv --entry_script ./onlinescoring/score.py --model_dir ./
サーバが起動し、スコアリングスクリプトの呼び出しに成功した場合、下記のようなログが表示されます。もし問題が発生していればログにエラーメッセージが表示されます。
-
サンプルリクエストファイルでのスコアリングスクリプトテスト
別のターミナルを開き、同じ作業ディレクトリに移動してコマンドを実行します。
curl` コマンドを使用して、サーバにリクエストを送信し、スコアリングの結果を受け取ります。curl --request POST "127.0.0.1:5001/score" --header 'Content-Type: application/json' --data @sample-request.json
スコアリングスクリプトに問題がなければ、スコアリング結果が返されます。もし何か問題があれば、スコアリングスクリプトを更新して再度サーバーを立ち上げ、更新後のスクリプトをテストすることができます。
サーバー側の実行ログにも推論リクエストが来たことが表示されています。
ログに表示されている "Init complete"、"model 1: request received"、"Request processed"はスコアリングスクリプト側で表示されたものです。このように、スコアリングスクリプト側でprint等を使ったデバッグを行いたい際に、簡単に推論サーバー経由で実行結果を確認することができます。
Discussion