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