大模型高效微调(PEFT)方法详解
随着大模型技术的快速发展,国内已发布的大模型数量激增。然而,绝大多数模型将是昙花一现,世界不需要这么多大模型。对于大多数人或公司,没有足够的财力从头开始训练大模型,基于已有的大模型作为基座,用自身业务相关的数据进行微调(Fine-tuning),是一个很好的选择。
1. PEFT 概述
微调主要有两种方法:
- 全参数微调:调整模型所有参数,需要大量 GPU 资源,且容易破坏预训练知识。
- 高效参数微调(PEFT):只微调少量参数,节省 GPU 资源,且能达到不错的效果。PEFT 即 Parameter-Efficient Fine-Tuning。
本文总结了从 2019 年以来主要的 PEFT 方法,主要参考综述论文《Scaling Down to Scale Up: A Guide to Parameter-Efficient Fine-Tuning》。
目前最流行的微调方法是 LoRA,后续将详细介绍。
2. PEFT 分类
按是否增加额外参数,PEFT 主要分为以下四类:
- Additive 类:在预训练模型基础上增加额外的参数或网络层,微调时只训练新增部分。
- Adapter:在 Transformer 子层后加入小的全连接层。
- Soft Prompts:直接在输入的 embedding 中加向量作为 soft prompts。
- Selective 类:选择模型中的部分层(如最后几层)或偏置项进行微调。
- Reparametrization-based 类:利用低秩表征来最小化可训练的参数,认为关键作用仅在一部分子空间中。
- Hybrid 类:混合了多种类别的方法。
3. 具体方法介绍
3.1 Additive 类:Adapters
Adapter 结构简洁明了,在 Transformer 的前馈层后加入 Adapter 层。Adapter 是一个 bottleneck 结构,先把 d 维特征映射为 m 维,然后通过一个非线性层,最后映射回 d 维特征(m << d)。模型微调的时候,学习的参数包含 Adapter 和 Layer Norm 层。
实验表明,在 BERT Large 模型上用 0.5%-5% 的参数微调,基本达到全参数微调性能,差距仅在 1% 以内。
3.2 Additive 类:Soft Prompts
Prefix-Tuning
Prefix-Tuning 在模型的输入里直接加上前缀向量进行微调,功能类似加 Prompt,但加的是向量,让这些向量自行训练,不用人为构造模板。它在每层的开头加了 Prefix 向量,微调只训练这部分对应的参数,其余 Transformer 固有参数冻结不变。
实验显示,只用微调占模型 0.1% 的参数,就能得到和全参数微调媲美的效果,普遍优于 Adapters 方法。
Prompt Tuning
Prompt Tuning 是 Prefix-Tuning 的简化版,只把 soft prompts 加到模型的输入层。研究表明只加到输入层效果就不错了,不必加到中间层。文章还探索了 Prompt Ensembling,即同一 batch 里同时训练多个任务,预测时用投票方式选 prompt,性能通常好于单个 prompt。
3.3 Selective 类:BitFit
BitFit 十分简洁,在 Transformer 结构中只微调所有偏置项(bias)参数。Transformer 过程中的 Q、K、V 计算、Attention 计算以及 Layer-Norm 中都包含 bias 项,BitFit 仅选择这些 bias 项参数进行微调。
在 GLUE 基准测试上,基于 BERT Large 基座模型,BitFit 在部分任务上能达到最优,且参数量极小。
3.4 Reparametrization-based 类:LoRA
LoRA(Low-Rank Adaptation)是目前最流行的 PEFT 方法,受欢迎是因为效果好且易用。
原理:对预训练模型权重 W,LoRA 认为微调时的参数变化可以压缩到一个很小的子空间。即 $W' = W + BA$,其中 $W$ 是预训练权重(冻结),$B$ 和 $A$ 是低秩矩阵(可训练),维度关系为 $r \ll \min(d, k)$。
优势:
- 相比 Prefix-Tuning,支持更长的输入。
- 相比 Adapters,增加的参数和基座模型计算是并行的,推理时无额外延迟。
- 部署方便,不同任务只需替换对应的 $BA$ 矩阵。
实验结果:在 RoBERTa、DeBERTa、GPT-2、GPT-3 等模型上的实验显示,LoRA 微调性能优于或持平全参微调,且参数量大幅减少。
劣势:不能在同一个 batch 里训练多个任务的 A 和 B。
3.5 Hybrid 类
- MAM Adapters:联合了并行的 adapters 和 soft prompts。
- UniPELT:联合了 LoRA、Prefix-tuning 和 Adapters。
4. LoRA 实战代码示例
在实际应用中,推荐使用 Hugging Face 的 peft 库来实现 LoRA。以下是一个简单的微调示例:
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "meta-llama/Llama-2-7b-hf"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
lora_config = LoraConfig(
r=8,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
此代码展示了如何配置 LoRA 参数并应用到模型上,通过设置 target_modules 可以选择性地对注意力机制的权重进行微调。
5. 总结与建议
PEFT 技术使得在有限算力下适配大模型成为可能。各类方法各有优劣:
- Adapters 适合需要模块化扩展的场景。
- Prefix/Prompt Tuning 适合生成式任务,参数极少。
- BitFit 适合快速验证,实现最简单。
- LoRA 综合性能最佳,是目前工业界首选方案。
建议开发者根据具体任务需求、显存限制及推理延迟要求选择合适的 PEFT 方法。对于大多数通用场景,LoRA 是性价比最高的选择。