其他
【他山之石】pytorch量化备忘录
“他山之石,可以攻玉”,站在巨人的肩膀才能看得更高,走得更远。在科研的道路上,更需借助东风才能更快前行。为此,我们特别搜集整理了一些实用的代码链接,数据集,软件,编程技巧等,开辟“他山之石”专栏,助你乘风破浪,一路奋勇向前,敬请关注。
地址:https://www.zhihu.com/people/wu-er-dong
01
什么是量化?
02
为什么要量化?
减小模型尺寸和存储空间,如int8量化可减少75%的模型大小; 加快推理速度,访问一次32位浮点型可以访问四次int8型,运算更快; 减少设备功耗,内存耗用少了推理速度快了自然减少了设备功耗; 支持微处理器,有些微处理器属于8位的,低功耗运行浮点运算速度慢,需要进行8bit量化;
增加了操作复杂度,有时会有一些特殊处理,甚至会有tradeoff,比如你发明了一个牛13的算子,可惜现有的量化工具不支持,自己实现又头大,只能忍痛割爱; 会损失一定的精度,所以有时会有微调,但也会有损失;不过值得一提的是,每次我用openvino量化,精度不降低反而还会升高一丢丢。这是因为模型参数是非常冗余的,量化可以看成一种正则化技术,会提升模型的泛化能力,可能在测试集上会表现好一点。不过都是事后诸葛的理论分析了,具体还是要看测试指标的。
03
怎么量化?
04
pytorch怎么做?
qnnpack fbgemm
05
量化步骤
权重转为int8数据类型存储; 模型融合的conv+bn+relu; 存储每层的量化参数: 量化缩放因子和zero-point; 对模型进行量化;
06
量化方式
Post Training Dynamic Quantization:最简单的量化方法,Post Training指的是在浮点模型训练收敛之后进行量化操作,其中weight被提前量化,而activation在前向推理过程中被动态量化,即每次都要根据实际运算的浮点数据范围每一层计算一次scale和zero_point,然后进行量化; Post Training Static Quantization:第一种不是很常见,一般说的Post Training Quantization指的其实是这种静态的方法,而且这种方法是最常用的,其中weight跟上述一样也是被提前量化好的,然后activation也会基于之前校准过程中记录下的固定的scale和zero_point进行量化,整个过程不存在量化参数(scale和zero_point)的再计算; Quantization Aware Training:对于一些模型在浮点训练+量化过程中精度损失比较严重的情况,就需要进行量化感知训练,即在训练过程中模拟量化过程,数据虽然都是表示为float32,但实际的值的间隔却会受到量化参数的限制。
07
后训练量化
def __init__(self):
self.quant = QuantStub()
self.dequant = DeQuantStub()
def forward(self, x):
x = self.quant(x)
# ------ # # 网络forward # ------ #
x = self.dequant(x)
return x
self.skip_add = nn.quantized.FloatFunctional()
z = self.skip_add.add(x, y) # 原来的是: z = x + y
resnet18_fused = torch.quantization.fuse_modules( resnet18,
[['conv1', 'bn1', 'relu'],
['layer1.0.conv1', 'layer1.0.bn1'], # , 'layer1.0.relu'],
['layer1.0.conv2', 'layer1.0.bn2'],
['layer1.1.conv1', 'layer1.1.bn1'], # , 'layer1.1.relu'],
['layer1.1.conv2', 'layer1.1.bn2']])
q_backend = 'qnnpack' # "qnnpack"
qconfig = torch.quantization.get_default_qconfig(q_backend)
torch.backends.quantized.engine = q_backend
resnet18_fused.qconfig = qconfig
torch.quantization.prepare(resnet18_fused, inplace=True)
with torch.no_grad():
for image, target in data_loader:
output = model(image)
resnet18_fused = resnet18.cpu()
torch.quantization.convert(resnet18_fused, inplace=True)
08
量化后怎么用?
features.0.0.weight
features.0.0.scale
features.0.0.zero_point
features.0.0.bias
features.1.conv.0.0.weight
features.1.conv.0.0.scale features.1.conv.0.0.zero_point ...
本文目的在于学术交流,并不代表本公众号赞同其观点或对其内容真实性负责,版权归原作者所有,如有侵权请告知删除。
直播预告
“他山之石”历史文章
LSTM模型结构的可视化
PointNet论文复现及代码详解
SCI写作常用句型之研究结果&发现
白话生成对抗网络GAN及代码实现
pytorch的余弦退火学习率
Pytorch转ONNX-实战篇(tracing机制)
联邦学习:FedAvg 的 Pytorch 实现
PyTorch实现ShuffleNet-v2亲身实践
训练时显存优化技术——OP合并与gradient checkpoint
浅谈数据标准化与Pytorch中NLLLoss和CrossEntropyLoss损失函数的区别
在C++平台上部署PyTorch模型流程+踩坑实录
libtorch使用经验
深度学习模型转换与部署那些事(含ONNX格式详细分析)
如何支撑上亿类别的人脸训练?显存均衡的模型并行(PyTorch实现)
PyTorch trick 集锦
分享、点赞、在看,给个三连击呗!