搞了半天,終於有了一個堪用的模型,現在我們要來部署了。一開始部署,我也是吃足了苦頭,原因是沒有考慮清楚環境的設定,也沒有考慮清楚要怎麼跟服務互動,後來搞清楚狀況後,就顯得相當簡單了。最先該做的事情,就是直接使用原本準備好的環境,就87%沒有問題了。
部署服務時,一樣需要兩份 py 檔
workspace
利用運算群組執行predict_currency.py
deploy_currency_prediction.py
,在本機執行,將預測的服務部署在workspace
使用服務,也就是標題上所寫的 inference,這個詞直接查字典的話,意思是推論或推斷,可以想做,我們利用過去蒐集到的資料做成一個模型之後,利用此模型推論未來的情境。白話一點,其實就是把做好的模型拿來使用。服務部署完成後,會產生該服務的 API ,便可以透過 API 使用預測服務了。
init
:讀取模型。run
:當使用者呼叫 API 時,執行預測,並回傳結果。predict_currency.py
import os
from datetime import datetime, timedelta
import pickle
from keras.models import load_model
import investpy
def init():
"""
Load the model
"""
global model
global scaler
# 模型的預設路徑就是 /var/azureml-app/azureml-models/,從中找到相對應的模型
for root, _, files in os.walk("/var/azureml-app/azureml-models/", topdown=False):
for name in files:
if name.split(".")[-1] == "h5":
model_path = os.path.join(root, name)
elif name.split(".")[-1] == "pickle":
scaler_path = os.path.join(root, name)
model = load_model(model_path)
with open(scaler_path, "rb") as f_h:
scaler = pickle.load(f_h)
f_h.close()
# 這邊的 raw_data 並沒有被使用到,因為資料可以直接透過 investpy 取得。
# 但因為直接省略 raw_data ,是無法部署的,所以只好保留。
def run(raw_data):
"""
Prediction
"""
today = datetime.now()
data = investpy.get_currency_cross_historical_data(
"USD/TWD",
from_date=(today - timedelta(weeks=105)).strftime("%d/%m/%Y"),
to_date=today.strftime("%d/%m/%Y"),
)
data.reset_index(inplace=True)
data = data.tail(240).Close.values.reshape(-1, 1)
data = scaler.transform(data)
data = data.reshape((1, 240, 1))
ans = model.predict(data)
ans = scaler.inverse_transform(ans)
# 要注意回傳的數值必須要是 JSON 支援的資料格式
return float(ans[0][0])
predict_currency.py
才找得到相對應的模型。deploy_currency_prediction.py
import os
import numpy as np
from azureml.core import Model, Workspace
from azureml.core import Run
from azureml.core.model import InferenceConfig
from azureml.core.webservice import AciWebservice
from azureml.core.authentication import InteractiveLoginAuthentication
def main():
"""
Deploy model to your service
"""
# 為了之後 pipeline 的使用,所以使用兩種方式取得 workspace。
run = Run.get_context()
try:
work_space = run.experiment.workspace
except AttributeError:
interactive_auth = InteractiveLoginAuthentication(
tenant_id=os.getenv("TENANT_ID")
)
work_space = Workspace.from_config(auth=interactive_auth)
# 選擇之前已經建立好的環境
environment = work_space.environments["train_lstm"]
# 選擇模型,如果不挑選版本,則會直接挑選最新模型
model = Model(work_space, "currency")
# scaler 也是會用到
scaler = Model(work_space, name="scaler", version=1)
# 設定部署服務的 config
service_name = "currency-service"
inference_config = InferenceConfig(
entry_script="predict_currency.py", environment=environment
)
# 設定執行服務的資源
aci_config = AciWebservice.deploy_configuration(cpu_cores=1, memory_gb=1)
# 部署服務
service = Model.deploy(
workspace=work_space,
name=service_name,
models=[model, scaler],
inference_config=inference_config,
deployment_config=aci_config,
overwrite=True,
)
service.wait_for_deployment(show_output=True)
print(service.get_logs())
# 印出服務連結,之後就是利用這個連結提供服務
print(service.scoring_uri)
if __name__ == "__main__":
main()
workspace
的端點,檢視服務的相關資訊。POST
使用。predict_currency_azml.py
import argparse
import json
import requests
def parse_args():
"""
Parse arguments
"""
parser = argparse.ArgumentParser()
# endpoint url 就是 API 的連結
parser.add_argument("-e", "--endpoint_url", type=str, help="Endpoint url")
args = parser.parse_args()
return args
def main():
"""
Predict mnist data with Azure machine learning
"""
args = parse_args()
data = {"data": ""}
# 將資料轉換成 JSON
input_data = json.dumps(data)
# Set the content type
headers = {"Content-Type": "application/json"}
# 使用 POST 呼叫 API
resp = requests.post(args.endpoint_url, input_data, headers=headers)
print("The answer is {}".format(resp.text))
if __name__ == "__main__":
main()
python3.7 predict_currency_azml.py -e 你的 API 連結
,就會得到預測結果了。做到這一步,算是完整的走一遍,利用 Azure machine learning 訓練模型與部屬服務的流程了,但實際應用上,可能還要考慮日後更新資料和模型的問題,這就會需要用到pipeline
和sechedule
的概念。下一篇,先從pipeline
開始。