![0.png](http://static.itsharecircle.com/231113/d4de447732851a548729c7705f413626.png)
今天给大家分享一套关于CUDA与TensorRT部署的视频教程,附带课件+源码资料下载,希望大家喜欢!
一、什么是TensorRT?
TensorRT是英伟达的AI加速推理模型,我们在使用GPU深度学习训练完后,会生成.pt模型,但是这个模型在推理时不够快,这时候就需要转化成trt模型,使用c++利用TensorRT API编写程序进行快速推理。
二、CUDA下载安装
本人下载的版本是cuda11.6,cudnn8.4,正好对应上的,当然cuda版本要能支持你的GPU,cuda版本太高你的GPU跑不了,cuda版本太低也不好。
运行命令提示符cmd,输入图中指令查看自己显卡信息。
三、如何确定运行参数和线程索引?
运行参数的确定
cuda核函数添加了<<<>>>尖括号配置信息,尖括号内的配置信息并不是传递给核函数的,而是传递给CUDA运行时系统,告诉运行时系统如何启动核函数。确定块个数和线程个数的一般步骤为:
1)先根据GPU设备的硬件资源确定一个块内的线程个数;
2)再根据数据大小和每个线程处理数据个数确定块个数。
参考代码如下:
//每个块内有256个线程
unsigned int threads = 256;
//每个线程处理4个数据,注意这4个数不是相邻的
unsigned int unroll = 4;
//根据数据量计算出块的个数
//为了保证线程数足够,在数据量的基础上加了threads-1,相当于向上取整
unsigned int blocks = (dataNum + threads -1)/threads/unroll;
cudaKernel<<<blocks, threads>>>(***);
四、简单案例
将一个数组中的每个元素在GPU上进行并行求解其sigmoid的数值
创建一个cpp文件
#include <cuda_runtime.h>
#include <stdio.h>
void test_print(const float* pdata, int ndata);
int main(){
float* parray_host = nullptr;
float* parray_device = nullptr;
int narray = 10;
int array_bytes = sizeof(float) * narray;
// pageable memory
parray_host = new float[narray];
// global memory
cudaMalloc(&parray_device, array_bytes);
for(int i = 0; i < narray; ++i)
parray_host[i] = i;
cudaMemcpy(parray_device, parray_host, array_bytes, cudaMemcpyHostToDevice);
// 调用核函数
test_print(parray_device, narray);
// 核函数的调用都是异步执行的,需要加入cudaDeviceSynchronize();
cudaDeviceSynchronize();
cudaFree(parray_device);
delete[] parray_host;
return 0;
}
五、安装cuDNN
安装cudnn需要先去NVIDIA官网下载安装包(这个解压后是一个文件夹)cuDNN官网下载地址,这里需要注意选择版本,要和自己安装的cuda版本适配。
解压后,发现有bin,include,lib三个文件夹,这里我们需要将对应的文件复制到之前我们安装的cuda目录下。
将bin文件夹下的dll文件拷贝到cuda的bin文件夹下,include文件夹下的头文件拷贝到cuda的include文件夹下,lib文件下下的lib文件拷贝到cuda的lib\x64文件夹下。
验证
进入cuda安装的目录下,找到extras\demo_suite目录,执行deviceQuery.exe,查看是否出现
六、CUDA中的线程与线束
在CUDA编程中,线程(Threads)和线束(Warps)是两个重要的概念,用于管理和执行并行计算任务。
线程(Thread): 线程是CUDA编程中最基本的并行执行单位。在CUDA中,每个线程独立地执行一个计算任务,并且可以访问自己的寄存器和局部内存。GPU上的线程数量非常庞大,通常可以有成千上万个线程同时执行,从而实现高度的并行计算。线程在CUDA中通常由线程索引(Thread Index)来标识,使用三维的线程索引(x, y, z)来表示线程在块(Block)中的位置。
线束(Warp): 线束是CUDA中的一个重要概念,它是一组连续的线程,通常包含32个线程。线束是GPU硬件层面的概念,在一个时钟周期内,线束内的所有线程同时执行相同的指令。这意味着线束内的线程必须保持一致性,即它们执行的代码路径和分支条件必须相同,否则会导致线束内的线程出现分支发散(Thread Divergence),从而降低执行效率。因此,在CUDA编程中,尽量保证线束内的线程执行相同的代码路径,以获得最佳的性能。
线程和线束之间的关系: 在GPU上,线程组织成线束。当GPU执行一个指令时,线束内的所有线程同时执行相同的指令,这就是线束级的并行。然后,GPU会同时执行多个线束,这就是线程级的并行。多个线程块在GPU上同时执行,每个线程块内又包含多个线程,这样就实现了GPU的高度并行计算。
CUDA编程充分利用了线程和线束的并行能力,通过合理的线程组织和并行计算,实现高性能的GPU计算。编写高效的CUDA程序需要充分理解线程和线束的概念,并注意避免线束内的分支发散,以保证最佳的性能。
七、tensorrt的yolov5部署
tensorrt是一个推理引擎架构,会将pytorch用到的网络模块,如卷积,池化等用tensorrt进行重写。pytorch模型转换为.engine后就可以进行推理。
在github上下载tensorrt, 注意tensorrt版本和yolov5版本的匹配关系,如tensorrt5.0对应yolov5的 v5.0
GitHub - wang-xinyu/tensorrtx at yolov5-v5.0
基本上搭建好环境后,根据github上这个开源项目的readme文件进行tensorrt部署就可以了。
1. generate .wts from pytorch with .pt, or download .wts from model zoo
```
git clone -b v5.0 https://github.com/ultralytics/yolov5.git
git clone https://github.com/wang-xinyu/tensorrtx.git
// download https://github.com/ultralytics/yolov5/releases/download/v5.0/yolov5s.pt
cp {tensorrtx}/yolov5/gen_wts.py {ultralytics}/yolov5
cd {ultralytics}/yolov5
python gen_wts.py -w yolov5s.pt -o yolov5s.wts
// a file 'yolov5s.wts' will be generated.
```
2. build tensorrtx/yolov5 and run
```
cd {tensorrtx}/yolov5/
// update CLASS_NUM in yololayer.h if your model is trained on custom dataset
mkdir build
cd build
cp {ultralytics}/yolov5/yolov5s.wts {tensorrtx}/yolov5/build
cmake ..
make
sudo ./yolov5 -s [.wts] [.engine] [s/m/l/x/s6/m6/l6/x6 or c/c6 gd gw] // serialize model to plan file
sudo ./yolov5 -d [.engine] [image folder] // deserialize and run inference, the images in [image folder] will be processed.
// For example yolov5s
sudo ./yolov5 -s yolov5s.wts yolov5s.engine s
sudo ./yolov5 -d yolov5s.engine ../samples
// For example Custom model with depth_multiple=0.17, width_multiple=0.25 in yolov5.yaml
sudo ./yolov5 -s yolov5_custom.wts yolov5.engine c 0.17 0.25
sudo ./yolov5 -d yolov5.engine ../samples
```
八、配环境,装依赖
一步步的来解决吧,我就是这么成功的,中间出了问题别烦躁,相信自己一定行,大不了看看英文文档。
>ubuntu 18.04 kernel 4.15.0 gcc7.3 glibc2.27
ubuntu18.04安装完后自带的kernel一般是4.15.0~4.18.0左右,gcc是7.3的,glibc是2.27的。也就是说,如果你是新装的18.04系统,那么这四个要求就自动满足了。
但是我在这里就出了许多问题,其一是,我有一次手滑,在系统问我要不要更新的时候点了更新,所以我的kernel变成了5.几的;其二是,我这台电脑之前装过ROS,对gcc有要求,我自己降了gcc版本,所以我的gcc版本不够7.3。实测如果什么都不管直接开始装CUDA的话是会失败的。
nvidia-smi # 查看现在用的显卡驱动
ubuntu-drivers devices # 查看支持的显卡驱动
sudo ubuntu-drivers autoinstall # 自动安装推荐的驱动
sudo apt install nvidia-driver-xxx # 自选
感谢观看,本文结束。
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传