在TensorRT的sample在成功make之后,/bin文件下就会出现trtexec这个可执行文件.在Developer Guide中已经表明,trtexec是对网络进行benchmark的工具,同时可以输出该model优化后生成的串行化(serialized)engine.
工作任务是测试各种网络的前馈时间,而trtexec恰好是工具.但是,由于涉及到自定义层,在导入自定义层的基础上,执行trtexec.
原理很简单,这里记录一下过程
我就拿samplePlugin中的自定义FCPlugin和PluginFactory作为导入对象.
PluginFactory parserPluginFactory;
(这里就用和samplePlugin中相同的名字了)
ICaffeParser* parser=createCaffeParser();
语句下,我添加了
parser->setPluginFactory(pluginFatory_);
其实完成这四步,这个FCPlugin就可以在trtexec中执行了,下面是一些小问题
比如想要在caffeToTRTModel运行
parser->setPluginFactory(pluginFatory_);
就要把caffeToTRTModel方法定义和调用的时候,把pluginFactory引入.
在samplePlugin中,因为涉及到了串/并行化,所以就实例化了两次FCPlugin(这里表达的不一定对),所以相对的也就前后两次声明了两个pluginFactory.
但是在trtexec中,被构建出来的engin直接执行inference,没涉及到串并行化,所以相当于只涉及了一次实例化FCPlugin.
因为在命令行下执行./trtexec的时候,最少只需要写清楚deployFile和output就可以执行,代码会自动为其随机model参数,然后返回runtime结果.
但是当我在IDE上执行的时候,不设置modelFile是会报错的,报错的地方是在调用PluginFactory的createPlugin的时候,告诉我assert(nbWeight==2)出错,debug之后发现这里nbWeight为0
这个具体代码还没看,可能是因为在我使用PluginFactory实例化FCPlugin的时候,还没有为model分配随机权值,如果有类似错误可以考虑在modelFile的定义地方,加上一个.caffemodel文件的路径,就好了.
先记录基础篇,继续肝,试着去写写别的层或者多个自定义层.
根据公司最近的需求,终于要了解trtexec中的各种参数了,研究TensorRT以来,trtexec的好多参数现在仍然不了解。
Trtexec中的各个参数功能简介:
Deploy文件(caffe的时候,用来接收prototxt文件的)
model文件(caffe的时候,用来接收.caffemodel文件的)
TensorRT4.x的产物,不用了,更新为了下面的saveEngine和loadEngine功能。
创建完engine,保存为指定名称
想要load的engine的path+name
int8校准相关的设置。
被用于caffeToTRTModel下的calibrator对象的定义部分,用于读取INT8校准的cache file,不支持onnx。
tensorFlow要转成uff格式才能经过tensorRT加速(用来接收uff文件)
pytorch等要转成onnx格式才能经过tensorRT加速(用来接收onnx文件)
输入层名称,让network知道输入层是什么(不必须)
输出层名称,让network知道输出层是什么,防止输出层被合并等操作优化、破坏。
uff模式下,input的输入信息
设置cuda的执行设备,默认值为{0},即使用‘0’号的GPU,这个数会以参数形式被传入cudaSetDevice方法。cudaSetDevice方法是为GPU执行设置设备的方法,即默认设置代号为‘0’的GPU设备,用它去申请host线程来执行以后的操作。当本机只有一个GPU的时候,并把值设置为{0,1},会报错“Cuda error in file src/implicit_gemm.cu at line 648: invalid device ordinal”。
设置GPU在执行过程中可以使用的最大temporary memory,默认值为16,会以参数的形式被传入setMaxWorkspaceSize方法中,使用时一般结合移位符:
setMaxWorkspaceSize(static_cast(gParams.workspaceSize) << 20
做迭代的次数,即每次迭代就会进行avgRun种策略的生成,最后每一次迭代都将avgRun种策略花费的时间做一次平均,然后输出。
每次迭代,都会做avgRun种优化策略的生成,然后计算几种优化策略的平均、
为支持DLA的layer指定DLA引擎,默认值为-1,即不设定。以下是对DLA的介绍。
Deep Learning Accelerator ,深度学习加速器。其中,英伟达推出的Xavier就是为自动驾驶开发的加速AI计算的Soc,它继承了新的Volta GPU架构,DLA是里面的inference加速器,功能类似于TPU。
DLA主要是为IoT设备设计的,如今的DLA只提供inference功能,在服务器端英伟达还是会采用传统的GPU设计。
(所以DLA应该是用于“片上系统”推理加速的一种产品或者说技术)
Soc:
System on clip。一般来说,Soc为系统级芯片,也叫片上系统,指它是一个产品,是一个有专有目标的集成电路,其中包含完整系统并有嵌入软件的全部内容。同时他又是一种技术,用以实现从确定系统功能开始,到软硬件的划分,并完成设计的整个过程。
TPU:
张量处理单元,是一种定制化的ASIC芯片,由谷歌从头设计,并专门用于机器学习工作负载。TPU 为谷歌的主要产品提供了计算支持,包括翻译、照片、搜索助理和 Gmail 等。(卷积神经网络的计算核心就是乘法与加法,也就是矩阵运算,所以硬件的处理关键点就是如何快速执行大型矩阵运算。)总之,TPU比GPU和CPU有更低的计算成本。
根据useDLACore的值,设置builder,确定是用DLA还是GPU。
仅仅在main.cpp下的configureBuilder方法中被调用一次。
是否打印log
做了一个类似保险的操作,当设置使用DLA的时候,而某个层不支持DLA的时候,会让它在GPU上跑。
被common.h中的enableDLA方法调用,默认值为true。在函数内部又被闭源的tensorRt函数allowGPUFallback调用,就是保证不能被DLA执行的去被GPU执行。
设置想要查看的阶段的时间,默认值为99,代表99%位置,会和vector类型的times共同作为参数传到percentile方法中。
例如,pct设置为99的时候,共10次avgRun的时候,结果中的percentile time会返回第0.99次的avgRun的时间,所以进行强制类型转换为int类型后,就是第9次的时间(从0开始,所以相当于第10次),也就是最后一次avgRun的时间。
同理,设置为16,共100次avgRun的时候,pct就控制结果中percentile time会返回第%16位置的第15次avgRun的时间;设置为1,就是第0次的avgRun的时间。
等待工作完成。 此选项可能会以额外的CPU使用量为代价减少多进程同步时间。
仅仅在Trtexec的doinference中被调用一次,根据其值决定cudaEventFlags这个变量的取值,以此来决定是用默认的方法调用cuda还是用block同步的方法调用cuda。
在测试的最后转储output。
默认值为false,仅仅在doinference中被使用一次,将输出device缓冲区的内容同步复制到输出host缓冲区,根据tensor的名字,找到这个output张量,然后把它转储到ostream中。