为什么要对大模型进行微调
1.成本效益:
o 大模型的参数量非常大,训练成本非常高,每家公司都去从头训练一个自己的大模型,这个事情的性价比非常低。
2.Prompt Engineering 的局限性:
o Prompt Engineering 是一种相对容易上手的使用大模型的方法,但它有明显缺点。因为通常大模型的实现原理都会对输入序列的长度有限制,Prompt Engineering 的方式会把 Prompt 搞得很长。越长的 Prompt,大模型的推理成本越高,因为推理成本是跟 Prompt 长度的平方正相关的。另外,Prompt 太长会因超过限制而被截断,进而导致大模型的输出质量打折扣,这也是一个非常严重的问题。
3.提升特定领域能力:
o Prompt Engineering 的效果达不到要求,而企业又有比较好的自有数据,能够通过自有数据,更好地提升大模型在特定领域的能力。这时候微调就非常适用。
4.个性化服务:
o 要在个性化服务中使用大模型的能力,这时候针对每个用户的数据,训练一个轻量级的微调模型,是一个不错的方案。
5.数据安全:
o 如果数据不能传递给第三方大模型服务,那么搭建自己的大模型就非常必要。
如何对大模型进行微调
从参数规模角度
1.全量微调(Full Fine Tuning, FFT)
o 对全量参数进行全量训练,用特定的数据,对大模型进行训练,将 W 变成 W’。W’ 相比 W ,最大的优点就是上述特定数据领域表现会好很多,但缺点是训练成本高,并且存在灾难性遗忘(Catastrophic Forgetting)的风险。灾难性遗忘(Catastrophic Forgetting),用特定训练数据去微调可能会把这个领域的表现变好,但也可能会把原来表现好的别的领域的能力变差。
2.参数高效微调(Parameter-Efficient Fine Tuning, PEFT)
o 只对部分参数进行训练,解决 FFT 存在的问题。PEFT 是目前比较主流的微调方案。
从训练数据来源和方法角度
1.增量预训练(Continue PreTraining)
o 一般垂直大模型是基于通用大模型进行二次的开发。为了给模型注入领域知识,就需要用领域内的语料进行继续的预训练。
举例:假设我们有一个已经在通用语料库上预训练的GPT模型,现在我们希望让这个模型在医学领域的文本上表现更好。我们可以使用大量的医学文献对这个GPT模型进行继续预训练,使其适应医学领域的语言特点。
2.监督式微调(Supervised Fine Tuning, SFT)
o 用人工标注的数据,用传统机器学习中监督学习的方法,对大模型进行微调。
例如:指令微调(Instruction Tuning)- 输入文本:“Good morning!” - 任务描述:“翻译成西班牙语” - 期望输出:“¡Buenos días!”
3.基于人类反馈的强化学习微调(Reinforcement Learning with Human Feedback, RLHF)
o 把人类反馈通过强化学习方式引入到对大模型的微调中,让生成结果更加符合人类期望。
4.基于AI反馈的强化学习微调(Reinforcement Learning with AI Feedback, RLAIF)
o 与 RLHF 类似,但反馈来源是 AI,以解决人类反馈收集成本高、效率低的问题。
5.直接偏好优化(Direct Preference Optimization)
o 它主要通过直接优化模型对用户偏好的预测能力来提升模型的性能。与传统的损失函数优化不同,DPO更加关注模型在实际应用中的表现,特别是在用户体验和满意度方面。
模型微调分成3个阶段:
- 第一阶段:(Continue PreTraining)增量预训练,在海量领域文档数据上二次预训练模型,以注入领域知识.
- 第二阶段: SFT(Supervised
Fine-tuning)有监督微调,构造指令微调数据集,在预训练模型基础上做指令精调,以对齐指令意图 - 第三阶段 (1)RLHF(Reinforcement Learning from Human
Feedback)基于人类反馈对语言模型进行强化学习,分为两步:RM(Reward
Model)奖励模型建模,构造人类偏好排序数据集,训练奖励模型,用来建模人类偏好,主要是"HHH"原则,具体是"helpful,
honest, harmless";RL(Reinforcement
Learning)强化学习,用奖励模型来训练SFT模型,生成模型使用奖励或惩罚来更新其策略,以便生成更高质量、更符合人类偏好的文.
DPO(Direct Preference
Optimization)直接偏好优化方法,DPO通过直接优化语言模型来实现对其行为的精确控制,而无需使用复杂的强化学习,也可以有效学习到人类偏好,DPO相较于RLHF更容易实现且易于训练,效果更好
一些比较流行的PEFT方案
从成本和效果的角度综合考虑,PEFT是目前业界比较流行的微调方案。接下来介绍几种比较流行的PEFT微调方案。
1、Prompt Tuning
Prompt Tuning的出发点,是基座模型(Foundation Model)的参数不变,为每个特定任务,训练一个少量参数的小模型,在具体执行特定任务的时候按需调用。
Prompt Tuning的基本原理是在输入序列X之前,增加一些特定长度的特殊Token,以增大生成期望序列的概率。
具体来说,就是将X = [x1, x2, …, xm]变成,X = [x
1, x2, ..., x
k; x1, x2, …, xm], Y = WX`。
例如:
假设我们有一个情感分析任务,原始输入句子为"I love this movie."
通过Prompt Tuning,我们在原始输入序列前增加一些提示语,例如:
X’ = [“This is a sentiment analysis task:”, “The sentiment of the following sentence is:”, “I”, “love”, “this”, “movie”, “.”]
2、Prefix Tuning
Prefix Tuning的灵感来源是,基于Prompt Engineering的实践表明,在不改变大模型的前提下,在Prompt上下文中添加适当的条件,可以引导大模型有更加出色的表现。
Prefix Tuning的出发点,跟Prompt Tuning的是类似的,只不过它们的具体实现上有一些差异。
Prompt Tuning是在Embedding环节,往输入序列X前面加特定的Token。
而Prefix Tuning是在Transformer的Encoder和Decoder的网络中都加了一些特定的前缀。
具体来说,就是将Y=WX中的W,变成W = [Wp; W],Y=W
X。
Prefix Tuning也保证了基座模型本身是没有变的,只是在推理的过程中,按需要在W前面拼接一些参数。
举例说明:
原始英文句子为:“I love this movie.”
Encoder 输入变为:W’_encoder = [Wp_encoder; W_encoder]
Decoder 输入变为:W’_decoder = [Wp_decoder; W_decoder]
然后,我们将新的输入序列 X 输入到修改后的 Transformer 模型中进行预测,得到输出 Y:
假设输出结果是:“我喜欢这部电影。”
3、LoRA
LoRA是跟Prompt Tuning和Prefix Tuning完全不相同的另一条技术路线。
LoRA背后有一个假设:我们现在看到的这些大语言模型,它们都是被过度参数化的。而过度参数化的大模型背后,都有一个低维的本质模型。
通俗讲人话:大模型参数很多,但并不是所有的参数都是发挥同样作用的;大模型中有其中一部分参数,是非常重要的,是影响大模型生成结果的关键参数,这部分关键参数就是上面提到的低维的本质模型。
LoRA的基本思路,包括以下几步:
首先, 要适配特定的下游任务,要训练一个特定的模型,将Y=WX变成Y=(W+∆W)X,这里面∆W主是我们要微调得到的结果;
其次,将∆W进行低维分解∆W=AB (∆W为m * n维,A为m * r维,B为r * n维,r就是上述假设中的低维);
接下来,用特定的训练数据,训练出A和B即可得到∆W,在推理的过程中直接将∆W加到W上去,再没有额外的成本。
另外,如果要用LoRA适配不同的场景,切换也非常方便,做简单的矩阵加法即可:(W + ∆W) - ∆W + ∆W`。
参考:https://zhuanlan.zhihu.com/p/663557294
4、QLoRA
LoRA 效果已经非常好了,可以媲美全量微调的效果了,那为什么还要有个QLoRA呢?
这里先简单介绍一下,量化(Quantization)。
量化,是一种在保证模型效果基本不降低的前提下,通过降低参数的精度,来减少模型对于计算资源的需求的方法。
量化的核心目标是降成本,降训练成本,特别是降后期的推理成本。
QLoRA就是量化版的LoRA,它是在LoRA的基础上,进行了进一步的量化,将原本用16bit表示的参数,降为用4bit来表示,可以在保证模型效果的同时,极大地降低成本。
论文中举的例子,65B的LLaMA 的微调要780GB的GPU内存;而用了QLoRA之后,只需要48GB。效果相当惊人!
5、Adapter Tuning
在面对特定的下游任务时,如果进行 Full-Fintuning(即预训练模型中的所有参数都进行微调),太过低效;而如果采用固定预训练模型的某些层,只微调接近下游任务的那几层参数,又难以达到较好的效果。
于是他们设计了如下图所示的 Adapter 结构,将其嵌入 Transformer 的结构里面,在训练时,固定住原来预训练模型的参数不变,只对新增的 Adapter 结构进行微调。同时为了保证训练的高效性(也就是尽可能少的引入更多参数)
引用地址:https://zhuanlan.zhihu.com/p/650287173
参考地址:https://zhuanlan.zhihu.com/p/627642632