大模型微调 PEFT 方法
因此,近年来研究者们提出了各种各样的参数高效迁移学习方法,即固定住预训练模型的大部分参数,仅调整模型的一小部分参数来达到与全部参数的微调接近的效果。调整的可以是模型自有的参数,也可以是额外加入的一些参数。目前的微调方法分为加性方法、选择性方法、重参数化方法和混合方法。
Q&A
[Q] 什么情况下模型显存占用大?
- batch size 大,并行计算;
- 模型参数量大,每个参数都需要存储空间(精度不同占用空间不同 fp32 fp16 bf16 int8 int4);
- 计算过程产生大量的中间变量(如激活值、梯度等),这些中间变量也需要存储在显存中,以便进行后续的计算;
- 优化器所需的额外信息多(如动量、学习率等);
- 模型复杂,反向传播的计算图占用更多显存;
[Q] 为什么减少了可训练参数就会减少显存占用?
- 不需要存储它们的梯度;
- 不需要为不可训练参数分配额外的内存来存储优化状态(如动量、学习率等);
- 不需要存储中间激活值(激活值用于在后向传播过程中,计算梯度,进而更新模型的参数);
以 LP32 精度全量微调一个 1.3B 的模型需要占用多少显存? |
[Q] 模型训练过程中有什么有效的减少显存占用的方法?
- 梯度累计技术:将多个小批量训练数据的梯度进行累积,在达到指定累积次数后,使用累积梯度统一更新一次模型参数,从而达到与大批量数据训练相近的效果;
- 相当于降低了 batch size,因而减少了显存占用;
- 多个小批量的可训练参数的梯度是存在一起的,不额外占用显存;
- 梯度检查点 gradient_checkpoint:在后向传播过程中重新计算前向传播中的某些中间激活值,从而减少显存占用;
[Q] 为什么需要 PEFT?
-
全量微调大模型虽然效果还不错,但需要大量的计算资源和训练数据(训练数据中通用数据和领域数据都要有);
-
为了降低计算资源,只微调模型的某几层参数时,无法得到较好的微调结果,会出现欠拟合或泛化能力降低的情况,模型无法有效学习领域数据的知识,且可能会破坏了预训练模型的通用语言语义能力;
-
当修改了输入 Embedding 或大模型每一层的某些部分时,可以在有限的计算资源上,得到与全量微调近似的微调效果,这便是 PEFT 存在的理由;
-
不同领域的全量微调模型需要分开部署,资源占用量大;由于只修改了部分参数,PEFT 中的方法,都具有“一次部署,多领域共用”的能力,只需要一次就能加载所有参数,针对不同领域的调用切换不同的 PEFT 参数,即采用该领域微调所增加的小部分参数;
[Q] 有哪些显存优化策略?
- 高效微调 PEFT;
- Lora
- Prefix-Tuning
- 前向激活值;
- Gradient Accumulation
- Gradient Checkpoints
- Data Length
- 优化器状态;
- Adafactor Optiomizer
- 前向激活值 + 梯度;
- Freeze Model
- 参数量化;
- QLora
背景
2018年Bert问世后,NLP 研究的趋势转变为“预训练模型+微调”。虽然更大的模型带来了更好的性能,但以传统的方式对模型进行全量微调会消耗巨大的计算和存储资源,过高的硬件门槛不利于该领域的研究和发展。
在此背景下,参数高效微调和量化技术应运而生,参数高效微调方法仅对模型的一小部分参数(这一小部分可能是模型自身的,也可能是外部引入的)进行训练,便可以为模型带来显著的性能变化,一些场景下甚至不输于全量微调,颇有一种四两拨千斤的感觉。
由于训练一小部分参数,极大程度降低了训练大模型的算力需求,不需要多机多卡,单卡即可完成对一些大模型的训练。不仅如此,少量的训练参数对存储的要求同样降低了很多,大多数的参数高效微调方法只需要保存训练部分的参数,与动辄几十 GB 的预训练大模型相比,几乎可以忽略。
当下流行 PEFT 结构一览:
常用的参数高效微调方法:
- Selective:选择模型中的一部分参数进行微调;
- Additive:冻结模型原有参数,微调新增的参数和模块;
- Adapters:
- Soft Prompt:
- Reparameterzation:
实现方法
开源工具
开源项目 | 微调方法 | 实现方法 |
---|---|---|
Llama Factory | GaLore、BAdam、DoRA、LongLoRA、LLaMA Pro、Mixture-of-Depths、LoRA+、LoftQ、PiSSA | peft 包、编写 LongLoRA、LlamaPro 流程【重点是对微调流程的整体架构,包括量化、数据预处理、加速训练、评估和模型存储等,用户可以开箱即用】 |
Swift | LoRA、LoRA+、LLaMA Pro、GaLore、LISA、UnSloth、SCEdit、NEFTune、LongLoRA、Adapter、IA3、AdaLoRA | peft 包、编写 LongLoRA、LoRA、LlamaPro、Adapter 流程 |
llama-recipes | LoRA、QLoRA、IA3、AdaLoRA | peft 包 |
Firefly | LoRA、QLoRA | 直接操作模型结构,为所有全连接添加 Adapter |
Axolotl | LoRA、QLoRA、ReLoRA | peft 包、编写 ReLoRA 流程 |
开发包
Bitsandbytes:训练过程中的参数量化、压缩和加速
Peft(没有Adapter方法的实现):参数高效微调技术,旨在通过最小化微调参数的数量和计算复杂度来提高预训练模型在新任务上的性能(可以实现)
Adapters:HuggingFace Transformers 的附加库,将各种适配器方法集成到最先进的预训练语言模型中,以最小的训练和推理编码开销。
DeepSpeed:提供了从训练到推理的全面优化方案,包括参数初始化、训练加速、内存优化等多个方面
开源数据集
测评方法
Acc、F1、PPL、Distinct-n、BLUE-n、Rouge-n、Rouge-L
微调算法
不包括:
微调图像大模型 Stable Diffusion:lokr loha;
将文本到图像的扩散模型适应下游任务:正交矩阵OFT、蝴蝶微调 Boft ;
基于加法 PEFT:增加额外可训练模型结构或参数(Embedding、MLP、LSTM),如:Prompt Tuning、Prefix Tuning、Adapter;
基于选择 PEFT:直接微调大模型中的一部分参数,如:BitFit、LN Tuning;
基于重参数化 PEFT:在已经训练好的参数矩阵的基础上,增加可训练、可合并的参数,如:LoRA、AdaLoRA、PISSA、GaLore;
融合上述三种方法的 PEFT:混合上述三种方法,如:MAM Adapter、UniPELT;
高效量化:不降低训练效果的前提下,降低计算资源的需求,如:QLoRA;
并行训练:提升训练速度,SLoRA;
工程系统角度的优化:梯度检查点、内存卸载;
可训练参数量比较:IA3 < BitFit < Prompt-Tuning < Lora = Prefix-Tuning
BitFit
只训练模型中的 bias 部分,冻结其他参数。
优势:
- 简单高效,资源占用量小;
- 泛化性强,适用各种场景;
不足:
- 可解释性差;
- 强依赖于大模型自身的质量;
LN-Tuning
单独调整 LayerNorm 模块的 weight 和 bias 参数,训练参数量少,便于和其他的微调方法一起使用。
实验表明,Prefix-Tuning + LN 的微调效果最佳。
优势
- 参数量低,效果不错;
Prompt-Tuning
冻结预训练大模型的全部参数,在训练的输入数据前加入一小段 Prompt,只训练 Prompt 的表示层,即一个 Embedding 模块。
其中,Prompt 存在两种形式,分别是 hard prompt 和 soft prompt。hard prompt 通过人工输入的提示词初始化 prompt,soft prompt 随机初始化 prompt。二者相比,hard prompt 可控性更强,训练速度更快。为了优化Soft prompt 的效果,后续研究提出了 P-Tuning。
可训练模块:Embedding(virtual_token, hidden_size)
优势:
- 简化了不同任务之间的转换和迁移,使得模型可以更加灵活地应用于各种场景;
不足:
- 预训练模型较小或在Few-shot场景下,微调结果不佳;
P-Tuning
在 Prompt-Tuning 的 Soft Prompt 基础上,对 Prompt 部分进行进一步的编码计算,加速收敛。具体来说,PEFT 包中支持两种编码方式,一种是 LSTM,一种是 MLP。
可训练模块:Embedding(virtual_token, hidden_size) + MLP/LSTM
优势:
- 通过 Encoder 将离散的 Prompt Embedding 转变为连续的,减少了 Prompt Embedding 初始化对微调性能的影响,提高了训练的稳定性;
不足:
- 增加的 Prompt Encoder 需要额外的计算资源;
Prefix Tuning
将可学习的前缀以 past_key_values 的形式放到模型的 attention 的 KV 头部,每个 MHA 中的注意力层共享同一组前缀。
past _key_values:Transformer 模型中历史计算过的 key 和 value 的结果,最早是用于生成类模型解码加速,解码逻辑是根据历史输入,每次预测一个新的 Token,然后将新的 Token 加入输入,再预测下一个 Token。这个过程中,会存在大量的重复计算,因此可以将 key 和 value 的计算结果缓存,作为 past_key_values 输入到下一次的计算中,这一技术又被称之为 kv cache。
# 可训练模块:Embedding + MLP,与 P-Tuning 的区别是 prefix 映射到了模型的隐藏层上 |
优势:
- 拟合速度快;
不足:
- 直接修改模型结构,依赖预训练模型本身的结构;
- 实现复杂,相比于直接修改输入 Prompt Embedding 没有显著优势;
- 相比于其他的 Soft Prompt 方法,Prefix Tuning 可训练参数量大,每一层的 K V 都需要可训练前缀;
P-Tuning V2
与 Prefix Tuning 最大的区别在于:移除重参数化的编码器,即没有MLP。
通过共享连续提示同时优化多个任务,多任务学习是 P-Tuning v2 的可选功能,可以通过多任务共享前缀进一步提升性能。
优势:
- 移除重参数化的编码器,对于较小的模型,会影响模型的表现,且对于大模型提升不大;
- 引入多任务学习概念,先在多任务的Prompt上进行预训练,然后再适配下游任务;
不足:
- prefix长度在 100~200 时,微调结果最优,但由于模型可接受的最大输入长度有限,随着软提示的参数量增多,实际输入序列的最大长度也会相应减小;
- 直接优化 prompt 和 prefix 是非单调的,比较难以收敛;
Diff pruning
不是修改模型的结构,而是通过一个特定任务的 diff 向量扩展基础模型。学习特定于任务的差异向量,该向量扩展了原始预训练参数。diff 向量 $$\delta_{task}$$ 在训练过程中自适应修剪,并加入 𝐿0 范数惩罚的可微近似来鼓励稀疏性。
$$\theta_{task}=\theta_{pretrained}+\delta_{task}$$
不足:
- 需要底层实现来加速非结构化稀疏矩阵的计算,不能直接使用现有的框架;
- 训练过程中需要存储完整的∆矩阵,相比于Full finetune并没有降低计算成本;
LoRA
深度网络由大量 Dense 层构成,这些参数矩阵通常是低秩的。相关工作表明,在适应特定任务时,预训练模型是过度参数化的,hidden_size 实际上存在于一个较低的内在维度上,即高维数据实际是在低维子空间中。
因此,将 $\Delta\mathbf{W}$ 用两个更参数量更小的矩阵 $\mathbf{A}\in\mathbb{R}^{d\times r}$ 和 $\mathbf{B}\in\mathbb{R}^{r\times d}$ 低秩近似(r<d)。其中,矩阵 B 通过高斯函数初始化,矩阵 A 为全零初始化,使得训练开始之前旁路对原模型不造成影响。
具体而言,冻结预训练的模型权重,并将可训练的秩分解矩阵注入到大模型的每个 Attention 层的线性变换中。输入分别与原始权重和两个低秩矩阵进行计算,共同得到最终结果。
训练完成后,可以将两个低秩矩阵与原始模型中的权重进行合并,合并后的模型与原始模型无异,避免了推理期间 Prompt 系列方法带来的额外计算量。
$$\mathbf{h}=(\mathbf{W}_0+\Delta\mathbf{W})\mathbf{x}=\mathbf{W}_0\mathbf{x}+\mathbf{B}\mathbf{A}\mathbf{x}$$
优势:
- 可以将原权重与训练后权重合并,在推理时不存在额外的计算开销;
- 不增加输入参数,不改变模型结构,简单易用,泛化性强;
- 提出低秩分解矩阵的思路,在减少计算资源需求的同时,不会丢失预训练原有的通用能力;
不足:
- 预先指定每个增量矩阵的内在秩 r 相同,忽略了在微调预训练模型时,权重矩阵的重要性在不同模块和层之间存在显著差异,在实验中可以发现 Wq 的秩更大,即存储的信息更多;因此无法完全捕捉预训练模型的特征,或无法有效地将原始模型的知识迁移到目标任务上;
- 只训练了self-attention,没有训练 feed-forward networks,事实上 FFN 更重要;
IA3
由于不同大模型结构不同,源码实现有差别。bloom 预训练模型的 QKV 共用 Linear 层 (hidden_size, hidden_size*3),IA3 的可训练参数同时作用于三者之上
抑制和放大内部激活,通过可学习的向量对激活值进行抑制或放大。具体来说,通过一组可训练参数直接于 K、V、FFN 相乘,针对不同 batch 的同一位置进行相同的调整(即乘上相同可学习参数),训练过程中冻结原始模型的权重,只更新新增的参数。训练完成后,与 Lora 类似,可以将学习部分的参数与原始权重合并,没有额外推理开销。
优势:
- 调节的参数少于 Lora,微调效果也不错;
不足:
- 学习率对微调效率影响较大,论文中的建议是 3e-3;
AdaLora
AdaLora 在微调过程中,采用“先探索参数空间,再关注最重要的权重”的方法,不预先指定矩阵的秩,而是动态更新增量矩阵的秩,因为研究发现权重矩阵的重要性在不同模块和层之间存在显著差异。在该微调方法中,需要先找到更加重要的矩阵,给其分配更多的参数(更大的秩),并裁剪不重要的矩阵。相比于Lora,该方法在提升模型效果的同时,降低了参数计算量。
区别于 Lora 的低秩矩阵分解,AdaLora 采用参数化矩阵来模拟奇异值分解(SVD),并舍弃不重要的奇异值,保留奇异向量。由于对一个大矩阵进行精确 SVD 分解的计算消耗非常大,这种方法可以加速计算,同时保留未来恢复的可能性并稳定训练。
$$W=W{(0)}+\Delta=W{(0)}+P \Lambda Q$$
计算三元组 QKV 的重要性分数,修剪不太重要的奇异值,将更多预算留给优先级较高的增量矩阵。
$$S_{k,i}=s\left(\lambda_{k,i}\right)+\frac{1}{d_1}\sum_{j=1}{d_1}s\left(P_{k,ji}\right)+\frac{1}{d_2}\sum_{j=1}{d_2}s\left(Q_{k,ij}\right)$$
通过灵敏度平滑和不确定性量化,加入累计灵敏度的影响来解决随机采样和复杂的训练动态导致灵敏度估计的变异性大、不确定性大的问题
$$\begin{aligned}&\bar{I}{(t)}\left(w_{ij}\right)=\beta_1\bar{I}{(t-1)}\left(w_{ij}\right)+\left(1-\beta_1\right)I{(t)}\left(w_{ij}\right)\&\bar{U}{(t)}\left(w_{ij}\right)=\beta_2\bar{U}{(t-1)}\left(w_{ij}\right)+\left(1-\beta_2\right)\left|I{(t)}\left(w_{ij}\right)-\bar{I}^{(t)}\left(w_{ij}\right)\right|\end{aligned}$$
$$s{(t)}\left(w_{ij}\right)=\bar{I}{(t)}\left(w_{ij}\right)\cdot\bar{U}^{(t)}\left(w_{ij}\right)$$
可以通过梯度下降的方式对$P, \Lambda, Q$进行更新,将不需要的奇异值 λ 剪裁 Mask,后续仍可以加入训练
$$\Lambda_k{(t+1)}=\mathcal{T}\left(\tilde{\Lambda}_k{(t)},S_k^{(t)}\right),\text{ with }\mathcal{T}\left(\tilde{\Lambda}k{(t)},S_k{(t)}\right){ii}=\begin{cases}\tilde{\Lambda}_{k,ii}{(t)}&S_{k,i}{(t)}\text{ is in the top- }b^{(t)}\text{ of }S^{(t)}\0&\text{ otherwise}&\end{cases}$$
训练损失中添加了额外的惩罚项,以规范奇异矩阵P和Q的正交性,从而避免SVD的大量计算并稳定训练。
$$R(P,Q)=\left|P^\top P-I\right|\mathrm{F}2+\left|QQ\top-I\right|\mathrm{F}^2$$
最终,微调的损失函数为
重要结论
AdaLoRA 总是倾向于将更多预算分配给 FFN 和顶层,即 FFN 模块和顶层的权重矩阵对于模型性能更为重要。
Adapter Tuning
在 Transformer Layer 的 Self-Attetion 和 FFN 之后插入一个先降维再升维的 MLP(以及一层残差和Layer Normalization)来学习模型微调的知识。
图中,Adapter 即插入的 FF Down + 非线性激活层 + FF up。在微调过程中,固定原始模型的参数,只微调适配层。
不足:
- 需要修改原有模型结构,会增加模型参数量;
变体:
- Paper:仅在 MLP 模块之后和 LayerNorm 之后使用适配器层
AdapterFusion
整合来自多个任务的知识的方法时,常遇到灾难性遗忘和多任务数据集平衡方面的困难。AdapterFusion 分离知识提取和知识组合这两个阶段,可以以非破坏性的方式有效地利用从多个任务中学到的表示。知识提取阶段学习Adapter 任务特定参数,其封装了特定于任务的信息;知识组合阶段将不同任务的 Adapter 组合到一起。
AdapterFusion 组件将在不同任务上训练的多个适配器的输出作为输入,并学习编码信息的参数化混合器,应用于单个任务多 Adapter 的场景和多任务混合的场景。单任务场景中,可以多个 Adapter 可用于提取同一下游任务不同维度的信息,再将他们融合起来。
优势:
- 优于在单任务和多任务中训练的 Adapter 模型,可以视为多Adapter提取不同维度的信息,AdapterFusion 将他们融合起来。
AdapterDrop
该方法在不影响任务性能的前提下,动态高效的移除冗余的 Adapter,可以尽可能地减少模型的参数量,提高模型在反向传播(训练)和正向传播(推理)时的效率。
优势:
- 通过从较低的 Transformer 层删除可变数量的Adaper来提升推理速度。 当对多个任务执行推理时,动态地减少了运行时的计算开销,并在很大程度上保持了任务性能;
MAM Adapter
分解了最先进的参数高效迁移学习方法的设计,并提出了一个在它们之间建立联系的统一框架。
UniPEFT
不同的 PEFT 方法在同一任务上的表现不同,因此为特定任务选择最合适的方法并非易事,特别是考虑到新 PEFT 方法和任务数量的快速增长。鉴于模型的多样性和模型选择的难度,UniPEFT 提出了一个统一的框架 UniPEFT,它将不同的PEFT 方法作为子模块,并通过门控机制学习激活最适合当前数据或任务设置的方法。
PISSA
peft 包中有 PISSA 初始化方法
self.pissa_init(adapter_name, init_lora_weights)
PISSA 和 LoRA 主要的区别是初始化方式不同。同样基于低秩特性的假设,但 PISSA 不是去近似,而是直接基于原矩阵操作。
PiSSA 对预训练模型的参数矩阵$$W\in R^{m\times n}$$ 进行奇异值分解,其中前 r 个奇异值和奇异向量用来初始化适配器 (adapter) 的两个矩阵$$A\in R^{m\times r}$$ 和$$B\in R^{r\times n}$$ ,; $$r\ll\min(m,n)$$ 剩余的奇异值和奇异向量用来构造残差矩阵$$W^{res}\in R^{m\times n}$$ ,使得$$W=AB+W^{res}$$ 。因此,适配器中的参数包含了模型的核心参数,而残差矩阵中的参数是修正参数。通过微调参数量较小的核心适配器 A、B,冻结参数量较大的残差矩阵 $$\text{Wres}$$ ,就达成了用很少的参数近似全参数微调的效果。
优势
- 相比于 LoRA,收敛速度更快,性能更好
VeRA
区别于Lora,Vera 将 A 和 B 矩阵按照高斯分布随机初始化并冻结,只训练两组直接和A、B相乘的一维参数。虽然直观看起来A和B像两个无用的张量,但实际上它们仍然是必不可少的,实验证明即使是随机张量也可以用于微调。
优势:
- VeRA显著减少了可训练参数的数量(LoRA相比参数减少了10倍),而精度没有损失;
- 缩放向量尺寸小,可以将许多版本驻留在单个GPU的有限内存中,从而大大提高了服务效率,适合于需要频繁交换大量微调模型的场景,比如针对个人用户个性化的基于云的人工智能服务;
DoRA
将每个高阶矩阵都分解为 1*k 大小矩阵和 d*k 方向矩阵的乘积,LoRA 倾向于同时改变幅度和方向,DoRA可以更容易地将二者分开调整,或者用另一个的负变化来补偿一个的变化。
SLORA
一个 GPU 上并行执行多个 lora adapters 的微调
S-LoRA 能够在单个 GPU 上或跨多个 GPU 以较小的开销为数千个 LoRA 适配器提供服务。该方法将所有 LoRA 模块存储在主内存中,并将当前运行的查询使用的适配器获取到 GPU 内存,提出采用统一分页技术,使用统一的内存池来管理具有不同等级的动态适配器权重和具有不同序列长度的 KV 缓存张量。此外,该方法采用新颖的张量并行策略和高度优化的定制 CUDA 内核,可视为定制化的 LoRA微调高效计算流程。
GaLore
梯度低秩投影(GaLore)是一种全量参数学习的训练策略,但比常见的低秩自适应方法(LoRA)更节省内存。其关键思想是利用权重矩阵 W 的梯度 $$G\in \mathbb{R}^{m\times n}$$ 缓慢变化的低秩结构,而不是试图将权重矩阵本身近似为低秩。
优势:
- 节省内存(三倍);
- 性能不错;
不足:
- 训练速度慢(三倍);
LoRA+
LoRA 中的适配器矩阵 A 和 B 以相同的学习率更新,实验表明对 A 和 B 使用相同的学习率并不能实现有效的特征学习,LoRA+ 通过精心选择的固定比率为 LoRA 适配器矩阵 A 和 B 设置不同的学习率,纠正 LoRA 的这种次优性。
LongLoRA
LongLoRA 扩展了模型的上下文,同时保留了其原始架构,并且与大多数现有技术兼容。一方面,虽然推理过程中需要密集的全局注意力,但微调过程更需要稀疏的局部注意力实现有效且高效反向传播。由此,该方法提出转移稀疏注意力
$$S^2-Attn$$
有效地实现了上下文扩展。另一方面,除了在线性层中训练 LoRA 权重之外,LongLoRA 还进一步使嵌入层和归一化层变得可训练,由此可以表现出较好的性能。从实现上来看,该方法在训练中只需两行代码即可实现,且在推理中是可选的,不会占用额外计算资源。
RsLoRA
LoRA通过在选定层添加可训练的低秩Adapter来实现参数有效的微调。每个LoRA由两个低秩矩阵乘积组成,并乘以一个与秩相关的因子,传统的LoRA采用“直接除以秩的因子”的方法过于激进,导致高秩Adapter的学习速度减缓,性能受限。因此,在实际应用中,LoRA通常仅限于使用非常低的秩。
rsLoRA深入研究了 LoRA 的缩放因子对学习过程的影响,并证明了 LoRA 应该除以秩的平方根而不是秩,通过使用较大的秩在训练期间增加计算资源以获得更好的微调性能,同时不改变推理计算成本。
LLaMA Pro
该方法提出的Block Expansion方法,即块扩展,在保持预训练模型参数不变的基础上,增加新的block来适应新的训练任务。这些新加入的block与原有block协同工作,既保留了模型原有的知识,又能够适应新的训练数据和任务需求。
方法性能对比
从方法类型、是否存储高效、是否内存高效、反向传播成本、推理开销五个维度比较 PEFT 方法:
各种参数高效方法的参与训练的参数量、最终模型与原始模型的改变参数(delta值)以及论文中参与评估的模型的范围:
PEFT 方法在何种模型大小上进行过评估,以及在论文中通常使用的可训练参数数量。我们所说的可训练参数数量是指由梯度优化算法更新的参数数量,而不是我们用“更改参数”表示的原始模型与最终模型之间的差异。对于重参数化方法,我们报告了重参数化前后的参数数量。由于S4模型在不同层使用了不同的方法,因此估算其更新后的参数数量比较复杂。我们报告了在已发表的文献中对这些方法进行评估的范围。
近年来,基于Transformer架构的大语言模型(LLM),在众多自然语言处理(NLP)任务达到了最佳性能表现。目前,构建领域专用LLM的主流策略是:在海量通用数据集上预训练的大语言模型(PLM),并通过针对特定下游任务的微调(Fine-tuning)。相较于直接采用PLM,针对下游任务的微调能显著提升模型性能。然而,随着LLM参数规模急剧增长,在消费级硬件上进行微调变得不切实际。
为应对此挑战,研究者们近年来提出了参数高效微调技术(Parameter-Efficient Fine-Tuning, PEFT),其核心思想在于固定PLM的大部分参数,仅调整一小部分关键参数或引入额外参数,以接近直接微调PLM的效果。这种方法不仅保留了PLM的广泛知识库,还显著降低了计算与存储需求,为在资源受限环境下高效微调LLM开辟了新路径。
高效量化
QLoRA
创新点:
- 4位NormalFloat(NF4):这是一种针对正态分布权重设计的信息理论上最优的量化数据类型。相较于传统的4位整数和4位浮点数,NF4为正态分布数据提供了更优异的实证性能。
- 双重量化:QLora引入了对量化常数的二次量化,进一步减小了缓存占用。这种双重量化机制包含对普通参数的一次量化和对量化常数的再量化,从而在不牺牲精度的前提下进一步压缩模型。
- 分页优化器:这是一种智能的内存管理技术,当GPU内存不足时,它可以将部分数据移到系统内存中,并在需要时调回GPU内存。这有助于处理长序列或大批量数据时的内存峰值问题。
优势:
- 提出了高效且有效的量化技术,使在单个GPU上微调超大型参数模型成为可能;
LoftQ
该方法一种新的量化框架,在对 LLM 进行量化的同时,为 LoRA 微调找到合适的低秩初始化。这种初始化减轻了量化模型和全精度模型之间的差异,并显着提高了下游任务的泛化能力。
GPTQ
AWQ
GGUF
微调方法适配
如何将微调模型应用在 自定义/未被官方适配 的大模型上
通过 target_modules
和 modules_to_save
实现自定义可训练参数和模块
Merge Peft Model:将预训练好的 Lora 或 IA3 的模型参数融入预训练模型中,实现不修改原模型的结构和参数量