Share via


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

適用対象: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 ワークスペース。 準備できていない場合は、Microsoft Azure Machine Learning ワークスペースの管理に関する記事の手順を使用して作成します。

  • ワークスペースに次のアクセス許可があることを確認します。

    • バッチ エンドポイントとバッチ デプロイを作成または管理する: 所有者または共同作成者のロール、あるいは Microsoft.MachineLearningServices/workspaces/batchEndpoints/* を許可するカスタム ロールを使用します。

    • ワークスペース リソース グループに ARM デプロイを作成する: 所有者または共同作成者のロール、あるいはワークスペースがデプロイされているリソース グループで Microsoft.Resources/deployments/write を許可するカスタム ロールを使用します。

  • Azure Machine Learning を使用するには、次のソフトウェアをインストールする必要があります。

    Azure CLImlAzure Machine Learning 用の 拡張機能

    az extension add -n ml
    

    注意

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

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

ワークスペースは、Azure Machine Learning の最上位のリソースで、Azure 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