前言
大语言模型(LLM)的训练过程通常分为两大阶段:
阶段一:预训练阶段
此阶段模型是在大规模的无标签数据集
上接受训练,目标是使模型掌握词汇的含义、句子的构造规则以及文本的基本信息和上下文。
需特别指出,预训练实质上是一种无监督学习过程。完成预训练的模型,亦即基座模型(Base Model),拥有了普遍适用的预测能力。像modelscope上带pretrained
字样的就是预训练模型。
阶段二:微调阶段
预训练完成的模型接下来会在针对性的任务数据集上接受更进一步的训练。这一阶段主要涉及对模型权重的细微调整,使其更好地适配具体任务。最终形成的模型将具备不同的能力,如gpt chat系列,gpt code系列等。
通俗来说,微调就是向模型“输入”特定领域的数据集,使模型学习特定领域知识,并对模型的特定功能进行“优化”,从而优化大模型在特定领域的NLP任务中的表现,如情感分析、实体识别、文本分类、对话生成等。
微调之所以很重要,就在于:通用大模型要想落地到生产环境,首先要能解决特定领域的特定问题,这些特定问题并不是单靠提示词调优(可以理解为练外功)就能解决,尤其是比较复杂的问题,需要微调手段来把能力内化到模型内部(练内功)才能有质的改变。
微调方法分类
市面上所有的微调手段,按照微调的参数量来讲可以分为两大类:
-
全面微调(Fine-tuning):涉及调整所有层和参数,以适配特定任务。此过程通常采用较小的学习率和特定任务的数据,可以充分利用预训练模型的通用特征,但可能需要更多计算资源。
-
参数高效微调(Parameter-Efficient Fine-Tuning,PEFT)旨在通过最小化微调参数数量和计算复杂度,提升预训练模型在新任务上的表现。它尤其适用于计算资源受限的情况下,PEFT不仅能提升模型效果,还能显著缩短训练时间和计算成本。
PEFT又包括LoRA、QLoRA、适配器调整(Adapter Tuning)、前缀调整(Prefix Tuning)、提示调整(Prompt Tuning)、P-Tuning及P-Tuning v2等多种方法。
要想理解各类微调手段,首先要了解通用模型的结构,PEFT各类微调手段其实都是对模型结构中的特定部分进行优化,以实现微调目的。
按照对模型结构的修改方式,可以分为三类:
-
对输入向量(Input Embedding)作修改的微调方法:
- Prompt Tuning:提示词微调
- Prefix Tuning:前缀微调
- P-Tuning:基于提示的微调
- P-Tuning V2:P-tuning的改进,针对每层输入都插入提示。
-
对注意力层(Multi-Head Attention)和前馈神经网络层(Feed Forward)作修改的微调方法:
- Lora :低秩适应
- QLoRA:Lora+量化
-
在注意力层(Multi-Head Attention)之后或前馈神经网络层(Feed Forward)之后插入小的神经网络的微调方法:
- Adapter tuning: 适配器调整
Adapter Tuning
思想:增加适配器模块(即少量可训练参数)用于特定任务的训练,而原始网络的参数保持不变,可以在不影响先前任务的情况下支持新任务。
方法:固定Transformer的全部参数
在Transformer的每一个Block里嵌入一些新初始化的Adapter Network。
其中Adapter由两层MLP组成(如下图黄色矩形块),分别负责将Transformer的表征降维和升维。
效果参考:在GLUE基准测试中,在仅为每个任务增加3.6%参数的情况下,实现了与完整微调性能相差不到0.4%的结果。相比之下,微调则需要对每个任务的100%参数进行训练。
优势 :
- 只需要添加不到5%的可训练参数,即可以几乎达到全参数训练的效果
- 在训练过程中大大节省了训练时间,做到时间有效性。
- 基本不降低模型在下游任务中的表现
不足之处:引入了新的层,增加了模型的深度和计算延时。
Prefix-Tuning
思想:在语言模型(LM)输入序列前添加可训练、任务特定的前缀,从而实现针对不同任务的微调。前缀微调主要受到提示机制的启发,允许后续标记关注这个前缀,就像它们是“虚拟标记”一样。
方法:固定预训练参数,为每一个任务额外添加一个或多个embedding,且利用多层感知编码prefix。不再像prompt tuning继续输入LLM。
特点:可以为不同任务保存不同的前缀,而不是为每个任务保存一整套微调后的模型权重,从而节省了大量的存储空间和微调成本。
优势在于:
- 不需要调整模型的所有权重,而是通过在输入中添加前缀来调整模型的行为,从而节省大量的计算资源;
- 单一模型能够适应多种不同的任务,前缀可以是固定的(即手动设计的静态提示)或可训练的(即模型在训练过程中学习的动态提示)。
不足在于:减少了可输入序列的长度。
详细可参考论文:Prefix-Tuning: Optimizing Continuous Prompts for Generation
P-Tuning
针对问题:
- 手动设计的提示往往依赖经验和直觉,即使是微小的变化也会导致模型性能的显著波动。
例如,仅改变提示中的一个单词就可能导致性能大幅下降。
- 手动设计的提示通常是固定的,难以适应不同的任务或数据集。
允许根据输入数据的不同生成不同的嵌入
思路:固定LLM参数,使用一个可训练的LSTM模型(称为提示编码器prompt_encoder)来对prompt进行编码,目的是学习提示的潜在特征,并捕捉提示中各个部分的顺序和依赖关系,将提示词映射到一个更适合模型输入的空间后,再正常输入LLM。
LSTM(长短期记忆网络)因其循环结构,擅长处理和理解长期依赖关系和复杂的上下文信息。它允许根据输入数据的不同生成不同的嵌入,提供更高的灵活性和适应性,适合需要精细控制和理解复杂上下文的任务。
方法:
- 将手动设计的prompt模板,使用MLP+LSTM进行编码,并输出捕捉了提示语上下文信息的编码向量。
- 将编码后的提示向量与其他输入向量(特定任务的输入数据)进行拼接,替代原始的input embedding。
优势:
- 通过最小化不同离散提示之间的差距来稳定训练过程。
- 特别适合处理复杂任务和需要细粒度控制的应用场景。
不足:
- 在小参数量模型中表现差(小参数模型如Bert,330M),上了10B的模型效果才开始可以持平
- 序列标注等对推理和理解要求高的任务,prompt-tuning效果会变差。
详细可参考论文:GPT Understands, Too
Lora
LoRA全称是Low-Rank Adaptation, 低秩适配。
思想:冻结预训练模型的权重,在Transformer架构的每一层中注入可训练的低秩分解矩阵,从而大大减少了下游任务的可训练参数数量。
方法:
- 固定LLM参数(蓝色部分),在每一个self-attention(或feed forward)层中,加入一个low-rank的矩阵,即下图橙色部分的 B × A B \times A B×A。
- 假设原始权重矩阵的尺寸为 d × d d \times d d×d,则A和B的尺寸可能为 d × r d \times r d×r和 r × d r \times d r×d,其中r远小于d。
- 在微调时,只更新 B × A B \times A B×A的参数。
- 最终新的低秩矩阵AB被叠加到原始权重矩阵W上,用数学表达式描述为:新权重 = 原始权重W + AB。
拿Qwen2举例,原始权重W的参数量可能是1536x1536=2359296,如果用r=8低秩矩阵微调,则 A × B A \times B A×B = 1536 * 8 + 8 * 1536 = 24576, 只相当于原始W的1.04%,训练的参数量减少了将近100倍。
优势:
- 与Adapter Tuning相比,不会增加模型的深度,也就不会带来额外的推理延迟。
- 与Prefix tuning之类的输入调整相比,不会减少模型可输入序列的长度。
- 在不显著增加额外计算负担的前提下,能够有效地微调模型,同时保留模型原有的性能水准。
- 训练参数较少,训练吞吐量更高,尤其适用于硬件设备资源有限的场景。
QLora
QLoRA(Quantized Low-Rank Adaptation)是一种结合了LoRA(Low-Rank Adaptation)方法与深度量化技术的高效模型微调手段。
思想:首先将LLM进行4位量化,从而显著减少模型的内存占用。接着,使用低阶适配器(LoRA)方法对量化的LLM进行微调。LoRA使得改进后的模型能够保留原始LLM的大部分准确性,同时具有更小的体积和更快的速度。
量化方法:在4位量化中,每个权重由4个比特表示,量化过程中需选择最重要的值并将它们映射到16个可能的值之一。首先确定量化范围(例如-1到1),然后将这个范围分成16个区间,每个区间对应一个4-bit值。然后,原始的32位浮点数值将映射到最近的量化区间值上。
量化过程的挑战在于:设计合适的映射和量化策略,以最小化精度损失对性能的影响。
小结:本文主要是参考各类文章对各类微调方法进行概念性的学习,以对不同微调方法的思想和切入点有一个自己的理解,并将自己认为比较重要的内容摘录成文,以供后续其他入行同学快速了解。