次の方法で共有


バッチ デプロイで出力をカスタマイズする

適用対象:Azure CLI ml extension v2 (現行)Python SDK azure-ai-ml v2 (現行)

このガイドでは、カスタム出力とファイルを生成するデプロイを作成する方法について説明します。 場合によっては、バッチ推論ジョブからの出力として書き込まれるものをより高度に制御する必要がある場合があります。 たとえば、次のような状況です。

  • 予測が出力に書き込まれる方法を制御する必要がある場合。 予測を元のデータに追加する場合などがあります (データが表形式の場合)。
  • バッチ デプロイですぐにサポートされるものとは異なるファイル形式で予測を記述する必要がある場合。
  • モデルが、出力を表形式で記述できない生成モデルの場合。 画像を出力として生成するモデルなどがあります。
  • モデルが、1 つではなく、複数の表形式ファイルを生成する場合。 複数のシナリオを考慮して予測を実行するモデルなどです。

バッチ デプロイでは、バッチ デプロイ ジョブの出力に直接書き込むことで、ジョブの出力を制御できます。 このチュートリアルでは、モデルをデプロイしてバッチ推論を実行し、予測を元の入力データに追加することで出力を parquet 形式で書き込む方法について説明します。

このサンプルについて

この例では、モデルをデプロイしてバッチ推論を実行し、予測を出力に書き込む方法をカスタマイズする方法を示します。 このモデルは、UCI Heart Disease データセットをベースにしています。 このデータベースには 76 個の属性が含まれていますが、この例ではそのうちの 14 個のサブセットを使用します。 このモデルは、患者の心臓病の存在を予測しようと試みるものです。 これは 0 (存在しない) から 1 (存在する) の整数値です。

モデルは XGBBoost 分類器を使ってトレーニングされ、必要な前処理はすべて scikit-learn パイプラインとしてパッケージ化されたため、このモデルは生データから予測までを行うエンドツーエンドのパイプラインになっています。

この記事の例は、azureml-examples リポジトリに含まれているコード サンプルを基にしています。 YAML などのファイルをコピーして貼り付けることなくコマンドをローカルで実行するには、最初にリポジトリを複製してから、ディレクトリをそのフォルダーに変更します。

git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli

この例のファイルは、次の場所にあります。

cd endpoints/batch/deploy-models/custom-outputs-parquet

Jupyter ノートブックで作業を進める

この例に従って実行するために使用できる Jupyter ノートブックがあります。 複製されたリポジトリで、custom-output-batch.ipynb というノートブックを開きます。

前提条件

  • Azure サブスクリプション。 Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。 無料版または有料版の Azure Machine Learning をお試しください。

  • Azure Machine Learning ワークスペース。 ワークスペースを作成するには、「Azure Machine Learning ワークスペースの管理」を参照してください。

  • Machine Learning ワークスペースでの以下のアクセス許可があることを確認してください。

    • バッチ エンドポイントとバッチ デプロイを作成または管理する: 所有者または共同作成者のロール、あるいは Microsoft.MachineLearningServices/workspaces/batchEndpoints/* を許可するカスタム役割を使用します。
    • ワークスペース リソース グループ内での Azure Resource Manager デプロイの作成: 所有者、共同作成者、またはワークスペースがデプロイされるリソース グループ での Microsoft.Resources/deployments/write を許可するカスタム ロールを使用します。
  • Machine Learning を使用するには、以下のソフトウェアをインストールします。

    次のコマンドを実行して、Azure CLIml という Azure Machine Learning 用の拡張機能をインストールします。

    az extension add -n ml
    

    バッチ エンドポイントのパイプライン コンポーネント デプロイは、Azure CLI 用拡張機能 ml のバージョン 2.7 で導入されました。 az extension update --name ml コマンドを使用して、最新バージョンを取得します。


ワークスペースに接続する

ワークスペースは、Machine Learning の最上位のリソースです。 これは Machine Learning を使用する際に作成するすべての成果物を操作するための一元的な場所を提供します。 このセクションでは、デプロイ タスクを実行するワークスペースに接続します。

次のコマンドで、サブスクリプション ID、ワークスペース、場所、リソース グループの値を入力します。

az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>

カスタム出力を使用してバッチ デプロイを作成する

この例では、バッチ デプロイ ジョブの出力フォルダーに直接書き込むことができるデプロイを作成します。 デプロイでは、この機能を使用してカスタム Parquet ファイルを書き込みます。

モデルを登録する

バッチ エンドポイントを使ってデプロイできるのは登録済みのモデルのみです。 この場合、リポジトリにモデルのローカル コピーが既に存在するため、ワークスペース内のレジストリにモデルを発行するだけで済みます。 デプロイ対象のモデルが既に登録されている場合は、この手順をスキップできます。

MODEL_NAME='heart-classifier-sklpipe'
az ml model create --name $MODEL_NAME --type "custom_model" --path "model"

スコアリング スクリプトを作成する

バッチ デプロイによって指定された入力データを読み取り、モデルのスコアを返すことができるスコアリング スクリプトを作成する必要があります。 また、ジョブの出力フォルダーに直接書き込みます。 要約すると、提案されたスコアリング スクリプトは次のように動作します。

  1. 入力データを CSV ファイルとして読み取ります。
  2. 入力データに対して MLflow モデル predict 関数を実行します。
  3. 入力データと共に予測を pandas.DataFrame に追加します。
  4. 入力ファイルとして指定されたファイルにデータを書き込みますが、parquet 形式です。

code/batch_driver.py

import os
import pickle
import glob
import pandas as pd
from pathlib import Path
from typing import List


def init():
    global model
    global output_path

    # AZUREML_MODEL_DIR is an environment variable created during deployment
    # It is the path to the model folder
    # Please provide your model's folder name if there's one:
    output_path = os.environ["AZUREML_BI_OUTPUT_PATH"]
    model_path = os.environ["AZUREML_MODEL_DIR"]
    model_file = glob.glob(f"{model_path}/*/*.pkl")[-1]

    with open(model_file, "rb") as file:
        model = pickle.load(file)


def run(mini_batch: List[str]):
    for file_path in mini_batch:
        data = pd.read_csv(file_path)
        pred = model.predict(data)

        data["prediction"] = pred

        output_file_name = Path(file_path).stem
        output_file_path = os.path.join(output_path, output_file_name + ".parquet")
        data.to_parquet(output_file_path)

    return mini_batch

備考:

  • 環境変数 AZUREML_BI_OUTPUT_PATH を使用して、デプロイ ジョブの出力パスにアクセスする方法に注意してください。
  • この init() 関数は、記述する場所を後で把握するために使用できる、output_path と呼ばれるグローバル変数を設定します。
  • この run メソッドは、処理されたファイルの一覧を返します。 これは、run 関数が list または pandas.DataFrame オブジェクトを返すために必要です。

警告

すべてのバッチ Executor に、このパスへの書き込みアクセス権が同時に付与されることを考慮してください。 つまり、コンカレンシーを考慮する必要があります。 この場合、各 Executor が出力フォルダーの名前として入力ファイル名を使用して独自のファイルを書き込むようにします。

エンドポイントを作成する

次に、heart-classifier-batch という名前のバッチ エンドポイントを作成し、そこにモデルをデプロイします。

  1. エンドポイントの名前を決めます。 エンドポイント名はエンドポイントに関連付けられる URI に含まれるため、"バッチ エンドポイント名は Azure リージョン内で一意である必要があります"。 たとえば、westus2 に存在できる mybatchendpoint という名前のバッチ エンドポイントは 1 つだけです。

    今回は、後で簡単に参照できるように、エンドポイント名を変数に配置します。

    ENDPOINT_NAME="heart-classifier-custom"
    
  2. バッチ エンドポイントを構成します。

    次の YAML ファイルは、バッチ エンドポイントを定義します。

    endpoint.yml

    $schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json
    name: heart-classifier-batch
    description: A heart condition classifier for batch inference
    auth_mode: aad_token
    
  3. エンドポイントを作成します。

    az ml batch-endpoint create -n $ENDPOINT_NAME -f endpoint.yml
    

デプロイを作成する

次の手順に従って、前のスコアリング スクリプトを使用してデプロイを作成します。

  1. 最初に、スコアリング スクリプトが実行される環境を作成します。

    Azure Machine Learning CLI の場合、追加の手順は必要ありません。 環境定義はデプロイ ファイルに含まれています。

    environment:
      name: batch-mlflow-xgboost
      image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
      conda_file: environment/conda.yaml
    
  2. 配置を作成します。 output_actionSUMMARY_ONLY に設定されていることに注意してください。

    Note

    この例では、名前が batch-cluster のコンピューティング クラスターがあることを前提としています。 名前を適宜変更します。

    作成されたエンドポイントの下に新しいデプロイを作成するには、次のような YAML 構成を作成します。 追加のプロパティについては、完全なバッチ エンドポイント YAML スキーマを確認してください。

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: heart-classifier-batch
    name: classifier-xgboost-custom
    description: A heart condition classifier based on XGBoost and Scikit-Learn pipelines that append predictions on parquet files.
    type: model
    model: azureml:heart-classifier-sklpipe@latest
    environment:
      name: batch-mlflow-xgboost
      image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
      conda_file: environment/conda.yaml
    code_configuration:
      code: code
      scoring_script: batch_driver.py
    compute: azureml:batch-cluster
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 2
      mini_batch_size: 2
      output_action: summary_only
      retry_settings:
        max_retries: 3
        timeout: 300
      error_threshold: -1
      logging_level: info
    

    次に、次のコマンドを使ってデプロイを作成します。

    az ml batch-deployment create --file deployment.yml --endpoint-name $ENDPOINT_NAME --set-default
    
  3. この時点で、バッチ エンドポイントを使用する準備は完了です。

展開をテスト

エンドポイントをテストするには、このリポジトリ内にあり、このモデルに使用できるラベルのないデータのサンプルを使用します。 バッチ エンドポイントは、クラウド内にあり、Azure Machine Learning ワークスペースからアクセスできるデータのみを処理できます。 この例では、これを Azure Machine Learning データ ストアにアップロードします。 スコアリングのためにエンドポイントを呼び出すのに使用できるデータ資産を作成します。 ただし、バッチ エンドポイントは、さまざまな場所に配置されている可能性があるデータを受け入れることに注意してください。

  1. ストレージ アカウントからのデータを使用してエンドポイントを呼び出します。

    JOB_NAME = $(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input https://azuremlexampledata.blob.core.windows.net/data/heart-disease-uci/data --query name -o tsv)
    

    Note

    ユーティリティ jq は、すべてのインストールでインストールされるとは限りません。 手順は、GitHub のこちらを参照してください。

  2. コマンドが戻ると、すぐにバッチ ジョブが開始されます。 ジョブの状態は、完了するまで監視できます。

    az ml job show -n $JOB_NAME --web
    

出力を分析する

このジョブは、生成されたすべてのファイルが配置される score という名前の出力を生成します。 入力ファイルごとに 1 つのファイルをディレクトリに直接書き込んだので、同じ数のファイルがあるはずです。 この特定の例では、出力ファイルに入力と同じ名前を付けますが、Parquet 拡張子が付けられます。

Note

ファイル predictions.csv も出力フォルダーに含まれていることに注意してください。 このファイルには、処理されたファイルの概要が含まれています。

ジョブ名を使って、その結果をダウンロードできます。

予測をダウンロードするには、次のコマンドを使用します。

az ml job download --name $JOB_NAME --output-name score --download-path ./

ファイルがダウンロードされたら、お気に入りのツールを使って開くことができます。 次の例では、Pandas データフレームを使って予測を読み込みます。

import pandas as pd
import glob

output_files = glob.glob("named-outputs/score/*.parquet")
score = pd.concat((pd.read_parquet(f) for f in output_files))
score

出力は次のようになります。

age sex ... thal prediction
63 1 ... 固定 0
67 1 ... 普通 1
67 1 ... 反転可能 0
37 1 ... 普通 0

リソースをクリーンアップする

次のコードを実行して、バッチ エンドポイントと基になるすべてのデプロイを削除します。 バッチ スコアリング ジョブは削除されません。

az ml batch-endpoint delete --name $ENDPOINT_NAME --yes