什么是LoRA
LoRA(Low-Rank Adaptation)是一种参数高效微调(PEFT)技术。它不修改预训练模型的原始权重,而是在模型中插入可训练的低秩矩阵,仅训练这些新增的参数。这使得微调大模型变得可行——单个GPU就能完成7B甚至13B模型的微调。
LoRA的工作原理
LoRA的核心思想是:模型的权重更新可以用低秩分解来表示。对于一个权重矩阵W,其更新ΔW被分解为两个小矩阵的乘积:ΔW = BA,其中B和A的秩远小于原始矩阵。训练时只更新A和B,推理时合并到原权重,不增加推理延迟。
环境配置
pip install transformers peft accelerate datasets bitsandbytes
# 验证安装
python -c "import torch; print(torch.cuda.is_available())"LoRA微调实战
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from peft import LoraConfig, get_peft_model, TaskType
from datasets import load_dataset
from trl import SFTTrainer
# 加载模型
model_name = "deepseek-ai/deepseek-llm-7b-chat"
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
# LoRA配置
lora_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=8, # 秩
lora_alpha=32, # 缩放因子
lora_dropout=0.1, # Dropout比例
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"]
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 训练参数
training_args = TrainingArguments(
output_dir="./lora-finetuned",
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
num_train_epochs=3,
learning_rate=2e-4,
fp16=True,
logging_steps=10,
save_strategy="epoch"
)
# 加载数据集
dataset = load_dataset("json", data_files="train_data.json")
# 训练
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset["train"],
tokenizer=tokenizer,
max_seq_length=512
)
trainer.train()
# 保存模型
model.save_pretrained("./lora-adapter")
tokenizer.save_pretrained("./lora-adapter")LoRA参数调优
- r(秩):通常设为4-64。r越大,模型容量越大,但计算量也越大。一般r=8或16是很好的起点
- lora_alpha:通常设为r的2倍。控制LoRA更新的幅度
- target_modules:选择要添加LoRA的模块。对于LLaMA架构,通常选择q_proj、v_proj、k_proj、o_proj
- lora_dropout:0.05-0.1,防止过拟合
推理与部署
from peft import PeftModel
# 加载基础模型和LoRA适配器
base_model = AutoModelForCausalLM.from_pretrained(model_name)
model = PeftModel.from_pretrained(base_model, "./lora-adapter")
# 合并权重(可选,减少推理延迟)
model = model.merge_and_unload()
# 推理
inputs = tokenizer("请用中文介绍人工智能", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(outputs[0]))总结
LoRA让大模型微调变得平民化。即使只有一张消费级GPU,也能完成7B-13B模型的微调。建议从较小的r值开始实验,逐步调整参数找到最佳配置。