共用方式為


對機器學習管線進行疑難排解

適用於: Python SDK azureml v1 (部分機器翻譯)

在本文中,您將了解如何在 Azure Machine Learning SDKAzure Machine Learning 設計工具中執行機器學習管線卻遇到錯誤時進行疑難排解。

疑難排解秘訣

下表包含管線開發期間的常見問題,並提供可能的解決方案。

問題 可能的解決方案
無法將資料傳遞至 PipelineData 目錄 請確定您已在指令碼中建立目錄,且該目錄對應至管線預期會有步驟輸出資料的位置。 在大部分的情況下,輸入引數會定義輸出目錄,然後您便可以明確地建立目錄。 請使用 os.makedirs(args.output_dir, exist_ok=True) 來建立輸出目錄。 如需顯示此設計模式的評分指令碼範例,請參閱教學課程
相依性錯誤 (bug) 如果您在遠端管線中看到進行本機測試時未發生的相依性錯誤,請確認您的遠端環境相依性和版本符合測試環境中的值。 請參閱環境建置、快取和重複使用
計算目標有不明確的錯誤 請嘗試刪除並重新建立計算目標。 重新建立計算目標的速度很快,而且可解決一些暫時性問題。
管線未重複使用步驟 步驟重複使用會預設為啟用,但請確定您未在管線步驟中將其停用。 如果已停用重複使用功能,則步驟中的 allow_reuse 參數會設定為 False
管線不必重新執行 為確保只有在基礎資料或指令碼變更時才重新執行步驟,請將每個步驟的原始程式碼目錄分離。 如果您使用相同的來原始目錄進行多個步驟,可能會發生不必要的重新執行。 在管線步驟物件上使用 source_directory 參數來指向該步驟的已隔離目錄,並確定您未針對多個步驟使用相同的 source_directory 路徑。
步驟在訓練 Epoch 中變慢或其他迴圈行為 請嘗試將任何檔案寫入 (包括記錄) 從 as_mount() 切換至 as_upload()掛接模式使用遠端虛擬化檔案系統,並且會在每次附加檔案時,上傳整個檔案。
計算目標需要很長的時間才能啟動 計算目標的 Docker 映像是從 Azure Container Registry (ACR) 載入的。 根據預設,Azure Machine Learning 會建立使用基本服務層級的 ACR。 將工作區的 ACR 變更為「標準」或「進階層」,可減少建立和載入映像所需的時間。 如需詳細資訊,請參閱 Azure Container Registry 服務層級

驗證錯誤

如果您從遠端工作執行計算目標的管理作業,您會收到下列其中一個錯誤:

{"code":"Unauthorized","statusCode":401,"message":"Unauthorized","details":[{"code":"InvalidOrExpiredToken","message":"The request token was either invalid or expired. Please try again with a valid token."}]}
{"error":{"code":"AuthenticationFailed","message":"Authentication failed."}}

例如,如果您嘗試從 ML 管線建立或連結為遠端執行所提交的計算目標,您會收到錯誤。

針對 ParallelRunStep 進行疑難排解

ParallelRunStep 的指令碼「必須包含」兩個函式:

  • init():請將此函式用於高成本或一般的準備,以進行後續的推斷。 例如,使用此函式將模型載入至全域物件。 此函式只會在程序開始時呼叫一次。
  • run(mini_batch):此函式會針對每個 mini_batch 執行個體來執行。
    • mini_batchParallelRunStep 會叫用 run 方法,並將 list 或 pandas DataFrame 作為引數傳遞給方法。 mini_batch 中的每個項目會是檔案路徑 (如果輸入是 FileDataset) 或 pandas DataFrame (如果輸入是 TabularDataset)。
    • response:run() 方法應該傳回 pndas DataFrame 或陣列。 針對 append_row output_action,這些傳回的元素會附加至一般輸出檔案。 針對 summary_only,則會忽略元素的內容。 針對所有輸出動作,每個傳回的輸出元素會指出輸入迷你批次中一次成功的輸入元素執行。 確保執行結果中有足夠的資料可將輸入對應至執行輸出結果。 執行輸出將會寫入至輸出檔案,而且不保證會按照順序,所以您應該在輸出中使用某個索引鍵以將其對應至輸入。
%%writefile digit_identification.py
# Snippets from a sample script.
# Refer to the accompanying digit_identification.py
# (https://github.com/Azure/MachineLearningNotebooks/tree/master/how-to-use-azureml/machine-learning-pipelines/parallel-run)
# for the implementation script.

import os
import numpy as np
import tensorflow as tf
from PIL import Image
from azureml.core import Model


def init():
    global g_tf_sess

    # Pull down the model from the workspace
    model_path = Model.get_model_path("mnist")

    # Construct a graph to execute
    tf.reset_default_graph()
    saver = tf.train.import_meta_graph(os.path.join(model_path, 'mnist-tf.model.meta'))
    g_tf_sess = tf.Session()
    saver.restore(g_tf_sess, os.path.join(model_path, 'mnist-tf.model'))


def run(mini_batch):
    print(f'run method start: {__file__}, run({mini_batch})')
    resultList = []
    in_tensor = g_tf_sess.graph.get_tensor_by_name("network/X:0")
    output = g_tf_sess.graph.get_tensor_by_name("network/output/MatMul:0")

    for image in mini_batch:
        # Prepare each image
        data = Image.open(image)
        np_im = np.array(data).reshape((1, 784))
        # Perform inference
        inference_result = output.eval(feed_dict={in_tensor: np_im}, session=g_tf_sess)
        # Find the best probability, and add it to the result list
        best_result = np.argmax(inference_result)
        resultList.append("{}: {}".format(os.path.basename(image), best_result))

    return resultList

如果推斷指令碼所在的相同目錄中有另一個檔案或資料夾,您可以藉由尋找目前的工作目錄來對其進行參照。

script_dir = os.path.realpath(os.path.join(__file__, '..',))
file_path = os.path.join(script_dir, "<file_name>")

ParallelRunConfig 的參數

ParallelRunConfig 是 Azure Machine Learning 管線中 ParallelRunStep 執行個體的主要組態。 您可以用此設定來包裝指令碼並設定必要參數,包括下列各項:

  • entry_script:作為本機檔案路徑的使用者指令碼,會在多個節點上平行執行。 如果 source_directory 存在,請使用相對路徑。 否則,使用可在機器上存取的路徑即可。
  • mini_batch_size:傳遞至單一 run() 呼叫的迷你批次大小。 (選擇性;預設值為 10 個檔案 (若為 FileDataset) 和 1MB (若為 TabularDataset)。)
    • 針對 FileDataset,這是最小值為 1 的檔案數目。 您可以將多個檔案結合成一個迷你批次。
    • 針對 TabularDataset,這是資料的大小。 範例值為 10241024KB10MB1GB。 建議值是 1MBTabularDataset 中的迷你批次絕對不會跨越檔案界限。 例如,如果您有各種大小的 .csv 檔案,最小檔案為 100 KB,最大檔案則為 10 MB。 如果您設定 mini_batch_size = 1MB,則系統會將小於 1 MB 的檔案視為一個迷你批次。 大於 1 MB 的檔案則會分割成多個迷你批次。
  • error_threshold:處理期間應該忽略的記錄失敗數目 (針對 TabularDataset) 和檔案失敗數目 (針對 FileDataset)。 如果整個輸入的錯誤計數超過此值,作業便會中止。 錯誤閾值適用於整個輸入,而非適用於傳送至 run() 方法的個別迷你批次。 範圍為 [-1, int.max]-1 部分會指出要在處理期間忽略所有失敗。
  • output_action:下列其中一個值說明輸出的資料會如何被組合:
    • summary_only:使用者指令碼會儲存輸出。 ParallelRunStep 只會將輸出用於計算錯誤閾值。
    • append_row:針對所有輸入,輸出資料夾中只會建立一個檔案,並以直線分隔的方式附加所有輸出。
  • append_row_file_name:若要自訂 append_row output_action 的輸出檔案名稱 (選用,預設值為 parallel_run_step.txt)。
  • source_directory:資料夾的路徑,資料夾中包含要在計算目標上執行的所有檔案 (選擇性)。
  • compute_target:只支援 AmlCompute
  • node_count:要用來執行使用者指令碼的計算節點數目。
  • process_count_per_node:每個節點的處理序數目。 最佳做法是設定為節點擁有的 GPU 或 CPU 數目 (選用,預設值為 1)。
  • environment:Python 環境定義。 您可以將其設定為使用現有 Python 環境,也可以設定暫存環境。 定義也會負責設定必要的應用程式相依性 (選擇性)。
  • logging_level:記錄詳細程度。 增加詳細程度的值包括:WARNINGINFODEBUG。 (選擇性;預設值為 INFO)
  • run_invocation_timeoutrun() 方法叫用逾時 (以秒為單位)。 (選擇性;預設值為 60)
  • run_max_try:迷你批次的 run() 嘗試次數上限。 如果擲回例外狀況,或達到 run_invocation_timeout 時未傳回任何內容 (選用;預設值為 3),則 run() 會失敗。

您可以將 mini_batch_sizenode_countprocess_count_per_nodelogging_levelrun_invocation_timeoutrun_max_try 指定為 PipelineParameter,以便在重新提交管線執行時,可以微調參數值。 在此範例中,您會針對 mini_batch_sizeProcess_count_per_node 使用 PipelineParameter,並在稍後重新提交執行時變更這些值。

用於建立 ParallelRunStep 的參數

使用指令碼、環境組態和參數來建立 ParallelRunStep。 指定您已附加至工作區的計算目標以作為推斷指令碼的執行目標。 使用 ParallelRunStep 來建立批次推斷管線步驟,其採用下列所有參數:

  • name:步驟的名稱,具有下列命名限制:唯一的、3 至 32 個字元,且 regex ^[a-z]([-a-z0-9]*[a-z0-9])?$。
  • parallel_run_config:如先前所定義的 ParallelRunConfig 物件。
  • inputs:要分割以進行平行處理的一或多個單一類型 Azure Machine Learning 資料集。
  • side_inputs:一或多個參考資料或資料集,用來作為不需要分割的端輸入。
  • output:對應至輸出目錄的 OutputFileDatasetConfig 物件。
  • arguments:傳遞至使用者指令碼的引數清單。 使用 unknown_args,在您的輸入腳本中擷取 (選用)。
  • allow_reuse:在使用相同設定/輸入執行時,步驟是否應重複使用先前的結果。 如果此參數為 False,則在管線執行期間,會為此步驟產生新的執行。 (選擇性;預設值為 True。)
from azureml.pipeline.steps import ParallelRunStep

parallelrun_step = ParallelRunStep(
    name="predict-digits-mnist",
    parallel_run_config=parallel_run_config,
    inputs=[input_mnist_ds_consumption],
    output=output_dir,
    allow_reuse=True
)

偵錯技術

有三種主要的方法可以用來對管線偵錯:

  • 偵錯本機電腦上的個別管線步驟
  • 使用記錄和 Application Insights 來隔離及診斷問題來源
  • 將遠端偵錯工具連結至在 Azure 中執行的管線

在本機偵錯指令碼

在管線中,最常見的其中一種失敗是網域指令碼未如預期般執行,或在遠端計算內容中包含難以偵錯的執行階段錯誤。

管線本身無法在本機執行。 但是,在本機電腦上以隔離方式執行指令碼可讓您更快速地進行偵錯,因為您無須等待計算和環境建置程序。 您需要進行一些開發工作才能執行這項作業:

  • 如果您的資料位於雲端資料存放區,則必須下載資料,並將資料提供給指令碼使用。 使用較小的資料範例,可讓您減少執行時間,並快速獲得關於指令碼行為的意見反應
  • 如果您嘗試模擬中繼管線步驟,則可能需要手動建置特定指令碼所預期、得自先前步驟的物件類型
  • 您必須定義自己的環境,並複寫遠端計算環境中所定義的相依性

當您將指令碼設定為在本機環境中執行之後,就能更輕鬆地執行偵錯工作,例如:

  • 連結自訂的偵錯設定
  • 暫停執行並檢查物件狀態
  • 擷取在執行階段開始之前不會顯露出來的類型或邏輯錯誤

提示

在能夠確認指令碼如預期般執行後,下一步就是先在單一步驟的管線中執行指令碼,然後再嘗試於多個步驟的管線中執行指令碼。

設定、寫入和檢閱管線記錄

在開始建置管線之前,先在本機測試指令碼,是偵錯主要程式碼片段和複雜邏輯的好方法。 有時候,您需要在實際管線執行本身期間偵錯指令碼,特別是在診斷管線步驟之間互動期間發生的行為時。 建議您在步驟指令碼中隨意使用 print() 陳述式,以便看看遠端執行期間的物件狀態和預期的值,情況就和您對 JavaScript 程式碼進行偵錯時一樣。

記錄選項和行為

下表針對管線的不同偵錯選項提供相關資訊。 這並不是詳盡的清單,因為除了此處顯示的 Azure Machine Learning 和 Python 之外,還有其他選項存在。

程式庫 類型 範例 Destination 資源
Azure Machine Learning SDK 計量 run.log(name, val) Azure Machine Learning 入口網站 UI 如何追蹤實驗
azureml.core.Run 類別
Python 列印/記錄 記錄 print(val)
logging.info(message)
驅動程式記錄、Azure Machine Learning 設計工具 如何追蹤實驗

Python 記錄

記錄選項範例

import logging

from azureml.core.run import Run

run = Run.get_context()

# Azure Machine Learning Scalar value logging
run.log("scalar_value", 0.95)

# Python print statement
print("I am a python print statement, I will be sent to the driver logs.")

# Initialize Python logger
logger = logging.getLogger(__name__)
logger.setLevel(args.log_level)

# Plain Python logging statements
logger.debug("I am a plain debug statement, I will be sent to the driver logs.")
logger.info("I am a plain info statement, I will be sent to the driver logs.")

handler = AzureLogHandler(connection_string='<connection string>')
logger.addHandler(handler)

Azure Machine Learning 設計工具

針對在設計工具中建立的管線,您可以在 [撰寫] 頁面或 [管線執行詳細資料] 頁面中找到 70_driver_log 檔案。

為即時端點啟用記錄功能

為了在設計工具中針對即時端點進行疑難排解和偵測,您必須使用 SDK 來啟用 Application Insight 記錄功能。 記錄功能可讓您針對模型的部署和使用問題進行疑難排解和偵錯。 如需詳細資訊,請參閱已部署模型的記錄

從撰寫頁面取得記錄

當您提交管線執行並留在 [撰寫] 頁面時,您可以在每個元件執行完成時,找到針對每個元件所產生的記錄檔。

  1. 選取已在製作畫布中執行完成的元件。

  2. 在元件的右窗格中,移至 [輸出 + 記錄] 索引標籤。

  3. 展開右窗格,然後選取 [70_driver_log.txt],以在瀏覽器中檢視檔案。 您也可以在本機下載記錄。

    在設計工具中展開 [輸出] 窗格

從管線執行取得記錄

您也可以在 [管線執行詳細資料] 頁面中找到特定執行的記錄檔,在工作室的 [管線] 或 [實驗] 區段中均可找到。

  1. 選取在設計工具中建立的管線執行。

    管線執行頁面

  2. 在 [預覽] 窗格中選取元件。

  3. 在元件的右窗格中,移至 [輸出 + 記錄] 索引標籤。

  4. 展開右窗格以在瀏覽器中檢視 std_log.txt 檔案,或選取該檔案以便在本機下載記錄。

重要

若要從 [管線執行詳細資料] 頁面更新管線,您必須將管線執行複製到新的管線草稿。 管線執行是管線的快照集。 其類似於記錄檔,而且無法變更。

使用 Visual Studio Code 進行互動式偵錯

在某些情況下,您可能需要以互動方式來對 ML 管線中使用的 Python 程式碼進行偵錯。 藉由使用 Visual Studio Code (VS Code) 和 debugpy,您可以在程式碼在訓練環境中執行時連結程式碼。 如需詳細資訊,請造訪 VS Code 中的互動式偵錯指南

HyperdriveStep 和 AutoMLStep 因網路隔離而失敗

使用 HyperdriveStep 和 AutoMLStep 之後,當您嘗試註冊模型時,可能會收到錯誤。

  • 您使用的是 Azure Machine Learning SDK v1。

  • 您的 Azure Machine Learning 工作區已設定為網路隔離 (VNet)。

  • 您的管線會嘗試註冊上一個步驟所產生的模型。 例如,在下列範例中,inputs 參數是 HyperdriveStep 中的 saved_model:

    register_model_step = PythonScriptStep(script_name='register_model.py',
                                       name="register_model_step01",
                                       inputs=[saved_model],
                                       compute_target=cpu_cluster,
                                       arguments=["--saved-model", saved_model],
                                       allow_reuse=True,
                                       runconfig=rcfg)
    

因應措施

重要

使用 Azure Machine Learning SDK v2 時,不會發生此行為。

若要解決此錯誤,請使用 Run 類別,取得從 HyperdriveStep 或 AutoMLStep 建立的模型。 以下是從 HyperdriveStep 取得輸出模型的範例指令碼:

%%writefile $script_folder/model_download9.py
import argparse
from azureml.core import Run
from azureml.pipeline.core import PipelineRun
from azureml.core.experiment import Experiment
from azureml.train.hyperdrive import HyperDriveRun
from azureml.pipeline.steps import HyperDriveStepRun

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--hd_step_name', 
        type=str, dest='hd_step_name', 
        help='The name of the step that runs AutoML training within this pipeline')
        
        
    
    args = parser.parse_args()
    
    current_run = Run.get_context()

    pipeline_run = PipelineRun(current_run.experiment, current_run.experiment.name)

    hd_step_run = HyperDriveStepRun((pipeline_run.find_step_run(args.hd_step_name))[0])
    hd_best_run = hd_step_run.get_best_run_by_primary_metric()

    print(hd_best_run)
    hd_best_run.download_file("outputs/model/saved_model.pb", "saved_model.pb")
    
    
    print("Successfully downloaded model") 

然後,您可以從 PythonScriptStep 使用該檔案:

from azureml.pipeline.steps import PythonScriptStep
conda_dep = CondaDependencies()
conda_dep.add_pip_package("azureml-sdk")
conda_dep.add_pip_package("azureml-pipeline")

rcfg = RunConfiguration(conda_dependencies=conda_dep)

model_download_step = PythonScriptStep(
    name="Download Model 9",
    script_name="model_download9.py", 
    arguments=["--hd_step_name", hd_step_name],
    compute_target=compute_target,
    source_directory=script_folder,
    allow_reuse=False,
    runconfig=rcfg
)

下一步