模型量化--int8量化

本文详细介绍了模型量化的方法,包括权重量化、激活量化、混合精度量化和剪枝与量化,重点阐述了INT8量化的过程、计算公式以及一个实际应用示例。通过量化,模型可以在保持性能的同时,显著减少存储和计算资源需求,适用于资源受限的设备。
摘要由CSDN通过智能技术生成


一、什么是模型量化?

  在深度学习领域,模型通常采用float32这种数据格式进行训练和存储,每个参数占据32比特(即4字节)的空间。例如,一个大小为7b的模型会需求28b的显存或内存资源。但如果能够将参数所需的存储空间压缩至16比特、8比特甚至4比特,那么就能显著减少所需的存储容量,并可能加快模型的推理速度。量化可以应用在模型的参数(即权重)、激活值,甚至是在训练过程中更新的梯度上。参数的量化通常相对容易实施,因为模型的参数分布通常比较稳定。
  模型量化的主要目标是在尽可能保持模型性能的前提下,减少模型的存储空间、内存带宽和计算资源消耗。较小的模型可以更轻松地部署在资源受限的设备上,例如移动设备、嵌入式系统和边缘设备等。

二、常见的模型量化方法

1.权重量化(Weight Quantization)

  将模型中的权重参数转换为较低比特的整数或浮点数表示。例如,将32位浮点数权重量化为8位整数或4位浮点数。

2.激活量化(Activation Quantization)

  将模型中的激活值转换为较低比特的整数或浮点数表示。类似于权重量化,激活量化可以将32位浮点数激活值量化为8位整数或4位浮点数。

3.混合精度量化(Mixed Precision Quantization)

  结合使用不同精度的数据表示,例如使用低精度整数表示权重和激活值,同时保持某些操作的高精度表示(如矩阵乘法)。

4. 剪枝和量化(Pruning and Quantization)

  将模型中的冗余连接或不重要的权重剪枝(删除),然后将剩余的权重进行量化。这种方法结合了剪枝和量化两种技术,可以进一步减少模型的存储需求和计算复杂性。

  模型量化的实现通常需要进行训练和校准过程。在训练阶段,模型使用原始的高精度表示进行训练。在校准阶段,使用预定义的数据集或一部分训练数据集来收集模型在推理过程中的激活值统计信息,以便确定合适的量化范围。然后,通过量化算法将权重和激活值转换为较低比特的表示。最后,量化后的模型可以用于推理阶段,其中计算和存储都使用量化后的数据格式。

三、什么是int8量化

  在深度学习模型中,通常使用32位浮点数(FP32)来表示权重和激活值。然而,FP32的存储需求和计算复杂性较高,特别是在边缘设备和嵌入式系统等资源有限的环境中运行时,会造成显著的性能瓶颈。INT8量化通过将这些浮点数值量化为8位整数,可以大幅度地减少模型的存储空间和内存带宽,并加速模型的推理过程。

1. int8量化步骤

  1. 训练模型:首先,使用常规的训练方法和数据集对深度学习模型进行训练,得到FP32精度的模型。
  2. 收集统计信息:使用预先定义的校准数据集或一部分训练数据集来收集模型在推理过程中的激活值统计信息。这些统计信息可以用于确定合适的量化范围,以便将浮点数值映射到8位整数。
  3. 量化权重和激活值:根据收集的统计信息,将模型的权重和激活值量化为8位整数。通常使用量化算法(如最大/最小值量化、均匀量化等)来将浮点数映射到8位整数。
  4. 构建量化模型:使用量化后的权重和激活值,重新构建量化模型。这个模型在推理过程中只使用8位整数进行计算。
  5. 推理过程:使用量化模型进行推理。输入数据经过量化模型,推理过程中的计算都使用8位整数进行,从而提高推理效率和性能。

2. int8量化计算公式

2.1 确定缩放因子(Scale)和零点(Zero Point)

缩放因子(scale):用于将浮点数映射到整数范围。
零点(Zero Point):确保浮点数0可以被准确地表示为整数。

计算scale和zero_point通常需要最大值(max_val)和最小值(min_val):

scale = (max_val - min_val) / (2^7 - 1)  # 127是int8的最大值 
zero_point = round(-min_val / scale) #zero_point需要在-128到127的范围内,因为这是8位有符号整数的范围

2.2 应用量化

使用scale和zero_point,量化一个浮点数(float_val)成一个8位整(int_val)。

int_val = round(float_val / scale) + zero_point #round"指的是将一个浮点数四舍五入到最接近的整数

2.3 整数裁剪

如果量化后的整数超出了-128到127的范围,它需要被裁剪以保持在有效范围内。

int_val = min(127, max(-128, int_val)) 

这样,量化过程就可以将32位浮点数数组转换为能够在8位整数范围内表示的数组,这减少了内存占用,同时可能提高了执行速度。

2.4 一个线性、非对称、int8后量化的例子

假设我们有下面这个列表的模型权重作为浮点数:

weights = [0.15, -0.8, 0.2, -0.5] 

量化到8位整数涉及以下步骤:

(1)确定量化范围:

在Int8量化中,值的范围通常是[-128, 127](对于有符号整数)。找到浮点列表中的最小和最大值:

min_val = min(weights)  # -0.8 
max_val = max(weights)  # 0.2 

(2)计算缩放系数(scale)和零点(zero point):

计算缩放系数,将浮点数范围映射到整数范围。举例来说,可以简单选择max(abs(min_val), abs(max_val))作为分母,然后以[-128, 127]为分子进行缩放计算。因为0可能不在浮点数的范围内,我们需要一个零点来表示量化值0对应的浮点数。通常,零点是通过缩放原始的浮点数零值来确定的。

scale = (max_val - min_val) / (127 - (-128)) 
#缩放系数 (0.2 - (-0.8)) / (127 - (-128))
#scale = 1.0 / 255
zero_point = 127-max_val / scale
#zero_point = 76

(3)应用量化转换:

将每个浮点数权重转换为整数表示。

quantized_weights = [round((w / scale) + zero_point) for w in weights] 

应用上面的公式,具体计算:

quantized_weights = [
    round(0.15 / scale) + zero_point,
    round(-0.8 / scale) + zero_point,
    round(0.2 / scale) + zero_point,
    round(-0.5 / scale) + zero_point
]
#根据scale,四舍五入并加上zero_point
quantized_weights = [
    round(38.4) + 76,
    round(-204.8) + 76,
    round(51.2) + 76,
    round(-128.0) + 76
]
得到的quantized_weights是: [114, -129, 127, -52]

(4)做截断,使得数据落在[-128,127]范围

量化后的权重如下所示:

quantized_weights = [114, -128, 127, -52] 

3.代码

model = AutoModelForCausalLM.from_pretrained("Llama-2-7b-ms", 
low_cpu_mem_usage=True, 
load_in_8bit=True, 
device_map="auto")
  • 32
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ONNX模型量化int8是一种将模型数据从浮点表示转换为8位整数表示的优化方法。这种量化方法可以带来多个好处。首先,使用8位整数数据进行计算时,NVIDIA GPU可以使用更快更低成本的8位张量核来执行卷积和矩阵乘法运算,从而提高计算吞吐量。其次,将数据从内存移动到计算单元需要时间和能量,并且会产生热量,将激活和参数数据的精度从32位浮点值降低到8位整数可以减少数据量,从而节省能量并减少热量的产生。此外,对于具有带宽限制的层,减少内存占用可以提高缓存利用率和参数更新效率。因此,ONNX模型量化int8是一种有效的优化方法,可以在保持模型准确性的同时提高计算效率和节省资源。\[3\] 要将模型量化int8,可以使用PyTorch的torch.onnx.export函数将模型导出为ONNX格式,并在导出时设置opset_version为13以支持每通道量化(PCQ)。在导出时,还可以将do_constant_folding参数设置为True,以生成更小且可读性更好的模型。以下是导出模型为ONNX并进行量化的示例代码: ``` import torch import torchvision import torch.onnx # 初始化模型 model = torchvision.models.__dict__\[model_name\](pretrained=pretrained) # 导出模型为ONNX dummy_input = torch.randn(1, 3, 224, 224) # 输入的示例数据 onnx_filename = "model.onnx" # 导出的ONNX文件名 opset_version = 13 # 使用的opset版本 torch.onnx.export(model, dummy_input, onnx_filename, verbose=False, opset_version=opset_version, do_constant_folding=True) ``` 通过以上代码,您可以将PyTorch模型导出为ONNX格式,并在导出时进行量化,从而将模型数据转换为int8表示。\[2\] #### 引用[.reference_title] - *1* *2* *3* [利用TensorRT实现INT8量化感知训练QAT](https://blog.csdn.net/zong596568821xp/article/details/120904429)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值