TensorRT从理论到实践

时间:2022-12-11 20:53:07

TensorRT从理论到实践

TensorRT理论

一. TensorRT介绍

  • TensorRT是一个高性能的深度学习推理优化器,可以为深度学习应用提供低延迟、高吞吐率的部署推理。TensorRT可用于对超大规模数据中心、嵌入式平台或自动驾驶平台进行推理加速。TensorRT现已能支持Tensorflow、Caffe、Mxnet、Pytorch等几乎所有的深度学习框架,将TensorRT和NVIDIA的GPU结合起来,能在几乎所有的框架中进行快速和高效的部署推理。
  • TensorRT 是一个C++库,提供C++ API和Python API,主要用来针对 NVIDIA
    GPU进行高性能推理(Inference)加速。
  • 在推理过程中,基于 TensorRT 的应用程序的执行速度可比 CPU 平台的速度快 40 倍。借助
    TensorRT,可以优化在所有主要框架中训练的神经网络模型,精确校正低精度,并最终将模型部署到超大规模数据中心、嵌入式或汽车产品平台中。
  • TensorRT 以 NVIDIA 的并行编程模型 CUDA 为基础构建而成,可帮助利用 CUDA-X
    中的库、开发工具和技术,针对人工智能、自主机器、高性能计算和图形优化所有深度学习框架中的推理。
  • 下图是NVDIA针对深度学习平台的一系列完整的解决方案。分为训练和部署两部分,训练部分首先也是最重要的是构建网络结构,准备数据集,使用各种框架进行训练,训练要包含validation和test的过程,最后对于训练好的模型要在实际业务中进行使用。
    TensorRT从理论到实践
    下图是TensorRT的应用:
    TensorRT从理论到实践

二. 为什么TensorRT能让模型加速?

TensorRT从理论到实践

1. 数据精度校准(Weight &Activation Precision Calibration)

  • 大部分深度学习框架在训练神经网络时网络中的张量都是32位浮点数的精度,一旦网络训练完成,在部署推理的过程中由于不需要反向传播,完全可以适当降低数据精度,比如降为FP16或INT8的精度。更低的数据精度将会使得内存占用和延迟更低,模型体积更小。
  • TensorRT支持FP16和INT8的计算。我们知道深度学习在训练的时候一般是应用32位或者16位数据,TensorRT在推理的时候可以降低模型参数的位宽来进行低精度推理,以达到加速推断的目的。

2. 层间融合或张量融合(Layer & Tensor Fusion)

  • TensorRT通过对层间的横向或纵向合并(合并后的结构称为CBR,卷积层、BN层、激活层),使得层的数量大大减少。横向合并可以把卷积、偏置和激活层合并成一个CBR结构,只占用一个CUDA核心。纵向合并可以把结构相同,但是权值不同的层合并成一个更宽的层,也只占用一个CUDA核心。合并之后的计算图的层次更少了,占用的CUDA核心数也少了,因此整个模型结构会更小,更快,更高效。

3. 内核自动调整(Kernel Auto-Tuning)

  • 网络模型在推理计算时,调用GPU的CUDA核进行计算。TensorRT可以针对不同的算法,不同的网络模型,不同的GPU平台,进行 CUDA核的调整,以保证当前模型在特定平台上以最优性能计算。

4.动态张量显存(Dynamic Tensor Memory)

  • 在每个tensor的使用期间,TensorRT会为其指定显存,避免显存重复申请,减少内存占用和提高重复使用效率。

5. 多流执行(Multi-Stream Execution)

  • 用于并行处理多个输入流的可扩展设计。

TensorRT实践

一. 环境准备

1. 确认cuda版本

TensorRT从理论到实践首先查看自己的cuda版本,根据cuda的版本安装对应的tensorRT

2. 安装docker

如果你的电脑还没有安装docker,请安装docker,在docker中操作会减少环境问题带来的莫名错误,因此强烈建议在docker中操作。

sudo apt install docker.io

3. 拉tensorRT镜像

根据上述的cuda版本,拉取镜像

sudo docker pull hakuyyf/tensorrtx:trt7_cuda10

TensorRT从理论到实践
该过程比较耗时,请耐心等待。。。

二. 生成权重文件

1. 创建容器并进入

docker run -it --name=trt7-guopei --gpus all --privileged --net=host --ipc=host --pid=host -v /home/work/guopei/workspace:/home/work hakuyyf/tensorrtx:trt7_cuda10 /bin/bash
# 创建一次就够了,下次直接进入容器
docker attach trt7-guopei

2. 获得训练权重

git clone https://github.com/wang-xinyu/pytorchx.git
cd pytorchx/lenet/
# 在当前路径下获得网络权重lenet5.pth
python lenet5.py 
# 将lenet5.pth转化为项目中需要的lenet5.wts文件
python inference.py

终端输出结果如图所示:
TensorRT从理论到实践

三. 编译推理

1. 下载tensorrtx对应的工程

git clone https://github.com/wang-xinyu/tensorrtx.git

2. 将lenet5.wts拷贝到对应的目录下

cp pytorchx/lenet/lenet5.wts tensorrtx/lenet/
cd tensorrtx/lenet/

3. 编译工程

mkdrir build
cd build
cmake ../
make

不出意外,你的工程已经编译好了,如下图:
TensorRT从理论到实践

4. 模型序列化&模型推理

./lenet -s     # 模型序列化,生成tensorrt的推理引擎lenet5.engine
./lenet -d     # 加载推理引擎,推理模型

推理结果如下图所示,可以对比上面pytorch的推理结果,几乎无差异:
TensorRT从理论到实践

四. 总结

    1. 用tensorrtx工程直接提取权重文件,中间过程可控;
    1. 该工程更加灵活,遇到不支持的层,容易解决;
    1. 该工程实现了主流算法的转化和推理,代码修改量不大即可适配自己的工程。

参考:
https://github.com/wang-xinyu/tensorrtx
https://github.com/wang-xinyu/pytorchx

对技术充满激情,对生活充满热爱!