LoRA微调手把手教程
LoRA:高效微调的利器 LoRA(Low-Rank Adaptation)通过在原模型权重旁添加低秩矩阵,只需训练极少量参数即可实现有效的微调。一个7B模型的LoRA微调只需8GB显存,而全量微调需要56GB。 环境准备 pip install peft transformers accelerate datasets bitsandbytes 完整微调代码 import torch from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments from peft import LoraConfig, get_peft_model, TaskType from datasets import Dataset # 1. 加载模型和分词器 model_name = "Qwen/Qwen3-7B" tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype=torch.float16, device_map="auto", trust_remote_code=True, ) # 2. LoRA配置 lora_config = LoraConfig( task_type=TaskType.CAUSAL_LM, r=64, # LoRA秩,越大容量越大但训练越慢 lora_alpha=128, # 缩放因子,通常为r的2倍 lora_dropout=0.05, # Dropout防止过拟合 target_modules=[ # 应用LoRA的模块 "q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj" ], bias="none", ) # 3. 应用LoRA model = get_peft_model(model, lora_config) model.print_trainable_parameters() # 输出:trainable params: 39,321,600 || all params: 7,078,299,648 || trainable%: 0.556% # 4. 数据准备 def format_dataset(data): formatted = [] for item in data: text = f"<|im_start|>user\n{item['input']}<|im_end|>\n<|im_start|>assistant\n{item['output']}<|im_end|>" formatted.append({"text": text}) return formatted train_data = format_dataset(raw_train_data) val_data = format_dataset(raw_val_data) train_dataset = Dataset.from_list(train_data) val_dataset = Dataset.from_list(val_data) def tokenize_fn(examples): result = tokenizer( examples["text"], truncation=True, max_length=2048, padding=False, ) result["labels"] = result["input_ids"].copy() return result train_dataset = train_dataset.map(tokenize_fn, batched=True, remove_columns=["text"]) val_dataset = val_dataset.map(tokenize_fn, batched=True, remove_columns=["text"]) # 5. 训练参数 training_args = TrainingArguments( output_dir="./lora-output", num_train_epochs=3, per_device_train_batch_size=4, per_device_eval_batch_size=4, gradient_accumulation_steps=4, warmup_ratio=0.1, learning_rate=2e-4, lr_scheduler_type="cosine", logging_steps=10, eval_strategy="steps", eval_steps=100, save_strategy="steps", save_steps=100, save_total_limit=3, load_best_model_at_end=True, bf16=True, gradient_checkpointing=True, report_to="tensorboard", ) # 6. 训练 from transformers import Trainer trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=val_dataset, data_collator=lambda features: { "input_ids": torch.nn.utils.rnn.pad_sequence( [torch.tensor(f["input_ids"]) for f in features], batch_first=True, padding_value=tokenizer.pad_token_id ), "labels": torch.nn.utils.rnn.pad_sequence( [torch.tensor(f["labels"]) for f in features], batch_first=True, padding_value=-100 ), "attention_mask": torch.nn.utils.rnn.pad_sequence( [torch.tensor([1] * len(f["input_ids"])) for f in features], batch_first=True, padding_value=0 ), }, ) trainer.train() # 7. 保存LoRA权重 model.save_pretrained("./lora-weights") tokenizer.save_pretrained("./lora-weights") 合并与部署 # 合并LoRA权重到基础模型 from peft import PeftModel base_model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype=torch.float16, device_map="auto" ) model = PeftModel.from_pretrained(base_model, "./lora-weights") merged_model = model.merge_and_unload() # 合并权重 # 保存合并后的完整模型 merged_model.save_pretrained("./merged-model") tokenizer.save_pretrained("./merged-model") # 导出为GGUF格式(用于Ollama部署) # python convert.py ./merged-model --outtype f16 QLoRA(量化LoRA) from transformers import BitsAndBytesConfig # 4-bit量化加载基础模型 bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.float16, bnb_4bit_use_double_quant=True, ) model = AutoModelForCausalLM.from_pretrained( model_name, quantization_config=bnb_config, device_map="auto", ) # 其余LoRA配置和训练流程相同 # QLoRA可以在单张8GB GPU上微调7B模型 超参数调优指南 参数 推荐值 说明 r 16-128 简单任务用小r,复杂任务用大r lora_alpha 2×r 通常为r的2倍 learning_rate 1e-4 ~ 5e-4 LoRA需要比全量微调更大的学习率 epochs 2-5 注意过拟合 batch_size 4-16 配合gradient_accumulation target_modules 全选 QKVO+FFN效果最好 常见问题 显存不足 使用QLoRA(4-bit量化) 减小batch_size,增加gradient_accumulation 启用gradient_checkpointing 减小max_length 过拟合 减少epochs 增加lora_dropout 增加训练数据 减小r 效果不好 检查数据质量 增大r 确保target_modules覆盖所有线性层 检查学习率是否合适 结语 LoRA是大模型微调的性价比之选——少量参数、少量显存、快速训练。通过合理的配置和高质量数据,LoRA微调可以达到接近全量微调的效果。掌握LoRA是LLM工程化的必备技能。 加入讨论 这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。 ...