[完結(jié)]CUDA與TensorRT部署實(shí)戰(zhàn)課程(附源碼+課件)
[完結(jié)]CUDA與TensorRT部署實(shí)戰(zhàn)課程(附源碼+課件)
網(wǎng)盤地址:https://pan.baidu.com/s/1XYYrm79c8HfsGtyn1aXFOQ 提取碼:giph?
騰訊微云下載地址:https://share.weiyun.com/9otzPM7G 密碼:dwe6fk
今天給大家分享一套關(guān)于CUDA與TensorRT部署的視頻教程,附帶課件+源碼資料下載,希望大家喜歡!
一、什么是TensorRT?
TensorRT是英偉達(dá)的AI加速推理模型,我們?cè)谑褂肎PU深度學(xué)習(xí)訓(xùn)練完后,會(huì)生成.pt模型,但是這個(gè)模型在推理時(shí)不夠快,這時(shí)候就需要轉(zhuǎn)化成trt模型,使用c++利用TensorRT API編寫程序進(jìn)行快速推理。
二、CUDA下載安裝
本人下載的版本是cuda11.6,cudnn8.4,正好對(duì)應(yīng)上的,當(dāng)然cuda版本要能支持你的GPU,cuda版本太高你的GPU跑不了,cuda版本太低也不好。
運(yùn)行命令提示符cmd,輸入圖中指令查看自己顯卡信息。
三、如何確定運(yùn)行參數(shù)和線程索引?
運(yùn)行參數(shù)的確定
cuda核函數(shù)添加了<<<>>>尖括號(hào)配置信息,尖括號(hào)內(nèi)的配置信息并不是傳遞給核函數(shù)的,而是傳遞給CUDA運(yùn)行時(shí)系統(tǒng),告訴運(yùn)行時(shí)系統(tǒng)如何啟動(dòng)核函數(shù)。確定塊個(gè)數(shù)和線程個(gè)數(shù)的一般步驟為:
1)先根據(jù)GPU設(shè)備的硬件資源確定一個(gè)塊內(nèi)的線程個(gè)數(shù);
2)再根據(jù)數(shù)據(jù)大小和每個(gè)線程處理數(shù)據(jù)個(gè)數(shù)確定塊個(gè)數(shù)。
參考代碼如下:
//每個(gè)塊內(nèi)有256個(gè)線程
unsigned int threads = 256;
//每個(gè)線程處理4個(gè)數(shù)據(jù),注意這4個(gè)數(shù)不是相鄰的
unsigned int unroll = 4;
//根據(jù)數(shù)據(jù)量計(jì)算出塊的個(gè)數(shù)
//為了保證線程數(shù)足夠,在數(shù)據(jù)量的基礎(chǔ)上加了threads-1,相當(dāng)于向上取整
unsigned int blocks = (dataNum + threads -1)/threads/unroll;
cudaKernel<<<blocks, threads>>>(***);
四、簡(jiǎn)單案例
將一個(gè)數(shù)組中的每個(gè)元素在GPU上進(jìn)行并行求解其sigmoid的數(shù)值
創(chuàng)建一個(gè)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);
? ? // 調(diào)用核函數(shù)
? ? test_print(parray_device, narray);
? ? // 核函數(shù)的調(diào)用都是異步執(zhí)行的,需要加入cudaDeviceSynchronize();
? ? cudaDeviceSynchronize();
? ? cudaFree(parray_device);
? ? delete[] parray_host;
? ? return 0;
}
五、安裝cuDNN
安裝cudnn需要先去NVIDIA官網(wǎng)下載安裝包(這個(gè)解壓后是一個(gè)文件夾)cuDNN官網(wǎng)下載地址,這里需要注意選擇版本,要和自己安裝的cuda版本適配。
解壓后,發(fā)現(xiàn)有bin,include,lib三個(gè)文件夾,這里我們需要將對(duì)應(yīng)的文件復(fù)制到之前我們安裝的cuda目錄下。
將bin文件夾下的dll文件拷貝到cuda的bin文件夾下,include文件夾下的頭文件拷貝到cuda的include文件夾下,lib文件下下的lib文件拷貝到cuda的lib\x64文件夾下。
驗(yàn)證
進(jìn)入cuda安裝的目錄下,找到extras\demo_suite目錄,執(zhí)行deviceQuery.exe,查看是否出現(xiàn)
六、CUDA中的線程與線束
? ? ? ? 在CUDA編程中,線程(Threads)和線束(Warps)是兩個(gè)重要的概念,用于管理和執(zhí)行并行計(jì)算任務(wù)。
線程(Thread): 線程是CUDA編程中最基本的并行執(zhí)行單位。在CUDA中,每個(gè)線程獨(dú)立地執(zhí)行一個(gè)計(jì)算任務(wù),并且可以訪問自己的寄存器和局部?jī)?nèi)存。GPU上的線程數(shù)量非常龐大,通??梢杂谐汕先f個(gè)線程同時(shí)執(zhí)行,從而實(shí)現(xiàn)高度的并行計(jì)算。線程在CUDA中通常由線程索引(Thread Index)來標(biāo)識(shí),使用三維的線程索引(x, y, z)來表示線程在塊(Block)中的位置。
線束(Warp): 線束是CUDA中的一個(gè)重要概念,它是一組連續(xù)的線程,通常包含32個(gè)線程。線束是GPU硬件層面的概念,在一個(gè)時(shí)鐘周期內(nèi),線束內(nèi)的所有線程同時(shí)執(zhí)行相同的指令。這意味著線束內(nèi)的線程必須保持一致性,即它們執(zhí)行的代碼路徑和分支條件必須相同,否則會(huì)導(dǎo)致線束內(nèi)的線程出現(xiàn)分支發(fā)散(Thread Divergence),從而降低執(zhí)行效率。因此,在CUDA編程中,盡量保證線束內(nèi)的線程執(zhí)行相同的代碼路徑,以獲得最佳的性能。
線程和線束之間的關(guān)系: 在GPU上,線程組織成線束。當(dāng)GPU執(zhí)行一個(gè)指令時(shí),線束內(nèi)的所有線程同時(shí)執(zhí)行相同的指令,這就是線束級(jí)的并行。然后,GPU會(huì)同時(shí)執(zhí)行多個(gè)線束,這就是線程級(jí)的并行。多個(gè)線程塊在GPU上同時(shí)執(zhí)行,每個(gè)線程塊內(nèi)又包含多個(gè)線程,這樣就實(shí)現(xiàn)了GPU的高度并行計(jì)算。
? ? ? ? CUDA編程充分利用了線程和線束的并行能力,通過合理的線程組織和并行計(jì)算,實(shí)現(xiàn)高性能的GPU計(jì)算。編寫高效的CUDA程序需要充分理解線程和線束的概念,并注意避免線束內(nèi)的分支發(fā)散,以保證最佳的性能。
七、tensorrt的yolov5部署
tensorrt是一個(gè)推理引擎架構(gòu),會(huì)將pytorch用到的網(wǎng)絡(luò)模塊,如卷積,池化等用tensorrt進(jìn)行重寫。pytorch模型轉(zhuǎn)換為.engine后就可以進(jìn)行推理。
在github上下載tensorrt, 注意tensorrt版本和yolov5版本的匹配關(guān)系,如tensorrt5.0對(duì)應(yīng)yolov5的 v5.0?
GitHub - wang-xinyu/tensorrtx at yolov5-v5.0
基本上搭建好環(huán)境后,根據(jù)github上這個(gè)開源項(xiàng)目的readme文件進(jìn)行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
```
八、配環(huán)境,裝依賴
一步步的來解決吧,我就是這么成功的,中間出了問題別煩躁,相信自己一定行,大不了看看英文文檔。
>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系統(tǒng),那么這四個(gè)要求就自動(dòng)滿足了。
但是我在這里就出了許多問題,其一是,我有一次手滑,在系統(tǒng)問我要不要更新的時(shí)候點(diǎn)了更新,所以我的kernel變成了5.幾的;其二是,我這臺(tái)電腦之前裝過ROS,對(duì)gcc有要求,我自己降了gcc版本,所以我的gcc版本不夠7.3。實(shí)測(cè)如果什么都不管直接開始裝CUDA的話是會(huì)失敗的。
nvidia-smi # 查看現(xiàn)在用的顯卡驅(qū)動(dòng)
ubuntu-drivers devices # 查看支持的顯卡驅(qū)動(dòng)
sudo ubuntu-drivers autoinstall # 自動(dòng)安裝推薦的驅(qū)動(dòng)
sudo apt install nvidia-driver-xxx # 自選
感謝觀看,本文結(jié)束。