基于Distiller的模型压缩工具简介

基于Distiller的模型压缩⼯具简介
Reference:
PART I: 介绍
Distiller模型压缩包含的算法:  稀疏算法(剪枝+正则化)+低精度算法(量化)
Distiller特点:
(1)    该框架融合了剪枝,正则化及量化算法
(2)    ⼀系列分析及评估压缩性能的⼯具
(3)    较流⾏压缩算法的应⽤
稀疏神经⽹络可以基于 (weight and biases) activations的稀疏tensor进⾏计算。
关注稀疏度的原因:对于像GoogleNet 之类的⼤型⽹络,对计算⼗分敏感,在经过加速处理过的设备上进⾏inference仍需花费⼤量时间。较⼤的模型占⽤内存资源
在移动端模型的存储及转移主要受到模型的⼤⼩及下载时间限制
Smaller
具有稀疏表⽰的数据并不需要进⾏解压缩
三种表⽰⽅法:1.稀疏表⽰,2.密集表⽰,3.针对硬件特点进⾏特殊的表⽰
通过剪枝及正则化处理,对于向量计算的compute engine的权重删除。
Faster
神经⽹络中的许多层都是bandwidth-bound,这意味着执⾏时间主要是被可利⽤的bandwidth占⽤,其中,占⽤时间⽐较长的为全连接层,同时RNN及LSTM层存在⼤量的bandwidth-dominated操作。
Pruning:对⽹络中的权重及激活值进⾏稀疏化处理,基于⼆元标准来进⾏决定那个权重可以修剪。将满⾜修剪标准的权重进⾏赋值为0并不让其参见反向传播运算。可修剪的对象包括:权重,偏差及激活值。
稀疏性:张量中存在0元素的个数占整个tensor向量中的⽐例,L0正则化,统计⾮0元素的个数
上海航天冰箱
Density = 1 – sparsity
Distiller⼯具:distiller.sparsity distiller.density
权重/模型修剪:⽤于提⾼⽹络权重稀疏性的⼀系列⽅法,通过⼀个修剪标准来决定哪个元素需要进⾏修剪,标准即pruning criteria,最常⽤的标准是每个元素的绝对值,其值与某个阈值进⾏⽐较,如果低于这个阈值,就将该元素的值置为0.
Distiller⼯具:distiller.MagnitudeParameterPruner 基于L1正则化的对于最终结果贡献量较⼩的权重重要性较低,⽽且可以被移除。
对于prune的理解 :参数量较⼤的模型中,存在⼤量的逻辑及特征冗余。⼀种想法是搜索尽可能多的权值为0的权重,同时在inference时可以达到与密集模型相似的准确率。另⼀种想法是,在⾼维度的参数空间中,密集模型的解空间中可能会存在⼀些稀疏解,修剪算法就是为了寻这个稀疏解。
One-shot pruning :对⼀个训练好的模型进⾏⼀次修剪
Iterative training :pruning-followed-by-retraining(fine-tuning),在训练迭代过程中,需要考虑的问题包括:pruning的标准是如何改变,迭代多少次,多久变化⼀次,那些张量需要被prune,这些被称为pruning schedule
对Iterative pruning 的理解:基于⼀个评价标准将权重进⾏重复训练学习,判断哪个权重是重要的,并将不重要的权重进⾏删除。调整后的权重将模型进⾏性能上的恢复,每次迭代修剪更多的权重。
修剪的停⽌条件也在schedule中,其取决于修剪算法。停⽌条件两个参考: specific sparsity level,required compute budget
修剪粒度(pruning granularity):对单个权重元素进⾏修剪,称为element-wise修剪,有时被称为find-grained pruning
Coarse-grained pruning: structure pruning , group pruning(filter pruning整个filters被移除),block pruning
敏感度分析:
将稀疏性引⼊修剪过程中的难点在于:对于每层⽹络张量中,阈值的选择及sparsity level,根据张量对修剪的敏感度进⾏排序。
甲苯胺蓝其思想是,针对特定的⽹络层设置pruning level(percentage),只对模型修剪⼀次,然后在测试数据集上进⾏评估并记录得到的分数值。若在每个参数化的⽹络层上应⽤此⽅法,在每个层上设置多个sparsity levels,可以得到每个层对于修剪的敏感性。
在进⾏敏感度分析前,预训练模型应达到最⼤的准确率,这是因为需要了解对于特定层权重的修剪对模型的性能造成的影响。
Distiler可以对结构进⾏敏感性评估,基于L1 –normal的独⽴元素进⾏element-wise pruning 敏感度分析以及基于filters间的mean L1-Norm 的filter-wise pruning 。相关函数:perform_sensitivity_analysis
正则化: 对模型算法进⾏修改的主要⽬的是减少generalization loss⽽不是训练损失。
正则化与⽹络稀疏表达的关系:
通过稀疏修剪对模型进⾏正则化处理:在给定sparsity constraint的限制条件下,⽹络⼀旦达到了局部最⼩值,则放宽限制条件,让⽹络可以以更⾼准确率逃离局部极⼩值的鞍点。
正则化也可以应⽤到稀疏表达中:L2正则化可以减少过拟合,同时压缩较⼤值的参数,但⽆法使这些参数的值完全变为0。⽽L1正则化则可以将某些参数置为0,在限制模型的同时对模型进⾏了简化处理。
Group Regularization:
对整个groups of parameter elements进⾏正则化处理。⽆论这个group是否被稀疏化处理过,该group结构都要预先定义。
Distiller中的相关函数: distiller.GroupLassoRegularizer
量化
量化是减少表⽰⼀个数的bit位数的过程,deep learning中的主流精度为32位浮点精度。为了降低⽹络模型的带宽及计算需求,开始转向较低精度的研究。
如果权重为⼆值的,如(-1,1)或者为(-1,0,1)则卷积层及全连接层中的计算可以由加减操作执⾏,将乘法操作完全移除。如果激活值也为⼆值类型的,则加法操作也可以移除,可以⽤位运算代替。
Integer与FP32的对⽐
数字精度的两个属性,I:动态范围,即可以表⽰数字的范围。II:根据需要表⽰的数值来决定精度。对于n位整形数字,其动态范围为[-2^(n-1)..2^(n-1)-1],INT8:[-128,127],可以表⽰2^(N)个数字,⽹络模型中32位精度能够表⽰的分布范围更⼴,同时,模型中不同层动态范围是不同的,权重及activation的分布也是不同的。
为了将tensor的浮点动态范围映射到整数精度的范围内增加了⼀个scale factor,scale factor⼤部分情况为浮点型。
避免溢出
累加器中存放卷积层及全连接层的中间结果。如果,将权重以及激活值的设置相同的⽐特位,很快就会溢出。因此,累加器中的精度要更⾼⼀些。两个n-bit的数字相乘得到2n-bit的数字,卷积层中存在c*k^2次乘法操作,为了避免溢出,累加器的位数应为(2n+M),M⾄少为log2(c*k^2)
保守量化:INT8
如果将⼀个FP32的预训练模型不进⾏再训练直接将其量化为INT8,则会造成⼀定准确率的损失。
Simple factor的设置:根据每个tensor中的每⼀层进⾏确定,最简单的⽅式就是将float tensor中的min/max映射为integer中的min/max,对于权重及偏差,这种操作⽐较简单,是因为其训练完成后,其值是固定的,⽽对于activation,其值可以从两个⽅⾯进⾏获得。
(1)Offline:即在部署模型之前进⾏激活值统计操作,基于统计的信息,计算得到scale factor,当模型部署完后将其值固定。这种⽅式存在⼀定的风险,即运⾏时,遇到的值超出了原来观察到的范围,⽽这个超出的值会被clip,进⽽造成准确率上的损失。
(2)Online:即在运⾏时动态的计算tensor中的min/max值。这种⽅式不会发⽣clip情况。⽽增加的计算量却很⼤。
基于全精度的激活层存在异常值,可以通过缩⼩min/max的范围将这个异常值进⾏丢弃,同时,也可以通过clip操作来提⾼包含主要信息部分的精度。⼀种简单有效的⽅式是⽤min/max的均值来替换实际的值
另⼀个可以优化的点是scale factor:最常⽤的⽅法是每⼀层使⽤scale-factor,也可以每个通道进⾏设置。
贪婪型量化:INT4
动画片卖猪
将FP32模型直接量化为INT4或者更低的精度,使准确率⼤幅度降低
解决⽅法:
(1)    training/retraining:将量化考虑到训练中
(2)    替换激活函数:将⽆边界的ReLU替换为有边界的激活函数。
(3)    调整⽹络的结构:通过增加层的宽度来弥补由于量化产⽣的损失信息。或者将卷积⽤多个⼆值卷积进⾏替换,通过scale可以调整覆盖更⼤的范围
(4)    模型的第⼀层和最后⼀层不进⾏量化操作
(5)    迭代量化:⾸先对预训练的FP32的模型进⾏部分量化,然后进⾏再训练恢复由于量化产⽣的准确率的损失
(6)    将权重及激活值的精度进⾏混合:激活对量化的敏感度相⽐权重要更敏感⼀些
包含量化的训练
训练过程中全精度的权重也被保留,⽤于记录精度损失造成的梯度上的变化,inference时只有量化后
的权重起作⽤。
PART II: 基于Distiller 的分类模型
Step I : git clone
Step II: 创建环境 python3 –m virtualenv env (安装参考: )
StepIII: cd distiller  && pip3 install -e .
StepIV: cd distiller/examples/classifier_compression
StepV: 只对模型进⾏训练,不进⾏压缩处理
荔湾3-1python3 compress_classifier.py --arch simplenet_cifar ../../../data.cifar10 -p 30 -j=1 --lr=0.01
中国邮政华为合作--arch:模型名称
-p:打印频率
-j: 线程
-
-lr:学习率
StepVI: 统计稀疏模型的参数
python3 compress_classifier.py --resume=../ssl/checkpoints/checkpoint_trained_ch_regularized_dense.pth.tar -a=resnet20_cifar ../../../data.cifar10 --summary=sparsity
--resume:稀疏模型⽂件路径
--summary: {sparsity,compute,model,modules,png,png_w_params,onnx}
Sparsity:统计稀疏信息
Compute:统计计算量信息
Model:详细的模型描述
Modules:每层对应的类型
PNG:将⽹络结构保存为图⽚
png_w_params:将⽹络中的权重信息保存为图⽚
打印信息
Name:处理层名称
Shape:该层尺⼨
NNZ(dense):稀疏前该层的参数量,其值为shape[0]*shape[1]*shape[2]*shape[3]
NNZ(sparse):处理后该层的参数量。
Cols,Rows,Ch,2D,3D,Fine分别代表,在纵向,横向,Channel-wise,Kernel-wise,Filter-wise,Element-
wise(属于Fine-grained pruning)上参数稀疏的程度,其值为(NNZ(dense)-NNZ(sparse)) / NNZ(dense) Std:该层的标准差
Mean: 该层的均值
Abs-Mean:该层绝对值的均值
Total sparsity = (total_NNZ(dense) – total_NNZ(sparse)) / total_NNZ(dense)
StepVII: 统计稀疏模型的计算量
python3 compress_classifier.py --resume=../ssl/checkpoints/checkpoint_trained_ch_regularized_dense.pth.tar -a=resnet20_cifar ../../../data.cifar10 --summary=sparsity
Name:该层名称
Type:该层的类型
Attrs: 卷积核⼤⼩
IFM:输⼊尺⼨
IFM volume:输⼊维度 = IFM[0] * IFM[1] * IFM[2] * IFM[3]
OFM:输出尺⼨
OFM volume:输出维度 = OFM[0] * OFM[1] * OFM[2] * OFM[3]
Weights volume:权重维度 = Attrs[0] * Attrs[1] * IFM[1] * OFM[1]
MACs  = OFM[2] * OFM[3] * Weights volume
Step VIII: post-training quantization
python3 compress_classifier.py -a resnet20_cifar ../../../data.cifar10 --resume ../ssl/checkpoints/checkpoint_trained_dense.pth.tar --quantize-eval --evaluate
--quantize-eval 在进⾏evaluate前进⾏线性量化操作
PART III: Distiller 代码部署步骤
Step I:  在 main.py中增加代码
1. Preparing the code: 调⽤Distiller  通过sys.path将distiller的根⽬录引⼊到main.py⽂件中。
2. 置定义输⼊参数
--summary:有关压缩说明
--compress:指明 compression schedule⽂件路径
增加对上⾯两个参数的处理代码
3. Optimizer及learning-rate decay policy scheduler
4. setup the logging backends:⼀个是Python logger backend⽤于从⽂件及命令⾏中读取参数;另⼀个是TensorBoard backend logger将logs信息变为tensorboard 数据⽂件(tflogger)
5. Training loop:
6. 下列代码位于train中⽤于记录信息
虎门销烟教学设计7. 在train外进⾏迭代训练优化

本文发布于:2024-09-23 01:34:51,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/53845.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:模型   权重   修剪
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议