工厂拿货回家加工,公司网站seo公司,网站改版301是什么,怎么找到网站后台做优化有时候真的很头疼#xff0c;绞尽脑汁的想怎么做算法等价#xff0c;怎么把神经网络各层指令流水起来#xff0c;在确保整网精度的同时#xff0c;又有高性能。
但有时做了半天#xff0c;却发现流水根本就流不起来#xff0c;总是莫名其妙地被卡住。
真的是一顿…做优化有时候真的很头疼绞尽脑汁的想怎么做算法等价怎么把神经网络各层指令流水起来在确保整网精度的同时又有高性能。
但有时做了半天却发现流水根本就流不起来总是莫名其妙地被卡住。
真的是一顿操作猛如虎回头一看原地杵。 今天介绍一种神经网络的性能优化方法。它不需要懂特深奥的算法知识就能做到整个优化系统大到网络小到算子的性能的成倍提升。
而且绝对是成倍的性能提升并且显而易见的算法等价。
怎么做呢很简单只需要改一下算子的先后调用顺序就行。
先说下背景。
在做AI推理或者训练时大部分情况下一个神经网络中的所有层Layer的计算数据类型是相同的。
比如为了网络有更好的识别精度神经网络中的运算可以使用高精度的浮点数如 float32简称 FP32。
但有时为了性能稍微损失一点识别精度也能接受此时可能会使用 float16简称FP16, 也就是半精度数据类型来做运算。
FP32 和 FP16 的区别在于前者数据位宽是后者的两倍因此表示相同的数据的时候前者的精度更高但内存占用也更大。
比如同时存储一张图片如果使用 FP32的话可能会占用1MB的内存但如果使用FP16来存储只占0.5MB的内存。
我们可能听说过混合精度推理、混合精度训练。这里说的混合指的就是精度混合。比如一个神经网络中存在多种数据类型。
为什么可以做混合精度的推理或训练呢
一个神经网络就像是一个大厦由一层一层的算法搭建而成每一层的算法可能不同。不同的算法对数据精度的敏感程度不同。
有很多算法对数据精度不敏感比如 transpose, gather, scatter等这类算法都是数据搬运操作也就是纯IO操作。他们不需要进行数据计算无需考虑数据在做加法时候的溢出处理等情况。
而有些算法对数据精度很敏感典型的比如conv2d算法它需要做大量的乘累加操作数据的累加很容易出现溢出此时需要用更高位宽的数据来接收累加结果。
如果把操作 FP32 比作需要搬运32块砖的话那么 FP16 就是只需要搬运 16块砖。很明显搬运16块砖比搬运32块砖在其他条件不变的情况下要省时省力。
因此在神经网络尤其是混合训练或推理的网络中如果遇到了一些数据搬运算法搬运的是 FP32那么是很有机会只让他搬16块砖(FP16)的。
那么具体怎么做呢?
首先简化一个神经网络假设一个神经网络有如下结构: 在这个假想的网络中卷积层conv2d计算的输出是 FP32然后送给transpose 层进行数据搬运transpose由于是纯IO算法因此它的输出也是FP32。
transpose的输出送给下一层castcast负责将FP32的数据转换为FP16, 因此cast 的输出是FP16。然后FP16的数据送给接下来的层进行运算。
不知有没有发现在这个网络中transpose 算法先搬运了FP32的数据然后交给了 cast 进行数据类型转换转换成了更低位宽的 FP16。
但是由于 transpose 是纯IO运算对数据类型不敏感因此我们完全可以将cast算子提前到 transpose 之前如此的话transpose 只需要做 FP16 的数据搬运。
转换之后的网络如下 这样做的结果就是整个网络的计算是等价的但是 transpose 算子却由原来进行 FP32 的数据搬运变成了 FP16 的数据搬运。对 transpose而言其IO性能表现是成倍的提升。
这只是举一个很简单的例子。
而实际上在真实的网络中使用此方法可以优化成功的算法有时不仅仅是一个简单的 transpose而是一个很大的网络片段。
由此可见仅仅将 cast 提前这一个简单的操作就能使整网的性能提升一倍。
这个方法很简单很有效也很容易实施。但是在实际进行网络优化的时候有时却会被忽略。
能够使用这一优化的网络必须满足以下两个条件 必须是混合精度的网络 由高位宽转低位宽的cast 算子前存在 IO 型算子
在我们绞尽脑汁使用一些高级的技巧如模型并行、层层流水来做网络优化的同时不妨放大视角着眼全图看看整网是否满足上面的条件没准只一眼就能发现这一最简单有效的优化点从此百分比的提升网络性能不是梦