模型推論最佳化檢查清單¶
此檢查清單描述診斷模型推論效能問題時應完成的一些步驟。其中一些建議僅適用於 NLP 模型(例如,確保輸入未過度填充和序列分桶),但一般原則也適用於其他模型。
一般系統最佳化¶
檢查 PyTorch、Nvidia 驅動程式和其他組件的版本,並更新到最新的相容版本。通常,已知的效能錯誤已經修復。
收集系統層級的活動日誌,以了解整體資源利用率。了解模型推論管線如何在較高層級使用系統資源非常有用,這是最佳化的第一步。即使是像 nvidia-smi 和 htop 這樣的簡單 CLI 工具也會有所幫助。
從對效能影響最大的目標開始。從系統活動日誌中應該可以清楚看出最大的瓶頸在哪裡 – 不要只關注模型推論,因為前/後處理可能很耗費資源,並且對端對端吞吐量的影響也很大。
量化並減輕慢速 I/O(例如磁碟和網路)對端對端效能的影響。雖然最佳化 I/O 超出此檢查清單的範圍,但尋找使用非同步、並行、管線化等技術來有效「隱藏」I/O 成本的方法。
對於動態長度輸入序列(例如,NLP 的轉換器)上的模型推論,請確保 tokenizer 沒有過度填充輸入。如果轉換器在訓練時填充到恆定長度(例如,512),並以相同的填充部署,則在短序列上執行時會不必要地慢(數量級)。
JPEG 格式輸入的視覺模型通常受益於 CPU 上更快的 JPEG 解碼(例如 libjpeg-turbo 和 Pillow-SIMD)以及 GPU 上更快的 JPEG 解碼(例如 torchvision.io.decode_jpeg 和 Nvidia DALI)。正如這個 範例 所示,即使在舊的 K80 GPU 上,Nvidia DALI 也比 torchvision 快約 20%。
模型推論最佳化¶
僅在其他因素(「垂手可得的果實」)經過廣泛評估和解決後,才開始模型推論最佳化。
在模型上呼叫正向傳遞之前使用
with torch.inference_mode()
上下文或在inference()
方法上使用@torch.inference_mode()
裝飾器可以提高推論效能。這是透過停用檢視追蹤和版本計數器增加來實現的。GPU 推論使用 fp16。在具有張量核心的新型 GPU 上,速度很可能會提高一倍以上,而準確度的下降可以忽略不計。從技術上講,fp16 是一種量化類型,但由於它很少因推論而遭受準確度損失,因此應始終對其進行探索。如本文章所示,使用 fp16 可以提高大型神經網路應用程式的速度。
CPU 推論使用模型量化(即 int8)。探索不同的量化選項:動態量化、靜態量化和量化感知訓練,以及諸如 Intel Neural Compressor 之類的工具,這些工具提供更精密的量化方法。值得注意的是,量化會帶來一定的準確度損失,並且在某些硬體上可能並不總能顯著提高速度,因此這可能並不總是正確的方法。
透過智慧批次處理平衡吞吐量和延遲。在滿足延遲 SLA 的同時,嘗試更大的批次大小以提高吞吐量。
嘗試最佳化的推論引擎,例如 onnxruntime、tensorRT、lightseq、ctranslate-2 等。這些引擎通常提供額外的最佳化,例如運算子融合,以及模型量化。
嘗試模型蒸餾。這更複雜,通常需要訓練資料,但潛在的收益可能很大。例如,MiniLM 在達到原始 BERT base 模型 99% 準確度的同時,速度快了 2 倍。
如果使用 CPU,您可以嘗試核心釘選。您可以在這篇部落格文章中找到更多關於如何使用它的資訊。
對於不同長度的序列上的批次處理,序列分桶可能會將吞吐量提高 2 倍。在這種情況下,序列分桶的簡單實現是在將所有輸入饋送到模型之前按序列長度對其進行排序,因為這減少了批次處理序列時不必要的填充。
雖然此檢查清單並非詳盡無遺,但瀏覽這些項目可能會幫助您從模型推論管線中榨取更多效能。