- 训练时对gredient量化,减少网络传输,加快训练速度(1-bit quantization)
- 预测模型量化,减少模型大小,使得能加载进内存或显存;计算时还是转成float计算;
- 预测模型量化,输入的样本也量化,中间激活值也用量化的,INT8和INT8直接计算,计算也加速了;
- 训练Forward时也进行伪量化,让训练的模型尽量往减少Forward误差上靠拢,从而减少预测时的量化误差;
Tensorflow里用的几种量化
hybrid量化和float16量化都只能减少模型大小,只量化模型参数;计算的时候要反量化成float32才能计算;
全整型量化,既减少模型大小,又大大加快计算速度;既量化模型参数,也量化激活结果和输入层;计算的时候直接in8和in8计算;(需要先跑一份小数据集,系统拿到所有激活值的min和max,从而决定量化Scale!)
神经网络量化简介
关键:
1. 确定float的min和max,可以是样本最多的区间(即不覆盖整个取值范围),让超出范围的样本取quantized_max或quantized_min; 确定zero_point,即float的0值对应的INT8的值是多少(INT8的0一般对应quantized_min, INT8的255一般对应quantized_max,所以zero_point一般是中间的一个uint数值)
2. 把float和float之间的计算,映射到INT8和INT8的计算上(即不需要INT8转成float再计算再转成INT8)
3. 工业界:着力于解决将 FP32 转换为 INT8 时碰到的实际问题。
量化矩阵乘法&训练过程也加入了量化
早先的Quantization技术用于推理多是在取得fp32计算训练好的模型参数权重之后,再对权重进行quantization,然后即使用scale过后的int8(or uint8)权重与op输入feature maps(亦经scale后变为了low-bits的表示)进行原本由fp32类型进行的乘法或乘加计算,如此执行所用的ops以完成整个模型推理过程。
而这一inference过程本质上与fp32 train时进行的forward的计算有较大区别的,毕竟在使用fp32类型进行forward/backward计算是并无引入任何scale之类的东西。这样train出来的weights经由quantized inference显然会有较大的精度损失风险。为了避免较大精度损失,成功地在fp32 train时考虑进入scaling的影响,作者们设计了一种与quantization inference相辅相成的带有simulated quantization的训练机制。
2016 ICLR: Deep Compression
1. pruning : 绝对值小于阈值的权重去掉(归0),剩下的权重用稀疏数组表示;index使用diff法(类似倒排索引的文档ID存储),diff太大的就用max_diff和0来接力; 分成3步:A.完全训练-->B.prune-->C.在剩下的边上继续训练-->调至B
2. train quantization:聚类+编码(w的聚类编码可以理解;g用和w相同的分组来组内累加梯度,并加到对应组的w_float上,看懂了!因为3.3节的那个求导公式,对聚类中心进行求导);初始聚类中心,使用在[min, max]之间线性均匀选择,这样聚类出来的结果往往能精准的表示绝对值大的w,因为大w对网络影响大,所以应该更精确的表示;
3. huffman coding:量化编码后的w们,还可以进一步使用哈夫曼编码来减少bit数;(省个20%~30%的网络传输,作用不大)
权重矩阵的SVD分解也是个路子,但是对accuracy的损失较大;
实时场景对时延要求苛刻,所以每来1个样本马上去infer,不等mini-batch到齐;所以矩阵-矩阵乘法变成了向量-矩阵乘法,后者访存和计算一样密集;pruning和量化可以使内存占用更小,缓存进cache,所以速度快;
用的cuSPARSE和MKL SPSPARSE库,去做稀疏向量和稀疏矩阵的乘法;因为现有库不支持量化,所以只用了pruning做实验;