適用対象:Azure Machine Learning SDK v1 for Python
重要
この記事では、Azure Machine Learning SDK v1 の使用に関する情報を提供します。 SDK v1 は 2025 年 3 月 31 日の時点で非推奨となり、サポートは 2026 年 6 月 30 日に終了します。 SDK v1 は、その日付までインストールして使用できます。
2026 年 6 月 30 日より前に SDK v2 に移行することをお勧めします。 SDK v2 の詳細については、「 Azure Machine Learning Python SDK v2 と SDK v2 リファレンスとは」を参照してください。
この記事では、Azure Machine Learning で特殊なユース ケースのエントリ スクリプトを記述する方法について説明します。 エントリ スクリプトは、スコアリング スクリプトとも呼ばれ、要求を受け入れ、モデルを使用してデータをスコア付けし、応答を返します。
前提条件
Azure Machine Learning を使用してデプロイするトレーニング済みの機械学習モデル。 モデルのデプロイの詳細については、「 機械学習モデルを Azure にデプロイする」を参照してください。
Swagger スキーマを自動生成する
Web サービスのスキーマを自動的に生成するには、定義されている型オブジェクトの 1 つについて、コンストラクター内の入力または出力のサンプルを提供します。 型とサンプルはスキーマを自動作成するために使用されます。 Azure Machine Learning では、デプロイ時に Web サービス用の OpenAPI 仕様 (以前は Swagger 仕様) が作成されます。
警告
サンプルの入力または出力に機密データやプライベート データを使用しないでください。 Azure Machine Learning では、推論用の Swagger ページでサンプル データが公開されます。
現在、次の種類がサポートされています。
pandas
numpy
pyspark
- 標準的な Python オブジェクト
スキーマ生成を使用するには、依存関係ファイルにオープンソース inference-schema
パッケージ バージョン 1.1.0 以降を含めます。 このパッケージの詳細については、 GitHub の InferenceSchema を参照してください。 Web サービスの自動使用に対応する Swagger を生成するには、スコアリング スクリプトの run
関数が次の条件を満たしている必要があります。
- 最初のパラメーターには、型
StandardPythonParameterType
、Inputs
という名前を付け、入れ子にする必要があります。 StandardPythonParameterType
という名前の型GlobalParameters
のオプションの 2 番目のパラメーターが必要です。- この関数は、
StandardPythonParameterType
という名前で入れ子になっているResults
型のディクショナリを返す必要があります。
変数 sample_input
と sample_output
で入力と出力のサンプル形式を定義します。これは Web サービスの要求と応答の形式を表します。 これらのサンプルを、run
関数の入力と出力の関数デコレーターで使用します。 次のセクションの scikit-learn
例では、スキーマの生成を使用します。
Power BI と互換性のあるエンドポイント
次の例では、前のセクションの手順に従って run
関数を定義する方法を示します。 このスクリプトは、Power BI からデプロイされた Web サービスを使用するときに使用できます。
import os
import json
import pickle
import numpy as np
import pandas as pd
import azureml.train.automl
import joblib
from sklearn.linear_model import Ridge
from inference_schema.schema_decorators import input_schema, output_schema
from inference_schema.parameter_types.standard_py_parameter_type import StandardPythonParameterType
from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType
from inference_schema.parameter_types.pandas_parameter_type import PandasParameterType
def init():
global model
# Replace the file name if needed.
model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')
# Deserialize the model file back into a sklearn model.
model = joblib.load(model_path)
# Provide three sample inputs for schema generation.
numpy_sample_input = NumpyParameterType(np.array([[1,2,3,4,5,6,7,8,9,10],[10,9,8,7,6,5,4,3,2,1]],dtype='float64'))
pandas_sample_input = PandasParameterType(pd.DataFrame({'name': ['Sarah', 'John'], 'age': [25, 26]}))
standard_sample_input = StandardPythonParameterType(0.0)
# The following sample is a nested input sample. Any item wrapped by `ParameterType` is described by the schema.
sample_input = StandardPythonParameterType({'input1': numpy_sample_input,
'input2': pandas_sample_input,
'input3': standard_sample_input})
sample_global_parameters = StandardPythonParameterType(1.0) # This line is optional.
sample_output = StandardPythonParameterType([1.0, 1.0])
outputs = StandardPythonParameterType({'Results':sample_output}) # "Results" is case sensitive.
@input_schema('Inputs', sample_input)
# "Inputs" is case sensitive.
@input_schema('GlobalParameters', sample_global_parameters)
# The preceding line is optional. "GlobalParameters" is case sensitive.
@output_schema(outputs)
def run(Inputs, GlobalParameters):
# The parameters in the preceding line have to match those in the decorator. "Inputs" and
# "GlobalParameters" are case sensitive.
try:
data = Inputs['input1']
# The data gets converted to the target format.
assert isinstance(data, np.ndarray)
result = model.predict(data)
return result.tolist()
except Exception as e:
error = str(e)
return error
ヒント
スクリプトからの戻り値には、JSON にシリアル化できる任意の Python オブジェクトを指定できます。 たとえば、モデルが複数の列を含む Pandas データフレームを返す場合は、次のコードのような出力デコレーターを使用できます。
output_sample = pd.DataFrame(data=[{"a1": 5, "a2": 6}])
@output_schema(PandasParameterType(output_sample))
...
result = model.predict(data)
return result
バイナリ (画像) データ
モデルがイメージなどのバイナリ データを受け入れる場合は、未加工の HTTP 要求を受け入れるように、デプロイで使用される score.py ファイルを変更する必要があります。 生データを受け入れるには、エントリ スクリプトで AMLRequest
クラスを使用して、@rawhttp
デコレーターを run
関数に追加します。
次の score.py スクリプトはバイナリ データを受け入れます。
from azureml.contrib.services.aml_request import AMLRequest, rawhttp
from azureml.contrib.services.aml_response import AMLResponse
from PIL import Image
import json
def init():
print("This is init()")
@rawhttp
def run(request):
print("This is run()")
if request.method == 'GET':
# For this example, return the URL for GET requests.
respBody = str.encode(request.full_path)
return AMLResponse(respBody, 200)
elif request.method == 'POST':
file_bytes = request.files["image"]
image = Image.open(file_bytes).convert('RGB')
# For a real-world solution, load the data from the request body
# and send it to the model. Then return the response.
# For demonstration purposes, this example returns the size of the image as the response.
return AMLResponse(json.dumps(image.size), 200)
else:
return AMLResponse("bad request", 500)
重要
AMLRequest
クラスは azureml.contrib
名前空間にあります。 この名前空間のエンティティはプレビュー段階です。 サービスが改善されている間は頻繁に変更されます。 Microsoft では、これらのエンティティの完全なサポートを提供していません。
ローカル開発環境でこのクラスを使用するコードをテストする必要がある場合は、次のコマンドを使用してコンポーネントをインストールできます。
pip install azureml-contrib-services
注意
カスタム状態コードとして 500
を使用することはお勧めしません。 Azure Machine Learning 推論ルーター (azureml-fe
) 側では、状態コードが 502
に書き換えられます。
- 状態コードは、
azureml-fe
経由で渡され、クライアントに送信されます。 azureml-fe
コードは、モデル側から返された500
を502
として書き換える。 クライアントは、502
のコードを受け取ります。azureml-fe
コード自体が500
を返す場合、クライアント側は引き続き500
のコードを受け取ります。
AMLRequest
クラスを使用すると、score.py ファイル内の未加工の転記済みデータにのみアクセスできます。 クライアント側コンポーネントはありません。 クライアントから、通常どおりデータを投稿できます。 たとえば、次の Python コードは、画像ファイルを読み取ってデータを送信します。
import requests
uri = service.scoring_uri
image_path = 'test.jpg'
files = {'image': open(image_path, 'rb').read()}
response = requests.post(uri, files=files)
print(response.json)
クロスオリジン リソース共有
クロスオリジン リソース共有 (CORS) は、Web ページ上のリソースを別のドメインから要求する方法を提供します。 CORS は、クライアント要求と共に送信され、サービス応答で返される HTTP ヘッダーを介して機能します。 CORS と有効なヘッダーの詳細については、「 クロスオリジン リソース共有」を参照してください。
CORS をサポートするようにモデル デプロイを構成するには、エントリ スクリプトで AMLResponse
クラスを使用します。 このクラスを使用する場合は、応答オブジェクトにヘッダーを設定できます。
次の例では、エントリ スクリプトから応答に対して Access-Control-Allow-Origin
ヘッダーを設定しています。
from azureml.contrib.services.aml_request import AMLRequest, rawhttp
from azureml.contrib.services.aml_response import AMLResponse
def init():
print("This is init()")
@rawhttp
def run(request):
print("This is run()")
print("Request: [{0}]".format(request))
if request.method == 'GET':
# For this example, just return the URL for GET.
# For a real-world solution, you would load the data from URL params or headers
# and send it to the model. Then return the response.
respBody = str.encode(request.full_path)
resp = AMLResponse(respBody, 200)
resp.headers["Allow"] = "OPTIONS, GET, POST"
resp.headers["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST"
resp.headers['Access-Control-Allow-Origin'] = "http://www.example.com"
resp.headers['Access-Control-Allow-Headers'] = "*"
return resp
elif request.method == 'POST':
reqBody = request.get_data(False)
# For a real-world solution, you would load the data from reqBody
# and send it to the model. Then return the response.
resp = AMLResponse(reqBody, 200)
resp.headers["Allow"] = "OPTIONS, GET, POST"
resp.headers["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST"
resp.headers['Access-Control-Allow-Origin'] = "http://www.example.com"
resp.headers['Access-Control-Allow-Headers'] = "*"
return resp
elif request.method == 'OPTIONS':
resp = AMLResponse("", 200)
resp.headers["Allow"] = "OPTIONS, GET, POST"
resp.headers["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST"
resp.headers['Access-Control-Allow-Origin'] = "http://www.example.com"
resp.headers['Access-Control-Allow-Headers'] = "*"
return resp
else:
return AMLResponse("bad request", 400)
重要
AMLRequest
クラスは azureml.contrib
名前空間にあります。 この名前空間のエンティティはプレビュー段階です。 サービスが改善されている間は頻繁に変更されます。 Microsoft では、これらのエンティティの完全なサポートを提供していません。
ローカル開発環境でこのクラスを使用するコードをテストする必要がある場合は、次のコマンドを使用してコンポーネントをインストールできます。
pip install azureml-contrib-services
警告
Azure Machine Learning では、スコアリング サービスを実行するコンテナーに POST 要求と GET 要求のみがルーティングされます。 ブラウザーが OPTIONS 要求を使用してプレフライト要求を発行すると、エラーが発生する可能性があります。
登録されているモデルを読み込む
エントリ スクリプトでモデルを見つける、次の 2 つの方法があります。
AZUREML_MODEL_DIR
: モデルの場所へのパスを含む環境変数Model.get_model_path
: 登録済みのモデル名を使用してモデル ファイルへのパスを返す API
AZUREML_MODEL_DIR
AZUREML_MODEL_DIR
は、サービスのデプロイ時に作成される環境変数です。 この環境変数を使用して、デプロイされたモデルの場所を見つけることができます。
次の表では、さまざまな数のデプロイ 済みモデルに対する AZUREML_MODEL_DIR
の使用可能な値について説明します。
デプロイ | 環境変数の値 |
---|---|
単一モデル | モデルを含むフォルダーへのパス。 |
複数モデル | すべてのモデルを含むフォルダーへのパス。 モデルは、このフォルダー内の名前とバージョンによって <model-name>/<version> 形式で配置されます。 |
モデルの登録とデプロイ中、モデルは AZUREML_MODEL_DIR
パスに配置され、元のファイル名は保持されます。
エントリ スクリプトでモデル ファイルへのパスを取得するには、環境変数と探しているファイル名を組み合わせます。
単一モデル
次の例は、単一のモデルがある場合にパスを検索する方法を示しています。
import os
# In the following example, the model is a file.
model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')
# In the following example, the model is a folder that contains a file.
file_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'my_model_folder', 'sklearn_regression_model.pkl')
複数モデル
次の例は、複数のモデルがある場合にパスを検索する方法を示しています。 このシナリオでは、2 つのモデルがワークスペースに登録されています。
my_first_model
: このモデルには 1 つのファイル my_first_model.pkl が含まれており、1 つのバージョン1
。my_second_model
: このモデルには 1 つのファイル my_second_model.pkl が含まれており、1
と2
の 2 つのバージョンがあります。
サービスをデプロイするときは、デプロイ操作で両方のモデルを指定します。
from azureml.core import Workspace, Model
# Get a handle to the workspace.
ws = Workspace.from_config()
first_model = Model(ws, name="my_first_model", version=1)
second_model = Model(ws, name="my_second_model", version=2)
service = Model.deploy(ws, "myservice", [first_model, second_model], inference_config, deployment_config)
サービスをホストする Docker イメージの AZUREML_MODEL_DIR
環境変数には、モデルが配置されているフォルダーが含まれています。 このフォルダーでは、各モデルは <model-name>/<version>
のフォルダー パスにあります。 このパスでは、 <model-name>
は登録済みモデルの名前であり、 <version>
はモデルのバージョンです。 登録されたモデルを構成するファイルは、これらのフォルダーに格納されます。
この例では、最初のモデルのパスは $AZUREML_MODEL_DIR/my_first_model/1/my_first_model.pkl
。 2 番目のモデルのパスは $AZUREML_MODEL_DIR/my_second_model/2/my_second_model.pkl
。
# In the following example, the model is a file, and the deployment contains multiple models.
first_model_name = 'my_first_model'
first_model_version = '1'
first_model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), first_model_name, first_model_version, 'my_first_model.pkl')
second_model_name = 'my_second_model'
second_model_version = '2'
second_model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), second_model_name, second_model_version, 'my_second_model.pkl')
モデルのパスを取得する
モデルを登録するときに、レジストリ内のモデルを管理するために使用されるモデル名を指定します。 この名前を Model.get_model_path
メソッドと共に使用して、ローカル ファイル システム上のモデル ファイルまたはファイルのパスを取得します。 フォルダーまたはファイルのコレクションを登録すると、この API はそれらのファイルを含むフォルダーのパスを返します。
モデルを登録するときに名前を指定します。 この名前は、ローカル環境で、またはサービスのデプロイ時に、モデルが配置される場所に対応します。
フレームワーク固有の例
特定の機械学習のユース ケースのエントリ スクリプトの例については、次の記事を参照してください。