搭配託管服務來使用您自有的推論程式碼 - Amazon SageMaker

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

搭配託管服務來使用您自有的推論程式碼

本節說明 Amazon 如何與執行您自己的託管服務推論程式碼的 Docker 容器 SageMaker 互動。請運用本文資訊來撰寫推論程式碼和建立 Docker 映像。

如何 SageMaker 執行您的推論影像

欲設定容器做為可執行檔來執行,請使用 Dockerfile 的 ENTRYPOINT 指示。注意下列事項:

  • 對於模型推斷, SageMaker 運行容器為:

    docker run image serve

    SageMaker 透過在影像名稱後指定serve引數,覆寫容器中的預設CMD陳述式。您在 Dockerfile 中搭配 CMD 指令提供的引數,會被 serve 引數覆寫。

     

  • SageMaker 預期所有容器都與 root 使用者一起執行。建立您的容器,使其僅使用根使用者。 SageMaker 執行容器時,沒有根層級存取權的使用者可能會造成權限問題。

     

  • 建議使用 ENTRYPOINT 指示的 exec 格式:

    ENTRYPOINT ["executable", "param1", "param2"]

    例如:

    ENTRYPOINT ["python", "k_means_inference.py"]

    ENTRYPOINT 指示的 exec 格式會直接做為可執行檔啟動,而非 /bin/sh 的子項。這使得它能夠接收SIGKILL來自 SageMaker API 操作之類SIGTERM的信號,這是一項要求。

     

    例如,當您使用 CreateEndpointAPI 建立端點時,請 SageMaker佈建端點設定所需的 ML 運算執行個體數量,這些執行個體數量是您在要求中指定的。 SageMaker 在這些執行個體上執行 Docker 容器。

     

    如果您減少支援端點的執 SageMaker 行個體數量 (透過呼叫 UpdateEndpointWeightsAndCapacitiesAPI),請執行命令,在要終止的執行個體上停止 Docker 容器。該命令會傳送出 SIGTERM 訊號,三十秒後再傳送 SIGKILL 訊號。

     

    如果您更新端點 (透過呼叫 UpdateEndpointAPI),請 SageMaker 啟動另一組 ML 運算執行個體,並在其上執行包含您的推論程式碼的 Docker 容器。然後會執行命令,將前一個 Docker 容器停止。若要停止 Docker 容器,命令會傳送 SIGTERM 訊號,30 秒後再傳送 SIGKILL 訊號。

     

  • SageMaker 使用您在CreateModel請求中提供的容器定義來設定容器的環境變數和 DNS 主機名稱,如下所示:

     

    • 它使用ContainerDefinition.Environment string-to-string地圖設置環境變量。

    • 它使用 ContainerDefinition.ContainerHostname 設定 DNS 主機名稱。

       

  • 如果您計劃使用 GPU 裝置進行模型推論 (在您的 CreateEndpointConfig 請求中指定以 GPU 為基礎的機器學習 (ML) 運算執行個體),請確保您的容器與 nvidia-docker 相容。請勿將 NVIDIA 驅動程式與映像整合成套件。如需 nvidia-docker 的詳細資訊,請參閱 NVIDIA/nvidia-docker

     

  • 您不能使用tini初始化程序作為 SageMaker容器中的入口點,因為它會被trainserve參數混淆。

如何 SageMaker 載入模型人工因素

CreateModelAPI 請求中,您可以使用ModelDataUrlS3DataSource參數來識別存放模型成品的 S3 位置。 SageMaker 將您的模型成品從 S3 位置複製到目/opt/ml/model錄,供您的推論程式碼使用。您的容器只有 /opt/ml/model 的唯讀存取權限。請勿寫入此目錄。

ModelDataUrl 必須指向 tar.gz 檔案。否則, SageMaker 將不會下載該文件。

如果您在中訓練模型 SageMaker,模型成品會儲存為 Amazon S3 中的單一壓縮 tar 檔案。如果您在外部訓練模型 SageMaker,則需要建立此單一壓縮 tar 檔案,並將其儲存在 S3 位置。 SageMaker 在容器啟動之前,將此 tar 文件解壓縮到/opt/ml/model 目錄中。

對於部署大型模型,我們建議您依照 部署未壓縮的模型

容器對推論請求應有的回應方式

若要取得推論,用戶端應用程式會傳送 POST 要求至 SageMaker端點。 SageMaker 將請求傳遞給容器,並將推論結果從容器返回給客戶端。

如需容器將收到的推論請求的詳細資訊,請參閱 Amazon SageMaker API 參考中的下列動作:

推論容器的需求

若要回應推論請求,您的容器須符合下列要求:

  • SageMaker 除了支持的POST標題以外的所有標題InvokeEndpoint。 SageMaker 可能會添加其他標題。推論容器必須能安全地忽略這類額外的標題。

  • 為了接收推論請求,容器須擁有可以監聽 8080 連接埠的 Web 伺服器,且需接受傳至 /invocations/ping 端點的 POST 請求。

  • 客戶的模型容器必須在 250 毫秒內接受插槽連線請求。

  • 客戶的模型容器必須在 60 秒內回應請求。模型本身在回應 /invocations 之前的處理時間上限為 60 秒。如果您的模型處理時間需要 50-60 秒,則 SDK 的插槽逾時應設為 70 秒。

範例 調用函式

下列範例示範容器中的程式碼如何處理推論請求。這些範例會處理用戶端應用程式使用 InvokeEndpoint 動作傳送的要求。

FastAPI

FastAPI 是使用 Python 建置 API 的 Web 架構。

from fastapi import FastAPI, status, Request, Response . . . app = FastAPI() . . . @app.post('/invocations') async def invocations(request: Request): # model() is a hypothetical function that gets the inference output: model_resp = await model(Request) response = Response( content=model_resp, status_code=status.HTTP_200_OK, media_type="text/plain", ) return response . . .

在此範例中,invocations函數會處理 SageMaker 傳送至/invocations端點的推論要求。

Flask

Flask 是使用 Python 開發 Web 應用程式的架構。

import flask . . . app = flask.Flask(__name__) . . . @app.route('/invocations', methods=["POST"]) def invoke(request): # model() is a hypothetical function that gets the inference output: resp_body = model(request) return flask.Response(resp_body, mimetype='text/plain')

在此範例中,invoke函數會處理 SageMaker 傳送至/invocations端點的推論要求。

範例 串流請求的調用函式

下列範例示範推論容器中的程式碼如何處理串流推論請求。這些範例會處理用戶端應用程式使用 InvokeEndpointWithResponseStream 動作傳送的要求。

容器處理串流推論請求時,在模型產生推論時會以遞增方式連續傳回一部分的模型推論。用戶端應用程式在可用時立即開始接收回應。該應用程式不需要等待模型產生整個回應。您可以實作串流以支援快速互動體驗,例如聊天機器人、虛擬助理和音樂產生器。

FastAPI

FastAPI 是使用 Python 建置 API 的 Web 架構。

from starlette.responses import StreamingResponse from fastapi import FastAPI, status, Request . . . app = FastAPI() . . . @app.post('/invocations') async def invocations(request: Request): # Streams inference response using HTTP chunked encoding async def generate(): # model() is a hypothetical function that gets the inference output: yield await model(Request) yield "\n" response = StreamingResponse( content=generate(), status_code=status.HTTP_200_OK, media_type="text/plain", ) return response . . .

在此範例中,invocations函數會處理 SageMaker 傳送至/invocations端點的推論要求。為了串流回應,該範例使用 Starlette 架構中的StreamingResponse 類別。

Flask

Flask 是使用 Python 開發 Web 應用程式的架構。

import flask . . . app = flask.Flask(__name__) . . . @app.route('/invocations', methods=["POST"]) def invocations(request): # Streams inference response using HTTP chunked encoding def generate(): # model() is a hypothetical function that gets the inference output: yield model(request) yield "\n" return flask.Response( flask.stream_with_context(generate()), mimetype='text/plain') . . .

在此範例中,invocations函數會處理 SageMaker 傳送至/invocations端點的推論要求。為了串流回應,該範例使用 Flask 架構中的 flask.stream_with_context 函式。

容器對運作狀態檢查 (Ping) 請求應有的回應方式

SageMaker 在下列情況下,會啟動新的推論容器:

  • 回應 CreateEndpointUpdateEndpointUpdateEndpointWeightsAndCapacities API 呼叫

  • 安全性修補程式

  • 取代狀態不佳的執行個體

容器啟動後不久, SageMaker 開始向/ping端點發送定期 GET 請求。

容器上最簡單的請求是以 HTTP 200 狀態碼和空內文做為回應。這表示容器 SageMaker 已準備好在/invocations端點接受推論要求。

如果容器在啟動後的 8 分鐘內持續回應 200 秒,並未開始通過運作狀態檢查,則新執行個體啟動會失敗。這會導CreateEndpoint致失敗,使端點處於失敗狀態。要求的更新尚未完成、UpdateEndpoint不會套用安全性修補程式,且不會取代運作狀態不良的執行個體。

雖然容器的最低標準是傳回靜態的 200,容器開發人員也能運用此功能來進行更加深入的檢查。/ping 嘗試的請求逾時為 2 秒。