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

這篇教你把訓練好的 AI 模型穩定送進 production,透過 ONNX、TensorRT、動態輸入、版本鎖定與 Triton 檢查,建立可重複的部署流程。
這篇給 ML 工程師、平台團隊與後端開發者看,目標是把已訓練模型從 notebook 送到 production 時常見的匯出失敗、runtime 不一致與延遲落差降到最低。
照著做完,你會得到一條可重複的 serving 流程:先驗證匯出,再處理動態輸入形狀,接著鎖定相容版本,最後部署可量測的推論服務。
開始之前
訂閱 AI 趨勢週報
每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。
不會寄垃圾信,隨時可取消。
- NVIDIA GPU 與 CUDA 相容驅動
- Python 3.10+
- Docker 24+
- PyTorch 2.2+
- ONNX 1.15+
- TensorRT 10+
- 可讀取 TensorRT 文件 與 TensorRT GitHub repo
- 可讀取 Dynamo-Triton 文件 與 Triton Inference Server GitHub repo
- 選用但建議:NGC 帳號,用來拉預建容器
Step 1: 匯出乾淨的 ONNX 模型
目的:先產出可上線的圖,移除訓練專用行為,並在進入 serving 前把匯出問題攔下來。

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。

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 標準。