1. 什么是量化
量化技术是一种用来减少模型大小和提高推理速度的技术。量化指的是将模型的参数从高精度表示(如常见的32位浮点数FP32)转换到更低精度的整数表示,以节省内存带宽和计算资源。
2. W8A8 和 W8A16
“W8A8” 和 “W8A16” 是两种不同的量化策略,具体如下:
(1)W8A8 :指的是权重(Weight)使用8位整数(INT8)量化,激活值(Activation)也使用8位整数量化。这种量化方式通常会显著减少模型大小,并且在某些情况下可以保持相当高的准确性。SmoothQuant 是一种实现了 W8A8 量化的技术,它能够在保持较高准确性的前提下,将模型的权重和激活值都降低到 INT8 精度。
(2)W8A16 :指权重使用8位整数量化,但是激活值仍然保留较高的精度,通常是使用16位浮点数(FP16)或者混合精度(Mixed Precision)。这种方式相比于 W8A8,可能会提供更好的模型准确性,但是代价是在激活值上保留了更高的精度,因此可能不会像 W8A8 那样大幅度减少内存使用。
选择哪种量化方式取决于多种因素,包括模型的具体需求、硬件支持、以及对推理速度和准确性的权衡。在实际应用中,可能需要根据具体的场景来选择最适合的量化策略。例如,如果部署环境对内存带宽有严格限制,那么 W8A8 可能是更好的选择;而如果模型准确性是首要考虑的因素,则可能需要使用 W8A16 或其他更高精度的量化方案。
3. W8A8 量化
3.1 权重量化
(1)确定量化范围:找到权重的最大绝对值,作为量化范围的参考。
(2)选择量化级别:确定使用8位量化,即256个离散值。
(3)计算量化参数:
- 缩放因子 s c a l e scale scale: s c a l e = m a x _ v a l u e / 127 scale = max\_value / 127 scale=max_value/127,这里127是因为8位整数范围是从-128到127
- 零点 z e r o _ p o i n t zero\_point zero_point:对于对称量化,零点通常设置为128(无符号)或0(有符号)
(4)应用量化:
- 对于每个权重 w w w,计算量化后的值 q q q: q = r o u n d ( w / s c a l e ) + z e r o _ p o i n t q = round(w / scale) + zero\_point q=round(w/scale)+zero_point
- 将 q q q 限制在8位整数范围内,即 q = c l i p ( q , − 128 , 127 ) q = clip(q, -128, 127) q=clip(q,−128,127)
3.2 激活量化
(1)校准:使用校准数据集来确定激活值的最大和最小值。
(2)计算量化参数:
- 缩放因子 s c a l e scale scale: s c a l e = ( m a x _ v a l u e − m i n _ v a l u e ) / 255 scale = (max\_value - min\_value) / 255 scale=(max_value−min_value)/255
- 零点 z e r o _ p o i n t zero\_point zero_point: z e r o _ p o i n t = r o u n d ( ( 0 − m i n _ v a l u e ) / s c a l e ) zero\_point = round((0 - min\_value) / scale) zero_point=round((0−min_value)/scale)
(3)应用量化:
- 对于每个激活值 a a a,计算量化后的值 q q q: q = r o u n d ( a / s c a l e ) + z e r o _ p o i n t q = round(a / scale) + zero\_point q=round(a/scale)+zero_point
- 将 q q q 限制在8位整数范围内,即 q = c l i p ( q , 0 , 255 ) q = clip(q, 0, 255) q=clip(q,0,255) 或 q = c l i p ( q , − 128 , 127 ) q = clip(q, -128, 127) q=clip(q,−128,127),取决于是否使用无符号整数
4. W8A16 量化
4.1 权重量化
(1)确定量化范围:找到权重的最大绝对值,作为量化范围的参考。
(2)选择量化级别:确定使用8位量化,即256个离散值。
(3)计算量化参数:
- 缩放因子 s c a l e scale scale: s c a l e = m a x _ v a l u e / 127 scale = max\_value / 127 scale=max_value/127
- 零点 z e r o _ p o i n t zero\_point zero_point:零点通常设置为128(无符号)或0(有符号)。
(4)应用量化:
- 对于每个权重 w w w,计算量化后的值 q q q: q = r o u n d ( w / s c a l e ) + z e r o _ p o i n t q = round(w / scale) + zero\_point q=round(w/scale)+zero_point
- 将 q q q 限制在8位整数范围内,即 q = c l i p ( q , − 128 , 127 ) q = clip(q, -128, 127) q=clip(q,−128,127)
4.2 激活量化
(1)校准:使用校准数据集来确定激活值的最大和最小值。
(2)计算量化参数:
- 缩放因子 s c a l e scale scale: s c a l e = ( m a x _ v a l u e − m i n _ v a l u e ) / 65535 scale = (max\_value - min\_value) / 65535 scale=(max_value−min_value)/65535
- 零点 z e r o _ p o i n t zero\_point zero_point: z e r o _ p o i n t = r o u n d ( ( 0 − m i n _ v a l u e ) / s c a l e ) zero\_point = round((0 - min\_value) / scale) zero_point=round((0−min_value)/scale)
(3)应用量化:
- 对于每个激活值 a a a,计算量化后的值 q q q: q = r o u n d ( a / s c a l e ) + z e r o _ p o i n t q = round(a / scale) + zero\_point q=round(a/scale)+zero_point。
- 将 q q q 限制在16位整数范围内,即 q = c l i p ( q , 0 , 65535 ) q = clip(q, 0, 65535) q=clip(q,0,65535) 或 q = c l i p ( q , − 32768 , 32767 ) q = clip(q, -32768, 32767) q=clip(q,−32768,32767),取决于是否使用无符号整数。
欢迎关注本人,我是喜欢搞事的程序猿; 一起进步,一起学习;
欢迎关注知乎/CSDN:SmallerFL
也欢迎关注我的wx公众号(精选高质量文章):一个比特定乾坤