SNPE使用之Int8量化的理解
[TOC]
概述
本系列的目是详细叙述当前移动端Int8的方方面面,从最底层的Int8的汇编层实现原理以及汇编性能优化手段,到中间层的移动框架的配套代码实现(标准就以NCNN为例吧),以及上层对应的PC端量化方法(各种论文思路)总结及实现,和最后模型端re-train的方法、策略及指标介绍。
此外,利用PowerPerf(一种专门针对ARM CPU应用性能优化而开发的调试工具)对卷积kernel(汇编算子)各项硬件参数指标进行量化优化也是本文的重点,旨在提炼出一套通用的汇编代码调优方法论,从而使得PowerPerf能适用于所有移动端CPU性能优化场景。
背景
尽管模型size在不断地压缩,但是其计算量通常还是有一两百MFLOPS的样子,这个计算量对于目前的(中低端)移动端CPU算力来说,还是有点吃力的,因此模型端做了最大的努力,移动端也要不甘示弱努力加油!
通常移动端加速的方案时分CPU派跟GPU派的,目前在低端机型上arm的mali GPU性能较差,所以基本配备的还是CPU方案,而中高端机其配备的GPU大部分就是高通的了,其性能整体比CPU强劲,因此,目前在不同的定位平台上不同的方案各有优势,各自根据具体的场景适配选择方案即可。
上图1-1是前一阵子(2018.7.12)ARM在腾讯做介绍的ppt,可以看到性能可观!!!可以看到arm在cpu这块会针对性地加强AI能力,我们再看个截图:
INT8量化原理
目前最简单的实现方案是英伟达的tensorRT方案,直接量化,无需retrain,实现简单;
其次就是谷歌的那套方案,稍显复杂需要retrain;
retrain的要求就是,你的权值、激活值(实测对最终精度的影响不是很大)都必须是分布比较均匀的,也就是方差不要太大。其次是能否控制每层的输出在一定的范围内,这对我们做int8量化时,溢出的处理很有帮助。
NVIDIA的方案是公开了的,但是并没有开源,也就是说你只能用他的那一套工具(tensorRT)来进行量化、部署,当然很正常的,我们也想用他的量化校准部分获取校准参数,然后移动端直接用,目前发现是导不出来这些中间参数的,而且也没源码,在安装包内的python借口也是调用的so文件;它们给的ppt链接如下:
接下来我在这章将详细分析其原理(python实现单独拿一篇来讲,因为里面有一些小细节需要说清楚),并将在实现过程中碰到的坑一一解剖之(也就是ppt中说的一个很简单的思路,但是在实现的时候是有很多小细节是不确定的,需要一一验证的,NVIDIA的ppt是不会告诉你这些细节的,需要我们来好好理解消化)。
我们首先整体过一遍原理:
我们的目的是把原来的float 32bit 的卷积操作(乘加指令)转换为int8的卷积操作,这样计算就变为原来的1/4,但是访存并没有变少哈,因为我们是在kernel里面才把float32变为int8进行计算的。
最粗糙、最本质的原理就是这个图: