在批次部署中部署 MLflow 模型

適用於:Azure CLI ml 延伸模組 v2 (目前)Python SDK azure-ai-ml v2 (目前)

在本文中,了解如何使用批次端點,將 MLflow 模型部署至 Azure Machine Learning 以用於批次推斷。 將 MLflow 模型部署至批次端點時,Azure Machine Learning:

  • 提供 MLflow 基底映像/策展環境,其中包含執行 Azure Machine Learning 批次工作所需的相依性。
  • 使用評分指令碼為您建立批次工作管線,以使用平行處理來處理資料。

注意

如需所支援輸入檔類型的詳細資訊,以及 MLflow 模型如何運作方式的詳細資料,請參閱部署至批次推斷時的考量

關於此範例

此範例示範如何將 MLflow 模型部署到批次端點,以執行批次預測。 此範例使用以 UCI 心臟疾病資料集為基礎的 MLflow 模型。 資料庫包含76個屬性,但我們使用其中14個的子集。 此模型會嘗試預測病患是否有心臟疾病。 值為 0 (沒有) 到 1 (有) 的整數值。

模型已使用 XGBBoost 分類器進行訓練,而且所有必要的前置處理都已封裝為 scikit-learn 管線,讓此模型成為從原始資料到預測的端對端管線。

本文中的範例是以 azureml-examples 存放庫中包含的程式碼範例為基礎。 若要在本機執行命令,而不需要複製/貼上 YAML 和其他檔案,請複製存放庫,然後將目錄變更為該資料夾:

git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli

此範例的檔案位於:

cd endpoints/batch/deploy-models/heart-classifier-mlflow

在 Jupyter Notebook 中跟著做

您可以在下列筆記本中遵循此範例。 在複製的存放庫中,開啟筆記本:mlflow-for-batch-tabular.ipynb

必要條件

遵循本文中的步驟之前,請確定您已滿足下列必要條件:

  • Azure 訂用帳戶。 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。 試用免費或付費版本的 Azure Machine Learning

  • Azure Machine Learning 工作區。 如果您沒有帳戶,請使用管理 Azure 機器學習 工作區一文中的步驟來建立一個工作區。

  • 請確定您在工作區中具有下列權限:

    • 建立或管理批次端點和部署:使用允許 Microsoft.MachineLearningServices/workspaces/batchEndpoints/*的擁有者、參與者或自定義角色。

    • 在工作區資源群組中建立ARM部署:使用可在部署工作區的資源群組中使用擁有 Microsoft.Resources/deployments/write 者、參與者或自定義角色。

  • 您必須安裝下列軟體,才能使用 Azure 機器學習:

    Azure CLI適用於 Azure Machine Learningml 擴充功能。

    az extension add -n ml
    

    注意

    批次端點的管線元件部署是在 Azure CLI 的 ml 擴充功能 2.7 版中引進。 使用 az extension update --name ml 來取得其最後一個版本。

連線到您的工作區

工作區是 Azure Machine Learning 的最上層資源,其提供一個集中位置來處理您在使用 Azure Machine Learning 時建立的所有成品。 在本節中,我們將連線到您將執行部署工作的工作區。

在下列程式碼中傳入訂用帳戶識別碼、工作區、位置和資源群組的值:

az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>

步驟

請遵循下列步驟,將 MLflow 模型部署至批次端點,以針對新資料執行批次推斷:

  1. 批次端點只能部署已註冊的模型。 在此案例中,存放庫中已具有模型的本機複本,因此我們只需要將模型發佈至工作區中的登錄。 如果您已註冊您嘗試部署的模型,則可以略過此步驟。

    MODEL_NAME='heart-classifier-mlflow'
    az ml model create --name $MODEL_NAME --type "mlflow_model" --path "model"
    
  2. 在向前邁進之前,我們需要確定即將建立的批次部署可以在某些基礎結構上執行(計算)。 批次部署可以在工作區中現有的任何 Azure Machine Learning 計算上執行。 這表示多個批次部署可以共用相同的計算基礎結構。 在此範例中,我們將處理名為 cpu-cluster的 Azure 機器學習 計算叢集。 我們須確認計算存在於工作區上,否則要另外建立。

    建立計算叢集,如下所示:

    az ml compute create -n batch-cluster --type amlcompute --min-instances 0 --max-instances 5
    
  3. 現在是時候建立批次端點和部署了。 讓我們先從端點開始。 端點只需要建立名稱和描述。 端點的名稱最後將會出現在與您的端點相關聯的 URI 中。 因此,批次端點名稱在 Azure 區域內必須是唯一的。 例如,westus2 中只能有一個名稱為 mybatchendpoint 的批次端點。

    在此情況下,讓我們將端點的名稱放在變數中,方便稍後參考。

    ENDPOINT_NAME="heart-classifier"
    
  4. 建立端點:

    若要建立新的端點,請建立如下的 YAML 設定:

    endpoint.yml

    $schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json
    name: heart-classifier-batch
    description: A heart condition classifier for batch inference
    auth_mode: aad_token
    

    然後,使用下列命令建立端點:

    az ml batch-endpoint create -n $ENDPOINT_NAME -f endpoint.yml
    
  5. 現在,我們來建立部署。 MLflow 模型不需要您在建立部署時指示環境或評分指令碼,因為會自行為您建立。 不過,如果您想要自訂部署的推斷方式,則可以指定。

    若要在已建立的端點下建立新部署,請建立 YAML 設定,如下所示。 您可以檢查完整的批次端點 YAML 結構描述,以取得額外的屬性。

    deployment-simple/deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: heart-classifier-batch
    name: classifier-xgboost-mlflow
    description: A heart condition classifier based on XGBoost
    type: model
    model: azureml:heart-classifier-mlflow@latest
    compute: azureml:batch-cluster
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 2
      mini_batch_size: 2
      output_action: append_row
      output_file_name: predictions.csv
      retry_settings:
        max_retries: 3
        timeout: 300
      error_threshold: -1
      logging_level: info
    

    接著,使用下列命令建立部署:

    az ml batch-deployment create --file deployment-simple/deployment.yml --endpoint-name $ENDPOINT_NAME --set-default
    

    重要

    根據您的模型在單一批次上執行推斷所需的時間,在部署中設定 timeout。 批次大小越大,這個值必須越長。 請記得,mini_batch_size 會指出批次中的檔案數目,而不是樣本數目。 使用表格式資料時,每個檔案可能包含多個資料列,這會增加批次端點處理每個檔案所需的時間。 在這些情況下使用較高的值,以避免逾時錯誤。

  6. 雖然您可以在端點內叫用特定部署,但是您通常會想要叫用端點本身,讓端點決定要使用的部署。 這類部署名為「預設」部署。 這可讓您變更預設部署,進而變更提供部署的模型,而不需變更與端點叫用者之間的合約。 使用下列指示來更新預設部署:

    DEPLOYMENT_NAME="classifier-xgboost-mlflow"
    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  7. 此時,我們的批次端點已可供使用。

測試部署

為了測試端點,我們將使用位於此存放庫中且可與模型搭配使用的未標記數據的範例。 批次端點只能處理位於雲端且可從 Azure Machine Learning 工作區存取的資料。 在此範例中,我們將將其上傳至 Azure 機器學習 資料存放區。 特別是,我們將建立可用來叫用端點進行評分的數據資產。 不過,請注意,批次端點可接受可放置在各種位置類型的資料。

  1. 讓我們先建立資料資產。 此資料資產包含一個具有多個 CSV 檔案的資料夾,我們想要使用批次端點進行平行處理。 如果您的資料已註冊為資料資產,或您想要使用不同的輸入類型,您可以略過此步驟。

    a. 在 YAML 中建立資料資產定義:

    heart-dataset-unlabeled.yml

    $schema: https://azuremlschemas.azureedge.net/latest/data.schema.json
    name: heart-dataset-unlabeled
    description: An unlabeled dataset for heart classification.
    type: uri_folder
    path: data
    

    b. 建立資料資產:

    az ml data create -f heart-dataset-unlabeled.yml
    
  2. 現在資料已上傳並可供使用,讓我們來叫用端點:

    JOB_NAME = $(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input azureml:heart-dataset-unlabeled@latest --query name -o tsv)
    

    注意

    公用程式 jq 可能不會在每次安裝時進行安裝。 您可以在此連結中取得安裝指示。

    提示

    請注意,我們不會在叫用作業中指出部署名稱。 這是因為端點會自動將工作路由至預設部署。 因為我們的端點只有一個部署,所以該部署就是預設部署。 您可以指示引數/參數 deployment_name,以特定部署為目標。

  3. 命令傳回時,就會立即啟動批次工作。 您可以監視工作的狀態,直到工作完成為止:

    az ml job show -n $JOB_NAME --web
    

分析輸出

輸出預測會在 predictions.csv 檔案中產生,如部署設定中所述。 此工作會產生名為 score 的具名輸出,而此檔案會放置於其中。 每個批次作業只會產生一個檔案。

該檔案的結構如下:

  • 每個傳送至模型的資料點各有一個資料列。 對於表格式數據,這表示檔案 (predictions.csv) 會針對每個已處理檔案中的每個數據列包含一個數據列。 對於其他數據類型(例如影像、音訊、文字),每個處理過的檔案各有一個數據列。

  • 下列資料列位於 檔案中(依序):

    • row (選擇性),輸入數據文件中對應的數據列索引。 這隻適用於輸入數據為表格式時。 預測會以輸入檔中顯示的相同順序傳回,因此您可以依賴數據列編號來比對對應的預測。
    • prediction,與輸入數據相關聯的預測。 此值會依模型 predict(). 函式提供的「原樣」傳回。
    • file_name,這是從中讀取數據的檔名。 在表格式資料中,使用此欄位來了解哪些預測屬於哪個輸入資料。

您可以使用工作名稱來下載工作的結果:

若要下載預測,請使用下列命令:

az ml job download --name $JOB_NAME --output-name score --download-path ./

下載檔案之後,您可以使用慣用的工具來開啟。 下列範例會使用 Pandas 資料框架載入預測。

import pandas as pd

score = pd.read_csv(
    "named-outputs/score/predictions.csv", names=["row", "prediction", "file"]
)

輸出如下所示:

row prediction 檔案
0 0 heart-unlabeled-0.csv
1 1 heart-unlabeled-0.csv
2 0 heart-unlabeled-0.csv
... ... ...
307 0 heart-unlabeled-3.csv

提示

請注意,在此範例中,輸入資料為格式為 CSV 的表格式資料,而且有 4 個不同的輸入檔 (heart-unlabeled-0.csv、heart-unlabeled-1.csv、heart-unlabeled-2.csv 和 heart-unlabeled-3.csv)。

部署至批次推斷時的考量

Azure Machine Learning 支援將 MLflow 模型部署至批次端點,而不會指出評分指令碼。 這代表的是部署需要以批次方式處理大量資料的模型的便利方式。 Azure Machine Learning 會使用 MLflow 模型規格中的資訊來協調推斷程序。

工作如何分散在背景工作角色上

批次端點會針對結構化和非結構化資料,在檔案層級散發工作。 因此,僅 URI 檔案URI 資料夾支援使用此功能。 每個背景工作角色都會逐一處理 Mini batch size 檔案的批次。 針對表格式資料,批次端點不會在散發工作時考慮每個檔案內的資料列數目。

警告

推斷期間不會探索巢狀資料夾結構。 如果您要使用資料夾分割數據,請務必事先扁平化結構。

批次部署會針對每個檔案呼叫 MLflow 模型的 predict 函式一次。 對於包含多個資料列的 CSV 檔案,這可能會對基礎計算施加記憶體壓力,並可能會增加模型為單一檔案評分所需的時間 (特別是大型語言模型之類的昂貴模型)。 如果您遇到數個記憶體不足的例外狀況或記錄中的逾時項目,請考慮將資料分割成資料列較少的較小檔案,或在模型/評分指令碼內的資料列層級實作批次處理。

檔案類型支援

部署不含環境和評分指令碼的 MLflow 模型時,批次推斷支援下列資料類型。 如果您想要處理不同的檔案類型,或以與批次端點的預設方式不同的方式執行推斷,可以一律使用評分指令碼來建立部署,如搭配評分指令碼使用 MLflow 模型中所述。

副檔名 類型傳回為模型的輸入 簽章需求
.csv、 、 .parquet.pqt pd.DataFrame ColSpec. 如果未提供,則不會強制執行資料類型。
.png、、.jpg.jpeg.tiff、、.bmp.gif np.ndarray TensorSpec. 如果可用,輸入會重新調整以符合張量圖形。 如果沒有可用的簽章,則會推斷類型 np.uint8 的張量。 如需其他指引,請參閱 MLflow 模型處理影像時的考量

警告

請注意,任何可能存在於輸入資料中的不支援檔案都會使作業失敗。 您會看到錯誤專案,如下所示: “ERROR:azureml:Error processing input file: '/mnt/batch/tasks/.../a-given-file.avro'。不支援檔類型 『avro』。」

MLflow 模型的簽章強制

使用可用的 MLflow 模型簽章來讀取資料時,批次部署作業會強制輸入的資料類型。 這表示您的資料輸入應符合模型簽章中所指出的類型。 如果無法如預期般剖析資料,作業將會失敗,並出現類似下列的錯誤訊息:「錯誤: azureml: 處理輸入檔案時發生錯誤: '/mnt/batch/tasks/.../a-given-file.csv'。例外狀況:具有基底 10 的 int() 無效的常值: 'value'」

提示

MLflow 模型中的簽章是選擇性的,但強烈建議使用,因為可讓您更方便地及早偵測資料相容性問題。 如需如何使用簽章記錄模型的詳細資訊,請參閱使用自訂簽章、環境或範例記錄模型

您可以開啟與 MLflow 模型相關聯的 MLmodel 檔案,以檢查模型的模型簽章。 如需簽章如何在 MLflow 中運作的詳細資訊,請參閱 MLflow 中的簽章

類別支援

批次部署僅支援使用 pyfunc 類別部署 MLflow 模型。 如果您需要部署不同的類別,請參閱搭配評分指令碼使用 MLflow 模型

使用評分指令碼自訂 MLflow 模型部署

無須在部署定義中指出評分指令碼,也可將 MLflow 模型部署到批次端點。 不過,您可以選擇指出此檔案 (通常稱為批次驅動器) 來自訂推斷的執行方式。

您通常會在下列情況下選取此工作流程:

  • 必須處理批次部署 MLflow 部署不支援的檔案類型。
  • 您必須自訂模型執行的方式,例如,使用特定類別搭配 mlflow.<flavor>.load() 來載入模型。
  • 當模型本身未完成 pre/pos 處理時,您必須在評分常式中執行該處理。
  • 模型輸出無法在表格式資料中正確表示。 例如,呈現影像的張量。
  • 模型因為記憶體限制而無法一次處理每個檔案,而需要以區塊方式讀取。

重要

如果您選擇指出 MLflow 模型部署的評分腳本,您也必須指定部署執行所在的環境。

步驟

使用下列步驟部署具有自訂評分指令碼的 MLflow 模型。

  1. 識別放置 MLflow 模型的資料夾。

    a. 移至 Azure Machine Learning 入口網站

    b. 移至 [模型] 區段。

    c. 選取您嘗試部署的模型,然後按兩下 [成品] 索引標籤

    d. 記下所顯示的資料夾。 註冊模型時會指出此資料夾。

    顯示模型成品放置所在資料夾的螢幕快照。

  2. 建立評分指令碼。 請注意您之前識別的資料夾名稱 model 如何包含在 init() 函式中。

    deployment-custom/code/batch_driver.py

    # Copyright (c) Microsoft. All rights reserved.
    # Licensed under the MIT license.
    
    import os
    import glob
    import mlflow
    import pandas as pd
    import logging
    
    
    def init():
        global model
        global model_input_types
        global model_output_names
    
        # AZUREML_MODEL_DIR is an environment variable created during deployment
        # It is the path to the model folder
        # Please provide your model's folder name if there's one
        model_path = glob.glob(os.environ["AZUREML_MODEL_DIR"] + "/*/")[0]
    
        # Load the model, it's input types and output names
        model = mlflow.pyfunc.load(model_path)
        if model.metadata and model.metadata.signature:
            if model.metadata.signature.inputs:
                model_input_types = dict(
                    zip(
                        model.metadata.signature.inputs.input_names(),
                        model.metadata.signature.inputs.pandas_types(),
                    )
                )
            if model.metadata.signature.outputs:
                if model.metadata.signature.outputs.has_input_names():
                    model_output_names = model.metadata.signature.outputs.input_names()
                elif len(model.metadata.signature.outputs.input_names()) == 1:
                    model_output_names = ["prediction"]
        else:
            logging.warning(
                "Model doesn't contain a signature. Input data types won't be enforced."
            )
    
    
    def run(mini_batch):
        print(f"run method start: {__file__}, run({len(mini_batch)} files)")
    
        data = pd.concat(
            map(
                lambda fp: pd.read_csv(fp).assign(filename=os.path.basename(fp)), mini_batch
            )
        )
    
        if model_input_types:
            data = data.astype(model_input_types)
    
        # Predict over the input data, minus the column filename which is not part of the model.
        pred = model.predict(data.drop("filename", axis=1))
    
        if pred is not pd.DataFrame:
            if not model_output_names:
                model_output_names = ["pred_col" + str(i) for i in range(pred.shape[1])]
            pred = pd.DataFrame(pred, columns=model_output_names)
    
        return pd.concat([data, pred], axis=1)
    
  3. 讓我們來建立可執行評分指令碼的環境。 由於我們的模型是 MLflow,因此在模型套件中也會指定 conda 需求 (如需有關 MLflow 模型及其鍾所含檔案的詳細資訊,請參閱 MLmodel 格式)。 接著,我們將使用 檔案中的 conda 相依性來建置環境。 不過,我們也需要包含批次部署所需的 azureml-core 套件。

    提示

    如果您的模型已在模型登錄中註冊,您可以移至 Azure Machine Learning 工作室> [模型] > 從清單中選取您的模型 > [成品],以下載/複製與您的模型相關聯的 conda.yml 檔案。 在導覽列中開啟根資料夾,然後選取列出的 conda.yml 檔案。 按一下 [下載] 或複製其內容。

    重要

    此範例使用 /heart-classifier-mlflow/environment/conda.yaml 上指定的 conda 環境。 此檔案是藉由合併原始的 MLflow conda 相依性檔案和新增 azureml-core 套件來建立。 您無法直接從模型使用 conda.yml 檔案

    環境定義會以匿名環境的形式包含在部署定義本身。 您將在部署的下列幾行中看到:

    environment:
      name: batch-mlflow-xgboost
      image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
      conda_file: environment/conda.yaml
    
  4. 設定部署:

    若要在已建立的端點下建立新部署,請建立 YAML 設定,如下所示。 您可以檢查完整的批次端點 YAML 結構描述,以取得額外的屬性。

    deployment-custom/deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: heart-classifier-batch
    name: classifier-xgboost-custom
    description: A heart condition classifier based on XGBoost
    type: model
    model: azureml:heart-classifier-mlflow@latest
    environment:
      name: batch-mlflow-xgboost
      image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
      conda_file: environment/conda.yaml
    code_configuration:
      code: code
      scoring_script: batch_driver.py
    compute: azureml:batch-cluster
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 2
      mini_batch_size: 2
      output_action: append_row
      output_file_name: predictions.csv
      retry_settings:
        max_retries: 3
        timeout: 300
      error_threshold: -1
      logging_level: info
    
  5. 現在讓我們建立部署:

    az ml batch-deployment create --file deployment-custom/deployment.yml --endpoint-name $ENDPOINT_NAME
    
  6. 此時,我們的批次端點已可供使用。

清除資源

執行下列程式碼,以刪除 Batch 端點和所有基礎部署。 將不會刪除批次評分作業。

az ml batch-endpoint delete --name $ENDPOINT_NAME --yes

下一步