量化简介
量化是将模型浮点数变为定点数运行的过程。
基本概念 :模型量化可以减少模型尺寸,进而减少在推理时的内存消耗,并且在一些低精度运算较快的处理器上可以增加推理速度。
常见方法:工业界目前最常用的量化位数是8比特,低于8比特的量化被称为低比特量化。1比特是模型压缩的极限,可以将模型压缩为1/32。
精度类型
低精度浮点数:在PyTorch中用torch.bfloat16和torch.float16表示。
双精度浮点数:在PyTorch中用torch.float64表示,或者在其他语言中也称为double类型,在LLM训练中一般比较少用
全精度浮点数:在PyTorch中用torch.float32表示
精度类型注意点
- bfloat16的小数部分较短,整数部分较长,这会有利于在训练中减少梯度爆炸的情况(即梯度累加值超过了最大值),但是这种数据类型是在N系列显卡Ampere系列才支持的,即30系列显卡。
- float16的小数部分较长,这意味着在精度控制上float16更好,但整数部分较短,比较容易梯度爆炸。
量化基本思路
量化的基本原理是根据每个tensor的浮点型最大值和最小值,将其映射为一个固定范围的整形数值集合,比如[-127~127]。
量化的精度损失
在后续计算或反量化为浮点型时存在无法完全还原的情况,这就是精度损失。
量化部分
按照量化发生的步骤区分
可以划分为PTQ(训练后量化,或离线量化)和QAT(训练感知型量化,或在线量化)。
按照量化方法可以划分
可以划分为线性量化、非线性量化(如对数量化)等多种方式,目前较为常用的是线性量化。其中线性量化又可以按照对称性划分为对称量化和非对称量化,非对称量化为了解决weight分布不均匀问题,其在公式中增加了zero_point项。
按照量化粒度划分
可以分为逐层量化(每层使用一套量化因子)、逐组量化(在每层中按照group使用一套量化因子)、逐通道量化(按channel划分量化因子)等几种方式。
按照量化最大值的阈值区分
可以分为饱和量化和不饱和量化两种。不饱和量化按照浮点数最大值和量化后最大值的比例计算量化因子,由于原始weight的非均匀性会导致某些整形数值范围存在权重空缺。饱和量化会计算一个中间值以计算出量化因子,因此会舍弃一部分不重要数据,将重要数据尽量均匀的分布到量化数值范围内。
混合精度训练
混合精度训练是一种深度学习的优化技术,旨在加速训练过程并减少内存使用,特别是在处理大规模神经网络模型时。它通过在训练中同时使用两种浮点数据类型——半精度(FP16)和单精度(FP32)。
具体策略:
-
权重的双精度备份:保持权重的FP32副本,用FP16进行前向传播,然后在反向传播时将梯度从FP16转换回FP32进行更新,以避免精度大幅下降。
-
损失缩放(Loss Scaling):放大损失值并以FP16存储,以解决小数值在FP16中表示的问题,之后在更新权重前进行反向缩放,减少梯度消失
方法适合大规模模型和大批次训练,但在小批次训练中可能不会提升速度,甚至可能因为额外的类型转换而变慢,因为小批次的训练瓶颈通常是I/O而非计算。
AutoAWQ
AWQ是一个“激活感知权重量化(Activation-aware Weight Quantization)”的方法。主要思想就是权重对于LLM的性能不是一样重要,有多有少。存在约(0.1%-1%)显著权重对大模型性能影响太大,通过跳过这1%的显著权重(salient weight)不进行量化,减少量化误差。
由于 LLM 的权重并非同等重要,与其他权重相比,有一小部分显著权重对 LLM 的性能更为重要。
可以在不进行任何训练的情况下,弥补量化损失造成的性能下降。
思想在于对模型进行INT3量化,但是保留一定权重通道的比例为FP16(大部分大语言模型的精度都在FP16)
ONNX
Tensortrt
FlashAttention
ExLlamav2