[IND] 7 分鐘閱讀OraCore 編輯部

怎麼降低 AI 模型部署摩擦

這篇教你把訓練好的 AI 模型穩定送進 production,透過 ONNX、TensorRT、動態輸入、版本鎖定與 Triton 檢查,建立可重複的部署流程。

分享 LinkedIn
怎麼降低 AI 模型部署摩擦

這篇教你把訓練好的 AI 模型穩定送進 production,透過 ONNX、TensorRT、動態輸入、版本鎖定與 Triton 檢查,建立可重複的部署流程。

這篇給 ML 工程師、平台團隊與後端開發者看,目標是把已訓練模型從 notebook 送到 production 時常見的匯出失敗、runtime 不一致與延遲落差降到最低。

照著做完,你會得到一條可重複的 serving 流程:先驗證匯出,再處理動態輸入形狀,接著鎖定相容版本,最後部署可量測的推論服務。

開始之前

訂閱 AI 趨勢週報

每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。

不會寄垃圾信,隨時可取消。

Step 1: 匯出乾淨的 ONNX 模型

目的:先產出可上線的圖,移除訓練專用行為,並在進入 serving 前把匯出問題攔下來。

怎麼降低 AI 模型部署摩擦
python export.py 
  --model checkpoints/model.pt 
  --output model.onnx 
  --opset 17

把匯出流程同時放進本機與 CI,並在轉換前先做常數折疊、移除 dropout、teacher-forcing 分支或其他訓練專用路徑。如果匯出失敗,應回頭修正 source model 的不支援 op 或 tensor shape 假設,不要等到部署階段才補救。

你應該看到一個有效的 ONNX 檔案,以及沒有 unsupported-operation 錯誤的匯出紀錄。

Step 2: 用 TensorRT 轉成推論引擎

目的:把 ONNX 圖轉成 GPU 最佳化 engine,讓 TensorRT 幫你融合 layer 並挑選較有效率的 kernel。

怎麼降低 AI 模型部署摩擦
trtexec 
  --onnx=model.onnx 
  --saveEngine=model.plan 
  --fp16

先用 TensorRT 驗證圖能否乾淨轉換,再比較 FP16 與 FP32,確認精度取捨符合你的工作負載。如果 TensorRT 回報不支援的 layer,就決定要改寫模型、替換運算,或補一個 plugin。

你應該看到已儲存的 engine 檔,以及列出精度選擇與 layer 最佳化結果的 build summary。

Step 3: 為不支援的運算加入 plugin

目的:當 TensorRT 不能原生支援某個 layer 或自訂 operator 時,讓整條 pipeline 繼續往下走。

// Custom TensorRT plugin skeleton
class MyPlugin : public nvinfer1::IPluginV2DynamicExt {
  // implement configurePlugin, enqueue, getOutputDimensions
};

針對標準 TensorRT layer 無法表達的運算,實作必要的 C++ 或 CUDA plugin。寫新 code 之前,先搜尋 TensorRT plugin 生態與既有 sample,避免重複造輪子。把 plugin 介面維持得越窄越好,這樣才容易測試與版本化。

你應該看到模型在連結 plugin 後成功 build,且 inference 回傳符合預期的 tensor shapes。

Step 4: 設定動態輸入 profile

目的:支援可變 batch size 或 sequence length,而不用為每一種請求型態重編 engine。

trtexec 
  --onnx=model.onnx 
  --minShapes=input:1x3x224x224 
  --optShapes=input:8x3x224x224 
  --maxShapes=input:32x3x224x224

建立符合真實流量的 optimization profiles,不要只抓最大 tensor。如果工作負載有明顯不同模式,例如互動式小請求與大批次作業,就建立多個 profile,讓 server 能選到較合適的配置。這通常能減少 padding 浪費,也避免昂貴的 engine rebuild。

你應該看到同一個 engine 支援多種輸入大小,而且 benchmark 在 request dimension 改變時不再觸發重新編譯。

Step 5: 鎖定 runtime 版本並部署 Triton

目的:把模型放進一致的 inference 環境,消除版本漂移。

docker run --gpus all --rm -p 8000:8000 -p 8001:8001 -p 8002:8002 
  -v $PWD/model_repository:/models 
  nvcr.io/nvidia/tritonserver:latest-trtllm-python-py3

使用預建容器或鎖定的 image tag,讓 CUDA、TensorRT 與 server runtime 保持一致。在 model repository 中,明確定義 model version、backend 與 config。如果你需要 dynamic batching、concurrent versions 或 multi-GPU scaling,Triton 可以把這些控制集中在同一處。

你應該看到 Triton 正常啟動,並且健康檢查與 inference endpoints 都能回應,沒有 library mismatch 警告。

Step 6: 量測吞吐與延遲

目的:確認部署達到 production 目標,並在 rollout 前找出下一個瓶頸。

trtexec 
  --loadEngine=model.plan 
  --warmUp=200 
  --duration=60 
  --streams=4

用 trtexec、Nsight Systems 或 Model Analyzer 量測 engine,檢查 batch size、concurrency 與 instance count。一次只調一個變數,才看得出某個變更是提升吞吐、拖慢延遲,還是只是把工作從 CPU 移到 GPU。把 baseline 與調整後的結果寫進部署紀錄。

你應該看到穩定的延遲數字、更高的 GPU 使用率,以及 serving 設定的前後對照結果。

指標基準/優化前結果/優化後
模型匯出可靠性常在 ONNX 轉換時失敗CI 驗證匯出,減少部署驚喜
輸入處理形狀改變就要重新編譯動態 optimization profile 重用同一個 engine
runtime 一致性不同環境容易出現版本不符鎖定容器與依賴版本
服務效率batch 與 concurrency 未調整經量測的 Triton 部署與吞吐結果

常見錯誤

  • 把 export 驗證留到 release day 才做。修法:每次模型變更都在 CI 跑 ONNX export 與 TensorRT build 檢查。
  • 所有流量共用一個過大的 dynamic profile。修法:依真實流量分段建立 profile,例如互動式與批次作業分開。
  • local、staging、production 混用不同 library 版本。修法:使用鎖定的 container image,並固定精確的 framework 與 runtime 版本。

接下來可以看什麼

當這條 pipeline 穩定後,可以再往 custom backend、multi-model routing 與 Model Analyzer 自動調參深入,讓不同團隊與工作負載都能共用同一套 serving 標準。