tensorrt 6.0小白入门记(从安装到使用)

一、下载安装tensorrt

1.1 检查linux环境

一定要清楚自己cuda的版本号
cat /usr/local/cuda/version.txt 查看cuda版本号,我的是10.0.130
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2 查看cudnn的版本号 7.6.4

1.2 安装pycuda

pip install ‘pycuda>=2017.1.1’

1.3 下载tensorrt

官网下载地址: https://developer.nvidia.com/nvidia-tensorrt-6x-download
nvidia的官网需要注册,下载的时候写一些相关内容就可以啦
根据我自己的配置下载的是:TensorRT-6.0.1.5.Ubuntu-18.04.x86_64-gnu.cuda-10.0.cudnn7.6

1.4 安装tensorrt

1、解压tensorrt:
tar xzvf TensorRT-6.0.1.5.Ubuntu-18.04.x86_64-gnu.cuda-10.0.cudnn7.6.tar.gz
2、添加环境变量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/dl/Tools/TensorRT-6.0.1.5/lib
3、安装 Tensorrt
cd TensorRT-6.0.1.5/python/
pip install tensorrt-6.0.1.5-cp37-none-linux_x86_64.whl (我的是python3.7)
4、安装 uff
cd TensorRT-6.0.1.5/uff/
pip install uff-0.6.5-py2.py3-none-any.whl
5、安装 graphsurgeon
cd TensorRT-6.0.1.5/graphsurgeon
pip install graphsurgeon-0.4.1-py2.py3-none-any.whl
6、测试安装是否成功

 import tensorrt
 tensorrt.__version__
'6.0.1.5'

二、将pytorch模型部署到tensorrt

2.1 认识ONNX

   ONNX是一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型。它使得不同的人工智能框架(如Pytorch, MXNet)可以采用相同格式存储模型数据并交互。 ONNX的规范及代码主要由微软,亚马逊 ,Facebook 和 IBM 等公司共同开发,以开放源代码的方式托管在Github上。目前官方支持加载ONNX模型并进行推理的深度学习框架有: Caffe2, PyTorch, MXNet,ML.NET,TensorRT 和 Microsoft CNTK,并且 TensorFlow 也非官方的支持ONNX。—维基百科

2.2 tensorrt前向部署

   使用tensorrt部署前向有两种方法,一种是使用pytorch自带的onnx将模型转换乘onnx格式,然后使用tensorrt自带的onnx解析器进行模型加载和解析;一种是使用tensorrt自己的c++API创建整个网络,然后将训练好的权重填充的网络里面。第一种方法不需要重新搭建网络,但是在解析器经常会遇到"unsupported operations or layers" 这样的问题,特别是一些最先进的模型经常使用一些新的层;第二种方法要使用tensorrt的c++API自己去搭建网络层,需要自己熟悉这些API,但是可以跳出解析器能力的限制,部署更多的网络。

1、 pytorch模型转onnx

input_name = ['input']
output_name = ['output']
input = torch.randn(1, 3, 48, 48).cuda()
net_size = 48
net = Onet(net_size, net_size, 2)
net.cuda()
net.load_state_dict(torch.load(weight_path)['state_dict'])
torch.onnx.export(net, input, 'onet.onnx', input_names=input_name, output_names=output_name, verbose=True)

2、 tensorrt 解析onnx模型

第一步:builder

IBuilder* builder = createInferBuilder(gLogger);

第二步:network

nvinfer1::INetworkDefinition* network = builder->createNetwork();

第三步:onnx解析

auto parser = nvonnxparser::createParser(*network, gLogger);
parser->parseFromFile(modelFile.c_str(), static_cast<int>(gLogger.reportableSeverity))

第四步:使用builder创建engine,并且设置最大batch size和最大workspace size
最大batch size指定TensorRT将要优化的batch大小。在运行时,只能选择比这个值小的batch。
各种layer算法通常需要临时工作空间。这个参数限制了网络中所有的层可以使用的最大的workspace空间大小。 如果分配的空间不足,TensorRT可能无法找到给定层的实现。

builder->setMaxBatchSize(maxBatchSize);
builder->setMaxWorkspaceSize(1 << 20);
ICudaEngine* engine = builder->buildCudaEngine(*network);

第五步:用完分配过的network,builder和parser记得解析

parser->destroy();
network->destroy();
builder->destroy();

第六步:用 C++ API 序列化一个模型,并且保存起来
序列化模型,即把engine转换为可存储的格式以备后用。推理时,再简单的反序列化一下这个engine即可直接用来做推理。通常创建一个engine还是比较花时间的,可以使用这种序列化的方法避免每次重新创建engine。

IHostMemory *serializedModel = engine->serialize();
// store model to disk
std::ofstream p(save_path)
p.write(reinterpret_cast<const char*>(serializedModel->data()), serializedModel>size());
serializedModel->destroy();

第七步:读取序列化数据,并且创建一个runtime并用来反序列化

char *trtModelStream{nullptr};
std::ifstream file(serializedModel_path)
file.seekg(0, file.end);
size = file.tellg();
file.seekg(0, file.beg);
trtModelStream = new char[size];
assert(trtModelStream);
file.read(trtModelStream, size);
file.close();

IRuntime* runtime = createInferRuntime(gLogger);
ICudaEngine* engine = runtime->deserializeCudaEngine(trtModelStream, modelSize, nullptr);

第八步:用 C++ API 执行推理
1、 创建一个Context用来存储中间激活值

IExecutionContext *context = engine->createExecutionContext();

2、用input和output的blob名字获取对应的input和output的index

int inputIndex = engine.getBindingIndex(INPUT_BLOB_NAME);
int outputIndex = engine.getBindingIndex(OUTPUT_BLOB_NAME);

3、使用上面的indices,在GPU上创建一个指向input和output缓冲区的buffer数组

void* buffers[2];
buffers[inputIndex] = inputbuffer;
buffers[outputIndex] = outputBuffer;

4、 通常TensorRT的执行是异步的,因此将kernels加入队列放在CUDA stream流上

context.enqueue(batchSize, buffers, stream, nullptr);

你可能感兴趣的:(实践,神经网络)