一、AIP Runtime
AIP (AI Processor) Runtime是Q6、HVX和HTA三者在执行模型时候的一层软件抽象。
1、部署前提条件,让模型在AIP上执行的前提条件:
1)看硬件设备是否支持(查看前文中支持SNPE处理器的硬件列表);
2)量化模型如caffe转DLC格式时,需模型量化命令中带–enable_hta参数(–enable_partitions参数可选,表示一部分即subnet在HTA上执行,一部分即subnet在HNN上执行,调度通过Q6。具体见下文)。 相比量化,这个过程会调用HTA编译器,将编译好的AIP执行部分以二进制形式嵌入到DLC中。
在设备上使用DSP和AIP(也是DSP)的runtime是动态加载的,从而实现SNPE与AIP runtime的通讯。如安卓需要将对应DSP的库文件上传到对应路径,并export导入相关动态库和设备位置的环境变量ADSP_LIBRARY_PATH,ADSP或CDSP(即无论DSP或AIP runtime)都需要该环境变量。
2 内部调度
SNPE在用AIP计算时,会通过加载DSP的动态库从而与AIP runtime通讯,但调度管理器我想应该是Q6,通过Q6去管理使用HTA和HNN,下图的结构描述可以看到Q6是Hexagon DSP上的一部分,Q6这部分应该都是软件层面。
模型调用AIP执行过程中,SNPE Runtime上的AIP runtime会调用DSP执行器(executor,位于DSP动态库中),DSP执行器来调用HTA和HVX来管理模型的执行:
• 当DSP executor遇到HTA模型(部分),会通过HTA Driver调用HTA来执行模型该部分subnet;
• 当DSP executor遇到HVX模型(部分),会通过Hexagon NN来调用HVX执行该部分subnet。
不同部分在DLC量化过程中将相应的描述信息写到了量化后的DLC文件中,DSP executor遇到对应描述信息从而选择对应硬件驱动调用执行。
3 模型执行
因量化时可以选是否启用–hta_partitions以及对应的层数,若启用得到的模型会包含subnet。在执行过程中遇到subnet会被AIP runtime打断,根据subnet描述信息调用不同的硬件设备执行。
• HTA subnets:模型部分由HTA Compiler编译,位于DLC文件得到HTA部分;
• HNN subnets : 模型剩余部分可在DSP上调用Hexagon NN库完成计算。
目前,AIP只支持单独的HTA subnet + 单独的HNN subnet。此外,Adding HTA sections小节中还提到其它限制:HTA和HNN subnets只支持层的单一输入与输出;HTA subnet需要从第一层开始。
根据HTA、HNN subnets的分片,可将模型执行分为如下几种情况:
1)HTA subnet:runtime识别出DLC中描述信息整个网络都是HTA网络,完成计算后,如有必要先做计算结果的转换和反量化,再将输出结果返回给ARM CPU;
2)HTA subnet + HNN subnet:根据量化时的参数选择,模型的0-3层在HTA上计算,后面在HNN上计算。HTA subnet的输出交给HNN subnet作为输入,最后将结果给ARM CPU(同样,如有必要则需要反量化或转换操作);
3)TA subnet + HNN subnet + CPU subnet:这部分不同在于,前两个子网络在AIP上计算,最后几层交给ARM CPU完成计算。
二、SNPE性能与精度
下面是SNPE在小米MIX2上3个Runtime上做的benchmark。
• MIX2的SOC是骁龙835
• CPU:8核的大小核架构,1.9GHz+2.45GHz,大小核均为 Kryo280架构;
◦ 大核心频率2.45GHz,其大核心簇带有2MB的L2 Cache;
◦ 小核心频率1.9GHz,其小核心簇带有1MB的L2 Cache;
• GPU为Adreno 540@670MHz;
• DSP:Hexagon 690 DSP;
• AIP:无。
benchmark的4个模型有:AlexNet,GoogleNet,MobileNetV1/V2,SqueezeNetV1.1。一切参数根据CaffeModel和Prototxt基于SNPE提供的转换或量化工具而来。
1、 AlexNet
• 正确性验证,根据./models/alexnet/scripts/show_alexnet_classifications.py下的脚本,通过图像真实类别与网络分类类别比对,并非逐个featuremap单个元素值比较;
• fxp前缀:是使用snpe-dlc-quantize量化过的模型, 其量化策略采用8 bit的Tensorflow方式编码(下面相同),使用snpe的默认量化方式(snpe提供两种量化方式)。
2、GoogleNet
3、 MobileNetV1
4、 MobileNetV2
5、SqueezeNetV1.1
可以看出:
• 大模型DSP更有优势,小模型GPU和DSP差不多。但不能忽略的是DSP跑的都是int8量化的模型,若非量化模型,可能执行前DSP会自动量化模型初始化会占用一部分可被忽略的时间。
• 整体而言,GPU和DSP性能差不多,但GPU是float32或者float16,精度比只能跑int8的DSP要高一些,对检测、分割(如超分辨率)任务应该GPU(能加载原始非量化的模型)表现更好。GPU跑相同模型,float32和float16的推理时间差别不大,而且本身float16也能满足计算需要,在GPU情况下,可能选float32的模型更好;
• 高通对CPU的优化力度有限,毕竟DSP和GPU就是用来卸载CPU负载的,CPU与GPU/DSP相比,推理时间上慢了1到2个数量级;
• int8量化精度低。mobilenetv1和v2对于量化模型,无论是离线通过脚本转换,或者DSP直接加载float32模型做的int8定点量化,分类模型的计算结果全都错误。