模型量化(pytorch)

1、量化简介

1.1、量化介绍

  • 基于pytorch的量化官方地址https://pytorch.org/docs/stable/quantization.html

  • 量化的作用:
    减小模型大小(减小四倍左右),方便模型部署到小型设备中(如低成本嵌入式设备)

  • 量化的数据:
    weight的8 bit量化 :data_type = qint8,数据范围为[-128, 127]
    activation的8 bit量化:data_type = quint8,数据范围为[0, 255]

<1>一般我们都将float32量化到qint8。

<2>模型参数中的bias一般是不进行量化操作的,仍然保持float32的数据类型。

<3>weight在浮点模型训练收敛之后一般就已经固定住了,所以根据原始数据就可以直接量化。

<4>activation会因为每次输入数据的不同,导致数据范围每次都是不同的,所以针对这个问题,在量化过程中专门会有一个校准过程,即提前准备一个小的校准数据集,在测试这个校准数据集的时候会记录每一次的activation的数据范围,然后根据记录值确定一个固定的范围。

1.2、量化方法

1.2.1、训练后动态量化(Post Training Dynamic Quantization)

官方地址:torch.quantization.quantize_dynamic()

<1>顾名思义,就是在训练完成后进行量化。

<2>编译器中书写方法
Class torch.quantization.quantize_dynamic(model, qconfig_spec=None, dtype=torch.qint8, mapping=None, inplace=False)

<3>将float型model转化为动态量化(仅weight)model。

<4>最简单的是将模型变为float16或qint8,且动态量化只针对一些权重大的层,例如Linear或RNN

<5>代码示例(假设我们需要写了一个名叫lstm_for_demonstration的类,其中包括nn.LSTM层与nn.Linear层,我们将该类实例化为float_lstm再进行量化)

	# 实例化类
	float_lstm = lstm_for_demonstration(model_dimension, model_dimension,lstm_depth)
	#进行动态量化(量化nn.LSTM, nn.Linear层为qint8)
	quantized_lstm = torch.quantization.quantize_dynamic(
	    float_lstm, {nn.LSTM, nn.Linear}, dtype=torch.qint8
	)

<6>动态量化公式讲解,请看这里:https://blog.csdn.net/kuan__/article/details/108928491

查看公式后请注意:动态量化系统自动选择最合适的scale (标度)和 zero_point(零点位置),不需要自定义。量化后的模型,可以推理运算,但不能训练(不能反向传播)

1.2.2、训练后静态量化(Post Training Static Quantization)

官方地址:torch.quantize_per_tensor()

<1>训练后进行量化。

<2>静态量化之前,可能需要修改模型,请参考此处:静态量化前修改模型

<3>训练后的静态量化不仅包括将权重从浮点数转换为整数,还执行额外的步骤,首先通过网络输入一批数据并计算不同激活的结果分布(具体来说,这是通过插入观察者完成记录此数据的不同点的模块)。然后使用这些分布来确定在推理时如何具体量化不同的激活(一种简单的技术是将整个激活范围简单地划分为 256 个级别,但也支持更复杂的方法)。重要的是,这个额外的步骤允许我们在操作之间传递量化值,而不是在每个操作之间将这些值转换为浮点数 - 然后再转换回整数,从而显着加快速度。

<5>静态量化公式讲解,请看这里:https://blog.csdn.net/kuan__/article/details/108928491

查看公式后请注意:scale (标度)和 zero_point(零点位置)需要自定义。量化后的模型,不能训练(不能反向传播),也不能推理,需要解量化后,才能进行运算

1.2.3、量化意识训练

官方地址:https://pytorch.org/tutorials/advanced/static_quantization_tutorial.html

<1>系统自动选择最合适的scale (标度)和 zero_point(零点位置),不需要自定义。但这是一种伪量化,量化后的模型权重仍然是32位浮点数,但大小和8位定点数权重的大小相同。伪量化后的模型可以进行训练。虽然是以32位浮点数进行的训练,但结果与8位定点数的结果一致

2、总结与注意事项

<1>个人觉得静态量化和量化意识训练都比较麻烦,做简单的量化可以选择动态量化。直接调用函数即可。

<2>有在wenet上做过动态量化。能够将513M的模型量化到180M左右;测试的CER与不做量化前基本保持一致,但仍有0.1-0.2(cer为字符错误率)的差距;RTF更高。

<3>在wenet中对已训练好的模型进行stage6动态量化后,得到量化后的模型quant_model.zip,这里用于C++,我们也可以修改代码生成python测试可用的.pt等文件类型。

<4>wenet中实验:在测试文件里量化我们原始model,便能进行python上的推理。代码如下(recognize.py)

# Init asr model from configs
model = init_asr_model(configs)
quantized_model = torch.quantization.quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8)

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值