搞了半天,終於有了一個堪用的模型,現在我們要來部署了。一開始部署,我也是吃足了苦頭,原因是沒有考慮清楚環境的設定,也沒有考慮清楚要怎麼跟服務互動,後來搞清楚狀況後,就顯得相當簡單了。最先該做的事情,就是直接使用原本準備好的環境,就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開始。