参数高效微调
一、PEFT 技术综述
1、大模型微调的困境与PEFT诞生
1. 传统全量微调的四大难题
-
高昂训练成本:千亿参数模型需数百GB显存和极大时间成本。
-
巨大存储压力:每个下游任务都要保存完整模型副本。
-
灾难性遗忘:微调特定任务时,模型可能丧失预训练学到的通用知识。
-
训练不稳定性:大模型对超参数敏感,易梯度消失/爆炸。
2. “提示”范式的兴起与局限
-
In-Context Learning (硬提示):无需训练,通过离散文本指令(Prompt)引导模型完成任务。
-
硬提示的局限:
-
过程繁琐不稳定,试错成本高。
-
离散文本表达能力有限。
-
不同模型间迁移性差。
-
3. PEFT的核心思想
参数高效微调(Parameter-Efficient Fine-Tuning):冻结预训练模型绝大部分参数(>99%),只微调极少量参数或插入额外微型模块,以极低成本适应下游任务。灵感来自CV领域的迁移学习(冻结卷积层,微调全连接层)。
2、PEFT 技术发展脉络
1. Adapter Tuning

左侧的 Transformer 层展示了 Adapter 模块是如何被集成进去的。Adapter 被插入到每个子层(注意力层和前馈网络)的内部,并与主干网络形成残差连接。在训练时,只有 Adapter 模块的参数会被更新。
右侧展示了 Adapter 模块自身的结构,主要包括一个“降维”的全连接层(Feedforward down-project)将高维特征映射到低维空间,一个非线性激活函数(Nonlinearity),一个“升维”的全连接层(Feedforward up-project)再将特征映射回原始维度,以及一个贯穿该模块的残差连接将模块的输出与原始输入相加,保证信息流的稳定。
-
方法:在Transformer每层(注意力/前馈子层)中插入小型的“适配器”模块。
-
模块结构:降维全连接 → 非线性激活 → 升维全连接,并与主干网络形成残差连接。这种“瓶颈式”结构用极少量参数捕捉任务知识。
-
特点:参数效率高,性能接近全量微调;但插入额外模块会引入激活内存开销和微小推理延迟。
2. Prefix Tuning

该图分别展示了 Prefix Tuning 在自回归语言模型(上)和编码器-解码器模型(下)中的应用。
前缀激活值(Prefix Activations):图中 PREFIX 部分对应的激活值 hi(其中 i∈Pidx)是从一个专门的可训练矩阵 Pθ 中提取的,这部分参数就是微调的对象。
模型计算的激活值: 而原始输入 x 和输出 y 对应的激活值,则是由冻结的 Transformer 模型正常计算得出的。
-
方法:在模型外部添加可训练的前缀激活值,作为各层注意力的额外键(K)和值(V),引导模型行为。Prefix Tuning 不仅在输入层添加前缀,还在 Transformer 的每一层都添加了对应的可学习 Prefix,并通过一个小型的前馈网络(MLP)来生成这些参数。
-
前端生成:通常用小型MLP生成这些前缀参数。
-
优点:
-
参数效率极高,不更新原模型参数。
-
显著降低显存与存储开销。
-
适用于自回归(GPT类)和编解码(T5/BART)模型。
-
-
缺点:
-
直接优化前缀训练相对不稳定,对超参数敏感。
-
前缀长度计入注意力窗口,会压缩有效上下文长度。
-
3. Prompt Tuning (软提示)

-
方法:仅在输入Embedding层添加可学习的虚拟Token(Soft Prompt),不干预中间层。任务知识完全“外置”到轻量提示中。
-
将任务知识完全“外置”到一个轻量级的提示(Prompt)中。实践中可便利地实现混合任务批处理(Mixed-task Batch),便于共享同一冻结模型并提升训练吞吐;多任务训练并非 Prompt Tuning 所独有,但其实现较为简洁。我们可以通过一个具体的例子来理解这个过程:
- 定义任务:假设我们有三个不同的任务类型。
任务 A是情感分析,任务 B是问答,任务 C是 文章摘要。 - 准备数据:
任务 A的一条数据a1可能是一句影评:“这部电影拍得真不错!”。任务 B的数据b1可能是一个问答对:“上下文:'Datawhale是一个专注于AI与数据科学的开源组织。' 问题:'Datawhale是什么?'”。 - 拼接提示进行训练:在训练时,我们会为
a1这条数据前,拼接上专门为“情感分析”任务学习的、可训练的Soft Prompt A。这个Soft Prompt A并非一段人类可读的文本指令(如“请分析情感”),而是一组可通过反向传播优化的、连续的向量(Embeddings)。可以把它理解为一把能解锁大模型特定能力的“钥匙”:在训练时,它可能由“情感”、“正面”、“负面”等词的向量来初始化,并最终被模型自动微调成最优的、能够高效引导模型执行情感分析任务的“虚拟指令”。同理,为b1数据拼接上为“问答”任务学习的Soft Prompt B。如图所示,这些来自不同任务、但都已拼接好各自 Soft Prompt 的数据,可以被组合成一个混合批次,然后一起送入同一个、完全冻结的大语言模型进行训练。模型通过反向传播,只会更新Soft Prompt A和Soft Prompt B的参数,而自身权重保持不变。
- 定义任务:假设我们有三个不同的任务类型。
-
突出优势:
-
实现混合任务批处理,多个任务共享冻结大模型,极大提升训练吞吐。
-
产出极小提示文件(参数万级),而非庞大模型副本。
-
-
关键发现:模型规模的缩放效应
当模型参数量超过100亿(10B)时,Prompt Tuning的性能即可追平甚至超越全量微调;模型较小则效果远不如传统微调。 -
局限:强依赖超大模型规模,中小模型上不适用。
3、P-Tuning v2:从浅层到深层的进化
1. P-Tuning v1 的逻辑与不足

- (a)离散提示搜索:这类方法试图在离散的文本空间中找到最优的提示词组合。这种搜索过程通常只能依赖离散的奖励信号,优化非常困难且不稳定,找到的解往往是次优的。
- (b)P-Tuning:它提出,不应该在离散空间搜索,而应该在连续空间中进行优化。为此,P-Tuning v1 引入了一个关键组件——Prompt Encoder。它的逻辑是先定义一组可学习的、连续的伪提示(Pseudo Prompts),例如 [P0],...,[Pm],然后将这些伪提示作为输入,送入一个小型神经网络(如 LSTM)构成的
Prompt Encoder。Prompt Encoder会将这些伪提示编码,捕捉它们之间的依赖关系,并生成最终作为大模型输入的任务相关向量 h0,...,hm。-
(1)传统离散提示:我们需要精心设计一个自然语言模板,例如
"The capital of Britain is [MASK]"。 在这个模板中,"The","capital","of","is"这些词是固定的、离散的 Token。如果我们将模板换成"Britain's capital city is [MASK]",模型的输出效果可能会发生剧烈变化。这种对提示词的敏感性使得找到“最佳模板”变得很困难。(2)P-Tuning:P-Tuning 放弃了寻找具体的离散单词,而是引入了一组连续的伪 Token(Pseudo Tokens),我们将其标记为 [h0,h1,...,hi][h0,h1,...,hi]。这时,输入给模型的序列可能变成了这样:
[h0,h1,...,hi],"capital","Britain",[hi+1,...,hm],[MASK]
这里的 h 并不是词表里的某个具体单词,而是可训练的向量参数。在训练开始时,这些向量可能只是随机初始化的,或者用 "The capital of" 对应词向量进行初始化。随后在训练过程中,通过反向传播算法,这些 h 向量会在连续的向量空间中不断调整数值。最终,它们会收敛为一组人类无法直接阅读(因为它们不对应具体的词),但对模型来说最优的提示特征。这组特征能比任何人工设计的离散句子更准确地激发模型输出 "London"。就好比我们不再试图用字典里有限的词汇去拼凑一句“咒语”,而是直接把钥匙(提示向量)打磨成最契合锁孔(模型参数)的形状,以此打开模型知识库的大门。
-
- 通过这种方式,
Prompt Encoder及其输入的伪提示,都可以通过反向传播进行端到端的优化。这从根本上改变了寻找最优提示的方式:从“人工试错”变成了可以通过“梯度下降”来自动化求解的数学问题,大幅提升了优化的稳定性和最终效果。我们可以结合上图的具体案例来理解一下。图中展示了一个首都预测任务,输入实体是 "Britain"(英国),目标输出是 "London"(伦敦)。 -
核心创新:引入Prompt Encoder(如LSTM),在连续空间中学习伪提示向量,通过梯度下降端到端优化,取代离散提示的“手工试错”。
-
两大局限:
-
浅层提示:提示向量仅插入输入层,对深层行为影响力有限,需很大模型规模才能生效。
-
任务限制(Verbalizer):将所有任务强扭成“完形填空”形式,要求模型预测特定词再映射标签,难以处理序列标注等复杂任务。
-
2. P-Tuning v2 的关键改进

(1)P-Tuning v1 的瓶颈:注意图(a)中橙色的提示向量 h0,…,hi 的位置。
- 浅层提示(Shallow Prompting):提示向量仅被插入到输入层。这意味着提示信息必须经过 Transformer 所有层的层层传递,对模型深层行为的影响力非常有限。也就解释了为什么 P-Tuning v1 和 Prompt Tuning 这类技术在中小规模模型上效果远不如全量微调,往往只有在模型参数规模足够大(具备极强的内在通用能力)时,才能仅靠输入层的微调获得不错的效果。
- 任务局限(Verbalizer):观察输出端的
Verbalizer。第一代技术为了利用预训练目标,强行将所有任务都包装成“完形填空”问题(Masked Language Modeling)。比如做情感分类,必须让模型预测 "good" 或 "bad" 这样的词,再映射回标签。这在处理分类任务时还能应付,但面对序列标注或抽取式阅读理解这种需要对每个 Token 进行细粒度分类的复杂任务时,设计 Verbalizer 就变得极其困难甚至不可能。
(2)P-Tuning v2 的演进:P-Tuning v2 针对上述两个痛点进行了改进,其结构如图(b)所示。
-
深层提示(Deep Prompting):可以看到图(b)左侧的橙色箭头。提示向量不再只停留在输入层,而是被复制并独立注入到 Transformer 的每一层(Layer 1 Prompts, Layer 2 Prompts...)。这借鉴了 Prefix Tuning 的多层设计。现在,每一层的 Transformer 块都能直接接收到可学习的提示信息。相当于给模型开了“后门”,在每一层都进行直接引导。这种设计大幅增强了提示对模型的控制力。即使是小模型,深层提示也能发挥显著作用。
-
回归传统分类头(No Verbalizer):我们来看看图(b)下方的输出端,它抛弃了复杂的 Verbalizer,直接换回了传统的
Class Label (with linear head)。既然我们已经通过 Deep Prompting 获得了足够的控制力,就不再需要强行迎合预训练任务了。对于分类或序列标注任务,我们可以直接在最后一层接一个简单的线性层(Linear Head),像传统微调(Fine-tuning)一样直接输出标签。通过这种机制,P-Tuning v2 瞬间拥有了处理复杂任务的能力。它不再受限于“填空题”的格式,可以轻松应用于各类复杂任务。这使得P-Tuning v2能轻松处理分类、序列标注等各种复杂任务。
-
本质:融合了Prefix Tuning的多层结构 + 传统微调的输出头 + Prompt Tuning的轻量化。仅需微调0.1%~3%参数,但在不同模型规模和复杂任务上都能达到与全量微调媲美的稳定性与通用性。
4、重点知识点提炼
| 技术 | 可训练部分位置 | 关键机制 | 优势与适用场景 |
|---|---|---|---|
| Adapter | 每层内部插入模块 | 瓶颈结构(降维/升维+残差) | 参数效率高,但推理有少量额外开销 |
| Prefix Tuning | 每层注意力的额外K/V | 可训练前缀,MLP生成 | 高参数效率,显存友好,占用上下文窗口 |
| Prompt Tuning | 仅输入Embedding层 | Soft Prompt(虚拟Token) | 极轻量,可混合批处理;依赖超大模型(>10B) |
| P-Tuning v1 | 输入层伪提示+Prompt Encoder | 连续空间优化,LSTM编码 | 稳定优化,但浅层且受Verbalizer限制 |
| P-Tuning v2 | 所有层注入可学习提示 | 深层提示 + 线性分类头 | 通用性最强,适应各种规模模型与复杂任务 |
总核心:PEFT 让大模型适配不再是“每个任务都复制一座大厦”,而是“共享大厦,只调试几把专用钥匙”,在保持强大能力的同时大幅降低成本与资源需求。
二、LoRA 方法详解
1、LoRA:低秩适应的核心思想
1. 提出背景与前人局限
全量微调需为每个权重矩阵计算同等大小的更新矩阵,成本极高。此前的方法各有痛点:
-
Adapter:串行插入模块,引入额外推理延迟。
-
Prompt Tuning:占用输入序列长度,优化难度较高。
2. 核心假设与低秩分解
LoRA 基于一个关键假设:大模型是过参数化的,其权重更新矩阵ΔW具有很低的“内在秩”。因此,可将庞大的ΔW 分解为两个小矩阵的乘积:
ΔW=B⋅A
其中,W0∈Rd×k,B∈Rd×rB∈Rd×r, A∈Rr×kA∈Rr×k,且秩 r≪min(d,k)(通常取一个小值,如8、16、64)。

LoRA 的工作方式可以理解为在原始的预训练权重 W0 旁边,增加了一个并行的“旁路”结构,如图 计算分为两条路径:
- 主路:输入 x 经过原始的、被冻结的预训练权重 W0。
- 旁路:输入 x 依次通过两个低秩矩阵 A 和 B。矩阵 A 先将输入维度从 k “压缩”到一个很小的秩 r,然后再由矩阵 B “解压”回输出维度 d。
在训练时,只有旁路的矩阵 A 和 B 会被更新。通过这种方式,需要优化的参数量由 d×k 骤降至 d×r+r×kd×r+r×k。
3. 旁路结构与前向计算
LoRA 在原冻结权重旁增加一个并行旁路:h=W0⋅x+ΔW⋅x=W0⋅x+(B⋅A)⋅x
-
主路:冻结的预训练权重W0。
-
旁路:低秩矩阵 A(压缩维度)与B(解压维度)。
-
初始化:A 高斯随机初始化,B 初始化为零,保证训练初旁路输出为零。
-
缩放:实际计算会引入缩放因子s: h=W0⋅x+s⋅(B⋅A)⋅xh=W0⋅x+s⋅(B⋅A)⋅x。这个 s 通常设为 α/r,其中 α 是一个可调超参。这个缩放操作有助于在调整秩 r 时,减少对学习率等其他超参数的重新调整需求,让训练过程更稳定。
2、LoRA 的优势与实践
1. 核心优势
-
极高参数与存储效率:每个任务只需保存极小的 A、B 矩阵,checkpoint 体积可缩小高达 10,000 倍。训练时显存节省最高 2/3,速度提升约 25%。
-
零额外推理延迟:这是 LoRA 相比 Adapter Tuning 最具吸引力的优点。训练后可将旁路矩阵合并回原权重 (W′=W0+s⋅B⋅A) ,推理时网络结构与原模型完全一致,无任何额外计算。代价是,如果你需要为 不同的任务(拥有不同的 LoRA 权重)同时提供服务,在单个 batch 中混合处理这些任务会变得不那么直接。
-
效果媲美全量微调,且不占用输入长度:直接修改权重矩阵,影响更深入直接,且不占用任何上下文长度,适合长文本任务。
-
良好的可组合性:可与其他 PEFT 方法(如 Prefix-Tuning)正交组合使用。
2. 关键实践指导
-
应该微调哪些权重?:论文限定在自注意力模块 Wq、Wk、Wv、Wo 。实验证明,在固定参数预算下,将 LoRA 应用于多种权重组合(尤其是 Wq 和 Wv ) 比将预算全用于增大单一权重的秩效果更好。
-
秩 r 越大越好吗?:不是。非常小的秩(如 4、8、甚至 1)已足够强大,盲目增大 r 可能增加参数而不提性能,验证了权重更新确实是低秩的。
-
LoRA 如何生效?:LoRA 学到的是预训练中未被充分强调、但对下游任务至关重要的“隐藏特征”并进行放大,是在“查缺补漏”而非重复已知,精准地增强了模型在特定任务上所欠缺的能力。
3、AdaLoRA:自适应秩分配的微调
1. 固定 LoRA 的局限性
-
秩 r 固定:无法在训练中自适应调整。
-
微调目标固定:为所有层和矩阵设置统一秩并非最优,不同模块(注意力 vs. 前馈网络)、不同层级的可塑性和重要性各异。

-
实验显示,微调 FFN 权重和模型高层往往比微调注意力权重和底层收益更高。
2. AdaLoRA 的三大创新
① 基于 SVD 的参数化
将更新矩阵参数化为 SVD 形式:ΔW=PΛQ。
-
P 和 Q 决定更新“方向”,对角矩阵 Λ 上的奇异值 λi 决定更新“幅度”。
-
好处:无需计算昂贵的 SVD,仅形式上模拟;通过控制奇异值即可结构化地调整每个更新分量的重要性(即秩)。训练时引入正交正则化以保持 P 和 Q 正交。
② 重要性评分与动态分配
为每个奇异值三元组 Gk,i={Pk,∗i,λk,i,Qk,i∗} 计算重要性分数 Sk,i ,裁剪低分三元组。
参数 w 的重要性 s(w) 由两部分相乘得到:
-
平滑敏感度 Iˉ(w) :平滑后的参数与梯度乘积的绝对值,衡量参数对损失的影响程度。
-
平滑不确定性Uˉ(w):敏感度瞬时值与平滑值偏差的平滑值,衡量敏感度的稳定性。
-
一个参数既敏感又稳定(不确定性低),则重要性更高。
在计算出所有三元组的重要性分数后,AdaLoRA 会进行排序,并根据一个预设的参数预算(总秩),裁剪掉那些得分最低的三元组(即将它们对应的奇异值 λi 置为 0),从而实现了参数的动态分配。
③ 全局预算调度器
训练中保留的奇异值总数(预算)b(t) 遵循“先探索、后收敛”策略:
-
热身阶段:高于目标预算,充分探索所有参数潜力。(0≤t<ti),从一个比目标预算 b(T) 略高的初始预算 b(0) 开始训练。
-
裁剪阶段:按照一个三次方的调度曲线,逐步地裁剪掉重要性分数较低的奇异值,将预算平滑地降低到最终的目标值。(ti≤t<T−tf)
-
微调阶段:锁定最终预算 b(T) 微调至收敛。

最终,模型能自动为 FFN 和高层分配更高秩,与实验观察吻合。
与 Adapter、SVD 主题模型的联系
- 与 Adapter Tuning:两者都采用了“高维 → 低维 → 高维”的瓶颈结构。但 Adapter 是作用于 激活值 的 串行 模块(增加推理延迟),而 LoRA/AdaLoRA 是作用于权重的并行支路(可合并,无额外延迟)。AdaLoRA 在结构上更高效。
- 与 SVD 主题模型: SVD 在主题模型中被用于分解“词-文档”矩阵,以发现最重要的“语义主题”(数据层面的低秩近似)。而 AdaLoRA 则创造性地将 SVD 的思想用于分解“权重更新矩阵”,以找到最关键的“参数变化方向”(模型层面的低秩近似)。
论文的实验结果也表明,AdaLoRA 的自适应机制是有效的。它能自动发现前馈网络和模型顶层的权重矩阵更为重要,并为其分配更高的秩。此外,消融实验证明,即使不使用动态预算分配,仅仅将参数化形式从 B⋅A 替换为 PΛQ,就已经能带来性能提升,说明 SVD 结构本身的优越性。这种自适应的机制,让 AdaLoRA 在相同的参数预算下,往往能达到比原始 LoRA 更好的性能,进一步提升了参数高效微调的水平。
4、QLoRA:极致量化的参数压缩
1. 核心目标与成就
在 LoRA 基础上进一步解决基座模型本身的高显存占用问题。通过将冻结的基座模型量化为 4-bit,成功在单张 48GB GPU 上微调 65B 参数模型,性能媲美 16-bit 全量微调。梯度会穿过被冻结的 4-bit 模型,反向传播到 16-bit 的适配器中,并只更新适配器参数。此外,它还引入了 分页优化器,在显存不足时,可以将优化器状态临时卸载到 CPU 内存,从而有效管理内存峰值。

QLoRA 训练出的 Guanaco 模型系列,在 Vicuna 基准测试中甚至达到了 ChatGPT 99.3% 的性能水平,而这仅仅需要单张 GPU 训练 24 小时。
2. 三大技术创新
① 4-bit NormalFloat (NF4)
专门为零中心正态分布(其中大部分值集中在 0 附近,而少量“离群值”的绝对值又非常大。均匀的量化策略无法很好地适应这种非均匀分布,导致较大的精度损失)的权重设计的、信息论上最优的数据类型。
-
原理:基于“分位数量化”,在数据密集区(分布中心)量化点密集,稀疏区(两尾)量化点稀疏。
-
构建:计算标准正态分布 N(0,1) 的 2^4 = 16 个分位数点作为量化值;对实际权重块用其绝对值最大值归一化后,映射到最近的分位数点。
通过这种方式,NF4 用极其有限的 4 个 bit,实现了对正态分布数据的高精度近似,最大程度地保留了原始权重中的信息,远优于传统的 4-bit 整数或浮点数量化。
② 双量化 (Double Quantization)
上述量化过程需要为每一组(block)权重存储一个对应的“量化常数”(通常是 32-bit 的浮点数)。对于一个巨大的模型,这些量化常数累加起来也会占用相当大的显存。例如,对于一个 block size 为 64 的权重块,这些常数平均会给每个参数带来 32/64=0.5 bit 的额外开销。双量化的思想是,对这些量化常数本身,再进行一次量化。通过用 8-bit 浮点数对第一级量化常数进行第二级量化,可以将这部分额外开销从每参数 0.5 bit 大幅降低到约 0.127 bit。
③ 分页优化器 (Paged Optimizers)
梯度和优化器状态(如 Adam 算法中的动量和方差)会产生瞬时的显存峰值,尤其是在处理长序列时,很容易导致显存溢出(Out-of-Memory, OOM)。利用 NVIDIA 统一内存,在 GPU 显存峰值时自动将优化器状态“分页”暂存到 CPU 内存,待需要时再加载回 GPU,增强训练稳定性。
3. “存算分离”工作流
QLoRA 采用“低精度存储、高精度计算”的设计:
-
存储:基座模型以 4-bit NF4 + 双量化格式冻结。
-
计算(前向):需要时将基座权重动态反量化为 16-bit 与输入相乘;用完即丢弃临时高精度结果。
-
更新:梯度只会通过冻结的 4-bit 模型反向传播到 16-bit 的 LoRA 适配器中,并只更新适配器的权重。如果出现显存峰值,分页优化器 会介入,防止 OOM 发生。
5、重点知识点总结对比
| 方法 | 核心思想 | 可训练部分 | 关键机制 | 解决的问题 |
|---|---|---|---|---|
| LoRA | 低秩近似 | 低秩矩阵 A 和 B (旁路) | \(\Delta W = B \cdot A\),可合并入原权重 | 无推理延迟,极高参数/存储效率 |
| AdaLoRA | 自适应低秩分配 | SVD 参数化的 P, Λ, Q | 重要性评分 + 动态预算调度 | 固定秩分配的次优性,模块/层级重要性差异 |
| QLoRA | 量化基座模型 + LoRA | NF4 量化后的基座 + 16-bit 适配器 | NF4 数据类型、双量化、分页优化器 | 基座模型自身的巨大显存占用,使其能在单 GPU 上微调超大模型 |
三、基于 peft 库的 LoRA 实战
1、peft 库的设计与核心组件
设计理念:插件式“神通”
peft 库是 transformers 的增强插件,而非替代品。它将 PEFT 技术(如 LoRA)抽象为像“七十二变”一样的法术,为目标模型“临阵变身”,以应对不同任务,无需改动庞大的基础模型。核心是冻结基座模型,只训练轻量级适配器。
两大核心组件
-
PeftConfig(神通方案)
声明式定义微调策略的配置基类。关键参数:-
peft_type:指定 PEFT 方法(如PeftType.LORA)。 -
task_type:指定任务类型(如TaskType.CAUSAL_LM),确保模型头部正确适配。 -
方法专属子类如
LoraConfig,包含r(秩)、lora_alpha(缩放因子)、target_modules(目标模块)、lora_dropout等,直接对应 LoRA 论文理论。
-
-
get_peft_model(临阵变身)
核心工厂函数。接收base_model和peft_config,动态地将原始目标层(如nn.Linear)替换为注入了 LoRA 旁路的对应模块,最终返回一个接口完全兼容的PeftModel实例。peft_model.print_trainable_parameters()可直观查看参数效率。
2、LoRA 微调实战流程
1. 环境准备:加载基座模型与分词器
-
量化加载:结合
bitsandbytes,通过BitsAndBytesConfig实现 4/8-bit 量化加载,大幅降低显存。 -
设备分配:设置
device_map="auto",让accelerate跨硬件智能分配模型层。
2. 模型预处理:prepare_model_for_kbit_training
对量化模型微调前进行必要处理:
-
类型转换:将
LayerNorm等转为 FP32 保证数值稳定。 -
启用梯度检查点:用时间换显存,降低显存峰值。
-
输入梯度处理:确保反向传播在 k-bit 训练下的兼容性。
3. 配置注入:定义 LoraConfig 并创建 PeftModel
这是最关键的一步,建立理论与实践的桥梁:
-
r(秩):决定低秩矩阵维度,控制可训练参数量与表达能力。非越大越好,常规从 8/16 起。 -
lora_alpha:更新量的缩放系数,常设为r的两倍。 -
target_modules:精确指定应用 LoRA 的层。需根据实际模型结构打印后确定,通常包含注意力层的query、key、value及前馈层的部分线性层。
4. 数据处理
-
使用
datasets库加载并预处理数据。 -
定义编码函数,用
tokenizer将文本转为input_ids,并通过dataset.map()高效处理。
5. 训练:使用 Trainer
-
将
PeftModel直接传入Trainer,它自动仅更新 LoRA 适配器的权重。 -
TrainingArguments中的有效批量大小由per_device_train_batch_size×gradient_accumulation_steps× GPU 数量共同决定。 -
使用
fp16=True混合精度训练进一步减存加速。
6. 保存与推理
-
保存:
peft_model.save_pretrained()仅保存几十 MB 的适配器,而非整个模型。 -
零延迟推理(合并):
merged_model = peft_model.merge_and_unload()可将 LoRA 权重合并回原模型,网络结构与推理时延与原始模型完全一致。 -
生成:调用
peft_model.generate(),通过temperature、top_p等参数控制生成的非确定性与多样性。
3、重点知识点
| 类别 | 核心要点 | 作用与说明 |
|---|---|---|
| 设计理念 | peft 是 transformers 的插件 |
冻结基座模型,只训练轻量适配器,实现“一个基座,多个插件” |
| 模型加载 | BitsAndBytesConfig |
实现 4/8-bit 量化,让消费级硬件运行大模型成为可能 |
| 模型预处理 | prepare_model_for_kbit_training |
提升量化模型训练的数值稳定性与显存效率 |
| 核心配置 | LoraConfig |
- r:控制表达力与参数量- lora_alpha:更新缩放- target_modules:根据模型结构精确指定,是性能关键- bias:"none" 最大化参数效率 |
| 训练要点 | 有效批量大小 | = batch_size × grad_accum_steps × GPU 数,用于显存不足时模拟大批量 |
| 关键优势 | 可合并 | 推理前 merge_and_unload(),完全消除额外推理延迟,是 LoRA 的核心竞争力 |
| 生成控制 | 采样参数 | do_sample=True 时,temperature、top_p 等引入并控制输出的多样性 |
四、Qwen2.5 微调私有数据
1、Qwen2.5 模型要点
1. 预训练基础
-
数据规模:在 18 万亿 Token 的高质量多样化数据上预训练,规模与性能正相关。
-
领域强化:特别加强了代码和数学相关的训练,奠定了后续专业模型(Qwen2.5-Coder/Math)的基础。
2. Decoder-only 架构(与 Llama 类似)
-
分组查询注意力 (GQA):降低 KV 缓存,提升长序列推理效率。
-
SwiGLU 激活:FFN 使用 SiLU 激活的门控前馈,提升性能。
-
旋转位置编码 (RoPE):有效编码长序列位置信息。
-
RMSNorm:子层前预归一化,稳定训练。
-
QKV 偏置:注意力 Q/K/V 投影包含偏置项,增强表达。
3. 分词器与对话模板(沟通“语法”)
-
分词器:字节级 BPE (BBPE),词表大小 151,643。
-
对话模板:使用
<|im_start|>和<|im_end|>等特殊 Token 结构化多轮对话。必须通过tokenizer.apply_chat_template应用标准格式,否则模型无法正确理解指令。
2、微调策略四问
-
基础架构:Decoder-only,唯一的预训练任务是因果语言模型 (Causal LM)。因此
LoraConfig需设task_type="CAUSAL_LM",数据须为因果序列格式。 -
沟通语言:严格使用对话模板格式化数据,
apply_chat_template是保证零偏差的关键。 -
目标模块 (
target_modules):优先注入自注意力和 FFN 的线性层。-
注意力:
q_proj, k_proj, v_proj, o_proj -
前馈网络:
gate_proj, up_proj, down_proj
-
-
先天优势:Qwen2.5 已在知识、代码、数学领域强化。若微调目标与此相关,则事半功倍,是在已有强大能力上进行专业“深造”。
3、构建私有数据集流程
1. 微调前评估 – 确认必要性
-
使用
Qwen2.5-7B-Instruct量化加载(4-bit),定义带对话模板的推理函数。 -
测试发现:基础模型对《黑神话:悟空》知识存在明显细节缺失和偏差,微调必要。
2. 基于“教师模型”的数据生成
-
教师模型:用能力更强的 LLM(如 Qwen3-235B),自动化将非结构化文档转变为高质量
(instruction, output)对。 -
流程:
-
切分源文档:按二/三级标题切割 Markdown 为知识片段。
-
生成基础问答对:为每个片段生成(问题,答案)核心样本。
-
数据增强:对每个基础问题,生成多个等价问法,增加提问多样性,构建最终数据集。
-
4、QLoRA 微调实战
QLoRA vs LoRA
-
LoRA:方法本体,冻结基座,训练低秩适配器,可与不同精度加载结合。
-
QLoRA:LoRA 框架下的一套极致显存优化方案。标准做法:基座权重 4-bit 量化(NF4),启用双重量化与分页优化器,仅以 16-bit (BF16) 训练适配器。
关键步骤
-
4-bit 量化配置 (
BitsAndBytesConfig)-
load_in_4bit=True -
bnb_4bit_quant_type="nf4":针对正态分布权重的最优数据类型。 -
bnb_4bit_use_double_quant=True:二次量化量化常数,极致压缩。 -
bnb_4bit_compute_dtype=torch.bfloat16:计算时使用 BF16,稳定且高效。
-
-
K-bit 训练准备:
prepare_model_for_kbit_training,转换 LayerNorm 精度,启用梯度检查点等。 -
简化目标模块配置:利用
peft内置映射TRANSFORMERS_MODELS_TO_LORA_TARGET_MODULES_MAPPING["qwen2"]自动获取推荐模块,避免手动检查。 -
数据格式化与损失计算:
-
使用
apply_chat_template分别构建不含答案的 prompt 和含答案的完整对话。 -
生成
labels:prompt 部分设为 -100(忽略),仅对回答部分计算损失,确保模型学会“回答”而非“复述问题”。
-
-
训练参数:
-
per_device_train_batch_size=1,gradient_accumulation_steps=8:有效批量 = 8。 -
bf16=True:优先于 fp16,动态范围大,避免梯度下溢,训练更稳定。
-
-
保存适配器:调用
peft_model.save_pretrained(),仅保存轻量适配器权重。
微调后效果评估
-
微调后模型能准确回答游戏相关的具体问题,成功“吸收”了私有知识。
5、技术选型路径:何时微调?
遵循成本效益原则,由低到高:
-
提示词工程:优化提问,不改变模型。适用于任务简单、模型已有相关知识。
-
检索增强生成 (RAG):外挂知识库,为模型提供信息。适用于模型缺乏特定/实时知识。
-
微调:直接修改模型权重,重塑行为。适用于改变“技能或行为模式”(如特定输出格式、风格模仿、复杂指令内化)。
核心决策: 若目标是改变模型“如何做”(技能),则选择微调;若目标是补充“知道什么”(知识),优先选择 RAG。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)