撰寫批次部署的評分指令碼
適用於:Azure CLI ml 延伸模組 v2 (目前)Python SDK azure-ai-ml v2 (目前)
批次端點可用於部署模型,以大規模執行長期推斷。 部署模型時,您必須建立並指定評分指令碼 (也稱為批次驅動程式指令碼),以指出如何對輸入資料使用它來建立預測。 在此文章中,您將了解如何針對不同案例在模型部署中使用評分指令碼。 您也將了解適用於批次端點的最佳做法。
提示
MLflow 模型不需要評分指令碼。 其會為您自動產生。 如需批次端點如何使用 MLflow 模型的詳細資訊,請參閱在批次部署中使用 MLflow 模型專用教學課程 (英文)。
警告
若要在批次端點之下部署自動化 ML 模型,請注意自動化 ML 提供的評分指令碼僅適用於線上端點。 該評分指令碼並非設計來批次執行。 如需如何建立評分指令碼 (針對您模型執行的作業進行自訂) 的詳細資訊,請遵循這些方針。
了解評分指令碼
評分指令碼是一個 Python 檔案 (.py
),其會指定如何執行模型,並讀取批次部署執行程式所提交的輸入資料。 每個模型部署都會在建立時提供評分指令碼 (以及所有其他必要的相依性)。 評分指令碼通常看起來像這樣:
deployment.yml
code_configuration:
code: code
scoring_script: batch_driver.py
評分指令碼必須包含兩個方法:
init
方法
將此 init()
方法用於任何昂貴或一般的準備。 例如,用其將模型載入記憶體中。 整個批次工作開始時會呼叫此函式一次。 模型的檔案位於環境變數 AZUREML_MODEL_DIR
所決定的路徑中。 根據模型註冊方式而定,其檔案可能包含在某個資料夾中。 在下一個範例中,模型在名為 model
的資料夾中有數個檔案。 如需詳細資訊,請瀏覽如何判斷模型所使用的資料夾。
def init():
global model
# AZUREML_MODEL_DIR is an environment variable created during deployment
# The path "model" is the name of the registered model's folder
model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")
# load the model
model = load_model(model_path)
在此範例中,我們將模型放在全域變數 model
中。 若要提供對評分函式執行推斷所需的資產,請使用全域變數。
run
方法
使用 run(mini_batch: List[str]) -> Union[List[Any], pandas.DataFrame]
方法來處理批次部署所產生之每個迷你批次的評分。 對於您輸入資料所產生的每個 mini_batch
,都會呼叫此方法一次。 批次部署會根據部署的設定方式,批次讀取資料。
import pandas as pd
from typing import List, Any, Union
def run(mini_batch: List[str]) -> Union[List[Any], pd.DataFrame]:
results = []
for file in mini_batch:
(...)
return pd.DataFrame(results)
此方法會以參數 (mini_batch
) 的形式接收檔案路徑清單。 您可以使用此清單,逐一查看並個別處理每個檔案,或讀取整個批次並一次完整處理。 最佳選項取決於計算記憶體和所需達到的輸送量。 如需描述如何一次讀取整個資料批次的範例,請參閱高輸送量部署 (英文)。
注意
如何散發工作?
批次部署會在檔案層級散發工作,這表示包含 100 個檔案且迷你批次為 10 個檔案的資料夾,會產生 10 個批次,每個批次各有 10 個檔案。 請注意,相關檔案的大小並無任何相關性。 若檔案太大而無法在大型迷你批次中處理,建議您將檔案分割成較小的檔案,以達到較高層級的平行處理原則,或減少每個迷你批次的檔案數目。 目前,批次部署無法將檔案大小散發中的扭曲納入考量。
run()
方法應該傳回 Pandas DataFrame
或陣列/清單。 每個傳回的輸出元素表示輸入 mini_batch
中輸入元素的一個成功執行。 針對檔案或資料夾資料資產,每個傳回的資料列/元素都代表已處理的單一檔案。 針對表格式資料資產,每個傳回的資料列/元素都代表已處理檔案中的一個資料列。
重要
如何寫入預測?
run()
函式傳回的所有內容都將附加在批次工作所產生的輸出預測檔案中。 請務必從此函式傳回正確的資料類型。 需要輸出單一預測時,請傳回陣列。 需要傳回多個資訊片段時,請傳回 Pandas DataFrame。 例如,針對表格式資料,您可以將預測附加至原始記錄。 請使用 pandas DataFrame 來執行此作業。 儘管 pandas DataFrame 可能包含資料行名稱,但輸出檔案不會包含那些名稱。
若要以不同方式寫入預測,您可以在批次部署中自訂輸出 (英文)。
警告
在 run
函式中,不要輸出複雜資料類型 (或複雜資料類型清單),而是輸出 pandas.DataFrame
。 那些輸出將轉換為字串,而其將變得難以讀取。
產生的 DataFrame 或陣列會附加至指定的輸出檔案。 沒有任何關於結果基數的需求。 一個檔案可以在輸出中產生 1 或多個資料列/元素。 結果 DataFrame 或陣列中的所有元素皆會依現況寫入輸出檔案 (須注意 output_action
不是 summary_only
)。
用於評分的 Python 套件
您必須指定評分指令碼在批次部署執行所在環境中執行所需的任何程式庫。 針對評分指令碼,每個部署都會指定環境。 您通常會使用 conda.yml
相依性檔案來指定需求,如下所示:
mnist/environment/conda.yaml
name: mnist-env
channels:
- conda-forge
dependencies:
- python=3.8.5
- pip<22.0
- pip:
- torch==1.13.0
- torchvision==0.14.0
- pytorch-lightning
- pandas
- azureml-core
- azureml-dataset-runtime[fuse]
如需如何為模型指定環境的詳細資訊,請參閱建立批次部署 (英文)。
以不同方式撰寫預測
如部署中所述,批次部署預設會在單一檔案中寫入模型的預測。 不過,在某些情況下,您必須在多個檔案中寫入預測。 例如,針對資料分割的輸入資料,您也可以產生資料分割的輸出。 在那些案例中,您可以在批次部署中自訂輸出 (英文),以指定:
- 用來寫入預測的檔案格式 (CSV、parquet、json 等)
- 在輸出中分割資料的方式
如需如何達成此目的的詳細資訊,請參閱在批次部署中自訂輸出 (英文)。
評分指令碼的原始檔控制
強烈建議您將評分指令碼放在原始檔控制之下。
撰寫評分指令碼的最佳做法
撰寫處理大量資料的評分指令碼時,您必須考慮數個因素,包括
- 每個檔案的大小
- 每個檔案上的資料量
- 讀取每個檔案所需的記憶體量
- 讀取整批檔案所需的記憶體量
- 模型的磁碟使用量
- 對輸入資料執行時的模型磁碟使用量
- 計算中的可用記憶體
批次部署會在檔案層級散發工作。 這表示包含 100 個檔案且迷你批次為 10 個檔案的資料夾,會產生 10 個批次,每個批次各有 10 個檔案 (無論所涉及的檔案大小為何)。 若檔案太大而無法在大型迷你批次中處理,建議您將檔案分割成較小的檔案,以達到較高層級的平行處理原則,或減少每個迷你批次的檔案數目。 目前,批次部署無法將檔案大小散發中的扭曲納入考量。
平行處理原則的程度與評分指令碼之間的關聯性
部署設定會同時控制每個迷你批次的大小,以及每個節點上的背景工作角色數目。 當您決定是否要讀取整個迷你批次來執行推斷、逐檔案執行推斷,或逐列執行推斷 (針對表格式) 時,這會變得很重要。 如需詳細資訊,請參閱在迷你批次、檔案或資料列層級執行推斷。
在同一個執行個體上執行多個背景工作角色時,您應該將會在所有背景工作角色之間共用記憶體這件事納入考量。 增加每個節點的背景工作角色數目,通常應該會伴隨著迷你批次大小的減少,或者,如果資料大小和計算 SKU 保持不變,則會伴隨著評分策略的變更。
在迷你批次、檔案或資料列層級執行推斷
批次端點會針對每個迷你批次,在評分指令碼中呼叫 run()
函式一次。 不過,您可以決定是否要對整個批次執行推斷、一次對一個檔案執行,或針對表格式資料一次對一個資料列執行。
迷你批次層級
您通常會希望一次對批次完整執行推斷,以在批次評分流程中達到高輸送量。 如果您要對希望達到推斷裝置飽和度的 GPU 執行推斷,就會發生此情況。 如果記憶體無法容納資料,您也可以依賴能夠自行處理批次的資料載入器,例如 TensorFlow
或 PyTorch
資料載入器。 在這些情況下,您可能想要對整個批次執行推斷。
警告
在批次層級執行推斷可能需要嚴格控制輸入資料大小,才能正確考慮記憶體需求,並避免記憶體不足的例外狀況。 您是否能夠在記憶體中載入整個迷你批次,取決於迷你批次的大小、叢集中執行個體的大小、每個節點上的背景工作角色數目,以及迷你批次的大小。
請參閱高輸送量部署 (英文),以了解如何達成此目的。 此範例會一次處理整個批次的檔案。
檔案層級
執行推斷的最簡單方式之一,就是逐一查看迷你批次中的所有檔案,然後對其執行模型。 在某些案例中 (例如映像處理),這可能是個好主意。 針對表格式資料,您可能需要對每個檔案中的資料列數目進行良好估計。 此估計可顯示您的模型是否可以處理記憶體需求,以將整個資料載入到記憶體,並對其執行推斷。 某些模型 (特別是以循環神經網路為基礎的模型) 展開並呈現具有潛在非線性資料列計數的記憶體使用量。 對於記憶體費用較高的模型,請考慮在資料列層級執行推斷。
提示
請考慮將大小太大而無法一次讀取的檔案細分成多個較小的檔案,以實現更好的平行處理。
請瀏覽使用批次部署進行映像處理,以了解如何執行此作業。 該範例會一次處理一個檔案。
資料列層級 (表格式)
針對存在輸入大小挑戰的模型,您可以在資料列層級執行推斷。 您的批次部署仍會提供具有迷你檔案批次的評分指令碼。 不過,您將一次讀取一個檔案、一個資料列。 這可能看起來效率低落,但對某些深度學習模型來說,其可能是在不擴大硬體資源的情況下執行推斷的唯一方式。
請瀏覽使用批次部署進行文字處理 (英文),以了解如何執行此作業。 該範例會一次處理一個資料列。
使用其為資料夾的模型
AZUREML_MODEL_DIR
環境變數包含連至所選模型位置的路徑,而 init()
函式通常會使用該環境變數來將模型載入到記憶體。 不過,有些模型可能會在資料夾中包含檔案,而您可能需要在載入它們時將其列入考量。 您可以識別模型的資料夾結構,如下所示:
使用此路徑來載入模型:
def init():
global model
# AZUREML_MODEL_DIR is an environment variable created during deployment
# The path "model" is the name of the registered model's folder
model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")
model = load_model(model_path)
下一步
- 針對批次端點進行疑難排解
- 在批次部署中使用 MLflow 模型 (英文)
- 使用批次部署進行映像處理 (英文)