最近看到,很多前沿的开源仓库采用Rust作为主要语言。
比如,Codex就经历了一次较大的代码重构,将主力语言从Python转换成Rust。
这不仅让我想到一个问题:对于AI模型推理而言,使用Rust是否会比纯用Python更具备速度优势?

本文将通过YOLO26[1]这个目标检测算法为例,探寻这个问题的答案。
Python推理速度统计
下面的实验场景是在Apple M5芯片的设备上,让YOLO26n这个模型去推理一个带有10张图片的文件夹,统计任务总耗时和平均FPS。
下面是一个Python语言编写的推理代码:
import timeimport osfrom ultralytics import YOLOimport torchimage_dir = "images"model_path = "yolo26n.pt"device = "mps" if torch.backends.mps.is_available() else "cpu"print(f"Using device: {device}")model = YOLO(model_path)image_paths = []for name in os.listdir(image_dir):if name.lower().endswith((".jpg", ".png", ".jpeg")): image_paths.append(os.path.join(image_dir, name))print(f"检测图片数量: {len(image_paths)}")start_time = time.time()count = 0for path in image_paths: _ = model.predict( source=path, device=device, verbose=False) count += 1end_time = time.time()total_time = end_time - start_timefps = count / total_time if total_time > 0 else 0print("\n====== 推理统计 ======")print(f"总图片数: {count}")print(f"总耗时: {total_time:.2f} 秒")print(f"平均FPS: {fps:.2f} 张/秒")
推理结果我分别统计了使用cpu和mps的推理结果,统计如下:
Using device: cpu总图片数: 10总耗时: 0.28 秒平均FPS: 35.99 张/秒Using device: mps总图片数: 10总耗时: 0.68 秒平均FPS: 14.60 张/秒
由于这是一个IO密集型的任务,IO耗时大于计算耗时,使用mps的推理速度反而不如直接使用cpu的推理速度。
Rust推理速度统计
选取YOLO26作为推理比较任务的一大原因是,ultralytics官方有个仓库[2]专门适配了Rust语言的模型推理。
要使用它进行推理,首先需要把pt模型转换成onnx模型。
可以通过以下代码进行转换:
from ultralytics import YOLOmodel = YOLO("yolo26n.pt")model.export(format="onnx")
转换完成后,新建一个rust项目:
cargo new yolo_video_benchcd yolo_video_bench
配置 Cargo.toml 文件:
[package]name = "yolo_video_bench"version = "0.1.0"edition = "2021"[dependencies]ultralytics-inference = { git = "https://github.com/ultralytics/inference.git" }image = "0.24"imageproc = "0.23"
编写 src/main.rs 文件:
use std::error::Error;use std::fs;use std::time::Instant;use ultralytics_inference::{Device, InferenceConfig, YOLOModel};fn main() -> Result<(), Box<dyn Error>> {let image_dir = "images";let device = Device::Cpu;let config = InferenceConfig::new().with_device(device);let mut model = YOLOModel::load_with_config("yolo26n.onnx", config)?;let mut image_paths = Vec::new();for entry in fs::read_dir(image_dir)? {let path = entry?.path();if let Some(ext) = path.extension() {let ext = ext.to_string_lossy().to_lowercase();if ext == "jpg" || ext == "png" || ext == "jpeg" { image_paths.push(path); } } }println!("检测图片数量: {}", image_paths.len());let start = Instant::now();let mut count = 0;for path in &image_paths {let path_str = path.to_str().unwrap();let _ = model.predict(path_str)?; count += 1; }let total_time = start.elapsed().as_secs_f64();let fps = count as f64 / total_time;println!("\n====== 推理统计 ======");println!("总图片数: {}", count);println!("总耗时: {:.2} 秒", total_time);println!("平均FPS: {:.2} 张/秒", fps);Ok(())}
测试结果如下:
====== 推理统计 ======总图片数: 10总耗时: 0.25 秒平均FPS: 39.30 张/秒
结果发现,使用CPU进行推理时,Rust确实会比Python推理快一些,但领先幅度不高。
本来我还想测试一下使用mps的效果,即把Device::Cpu替换成Device::Mps,但是会出现以下警告:
WARNING ⚠️ Device 'mps' requested but feature not enabled or supported. Falling back to available providers.
该警告说明,虽然官方有这个接口,但并未完全支持,实际还是用CPU进行推理。
近一步优化Python推理速度
实际上,在前面的Python推理测试中,并没完全发挥出它的潜力。
model.predict可以通过增加两个参数,进一步提升推理速度:
- stream=True:启用流式推理模式,将原本“逐次调用推理”的离散执行方式,转换为“单次调用 + 持续流水线处理”的模式。这样可以复用内部的数据加载与预处理流程,减少重复初始化开销。
- batch=10:启用批处理机制,将10张图片打包成一个批次进行推理。
完整测试代码如下:
import timeimport osfrom ultralytics import YOLOimage_dir = "images"model_path = "yolo26n.pt"device = "cpu"print(f"Using device: {device}")model = YOLO(model_path)image_paths = [ os.path.join(image_dir, n)for n in os.listdir(image_dir)if n.lower().endswith((".jpg", ".jpeg", ".png"))]print(f"检测图片数量: {len(image_paths)}")start_time = time.perf_counter()results = model.predict( source=image_paths, device=device, stream=True, batch=10, verbose=False)count = 0for _ in results: count += 1end_time = time.perf_counter()total_time = end_time - start_timefps = count / total_time if total_time > 0 else 0print(f"总图片数: {count}")print(f"总耗时: {total_time:.4f} 秒")print(f"平均FPS: {fps:.2f} 张/秒")
测试结果会比之前快一些。
Using device: cpu检测图片数量: 10总图片数: 10总耗时: 0.2424 秒平均FPS: 41.26 张/秒
总结
从测试结果看,没必要纠结Python和Rust推理谁更快这个问题,语言本身所带来的增益有限,主要在于底层调用的推理引擎,从ultralytics的Rust仓库关注度来说,用Rust重构意义不大。
此外,就生态而言,Python的生态比Rust繁荣得多。本实验中,起初想通过视频推理的实验进行比较,但因Rust和OpenCV/FFMpeg之间的版本依赖问题,最终止步。
因此,无脑选用Python就行,性能问题选用合适的依赖库就能解决。
参考
[1] https://github.com/ultralytics/ultralytics[2] https://github.com/ultralytics/inference