【引】将Caffe转TensorRT的时候,有很多自己设计的接口TensorRT库本身不支持。我们需要自己创建Plugin,本文介绍TensorRT的创建,如何自定义Plugin,和快速书写cuda函数。

【结构】

将Caffe转TensorRT的时候,有很多自己设计的接口TensorRT库本身不支持。我们需要继承TensorRT里面的IPlugin类来创建自己的Plugin。然后ICaffeParser对象会通过IPluginFacotry 解析Prototext里的网络结构,参数等信息,并将解析的信息放在内存中以便之后的计算。同时IBuilder负责设置网络数据类型(int8 FP16)batchSzie等一些通用信息。这样一个网络就被建立,网络的结构,参数都被创建在内存之中被INetworkDefinition对象所管理

【重载plugin】

class UpsampleLayer : public IPlugin
{
public:UpsampleLayer(){}//serilize constructureUpsampleLayer(size_t stride):stride_(stride){}//deserilize constructureUpsampleLayer(const void* buffer,size_t sz, size_t stride):stride_(stride){/* 反序列化, 将连续放置的内存,读取到成员变量里面 */const int* d = reinterpret_cast<const int*>(buffer);channel_=d[0];w_=d[1];h_=d[2];}// get output size infomationinline int getNbOutputs() const override { return 1; };Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override{channel_=inputs[0].d[0];w_=inputs[0].d[1];h_=inputs[0].d[2];return DimsCHW(inputs[0].d[0], inputs[0].d[1]*stride_, inputs[0].d[2]*stride_);}int initialize() override {return 0;}inline void terminate() override{}inline size_t getWorkspaceSize(int) const override { return 0; }// inference function, operation logicint enqueue(int batchSize, const void*const *inputs, void** outputs, void*, cudaStream_t stream) override{Forward_gpu((float*)inputs[0],1,channel_, w_, h_, stride_, (float*)outputs[0] );return 0;}//serialization sizesize_t getSerializationSize() override{return 4*sizeof(int);}//serialized buffer addrvoid serialize(void* buffer) override{int* d = reinterpret_cast<int*>(buffer);d[0] = channel_; d[1] = w_; d[2] = h_;d[3]=stride_;}//run before initializevoid configure(const Dims*inputs, int nbInputs, const Dims* outputs, int nbOutputs, int) override{channel_=inputs[0].d[0];w_=inputs[0].d[1];h_=inputs[0].d[2];}protected:int stride_;int channel_;int w_;int h_;
};

模块

上面函数是一个plugin的写法,也是tensorrt引擎理解prototxt,运行运算的接口。

IPlugin类 ──── ┐─────  理解prototxt

|

└─────  enqeue推理函数

【函数执行顺序】

Builder最先创建网络结构,之后IExecutionContext是运行时(runtime)调用子函数。

Builder时函数:

△ Configure()先于initilize调用用来检验Layer的Input数据,又或者选择自定义的算法来处理Input数据,在一些复杂结构中还会用到卷积处理Input,如果需要runtime(实时)处理数据,应该写到plugin,序列化和反序列化函数里面。

△ 当需要存储中间结果时,可以利用共享内存的workspace(为了节省支援)。这个例子不需要用到所以getWorkspaceSize返回0。

IExecutionContext时函数:

△△△ 构造函数有两个,TileLayer()负责序列化 TileLayer(const void* buffer, size_t size)负责反序列化。

△ Initilize和terminate是运行时执行可以用于初始化算法对象如cuDNN, cuBLAS,又或者开辟中间变量内存用于计算。

△ 我们定义的网络,TensorRT需要知道每层网络的输出getNbOutputs()函数返回该层函数的Output数量,getOutputDimensions返回该层网络的Output维度。

△△△△ enqueue,Layer中最重要的运行时函数,需要编写cuda代码用于计算层中的逻辑计算

△△△△ serialization 和 deserialization 也是非常重要的函数,目的是将Layer的成员变量按连续内存方式存储(序列化)或者将一段连续内存(【e.g】 ( void ) *ptr [float0 float1 int char] ===>  float a = (float*) ptr[0]; float b = ((float*)ptr + 1)[0] 等)读到类成员变量里面赋值(反序列化)

【创建TensorRT】

void caffeToGIEModel(const std::string& deployFile,                  // name for caffe prototxtconst std::string& modelFile,                 // name for model const std::vector<std::string>& outputs,        // network outputsunsigned int maxBatchSize,                        // batch size - NB must be at least as large as the batch we want to run with)nvcaffeparser1::IPluginFactory* pluginFactory,    // factory for plugin layersIHostMemory *&gieModelStream)                   // output stream for the GIE model
{std::cout << "start parsing model..." << std::endl;//创建build 导入glogger以便查阅日志IBuilder* builder = createInferBuilder(gLogger);std::cout << "start1 parsing model..." << std::endl;//创建network对象&ICaffeParser对象INetworkDefinition* network = builder->createNetwork();ICaffeParser* parser = createCaffeParser();//CafferParser解析pluginparser->setPluginFactory(pluginFactory);std::cout << "start2 parsing model..." << std::endl;//builder设置网络类型bool fp16 = builder->platformHasFastFp16();//解析prototxt 写入network内存中const IBlobNameToTensor* blobNameToTensor = parser->parse( deployFile.c_str(),modelFile.c_str(),*network,fp16 ? DataType::kHALF : DataType::kFLOAT);std::cout << "start3 parsing model..." << std::endl;//根据自定义blobname在net中寻找内存地址for (auto& s : outputs)network->markOutput(*blobNameToTensor->find(s.c_str()));std::cout << "start4 parsing model..." << std::endl;//设置network通用参数builder->setMaxBatchSize(maxBatchSize);builder->setMaxWorkspaceSize(10 << 20);builder->setHalf2Mode(fp16);ICudaEngine* engine = builder->buildCudaEngine(*network);assert(engine);std::cout << "start5 parsing model..." << std::endl;network->destroy();parser->destroy();std::cout << "start6 parsing model..." << std::endl;//序列化网络gieModelStream = engine->serialize();engine->destroy();builder->destroy();shutdownProtobufLibrary();std::cout << "End parsing model.qq.." << std::endl;
}int main(int argc, char** argv) {// create a GIE model from the caffe model and serialize it to a streamPluginFactory pluginFactory;IHostMemory *gieModelStream{nullptr};caffeToGIEModel("../model_voc14/deploy.prototxt_attention",
"../model_voc14/infer.caffemodel",std::vector<std::string>{AD_OUTPUT_BLOB_NAME, AD_OUTPUT_BLOB_NAME1},1,&pluginFactory, gieModelStream);pluginFactory.destroyPlugin();std::cout << "staraaat deserializeCudaEngine model..." << std::endl;// deserialize the engineIRuntime *runtime = createInferRuntime(gLogger);std::cout << "start deserializeCudaEngine model..." << std::endl;ICudaEngine *engine = runtime->deserializeCudaEngine(gieModelStream->data(), gieModelStream->size(),&pluginFactory);std::cout << "end deserializeCudaEngine model..." << std::endl;IExecutionContext *context = engine->createExecutionContext();context->setProfiler(&gProfiler);...return 1;
}

待更新.....

贤者之路, Caffe转TensorRT相关推荐

  1. 贤者之路,Tensorrt的int8 calibration创建

    [INT8 Calibration] 无论哪块GPU计算板卡都能够支持Int8的加速,但需要事先生成 calibration文件,下面是.h .cpp分别继承IInt8EntropyCalibrato ...

  2. 贤者之路,cuda版本convertto实现(与OPENCV 3.4 CPU版本数值一致)

    [引言]: 将一个float32精度的矩阵砍到uchar精度,每个库都会根据自己算法目标类型做一些加速的优化从而导致结果不一样,比如在OpenCV3.4 cpu版本的convertto中, 1.5f的 ...

  3. 贤者之路,Cuda block内部矩阵求逆,mxm矩阵 复杂度为O(m)

    在做线性变换上经常要用到NXN的矩阵求逆.在CUDA用的是高斯消元比较适合并行计算. 下面是3X3Cuda实现矩阵求逆的Device函数,也就是说可以直接写到你的kernel函数上去.当然也可以是任何 ...

  4. TensorRT Analysis Report分析报告

    TensorRT Analysis Report 一.介绍 TensorRT是一个高性能的深度学习推理(Inference)优化器,可以为深度学习应用提供低延迟.高吞吐率的部署推理.TensorRT可 ...

  5. 实践教程 | TensorRT部署深度学习模型

    作者 | ltpyuanshuai@知乎 来源 | https://zhuanlan.zhihu.com/p/84125533 编辑 | 极市平台 本文仅作学术分享,版权归原作者所有,如有侵权请联系删 ...

  6. TensorRT部署深度学习模型

    1.背景 目前主流的深度学习框架(caffe,mxnet,tensorflow,pytorch等)进行模型推断的速度都并不优秀,在实际工程中用上述的框架进行模型部署往往是比较低效的.而通过Nvidia ...

  7. 收藏 | TensorRT部署深度学习模型

    点上方计算机视觉联盟获取更多干货 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:作者 | ltpyuanshuai@知乎 来源 | https://zhuanlan.zhihu.com/p/ ...

  8. 万字讲解Apollo,全网Apollo资料整理和学习

    0 参考资料 0.1 Apollo各模块系列笔记记录 模块 参考文章 Cyber apollo介绍之cyber设计(五) - 知乎 (zhihu.com) apollo介绍之Cyber框架(十) - ...

  9. 元旦福利 | Python、机器学习、TensorFlow 图书送一波

    随着人工智能的升温,大家越来越关注这门最接近AI的编程语言,关于Python的消息也是接连不断.比如浙江省信息技术课程改革方案出台,Python 确定进入浙江省信息技术高考,从2018年起浙江省信息技 ...

最新文章

  1. JavaScript:window.event.srcElement(指触发事件的对象)
  2. android 外键,android - 创建一个具有外键的sqlite数据库表,作为android中的表列。 我面临以下错误。 我该如何解决 - 堆栈内存溢出...
  3. Linux 中常见的较为复杂的命令实例
  4. Azure Cosmos DB(Azure 宇宙数据库)--地球已无法阻止微软玩数据库了
  5. 单片机c语言 arduino,单片机C语言程序设计实训100例——基于Arduino+Proteus仿真
  6. 环境监测设备中,使用GPS模拟器测试TTFF和灵敏度的注意点
  7. 进销存excel_excel进销存人人都会的制作方法
  8. win10 网络发现 打开保存后,自动关闭
  9. C++ isalpha、isalnum、islower、isupper、tolower、toupper用法
  10. 使用mysql打开什么文件格式_dbf是什么文件怎么打开
  11. 如何处理计算机显卡故障,电脑显卡常见故障及解决方案
  12. 迁移学习基础知识整理
  13. 变速器--中英文翻译
  14. 利用 画图 快速给图片添加文字
  15. SpringBoot中的 ApplicationEvent和Listener
  16. 教你怎样混社会(转)
  17. Crunch生成字典
  18. 全国计算机一级比赛,2017年全国计算机一级考试题及答案
  19. 西安软件园:英特尔移动通信西安有限公司
  20. 最新最全python镜像源-(转)

热门文章

  1. 以哥德尔命名的哥德尔数——哥德尔拆解汉译之四
  2. 小米互联通信服务_小米战华为,中国手机市场正上演最精彩攻防战
  3. 如果哈夫曼树有67个结点,则可知叶结点总数为
  4. 室内外实时一体化建模
  5. python5 5的 阵列_Biopython表型微阵列
  6. 关于mybatis 的一些实验
  7. php 5 php.ini中文注释
  8. 4G LTE 频率表
  9. 图:邻接矩阵表示法创建无向图并深度优先搜索遍历
  10. 常用API,基本类型包装类,日期类,异常,集合进阶,IO流,多线程