Hass optimization AI HI3516DV300 SSD-chip code


Some time ago I have been doing work on the optimization of AI Hass chip HI3516DV300 SSD code summarize here some of the feelings and experiences optimized. The reason for doing the optimization of the Hass AI chip HI3516DV300 SSD Code, in part because the SSD running on the CPU, and the CPU performance on HI3516DV300 relatively poor, as long as the slightly more complex network, CPU part of the operation will be very slow. The following table gives the time some models running on the chip, you can see part of CPU time to run up the majority.
Note: Because of my job, too inconvenient to have some details elaborated in a blog, I hope you understand

Here Insert Picture Description
Note:
Forward here corresponds SAMPLE_SVP_NNIE_Forward () function, which is basically running on the NNIE, GetResult SAMPLE_SVP_NNIE_Ssd_GetResult function corresponding to this function is running directly behind on the function represented by CPU GetResult


DetectionOutForward optimization

Analysis of performance bottlenecks

By GetResult function analysis showed mainly two functions in the Processed: SVP_NNIE_Ssd_SoftmaxForward and SVP_NNIE_Ssd_DetectionOutForward, and directly behind representing SoftmaxForward DetectionOutForward.
Here Insert Picture Description

DetectionOutForward further analysis function, wherein DetectionOutForward mainly includes two steps, which correspond to the two parts for the two cycles:

  1. decode box: the predicted value of the output switching network to an actual coordinate value, this part referred to as Loop1
  2. NMS: do the NMS to the highest bbox before topk a confidence level for each class of targets, this section referred to as Loop2

Processed found mainly in the Loop1
Here Insert Picture Description
Loop1 corresponding to the following code:
Here Insert Picture Description

分析Loop1代码,Loop1主要功能是对所有anchor的预测值进行解码转换为anchor在图像中实际的坐标值。
Here Insert Picture Description
对每一个anchor都需要调用两次exp()函数(上图中红框标出的部分),这个函数是一个非常耗时的函数,45120个anchor一共调用90240次exp(),通过测试发现90240次exp()调用需要耗时21ms,如果能够减少exp()的调用次数,将会大大减少时间。
由于实际做NMS的时候,我们只对前topk个置信度最高的bbox做NMS,也就是说只会用到前topk个bbox的真实坐标值,其他bbox的坐标值用不到,所以我们只需要计算出前topk个bbox的真实坐标值就可以了,这里topK设置为400,也就是说只需要执行800次exp操作就可以,而800次exp操作只需要0.2ms,可以大大减少时间。

但是最后做NMS的时候,使用的是图1中蓝框中的4个变量,而如果要计算出真实坐标值,就必须要知道网络输出的预测值和priorbox的坐标,也就是如果要计算出前topk个bbox的真实坐标值,就必须要知道每个bbox对应的8个变量,图1中红框和绿框中的8个值。

Here Insert Picture Description图1

8个值:

ps32PriorBoxes[jSAMPLE_SVP_NNIE_COORDI_NUM]
ps32PriorBoxes[j
SAMPLE_SVP_NNIE_COORDI_NUM+1]
ps32PriorBoxes[jSAMPLE_SVP_NNIE_COORDI_NUM+2]
ps32PriorBoxes[j
SAMPLE_SVP_NNIE_COORDI_NUM+3]
ps32LocPreds[jSAMPLE_SVP_NNIE_COORDI_NUM]
ps32LocPreds[j
SAMPLE_SVP_NNIE_COORDI_NUM+1]
ps32LocPreds[jSAMPLE_SVP_NNIE_COORDI_NUM+2]
ps32LocPreds[j
SAMPLE_SVP_NNIE_COORDI_NUM+3]

下面的问题就是如何将每个bbox对应的这8个变量编码到4个变量中,通过对每个bbox对应的8个变量分析发现:

  1. 由于网络输入大小是512,也就是图像中的坐标在[0,512]之间,也就是ps32PriorBoxes的值也在[0,512]之间,也就表示ps32PriorBoxes的值可以通过3位数来表示
  2. ps32LocPreds的值有正有负,而且值的范围可以使用5位数表示

基于上面的发现,设计了以下编码方式:

ps32LocPreds * 10000+ps32PriorBoxes * 10+flag

其中flag为标记位,当ps32LocPreds值为负数时,flag为0,当ps32LocPreds值为正数时,flag为1
而且编码之后的值全部转换为正数,便于解码。
这个编码的含义就是:最后一位是标记位,倒数第2到第4位是priorbox的值,剩下的位数是位置预测值
示例:
-3852,125→38521250
5017,96→50170961
-13590,145→135901450
Here Insert Picture Description
最后,在NMS的时候,进行解码就可以计算出真实坐标值了,比如对每个bbox编码之后的4个值的第一个值进行解码:
Here Insert Picture Description

这样就可以得到需要的8个值,最后根据这8个值就可以计算出该bbox的真实坐标值了
Here Insert Picture Description

使用优化后的代码进行速度测试
Here Insert Picture Description
行人检测器Loop1经过优化后从原来的34ms提高到了7ms,速度得到了明显提高,由于Loop2增加了解码的时间,所以Loop2会略微变慢,但是总体时间还是大大降低了。
优化之后对精度是完全没有影响的。


NMS的优化

AI芯片中官方给的SSD代码在对每一类做NMS的时候,实现上有点bug,官方代码中,当类别为背景的时候,也做了NMS。
当类别为背景的时候,是不需要对所有的预测框做NMS的,这样可以节省很多时间。
Here Insert Picture Description

修改后的代码:
Here Insert Picture Description
优化后的时间:
Here Insert Picture Description
我们可以看到优化后Loop2的时间大大降低,在CPU上运行的时间基本上降低为原来的一半了。


Softmax的优化

上面分析了GetResult函数主要耗时在两个函数中:SoftmaxForward和DetectionOutForward。上面对DetectionOutForward进行了优化,那么SoftmaxForward是否可以优化呢?

分析了SoftmaxForward函数,发现计算所有anchor的置信度的时候,45120个anchor也需要调用90240次exp(),需要耗时21ms。

我们知道softmax概率的计算公式如下:
Here Insert Picture Description
在对softmax进行优化的时候,我做了一个实验,直接使用fi表示softmax置信度,然后在多个模型中做了测试:
数据集A:
Here Insert Picture Description
数据集B:
Here Insert Picture Description
我发现一个很奇怪的现象:直接使用fi代替softmax概率,大部分模型精度基本上没有损失。同时也观察了一系列模型的结果,发现softmax概率大的目标往往fi值也大。 目前还不知道具体原因。有知道其中原因的朋友欢迎留言讨论。

Here Insert Picture Description

由于去掉了softmax的计算,所以时间会大大减少,上表中可以看到去掉了softmax计算后,从原来的77ms直接降低到了18ms,速度提高了4倍多。但是由于目前对这种现象的原因还不明确,所以暂时是没有使用的。


结束语

通过本次优化,深刻体会到了算法性能的重要性,PC上很快的一个操作,在其他平台很可能就是性能的瓶颈。同时也体会到了深入理解算法的重要性以及将速度做到极致的那种成就感。


非常感谢您的阅读,如果您觉得这篇文章对您有帮助,欢迎扫码进行赞赏。
Write pictures described here

发布了42 篇原创文章 · 获赞 313 · 访问量 44万+

Guess you like

Origin blog.csdn.net/qianqing13579/article/details/103003808