nvidia tensorrt 支持循环结构,这对于循环网络很有用。 tensorrt 循环支持扫描输入张量、张量的循环定义以及“扫描输出”和“最后一个值”输出。
10.1. defining a loop
循环由循环边界层(loop boundary layers)定义。
itriplimitlayer指定循环迭代的次数。
iiteratorlayer使循环能够迭代张量。
irecurrencelayer指定一个循环定义。
iloopoutputlayer指定循环的输出。
每个边界层都继承自类iloopboundarylayer ,该类有一个方法getloop()用于获取其关联的iloop 。 iloop对象标识循环。具有相同iloop的所有循环边界层都属于该循环。
下图描绘了循环的结构和边界处的数据流。循环不变张量可以直接在循环内部使用,例如 foolayer 所示。
一个循环可以有多个iiteratorlayer 、 irecurrencelayer和iloopoutputlayer ,并且最多可以有两个itriplimitlayer ,如后面所述。没有iloopoutputlayer的循环没有输出,并由 tensorrt 优化。
nvidia tensorrt 支持矩阵中的流控制结构层部分描述了可用于循环内部的 tensorrt 层。
内部层可以自由使用在循环内部或外部定义的张量。内部可以包含其他循环(请参阅嵌套循环)和其他条件构造(请参阅条件嵌套)。
要定义循环,首先,使用inetworkdefinition ::addloop方法创建一个iloop对象。然后添加边界层和内部层。本节的其余部分描述了边界层的特征,使用loop表示inetworkdefinition ::addloop返回的iloop* 。
itriplimitlayer支持计数循环和 while 循环。
loop -》addtriplimit( t ,triplimit::kcount)创建一个itriplimitlayer ,其输入t是指定循环迭代次数的 0d int32 张量。
loop -》addtriplimit( t ,triplimit::kwhile)创建一个itriplimitlayer ,其输入t是一个 0d bool 张量,用于指定是否应该进行迭代。通常t要么是irecurrencelayer的输出,要么是基于所述输出的计算。
一个循环最多可以有一种限制。
iiteratorlayer支持在任何轴上向前或向后迭代。
loop -》additerator( t )添加一个iiteratorlayer ,它在张量t的轴 0 上进行迭代。例如,如果输入是矩阵:
2 3 5
4 6 8
第一次迭代的一维张量{2, 3, 5}和第二次迭代的{4, 6, 8} 。超出张量范围的迭代是无效的。
loop -》additerator( t , axis )类似,但该层在给定的轴上迭代。例如,如果 axis=1 并且输入是矩阵,则每次迭代都会传递矩阵的一列。
loop -》additerator( t , axis,reverse )类似,但如果reverse =true ,则该层以相反的顺序产生其输出。
iloopoutputlayer支持三种形式的循环输出:
loop -》addloopoutput( t, loopoutput::klast_value)输出t的最后一个值,其中t必须是irecurrencelayer的输出。
loop-》 addloopoutput( t ,loopoutput::kconcatenate, axis )将每次迭代的输入串联输出到t 。例如,如果输入是一维张量,第一次迭代的值为{ a,b,c} ,第二次迭代的值为{d,e,f} , axis =0 ,则输出为矩阵:
a b c
d e f
如果axis =1 ,则输出为:
a d
b e
c f
loop-》 addloopoutput( t ,loopoutput::kreverse, axis )类似,但颠倒了顺序。 kconcatenate和kreverse形式都需要第二个输入,这是一个 0d int32 形状张量,用于指定新输出维度的长度。当长度大于迭代次数时,额外的元素包含任意值。第二个输入,例如u ,应使用iloopoutputlayer::setinput(1, u )设置。
最后,还有irecurrencelayer 。它的第一个输入指定初始输出值,第二个输入指定下一个输出值。第一个输入必须来自循环外;第二个输入通常来自循环内部。例如,这个 c++ 片段的 tensorrt 模拟:
for (int32_t i = j; 。..; i += k) 。..
可以通过这些调用创建,其中j和k是itensor* 。
iloop* loop = n.addloop();
irecurrencelayer* irec = loop-》addrecurrence(j);
itensor* i = irec-》getoutput(0);
itensor* inext = addelementwise(*i, *k,
elementwiseoperation::kadd)-》getoutput(0);
irec-》setinput(1, *inext);
第二个输入是tensorrt允许后沿的唯一情况。如果删除了这些输入,则剩余的网络必须是非循环的。
10.2. formal semantics
tensorrt 具有应用语义,这意味着除了引擎输入和输出之外没有可见的副作用。因为没有副作用,命令式语言中关于循环的直觉并不总是有效。本节定义了 tensorrt 循环结构的形式语义。
形式语义基于张量的惰性序列(lazy sequences)。循环的每次迭代对应于序列中的一个元素。循环内张量x的序列表示为〈 x 0, x 1, x 2, 。.. 〉 。序列的元素被懒惰地评估,意思是根据需要。
iiteratorlayer(x)的输出是〈 x[0], x[1], x[2], 。.. 〉其中x[i]表示在iiteratorlayer指定的轴上的下标。
irecurrencelayer(x,y)的输出是〈 x, y0, y1, y2, 。.. 〉 。 的输入和输出取决于loopoutput的类型。
klast_value :输入是单个张量x ,对于 n-trip 循环,输出是x n 。
kconcatenate :第一个输入是张量x,第二个输入是标量形状张量y。结果是x0, x1, x2, 。.. xn-1与后填充(如有必要)连接到y指定的长度。如果y 《 n则为运行时错误。 y是构建时间常数。注意与iiteratorlayer的反比关系。 iiteratorlayer将张量映射到一系列子张量;带有kconcatenate的iloopoutputlayer将一系列子张量映射到一个张量。
kreverse :类似于kconcatenate ,但输出方向相反。
iloopoutputlayer的输出定义中的n值由循环的itriplimitlayer确定:
对于计数循环,它是迭代计数,表示itriplimitlayer的输入。
对于 while 循环,它是最小的 n 使得$x_n$为假,其中x是itriplimitlayer的输入张量的序列。
非循环层的输出是层功能的顺序应用。例如,对于一个二输入非循环层f(x,y) = 〈 f(x 0 , y 0 ), f(x 1 , y 1 ), f(x 2 , y 2 )。.. 〉 。如果一个张量来自循环之外,即是循环不变的,那么它的序列是通过复制张量来创建的。
10.3. nested loops
tensorrt 从数据流中推断出循环的嵌套。例如,如果循环 b 使用在循环 a 中定义的值,则 b 被认为嵌套在 a 中。
tensorrt 拒绝循环没有干净嵌套的网络,例如如果循环 a 使用循环 b 内部定义的值,反之亦然。
10.4. limitations
引用多个动态维度的循环可能会占用意外的内存量。 在一个循环中,内存的分配就像所有动态维度都取任何这些维度的最大值一样。例如,如果一个循环引用两个维度为[4,x,y]和[6,y]的张量,则这些张量的内存分配就像它们的维度是[4,max(x,y),max(x ,y)]和[6,max(x,y)] 。
带有klast_value的loopoutputlayer的输入必须是irecurrencelayer的输出。 循环 api 仅支持 fp32 和 fp16 精度。
10.5. replacing irnnv2layer with loops
irnnv2layer在 tensorrt 7.2.1 中已弃用,并将在 tensorrt 9.0 中删除。使用循环 api 合成循环子网络。例如,请参阅samplecharrnn方法samplecharrnnloop::addlstmcell 。循环 api 让您可以表达一般的循环网络,而不是局限于irnnlayer和irnnv2layer中的预制单元。
关于作者
ken he 是 nvidia 企业级开发者社区经理 & 高级讲师,拥有多年的 gpu 和人工智能开发经验。自 2017 年加入 nvidia 开发者社区以来,完成过上百场培训,帮助上万个开发者了解人工智能和 gpu 编程开发。在计算机视觉,高性能计算领域完成过多个独立项目。并且,在机器人和无人机领域,有过丰富的研发经验。对于图像识别,目标的检测与跟踪完成过多种解决方案。曾经参与 gpu 版气象模式grapes,是其主要研发者。
HT塑料配电箱的类型都有哪些
介绍一种基于光信号的应变传感器
基于GPRS的电网调度自动化系统
在集成电路产业无锡因自主创新获得了自主可控技术
嵌入式FPGA能随时更改RTL的灵活性,将改变芯片和SoC未来的设计方式
NVIDIA TensorRT支持矩阵中的流控制结构层部分
降低开关电源输出纹波与噪声的方案
人工智能文案写手比人类更占上风
基于AI的应用Google Translate可以帮助非英语国家的患者及其提供者
基于微控制器的MicroPython模块运行
FDD和TDD共通融合,促进LTE全球发展
一加3Tcolette纪念版正式发布,配置亮点和价格介绍
你知道为什么Julia的速度能做到那么快吗?
政策利好半导体材料行业发展,中国半导体国产替代空间巨大
5G时代来临 WiFi面临着大批量测试挑战
软硬件整合布局,ARM大举进攻物联网
如何判断标准PoE供电交换机的可靠性?
气象观测传感器质量如何
简易夜间自动照明电路
恩智浦推出安全三无线电设备 瑞萨电子推出SIL3认证解决方案