本文探讨了大模型微调的核心概念和方法,详细介绍了如LoRA、Adapter Tuning、Prefix Tuning等多种微调策略。每种方法的原理、优势及适用场景都有详尽阐述,大家可以根据不同的应用需求和计算资源,选择到最合适自己的微调途径。
希望本文能对想了解大模型原理、面试的同学,有所帮助,喜欢本文记得收藏、关注、点赞,面试&技术交流,文末获取
LLM大语言模型训练一般有两个阶段
Step 1.预训练阶段
大模型首先在大量的无标签数据上进行训练,预训练的最终目的是让模型学习到语言的统计规律和一般知识。在这个过程中模型能够学习到词语的语义、句子的语法结构、以及文本的一般知识和上下文信息。
需要注意的是,预训练本质上是一个无监督学习过程;得到预训练模型(Pretrained Model), 也被称为基座模型(Base Model),模型具备通用的预测能力。如GLM-130B模型、OpenAI的A、B、C、D四大模型,都是基座模型。
Step 2.微调阶段
预训练好的模型然后在特定任务的数据上进行进一步的训练。这个过程通常涉及对模型的权重进行微小的调整,以使其更好地适应特定的任务;得到最终能力各异的模型,例如 gpt code系列、gpt text系列、 ChatGLM-6B等模型;
那么,什么是大模型微调?
感性理解:大模型微调指的是“喂”给模型更多信息,对模型的特定功能进行 “调教”,即通过输入特定领域的数据集,让其学习这个领域的知识,从而让大模型能够更好的完成特定领域的NLP任务,例如情感分析、命名实体识别、文本分类、对话聊天等;
为什么需要微调?
核心原因还是在于需要“赋予”大模型更加定制化的功能,例如结合本地知识库进行检索、围绕特定领域问题进行问答等。
例如,VisualGLM是通用多模态大模型,但应用于医学影像判别领域,则需要代入医学影像领域的数据集来进行大模型微调,从而使得模型能够更好的围绕医学影像图片进行识别;。
就像机器学习模型的超参数优化,只有调整了超参数,才能让模型更佳适用于当前的数据集; 同时,大模型是可以多次进行微调,每次微调都是一次能力的调整,即我们可以在现有的、 已经具备某些特定能力的大模型基础上进一步进行微调。
GPT中的的Transformer是一种深度学习模型架构,其通过自注意力机制(self-attention)等手段来解决这些问题。正是有了Transformer,以GPT为基础的的大语言模型才有了巨大的进步。
下面是Transformer的模型架构图,包含了很多模块,我们说的各种微调技术,往往是在其中某个位置的模块做优化,从而达成微调的目标。
要理解各种微调方法,首先要对网络架构有所理解,这里以Transformer为例说明各模块的功能:
输入(Inputs):这是模型的输入部分,通常是一串单词或符号的序列。
输入嵌入(Input Embedding):这一步将输入的序列(比如一句话中的每个单词)转换为嵌入表示。嵌入表示是一种高维的、能够捕捉到单词语义信息的向量形式。
位置编码(Positional Encoding):由于Transformer是不依赖于序列的,位置编码用于给模型提供关于单词在序列中位置的信息。这些编码是添加到输入嵌入上的,确保即使在处理同时的输入时,模型也能利用单词的顺序信息。
Nx:这表示有N个相同的编码器层堆叠在一起。每层都有两个主要子层。第一个是多头自注意力机制(Multi-Head Attention),第二个是前馈神经网络(Feed Forward)。
多头自注意力(Multi-Head Attention):注意力机制允许模型在处理每个词时考虑到输入序列中的所有词。多头部分意味着模型会并行地学习输入数据的不同表示。
残差连接和归一化(Add & Norm):每个注意力层后面都会有残差连接(Add),后面跟着层归一化(Norm)。残差连接有助于避免深层网络中的梯度消失问题,而层归一化则有助稳定训练过程并加快收敛速度。
前馈神经网络(Feed Forward):这是一个简单的全连接神经网络,它对自注意力层的输出进行处理,它由两个线性变换和一个非线性激活函数组成。
解码器同样包含多个相同的层,并且每层也有三个主要子层:掩蔽的多头自注意力机制(Masked Multi-Head Attention)、多头自注意力机制(Multi-Head Attention)和前馈神经网络(Feed Forward)。
掩蔽多头自注意力(Masked Multi-Head Attention):这与编码器中的多头自注意力机制相似,但有一个关键区别:为了保证解码的顺序性,掩蔽操作确保了位置i的预测只能依赖于位置i之前的输出,不会"看到"未来的信息。
多头自注意力(Multi-Head Attention):这个模块接受编码器的输出和掩蔽多头注意力的输出作为输入。这样,解码器可以关注输入序列的相关部分,并结合它自己的输出进行预测。
前馈神经网络(Feed Forward):与编码器中的相同。每个子层后面同样跟有加法和归一化步骤。为每个位置上的向量提供额外的非线性变换。
输出嵌入层(Output Embedding)
解码器端的嵌入层将目标序列(在训练时是正确的输出序列,在推理时是已经生成的序列)转换为向量的形式。
线性层(Linear):解码器的最后输出通过一个线性层,这个层的作用是将解码器层的高维输出映射到一个更大的词汇空间,这个空间的每一个维度对应一个可能的输出单词。
Softmax层: 线性层的输出通过Softmax函数转换成一个概率分布,这个分布表示每个可能的下一个单词的概率。
大模型全量微调(Fine-tuning) 通过在预训练的大型模型基础上调整所有层和参数,使其适应特定任务。这一过程使用较小的学习率和特定任务的数据进行,可以充分利用预训练模型的通用特征,但可能需要更多的计算资源。
PEFT(Parameter-Efficient Fine-Tuning ) 技术旨在通过最小化微调参数的数量和计算复杂度,来提高预训练模型在新任务上的性能,从而缓解大型预训练模型的训练成本。
这样一来,即使计算资源受限,也可以利用预训练模型的知识来迅速适应新任务,实现高效的迁移学习。因此,PEFT技术可以在提高模型效果的同时,大大缩短模型训练时间和计算成本,让更多人能够参与到深度学习研究中来。
PEFT包括LORA、QLoRA、Adapter Tuning、Prefix Tuning、Prompt Tuning、P-Tuning及P-Tuning v2等。
下图示例了7个主流微调方法在Transformer网络架构的作用位置和简要说明,下面一一详细介绍。
LoRA是一种用于微调大型预训练语言模型(如GPT-3或BERT)的方法。它的核心思想是在模型的关键层中添加小型、低秩的矩阵来调整模型的行为,而不是直接改变整个模型的结构。
这样做的好处是,可以在不增加太多额外计算负担的情况下,有效调整模型,同时保持其原有的性能。
LoRA的工作原理如下:
选择要调整的权重矩阵:在大型模型(如GPT)中,我们首先确定要微调的权重矩阵。通常,这些矩阵位于模型的多头自注意力(Multi-head Self-Attention)和前馈神经网络(Feed-Forward Neural Network)部分。
引入两个低秩矩阵:接着,我们引入两个低秩矩阵,记为A和B,这两个矩阵的维度比原始权重矩阵小得多,例如,如果原始矩阵的尺寸是d*d,那么,A和B的尺寸可能是d*r和r*d,其中r是一个远小于d的数。
计算低秩更新:通过计算这两个低秩矩阵的乘积,生成一个新的矩阵AB,这个新矩阵的秩(即r)远小于原始权重矩阵的秩。这个乘积实际上是一个低秩近似,可以视为对原始权重矩阵的一种调整。
结合原始权重:最后,这个新生成的低秩矩阵AB被加到原始的权重矩阵上。这样,原始的权重矩阵得到了微调,但大部分权重保持不变。这个过程可以用数学公式表示为:新权重 = 原始权重 + AB。
举个例子。
假设我们有一个大型语言模型,原本是用来处理广泛的自然语言处理任务的。现在,我们想要微调这个模型,使其更擅长于处理医疗健康相关的文本。
使用LoRA方法,我们不需要直接修改模型原有的大量权重。相反,我们只需在模型的关键部分引入低秩矩阵,通过这些矩阵的乘积来实现对权重的有效调整。这样,我们可以使模型更加适应医疗健康领域的特殊语言和术语,同时避免了大规模的权重调整和重新训练的需要。
QLoRA(Quantized Low-Rank Adaptation)是一种高效的模型微调方法,它在LoRA(Low-Rank Adaptation)的基础上引入了深度量化过程。QLoRA的核心特点包括:
量化技术:
QLoRA使用一种新颖的高精度技术将预训练模型量化为4-bit。这种技术包括一种低精度存储数据类型(4-bit NormalFloat,简写为NF4)和一种计算数据类型(16-bit BrainFloat)。这样做可以在保持整个模型精度损失极小的同时,减少存储需求。
那么,量化具体怎么做呢?
4-bit量化意味着每个权重仅由4个比特表示,量化过程需要选择哪些值最重要并将它们映射到这16个可能的值上。
首先确定量化的范围,比如从-1到1,然后将这个范围划分为16个区间,每个区间对应一个4-bit的值。
其次,将原始的32位浮点数值映射到最近的量化区间上。例如,如果原始值是0.85,且0.8和0.9是两个最近的量化点,根据舍入规则,0.85可能被量化为0.8或0.9。
微调过程:
在训练过程中,QLoRA首先将模型用4-bit加载,然后在训练时把数值反量化到bf16后进行训练。这样的设计使得训练所需的显存大大减少。例如,一个33B的LLaMA模型可以在24 GB的显卡上进行训练。
由于量化显著减少了模型的精确度,这通常会带来性能上的损失。然而,对于大型模型,这种方法可以大幅减少内存和计算需求,使得在资源有限的环境下部署和训练成为可能。
量化过程中的关键挑战是如何设计映射和量化策略,以尽量减少因精度损失带来的性能下降。
与 LoRA 类似,Adapter Tuning 的目标是在不改变预训练模型的原始参数的前提下,使模型能够适应新的任务。
在 Adapter Tuning 中,会在模型的每个层或某些特定层之间插入小的神经网络模块,称为“adapters”。这些 adapters 是可以训练的,而原始模型的参数则保持不变。
Adapter Tuning 的关键原理和步骤:
预训练模型作为基础:开始时,我们有一个已经预训练好的大型模型,例如BERT或GPT。这个模型已经学习了大量的语言特征和模式。
插入适配器:在这个预训练模型的每一层或选定的层中,我们插入适配器。这些适配器是小型的神经网络,通常只包含几层,并且参数相对较少。
保持预训练参数不变:在微调过程中,原始预训练模型的参数保持不变。这意味着我们不直接调整这些参数,而是专注于训练适配器的参数。
训练适配器:适配器的参数会根据特定任务的数据进行训练。这样,适配器可以学习如何根据任务调整模型的行为。
任务特定的调整:通过这种方式,模型能够对每个特定任务做出微调,而不会影响到模型其他部分的通用性能。适配器可以帮助模型更好地理解和处理与特定任务相关的特殊模式和数据。
高效和灵活:由于只有一小部分参数被调整,这种方法比全模型微调更高效,同时也允许模型快速适应新任务。
例如,假设我们有一个大型的文本生成模型,原本用于广泛的文本生成任务。如果我们想要将其微调以生成专业的金融报告,我们可以在模型的关键层中添加适配器。
在微调过程中,只有这些适配器的参数会根据金融领域的数据进行更新。这样,模型就能更好地适应金融报告的写作风格和术语,同时避免了对整个模型架构的显著调整。
LoRA和Adapter Tuning的区别:
LoRA:通过在模型的权重矩阵中引入低秩矩阵(通常是两个小的矩阵的乘积)来实现对模型的微调。这些低秩矩阵作为原有权重矩阵的修改项,使得原有的权重矩阵在实际计算时得到调整。
Adapter Tuning:通过在模型的各个层中添加小型神经网络模块,即“适配器”,来实现微调。这些适配器独立于模型的主体结构,只有它们的参数在微调过程中被更新,而模型的其他预训练参数保持不变。
传统的微调范式利用预训练模型去对不同的下游任务进行微调,对每个任务都要保存一份微调后的模型权重,一方面微调整个模型耗时长;另一方面也会占很多存储空间。
基于上述两点,Prefix Tuning提出固定预训练LM,为LM添加可训练,任务特定的前缀,这样就可以为不同任务保存不同的前缀,微调成本也小。
同时,这种Prefix实际就是连续可微的Virtual Token(Soft Prompt/Continuous Prompt),相比离散的Token,更好优化,效果更好。
这张图展示了两种不同的模型微调方法:Fine-tuning 和 Prefix-tuning。这两种方法都是为了调整预训练的Transformer模型以适应特定任务。
在 Fine-tuning 部分,图展示了三个不同任务的Transformer模型,分别用来做翻译、总结或将表格转换为文本(table-to-text)。
每个任务都有自己的微调模型,这意味着模型的所有权重都在微调过程中针对特定任务进行了更新。这种方法通常需要大量的数据和计算资源,因为整个模型都在学习任务特定的知识。
在 Prefix-tuning 部分,图展示了一种不同的微调策略,对于每个任务,都有一个特定的前缀被添加到输入序列的开始部分。这些前缀相当于任务特定的提示,可以是一组固定的词或是可训练的嵌入向量。
Prefix-tuning 的优势在于它不需要调整模型的全部权重,而是通过在输入中添加前缀来调整模型的行为,这样可以节省大量的计算资源,同时使得一个单一的模型能够适应多种不同的任务。前缀可以是固定的(即手动设计的静态提示)或可训练的(即模型在训练过程中学习的动态提示)。
Prompt Tuning是一种微调方法,它在预训练语言模型的输入中添加可学习的嵌入向量作为提示。这些提示被设计成在训练过程中更新,以引导模型输出对特定任务更有用的响应。
Prompt Tuning和Prefix Tuning都涉及在输入数据中加入可学习的向量,这些元素是在输入层添加的,但两者的策略和目的是不一样的:
Prompt Tuning:可学习向量(通常称为prompt tokens)旨在模仿自然语言提示的形式,它们被设计为引导模型针对特定任务生成特定类型的输出。这些向量通常被看作是任务指导信息的一部分,倾向于用更少量的向量模仿传统的自然语言提示。
Prefix Tuning:可学习前缀则更多地用于提供输入数据的直接上下文信息,这些前缀作为模型内部表示的一部分,可以影响整个模型的行为。
下面的训练例子说明了两者的区别:
Prompt Tuning示例:
输入序列: [Prompt1][Prompt2] “这部电影令人振奋。”
问题: 评价这部电影的情感倾向。
答案: 模型需要预测情感倾向(例如“积极”)
提示: 无明确的外部提示,[Prompt1][Prompt2]充当引导模型的内部提示,因为这里的问题是隐含的,即判断文本中表达的情感倾向。
Prefix Tuning 示例:
输入序列: [Prefix1][Prefix2][Prefix3] “I want to watch a movie.”
问题: 根据前缀生成后续的自然语言文本。
答案: 模型生成的文本,如“that is exciting and fun.”
提示: 前缀本身提供上下文信息,没有单独的外部提示
P-Tuning(Prompt-based Tuning)和Prompt Tuning都是调整大型预训练语言模型(如GPT系列)以适应特定任务的技术。
两者都旨在利用预训练的语言模型来执行特定的下游任务,如文本分类、情感分析等。它们都使用某种形式的“提示”或“指导”来引导模型的输出,以更好地适应特定任务。
Prompt Tuning与Prompt Tuning的区别主要在于:
Prompt Tuning:使用静态的、可训练的虚拟标记嵌入。这些嵌入在初始化后保持固定,除非在训练过程中被更新,相对简单,因为它只涉及调整一组固定的嵌入参数。在处理多种任务时表现良好,但可能在处理特别复杂或需要细粒度控制的任务时受限。
P-Tuning:使用一个可训练的LSTM模型(称为prompt_encoder)来动态生成虚拟标记嵌入,允许根据输入数据的不同生成不同的嵌入,提供了更高的灵活性和适应性,适合需要精细控制和理解复杂上下文的任务,相对复杂,因为它涉及一个额外的LSTM模型来生成虚拟标记嵌入。
在P-Tuning中使用LSTM(长短期记忆网络)作为生成虚拟标记嵌入的工具,充分利用了LSTM的优势,包括:
更好的适应性和灵活性:由于LSTM可以捕捉输入数据中的时间序列特征,它能够更好地理解和适应复杂的、顺序依赖的任务,如文本生成或序列标注。
改进的上下文理解:LSTM由于其循环结构,擅长处理和理解长期依赖关系和复杂的上下文信息。
参数共享和泛化能力:在P-Tuning中,LSTM模型的参数可以在多个任务之间共享,这可以提高模型的泛化能力,并减少针对每个单独任务的训练需求。而在Prompt Tuning中,每个任务通常都有其独立的虚拟标记嵌入,这可能限制了跨任务泛化的能力。
这些特点使得LSTM特别适合于处理复杂任务和需要细粒度控制的应用场景。然而,这些优势也伴随着更高的计算复杂度和资源需求,因此在实际应用中需要根据具体需求和资源限制来权衡使用LSTM的决策。
在P-Tuning中,连续提示被插入到输入序列的embedding里,除了语言模型的输入成之外,其他层的prompt embddding都来自于上一层。这样的设计存在两个问题:
第一、约束了要优化的参数量。由于模型的input text的长度是一定的,一般是512,那么prompt的长度就不能过于长。
第二、当模型层数很深时,tuning时模型的稳定性难以保证;模型层数越深,在第一层输入的prompt对后面的影响是难以预估的,这会影响模型的稳定性。
P-Tuning v2的改进在于,将只在第一层插入连续提示修改为在许多层都插入连续提示,而不仅仅是输入层,层与层之间的连续提示是相互独立的。这样一来,在模型tuning时,可训练的参数就增多了,P-Tuning v2在应对复杂的NLU任务和小型模型方面,相比原始P-Tuning具有更出色的效能。
除了以上PEFT,当前还存在PILL(Pluggable Instruction Language Learning)、SSF(Scaling & Shifting Your Features)等其他类型的微调方法。
PILL是PEFT的一个特定实现,特别关注于如何通过插入可训练的模块或插件来提升模型的任务适应性。这些插件被设计为与原始模型协同工作,以提高模型在处理特定任务时的效率和效果。
SSF核心思想是对模型的特征(即模型层的输出)进行缩放(Scaling)和位移(Shifting)。简单来说,就是通过调整特征的比例和偏移量来优化模型的性能。
这种方法可以在改善模型对特定任务的响应时,不需要调整或重新训练模型中的所有参数,从而在节省计算资源的同时保持或提升模型性能。这对于处理大规模模型特别有效,因为它减少了训练和调整所需的资源和时间。
综上所述,微调是一种强大的工具,它能够使大型预训练模型适应于特定的任务和应用场景。正确选择和应用微调策略对于实现高效且有效的模型性能至关重要。
1、微调与迁移学习:微调实际上是迁移学习的一个实例,其中预训练的模型(通常在大型通用数据集上训练)被用作特定任务的起点。这种方法使得即使是对于小数据集的任务,也可以实现高效的学习
2、选择微调策略:选择哪种微调方法取决于多个因素,包括任务的复杂性、可用的数据量、计算资源和期望的性能。
例如,对于需要细粒度控制的复杂任务,P-Tuning v2或LSTM基础的P-Tuning可能更适合。而对于计算资源有限的情况,可以选择LoRA或Adapter Tuning等方法。
3、微调与模型泛化能力:微调时需要注意的一个关键问题是保持模型的泛化能力。过度的微调可能会导致模型对特定训练数据过拟合,而忽略了其在实际应用中的泛化能力。
4、持续发展和创新:随着深度学习和NLP领域的持续发展,新的微调技术和策略不断出现。这要求从业者保持对最新研究和技术动态的关注,并根据项目需求灵活选择和调整策略。
前沿技术资讯、算法交流、求职内推、算法竞赛、面试交流(校招、社招、实习)等、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企开发者互动交流~
我们建了大模型面试与技术交流群, 想要进交流群、需要源码&资料、提升技术的同学,可以直接加微信号:mlc2060。加的时候备注一下:研究方向 +学校/公司+CSDN,即可。然后就可以拉你进群了。
方式①、微信搜索公众号:机器学习社区,后台回复:加群
方式②、添加微信号:mlc2060,备注:技术交流
资料1