pykeio/ort · 上手攻略

  • 仓库:pykeio/ort
  • 链接:https://github.com/pykeio/ort
  • 分类:llm-infra / app(ONNX Runtime 的 Rust 绑定 + 备选纯 Rust 后端)
  • 作者:spark
  • 更新:2026-07-30

提示:仓库 README、API 文档链接均指向 ort 2.0 系列,本攻略以当前 main 分支为准(最新示例分支标签为 v2.0.0-rc.13,来自仓库 docs 与 examples 中给出的克隆命令)。若你看到更新 rc tag,请以 crates.io 与 docs.rs 的最新版为准。

1. 是什么

ortRust 生态里跑 ONNX 模型的主流 crate。核心是 Microsoft ONNX Runtime(跨平台、跨加速器)的高层封装,对外暴露 Session / Value / Tensor / I/O binding 等安全 Rust API;同时支持 [actix-web 之外的] 备选后端 ort-candle / ort-tract / ort-web(WASM)。

项目源自现已停摆的 onnxruntime-rs,现在由 Pyke 维护,并以 onnxruntime v1.28.0 为默认二进制(来自 README badge 字段)。它解决的核心问题是:用 Rust 写产品代码时,不愿意拉 Python,又要拿到 ONNX 的所有 Execution Provider(CUDA / TensorRT / DirectML / CoreML / OpenVINO / NNAPI / QNN …)。

2. 解决什么问题

  • 在桌面、服务器、移动端、嵌入式上用同一份 Rust 代码跑同个 ONNX 模型,硬件加速自动切到 CUDA/TensorRT/DirectML/CoreML/...
  • 在终端、CLI、服务、桌面 App、WASM 中内嵌模型推理,又不想为了 PyTorch 拉整个 Python 运行时。
  • 想做真训练(不只是推理):ort 同时暴露了 minimal training API(train-clm / train-clm-simple 两个示例)。

不适用的场景:

  • 模型是 PyTorch/JAX 但没导出过 ONNX——可以,但 ort-candle/ort-tract 后端在多数 PT 模型上兼容性差,建议先导出 ONNX。
  • 需要 GPU 自定义算子 ONNX Runtime 没实现的——custom-ops 例子演示了怎么在 Rust 里注册自定义算子核,但要小心跨设备兼容。

3. 快速安装

# Cargo.toml 中
[dependencies]
ort = "2.0"   # 主要方式,会拉默认 ONNX Runtime 预编译二进制

CPU 即可直接跑。如果想用 CUDA:

ort = { version = "2.0", features = ["cuda"] }

其他常见 feature flags(来自仓库 README 与文档):tensorrtdirectmlcoremlopenvinonnapiqnnrocmvitis-aiaclonednntvmxnnpacktractcandleweb。每个 feature 对应一个 Execution Provider(EP)。

第一次构建会从 Pyke 自己的 CDN 拉 ONNX Runtime 预编译包(参考 README 中的 parcel.pyke.io 图标与 docs 中的 "Prebuilt binaries"),Windows/Linux/macOS 都有。Windows 上 MSVC 工具链要装好;用 Linux glibc < 2.31 的发行版可能要从源码 build。

4. 核心用法

4.1 加载并跑一个 ONNX 模型(CPU)

简化版(仓库 examples/gpt2/gpt2.rs 的最小骨架):

use ort::session::Session;
use ort::value::Tensor;

fn main() -> ort::Result<()> {
    // 1. 初始化(只一次)
    ort::init()?;

    // 2. 加载模型(默认优化级别、性能设置由 builder 控制)
    let mut session = Session::builder()?
        .commit_from_file("model.onnx")?;

    // 3. 构造输入张量(任意实现了 Into<Tensor<...>> 的 ndarray / Vec)
    let input = Tensor::from_array(ndarray::Array2::<f32>::zeros((1, 3)))?;

    // 4. 跑推理
    let outputs = session.run(ort::inputs!["input_name" => input])?;

    // 5. 取出结果
    let output: Tensor<f32> = outputs["output_name"].try_extract_tensor()?;
    println!("{:?}", output);
    Ok(())
}

真实使用要写 gpt2/yolov8/phi-3-vision 等例子里那种 tokenizer + 后处理循环。

4.2 跑 examples

git clone https://github.com/pykeio/ort
cd ort

# 想钉到具体 rc 版本(仓库里建议的命令)
# git clone https://github.com/pykeio/ort --branch v2.0.0-rc.13

# 跑 GPT-2 文本生成(CPU)
cargo example-gpt2

# 跑 YOLOv8 目标检测
cargo example-yolov8

# 想用 CUDA EP,加上 feature flag
cargo example-gpt2 --features cuda

# 想用纯 Rust 的 Tract 后端(不依赖 ONNX Runtime)
cargo example-gpt2 --features backend-tract

# 异步 GPT-2 + axum HTTP API + SSE 流式输出
cargo example-async-gpt2-api

# WASM 浏览器端手部检测(ort-web 后端)
cd examples/web-hands
wasm-pack build --target web

仓库提供 gpt2async-gpt2-apiyolov8web-handssemantic-similaritymodnet/cudarcphi-3-visionmodel-infotrain-clm/train-clm-simplecustom-ops。README 上写有少量日志噪声,介意可以:

RUST_LOG=ort=warn cargo example-gpt2

4.3 I/O Binding 与 async

  • I/O Binding:在 CPU 内存与 GPU 之间预分配 buffer,避免重复拷贝;详见 docs Performance / I/O Binding 章节。
  • async:Session::run_async(...) 支持 tokio 异步(async-gpt2-api 例子就是 axum + SSE)。

4.4 在浏览器里跑模型

ort-web 后端:构建产物是 WASM,用 wasm-pack build --target web 编译 web-hands 例子即可在浏览器打开摄像头做手部检测(README 里给了 demo 链接 spaces.pyke.io/testwebhands)。

5. 典型适用场景

  • CLI 工具 + 本地模型推理:grep 替代品、图片批处理工具、命令行 LLM 包装。
  • 自带模型的桌面 / 移动端应用:Tauri、egui、Slint 等 Rust UI 框架内置 ML。
  • 服务端低延迟推理:CUDA/TensorRT EP 上跑 LLM / 文本 embedding,比 Python 进程省内存、启动快。
  • WASM 端侧:把 ONNX 模型塞进浏览器或边缘设备。

README 里提到 Huggings Face text-embeddings-inference、Google 的 magika、Style-BERT-VITS2 的 sbv2-apiedge-transformersoar-ocrFastEmbed-rsMurmure(Parakeet ASR)、SilentKeysXybridUltralytics YOLO Rust Inference 等都用 ort 作为推理引擎——可作为"生产用过"的旁证。

6. 坑与注意

  • ort::init() 一定要在创建任何 Session 之前调用一次,否则在多线程/多 session 场景会出诡异错误。
  • Windows 链接 Microsoft Visual C++ Runtime,缺 MSVC 会 link 阶段报错。
  • 不同 EP feature 不能同时开:--features cuda--features directml 可能会冲突,请按 EP 文档互斥选择。
  • 1.x → 2.x 是 breaking change,仓库提供迁移指南 https://ort.pyke.io/migrating/v2,API 重命名为 Session::run(...)ort::inputs! 宏等。
  • 训练 API(train-clm)相对基础,复杂模型训练仍建议 PyTorch / burn。
  • 模型导出 ONNX 时注意 opset 版本与 dynamic_axes,部分 ONNX Runtime EP 对超新 opset 支持滞后。

7. 与同类对比

  • vs tvm-ffitch-rs(libtorch Rust 绑定):tch-rs 是直接把 PyTorch C++ 接进来,体量大;ort 体积小、跨硬件强、但只能跑 ONNX。
  • vs candle(纯 Rust):candle 更"ML 框架自训自推";ort 偏向"已经训练好、想跑得快"。
  • vs tract:纯 Rust,无原生 GPU EP,CPU 上更轻便;ort 默认后端 ONNX Runtime 在 CUDA/TensorRT/DirectML 等加速器上更猛,但二进制更大。
  • vs 上层封装(如 Hugging Face text-embeddings-inference):hf TEI 是 Go 的"开箱用 HTTP 服务";ort 是底层,可被 TEI 等服务用。
  • vs ONNX Runtime 官方 Python/C++:纯 Python 服务上线时大多也是包 ONNX Runtime,但 Rust 在部署内存、启动延迟、跨语言互操作上有优势。

8. 一句话结论

想用 Rust 把一个 ONNX 模型丢进桌面/服务器/WASM 加速跑,ort 是当下最省心的选择——ONNX Runtime 几乎所有 Execution Provider 都给你接好,连 WASM 浏览器推理和最小训练都顺手覆盖;如果你还在 PyTorch 写研究,先导出 ONNX 再切 ort 也很值。