4、CUDA与cuDNN在嵌入式平台的适配:Jetson系列CUDA环境检查、cuDNN版本匹配、TensorRT核心库安装
好,咱们进入正题。这一章讲的是嵌入式平台上的环境适配,说白了就是让CUDA、cuDNN和TensorRT这三个家伙在Jetson上好好干活。我当年第一次在Jetson上部署模型时,就栽在版本匹配上——折腾了两天才发现是cuDNN版本不对。嗯,这种坑咱们今天必须填平。
4.1 Jetson上的CUDA环境检查
Jetson系列设备出厂时,NVIDIA已经预装了CUDA工具包。但预装不代表万事大吉。我个人习惯,拿到板子第一件事就是确认CUDA版本和驱动状态。
检查CUDA版本,最直接的方法就是跑这条命令:
nvcc --version
输出会显示CUDA的编译版本。比如我手头这块Jetson Orin NX,输出是:
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Wed_Nov_22_10:17:15_PST_2023
Cuda compilation tools, release 12.2, V12.2.140
Build cuda_12.2.r12.2/compiler.33567101_0
这里要注意,nvcc --version显示的是CUDA工具包版本,而驱动版本需要用nvidia-smi查看。两者可能不一致,但Jetson上通常是对应的。
检查驱动版本:
nvidia-smi
输出中会显示驱动版本和CUDA驱动API版本。我曾经遇到过驱动版本太老,导致TensorRT无法加载某些算子。所以,建议定期更新JetPack SDK,它会统一更新驱动、CUDA、cuDNN和TensorRT。
nvcc找不到,检查一下环境变量。Jetson上CUDA通常安装在/usr/local/cuda,可以手动添加export PATH=/usr/local/cuda/bin:$PATH到.bashrc。
4.2 cuDNN版本匹配——这个坑我踩过
cuDNN是CUDA的深度学习加速库。版本匹配是个大问题。为什么?因为TensorRT、PyTorch、TensorFlow等框架都依赖特定版本的cuDNN。版本不对,轻则报错,重则推理结果错误。
检查当前cuDNN版本:
cat /usr/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
或者:
dpkg -l | grep cudnn
输出示例:
ii libcudnn8 8.9.4.25-1+cuda12.2 amd64 cuDNN runtime libraries
ii libcudnn8-dev 8.9.4.25-1+cuda12.2 amd64 cuDNN development libraries
这里显示cuDNN 8.9.4,对应CUDA 12.2。
版本匹配原则:
- TensorRT 8.x 通常需要 cuDNN 8.x
- TensorRT 9.x 需要 cuDNN 8.9+ 或 9.x
- PyTorch 2.x 对 cuDNN 版本也有要求
我建议的做法是:先确定你要用的TensorRT版本,然后根据NVIDIA官方兼容性表选择cuDNN版本。别自己瞎猜,去官网查表最靠谱。
4.3 TensorRT核心库安装
TensorRT的安装方式有两种:通过JetPack一键安装,或者手动下载deb包。我推荐前者,省心。
方式一:JetPack安装(推荐)
运行SDK Manager,选择你的Jetson型号和JetPack版本。安装时勾选TensorRT组件即可。安装完成后,TensorRT位于:
/usr/lib/aarch64-linux-gnu/libnvinfer.so
/usr/include/aarch64-linux-gnu/NvInfer.h
方式二:手动安装deb包
从NVIDIA官网下载对应Jetson架构的deb包。比如:
sudo dpkg -i tensorrt_8.6.1.6-1+cuda12.2_arm64.deb
sudo apt-get install -f
安装后验证:
dpkg -l | grep tensorrt
输出应包含:
ii tensorrt 8.6.1.6-1+cuda12.2 arm64 TensorRT core library
检查TensorRT版本:
python3 -c "import tensorrt; print(tensorrt.__version__)"
如果输出8.6.1,说明安装成功。
python3 -c "import tensorrt"不报错,才算真正装好。
4.4 环境验证脚本
我习惯写一个简单的验证脚本,一次性检查CUDA、cuDNN和TensorRT。这样每次换板子或重装系统后,跑一遍就能确认环境是否就绪。
#!/bin/bash
echo "=== CUDA ==="
nvcc --version | grep "release"
echo "=== cuDNN ==="
cat /usr/include/cudnn_version.h | grep CUDNN_MAJOR -A 2 | head -3
echo "=== TensorRT ==="
python3 -c "import tensorrt; print('TensorRT version:', tensorrt.__version__)"
echo "=== Device ==="
python3 -c "import torch; print('CUDA available:', torch.cuda.is_available())"
保存为check_env.sh,运行:
chmod +x check_env.sh
./check_env.sh
输出示例:
=== CUDA ===
release 12.2, V12.2.140
=== cuDNN ===
#define CUDNN_MAJOR 8
#define CUDNN_MINOR 9
#define CUDNN_PATCHLEVEL 4
=== TensorRT ===
TensorRT version: 8.6.1
=== Device ===
CUDA available: True
看到这个输出,基本可以放心了。
4.5 知识体系结构图
下面这张图总结了本章的核心逻辑:从硬件到软件,层层依赖,环环相扣。
4.6 避坑指南
最后,分享几个我实际踩过的坑:
- cuDNN符号链接问题: 有时候安装多个cuDNN版本,符号链接指向了旧版本。检查
/usr/lib/aarch64-linux-gnu/libcudnn.so指向的是否正确。 - TensorRT Python绑定缺失: 手动安装TensorRT时,容易漏掉Python包。记得安装
python3-libnvinfer和python3-libnvinfer-dev。 - 权限问题: Jetson上默认用户是
nvidia,有时需要sudo权限才能访问某些库文件。建议把用户加入video组。 - JetPack版本回退: 如果遇到兼容性问题,不要硬扛。JetPack支持版本回退,用SDK Manager重新刷一个旧版本更省事。
嗯,这一章的内容就到这里。环境适配是基础,基础打牢了,后面模型转换和推理优化才能顺风顺水。