问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

LLM学习总结|模型量化: QLoRA论文笔记

创作时间:
作者:
@小白创作中心

LLM学习总结|模型量化: QLoRA论文笔记

引用
CSDN
1.
https://blog.csdn.net/weixin_52309665/article/details/141020636

模型量化是大语言模型部署和优化中的关键技术,它通过将浮点数映射为整数来减少模型的存储和计算需求。本文详细介绍了模型量化的原理,并重点阐述了QLoRA技术在模型量化方面的创新,包括NF4数据类型和双重量化技术的实现细节。

什么是模型量化?

量化的基本原理是根据每个tensor的浮点型最大值和最小值,将其映射为一个固定范围的整形数值集合,比如[-127~127]。假设一个简单的公式:qweight=round(weight/scale),其中qweight代表量化后权重,weight代表量化前权重,scale代表缩放因子,可以看到在进行缩放后为了将浮点型转换为整数过程中增加了round操作丢失了小数部分。在后续计算或反量化为浮点型时存在无法完全还原的情况,这就是精度损失。

QLoRA

1. QLoRA 和 LoRA的区别?在哪些步骤进行了量化?

与LoRA不同,QLoRA 微调时使用的模型是量化为 4bit 的大模型,大模型的参数储存为 NF4 的数据类型。但是在训练 adapter ,前向传播以及反向传播时,大模型的参数会被反量化为 BF16 的数据类型进行计算;adapter部分的梯度的数据类型也是 BF16。

2. NF4 数据类型和 int4 数据类型的异同?

在详细阐述二者区别前需要先介绍几个量化中的概念:

2.1 如何量化

量化的本质其实是在做映射,将范围较大的浮点数映射为范围固定的整数。比如说,在不考虑负数的情况下,int4 量化实际上就是把浮点数映射到 0~15 的范围内。

量化公式:

(min_weight也可以是设定的offset)
(for int k quantization, and the range is from 0 to 2^k -1)

反量化的过程就是:

因此,为了之后能够重新映射回浮点数,量化后需要额外储存的两个参数是 scale 和 min_weight(offset)。但由于量化时为了将浮点数映射为整数采用了取整,不可避免地,小数部分会被丢失,因此在量化过程中一定会造成精度损失

2.2 Block size

大模型参数矩阵是高维而且很大,于是可以分成多个不同的block,然后分别在每个block里进行量化(因为量化需要被量化数据的范围,即最大值和最小值)。使用 block 有利于gpu进行并行运算,而且一定程度也能提高量化后数值的精度。但是block分的越多,需要储存的scale 和 min_weight 就越多。

2.3 NF4 的改进

以上介绍的量化方式使用的是线性映射的方式。然而,神经网络的参数一般遵循以零为中心的正态分布,也就是靠近中心的数据分布比靠近尾端的数据分布更加稠密。使用简单线性映射的弊端在于,如果很多数值不同的浮点数都聚集在同一个整数附近,那线性量化就会导致这些不同的浮点数全部被映射为同一个整数,导致反量化后精度损失严重。

基于此,QLoRA论文提出一种新的数据类型 NF4,在做映射时使用了一种近似对数的编码方式,使得在靠近正态分布的均值附近的参数值可以获得更高的精度(因为靠近均值的参数较多,远离均值的参数较少,这样能让靠近均值的参数在量化后彼此之间也能相互区分开,反量化后准确度更高)。

所以 NFk 的思路是把参数的分布转换为标准高斯分布,然后从标准高斯分布中取样一定分位数的量化间隔并设定量化值(该值采用两边分位数的均值),并且正则化到[-1, 1]区间中。

3. 双重量化 Double Quantization

对大模型进行量化后得到需要储存 scale factor 以及 offset,此时精度为 fp32;可以以此作为输入进行第二次量化;

不用双重量化的情况下: blocksize = 64, 精度为 fp32,所以对于每个参数来说需要存储的内存增加为 32/64 = 0.5 bits per parameter

双重量化的第一次量化:blocksize = 64, 精度为 int8, 所以对每个参数来说需要存储的内存增加为 8/64 = 0.125 bits per parameter

双重量化的第二次量化:blocksize = 256, 精度为 fp32, 所以对于每个参数来说平均需要存储的内存增加为 32/(256*64) 约等于 0.02 bits per parameter

(p.s. 第一次量化时,每个 block (即64个参数)共享一套 scale factor 和 offset;第二次量化时,每 256 个block 共享一套 scale factor 和 offset,所以一共是 256 * 64 个参数共享一套scale factor 和 offset)

因此,使用双重量化后每个参数平均需要的内存占用降低为 0.127 bits,论文里说在使用 int8 量化的情况下模型没有出现表现的退化。

参考资料

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号