はじめに
今回はAzure Auto MLで作成したモデルをPythonからデプロイ・推論まで行ってみます。
開発環境
- OS Windows 10(NVIDIA GTX 1650Ti,16GB RAM, i5-10300H CPU)
- Visual Studio Code 1.73.1
- Python 3.7
モデルのデプロイ・推論を行う
前回作成したトレーニング済みのモデルをデプロイしていきます。
(Pythonからトレーニングさせる方法についてはこちらを参照ください。)
モデルの登録
1 2 3 4 5 6 7 8 9 10 11 12 13 |
register_model.py from azureml.core.experiment import Experiment from azureml.core import Workspace from azureml.train.automl.run import AutoMLRun ws = Workspace.from_config() experiment = ws.experiments["t-kawano-1207"]#実験名 automl_run = AutoMLRun(experiment, run_id='AutoML_XXX')#実行ID best_run = automl_run.get_best_child() model = automl_run.register_model(model_name="trainmodel")#モデル名 |
まずはワークスペースへの接続を行い、登録するモデルがある実験の内容を取得します。
実行IDは、Pythonからトレーニングする際に
1 2 3 |
run = experiment.submit(automl_classifier) print(run) |
runを表示するようにしたらこちらの「AutoML_XXX」の部分から取得できます。
1 2 3 4 5 6 |
Submitting remote run. Run(Experiment: t-kawano-1207, Id: AutoML_XXX, Type: automl, Status: NotStarted) |
もしくは完了したジョブの「名前」のところから実行IDを取得することもできます。
そしてget_best_child()
メソッドによって、作成されたモデルの中で最も良いスコアを持つモデルを選択。これをregister_model()
で名前を決め、モデルを登録します。
実行後、ワークスペースに戻って「モデル」タグから一覧を確認すると
「trainmodel」という名前のモデルが登録されているのを確認できました。
登録したモデルをデプロイする
1 2 3 4 5 6 7 8 9 10 11 |
deploy_model.py from azureml.core import Workspace from azureml.core.model import InferenceConfig from azureml.core.webservice.aci import AciWebservice from azureml.core.model import Model ws = Workspace.from_config() model = ws.models["trainmodel"]#モデル名 inference_config = InferenceConfig(entry_script="score.py")#エントリスクリプトを入力 deployment_config = AciWebservice.deploy_configuration(cpu_cores = 1, memory_gb = 1) service = Model.deploy(ws, "t-kawano-test", [model], inference_config, deployment_config)#サービス名を入力 |
デプロイするモデル名を入れ、エントリスクリプトのファイル名を入力します。
そして作成するWebサービスエンドポイントに割り当てるCPUのコア数とメモリ量を指定し、サービス名を入力します。
これを実行すると、デプロイができます。
また、エントリスクリプトの中身はこちらです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
score.py import pandas as pd import json from azureml.core.model import Model import joblib import io def init(): global model model_path = Model.get_model_path('trainmodel') model = joblib.load(model_path) def run(raw_data): df = pd.read_csv(io.StringIO(json.loads(raw_data)['data'])) predictions = model.predict(df) df["Class"] = predictions return df.to_csv(index=False) |
init
で登録したモデルのロードを行い、run
で推論を行うという構成です。
APIからCSV形式のデータが入力されるので、これをpandasで読み込みます。
その後、model.predict
で推論を行い、この結果を’Class’列に追加し、CSV形式で出力するという流れです。
大体10分ほどでエンドポイントが作成されました!
デプロイ状態も「Healthy」となっており、エンドポイントを使用できる状態になっています。
デプロイしたモデルを使う
1 2 3 4 5 6 7 8 9 10 11 12 13 |
use_model.py import json import pandas as pd import requests df = pd.read_csv("creditcard_NoClass.csv") data = { "data": df.to_csv(index=False) } body = str.encode(json.dumps(data)) print(body) url = 'http://XXX' headers = {'Content-Type':'application/json'} response = requests.post(url, data=body, headers=headers) print(response.text) |
作成したエンドポイントから「RESTエンドポイント」と書かれたところにURLがあります。
creditcard.csvのClass
列を削除したデータでテストを行ってみます。
1 2 |
413 Request Entity Too Large |
実行途中、status code 413のこちらのエラーが出ました。
これは送ったファイルのデータ量が多いときに出るエラーみたいです。
そのため、このように
テストデータは1行のみで推論することにしました。
入力したテストデータはpandasを用いて読み込み、辞書型にした後JSON形式に成型して使うようにしました。
こちらが入力データです。
1 2 |
b'{"data": "Time,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,V20,V21,V22,V23,V24,V25,V26,V27,V28,Amount\\r\\n0,-1.359807134,-0.072781173,2.536346738,1.3781552240000001,-0.33832077,0.46238777799999997,0.239598554,0.09869790099999999,0.36378697,0.09079417199999999,-0.551599533,-0.617800856,-0.991389847,-0.311169354,1.468176972,-0.470400525,0.207971242,0.02579058,0.40399296,0.25141209800000003,-0.018306778,0.27783757600000003,-0.11047391,0.066928075,0.12853935800000002,-0.18911484399999998,0.133558377,-0.021053053,149.62\\r\\n"}' |
あとはPOSTメソッドを使って実行してみます。
1 2 |
"Time,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,V20,V21,V22,V23,V24,V25,V26,V27,V28,Amount,Class\n0.0,-1.3598071,-0.072781175,2.5363467,1.3781552,-0.33832076,0.46238777,0.23959856,0.0986979,0.36378697,0.09079417,-0.55159956,-0.61780083,-0.9913899,-0.31116936,1.468177,-0.4704005,0.20797125,0.02579058,0.40399295,0.2514121,-0.018306779,0.27783757,-0.11047391,0.066928074,0.12853935,-0.18911484,0.13355838,-0.021053053,149.62,False\n" |
実行後、結果はエントリスクリプトで指定したようにCSV形式で返ってきました。