🌟

Azure Machine Learning Inference HTTP Serverを使って推論スクリプトをローカルで実行する

2022/12/13に公開

はじめに

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を対象にしています。

ドキュメント上に比較表が掲載されています。

シナリオ Inference HTTP Server ローカルエンドポイント
Docker イメージの再構築なしで、ローカルの Python 環境を更新 Yes No
スコアリングスクリプトの更新 Yes Yes
デプロイメント設定(デプロイメント、環境、コード、モデル)の更新 No Yes
VSCode でのデバッグ連携 Yes Yes

推論 HTTP サーバをローカルで実行することにより、デプロイメント コンテナの設定に影響されることなく、スコアリング スクリプトのデバッグに集中することができます。

前提条件

  • AzureML の使用経験
  • Python >=3.7
  • Anaconda インストール済み

スコアリングスクリプトの推論サーバでのデバッグ

ダミーのスコアリングスクリプトでサーバーの挙動を理解する

(ドキュメントの内容ベースのセクションです)

  1. ファイルを格納するディレクトリを作成します。

    mkdir server_quickstart
    cd server_quickstart
    
  2. パッケージの競合を避けるため、仮想環境を作成することが推奨されます。

    virtualenv myenv
    source myenv/bin/activate
    
  3. pypiから azureml-inference-server-httpパッケージをインストールします。

    python -m pip install azureml-inference-server-http
    
  4. エントリースクリプト(score.py)を作成します。以下の例では、基本的なエントリースクリプトを作成しています。こいつはどんな入力があっても {"message":"Hello, World!"}と返します。

    echo '
    import time
    
    def init():
        time.sleep(1)
    
    def run(input_data):
        return {"message":"Hello, World!"}
    ' > score.py
    
  5. 推論サーバー (azmlinfsrv) を起動し、エントリースクリプトとして score.py を設定します。

    azmlinfsrv --entry_script score.py
    
  6. curl を使ってサーバーにスコアリングリクエストを送ります。

    curl -p 127.0.0.1:5001/score
    

    サーバーからこのような応答があります。

    {"message": "Hello, World!

このように、推論サーバーを使用することで、ローカル上でscore.pyの動作確認を簡単に行うことができました。

サンプルモデル/スクリプト/環境を使用した例

ここでは、サンプルのリポジトリにある サンプルファイル (モデル/スクリプト/環境) を使って、ローカルで推論サーバーを実行します。サンプルファイルは、機械学習モデルをオンライン エンドポイントにデプロイするのドキュメントでも使用されています。

  1. サンプルリポジトリをクローンします。

    git clone --depth 1 https://github.com/Azure/azureml-examples
    cd azureml-examples/cli/endpoints/online/model-1/
    
  2. 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
    
  3. スコアリングスクリプトの内容は下記になっています。
    ファイル:azureml-examples/score.py at main · Azure/azureml-examples

    import 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()
    
  4. スコアリングスクリプトとモデルファイルを指定して推論サーバーを起動します。
    指定されたモデルディレクトリ(model_dirパラメーター)は AZUREML_MODEL_DIR 変数として定義され、スコアリングスクリプトの中で取得されます。
    今回の場合、スコアリングスクリプト内のパス指定部分でサブディレクトリが model/sklearn_regression_model.pkl との形で指定されているので、引数ではカレントディレクトリ (./) を指定します。

    azmlinfsrv --entry_script ./onlinescoring/score.py --model_dir ./
    

    サーバが起動し、スコアリングスクリプトの呼び出しに成功した場合、下記のようなログが表示されます。もし問題が発生していればログにエラーメッセージが表示されます。

  5. サンプルリクエストファイルでのスコアリングスクリプトテスト
    別のターミナルを開き、同じ作業ディレクトリに移動してコマンドを実行します。
    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等を使ったデバッグを行いたい際に、簡単に推論サーバー経由で実行結果を確認することができます。

参考

GitHubで編集を提案
Microsoft (有志)

Discussion