LoRA 是一种高效的参数微调技术,旨在解决大规模预训练模型全参数微调时计算和存储开销过大的问题。通过在冻结预训练模型权重的基础上,仅引入两个低秩矩阵进行增量更新,LoRA 实现了对模型进行轻量级定制,既能大幅降低微调参数量,又保持了优异的任务性能。
冻结预训练权重
预训练模型中的所有权重 W 均保持不变,避免了全模型更新带来的资源消耗。
引入低秩矩阵进行微调
在关键层(通常为 Transformer 的注意力层)中引入两个可训练低秩矩阵 A 和 B,对原始权重进行微调。公式表示为:
推理时合并权重
在推理过程中,可以直接计算 W′=W+BA,因此不会引入额外的计算成本。
参数高效
仅更新极少量参数(通常仅占总参数的百分之几),大大降低内存和存储需求。
扩展性强
支持在同一基础模型上为不同任务加载独立的 LoRA 模块,实现多任务、多领域的高效切换。
易于部署
推理时直接将低秩矩阵与冻结权重相加,不会引入额外推理延迟,适合边缘设备和大规模部署。
兼容性好
可与其他参数高效微调技术(如 Adapters、Prompt Tuning)结合使用,进一步提升应用灵活性。
LoRA 技术适用于各种需要微调大模型的场景,例如:
自然语言处理
文本分类、问答系统、对话生成、机器翻译、文本摘要等任务。
计算机视觉
图像分类、目标检测、图像生成与风格迁移等领域也可采用类似思路(针对 Vision Transformer 等架构)。
多任务与跨领域微调
在同一预训练模型上,为不同任务或语言加载各自的 LoRA 模块,便于灵活切换而无需重复存储整个模型。
边缘计算和资源受限环境
在单 GPU 或边缘设备上进行高效微调与部署,显著降低硬件要求。
以下代码示例展示了如何使用 LoRA 技术对预训练的 BERT 模型进行情感分类任务的微调。示例采用 GLUE 数据集中的 SST-2 任务,并利用 Hugging Face 的 transformers
和 peft
库。
确保安装相关依赖:
pip install transformers peft datasets accelerate torch
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForSequenceClassification
# 加载 SST-2 数据集(GLUE任务)
dataset = load_dataset("glue", "sst2")
train_dataset = dataset["train"]
eval_dataset = dataset["validation"]
# 加载预训练 BERT 分词器和模型
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)
# 数据预处理:分词、截断、填充
def preprocess_function(examples):
return tokenizer(examples["sentence"], truncation=True, padding="max_length", max_length=128)
train_dataset = train_dataset.map(preprocess_function, batched=True)
eval_dataset = eval_dataset.map(preprocess_function, batched=True)
train_dataset.set_format("torch", columns=["input_ids", "attention_mask", "label"])
eval_dataset.set_format("torch", columns=["input_ids", "attention_mask", "label"])
说明:
load_dataset
加载公开的 SST-2 数据集,并对文本进行预处理,使其适应 BERT 模型输入要求。from peft import LoraConfig, get_peft_model, TaskType
# 定义 LoRA 参数配置
lora_config = LoraConfig(
task_type=TaskType.SEQ_CLS, # 任务类型为序列分类
inference_mode=False, # 训练模式
r=8, # 低秩矩阵的秩,您可以根据需求调整此值
lora_alpha=16, # 缩放系数
lora_dropout=0.1, # Dropout 防止过拟合
target_modules=["query", "value"] # 在 Attention 层中的 query 和 value 模块上应用 LoRA
)
# 将 LoRA 模块添加到模型中
model = get_peft_model(model, lora_config)
# 输出模型中可训练参数的比例(应仅为 LoRA 参数)
model.print_trainable_parameters()
说明:
LoraConfig
指定 LoRA 参数,包括低秩维度 r
、缩放系数 lora_alpha
、Dropout 率以及目标模块。get_peft_model
会将 LoRA 模块嵌入到原始模型中,同时冻结主干参数。print_trainable_parameters()
可验证只有 LoRA 参数在训练过程中更新。from transformers import TrainingArguments, Trainer
# 定义训练超参数
training_args = TrainingArguments(
output_dir="./lora_bert_sst2",
evaluation_strategy="epoch",
save_strategy="epoch",
learning_rate=2e-4, # 由于参数量较少,可采用较大学习率
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
num_train_epochs=3,
logging_steps=100,
save_total_limit=1,
load_best_model_at_end=True,
)
# 初始化 Trainer 对象
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
tokenizer=tokenizer
)
# 启动微调训练
trainer.train()
说明:
TrainingArguments
设置训练输出目录、评估策略、学习率、批次大小及训练轮数等参数。Trainer
封装训练过程,确保仅微调 LoRA 模块。trainer.train()
后开始微调训练。# 保存 LoRA 适配器参数
model.save_pretrained("./lora_adapter")
# 加载时先加载基础模型,再加载适配器参数
from peft import PeftModel
base_model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)
lora_model = PeftModel.from_pretrained(base_model, "./lora_adapter")
说明:
PeftModel.from_pretrained
将预训练模型与保存的 LoRA 参数合并,恢复微调效果。更换底座模型
bert-base-uncased
替换为其他预训练模型,如 roberta-base
、gpt-2
、t5-small
、llama-7b
等。model_name
字符串即可: model_name = "roberta-base"
调整 LoRA 参数
混合微调策略
优化训练策略
与其他 PEFT 方法结合
硬件资源配置
掌握 LoRA 技术后,您可以在有限资源下快速定制大模型,实现多任务、多领域的智能应用,为您的项目和产品创新提供坚实技术支持。
【参考资料】
【哈佛博后带小白玩转机器学习】 哔哩哔哩_bilibili
总课时超400+,时长75+小时