量化可以定义为将值从大量实数映射到小离散集合中的值的过程。通常,这涉及将连续输入映射到输出处的固定值。实现此目的的常见方法是舍入或截断。在四舍五入的情况下,我们计算最接近的整数。例如,1.8 的值会变成 2。但是 1.2 的值会变成 1。在截断的情况下,我们会盲目地删除小数点后的值,将输入转换为整数。
无论我们采取哪种方式,深度神经网络量化背后的主要动机是提高推理速度,因为不用说,神经网络的推理和训练在计算上是相当昂贵的。随着大型语言模型的出现,这些模型中的参数数量只会增加,这意味着内存占用只会越来越高。
随着这些神经网络发展的速度,在我们的笔记本电脑或手机甚至手表等微型设备上运行这些神经网络的需求越来越大。如果没有量化,这一切都是不可能的。
在深入研究量化之前,我们不要忘记经过训练的神经网络只是存储在计算机内存中的浮点数。
在计算机中存储数字的一些众所周知的表示或格式有 float32 或 FP32、float16 或 FP16、int8、bfloat16,其中 B 代表 Google Brain 或更近的张量 float 32 或 TF32,这是一种用于处理矩阵或张量的专用格式操作。这些格式中的每一种都会消耗不同的内存块。例如,float32 为符号分配 1 位,为指数分配 8 位,为尾数分配 23 位。
类似地,float16 或 FP16 为符号分配 1 位,但为指数分配 5 位,为尾数分配 10 位。另一方面,BF16 为指数分配 8 位,为尾数分配 7 位。
足够的陈述。我的意思是,从较高存储格式到较低存储格式的转换称为量化。在深度学习术语中,Float32 被称为单精度或全精度, Float16 和 BFloat16 被称为半精度。深度学习模型训练和存储的默认方式是完全精确的。最常用的转换是从全精度到 int8 格式。
量化可以是均匀的或非均匀的。在均匀情况下,从输入到输出的映射是线性函数,从而为均匀间隔的输入产生均匀间隔的输出。在非均匀情况下,从输入到输出的映射是非线性函数,因此对于均匀输入,输出不会均匀分布。
深入研究统一类型,线性映射函数可以是缩放和舍入操作。因此,均匀量化涉及方程中的比例因子S。
当从 float16 转换为 int8 时,请注意,我们始终可以限制为 -127 到 + 127 之间的值,并确保输入的零完美映射到输出的零,从而导致对称映射,因此这种量化称为对称量化。
另一方面,如果零两侧的值不相同,例如在 -128 和 +127 之间。此外,如果我们将输入的零映射到输出处除零之外的其他值,则称为非对称量化。由于我们现在在输出中移动了零值,因此我们需要通过在方程中包含零因子Z来在方程中对此进行计数。
为了了解如何选择比例因子和零点,让我们举一个在实数轴上分布如上图所示的示例输入。比例因子实质上将输入权从最小值r_min到最大值r_max的整个范围划分为均匀的分区。然而,我们可以选择在某个时刻剪裁这个输入,比如 alpha 表示负值,beta 表示正值。任何超出 alpha 和 beta 的值都没有意义,因为它映射到与 alpha 相同的输出。在此示例中,它是 -127 和 +127。选择这些限幅值 alpha 和 beta 以及限幅范围的过程称为校准。
为了防止过度裁剪,最简单的选择是将 alpha 设置为等于 r_min,将 beta 设置为等于 r_max。我们可以使用这些r_min和r_max值愉快地计算比例因子S 。然而,这可能会导致输出不对称。例如,输入中的r_max可以是 1.5,但r_min只能是 -1.2。因此,为了约束对称量化,我们需要 alpha 和 beta 为两者的最大值,当然将零点设置为 0。
对称量化正是在量化神经网络权重时使用的,因为训练的权重已经在推理过程中预先计算,并且在推理过程中不会改变。与非对称情况相比,由于零点设置为 0,计算也更简单。
现在让我们回顾一个示例,其中输入偏向一个方向,即正向一侧。这类似于一些最成功的激活函数(如 ReLU 或 GeLU)的输出。最重要的是,激活的输出随着输入而变化。例如,当我们显示两张猫的图像时,激活函数的输出就完全不同。所以现在的问题是,“我们什么时候校准量化范围?”是在训练的时候吗?或者在推理过程中,当我们获得预测数据时?
这个问题导致了各种量化模式,特别是在训练后量化(PTQ)中。在 PTQ 中,我们从预训练模型开始,无需进行额外的训练。模型所需的关键数据包括校准数据,用于计算限幅范围,以及随后的比例因子 (S) 和零点 (Z)。通常,该校准数据源自模型权重。校准过程完成后,我们可以对模型进行量化,得到量化模型。
在量化感知训练(简称 QAT)中,我们使用标准程序对训练后的模型进行量化,然后使用新的训练数据进行进一步的微调或重新训练,以获得量化模型。 QAT 通常用于调整模型的参数,以恢复丢失的精度或我们在量化过程中关心的任何其他指标。因此,QAT 往往会提供比训练后量化更好的模型。
为了进行微调,模型必须是可微的。但量化操作是不可微的。为了克服这个问题,我们使用假量化器,例如直通估计器。在微调期间,这些估计器估计量化误差,并将误差与训练误差结合起来,以微调模型以获得更好的性能。在微调期间,对量化模型进行浮点的前向和后向传递。然而,参数在每次梯度更新后都会被量化。
观看下面的视频,解释深度学习中的模型量化
这几乎涵盖了量化的基础知识。我们从量化的需求以及不同类型的量化(例如对称和非对称)开始。我们还很快了解了如何选择量化参数,即比例因子和零点。我们以不同的量化模式结束。但这一切是如何在 PyTorch 或 TensorFlow 中实现的呢?那是另一天的事情了。我希望这个视频能让您对深度学习中的量化有一些了解。
我希望在下一次见到你。在那之前,请保重!