ONNX 有显卡却跑了 CPU

推理与优化 · 2026-08-30 · 6 分钟

一行遗漏的条件判断,让 GPU 模型跑在 CPU 上。从 12.80ms 到 3.95ms 的排查过程。

在家用调试环境部署项目时,一个性能问题查到最后发现是一行条件判断少写了一个枚举值。本文记录本地复现与单机基准,数据口径限定于该调试环境。

模型加速的规则按文件扩展名推导后端:.pt 走 CUDA、.onnx 走 ONNX。而"是否上 GPU"的判断只覆盖了前一种——于是 .onnx 模型即使机器上有显卡,也会被分配 CPU provider。

它不报错,只是慢。慢到什么程度?

量化之后

在同一台机器、同一个模型、同一帧输入下:

单帧推理 12.80ms → 3.95ms(3.2 倍),吞吐 78 → 253 次/秒。<br />仅按纯推理吞吐估算,25fps 视频流约 3.1 路 → 10 路;实测端到端为单路。

而 GPU 利用率只有 10%、功耗 38W、显存 640MB——说明这张卡远没有被喂饱。

真正的结论在数字之外

把推理压到 3.95ms 之后,单路 25fps 的端到端(解码→预处理→推理→后处理→编码)依然只有 25.2fps 勉强不丢帧。继续埋点才看清:

单帧耗时里,纯推理只占 4.5ms,其余 约 7ms 是 Python 侧的预处理与后处理——缩放、格式转换、结果解析、跟踪关联。

优化到一定程度,瓶颈一定在你自己的代码里,不在硬件上。

这个结论直接改变了后续的多路扩展策略:不是继续压模型,而是把前后处理搬出主循环、做成可并行的批处理。