应统一使用gpu版onnx runtime预编译包(如onnxruntime-win-x64-gpu-1.xx.x.zip),因其内置cpu/gpu双执行提供者,可自动降级;需通过ort::getavailableproviders()动态检测并选择可用提供者,而非硬编码设备,同时严格匹配cuda/cudnn/驱动版本及vs运行时。

直接用 GPU 版本的 ONNX Runtime 库,不用分 CPU/GPU 两套环境——它自带自动降级能力,只要运行时没 CUDA 驱动或显卡,CUDAExecutionProvider 就不会被激活,会无声 fallback 到 CPUExecutionProvider。硬拆两套配置反而容易出错。
怎么选对 ONNX Runtime 预编译包
别去官网手动点“CPU”或“GPU”下载按钮。Windows 下推荐统一下载 onnxruntime-win-x64-gpu-1.xx.x.zip(比如 1.27.0),它同时包含 CPU 和 GPU 执行提供者,且 VS2022 编译器兼容性最好。你用 VS2022 编译,就一定得用 MSVC 构建的版本,否则链接时大概率遇到 LNK2038(不匹配的 runtime library)或运行时报堆损坏。
关键点:
-
.nupkg文件不是解压目录,必须用nuget.exe解包或手动重命名为.zip再解压,否则onnxruntime.lib找不到 - 确认解压后有
lib/onnxruntime.lib、include/onnxruntime_cxx_api.h、bin/onnxruntime.dll(不是onnxruntime_providers_cuda.dll单独放) - VS 项目属性里:包含目录填
include路径,库目录填lib路径,附加依赖项写onnxruntime.lib
代码里怎么让 CPU/GPU 自动切换
核心是调用 Ort::GetAvailableProviders() 查当前可用的执行提供者,而不是写死 AppendExecutionProvider_CUDA()。这个函数返回的是运行时实际能用的列表,取决于:ONNX Runtime 构建时是否启用了 CUDA、系统是否装了对应版本的 NVIDIA 驱动、CUDA/cuDNN 是否在 PATH 中、GPU 是否被占用。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
典型判断逻辑:
- 如果
"CUDAExecutionProvider"在返回列表里 → 配置OrtCUDAProviderOptions并追加 - 否则默认走 CPU,什么都不用加(
CPUExecutionProvider总是内置的) - 注意:
AppendExecutionProvider_CUDA()必须在Ort::SessionOptions创建后、创建Ort::Session前调用,顺序错了会静默失败
常见报错和坑点
很多崩溃不是代码写错,而是环境链断了。最常踩的几个点:
-
Ort::Exception: CUDA provider not registered:说明你用了 GPU 版本的库,但运行时找不到onnxruntime_providers_cuda.dll或它依赖的cudnn64_8.dll/cublas64_11.dll。把bin目录下所有 DLL 拷到你的可执行文件同目录,或者确保它们在 PATH 中 - 程序启动就崩在
Ort::Session构造函数:大概率是 Debug/Release 混用——你用 Release 模式编译项目,却链接了 Debug 版的onnxruntime.lib(文件名带d后缀),反之亦然 - GPU 推理结果全零或 NaN:检查模型输入张量是否在 GPU 上分配内存(
Ort::MemoryInfo::CreateCpu不能传给 CUDA 会话),也可能是 cuDNN 版本和 CUDA 不匹配(例如 CUDA 12.2 + cuDNN 8.9.7 是安全组合,但 8.9.5 就可能出问题)
真正麻烦的从来不是“怎么写代码”,而是“为什么明明写了却没生效”。GetAvailableProviders() 返回值一定要打日志看一眼,别凭感觉猜;DLL 路径宁可全拷进输出目录,也别信 PATH 设置;CUDA 版本号要精确到小数点后一位,差 0.1 都可能白忙活半天。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










