圖:“Rust 的吉祥物 Ferris the Crab 透過 ort 搭建起 Rust 和 ONNX 之間的橋樑”,gemini-2.5-flash-preview,2025年09月22日。
看著 Python 在 AI 領域獨領風騷,心想:「我什麼時候才能用我心愛的 Rust 來駕馭那些強大的神經網路模型呢?」
ort
:我來解救你!
ort crate 正是 ONNX Runtime 的 Rust 綁定 (binding),它讓我們能用 Rust 的方式,安全、高效地呼叫 ONNX Runtime 引擎,執行來自 AI 世界的 ONNX 模型。今天,我們就跟著這位螃蟹技師,一步步搭建這座橋樑,並實際運行一個物件辨識(Object Detection)的應用程式!
[dependencies]
ort = { version = "1.16.3", features = ["download-binaries"] }
重要提示: ort
crate 需要你的系統上安裝了 ONNX Runtime 函數庫。最簡單的方式是從 ONNX Runtime 的 GitHub Releases 下載對應你作業系統的預編譯版本,並將其解壓縮。接著,設定環境變數 ONNXRUNTIME_LIB_DIR 指向函式庫所在的 lib 資料夾。
若從 Python 生態系過來嚐鮮的 AI 技術愛好者,相信以下操作一定再熟悉不過了,就是起手式!一樣的,我們要站在巨人的肩膀上,ultralytics
早已是 AI 生態系中相當成熟的 YOLO 電腦視覺模型函數庫。我們在接下來的 AI 應用中並不會訓練模型,我們將著重在推理的落地上,故第一步我們將利用 ultralytics
這一工具進行模型下載和驗證。
pip install -U ultralytics
然後,將所需的 YOLOv8/YOLO11 模型匯出為 ONNX 格式,詳細資訊請參閱 Model Export with Ultralytics YOLO。
# 匯出具有動態形狀的 ONNX 模型(建議使用以提高靈活性)
yolo export model=yolo11s.pt format=onnx simplify dynamic
yolo export model=yolo11s-cls.pt format=onnx simplify dynamic
yolo export model=yolo11s-pose.pt format=onnx simplify dynamic
yolo export model=yolo11s-seg.pt format=onnx simplify dynamic
/// 模型驗證函數,用於驗證 ONNX 模型載入和配置 (Model validation function to verify ONNX model loading and configuration)
fn validate_onnx_model(config: &config::Config) -> Result<(), Box<dyn std::error::Error>> {
println!("🔍 驗證 ONNX 模型載入 (Validating ONNX Model Loading)");
println!("========================");
// 載入 YOLO 模型 (Load the YOLO model)
println!("📦 載入模型 (Loading model): {}", config.model);
let model = YOLOv8::new(config.clone())?;
println!("✅ 模型載入成功! (Model loaded successfully!)");
// 顯示模型資訊 (Display model information)
println!("\n📊 模型資訊 (Model Information):");
println!(" 任務類型 (Task Type): {:?}", model.task);
println!(" 輸入尺寸 (Input Dimensions): {}x{}", model.width, model.height);
println!(" 批次大小 (Batch Size): {}", model.batch);
println!(" 類別數量 (Number of Classes - nc): {}", model.nc);
println!(" 關鍵點數量 (Number of Keypoints - nk): {}", model.nk);
println!(" 遮罩數量 (Number of Masks - nm): {}", model.nm);
println!(" 信心度閾值 (Confidence Threshold): {:.2}", model.conf);
println!(" IoU 閾值 (IoU Threshold): {:.2}", model.iou);
println!(" 關鍵點信心度閾值 (Keypoint Confidence Threshold): {:.2}", model.kconf);
// 顯示執行提供者 (Display execution provider)
println!("\n⚡ 執行提供者 (Execution Provider):");
println!(" 提供者 (Provider): {:?}", model.engine.ep());
// 顯示類別名稱(如果可用) (Display class names if available)
if !model.names.is_empty() {
println!("\n🏷️ 類別名稱 (Class Names - {} classes):", model.names.len());
for (i, name) in model.names.iter().enumerate() {
if i < 10 { // 顯示前 10 個類別 (Show first 10 classes)
println!(" {:2}: {}", i, name);
} else if i == 10 {
println!(" ... 還有 {} 個類別 (... and {} more classes)", model.names.len() - 10, model.names.len() - 10);
break;
}
}
} else {
println!("\n🏷️ 類別名稱 (Class Names): 模型元資料中無法取得 (Not available in model metadata)");
}
// 驗證模型後端資訊 (Verify model backend information)
println!("\n🔧 後端配置 (Backend Configuration):");
println!(" 動態批次 (Dynamic Batch): {}", model.engine.is_batch_dynamic());
println!(" 動態高度 (Dynamic Height): {}", model.engine.is_height_dynamic());
println!(" 動態寬度 (Dynamic Width): {}", model.engine.is_width_dynamic());
println!(" 資料類型 (Data Type): {:?}", model.engine.dtype());
Ok(())
}
🔍 驗證 ONNX 模型載入 (Validating ONNX Model Loading)
========================
📦 載入模型 (Loading model): model_weight/onnx/version/yolo11s.onnx
✅ 模型載入成功! (Model loaded successfully!)
📊 模型資訊 (Model Information):
任務類型 (Task Type): Detect
輸入尺寸 (Input Dimensions): 640x640
批次大小 (Batch Size): 1
類別數量 (Number of Classes - nc): 80
關鍵點數量 (Number of Keypoints - nk): 0
遮罩數量 (Number of Masks - nm): 0
信心度閾值 (Confidence Threshold): 0.30
IoU 閾值 (IoU Threshold): 0.45
關鍵點信心度閾值 (Keypoint Confidence Threshold): 0.55
⚡ 執行提供者 (Execution Provider):
提供者 (Provider): Cpu
🏷️ 類別名稱 (Class Names - 80 classes):
0: person
1: bicycle
2: car
3: motorcycle
4: airplane
5: bus
6: train
7: truck
8: boat
9: traffic light
... 還有 70 個類別 (... and 70 more classes)
🔧 後端配置 (Backend Configuration):
動態批次 (Dynamic Batch): true
動態高度 (Dynamic Height): true
動態寬度 (Dynamic Width): true
資料類型 (Data Type): Float32
今天太忙了!時間完全不夠用,先這樣!XD