首页 > 教程攻略 > ai资讯 >一文读懂 LLM 如何进行微调?

一文读懂 LLM 如何进行微调?

来源:互联网 时间:2026-08-25 13:51:35

大型语言模型(LLM)的应用方式其实远比很多人想象的要灵活。面对一个已经预训练好的模型,我们通常有几种不同的策略让它“为我所用”:一种是把它当成特征提取器,用一种更轻量级的模型来接手后续任务;另一种是直接给它展示几个例子,看它能不能自己“悟”出任务逻辑,这种思路被称之为“提示”;再者就是直接调整模型内部的参数,这个动作,就是今天要展开聊的重点——微调。

LLM 微调技术概览

怎么理解这三种策略的区别?打个比方:第一种是把一个已经训练好的“通才”模型当作原料仓库,我们不改变仓库本身,而是从里面调取各种原材料来训练我们自己的“小作坊”,比如一个线性分类器。第二种则是给这位“通才”看几个标准答案,让它照着葫芦画瓢。而在第三种情况下,如果我们希望获得更高的掌控力,那就需要直接修改“通才”模型的内在知识结构了,也就是微调。下面,我们就把这些方法掰开揉碎了仔细看看。

使用转换器进行分类任务

先从最经典的Transformer模型说起。对于这类模型,学术界和工业界积累了三种“传家宝”式的技术:在模型提取的特征上重新训练一个模型、只调整模型的输出层,以及直接调整所有层。

基于特征的方法

这种方法的核心在于“借力”。我们把训练好的BERT或GPT模型固定住,当成一个不动点。然后用它来提取新数据的特征,拿这些特征去训练另一个模型——比如随机森林或XGBoost,但从实际效果看,最简单的线性分类器往往就是最优解。原因不难理解:这些预训练大模型所提取的特征,本身就包含了非常丰富的语义信息和数据结构关系,其质量之高,让线性分类器几乎不用费什么功夫就能高效地划出分类边界。

而且,像逻辑回归或支持向量机这类线性模型,本身就有不错的防过拟合能力,这在处理高维特征空间的时候尤为关键。由于不需要更新预训练模型本身,这种方法在计算上非常高效。更妙的是,这些特征一经提取就不再改变,我们可以在训练开始前一次性计算好,供后续多个训练轮次重复使用。

图1:大语言模型通用的微调工作流程示例,展示了从预训练模型到特定任务(如德英翻译)的适配过程。

微调

微调的关键目标,是让模型更精确地贴合手头的任务。在实现上,它通常有两个分支:微调I和微调II。微调I只动模型顶部的输出层,微调II则是把整个模型里里外外都更新一遍。

微调I的思路和上面的特征方法有点类似:我们给模型加上几层新的输出层,但模型的主体部分依然保持冻结。这样做的好处就是,不需要对整个网络进行完整的反向传播,对计算资源的要求自然也就低得多。

微调II则是更彻底的手段——依然是加装输出层,但这次模型的所有层都得参与到训练中来,进行完整的反向传播。这无疑会带来更高的计算成本,但它也有明显的优势:当我们手头的数据非常专业,并且需求是模型必须对任务有比“浅层适应”更深刻的把握时,这种方法往往能释放出最好的表现。

简单来说,微调I强调快速迭代、低资源消耗;微调II则偏向精耕细作、代价更高,但上限也更值得期待。

图2:三种传统微调方法对比,左侧为微调I,右侧为微调II,中间为更基础的特征提取法。

图2很清晰地说明了这一点:微调II需要训练的参数和层数都远多于微调I,因此对应的反向传播计算量和资源消耗自然水涨船高。与之相比,不论是微调I还是更基础的“特征提取法”,在成本上都具备明显优势。

上下文学习、索引与提示调整

再来看看另一个很受关注的概念:上下文学习。这个概念随着GPT-2和GPT-3的诞生而成为热门话题,也被称为零样本或少样本学习。核心是,我们不再需要给模型喂海量的标注数据,它也具备完成新任务的能力。

图3:通过上下文学习为LLM提供任务示例,帮助其理解当前任务逻辑。

上下文学习的关键技巧就在于提供示例。比如,想用GPT-3完成德语到英语的翻译任务,我们只需要给它几个例子:

  • “Ich liebe Pfannkuchen” 翻译成 “I love pancakes.”
  • “Das Wetter ist heute schön” 翻译成 “The weather is nice today.”

然后,当模型看到新句子“Wo ist die nächste Bushaltestelle?”时,就能基于前面的样本进行推断。

但从实际效果来看,上下文学习的表现在某些场景下可能不如直接微调模型。因为它本质上是依靠模型预训练时积累的“直觉”来解决问题,而不是针对这个任务显式地去优化模型参数。

不过,上下文学习的价值在于灵活性。当手头没有足够的标签数据进行微调,或者只能通过API接口使用模型、无法直接修改参数时,它就变得无可替代了。

与上下文学习类似但思路不同的,还有一个叫“硬提示调整”的方法。这种方法不修改模型参数,而是直接修改给模型的语言提示,试图用更巧妙的问法引出更好的答案。例如:

  • “将德语句子‘{german_sentence}’翻译成英语:{english_translation}”
  • “德语:‘{german_sentence}’ → 英语:{english_translation}”

硬提示调整的好处是对资源要求极低,因为根本不用动模型。但局限也很明显:它无法让模型针对任务做深层度的参数优化,而且找到一个好提示可能需要花费大量人力进行反复实验。当然,现在也有另一种思路:用一个LLM来自动生成和评估“提示”,这又是另一个玩法了。

除此之外,还有一种基于纯上下文学习原则的方法——LLM索引方法。

图4:LLM索引从外部文档中检索信息,并返回相应的回答。

LLM索引的核心思路,是让大模型扮演一个“信息检索员”的角色。索引模块将外部文档库拆成小块,然后把这些小块转换为向量表示,存入一个向量数据库中。当用户提出问题时,索引模块将问题转化为向量,计算它与库中各个向量的相似度,并取出最匹配的几个,用于最终的回答合成。这就像一个巨型图书馆的自动索引系统,只不过查询和匹配都是靠向量运算来完成的。

参数高效微调

近年来,为了在计算效率和模型性能之间取得更好的平衡,一批被统称为“参数高效微调”的方法陆续诞生。图5整理了当前最热门的几类思路。

图5:参数高效微调技术的主要类别及代表性方法。

软提示调整

软提示调整的思路很直接:在输入的文本被嵌入成向量之前,我们先在其前面加上一个可学习的参数组(称为“软提示”)。这个软提示不是一成不变的,而是可以通过梯度下降等优化方法针对特定数据集进行调整。在代码实现上,它就是把一个可训练的“软提示张量”拼接在输入向量的前面,让模型能基于更长的序列来获取更多信号。

伪代码看起来是这样的:

x = EmbeddingLayer(input_ids)
x = concatenate([soft_prompt_tensor, x],
                 dim=seq_len)
output = model(x)

在这个代码片段中,soft_prompt_tensor 的维度是和嵌入层输出的特征维度保持一致的。这样一来,修改后的输入矩阵就拥有了额外的行,相当于通过额外的“虚拟词元”扩展了原始输入序列。

前缀调整

前缀调整与软提示调整类似,但区别在于:它不是在输入层前加一个软提示,而是在每一个Transformer块前都加入一个可训练的张量。这样做的好处是能够从模型的不同层引入新的约束,使得训练过程更加稳定。

图6:普通Transformer块(左)与前缀调整的Transformer块(右)对比。

无论是软提示调整还是前缀调整,都只训练新增的那一小部分参数张量,而原始的LLM参数本身保持不动,因此它们都属于名副其实的“参数高效”方法。

适配器方法

适配器方法和前缀调整是近亲,但采用的手段略有不同:它在Transformer层内部插入额外的全连接层作为“适配器”。具体来说,是在每个Transformer块的多头自注意力层和原有的全连接层之后,各加上一个小的全连接结构——只有这个新增的适配器在训练中被更新。

图7更直观地展示了这种对比:左边是普通Transformer块,右边则是在关键位置插入了适配器层的新版本。

图7:普通Transformer块(左)和带有适配器层的Transformer块(右)的对比。

由于这些适配器层的尺寸通常很小(第一层降维、第二层升维),它们只需要训练非常少的参数,便能带来显著的适配效果。对应的伪代码如下:

def transformer_block_with_adapter(x):
    residual = x
    x = SelfAttention(x)
    x = FullyConnectedLayers(x)  # 适配器层
    x = LayerNorm(x + residual)
    residual = x
    x = FullyConnectedLayers(x)
    x = FullyConnectedLayers(x)  # 适配器层
    x = LayerNorm(x + residual)
    return x

低秩适应(LoRA)

再来看一个当下非常火的微调方法——低秩适应,亦即LoRA。它的技术内核很有意思:用一种低秩变换来近似表示大模型的权重矩阵。说得更直白一些,就是把一个维度为 (A imes B) 的大矩阵,拆分成两个更小的矩阵的乘积(称为 (W_A) 和 (W_B))。训练时,我们只更新这两个小矩阵,而原来的大矩阵则保持冻结。

为什么它如此高效?假设一个权重矩阵的尺寸是25×50,那么它就有1250个参数。但如果用LoRA的方式,假设我们限制它只用5个维度来表示,那么 (W_A) 就有125个参数,(W_B) 有250个参数,总共才375个参数——几乎缩小到了原来的30%。用搬家来类比:原本要搬一整套家具,而用LoRA,等于只挑出了骨架和关键构件,搬家效率自然大幅提升。

将这个过程完整串联起来,前向传播的代码可以写成这样:

def lora_forward_matmul(x):
    h = x . W  # 常规矩阵乘法
    h += x . (W_A . W_B) * scalar  # 加上低秩适应部分
    return h

这里的scalar是一个可调节的放缩因子,用于平衡原有的预训练知识与新任务调整两者之间的权重。

根据LoRA原论文的数据,采用LoRA调校的模型,在特定任务上的表现不仅优于适配器方法,甚至常常超越之前讨论的全面微调(微调II)。可以说,它给模型装了一个小巧的助推器,让模型既能保留旧知识,又能高效吸收新技能。

从人类反馈中强化学习(RLHF)

此外还有一个绕不开的话题:如何让大模型更懂人类的偏好?这就是通过人类反馈进行强化学习的做法,简称RLHF。

常规的监督学习,是给模型大量的标签数据,让它照着学。这对于情感分类这类任务当然没问题。但到了更开放、更倾向主观判断的生成任务时,单纯靠标签就不够了。

RLHF的思路是:先通过监督学习让模型有一个比较好的起点,然后用强化学习来进一步打磨。具体做法包括:请真人标注员对模型的多个输出进行排序或打分,以此训练出一个“奖励模型”。这个奖励模型学会了标注员的偏好后,就作为训练LLM的信号源。为什么不能一直让真人来反馈?因为实时的人力成本太高,所以用奖励模型来扮演“人类的偏好模拟器”。这个优化过程常借助近端策略优化(PPO)来完成。

ChatGPT和InstructGPT就是这种思路下的代表作。通过RLHF,模型不仅能回答案,还会更倾向于输出那些让人类觉得有用、安全、自然的答案。

总结

将预训练的大模型直接进行全参数微调,的确是让模型适配新任务最彻底的方法之一。但正如我们在这篇文章里看到的,现实场景下,成本、资源和数据往往都是硬约束。无论是基于特征的方法、上下文学习,还是各类参数高效的微调技术(软提示、前缀调整、适配器、LoRA),它们提供了非常务实的替代路径:在性能和资源之间找到一个更好的平衡点。

总的来说,这些技术各有千秋:计算效率高的方法,在某些任务上可能表现相对受限;而效果突出的方法,代价往往也更高。同时,RLHF等强化学习方法进一步扩展了“微调”的定义边界,让模型不只是适应任务,更懂得“像人一样思考”。

随着预训练模型的迭代速度越来越快,适配它们的方式也在持续进化。我们可以确定的是——这个领域的创新远未停止,更多好用、高效的方法正在路上。