Win10 RTX50编译Paddle Inference C++预测库

在这里插入图片描述

前言

相关介绍

C++简介

C++ 是一种广泛使用的编程语言,最初由丹麦计算机科学家Bjarne Stroustrup于1979年在贝尔实验室开发,作为C语言的扩展。C++的设计目标是提供一种能够高效利用硬件资源,同时支持面向对象编程(OOP)特性的语言。随着时间的发展,C++也引入了泛型编程和函数式编程的支持,使其成为一种多范式编程语言。

DLL 简介

DLL(Dynamic Link Library,动态链接库)是 Windows 操作系统中的一个重要概念。它是一种包含代码和数据的文件,可以被多个程序同时使用。通过将公用的函数、类、变量等资源封装在 DLL 中,可以实现代码复用、节省内存并简化软件更新过程。

核心特点
  1. 共享性

    • 同一个 DLL 文件可以在多个应用程序之间共享,减少了内存占用。
  2. 模块化

    • 将大型应用程序分解为多个模块,每个模块作为一个独立的 DLL。这样可以提高开发效率,便于维护和升级。
  3. 易于维护

    • 当 DLL 内容更新时,只要接口不变,依赖该 DLL 的程序无需重新编译或链接,只需替换新的 DLL 文件即可。
  4. 性能优化

    • 动态加载机制允许只在需要时才加载相应的功能模块,有助于减少启动时间和内存消耗。
  5. 支持多种语言

    • 由于 DLL 提供了标准的调用接口,因此可以用不同编程语言编写的应用程序来调用同一个 DLL。
创建与使用
  • 创建 DLL:通常使用 C/C++ 编写,并通过特定的编译选项生成 DLL 文件。例如,在 Visual Studio 中设置项目属性为目标类型为“动态库 (.dll)”。

  • 导出函数:为了使其他程序能够访问 DLL 中的函数或变量,需要使用 __declspec(dllexport) 关键字将其导出。例如:

    extern "C" __declspec(dllexport) int add(int a, int b) {
        return a + b;
    }
    
  • 导入函数:在另一个程序中使用 DLL 函数时,可以通过 __declspec(dllimport) 或者直接加载 DLL 并获取函数指针的方式调用这些函数。例如:

    typedef int (*AddFunc)(int, int);
    HMODULE hModule = LoadLibrary("mydll.dll");
    AddFunc add = (AddFunc)GetProcAddress(hModule, "add");
    int result = add(5, 3); // 调用 DLL 中的 add 函数
    FreeLibrary(hModule);
    
应用场景
  • 操作系统组件:许多 Windows API 都是以 DLL 形式提供的,如 kernel32.dll、user32.dll 等。
  • 第三方库:很多第三方库以 DLL 形式提供给开发者使用,比如 OpenCV、TensorFlow 等。
  • 插件架构:某些软件采用插件架构,允许用户通过安装额外的 DLL 来扩展功能。
优点与挑战
  • 优点

    • 促进代码重用。
    • 改善应用程序的模块化设计。
    • 方便更新和维护。
  • 挑战

    • 版本兼容性问题:如果 DLL 更新但不向后兼容,则可能导致依赖它的程序无法正常工作。
    • DLL Hell:指的是当系统中有多个版本的同一 DLL 存在时,可能会导致应用程序加载错误版本的问题。

总之,DLL 是 Windows 系统中非常重要的组成部分,合理地利用它可以显著提升软件开发效率和系统性能。然而,开发者也需要注意处理好版本管理和兼容性问题。

Paddle Inference 简介

Paddle Inference 是飞桨的原生推理库,提供服务器端的高性能推理能力。由于 Paddle Inference 能力直接基于飞桨的训练算子,因此它支持飞桨训练出的所有模型的推理。

Paddle Inference 功能特性丰富,性能优异,针对不同平台不同的应用场景进行了深度的适配优化,做到高吞吐、低时延,保证了飞桨模型在服务器端即训即用,快速部署。

前提条件

  • 熟悉CUDA、CUDNN、Python、C++、VS2019、GIT、CMake等。

实验环境

在开始前,请先在 Windows 10 系统中安装以下工具:

软件版本建议与说明
Visual StudioVS2019(推荐)。安装时,务必在“工作负荷”中勾选“使用C++的桌面开发”,并在“语言包”中勾选“英语”。
CUDA ToolkitCUDA 12.8+。这是官方推荐的用于黑威尔架构(Blackwell Architecture)的版本。
cuDNNcuDNN 9.8+。与你下载的 CUDA 12.8+ 预编译包保持一致。
CMake3.17 或更高版本。安装时记得勾选Add CMake to the system PATH for all users
Git用于克隆源代码,使用默认选项安装即可。
Python3.9 至 3.13 之间的任一 64-bit 版本。安装时勾选Add Python 3.x to PATH

工具就绪后,检查一下系统环境变量,确保 GitCMakePython 都能在命令行中被正确调用。

💡 提示:要确保 CUDA 12.8 是你系统当前主要使用的版本。如果你装了多个版本的 CUDA,可以设置环境变量 CUDA_TOOLKIT_ROOT_DIR 来明确指向它,例如:set CUDA_TOOLKIT_ROOT_DIR=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.8

编译过程会消耗大量的内存和 CPU 资源,建议在编译时关闭其他大型应用。如果遇到编译器内存不足的报错,可以参考相关社区经验解决。


编译 Paddle Inference C++ 3.2.1预测库

获取源码

git clone --recursive --depth 1 --branch v3.2.1 https://github.com/PaddlePaddle/Paddle.git
cd Paddle
mkdir build
cd build

运行 CMake 配置

cmake .. -G "Visual Studio 16 2019" -A x64 ^
  -DCMAKE_BUILD_TYPE=Release ^
  -DWITH_GPU=ON ^
  -DWITH_MKL=ON ^
  -DWITH_TENSORRT=OFF ^
  -DWITH_INFERENCE_API_TEST=OFF ^
  -DWITH_TESTING=OFF ^
  -DON_INFER=ON ^
  -DWITH_PYTHON=OFF ^
  -DCUDA_ARCH_NAME=Manual ^
  -DCUDA_ARCH_BIN="120"

如果一切顺利,你会看到类似下面的输出:

-- The CXX compiler identification is MSVC 19.29.30138.0
-- The C compiler identification is MSVC 19.29.30138.0
-- The CUDA compiler identification is NVIDIA 12.8.93
-- Check for working CUDA compiler: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.8/bin/nvcc.exe
-- Check for working CUDA compiler: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.8/bin/nvcc.exe - works
-- Configuring done
-- Generating done

编译生成(十分耗时)

cmake --build . --config Release --target inference_lib_dist

或在 VS 中打开 Paddle.sln,右键 inference_lib_dist → “生成”。

成功编译或,在paddle_inference_install_dir会得到对应的dll文件。

在这里插入图片描述

测试paddle_inference.dll

官方提供的paddle_inference预测库,不支持RTX50系列,SM120架构

在这里插入图片描述

基于RTX50显卡,源码编译的paddle_inference预测库,支持RTX50系列,SM120架构

在这里插入图片描述

常见报错

CUDA 12.1.targets(606,9): error : The CUDA Toolkit v12.1 directory ‘’ does not exist.

这是 Visual Studio 中 旧版 CUDA 构建规则残留 导致的版本冲突。你的系统曾安装过 CUDA 12.1,现在却在使用 CUDA 12.8,但 VS 的构建规则依然指向了已不存在的 v12.1 路径。

解决方案:清理旧规则,安装新规则

1. 删除旧的 CUDA 12.1 构建文件

用管理员身份打开文件资源管理器,进入:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\BuildCustomizations

删除以下文件(如果有):

  • CUDA 12.1.props
  • CUDA 12.1.targets
  • CUDA 12.1.xml

路径中的 Enterprise 可能是 ProfessionalCommunity,以你系统实际情况为准。

2. 复制 CUDA 12.8 的构建规则

从 CUDA 安装目录复制最新规则:

  • 源文件夹C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.8\extras\visual_studio_integration\MSBuildExtensions
  • 目标文件夹:就是上一步的 BuildCustomizations 目录

将所有文件(CUDA 12.8.props, CUDA 12.8.targets, CUDA 12.8.xml)复制过去。

extern_warpctcextern_eigen3报错patch does not apply;patch failed unsupported

patch does not apply 的根源:补丁脚本无法匹配你本地文件的 HTML 行尾或上下文,即使版本锁定,Windows 换行符也会导致失败。

解决这个问题,核心思路是:既然源码已经就位,我们就不再让构建系统去尝试修补它们。这需要修改你提供的这两个文件,把里面关于“打补丁(PATCH)”的命令全部清空。

1. 修改 eigen.cmake 文件

打开 Paddle\cmake\external\eigen.cmake,找到下面这行:

PATCH_COMMAND ${EIGEN_PATCH_COMMAND}

将它修改为:

PATCH_COMMAND ""

最终效果:这个 ExternalProject_Add 指令的 PATCH_COMMAND 部分应该变成这样:

ExternalProject_Add(
  extern_eigen3
  ...
  PATCH_COMMAND ""
  ...
)

2. 修改 warpctc.cmake 文件

打开 Paddle\cmake\external\warpctc.cmake,找到下面这部分:

PATCH_COMMAND
  COMMAND ${WARPCTC_PATCH_COMMAND}
  COMMAND ${WARPCTC_PATCH_CUDA_COMMAND}
  COMMAND ${WARPCTC_PATHCH_ROCM_COMMAND}

将这三行 COMMAND ... 全部替换为 "",修改后效果如下:

PATCH_COMMAND
  COMMAND ""
  COMMAND ""
  COMMAND ""

💡 为什么这样改?

这样修改等于明确告诉 CMake:“这个外部依赖不需要执行任何补丁操作”。这就从根本上绕过了 patch does not apply 的错误,因为构建系统会直接使用你 third_party 目录下已经存在的、版本正确的源码进行编译。

⚠️ 改完之后的关键一步

修改并保存这两个文件后,你必须彻底删除 build 文件夹,然后重新运行 CMake 配置。这一步绝对不能省略,否则旧的、带补丁命令的构建规则会继续生效。

🎯 你的全新编译流程

请严格按顺序执行,避免旧的编译缓存干扰:

# 1. 回到源码根目录
cd /d Paddle

# 2. 彻底删除旧的 build 文件夹
rmdir /s /q build

# 3. 重新创建并进入 build 目录
mkdir build
cd build

# 5. 运行 CMake 配置
cmake .. -G "Visual Studio 16 2019" -A x64 ^
  -DCMAKE_BUILD_TYPE=Release ^
  -DWITH_GPU=ON ^
  -DWITH_MKL=ON ^
  -DWITH_TENSORRT=OFF ^
  -DWITH_INFERENCE_API_TEST=OFF ^
  -DWITH_TESTING=OFF ^
  -DON_INFER=ON ^
  -DWITH_PYTHON=OFF ^
  -DCUDA_ARCH_NAME=Manual ^
  -DCUDA_ARCH_BIN="120"

# 6. 开始编译
cmake --build . --config Release --target inference_lib_dist

或者,你也可以在 VS2019 中打开生成的 Paddle.sln,右键 inference_lib_dist 项目 ->“生成”。

LNK1181: 无法打开输入文件“dynload_tensorrt.lib”

你在 CMake 配置时设置了 -DWITH_TENSORRT=OFF,但 paddle_inference_shared 这个核心库在链接时,仍然试图链接与 TensorRT 相关的动态加载库 dynload_tensorrt.lib。由于 TensorRT 功能被关闭,这个库根本不会生成,所以链接器找不到文件。

解决方案1:修改链接配置,断掉对 TensorRT 的依赖

唯一的根本解决办法是让 paddle_inference_sharedWITH_TENSORRT=OFF 时不去链接 dynload_tensorrt.lib

1. 定位并修改文件

用文本编辑器打开以下文件:

Paddle\paddle\fluid\inference\CMakeLists.txt

搜索 dynload_tensorrt。你会找到类似这样的一行(可能在 target_link_libraries 语句里):

target_link_libraries(paddle_inference_shared
  ...
  dynload_tensorrt
  ...
)

将它用条件判断包裹起来,使其只在 TensorRT 开启时才链接:

if(WITH_TENSORRT)
  target_link_libraries(paddle_inference_shared dynload_tensorrt)
endif()

或者,如果 dynload_tensorrt 是混在一大串链接项里的,你可以直接找到单独的一行:

  dynload_tensorrt

然后把它注释掉或删除,并改为上面带条件的写法。

解决方案2:手动从项目文件中移除依赖

既然 CMake 生成的配置有误,最直接的修复方法是手动修改 paddle_inference_shared 项目的 .vcxproj 文件,移除有问题的依赖项。

  1. 备份项目文件: 在修改之前,建议先备份 Paddle\build\paddle\fluid\inference\paddle_inference_shared.vcxproj 文件。
  2. 用文本编辑器打开该 .vcxproj 文件
  3. 搜索 dynload_tensorrt.lib,并移除对应条目。如果相关的 <AdditionalDependencies> 组内只有这一项,可以同时删除整个组。例如,将:
<AdditionalDependencies>dynload_tensorrt.lib;%(AdditionalDependencies)</AdditionalDependencies>

修改为:

<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
  1. 移除所有配置(如 Debug|x64Release|x64)下的对应条目
  2. 保存文件并重新生成 inference_lib_dist 项目

为确保修改完全正确,你可以打开之前看到的 inference_lib_dist 项目属性,在链接器输入中检查是否仍能看到 dynload_tensorrt.lib 的踪迹,并一并移除。或者,使用 findstr /s /i "dynload_tensorrt" *.vcxproj 命令在 build 目录下搜索所有引用,逐个修复。

手动修改 .vcxproj 文件是解决此类链接器错误的常用直接手段,能让你无需重跑 CMake 即可继续编译过程。

MSB3073: 命令“setlocal … ”已退出,代码为 1

这个错误是 inference_lib_dist 项目在合并和拷贝最终预测库时失败的。这是因为第一步链接失败,导致 paddle_inference.dll.lib 等核心文件没有产生,拷贝时找不到源文件,于是整个打包过程报错退出。实在不行,自己手动复制相关依赖

extern_glog 报错`patch does not apply;

1. 修改 glog.cmake 文件

打开 Paddle\cmake\external\eigen.cmake,找到下面这行:

COMMAND ${GLOG_PATCH_COMMAND}

将它修改为:

COMMAND ""

最终效果:这个 ExternalProject_Add 指令的 PATCH_COMMAND 部分应该变成这样:

ExternalProject_Add(
  extern_glog
  ...
  UPDATE_COMMAND ""
  PATCH_COMMAND
  # COMMAND ${GLOG_PATCH_COMMAND}
  COMMAND ""
  ...
)

错误 C2065 “FLAGS_indentlevel”: 未声明的标识符

修改Paddle\paddle\fluid\eager\api\utils\global_utils.h文件

在文件开头,添加以下代码,即可。

#include "gflags/gflags.h"
DECLARE_int32(indentlevel);

第三方库 IntelliSense “活动”错误 (E0029 / E0147 / E1574)

错误(活动)	E0135	namespace "std" 没有成员 "result_of"	activation_op
错误(活动)	E0040	应输入标识符	activation_op
错误(活动)	E0065	应输入“;”	activation_op
错误(活动)	E1574	静态断言失败,原因是 "wrong alignment for 32-byte aligned T"	activation_op

具体可能原因:

  1. 注意前缀“错误(活动)”:这代表这些是 Visual Studio 编辑器 IntelliSense (实时语法检查) 报出的错误,并非真正的 MSVC 编译器 (MSBuild) 报错。
  2. cccl/libcudacxx 是 NVIDIA 的 CUDA C++ 核心库,其中大量使用了 C++20 Concepts 和复杂的模板元编程宏。VS 的 IntelliSense 引擎(EDG/Clang)在解析这些特定的 CUDA 宏时经常会出现误报(解析失败)。
  3. small_vector.h 的静态断言误报也与 IntelliSense 对内存对齐(32-byte aligned)的计算偏差有关。

结论:这些“活动”错误通常不会阻断实际的编译过程,属于 IDE 的“假阳性”报错。可以直接忽略 IntelliSense “活动”错误

如果觉得刺眼,可以在 VS 中通过 工具 -> 选项 -> 文本编辑器 -> C/C++ -> 高级 -> 禁用 IntelliSense 来关闭实时语法检查。
在这里插入图片描述

参考文献

[1] https://www.paddlepaddle.org.cn/inference/v3.0/guides/install/compile/source_compile_under_Windows.html
[2] https://github.com/PaddlePaddle/Paddle
[3] https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/index_cn.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FriendshipT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值