REST を使ってモデルをデプロイする

この記事では、オンライン エンドポイントを使用することで、Azure Machine Learning REST API を使用してモデルをデプロイする方法について説明します。 オンライン エンドポイントを使用すると、基盤となるインフラストラクチャと Kubernetes クラスターを作成して管理することなくモデルをデプロイできます。 以下の手順では、オンライン エンドポイントとデプロイを作成し、それを呼び出してエンドポイントを検証する方法を示します。

Azure Machine Learning オンライン エンドポイントを作成するには、さまざまな方法があります。 Azure CLIAzure Machine Learning スタジオ、または REST API を使用することができます。 REST API では、標準の HTTP 動詞を使用して、リソースの作成、取得、更新、および削除を行います。 これは HTTP 要求を作成できるすべての言語またはツールで使用できます。 その単純な構造から REST API は、スクリプト環境や機械学習操作の自動化のための適切な選択肢と言えます。

前提条件

エンドポイント名を設定する

エンドポイント名は Azure リージョン レベルで一意である必要があります。 my-endpoint などのエンドポイント名は、指定したリージョン内でその名前を持つエンドポイントが 1 つだけとなるようにする必要があります。

以下のように値 endpt-rest にサフィックスとして乱数を追加する RANDOM ユーティリティを呼び出して一意のエンドポイント名を作成します。

export ENDPOINT_NAME=endpt-rest-`echo $RANDOM`

機械学習資産を作成する

デプロイの準備として、Azure Machine Learning 資産を設定し、ジョブを構成します。 モデル、コード、環境などのデプロイに必要な資産を登録します。

ヒント

以下の手順内の REST API 呼び出しでは、一部の引数のプレースホルダーとして、$SUBSCRIPTION_ID$RESOURCE_GROUP$LOCATION (リージョン)、および Azure Machine Learning $WORKSPACE を使用します。 デプロイ用のコードを実装する際には、引数のプレースホルダーを具体的なデプロイの値に置き換えます。

管理 REST により、サービス プリンシパル認証トークンが要求されます。 デプロイ用のコードを実装する際には、$TOKEN プレースホルダーのインスタンスをデプロイのサービス プリンシパル トークンに置き換えます。 このトークンは、次のコマンドを使用して取得できます。

response=$(curl -H "Content-Length: 0" --location --request POST "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/onlineEndpoints/$ENDPOINT_NAME/token?api-version=$API_VERSION" \
--header "Authorization: Bearer $TOKEN")
accessToken=$(echo $response | jq -r '.accessToken')

サービス プロバイダーは、api-version 引数を使用して互換性を保証します。 api-version 引数はサービスによって異なります。

将来のバージョンに対応するために、以下のように API_version 変数を設定します。

API_VERSION="2022-05-01"

ストレージ アカウントの詳細を取得する

モデルとコードを登録するには、まずそれらのアイテムを Azure Storage アカウントにアップロードする必要があります。 Azure Storage アカウントの詳細は、データ ストアから入手できます。 この例では、ワークスペースの既定のデータ ストアと Azure Storage アカウントを取得します。 GET 要求を使用して自分のワークスペースに対してクエリを実行し、情報が含まれた JSON ファイルを取得します。

jq ツールを使用することで、JSON の結果を解析して必要な値を取得できます。 Azure portal を使用しても同じ情報を取得することができます。

# Get values for storage account
response=$(curl --location --request GET "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/datastores?api-version=$API_VERSION&isDefault=true" \
--header "Authorization: Bearer $TOKEN")
AZUREML_DEFAULT_DATASTORE=$(echo $response | jq -r '.value[0].name')
AZUREML_DEFAULT_CONTAINER=$(echo $response | jq -r '.value[0].properties.containerName')
export AZURE_STORAGE_ACCOUNT=$(echo $response | jq -r '.value[0].properties.accountName')

コードをアップロードして登録する

データ ストアが用意できたので、スコアリング スクリプトをアップロードできるようになりました。 Azure Storage CLI を使用して、BLOB を既定のコンテナーにアップロードします。

az storage blob upload-batch -d $AZUREML_DEFAULT_CONTAINER/score -s endpoints/online/model-1/onlinescoring

ヒント

Azure portal や Azure Storage Explorer などの他の方法でアップロードを実行することもできます。

コードをアップロードしたら、以下のように PUT 要求でコードを指定し、datastoreId 識別子でデータ ストアを参照することができます。

curl --location --request PUT "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/codes/score-sklearn/versions/1?api-version=$API_VERSION" \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/json" \
--data-raw "{
  \"properties\": {
    \"codeUri\": \"https://$AZURE_STORAGE_ACCOUNT.blob.core.windows.net/$AZUREML_DEFAULT_CONTAINER/score\"
  }
}"

モデルをアップロードして登録する

以下のように同様の REST API 呼び出しを使用してモデル ファイルをアップロードします。

az storage blob upload-batch -d $AZUREML_DEFAULT_CONTAINER/model -s endpoints/online/model-1/model

アップロードが完了したら、以下のようにモデルを登録します。

curl --location --request PUT "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/models/sklearn/versions/1?api-version=$API_VERSION" \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/json" \
--data-raw "{
    \"properties\": {
        \"modelUri\":\"azureml://subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/workspaces/$WORKSPACE/datastores/$AZUREML_DEFAULT_DATASTORE/paths/model\"
    }
}"

環境を作成する

デプロイは、必要な依存関係がある環境で実行する必要があります。 PUT 要求を使用して環境を作成します。 Microsoft Container Registry の Docker イメージを使用します。 docker コマンドを使用して Docker イメージを構成し、condaFile コマンドを使用して conda の依存関係を追加できます。

次のコードは、Conda 環境の内容 (YAML ファイル) を環境変数に読み取ります。

ENV_VERSION=$RANDOM
curl --location --request PUT "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/environments/sklearn-env/versions/$ENV_VERSION?api-version=$API_VERSION" \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/json" \
--data-raw "{
    \"properties\":{
        \"condaFile\": \"$CONDA_FILE\",
        \"image\": \"mcr.microsoft.com/azureml/openmpi3.1.2-ubuntu18.04:20210727.v1\"
    }
}"

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

オンライン エンドポイントを作成します。

response=$(curl --location --request PUT "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/onlineEndpoints/$ENDPOINT_NAME?api-version=$API_VERSION" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $TOKEN" \
--data-raw "{
    \"identity\": {
       \"type\": \"systemAssigned\"
    },
    \"properties\": {
        \"authMode\": \"AMLToken\"
    },
    \"location\": \"$LOCATION\"
}")

Create deployment

エンドポイントでデプロイを作成します。

response=$(curl --location --request PUT "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/onlineEndpoints/$ENDPOINT_NAME/deployments/blue?api-version=$API_VERSION" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $TOKEN" \
--data-raw "{
    \"location\": \"$LOCATION\",
    \"sku\": {
        \"capacity\": 1,
        \"name\": \"Standard_DS2_v2\"
    },
    \"properties\": {
        \"endpointComputeType\": \"Managed\",
        \"scaleSettings\": {
            \"scaleType\": \"Default\"
        },
        \"model\": \"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/models/sklearn/versions/1\",
        \"codeConfiguration\": {
            \"codeId\": \"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/codes/score-sklearn/versions/1\",
            \"scoringScript\": \"score.py\"
        },
        \"environmentId\": \"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/environments/sklearn-env/versions/$ENV_VERSION\"
    }
}")

エンドポイントを呼び出してモデルでデータをスコア付けする

デプロイ エンドポイントを呼び出すには、スコアリング URI とアクセス トークンが必要です。

まずは、以下のようにスコアリング URI を取得します。

response=$(curl --location --request GET "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/onlineEndpoints/$ENDPOINT_NAME?api-version=$API_VERSION" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $TOKEN")

scoringUri=$(echo $response | jq -r '.properties.scoringUri')

次に、以下のようにエンドポイント アクセス トークンを取得します。

response=$(curl -H "Content-Length: 0" --location --request POST "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/onlineEndpoints/$ENDPOINT_NAME/token?api-version=$API_VERSION" \
--header "Authorization: Bearer $TOKEN")
accessToken=$(echo $response | jq -r '.accessToken')

最後に、以下のように curl ユーティリティを使用してエンドポイントを呼び出します。

curl --location --request POST $scoringUri \
--header "Authorization: Bearer $accessToken" \
--header "Content-Type: application/json" \
--data-raw @endpoints/online/model-1/sample-request.json

デプロイ ログを確認する

デプロイ ログを確認します。

curl --location --request POST "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/onlineEndpoints/$ENDPOINT_NAME/deployments/blue/getLogs?api-version=$API_VERSION" \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/json" \
--data-raw "{ \"tail\": 100 }"

エンドポイントを削除する

これ以上デプロイを使用する予定がない場合は、リソースを削除します。

エンドポイントと根底にあるすべてのデプロイを削除する次のコマンドを実行します。

curl --location --request DELETE "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.MachineLearningServices/workspaces/$WORKSPACE/onlineEndpoints/$ENDPOINT_NAME?api-version=$API_VERSION" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $TOKEN" || true