效能指南¶
如果您有興趣最佳化使用 TorchServe 提供的 PyTorch 模型的記憶體用量、延遲或輸送量,這份指南非常適合您。
我們也建立了一份快速檢查清單,列出可以在本頁涵蓋範圍之外嘗試的其他事項。您可以在此處找到該清單。
最佳化 PyTorch¶
有許多技巧可以最佳化用於生產的 PyTorch 模型,包括但不限於蒸餾、量化、融合、剪枝、設定環境變數,我們鼓勵您進行基準測試,看看哪種方法最適合您。
通常很難最佳化模型,最簡單的方法是匯出到某些執行階段環境,例如 ORT、TensorRT、IPEX 或 FasterTransformer。我們在 TorchServe github 頁面上有許多關於如何整合這些執行階段環境的範例。如果您的最愛執行階段環境未受支援,請隨時開啟 PR。
torch.compile
從 PyTorch 2.0 開始,torch.compile
為大量模型提供現成的加速(約 1.8 倍)。您可以參考此儀表板,它會每晚追蹤此情況。
已使用 torch.compile
完全最佳化的模型顯示效能提升高達 10 倍
當使用較小的批次大小時,將 mode="reduce-overhead"
與 torch.compile
搭配使用可以提高效能,因為它使用了 CUDA 圖形
您可以在此處找到 torch.compile
與 TorchServe 的所有範例
有關 torch.compile
GenAI 範例的詳細資訊,請參閱此連結
ONNX 和 ORT 支援
TorchServe 原生支援 ONNX 模型,這些模型可以透過 ORT 載入,以進行加速的 CPU 和 GPU 推論。ONNX 的運作方式與一般的 PyTorch 模型略有不同,在執行轉換時,您需要明確設定和命名輸入和輸出維度。請參閱此範例。
從高層次來看,TorchServe 允許您執行以下操作:
封裝序列化的 ONNX 權重
torch-model-archiver --serialized-file model.onnx ...
使用
ort_session = ort.InferenceSession(self.model_pt_path, providers=providers, sess_options=sess_options)
從base_handler.py
載入這些權重,這支援 CPU 和 GPU 推論的合理預設值允許您定義自訂的預處理和後處理函數,以您 ONNX 模型期望的格式傳入資料,並使用自訂處理常式
若要在 TorchServe Docker 上使用 ONNX 與 GPU,我們需要使用 NVIDIA CUDA 執行階段作為基礎映像來建立映像,如此處所示
TensorRT
TorchServe 也支援透過 TensorRT 優化的模型。若要利用 TensorRT 執行階段,您可以依照這些指示轉換您的模型。完成後,您將擁有序列化的權重,可以使用 torch.jit.load()
載入。
轉換後,PyTorch 對待 Torchscript 模型和 TensorRT 模型的方式沒有任何差異。
Better Transformer
PyTorch 的 Better Transformer 實作了 torch.nn.TransformerEncoder
的向後相容快速路徑,用於 Transformer Encoder 推論,且不需要模型作者修改其模型。對於許多常見的執行情境,BetterTransformer 的改進可以在速度和吞吐量上超過 2 倍。您可以在這裡和這裡找到更多關於 Better Transformer 的資訊。
優化 TorchServe¶
如果您想改善 TorchServe 的效能,主要應該變更 config.properties
中的 batch_size
和 batch_delay
設定。更大的批次大小意味著更高的吞吐量,但會以降低延遲為代價。
第二重要的設定是 worker 的數量和 GPU 的數量,這將對 CPU 和 GPU 效能產生巨大影響。
並行性和 Worker 數量
TorchServe 公開了一些配置,允許使用者配置 CPU 和 GPU 上的 worker 執行緒數量。有一個重要的配置屬性可以根據工作負載加速伺服器。*注意:以下屬性在繁重的工作負載下影響更大。*
CPU 上的 TorchServe
如果在 CPU 上使用 TorchServe,您可以透過在 config.properties
中設定以下內容來提高效能
cpu_launcher_enable=true
cpu_launcher_args=--use_logical_core
這些設定透過啟動器核心綁定顯著提高效能。這種改進背後的理論在 這篇部落格 中討論,可以快速總結如下:
在啟用超執行緒的系統中,透過核心綁定將執行緒親和性設定為僅物理核心,以避免邏輯核心。
在具有 NUMA 的多插槽系統中,透過核心綁定將執行緒親和性設定為特定插槽,以避免跨插槽遠端記憶體存取。
GPU 上的 TorchServe
有一個名為 number_of_gpu
的配置屬性,它告訴伺服器每個模型使用特定數量的 GPU。在我們向伺服器註冊多個模型的情況下,這將適用於所有註冊的模型。如果將此值設定為較低的值(例如:0 或 1),將導致 GPU 未充分利用。相反,將其設定為較高的值(>= 系統上可用的最大 GPU 數量)會導致每個模型產生盡可能多的 worker。顯然,這將導致 GPU 不必要的爭用,並可能導致執行緒到 GPU 的次佳排程。
ValueToSet = (Number of Hardware GPUs) / (Number of Unique Models)
NVIDIA MPS
雖然 NVIDIA GPU 允許在 CUDA 核心上執行多個程序,但這也有其自身的缺點,即
核心的執行通常是序列化的
每個程序都會建立自己的 CUDA 環境,這會佔用額外的 GPU 記憶體
為了規避這些缺點,您可以利用 NVIDIA Multi-Process Service (MPS) 來提高效能。您可以在 這裡 找到更多關於如何將 NVIDIA MPS 與 TorchServe 結合使用的資訊。
NVIDIA DALI
NVIDIA Data Loading Library (DALI) 是一個用於資料載入和預處理的函式庫,旨在加速深度學習應用程式。它可以作為流行的深度學習框架中內建的資料載入器和資料迭代器的可攜式替代品。DALI 提供了一系列高度優化的構建模組,用於載入和處理影像、視訊和音訊資料。您可以在 這裡 找到 DALI 優化與 TorchServe 整合的範例。
效能評估¶
為了更容易比較各種模型和 TorchServe 配置,我們新增了一些輔助腳本,可以輸出效能資料,例如 p50、p90、p99 延遲,並以清晰的報告呈現,請參考這裡。這些腳本主要要求您透過 JSON 或 YAML 確定一些配置。您可以在 這裡 找到更多關於 TorchServe 效能評估的資訊。
效能分析¶
TorchServe 原生支援 PyTorch profiler,它可以幫助您找到程式碼中的效能瓶頸。
如果您建立了自訂的 handle
或 initialize
方法覆寫了 BaseHandler,您必須定義 self.manifest
屬性才能夠執行 _infer_with_profiler
。
export ENABLE_TORCH_PROFILER=TRUE
請訪問此連結以了解有關 PyTorch profiler 的更多訊息。
更多資源¶
在 Animated Drawings 應用程式上使用 TorchServe
如需深入了解如何在應用程式中微調 TorchServe 效能,請查看這篇文章。這裡顯示的案例研究使用了 Meta 的 Animated Drawings 應用程式來提高 TorchServe 效能。
效能檢查清單
我們也建立了一份快速檢查清單,列出可以在本頁涵蓋範圍之外嘗試的其他事項。您可以在此處找到該清單。