返回文章列表

Kubernetes 擴充套件 TorchServe Sidecar 模式

本文探討在 Kubernetes 中擴充套件 TorchServe 的挑戰,並提出使用 Sidecar 模式的解決方案。Sidecar 容器負責代理預測請求、下載模型檔案並註冊到

容器技術 機器學習

在 Kubernetes 佈署中擴充套件 TorchServe 時,常面臨負載平衡與模型註冊、模型儲存目錄管理以及模型負載平衡等挑戰。Sidecar 模式提供了一個有效的解決方案,透過在 TorchServe Pod 中引入一個輔助容器,Sidecar 負責代理預測請求、下載模型檔案並將其存入分享磁碟,接著註冊模型到 TorchServe 容器。此模式簡化了模型管理,並允許負載平衡器有效地分散預測工作負載,同時提升資源利用率。更進一步地,本文也探討了模型服務與模型伺服器兩種方法的選擇,並介紹 TensorFlow Serving 與 Triton Inference Server 等開源工具,分析其架構、功能與模型檔案格式,提供更全面的模型服務佈署參考。

在 Kubernetes 中擴充套件 TorchServe

在我們的範例服務中,為了展示目的,我們執行一個單一的 TorchServe 容器作為預測後端,但在生產環境中並非如此。擴充套件 TorchServe 面臨以下挑戰:

挑戰與解決方案

  1. 負載平衡器使得 TorchServe 模型註冊困難:在 TorchServe 中,模型檔案需要先註冊到 TorchServe 伺服器才能使用。但在生產環境中,TorchServe 例項被置於網路負載平衡器後面,因此我們只能向負載平衡器傳送預測請求,並讓它將請求路由到隨機的 TorchServe 例項。這使得模型註冊變得困難,因為我們無法指定哪個 TorchServe 例項服務於哪個模型。

  2. 每個 TorchServe 例項都需要有模型儲存目錄來載入模型:模型檔案需要在註冊前放入模型儲存目錄。多個 TorchServe 例項使得模型檔案複製變得難以管理,因為我們需要知道每個 TorchServe 例項的 IP 位址或 DNS。

  3. 需要在 TorchServe 例項之間平衡模型:讓每個 TorchServe 例項載入每個模型檔案不是一個好主意,這會浪費大量的計算資源。我們應該將負載均勻地分散在不同的 TorchServe 例項上。

為瞭解決這些挑戰並擴充套件 TorchServe 後端,我們可以在 Kubernetes 中引入「Sidecar」模式。圖 7.7 說明瞭整體概念。

Sidecar 模式的應用

圖 7.7 在 TorchServe Pod 中新增一個代理容器,以擴充套件 TorchServe 在 Kubernetes 中的應用。

Sidecar 容器功能

  • 代理(Proxy):接收預測請求並轉發給 TorchServe 容器。
  • 模型下載器(Model Downloader):下載模型檔案並存入分享磁碟(模型儲存)。

工作流程

  1. 預測請求首先到達代理容器。
  2. 代理下載模型檔案並將其輸入到分享磁碟(模型儲存)。
  3. 代理將模型註冊到 TorchServe 容器,並將推理請求轉換為 TorchServe 格式。
  4. TorchServe 容器執行模型服務並將結果傳回給代理。
  5. 代理容器將預測回應傳回給使用者。

使用 Sidecar 的好處

  • 無需擔心將預測請求傳送到沒有註冊相應模型的 TorchServe 例項。
  • 簡化資源管理,因為現在可以依賴負載平衡器在 TorchServe Pods 之間分散預測工作負載(模型)。
  • 透過在所有 TorchServe Pods 之間分享磁碟,可以分享所有 TorchServe 例項的模型儲存,從而減少模型下載時間並節省網路頻寬。

模型伺服器與模型服務的比較

在設計模型服務應用程式時,我們需要做出的第一個決定是在模型伺服器方法和模型服務方法之間進行選擇。如果選擇不當,我們的服務應用程式要麼難以使用和維護,要麼需要不必要地花費大量時間來構建。

Sidecar 模式的通用性

Sidecar 模式是執行不同模型伺服器容器的共同解決方案。無論是 TensorFlow Serving、TorchServe、Triton 等不同的模型伺服器實作,其設計理念都是相似的。它們都採用黑盒方法,需要特定的模型格式和一些模型管理來啟用模型服務。

何時選擇模型服務或模型伺服器

  • 單一應用場景:模型服務方法更簡單、更容易構建和維護。
  • 模型服務平台場景:當系統需要支援多種型別的模型時,模型伺服器方法是無可爭議的最佳選擇。

開源模型服務工具介紹

有多種開源模型服務工具可供選擇,包括 TensorFlow Serving、TorchServe、Triton 和 KServe。所有這些工具都可以直接使用,並適用於生產環境。

主要功能與適用場景

由於每種工具都有詳細的檔案,我們將討論保持在一般層面,關注它們的整體設計、主要功能和適用的使用場景。這應該足以作為進一步探索的起點。

7.4 實際模型服務工具實戰

7.4.1 TensorFlow Serving

TensorFlow Serving(https://www.tensorflow.org/tfx/guide/serving)是一個可自訂的獨立網頁系統,用於在生產環境中服務 TensorFlow 模型。TensorFlow Serving 採用模型伺服器方法,能夠以相同的伺服器架構和 API 服務所有型別的 TensorFlow 模型。

特色功能

TensorFlow Serving 提供以下特色功能:

  • 能夠服務多個模型或同一模型的多個版本
  • 與 TensorFlow 模型有開箱即用的整合
  • 自動發現新模型版本並支援不同的模型檔案來源
  • 統一的 gRPC 和 HTTP 端點用於模型推斷
  • 支援批次預測請求和效能調校
  • 具有可擴充的設計,可自訂版本政策和模型載入

高階架構

在 TensorFlow Serving 中,模型由一個或多個可服務物件(servables)組成。可服務物件是執行計算的底層物件(例如查詢或推斷);它是 TensorFlow Serving 中的核心抽象概念。來源(Sources)是找到並提供可服務物件的外掛模組。載入器(Loader)標準是載入和解除安裝可服務物件的 API。管理員(Manager)處理可服務物件的完整生命週期,包括載入、解除安裝和服務可服務物件。

TensorFlow Serving 模型檔案

TensorFlow Serving 需要將模型儲存為 SavedModel(http://mng.bz/9197)格式。我們可以使用 tf.saved_model.save(model, save_path) API 將模型儲存為 SavedModel 格式。SavedModel 是一個目錄,包含序列化的簽章和執行它們所需的狀態,包括變數值和詞彙表。例如,一個 SavedModel 目錄包含兩個子目錄 assetsvariables,以及一個檔案 saved_model.pb

# 儲存模型的範例程式碼
MODEL_DIR = 'tf_model'
version = "1"
export_path = os.path.join(MODEL_DIR, str(version))
model.save(export_path, save_format="tf")

模型服務

由於 TensorFlow 的 SavedModel 檔案可以直接載入到 TensorFlow Serving 程式中,因此執行模型服務非常簡單。一旦服務程式啟動,我們就可以將模型檔案複製到 TensorFlow Serving 的模型目錄中,然後立即傳送 gRPC 或 REST 預測請求。以下是一個預測請求的範例:

# 傳送預測請求到本地 TensorFlow Serving Docker 容器
json_response = requests.post('http://localhost:8501/v1/models/model_a/versions/1:predict',
                              data=data, headers=headers)

對於載入多個模型和同一模型的多個版本到服務伺服器,我們可以在模型設定檔中設定模型的版本,如下所示:

model_config_list {
  config {
    name: 'model_a'
    base_path: '/models/model_a/'
    model_platform: 'tensorflow'
    model_version_policy {
      specific {
        versions: 2
        versions: 3
      }
    }
  }
  config {
    name: 'model_b'
    base_path: '/models/model_b/'
    model_platform: 'tensorflow'
  }
}
7.4.2 TorchServe

TorchServe(https://pytorch.org/serve/)是一個高效能、彈性和易於使用的工具,用於服務 PyTorch Eager Mode 和 TorchScripted 模型(PyTorch 模型的中間表示,可以在高效能環境中執行,例如 C++)。與 TensorFlow Serving 類別似,TorchServe 採用模型伺服器方法,以統一的 API 服務所有型別的 PyTorch 模型。不同之處在於 TorchServe 提供了一組管理 API,使模型管理非常方便和彈性。例如,我們可以透過程式設計方式註冊和登出模型或不同版本的模型,並且可以擴充套件和縮減服務工作人員以處理模型和不同版本的模型。

7.4 開源模型服務工具巡覽

高層架構

TorchServe 伺服器由三個主要元件組成:前端、後端和模型儲存函式庫。前端負責處理 TorchServe 的請求和回應,並管理模型的生命週期。後端是一組模型工作者,負責在模型上執行實際的推論。模型儲存函式庫是一個目錄,用於存放所有可載入的模型,可以是雲端儲存資料夾或本地主機資料夾。圖 7.9 展示了 TorchServe 例項的高層架構。

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 高層架構

rectangle "請求/回應" as node1
rectangle "載入模型" as node2
rectangle "存放模型" as node3

node1 --> node2
node2 --> node3

@enduml

此圖示展示了 TorchServe 的基本架構,包括前端、後端和模型儲存函式庫之間的互動關係。

內容解密:

  1. 前端負責接收和處理外部請求,並將請求路由到後端的模型工作者。
  2. 後端的工作者負責執行模型的推論運算。
  3. 模型儲存函式庫提供了模型檔案的存放和管理。

特色功能

TorchServe 提供以下特色功能:

  • 可同時服務多個模型或同一模型的多個版本
  • 統一的 gRPC 和 HTTP 端點,用於模型推論
  • 支援批次預測請求和效能調校
  • 支援工作流程,將 PyTorch 模型和 Python 函式組合在序列或平行管線中
  • 提供管理 API,用於註冊/登出模型和擴充套件/縮減工作者數量
  • 處理模型版本控制,用於 A/B 測試和實驗

內容解密:

  1. TorchServe 的多模型支援使其能夠靈活地服務多種不同的 AI 應用。
  2. 統一的端點簡化了客戶端的開發和整合工作。
  3. 批次預測和效能調校功能可以顯著提升模型的推論效率。

TorchServe 模型檔案

純 PyTorch 模型無法直接載入到 TorchServe 伺服器。TorchServe 需要將所有模型封裝成 .mar 檔案。有關如何建立 .mar 檔案的詳細範例,請參閱第 7.2.6 節。

模型服務

以下程式碼片段列出了使用 TorchServe 進行模型推論的五個一般步驟。有關具體範例,請檢視我們的範例意圖分類別預測器的 README 檔案(http://mng.bz/WA8a)。

# 1. 建立 TorchServe 的模型儲存目錄,並將模型檔案複製到該目錄
mkdir -p /tmp/model_store/torchserving
cp sample_models/intent.mar /tmp/model_store/torchserving

# 2. 執行 TorchServe 的 Docker 容器
docker pull pytorch/torchserve:0.4.2-cpu
docker run --rm --shm-size=1g \
--ulimit memlock=-1 \
--ulimit stack=67108864 \
-p8080:8080 \
-p8081:8081 \
-p8082:8082 \
-p7070:7070 \
-p7071:7071 \
--mount type=bind,source=/tmp/model_store/torchserving,target=/tmp/models \
pytorch/torchserve:0.4.2-cpu torchserve --model-store=/tmp/models

# 3. 透過 TorchServe 的管理 API 註冊意圖分類別模型
curl -X POST "http://localhost:8081/models?url=intent_1.mar&initial_workers=1&model_name=intent"

# 4. 使用預設版本查詢意圖分類別模型
curl --location --request GET 'http://localhost:8080/predictions/intent' \
--header 'Content-Type: text/plain' \
--data-raw 'make a 10 minute timer'

# 5. 使用指定版本(1.0)查詢意圖分類別模型
curl --location --request GET 'http://localhost:8080/predictions/intent/1.0' \
--header 'Content-Type: text/plain' \
--data-raw 'make a 10 minute timer'

內容解密:

  1. 第一步建立了本地的模型儲存目錄,並將意圖分類別模型的 .mar 檔案複製到該目錄中。
  2. 第二步啟動了 TorchServe 的 Docker 容器,並將本地的模型儲存目錄掛載到容器內的 /tmp/models 目錄。
  3. 第三步透過管理 API 將意圖分類別模型註冊到 TorchServe。
  4. 第四步和第五步分別展示瞭如何使用預設版本和指定版本(1.0)查詢已註冊的意圖分類別模型。

REVIEW

TorchServe 是針對 PyTorch 模型的生產級模型服務解決方案,專為高效能推論和生產案例設計。TorchServe 的管理 API 為自定義模型佈署策略提供了很大的靈活性,並允許在每個模型的級別上管理計算資源。

與 TensorFlow Serving 類別似,TorchServe 的主要缺點是它是一個供應商鎖定的解決方案,只支援 PyTorch 模型。因此,如果您正在尋找一個與訓練框架無關的方法,TorchServe 不是您的選擇。

Triton Inference Server 簡介

Triton Inference Server(https://developer.nvidia.com/nvidia-triton-inference-server)是由 NVIDIA 開發的開源推論伺服器。它提供了一個針對 CPU 和 GPU 都進行了最佳化的雲端和邊緣推論解決方案。Triton 支援 HTTP/REST 和 gRPC 協定,允許遠端客戶端請求由伺服器管理的任何模型的推論。

Triton 的主要優勢之一是其訓練框架相容性。與 TensorFlow Serving 只支援 TensorFlow 模型、TorchServe 只支援 PyTorch 模型不同,Triton 伺服器可以服務從幾乎任何框架訓練出的模型,包括 TensorFlow、TensorRT、PyTorch、ONNX 和 XGBoost。

內容解密:

  1. Triton Inference Server 能夠在任何根據 GPU 或 CPU 的基礎架構(雲端、資料中心或邊緣)上,從本地儲存、Google Cloud Platform 或 Amazon Simple Storage Service(Amazon S3)載入模型檔案。
  2. Triton 在 GPU 上平行執行模型,以最大化吞吐量和利用率;支援 x86 和 ARM 處理器架構。

Triton Inference Server:高效能模型服務的關鍵技術

Triton Inference Server 是由 NVIDIA 開發的開源模型服務工具,專為高效能模型推理設計。它支援多種深度學習框架,包括 PyTorch、TensorFlow、TensorRT 和 ONNX Runtime 等,能夠在單一 GPU 或 CPU 上同時執行多個模型。

高階架構

Triton Inference Server 的高階架構如圖 7.10 所示。所有的推理請求都以 REST 或 gRPC 請求的形式傳送,並在內部轉換為 C API 呼叫。模型從模型儲存函式庫(model repository)載入,這是一個根據檔案系統的儲存函式庫,可以視為資料夾或目錄。

Triton 的特色功能

Triton 提供了以下特色功能:

  • 支援所有主要深度學習和機器學習框架後端。
  • 能夠在單一 GPU 或 CPU 上同時執行多個模型,並在多 GPU 伺服器上自動建立每個模型的例項以提高利用率。
  • 最佳化推理服務以實作實時推理、批次推理和串流推理,並支援模型整合(model ensemble)。
  • 處理動態批次輸入請求以提高吞吐量和利用率。
  • 能夠在生產環境中即時更新模型而無需重新啟動推理伺服器或幹擾應用程式。
  • 使用模型分析器(model analyzer)自動找到最佳模型組態以最大化效能。

Triton 模型檔案

每個 Triton 模型必須包含一個模型組態(model configuration),提供有關模型的必要和可選資訊。通常,這是一個名為 config.pbtxt 的檔案,指定為 ModelConfig protobuf。下面是一個 PyTorch 模型的簡單模型組態範例:

platform: "pytorch_libtorch"
input [
  {
    name: "input0"
    data_type: TYPE_FP32
    dims: [16]
  },
  {
    name: "input1"
    data_type: TYPE_FP32
    dims: [16]
  }
]
output [
  {
    name: "output0"
    data_type: TYPE_FP32
    dims: [16]
  }
]

內容解密:

此組態檔案指定了模型的輸入和輸出資料結構,包括資料型別和維度。其中,platform 指定了模型的後端框架為 PyTorch LibTorch,inputoutput 分別定義了模型的輸入和輸出資料的名稱、資料型別和維度。

TorchScript:PyTorch 模型的序列化

Triton 需要 PyTorch 模型以 TorchScript 的形式儲存。TorchScript 是 PyTorch 中的一種機制,可以將 PyTorch 模型序列化並最佳化。下面是一個將 PyTorch 模型轉換為 TorchScript 的程式碼範例:

# 1. 定義模型的例項
model = ...TorchModel()

# 2. 將模型切換到評估模式
model.eval()

# 3. 建立模型的 forward() 方法的範例輸入
example = torch.rand(1, 3, 224, 224)

# 4. 使用 torch.jit.trace 生成 torch.jit.ScriptModule
traced_script_module = torch.jit.trace(model, example)

內容解密:

此程式碼範例展示瞭如何將 PyTorch 模型轉換為 TorchScript。首先,需要定義模型的例項並將其切換到評估模式。然後,建立模型的 forward() 方法的範例輸入。最後,使用 torch.jit.trace 將模型追蹤並生成 torch.jit.ScriptModule,即 TorchScript 模型。這個過程使得 PyTorch 模型可以被 Triton 推理伺服器載入並執行高效能推理。