📖 概述
大语言模型(LLM)微调是将预训练的大模型适配到特定下游任务的关键技术。本教程将系统讲解当前最先进的参数高效微调(PEFT)方法,帮助你在有限计算资源下实现高质量的模型定制。
💡 学习目标
完成本教程后,你将掌握:
- 理解LoRA、QLoRA等参数高效微调原理
- 能够准备和构建高质量的指令微调数据集
- 熟练使用Hugging Face PEFT库进行模型微调
- 掌握训练优化技巧和模型部署方法
🎯 前置知识
Python编程
熟悉Python基础语法和常用库
PyTorch基础
了解张量操作和神经网络基础
Transformers
熟悉Hugging Face Transformers库
GPU环境
具备CUDA-enabled GPU访问权限
⚙️ 环境准备
1. 安装依赖库
bashpip install torch transformers datasets peft accelerate bitsandbytes
pip install trl wandb sentencepiece protobuf
2. 验证环境
pythonimport torch
print(f"PyTorch版本: {torch.__version__}")
print(f"CUDA可用: {torch.cuda.is_available()}")
print(f"CUDA版本: {torch.version.cuda}")
print(f"GPU数量: {torch.cuda.device_count()}")
📊 数据准备
高质量的数据是微调成功的关键。我们将使用Alpaca格式的指令微调数据。
数据格式示例
json{
"instruction": "解释什么是LoRA微调技术",
"input": "",
"output": "LoRA(Low-Rank Adaptation)是一种参数高效微调技术..."
}
1
数据预处理脚本
pythonfrom datasets import load_dataset, Dataset
import json
def format_alpaca_prompt(instruction, input_text, output):
if input_text:
prompt = f"### Instruction:\n{instruction}\n\n### Input:\n{input_text}\n\n### Response:\n"
else:
prompt = f"### Instruction:\n{instruction}\n\n### Response:\n"
return {"text": prompt + output}
# 加载并处理数据
dataset = load_dataset("json", data_files="your_data.json")
formatted_dataset = dataset.map(lambda x: format_alpaca_prompt(
x["instruction"], x.get("input", ""), x["output"]
))
🔧 LoRA微调
LoRA通过在原始权重矩阵旁路添加低秩矩阵来进行微调,大幅减少可训练参数。
LoRA配置
pythonfrom peft import LoraConfig, get_peft_model, TaskType
# LoRA配置参数
lora_config = LoraConfig(
r=16, # 低秩矩阵维度
lora_alpha=32, # 缩放参数
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
lora_dropout=0.05, # Dropout率
bias="none",
task_type=TaskType.CAUSAL_LM
)
# 应用LoRA到基础模型
model = get_peft_model(base_model, lora_config)
model.print_trainable_parameters() # 查看可训练参数量
⚠️ 重要提示
不同的模型架构需要指定不同的target_modules。对于LLaMA系列模型,通常是["q_proj", "v_proj"];对于ChatGLM,则需要根据具体版本调整。
🚀 QLoRA高效微调
QLoRA结合4-bit量化和双量化技术,可在单张消费级GPU上微调65B参数模型。
4-bit量化配置
pythonfrom transformers import BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True, # 嵌套量化
bnb_4bit_quant_type="nf4", # 4-bit量化类型
bnb_4bit_compute_dtype=torch.bfloat16
)
# 加载量化模型
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True
)
💡 内存优化技巧
- 使用
gradient_checkpointing节省激活内存 - 设置
max_memory参数控制每GPU最大内存 - 开启
fp16或bf16混合精度训练
📈 训练技巧
训练参数配置
pythonfrom transformers import TrainingArguments
from trl import SFTTrainer
training_args = TrainingArguments(
output_dir="./results",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
warmup_steps=100,
logging_steps=10,
save_strategy="epoch",
fp16=True,
optim="paged_adamw_8bit", # 分页优化器减少内存
lr_scheduler_type="cosine"
)
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset,
max_seq_length=512
)
trainer.train()
学习率调度策略对比
| 调度器 | 适用场景 | 特点 |
|---|---|---|
linear |
一般微调 | 线性衰减,稳定收敛 |
cosine |
长训练周期 | 余弦退火,平滑下降 |
constant |
短训练周期 | 固定学习率 |
🎯 模型部署
合并并保存模型
python# 合并LoRA权重到基础模型
merged_model = model.merge_and_unload()
# 保存完整模型
merged_model.save_pretrained("./merged_model")
tokenizer.save_pretrained("./merged_model")
# 或者只保存LoRA适配器(推荐)
model.save_pretrained("./lora_adapter")
# 使用时动态加载
model = PeftModel.from_pretrained(base_model, "./lora_adapter")
推理优化
python# 使用vLLM加速推理
from vllm import LLM, SamplingParams
llm = LLM(model="./merged_model", tensor_parallel_size=1)
sampling_params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=512
)
outputs = llm.generate(["解释什么是深度学习"], sampling_params)
📦 配套资源
完整代码Notebook
llm_finetuning_complete.ipynb • 2.3 MB
示例数据集
alpaca_zh_10k.json • 15.6 MB
配置文件模板
lora_config_templates.zip • 12 KB