模型部署Tensorrt学习记录
Posted 超级无敌陈大佬的跟班
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模型部署Tensorrt学习记录相关的知识,希望对你有一定的参考价值。
tensorrt官方文档:https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-723
一、简介
TensorRT是一种深度学习框架?是一种库?官方文档中的称呼是:TensorRT 是一个 SDK(Software Development Kit)软件开发工具,用于优化经过训练的深度学习模型以实现高性能推理。
加载engine模型参数
"step0.通过文件流读取engine文件"
std::vector<char> trtModelStream_; //engine文件参数读取后保存到该数组中
size_t size{0};
std::ifstream file(engineFile, std::ios::binary);
if (file.good()) {
file.seekg(0, file.end); //从打开的文件流中获取信息
size = file.tellg(); //获取到文件的大小
file.seekg(0, file.beg); //从打开的文件流中获取信息
trtModelStream_.resize(size);
file.read(trtModelStream_.data(), size); //读取文件流的内容保存到数组中
file.close();
}
"step1.通过RunTime对象反序列化engine引擎"
IRuntime *runtime = createInferRuntime(gLogger);
assert(runtime != nullptr);
m_engine = runtime->deserializeCudaEngine(trtModelStream_.data(), size, nullptr); //最后一个参数不再使用,必须是一个空指针.
assert(m_engine != nullptr);
"step2.创建context来开辟空间存储中间值,一个engine可以有多个context来并行处理"
//由于引擎保存网络定义和训练参数,因此需要额外的空间。这些保存在context中
m_context = m_engine->createExecutionContext();
assert(m_context != nullptr);
创建流并预分配GPU缓冲区内存
执行模型推理
"调用推理函数"
float *outdata = new float[m_batch_size * m_output_size];
doInference(*m_context, (float *)pre_img.ptr<float>(0), outdata, m_batch_size); //注意输入数据传入的方式.ptr
bool TensorRTWrapper::doInference(nvinfer1::IExecutionContext& context, float* input, float* output, int batchSize) {
const nvinfer1::ICudaEngine& engine = context.getEngine();
"步骤一:创建流(可以在推理之前创建)"
// Pointers to input and output device buffers to pass to engine.
// Engine requires exactly IEngine::getNbBindings() number of buffers.
assert(engine.getNbBindings() == 2); //getNbBindings()获取网络输入输出数量
void* buffers[2];
// In order to bind the buffers, we need to know the names of the input and output tensors.
// Note that indices are guaranteed to be less than IEngine::getNbBindings()
// 为了绑定缓冲区,我们需要知道输入和输出张量的名称。 请注意,索引必须小于IEngine::getNbBindings()
"step1.指定输入和输出节点名来获取输入输出索引"
const int inputIndex = engine.getBindingIndex(m_input_tensor_name.data());//blob名称是转换模型时设置好的,这里需要保持一致
const int outputIndex = engine.getBindingIndex(m_output_tensor_name.data());
"step2.在设备上开辟GPU缓冲区"
TENSORRTCHECK(cudaMalloc(&buffers[inputIndex], batchSize * 3 * m_height * m_width * sizeof(float)));
TENSORRTCHECK(cudaMalloc(&buffers[outputIndex], batchSize * m_output_size * sizeof(float)));//开辟输入输出需要的GPU内存,由网络输入输出决定
"step3.创建流"
cudaStream_t stream;
TENSORRTCHECK(cudaStreamCreate(&stream));
"步骤二:执行推理"
"step1.拷贝数据 从主机(CPU)--->设备(GPU)"
TENSORRTCHECK(cudaMemcpyAsync(buffers[inputIndex], input, batchSize * 3 * m_height * m_width * sizeof(float), cudaMemcpyHostToDevice, stream));
"step2.执行推理"
context.enqueue(batchSize, buffers, stream, nullptr);
"step3.拷贝数据 从设备(GPU)--->主机(CPU)"
TENSORRTCHECK(cudaMemcpyAsync(output, buffers[outputIndex], batchSize * m_output_size * sizeof(float), cudaMemcpyDeviceToHost, stream));
"step4.同步流"
cudaStreamSynchronize(stream);//因为上面的cudaMemcpyAsync()函数是异步方式执行的,所有这里需要进行同步
"步骤三:释放内存(可以放在类析构时)"
cudaStreamDestroy(stream);
TENSORRTCHECK(cudaFree(buffers[inputIndex]));
TENSORRTCHECK(cudaFree(buffers[outputIndex]));
}
以上是关于模型部署Tensorrt学习记录的主要内容,如果未能解决你的问题,请参考以下文章
ubuntu18一文学会Pytorch端到端网络部署Tensorrt模型推理