QLORA: Efficient Finetuning of Quantized LLMs
前言
一篇面向低资源大语言模型微调场景的文章,基于LoRA实现,能够将65B的大模型微调在单张48G的专业卡上,并且性能和全量微调相当,在业界引发了不小的轰动。本文将对这篇文章进行细致深入的剖析,来看看究竟运用了什么技术能够如此大幅度降低显存的需求。
Paper: https://arxiv.org/pdf/2305.14314.pdf
code: https://github.com/artidoro/qlora
Abstract
本文提出了QLORA,一种高效的微调方法,可以极大降低显存的开销,能够做到在48G的显存上微调65B参数模型,同时保留完整的16位精度。QLORA通过冻结的4位量化预训练语言模型将梯度反向传播到LoRA中。最好的微调模型性能达到了ChatGPT的99.3%,并且微调时间只有24小时。QLORA引入了多项创新技术来降低显存:
- 4位浮点数(NF4),对于正态分布权重来说是理论最优。
- 双量化,通过量化量化常数来减少平均内存占用。
- 分页优化器,管理内存的峰值。
作者采用8个指令微调数据集在超过1000个不同规模的模型上进行实验,并对模型性能进行详细分析,发现QLORA微调可以在更小模型上达到SOTA。
Introduction
微调大模型成本高昂,常规的16位LLaMA 65B参数模型需要超过780GB的显存。最近的量化方法虽然可以减少LLM的显存占用,但是只适用于推理阶段。
本文首次证明能够在不降低性能的情况下微调量化的4位模型。即将预训练模型量化为4位,然后添加一小组低秩适配器(LoRA)进行微调。将65B模型的显存需求从780GB降到了48GB,并且不会降低性能。作者设计最小的7B Guanaco模型只需要5GB的显存,微调效果比26GB的AIpaca要高出20个百分点以上。
QLORA引入了多项创新技术,旨在不损失性能的情况下减少显存的占用:
- 4-bit NormalFloat。 对于正态分布权重来说是理论最优。
- Double Quantization。 对量化常数进行量化的方法,每个参数节省0.37位(3GB for 65GB模型)。
- Paged Optimizers。 使用NVIDIA统一内存来避免处理检查点内存峰值。
将上述方法集成到LoRA中,避免了之前LoRA相关工作的性能损失。
作者对超过1000个规模为80M-65B的模型进行了指令微调,有了如下发现:
- 数据质量比数据集大小重要。
- 对于给定任务,数据集的适用性比大小更重要。
- 聊天机器人的性能评估发现,模型评估的方式与人类评估相比会具有不确定性。
Background
Block-wise k-bit Quantization
量化是将包含更多信息的表示离散化为包含较少信息的表示的过程。通常意味着减少数据的位数,为了充分利用低位数据类型的取值范围,通常会对输入数据进行重新缩放,将其标准化到目标数据类型所允许的范围内。这个标准化过程通常是通过将输入数据除以绝对最大值来实现的,而输入数据一般被组织成一个张量。例如将32位浮点张量量化为8位的[-127, 127]:
X I n 18 = round ( 127 absmax ( X F P 32 ) X F P 32 ) = round ( c F P 32 ⋅ X F P 32 ) \mathbf{X}^{\mathrm{In} 18}=\operatorname{round}\left(\frac{127}{\operatorname{absmax}\left(\mathbf{X}^{\mathrm{FP} 32}\right)} \mathbf{X}^{\mathrm{FP} 32}\right)=\operatorname{round}\left(c^{\mathrm{FP} 32} \cdot \mathbf{X}^{\mathrm{FP} 32}\right) XIn18=round(absmax(XFP32)127XFP32)=round(cFP32⋅XFP32)
其中c是量化常数(比例),反量化则是相反的过程:
dequant ( c F P 32 , X I n t 8 ) = X I n 88 c F P 32 = X F P 32 \operatorname{dequant}\left(c^{\mathrm{FP} 32}, \mathbf{X}^{\mathrm{Int} 8}\right)=\frac{\mathbf{X}^{\mathrm{In} 88}}{c^{\mathrm{FP} 32}}=\mathbf{X}^{\mathrm{FP} 32} dequant(cFP32,XInt8)=cFP32XIn88=XFP32
这种方法问题在于如果出现了异常值,就会导致某些量化位置没有得到充分利用。为了解决这个问题,一个常见的方法是将输入张量分成独立的量化模块,每一块都有自己的量化常数c。具体来说,将输入张量 X ∈ R b × h \mathbf{X} \in \mathbb{R}^{b \times h} X∈Rb×h切成连续的n个大小为B的块(n个长度相等的区间),对这些块分别进行独立量化操作,得到量化的张量和n个量化常数 c i c_i ci。
Low-rank Adapters
低秩适配器(LoRA)是一种固定原模型参数,利用少量可训练参数来减少内存的方法,LoRA方法通过引入一个额外的因子分解投影操作,对线性投影进行了增强,以改善模型的性能或效果。给定投影
X
W
=
Y
\mathbf{XW=Y}
XW=Y,其中
X
∈
R
b
×
h
\mathbf{X} \in \mathbb{R}^{b \times h}
X∈Rb×h,
W
∈
R
h
×
o
\mathbf{W} \in \mathbb{R}^{h \times o}
W∈Rh×o,计算:
Y
=
X
W
+
s
X
L
1
L
2
\mathbf{Y}=\mathbf{XW} + s\mathbf{XL_1L_2}
Y=XW+sXL1L2
其中
L
1
∈
R
h
×
r
\mathbf{L_1} \in \mathbb{R}^{h \times r}
L1∈Rh×r,
L
2
∈
R
r
×
o
\mathbf{L_2} \in \mathbb{R}^{r \times o}
L2∈Rr×o,s是标量。
Memory Requirement of Parameter-Efficient Finetuning
LoRA是参数高效微调方法(PEFT),因此LLM微调过程内存的占用来自于激活梯度而不是LoRA参数。以微调7B LLaMA为例,LoRA权重只占用0.2%,在显存占用方面,LoRA输入梯度为567MB,而LoRA参数只占用26MB。通过使用梯度检查点,每个序列的输入梯度平均减少到18MB,仍然比所有LoRA权重总和还要更占内存。因此减少LoRA的参数量只会产生很小的显存优势,不如使用更多的适配器,在别的地方如梯度检查点上减少显存。
QLORA Finetuning
QLORA通过NF4量化和双量化两种策略实现高保真度4位微调,此外还引入了分页优化器,防止梯度检查点期间显存峰值导致显存不足。
QLORA的数据类型包括低精度的存储类型(4位)和计算数据类型(16位),这意味着当使用QLORA权重张量时,都会将该张量反量化为BFloat16,执行16位矩阵乘法。
4-bit NormalFloat Quantization
NF数据类型建立在分位数量化的基础上,分位数量化是信息理论最优的数据类型,可以确保每个量化区间内的值相等。分位数量化主要的局限在于分位数估计过程成本高,因此使用快速分位数近似算法(比如SRAM分位数)来估计,但是对异常值会有较大的误差。
当输入的张量来自于一个量化常数固定的分布,可以避免高昂的量化估计和近似误差。这种情况下,输入张量具有相同的分位数,使得精确的分位数估计在计算上可行。
由于预训练模型神经网络权重通常具有
N
∼
(
0
,
σ
)
\mathcal{N} \sim(0, \sigma)
N∼(0,σ)正态分布,因此可以通过缩放σ将所有权重转换为单个固定分布,对于本文的数据类型,设置随机区间为[-1, 1],因此,数据类型的分位数和神经网络权重都要标准化到这个区间内。
符合上述描述的分布计算过程如下:
- 估计理论N(0,1)分布的2^k+1分位数,可以获得适用于正态分布的k位分位数量化数据类型。
- 采用该数据类型并将其标准化。
- 对输入权重张量进行标准化,从而进行量化。
一旦权重范围和数据类型范围匹配,就可以照常进行量化。步骤三相当于重新调整输入张量的标准差以匹配k位分位数的标准差。更正式地说,作者估计数据类型的2^k个值
q
i
q_i
qi如下:
q
i
=
1
2
(
Q
X
(
i
2
k
+
1
)
+
Q
X
(
i
+
1
2
k
+
1
)
)
q_i=\frac{1}{2}\left(Q_X\left(\frac{i}{2^k+1}\right)+Q_X\left(\frac{i+1}{2^k+1}\right)\right)
qi=21(QX(2k+1i)+QX(2k+1i+1))
其中
Q
X
(
⋅
)
Q_X(·)
QX(⋅)是标准正态函数N(0,1)的分位数函数。但是对于对称的k位量化而言存在一个问题,即这种方法无法对零进行精确表示。然而,精确表示零是一种重要的属性,因为它能够在对填充和其他值为零的元素进行量化时避免误差(即零需要一个精确编码)。为了确保离散零点为0,作者通过估计两个范围的分位数
q
i
q_i
qi来创建非对称的数据类型。对于负数部分,
q
i
q_i
qi的范围为
2
k
−
1
2^{k-1}
2k−1,正数部分为
2
k
−
1
+
1
2^{k-1}+1
2k−1+1,然后将这些
q
i
q_i
qi统一到一起,并删除其中重复的0。
Double Quantization
即量化量化常数以进一步节省内存。因为量化常数需要占用额外的空间。
双量化将第一次量化的常数
c
2
F
P
32
c_2^{\rm FP32}
c2FP32作为第二次量化的输入,产生量化的量化常数
c
2
F
P
8
c_2^{\rm FP8}
c2FP8和第二级的量化常数
c
1
F
P
32
c_1^{\rm FP32}
c1FP32。作者使用块大小为256的8位浮点进行第二次量化,性能没有下降。
c
1
F
P
32
c_1^{\rm FP32}
c1FP32为正数,所以需要处理成0点对称。以块大小为64位为例,原先量化常数显存占用量为32/64=0.5,量化量化常数后,占用量为8/64+32/64*256=0.127位,每个参数减少了0.373位。
Paged Optimizers
使用NVIDIA统一内存功能,可以实现CPU和GPU之间页到页的传输,以便在GPU显存不够的情况下仍能正常处理。具体来说,在GPU内存不足时,自动将其移出到CPU的RAM中,并在优化器更新步骤需要时取回到GPU显存中。
QLORA
结合上述组件便得到了单个线性层定义QLORA,如下所示:
Y
B
F
16
=
X
B
F
16
doubleDequant
(
c
1
E
P
32
,
c
2
k
-bit
,
W
N
F
4
)
+
X
B
F
16
L
1
B
F
16
L
2
B
F
16
\mathbf{Y}^{\mathrm{BF} 16}=\mathbf{X}^{\mathrm{BF} 16} \text { doubleDequant }\left(c_{1}^{\mathrm{EP} 32}, c_{2}^{\mathrm{k} \text {-bit }}, \mathbf{W}^{\mathrm{NF} 4}\right)+\mathbf{X}^{\mathrm{BF} 16} \mathbf{L}_{1}^{\mathrm{BF} 16} \mathbf{L}_{2}^{\mathrm{BF} 16}
YBF16=XBF16 doubleDequant (c1EP32,c2k-bit ,WNF4)+XBF16L1BF16L2BF16
其中双量化doubleDequant(·)定义如下
doubleDequant
(
c
1
F
P
32
,
c
2
k
-bit
,
W
k
-bit
)
=
dequant
(
dequant
(
c
1
F
P
32
,
c
2
k
-bit
)
,
W
4
b
i
t
)
=
W
B
F
16
\text { doubleDequant }\left(c_{1}^{\mathrm{FP} 32}, c_{2}^{\mathrm{k} \text {-bit }}, \mathbf{W}^{\mathrm{k} \text {-bit }}\right)=\operatorname{dequant}\left(\operatorname{dequant}\left(c_{1}^{\mathrm{FP} 32}, c_{2}^{\mathrm{k} \text {-bit }}\right), \mathbf{W}^{4 \mathrm{bit}}\right)=\mathbf{W}^{\mathrm{BF} 16}
doubleDequant (c1FP32,c2k-bit ,Wk-bit )=dequant(dequant(c1FP32,c2k-bit ),W4bit)=WBF16
作者将NF4应用于W,FP8应用于
c
2
c_2
c2,W采用64位大小的块以获得更高的量化精度,对
c
2
c_2
c2使用256小的块以节省内存。
参数更新只针对
∂
E
∂
L
i
\frac{\partial E }{\partial \mathbf{L}_{i}}
∂Li∂E,而不是4位权重梯度
∂
E
∂
W
\frac{\partial E }{\partial \mathbf{W}}
∂W∂E。但是前者的计算需要后者的计算,即通过第一个公式输入
W
N
F
4
\mathbf{W}^{\rm{NF4}}
WNF4输出得到
W
N
F
16
\mathbf{W}^{\rm{NF16}}
WNF16,以计算BFloat16精度的导数
∂
E
∂
W
\frac{\partial E }{\partial \mathbf{W}}
∂W∂E。
总的来说,QLoRA有一个存储数据类型(4位NormalFloat)和一个计算数据类型(16位BrainFloat),将存储数据类型反量化为计算数据类型以执行前向和反向传播,但是仅计算使用16位BrainFloat的LoRA参数的权重梯度。
QLoRA vs. Standard Finetuning
QLoRA在节省显存上有极大优势,那么在性能上是否能达到全量微调的一样效果呢。
Experimental setup
作者在三种不同架构模型上进行实验,并将QLoRA与16位的Adapter微调和全量微调的3B模型进行对比。完整的信息见附录A。
由于分页优化器它仅作用在处理长序列、小批量数据的情况,因此作者仅进行了简单的测度,发现批大小为16时,分页优化器提供与常规优化器相同的训练速度。未来的工作可以关注于在什么情况下分页优化器效率会降低。
Default LoRA hyperparameters do not match 16bit performance
标准的LoRA无法达到全量微调的性能,如下图所示:
实验发现影响LoRA性能最关键的超参数是LoRA的个数,并且在每一层上使用LoRA才能匹配全量微调的效果。
4-bit NormalFloat yields better performance than 4-bit Floating Point
作者在不同架构和大小的LLMs使用不同的数据类型进行实验评估,如下图和下表所示。
可以看到,NF4和FP4、Int4相比,显著提升了性能,并且双量化减少了内存使用,而不会降低性能。
k-bit QLORA matches 16-bit full finetuning and 16-bit LoRA performance
最近研究表明,4位量化用于推理是可能的,但是和16位微调相比性能会降低,那么可不可以通过对4位适配器进行微调来恢复损失的性能?
首先和16位全量微调的RoBERTA、T5模型(二者大小范围125M-3B)进行对比,结果如下:
观察到16位、8位和4位适配器方法复制了完全微调的16位基线性能。说明量化的精度问题可以通过适配器微调来完全恢复。
接着测试4位QLoRA是否可以在7B-65B的参数范围的模型上匹配16位LoRA。结果如下表所示:
NF4完全恢复了16位LoRA的性能,此外还发现FP4的QLoRA落后于16位LoRA约1个百分点,原因可能是:
- 带有 NF4 的 QLORA 复制了 16 位完全微调和 16 位 LoRA 微调性能。
- NF4在量化精度方面优于FP4。
Summary
总结上面的实验,可以表明具有NF4数据类型的4位QLoRA可以达到16位完全微调和LoRA微调的性能,并且NF4比FP4更为高效。此外,MMLU和Elo结果表明,增加适配器参数数量同时降低其精度是有效的。
Pushing the Chatbot State-of-the-art with QLoRA
本部分对指令微调进行深入的研究。为了评估指令微调这些模型的性能,作者在MMLU上进行评估,并开发用于现实世界聊天机器人性能评估的新方法。
Experimental setup
Data
作者选取八个最新的数据集,包括OASST1、HH-RLHF、AIpaca等,这些数据集涵盖不同的语言、数据大小和许可证。
Training Setup
为了避免不同数据集的目标不同带来混淆效应,即使在包含人类评判的数据集上,也仅使用交叉熵损失作为目标函数进行QLoRA模型的微调,而不使用强化学习的方法。这样做的目的是确保在微调过程中的一致性,并减少因不同训练目标带来的干扰。所有实验采用双量化和分页优化器的NF4 QLoRA方法。
Baselines
作者将模型和研究型(Vicuna、Open Assistant)、商业型(GPT-4、GPT-3.5-turbo和Bard)的聊天机器人系统进行对比。其中研究型模型都是对LLaMA的微调。
Evaluation
作者使用MMLU基准来衡量一系列语言理解任务的性能。此外还通过自动评估和人工评估来测试生成语言能力。
Benchmark Data
作者在Vicuna和OASST1数据集上进行评估,将其作为benchmarks。
Automated Evaluation
作者使用GPT-4在Vicuna数据集上为不同的模型的输出进行打分,由于GPT-4存在显著的顺序效应,即模型会提升prompt中较早位置响应的得分,为了消除影响,取两种顺序下的平均得分。
评分方案简化为三分类标签问题,通过GPT-4输出最优的输出,并提供解释。
Human Evaluation
当前GPT-4的判断难以证明是可靠的,因此作者在Vicuna上运行两个并行的人类评估,分别雇佣两个标注人员和ChatGPT进行比较,以及三个标注人员进行两两比较,这样可以通过人工标注的方式获取关于ChatGPT性能或质量的评估数据。
Elo Rating
作者采用Elo评分机制对不同模型的性能以比赛的形式进行评估,每场比赛后,Elo 评分的变化与预期结果成比例,也就是说,意外的冷门会导致 Elo 评分发生较大变化,而预期结果会导致较小的变化。最后随着时间的推移,Elo评分会最终匹配模型的能力。
Guanaco: QLORA trained on OASST1 is a State-of-the-art Chatbot
基于自动化和人工的评估,QLoRA调优的模型Guanaco 65B是性能最佳的开源聊天机器人模型,性能媲美ChatGPT。下表是相较于ChatGPT的Vicuna基准测试结果。
可以发现Guanaco 65B是继GPT-4之后表现最好的模型,Guanaco 33B比Vicuna 13B模型拥有更多的参数,但是使用4位精度权重,因此21GB比26GB的内存效率更高,性能提高了3个百分点。此外,Guanaco 7B可以轻松安装在5GB内存的现代手机上,同时得分仍比 Alpaca 13B高出近20个百分点。
此外,GPT-4与人类注释者的系统级判断之间存在适度的一致性,因此基于模型的评估代表了人类评估的一种可靠的替换方案。
上表的Elo排名表明,Guanaco 33B和65B模型在Vicuna和OA基准中优于除了GPT-4之外的所有模型,与ChatGPT性能相当,此外,不同的数据集下模型的表现不同,这表明强大的MMLU性能并不意味着强大的聊天机器人性能,反之亦然。
Guanaco是评估中唯一未接受专有数据进行训练的顶级模型,而下一个这样的模型是HH-RLHF模型,在Vicuna基准上比Guanaco低了30个百分点,这表明4位QLoRA是有效的。
Qualitative Analysis
定量分析仍会存在问题,机器学习模型有时候会利用基准的捷径,为了缓解这种问题,这里分两部分进行一些定性分析:
- 展示一些示例,这些示例可以代表65B Guanaco模型的生成模式。
- 6.2节详细说明对这些结果的讨论和解释。
Qualitative Analysis of Example Generations
首先查看在Vicuna基准和OpenAssistant基准下,生成的数据是什么样的。作者试图测试模型的一些模式,通过“lemons”寻找和修复模型的缺点和不足,通过“cherries”确认和强调模型的优点和长处,从而让模型更加全面,更好地理解和优化模型的性能。
当然这样的定性研究肯定不够全面,作者希望给定的prompt所生成的响应是具有代表性的,并且希望未来的工作可以更详细研究这里所提出的问题。
Factual Recall
随着事实问题更为复杂,如问某个歌曲的歌手出生在哪一年,Guanaco会给出错误的歌手和其出生日期。
Suggestibility
Guanaco对于教唆性错误言论生成强烈的抵制内容。如作者提问中说明地球是平的,但是Guanaco就会纠正这个错误,并且说明错误原因。
Refusal
Guanaco有时候会出于随机的原因拒绝响应指令,即使任务很简单。
Secret Keeping
对于秘密词语,Guanaco可以坚决保守这个秘密,但是会有非常小的可能的trick会打破秘密,比如告诉它这是个游戏,让它说出秘密词。
Math
很多大语言模型在数学上都很薄弱,Guanaco也不例外,在稍微复杂一点的数学任务上就会折戟。
Theory of Mind
Guanaco具有很强的理解人心理的能力,但是可能会臆想一些不存在的事情。
Considerations
Evaluation
作者发现在比较两个强大的模型时,人类注释者之间的一致性会下降,这表明当前聊天机器人任务性能的基准和人工评估协议存在局限性,未来需要工作去消除人类注释者的主观因素以更好衡量模型的性能。
此外,作者还发现GPT-4有明显的顺序效应, 即给最先prompt的系统给予更高的分数,并且在评分时会给自己的响应赋予更高的得分。未来工作需要关注于如何消去这种偏差。
Data & Training
OASST1数据集包含了多语言,OA基准也有多语种prompt,这是否表明多语言能提高模型的性能,或者说能提高多少。
在训练部分,模型仅在交叉熵损失函数上进行训练,而不依赖于人类反馈的强化学习(RLHF),这需要进一步的分析。
Related Work
Quantization of Large Language Models
LLMs的量化关注于推理时间上的量化。大部分方法为了保持16位LLM质量侧重于管理离群特征,而其它的方法则使用更复杂的分组方法。有损的量化方法包括常规的舍入权衡,或者如何优化舍入决策来提高来量化精度。鲜有工作把量化作用在反向传播上。
Finetuning with Adapters
LoRA被证实可以达到完整的16位微调性能。此外其他的参数有效性方法如prompt tuning,微调Embedding层输入,微调隐藏层,微调偏差等。这些方法都可以进一步进行量化上的探索。
Instruction Finetuning
指令微调使用各种数据源的输入-输出对来微调预训练的 LLM,以在给定输入作为提示的情况下生成输出。方法和数据集包括MetaICL、MetaTuning、InstructGPT、FLAN等。
Chatbots
现有的聊天机器人通常基于人类反馈强化学习(RLHF),或者从现有模型生成数据以使用人工智能反馈(RLAIF)进行训练。
Limitations and Discussion
作者没有证明QLoRA可以匹配16位全量微调的33B和65B的模型。另一个局限性在指令微调模型的评估上,作者只在MMLU、OA等数据集上微调,但没有在BigBench、RAFT上微调,也就是模型评估的广度不够。
此外,作者发现基准测试的表现可能取决于微调数据与基准数据集的相似性,因此在评估之前,我们必须认真考虑评估的目标是什么。
文章的另一个局限性在于对Guanaco的评估不够全面。此外,在精度方面,还可以使用3位或者其它位的模型进行评估,参数有效性学习方法上,还有很多方法可以使用。
Broader Impacts
QLoRA方法是第一个能够在单个消费级显卡实现33B参数模型微调、在单个专业级显卡实现65B参数模型微调的方法,并且不会降低模型的性能。QLoRA有助于弥补大公司和小型团队在计算资源上的差距。
此外另一个冲击是QLoRA方法可以成为移动设备LLM微调的关键里程碑(可以在手机上实现7B模型的微调),作者已经在苹果12s上进行尝试,虽然没有到达ChatGPT的性能,但是这对于大模型下的隐私保护、大模型的部署有着重要的意义。
阅读总结
QLoRA本身并不是一个创新性的工作,而是将多个工作融合在一起,逐一击破以前方法的痛点,LoRA可以达到全量微调的效果,NF4量化和双量化两种策略实现高保真度4位微调,分页优化器可以解决显存峰值显存不足的问题。这些方法加起来实现了1+1>2的效果,这才实现了单张消费级显卡微调33B大模型、单张专业级显卡微调65B大模型。上面部分是文章的前半部分,证明QLoRA的方法能够在低计算资源场景进行微调,后半部分更多是介绍Guanaco模型,来验证QLoRA的性能。Guanaco是一个基于QLoRA微调的大模型,作者通过定性和定量的分析,和其他大模型进行了对比,证明Guanaco的性能与ChatGPT相当,间接证明了QLoRA在性能上达到了全量微调的能力,此外还对模型的一些其他性质进行了进一步的探索。
那么这篇文章的重点自然是前半部分,对于量化的过程我也并不是特别理解,还需要阅读代码加深影响,这篇工作对我最大的启发是做工作不能一味空想,而是要结合工业界的需求,或者说在应用中发现问题,再想办法用已有的知识解决问题,比如QLoRA就是在LoRA的基础上,发现显存还是不够,那么就压缩数据,显存会有峰值,那么就把一部分放到内存上,不能让显存爆掉,这些就是很容易想到的事情,只不过之前一直没人去做这样的工作罢了,可能也是前两年的需求不够的原因。只有多动手去解决问题,才能够发现更多问题,从而获得更多文章上的灵感。