【学习记录】大模型微调方法
本文主要记录部分大模型微调的常用的、主流的方法及其原理。
目录
写在前面
仅作个人学习记录用。本文主要记录部分大模型微调的常用的、主流的方法及其原理。
一、为什么需要大模型微调
首先对大模型的训练进行一个十分简略的定义:
大模型输入序列 X = ( x 1 , x 2 , . . . , x m ) X = (x_1, x_2, ..., x_m) X=(x1,x2,...,xm)
大模型输出序列 Y = ( y 1 , y 2 , … , y n ) Y = (y_1, y_2, …, y_n) Y=(y1,y2,…,yn)
大模型训练出的参数是 W W W
其中X和Y的关系是: Y = W X Y = WX Y=WX
要想将已有的通用大模型转变为等各个领域,例如医疗、法律、教育、金融的垂直大模型,我们即是需要改变参数 W W W。仅仅对提示词下手做Prompt Engineering是远远不够的(当然学会这一技能也是十分有用的,详见 人人都需要掌握的Prompt Engineering技巧)。因此,大模型微调(Fine Tuning)成为了打造垂直大模型无法绕过的技术。
二、大模型微调方法
1. FFT(Full Fine Tuning)
全参数微调(Full Fine Tuning, FFT)顾名思义是对全量的参数,进行全量的训练。用特定的领域数据,例如金融行业数据,更新训练整个 W W W,使其变成 W ′ W' W′。
一个使用场景的典型例子:假设现在有 Stable Diffusion模型,能生成各种场景的图像。如果需要让这个模型只用于生成各种现实场景的各种真人照片,这时候可以采用全参数微调。准备大量真人的照片,然基于这些图像进行微调,训练一个只用于真实照片生成的专用模型。
大语言模型也是同样的道理,如果想训练一个仅用于金融领域的的LLM,可以准备大量的金融文本数据,采用FFT将通用LLM训练为金融专精的LLM。但是这样的方法存在两个严重的问题。一是训练的成本非常高,几乎相当于二次预训练;二是FFT可能导致灾难性遗忘,使得微调大模型的各种任务表现反而比通用大模型低。
因此,目前主流使用PEFT来代替FFT以缓解此类问题。本部分对FFT的原理也不再多加阐述。
2. PEFT(Parameter-Efficient Fine Tuning)
参数高效微调(Parameter-Efficient Fine Tuning, PEFT)是目前业界主流的微调方案。本部分主要介绍几种流行的、具有代表性的或者新提出值得注意的PEFT微调方案。
2.1 LoRA
作为目前最火的大模型轻量级微调方法,它的微调效果是毋庸置疑的。LoRA的出现得益于 Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning 中的关于内在维度(intrinsic dimension)的发现:
预训练模型拥有极小的内在维度(instrisic dimension),即存在一个极低维度的参数,微调它和在全参数空间中微调能起到相同的效果。
大模型在任务适配过程中权重的改变量是低秩(low rank)的,而LoRA(低秩自适应)方法允许我们通过优化适应过程中密集层变化的秩分解矩阵,来间接训练神经网络中的一些密集层,同时保持预先训练的权重不变。
方法如下:
(1) 在原始 PLM (Pre-trained Language Model) 中增加一个旁路,做一个降维再升维的操作,来模拟intrinsic rank。
(2) 开始训练,训练时固定 PLM 的参数,只训练降维矩阵 A A A 与升维矩阵 B B B 。而模型的输入输出维度不变,输出时将 B A BA BA与 PLM 的参数叠加。
(3) 用随机高斯分布初始化
A
A
A ,用 0 矩阵初始化
B
B
B ,保证训练的开始时的旁路矩阵依然是 0 矩阵。
假设要微调一个预训练LLM,则需要更新预训练模型的初始化参数
W
W
W,公式表示如下:
W
′
=
W
+
Δ
W
=
W
+
B
A
,
B
∈
R
d
×
r
,
A
∈
R
r
×
d
W' = W+\Delta W = W+BA , B\in \mathbb{R}^{d\times r}, A\in \mathbb{R}^{r\times d}
W′=W+ΔW=W+BA,B∈Rd×r,A∈Rr×d
其中
Δ
W
\Delta W
ΔW即是需要更新的参数。如果是FFT方法,则
Δ
W
=
W
\Delta W = W
ΔW=W,从这里同样可以看出,要FFT方法微调大模型,成本非常高昂,而FFT也可以被看做是LoRA的特例,即当
r
=
d
r=d
r=d 时。
在前向传播过程中,
Δ
W
\Delta W
ΔW和
W
W
W都会乘以相同的大模型输入序列
X
X
X,然后相加:
h
=
W
X
+
Δ
W
X
=
W
+
B
A
X
h = WX+\Delta WX = W+BAX
h=WX+ΔWX=W+BAX
LORA 的这种思想有点类似于残差连接,同时使用这个旁路的更新来模拟 FFT的过程。在推理过程中,LoRA也几乎未引入额外的Inference Latency,LoRA与Transformer的结合也很简单,仅在注意力的计算中增加了一个旁路。
2.2 QLoRA
QLoRA来源于 QLoRA: Efficient Finetuning of Quantized LLMs,是量化(Quantization)版的LoRA,它是在LoRA的基础上将原本用16bit表示的参数,降为用4bit来表示,可以在保证模型效果的同时,极大地降低训练成本和推理成本。
具体原理可参考 LORA微调系列(二):QLORA和它的基本原理。
2.3 AdaLoRA
AdaLoRA来源于 Adaptive Budget Allocation for Parameterefficient Fine-Tuing,其改进了LoRA可微调参数的分配方式,根据每个参数的重要程度自动得为其分配可微调参数的预算。从原理上来说,AdaLORA采用奇异值分解(SVD)的形式参数化增量更新。
具体原理可参考 LORA微调系列(三):AdaLORA和它的基本原理。
2.4 Prompt-tuning
Prompt-tuning聚焦于调整输入提示(input prompt)而非修改模型参数。这意味着预训练模型保持不变,只有输入提示被修改以适应下游的任务。通过设计和优化一组提示,可以使预训练模型执行特定任务。
即将 X = ( x 1 , x 2 , . . . , x m ) X = (x_1, x_2, ..., x_m) X=(x1,x2,...,xm)变成 X ′ = ( x 1 ′ , x 2 ′ , . . . , x m ′ ; x 1 , x 2 , . . . , x m ) X' = (x_1', x_2', ..., x_m';x_1, x_2, ..., x_m) X′=(x1′,x2′,...,xm′;x1,x2,...,xm),而参数 W W W并无变化。
2.4.1 Prefix tuning
Prefix tuning 在 Prefix-Tuning: Optimizing Continuous Prompts for Generation 中被提出。正如其名,前缀调整涉及学习特定任务的连续提示,在推理过程中将其添加到输入之前。其实可以被认为是一种Prompt-tuning,虽然Prefix tuning并不是在输入提示上下手,但却在Transformer的Encoder和Decoder的网络中都加了一些特定前缀,并没有修改模型底层参数。通过优化这个连续提示,模型可以适应特定任务而不修改底层模型参数,这节省了计算资源并实现了高效的精调。与一般的微调区别如下:
一般微调(顶部)更新所有Transformer参数(红色Transformer框),并且需要为每个任务存储完整的模型副本。而Prefix tuning(底部)冻结了Transformer参数并仅优化前缀(红色前缀块)。因此Prefix tuning只需要为每个任务存储前缀,使前缀调优模块化且节省空间。
2.4.2 P-Tuning
P-Tuning来源于 GPT Understands, Too,该方法将Prompt转换为可以学习的Embedding层,并用MLP+LSTM模型对Prompt Embedding进行进一步的处理。
相比Prefix Tuning在所有层加入virtual token,P-Tuning仅仅在输入层加入了可微的virtual token;另外,virtual token的位置也不一定是Prefix Tuning中的前缀,插入的位置是可选的。本质上 是把传统的人工设计的真实token替换成可微的virtual token。
2.4.3 P-Tuning v2
P-Tuning v2来源于 P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks。它的提出是为了缓解P-Tuning缺乏规模通用性、缺乏任务普遍性和缺少深度提示优化的问题。
具体做法和Prefix Tuning基本相同,可以看作是将文本生成的Prefix Tuning技术适配到自然语言理解(NLU)任务中,然后做了一些改进:移除重参数化的编码器(如:Prefix Tuning中的MLP、P-Tuning中的LSTM)、针对不同的文本生成任务采用不同提示长度、引入多任务学习、使用传统的分类标签范式。
2.5 Child-Tuning
Child-Tuning来源于 Raise a Child in Large Language Model: Towards Effective and Generalizable Fine-tuning,是在Fine-tuning过程中仅更新预训练模型中部分网络的参数(这部分网络被称做Child Network)。
方法如下:
(1) 在预训练模型中发现确认Child Network,并生成对应的Weights的Gradients 0-1 Mask
(2) 在后向传播计算完梯度之后,仅仅对Child Network中的参数进行更新,而其他参数保持不变。
具体原理可参考 极简单但贼有效的Fine-tuning算法,几行代码最高涨点8%。
- 更多更详细的PEFT方法详见 Scaling Down to Scale Up: A Guide to Parameter-Efficient Fine-Tuning
- 较早的或不是主流的微调方法(例如Adapter)的原理讲解可以参考大模型参数高效微调技术原理综述(四)和 大模型参数高效微调技术原理综述(六)
参考
[1] 通俗解读大模型微调(Fine Tuning)
[2] 预训练大语言模型的三种微调技术总结
[3] LORA:大模型轻量级微调
[4] 极简单但贼有效的Fine-tuning算法,几行代码最高涨点8%
[5] 大模型参数高效微调技术原理综述(三)
更多推荐
所有评论(0)