疑難排解遠端模型部署

了解如何對使用 Azure Machine Learning 將模型部署至 Azure 容器執行個體 (ACI) 和 Azure Kubernetes Service (AKS) 時可能發生的常見錯誤進行疑難排解並解決或採取因應措施。

注意

如果您要將模型部署到 Azure Kubernetes Service (AKS),建議您為該叢集啟用 Azure 監視器。 這可協助您了解整體叢集的健康情況和資源使用量。 您也可能會發現下列資源很有用:

如果您嘗試將模型部署到狀況不良或多載的叢集,則應該會遇到問題。 如果您在對 AKS 叢集問題進行疑難排解時需要協助,請連絡 AKS 支援人員。

必要條件

機器學習模型 Docker 部署的步驟

當您在 Azure Machine Learning 中將模型部署至非本機計算時,會發生下列情況:

  1. 您在 InferenceConfig 的 Environments 物件中指定的 Dockerfile 會傳送至雲端,以及來源目錄的內容
  2. 如果容器登錄無法使用之前組建的映像,系統會在雲端中組建新的 Docker 映像,並儲存在工作區的容器登錄中。
  3. 來自容器登錄的 Docker 映像會下載至您的計算目標。
  4. 您工作區的預設 Blob 存放區會掛接到您的計算目標,讓您能夠存取已登錄的模型
  5. 執行輸入指令碼的 init() 函式,即可初始化您的 Web 伺服器
  6. 當您已部署的模型收到要求時,您的 run() 函式會處理該要求

使用本機部署時的主要差異在於,容器映像是在本機電腦上建置的,這也是為什麼您需要安裝 Docker 以進行本機部署的原因。

了解這些高階步驟應可協助您了解發生錯誤的位置。

取得部署記錄

偵錯錯誤的第一個步驟是取得您的部署記錄。 首先,遵循這裡的指示以連線到您的工作區

適用於:Azure CLI ml 延伸模組 v1

若要從已部署的 Web 服務取得記錄,請執行:

az ml service get-logs --verbose --workspace-name <my workspace name> --name <service name>

在本機執行偵錯

如果您在將模型部署到 ACI 或 AKS 時遇到問題,請將它部署為本機 Web 服務。 使用本機 Web 服務可讓您更輕鬆地針對問題進行疑難排解。 若要針對本機部署進行疑難排解,請參閱本機疑難排解文章

Azure Machine Learning 推斷 HTTP 伺服器

本機推斷伺服器可讓您快速地對輸入指令碼 (score.py)進行偵錯。 如果基礎分數指令碼有錯誤 (bug),伺服器會無法初始化或提供模型。 相反地,它會擲回例外狀況和發生問題的位置。 深入了解 Azure Machine Learning 推斷 HTTP 伺服器

  1. pypi 摘要安裝 azureml-inference-server-http 套件:

    python -m pip install azureml-inference-server-http
    
  2. 啟動伺服器,並將 score.py 設定為輸入指令碼:

    azmlinfsrv --entry_script score.py
    
  3. 使用 curl,將評分要求傳送至伺服器:

    curl -p 127.0.0.1:5001/score
    

注意

了解 Azure 機器學習推斷 HTTP 伺服器的常見問題。

無法排程容器

將服務部署至 Azure Kubernetes Service 計算目標時,Azure Machine Learning 會嘗試使用要求的資源量來排程服務。 如果 5 分鐘後,叢集中沒有適當可用資源量的節點,部署將會失敗。 失敗訊息為 Couldn't Schedule because the kubernetes cluster didn't have available resources after trying for 00:05:00。 您可以藉由新增更多節點、變更節點的 SKU 或變更服務的資源需求,來解決此錯誤。

錯誤訊息通常指出需求較多的資源。例如,如果您看到錯誤訊息「0/3 nodes are available: 3 Insufficient nvidia.com/gpu」,即服務需要 GPU,但叢集中有三個節點沒有可用的 GPU。 如果您使用 GPU SKU,請新增更多節點解決此問題;如果不是,請切換至已啟用 GPU 的 SKU 或變更為不需要 GPU 的環境。

服務啟動失敗

成功建置映像後,系統就會嘗試使用您的部署組態啟動容器。 作為容器啟動程序的一部分,系統會叫用評分指令碼中的 init() 函式。 如果 init() 函式中有無法攔截的例外狀況,您可能會在錯誤訊息中看到 CrashLoopBackOff 錯誤。

使用檢查 Docker 記錄文章中的資訊。

容器 azureml-fe-aci 啟動失敗

將服務部署至 Azure 容器執行個體計算目標時,Azure Machine Learning 嘗試建立推斷要求名稱為 azureml-fe-aci 的前端容器。 如果 azureml-fe-aci 損毀,您可以執行 az container logs --name MyContainerGroup --resource-group MyResourceGroup --subscription MySubscription --container-name azureml-fe-aci 來查看記錄。 您可以遵循記錄中的錯誤訊息進行修正。

azureml-fe-aci 的最常見失敗是所提供的 SSL 憑證或金鑰無效。

函式錯誤:get_model_path()

通常,在評分指令碼 Model.get_model_path()init() 函式中,呼叫該函式是為了找出容器中的模型檔案或模型檔案資料夾。 如果找不到模型檔案或資料夾,函式會失敗。 若要對此錯誤進行偵錯,最簡單方式是在容器殼層中執行下列 Python 程式碼:

適用於:Python SDK azureml v1

from azureml.core.model import Model
import logging
logging.basicConfig(level=logging.DEBUG)
print(Model.get_model_path(model_name='my-best-model'))

此範例會列印容器中的本機路徑 (相對於 /var/azureml-app),即評分指令碼預期找到模型檔案或資料夾的位置。 接著您可以驗證檔案或資料夾是否確實位於預期的位置。

將記錄層級設定為 [偵錯] 可記錄額外資訊,這在要找出失敗原因時可能很實用。

函式失敗:run(input_data)

如果已成功部署服務,但此服務在您發佈資料到評分端點時發生損毀,您可以在 run(input_data) 函式中新增錯誤攔截陳述式,以傳回詳細的錯誤訊息。 例如:

def run(input_data):
    try:
        data = json.loads(input_data)['data']
        data = np.array(data)
        result = model.predict(data)
        return json.dumps({"result": result.tolist()})
    except Exception as e:
        result = str(e)
        # return error message back to the client
        return json.dumps({"error": result})

附註:從 run(input_data) 呼叫傳回錯誤訊息的方式應僅用於偵錯目的。 基於安全性理由,建議您不要在實際執行環境中以這種方式傳回錯誤訊息。

HTTP 狀態碼 502

502 狀態碼表示服務已在 score.py 檔案的 run() 方法中擲回例外狀況或損毀。 使用本文中的資訊來偵錯檔案。

HTTP 狀態碼 503

Azure Kubernetes Service 部署支援自動調整,所以您可以新增複本至支援的額外負載。 自動調整程式的設計訴求是處理負載中細微的變更。 如果您每秒收到非常大量的要求數,用戶端可能會收到 HTTP 狀態碼 503。 即使自動調整程式可迅速反應,AKS 建立更多容器仍需要大量時間。

擴大/縮減的決策是以目前容器複本的使用量為基礎。 忙碌中 (處理要求) 的複本數目除以目前複本的總數即為目前的使用率。 如果此數目超過 autoscale_target_utilization,則會建立更多複本。 如果低於此數目,即會減少複本。 新增複本的決策是積極且快速 (大約 1 秒)。 移除複本的決策是保守 (大約 1 分鐘)。 根據預設,自動調整目標使用率會設定為 70%,這表示服務可以處理突然增加的每秒要求數 (RPS),最高可達 30%

有兩個方法可協助防止出現 503 狀態碼:

提示

這兩個方法可以個別使用或結合使用。

  • 變更自動調整建立新複本的使用率層級。 您可以將 autoscale_target_utilization 設定為較低的值,來調整使用率目標。

    重要

    此變更不會「加快」建立複本的速度。 相反地,其會以較低的使用率閾值建立複本。 若不等到服務使用率達 70% 就將值變更為 30%,會在使用率達 30% 時建立複本。

    如果 Web 服務已使用目前最多的複本,但您仍看到 503 狀態碼,請增加 autoscale_max_replicas 值,增加複本的數目上限。

  • 變更最低複本數目。 增加最少複本數可提供較大的集區來處理傳入尖峰。

    若要增加最少的複本數目,請將 autoscale_min_replicas 設定為較高的值。 您可以使用下列程式碼來計算所需的複本數,並使用專案的特定值來取代這些值:

    from math import ceil
    # target requests per second
    targetRps = 20
    # time to process the request (in seconds)
    reqTime = 10
    # Maximum requests per container
    maxReqPerContainer = 1
    # target_utilization. 70% in this example
    targetUtilization = .7
    
    concurrentRequests = targetRps * reqTime / targetUtilization
    
    # Number of container replicas
    replicas = ceil(concurrentRequests / maxReqPerContainer)
    

    注意

    如果您收到的要求尖峰超過新的最小複本可以處理的數目,您可能會再次收到 503 狀態碼。 例如,隨著服務的流量增加,您可能需要增加最小複本數。

如需有關設定 autoscale_target_utilizationautoscale_max_replicasautoscale_min_replicas 的詳細資訊,請參閱 AksWebservice 模組參考。

HTTP 狀態碼 504

504 狀態碼表示要求已逾時。預設的逾時值為 1 分鐘。

您可以修改 score.py 來移除不必要的呼叫,以增加逾時時間或嘗試加快服務速度。 如果這些動作未修正問題,請使用本文中的資訊偵錯 score.py 檔案。 程式碼可能處於無回應狀態或無限迴圈。

其他錯誤訊息

針對下列錯誤採取這些動作:

錯誤 解決方法
409 衝突錯誤 當有作業已在進行時,該相同 Web 服務上的任何新作業會傳回 409 衝突錯誤。 例如,如果建立或更新 Web 服務作業正在進行,但您觸發新的刪除作業,它會擲回錯誤。
部署 Web 服務時,映像建置失敗 將 "pynacl==1.2.1" 當成 pip 相依性新增到 Conda 檔案,以用於映像設定
['DaskOnBatch:context_managers.DaskOnBatch', 'setup.py']' died with <Signals.SIGKILL: 9> 將部署中所使用 VM 的 SKU 變更為具有更多記憶體的 SKU。
FPGA 失敗 取得 FPGA 配額的要求和核准前,您不能在 FPGA 上部署模型。 若要要求存取權,請填妥配額要求表單:https://aka.ms/aml-real-time-ai

進階偵錯

您可能需要以互動方式來對模型部署中包含的 Python 程式碼進行偵錯。 例如,如果輸入指令碼失敗,而其他記錄無法判斷原因。 藉由使用 Visual Studio Code 和 debugpy,您可以連結至在 Docker 容器內執行的程式碼。

如需詳細資訊,請造訪 VS Code 中的互動式偵錯指南

模型部署使用者論壇

下一步

深入了解部署: