当前位置: 首页 > article >正文

qlora原理

QLORA论文学习 (QLORA: Efficient Finetuning of Quantized LLMs)

1、摘要

我们提出了QLORA,这是一种高效的微调方法,它减少了足够的内存使用,可以在单个48GB GPU上微调一个650亿参数的模型,同时保留了完整的16位微调任务性能。QLORA通过一个冻结的、4位量化的预训练语言模型向后传播梯度到低秩适配器(LoRA)。我们最好的模型系列,我们称之为Guanaco,在Vicuna基准测试中超过了所有以前公开发布的模型,达到了ChatGPT 99.3%的性能水平,而仅在单个GPU上微调了24小时。QLORA引入了一系列创新,以节省内存而不牺牲性能:(a) 4位NormalFloat (NF4),这是一种新的数据类型,对于正态分布的权重在信息理论上是最优的;(b) 双重量化,通过对量化常再次进行量化数来减少平均内存占用;以及© **分页优化器,用于管理内存尖峰。**我们使用QLORA对超过1000个模型进行了微调,提供了在8个指令数据集、多种模型类型(LLaMA、T5)和模型规模上的指令遵循和聊天机器人性能的详细分析,这些模型规模在常规微调中是不可行的(例如,330亿和650亿参数模型)。
我们的结果显示,QLoRA在小型高质量数据集上的微调得出了最先进的结果,即使使用比以前的最先进模型更小的模型也是如此。我们提供了基于人类和GPT-4评估的聊天机器人性能的详细分析,显示GPT-4评估是人类评估的一个便宜且合理的替代方案。

2、介绍

微调大型语言模型(LLMs)是一种非常有效的方法,可以改善它们的性能,并增加期望的行为或移除不期望的行为。然而,微调非常大的模型是过于昂贵的;常规的16位微调一个LLaMA 650亿参数模型需要超过780GB的GPU内存。虽然最近的量化方法可以减少LLM的内存占用,但这类技术只适用于推理,而在训练过程中会失效。我们首次证明,可以在不损失任何性能的情况下微调一个量化到4位的模型。我们的方法,QLORA,使用一种新颖的高精度技术将预训练模型量化到4位,然后添加一组小的可学习的低秩适配器权重,通过量化权重反向传播梯度来调整这些权重。

QLORA将650亿参数模型微调的平均内存需求从780GB以上的GPU内存降低到48GB以下,同时与16位完全微调的基线相比,不会降低运行时间或预测性能。这标志着大型语言模型微调可及性方面的重大转变:现在,迄今为止最大的公开可用模型可以在单个GPU上进行微调。使用QLORA,我们训练了Guanaco系列的模型,其中表现第二好的模型在Vicuna[10]基准测试中达到了ChatGPT 97.8%的性能水平,而其在单个消费者级GPU上的训练时间不到12小时;

使用单个专业级GPU超过24小时,我们的最大模型实现了99.3%,在Vicuna基准测试中基本缩小了与ChatGPT的差距。部署时,我们最小的Guanaco模型(70亿参数)仅需要5GB内存,并且在Vicuna基准测试中,其性能比一个26GB的Alpaca模型高出20多个百分点。

QLORA引入了多项创新,旨在减少内存使用而不牺牲性能:
**(1) 4位NormalFloat,**这是一种针对正态分布数据的信息理论上最优的量化数据类型,与4位整数和4位浮点数相比,能产生更好的实证结果。

(2)双重量化,一种对量化常数进行二次量化的方法,平均每个参数节省约0.37位(对于650亿参数模型大约节省3GB)。

(3) 分页优化器,使用NVIDIA统一内存来避免在处理具有长序列长度的小批量时出现的梯度检查点内存尖峰。我们将这些贡献结合到一个更优化的LoRA方法中,该方法在每个网络层都包括适配器,从而避免了先前工作中看到的几乎所有精度折衷。

QLORA的高效性使我们能够在模型规模上进行深入的指令微调和聊天机器人性能研究,这些模型规模由于内存开销,使用常规微调是不可能的。
因此,我们在几个指令调整数据集、模型架构和80M到65B参数的规模之间训练了超过1000个模型。除了展示QLORA恢复16位性能(第4节)和训练最先进的聊天机器人Guanaco(第5节)之外,我们还分析了训练模型中的趋势。

首先,我们发现数据质量远比数据集大小重要,例如,一个9k样本的数据集(OASST1)在聊天机器人性能上超过了450k样本的数据集(FLAN v2,抽样),即使两者都旨在支持指令遵循泛化。其次,我们展示了强大的大规模多任务语言理解(MMLU)基准性能并不意味着强大的Vicuna聊天机器人基准性能,反之亦然——换句话说,对于给定任务,数据集的适用性比大小更重要。

此外,我们还提供了使用人类评分者和GPT-4进行评估的聊天机器人性能的广泛分析。我们使用锦标赛风格的基准测试,其中模型在比赛中相互竞争,为给定的提示产生最佳响应。比赛的获胜者由GPT-4或人类评分者判断。锦标赛结果被汇总成Elo分数,这些分数决定了聊天机器人性能的排名。我们发现GPT-4和人类评估在锦标赛中模型性能排名上大体一致,但我们也发现存在强烈分歧的情况。因此,我们强调,虽然基于模型的评估为人类标注提供了一种廉价的替代方案,但也存在不确定性。我们通过定性分析Guanaco模型来补充我们的聊天机器人基准测试结果。我们的分析突出了定量基准测试未能捕捉到的成功和失败案例。

我们发布了所有模型生成的人类和GPT-4注释,以促进进一步的研究。我们开源了我们的代码库和CUDA内核,并将我们的方法集成到Hugging Face transformers堆栈中,使它们易于所有人访问。我们发布了一系列适配器,用于7/13/33/65B大小的模型,这些模型在8个不同的指令遵循数据集上进行了训练,总共发布了32个不同开源的微调模型。

不同的微调方法及其内存要求。QLORA通过将Transformer模型量化到4位精度,并使用分页优化器处理内存尖峰,从而改进了LoRA。

3、背景

块状k位量化: 量化是将输入从一个包含更多信息的表现形式离散化到包含较少信息的表现形式的过程。它通常意味着将一个位数更多的数据类型转换为位数更少的数据类型,例如从32位浮点数转换为8位整数。为了确保使用了低比特数据类型的整个范围,通常通过输入元素(通常结构化为张量)的绝对最大值进行归一化,将输入数据类型重新缩放为目标数据类型的范围。例如,将32位浮点(FP32)张量量化为范围为[-127, 127]的Int8张量:
X I n t 8 = r o u n d ( 127 a b s m a x ( X F P 32 ) X F P 32 ) = r o u n d ( c F P 32 ∗ X F P 32 ) X^{Int8} = round(\frac{127}{absmax(X^{FP32})} X^{FP32}) = round(c^{FP32}* X^{FP32}) XInt8=round(absmax(XFP32)127XFP32)=round(cFP32XFP32)

其中c是量化常数或量化比例。去量化是相反的过程:
d e q u a n t ( c F P 32 , X I n t 8 ) = X i n t 8 c F P 32 = X F P 32 dequant(c^{FP32}, X^{Int8}) = \frac{X^{int8}}{c^{FP32}}=X^{FP32} dequant(cFP32,XInt8)=cFP32Xint8=XFP32
这种方法的问题是,如果输入张量中出现了一个大数值(即,一个异常值),那么量化区间——某些比特组合——就不能很好地被利用,因为有些区间中几乎没有或没有数值被量化。为了防止异常值问题,一个常见的方法是将输入张量分块,每个块独立量化,每个块都有自己的量化常数c。这可以形式化为:我们将输入张量 X ∈ R b × h X ∈ R^{b×h} XRb×h分成n个大小为B的连续块,通过展平输入张量并将线性段切分为n = (b × h)/B块。我们独立使用方程1对这些块进行量化,以创建一个量化张量和n个量化常数ci。

低秩适配器 低秩适配器(LoRA)微调是一种通过使用一组小的可训练参数(通常称为适配器)来减少内存需求的方法,同时不更新保持固定的全模型参数。在随机梯度下降期间,梯度通过固定预训练模型权重传递到适配器,适配器被更新以优化损失函数。LoRA通过一个额外的分解投影来增强线性投影。给定一个投影XW = Y,其中 X ∈ R b × h X ∈ R^{b×h} XRb×h, W ∈ R h × o W ∈ R^{h×o} WRh×o,LoRA计算:
Y = X W + s X L 1 L 2 , Y = XW+ sXL1L2, Y=XW+sXL1L2,
其中 L 1 ∈ R h × r L1 ∈ R^{h×r} L1Rh×r L 2 ∈ R r × o L2 ∈ R^{r×o} L2Rr×o,s是一个标量。

参数高效微调的内存要求: 一个重要的讨论点是LoRA在训练过程中的内存需求,包括使用的适配器数量和大小。由于LoRA的内存占用非常小,我们可以使用更多的适配器来提高性能,而不会显著增加总内存使用。虽然LoRA被设计为一种参数高效微调(PEFT)方法,但LLM微调的大部分内存占用来自激活梯度,而不是学习的LoRA参数。对于在FLAN v2上训练的7B LLaMA模型,批处理大小为1,使用与原始模型权重[28, 37]常用的0.2%等效的LoRA权重,LoRA输入梯度具有567 MB的内存占用,而LoRA参数仅占用26 MB。使用梯度检查点[9],输入梯度减少到每个序列平均18 MB,使得它们比所有LoRA权重组合的内存占用更密集。相比之下,4位基础模型消耗了5,048 MB的内存。这强调了梯度检查点的重要性,但也表明,大幅减少LoRA参数的数量只会带来微小的内存好处。这意味着我们可以使用更多的适配器,而不会显著增加整体训练内存占用(详见附录G的详细分解)。正如后面讨论的,这对于恢复全16位精度的性能至关重要。

4、QLora Finetuning

QLORA通过我们提出的两种技术——4位NormalFloat(NF4)量化和双量化——实现了高保真4位微调。此外,我们引入了分页优化器,以防止在梯度检查点期间内存尖峰导致内存不足错误,这种错误传统上使得在单台机器上对大型模型进行微调变得困难。

QLORA有一个低精度存储数据类型,在我们的情况下通常是4位,还有一个通常是BFloat16的计算数据类型。在实践中,这意味着每当使用QLORA权重张量时,我们将其去量化到BFloat16,然后在16位中执行矩阵乘法。

我们现在讨论QLORA的组成部分,然后是QLORA的正式定义。

4位NormalFloat量化 NormalFloat(NF)数据类型建立在分位数量化之上,后者是一种信息论上最优的数据类型,确保输入张量中的每个量化区间都有相等数量的值分配。分位数量化通过估计输入张量的分位数,通过经验累积分布函数来工作。

分位数量化的主要限制是分位数估计过程特别昂贵。因此,使用快速分位数近似算法,如SRAM分位数,来估计它们。由于这些分位数估计算法的近似性质,数据类型对于异常值具有大的量化误差,而这些异常值通常是重要的值。当输入张量来自一个固定的分布,直到一个量化常数时,可以避免昂贵的分位数估计和近似误差。在这种情况下,输入张量具有相同的分位数,使得精确的分位数估计在计算上是可行的。

由于预训练的神经网络权重通常具有以零为中心的正态分布,标准差为σ(参见附录F),我们可以通过缩放σ来将所有权重转换到单一固定分布,使得分布正好适合我们数据类型的范围。对于我们的数据类型,我们设置任意范围[-1, 1]。因此,数据类型和神经网络权重的分位数都需要归一化到这个范围。

对于在范围[-1, 1]内具有任意标准差σ的零均值正态分布,信息论上最优的数据类型计算如下:(1)估计理论N(0, 1)分布的2k + 1个分位数,以获得正态分布的k位分位数量化数据类型,(2)取这个数据类型并将其值归一化到[-1, 1]范围,(3)通过绝对最大值重新缩放,将输入权重张量归一化到[-1, 1]范围,然后对其进行量化。

一旦权重范围和数据类型范围匹配,我们就可以像往常一样进行量化。步骤(3)等效于重新缩放权重张量的标准差,以匹配k位数据类型的标准差。更正式地说,我们估计数据类型的2k个值qi如下:
q i = f r a c 12 ( Q x ( i 2 k + 1 ) + Q x ( i + 1 2 k + 1 ) ) q_i = frac{1}{2}(Qx(\frac{i}{2^k+1}) + Qx(\frac{i+1}{2^k+1})) qi=frac12(Qx(2k+1i)+Qx(2k+1i+1))
其中QX(·)是标准正态分布N(0, 1)的分位数函数。对于对称的k位量化,这种方法没有零的精确表示,这是一个重要的属性,可以无误差地对齐填充和其他零值元素。

为了确保离散的零点为0,并使用所有2k位用于k位数据类型,我们创建了一个不对称的数据类型,通过估计两个范围的分位数qi:2k-1用于负部分,2k-1 + 1用于正部分,然后我们统一这些qi集合并删除两个集合中都出现的两个零中的一个。我们称这种具有每个量化区间中相等期望数量的值的数据类型为k位NormalFloat(NFk),因为该数据类型对于以零为中心的正态分布数据在信息论上是最优的。

**二次量化:**我们引入了双重量化(DQ),这是一种对量化常数进行量化以获得额外内存节省的过程。虽然精确的4位量化需要一个小的块大小[13],但它也带来了相当大的内存开销。例如,使用32位常数和64的块大小,量化常数平均每参数增加32/64 = 0.5位。双重量化有助于减少量化常数的内存占用。

更具体地说,双重量化将第一次量化的量化常数 c 2 F P 32 c^{FP32}_2 c2FP32作为第二次量化的输入。这一步产生了量化量化常数 c 2 F P 8 c^{FP8}_2 c2FP8和第二级量化常数 c 1 F P 32 c^{FP32}_1 c1FP32。我们使用256块大小的8位浮点数进行第二次量化,因为对于8位量化,没有观察到性能下降,这与Dettmers和Zettlemoyer的结果一致。
由于 c 2 F P 32 c^{FP32}_2 c2FP32是正数,我们在量化之前从c2中减去均值,以将值围绕零中心化,并使用对称量化。平均而言,对于64的块大小,这种量化将每参数的内存占用从32/64 = 0.5位减少到8/64 + 32/(64 256) = 0.127位,每参数减少了0.373位。

分页优化器使用NVIDIA统一内存特性,该特性在CPU和GPU之间自动进行页面到页面的传输,以便在GPU偶尔内存不足的情况下进行无错误的GPU处理。该特性类似于在CPU RAM和磁盘之间进行常规内存分页。我们使用这个特性为优化器状态分配分页内存,当GPU内存不足时,这些状态会自动被驱逐到CPU RAM中,在优化器更新步骤需要内存时,再分页回到GPU内存中。

**QLORA。**使用上面描述的组件,我们定义了QLORA,用于具有单个LoRA适配器的量化基础模型中的单个线性层,如下所示:
Y B F 16 = X B F 16 d o u b l e D e q u a n t ( c 1 F P 32 , c 2 k − b i t , W N F 4 ) + X B F 16 L 1 B F 16 L 2 B F 16 Y^{BF16} = X^{BF16} doubleDequant(c^{FP32}_1, c^{k-bit}_2, W^{NF4})+X^{BF16}L^{BF16}_1 L^{BF16}_2 YBF16=XBF16doubleDequant(c1FP32,c2kbit,WNF4)+XBF16L1BF16L2BF16 方程式5

其中doubleDequant(·)定义如下:

d o u b l e D e q u a n t ( c 1 F P 32 , c 2 k − b i t , W k − b i t ) = d e q u a n t ( d e q u a n t ( c 1 F P 32 , c 2 k − b i t ) , W 4 b i t ) = W B F 16 doubleDequant(c_1^{FP32}, c_2^{k-bit}, W^{k-bit}) = dequant(dequant(c_1^{FP32}, c_2^{k-bit}), W^{4bit}) = W^{BF16} doubleDequant(c1FP32,c2kbit,Wkbit)=dequant(dequant(c1FP32,c2kbit),W4bit)=WBF16
我们使用NF4数据类型对W进行量化,并使用FP8数据类型对c2进行量化。为了获得更高的量化精度,我们对W使用64的块大小,而对c2使用256的块大小以节省内存。

对于参数更新,只需要适配器权重相对于误差的梯度 ∂ E ∂ L i \frac{∂E}{∂Li} LiE,而不需要4位权重 ∂ E ∂ W \frac{∂E}{∂W} WE的梯度。然而,计算 ∂ E ∂ L i \frac{∂E}{∂Li} LiE 则需要计算 ∂ X ∂ W \frac{∂X}{∂W} WX,这通过方程式(5)进行,首先从存储数据类型 W N F 4 W^{NF4} WNF4进行去量化到计算数据类型 W B F 16 W^{BF16} WBF16,以计算BFloat16精度下的导数 ∂ X ∂ W \frac{∂X}{∂W} WX

总结一下,QLORA有一个存储数据类型(通常是4位NormalFloat)和一个计算数据类型(16位BrainFloat)。我们将存储数据类型去量化到计算数据类型,以执行前向和后向传递,但我们只计算使用16位BrainFloat的LoRA参数的权重梯度。


http://www.kler.cn/news/327707.html

相关文章:

  • 基于SpringBoot+Vue的留学信息推荐系统
  • UNI-APP_iOS开发技巧之:跳转到TestFlight或者App Store
  • 鸿蒙NEXT开发-ArkUI(基于最新api12稳定版)
  • 城市轨道交通网络客流大数据可视化分析系统----以某市交通网络客流数据为例
  • 负载均衡架构解说
  • 【Vue】vue2项目打包后部署刷新404,配置publicPath ./ 不生效问题
  • 极狐GitLab 17.4 升级指南
  • 小米2025届软件开发工程师(C/C++/Java)(编程题AK)
  • 丹摩智算平台部署 Llama 3.1:实践与体验
  • linux文件编程_进程
  • 2024新淘宝镜像地址下载【vue-cli】
  • 浅析人脸活体检测技术的实现过程及其应用领域
  • MongoDB 用户管理
  • docker 部署minio
  • Webpack 打包后文件过大,如何优化?
  • Maven超详细教程(三):Maven依赖查找顺序
  • PHP中的时间和日期详解
  • 无人机之数据提取篇
  • 性能优化-数据库分区技术深入解析
  • Java爬虫抓取数据的艺术
  • 56 门控循环单元(GRU)_by《李沐:动手学深度学习v2》pytorch版
  • 【JavaEE】——多线程常用类
  • spring boot集成日志
  • Hadoop集群的高可用(HA):NameNode和resourcemanager高可用的搭建
  • tauri中加载本地文件图片或者下载网络文件图片后存储到本地,然后通过前端页面展示
  • Trilium Notes笔记本地化部署与简单使用指南打造个人知识库
  • 数据结构和算法基础(一)
  • 探索Cherry键盘的FN+F9游戏模式与Ctrl+Fn功能
  • ffmpeg 结合 opencv 显示ps流文件
  • 深入计算机语言之C++:C到C++的过度