第二章 开发环境搭建:CUDA与cuDNN安装、TensorRT安装、CMake与编译工具链配置、VS Code开发环境配置

好,咱们直接进入正题。开发环境搭建这事儿,说简单也简单,说坑也多。我见过不少新手,插件写了一半才发现CUDA版本不对,或者TensorRT死活链接不上。嗯,这一章咱们就把这些基础打牢。

2.1 CUDA与cuDNN安装

CUDA是NVIDIA的并行计算平台。说白了,你的GPU能不能干活,全靠它。cuDNN则是专门为深度学习优化的加速库,TensorRT底层大量依赖它。

2.1.1 版本匹配原则

我个人习惯,先确定TensorRT版本,再反推CUDA和cuDNN版本。为什么?因为TensorRT对CUDA版本有严格限制。你想想看,装了半天发现不兼容,多闹心。

TensorRT版本 推荐CUDA版本 推荐cuDNN版本
8.6.x 11.6 / 11.7 / 11.8 8.7 / 8.8
8.5.x 11.6 / 11.7 8.6 / 8.7
8.4.x 11.6 8.4 / 8.5

我在项目中遇到过,有人拿着TensorRT 8.6硬配CUDA 12.0,结果编译时一堆符号找不到。嗯,这里要注意,NVIDIA官方文档里有个兼容性矩阵表,装之前一定看一眼。

2.1.2 CUDA安装步骤

我建议用runfile方式安装,别用deb包。deb包容易把系统搞乱,尤其是多版本切换时。

# 下载CUDA 11.8 runfile
wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run

# 执行安装,注意不要安装驱动(如果已有驱动)
sudo sh cuda_11.8.0_520.61.05_linux.run --toolkit --silent --override

# 配置环境变量
echo 'export PATH=/usr/local/cuda-11.8/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc
警告: 如果你已经装了NVIDIA驱动,安装CUDA时千万别选Driver选项。我曾经手滑选了一次,结果驱动崩了,桌面直接黑屏,折腾了半天才恢复。

2.1.3 cuDNN安装

cuDNN安装其实很简单,就是解压然后复制文件。但要注意,cuDNN需要注册NVIDIA账号才能下载,有点烦人。

# 解压下载的cuDNN包
tar -xzvf cudnn-linux-x86_64-8.8.0.121_cuda11-archive.tar.xz

# 复制到CUDA目录
sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda-11.8/include/
sudo cp -P cudnn-*-archive/lib/libcudnn* /usr/local/cuda-11.8/lib64/
sudo chmod a+r /usr/local/cuda-11.8/include/cudnn*.h /usr/local/cuda-11.8/lib64/libcudnn*

验证是否安装成功,可以跑一下这个命令:

cat /usr/local/cuda-11.8/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

如果能看到版本号,说明装好了。

2.2 TensorRT安装

TensorRT的安装方式有两种:tar包和deb包。我个人强烈推荐tar包方式,因为灵活,可以随时切换版本。

2.2.1 下载与解压

去NVIDIA官网下载TensorRT 8.6 GA版本,注意选对CUDA版本对应的包。

# 解压到指定目录
tar -xzvf TensorRT-8.6.1.6.Linux.x86_64-gnu.cuda-11.8.tar.gz
sudo mv TensorRT-8.6.1.6 /opt/

# 配置环境变量
echo 'export LD_LIBRARY_PATH=/opt/TensorRT-8.6.1.6/lib:$LD_LIBRARY_PATH' >> ~/.bashrc
echo 'export PATH=/opt/TensorRT-8.6.1.6/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

2.2.2 Python接口安装

如果你要用Python写插件测试,需要装TensorRT的Python包。

cd /opt/TensorRT-8.6.1.6/python
pip install tensorrt-8.6.1.6-cp38-none-linux_x86_64.whl
小提示: 注意Python版本要匹配。我习惯用Python 3.8,因为兼容性最好。如果你用Python 3.10,可能会遇到一些奇怪的符号链接问题。

2.2.3 验证安装

python3 -c "import tensorrt as trt; print(trt.__version__)"

如果能输出8.6.1.6,说明安装成功。如果报错,多半是LD_LIBRARY_PATH没配好,或者CUDA版本不匹配。

2.3 CMake与编译工具链配置

写TensorRT插件,CMake是绕不开的。你想想看,插件需要链接TensorRT、CUDA、cuDNN的库,手动写Makefile太痛苦了。

2.3.1 CMake安装

我建议用CMake 3.20以上版本,对CUDA支持更好。

# Ubuntu下安装
sudo apt-get install cmake cmake-curses-gui

# 或者从源码安装(推荐)
wget https://github.com/Kitware/CMake/releases/download/v3.26.3/cmake-3.26.3-linux-x86_64.tar.gz
tar -xzvf cmake-3.26.3-linux-x86_64.tar.gz
sudo mv cmake-3.26.3-linux-x86_64 /opt/
echo 'export PATH=/opt/cmake-3.26.3-linux-x86_64/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

2.3.2 编写CMakeLists.txt

这里给一个我常用的模板,专门用于TensorRT插件开发:

cmake_minimum_required(VERSION 3.20)
project(MyTensorRTPlugin)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 查找CUDA
find_package(CUDA REQUIRED)

# 设置TensorRT路径
set(TENSORRT_ROOT "/opt/TensorRT-8.6.1.6")
set(TENSORRT_INCLUDE_DIR "${TENSORRT_ROOT}/include")
set(TENSORRT_LIB_DIR "${TENSORRT_ROOT}/lib")

# 包含头文件
include_directories(
    ${CUDA_INCLUDE_DIRS}
    ${TENSORRT_INCLUDE_DIR}
)

# 添加自定义插件源文件
cuda_add_library(my_plugin SHARED
    src/my_plugin.cpp
    src/my_plugin_kernel.cu
)

# 链接库
target_link_libraries(my_plugin
    ${CUDA_LIBRARIES}
    ${TENSORRT_LIB_DIR}/libnvinfer.so
    ${TENSORRT_LIB_DIR}/libnvinfer_plugin.so
)
重点: 注意cuda_add_library和add_library的区别。前者会自动处理CUDA代码的编译,后者需要手动设置。我刚开始用add_library编译.cu文件,折腾了半天才发现这个坑。

2.3.3 编译与测试

mkdir build && cd build
cmake ..
make -j$(nproc)

如果编译成功,会生成libmy_plugin.so。这就是你的自定义插件库。

2.4 VS Code开发环境配置

VS Code是我最常用的IDE,没有之一。配置好了,写插件效率能翻倍。

2.4.1 必备插件

  • C/C++:微软官方,代码补全和调试必备
  • CMake Tools:CMake集成,一键编译
  • CUDA:NVIDIA官方,支持.cu文件语法高亮
  • Python:如果你用Python做测试

2.4.2 配置c_cpp_properties.json

这个文件告诉VS Code去哪里找头文件。我习惯这样配:

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/local/cuda-11.8/include",
                "/opt/TensorRT-8.6.1.6/include"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/g++",
            "cStandard": "c17",
            "cppStandard": "c++17",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

2.4.3 配置tasks.json

一键编译的配置:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build plugin",
            "type": "shell",
            "command": "cd build && cmake .. && make -j$(nproc)",
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": ["$gcc"]
        }
    ]
}
小技巧: 按Ctrl+Shift+B就能一键编译。我每次改完代码,习惯先跑一下编译,确保没有语法错误,再去做测试。

2.5 常见问题与避坑指南

最后,分享几个我踩过的坑:

  • 符号找不到:多半是LD_LIBRARY_PATH没配好,或者链接的库版本不对。我曾经因为链接了libnvinfer.so.8.5,但系统里装的是8.6,折腾了一下午。
  • CUDA版本冲突:如果你系统里有多个CUDA版本,一定要用update-alternatives管理。我习惯把常用版本设为默认。
  • CMake找不到TensorRT:检查TENSORRT_ROOT路径是否正确。我建议用绝对路径,别用相对路径。

嗯,环境搭建就到这里。下一章,咱们开始写第一个真正的自定义插件。