大模型微调步骤与精髓总结
一、微调核心步骤(6步法)
步骤1:环境与模型准备
python
# 关键依赖
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from trl import SFTTrainer
# 加载分词器(必须设置pad_token)
tokenizer = AutoTokenizer.from_pretrained(model_path)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token # 关键!
步骤2:数据集处理
python
# 核心要点:格式化prompt + 添加EOS_TOKEN
train_prompt_style = """### 指令:
{}
### 问题:
{}
### 回答:
{}
"""
EOS_TOKEN = tokenizer.eos_token # 必须添加,否则无限生成!
def formatting_prompts_func(examples):
texts = []
for input, cot, output in zip(inputs, cots, outputs):
text = train_prompt_style.format(input, cot, output) + EOS_TOKEN
texts.append(text)
return {"text": texts}
dataset = dataset.map(formatting_prompts_func, batched=True)
步骤3:模型量化(节省显存)
python
# 4bit量化(推荐)
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True, # 双重量化
bnb_4bit_quant_type="nf4", # NF4量化类型
bnb_4bit_compute_dtype=torch.bfloat16
)
# 8bit量化(备选)
bnb_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(
model_path,
quantization_config=bnb_config,
device_map="auto"
)
步骤4:LoRA配置(参数高效微调)
python
model = prepare_model_for_kbit_training(model) # 量化模型准备
lora_config = LoraConfig(
r=16, # LoRA秩(常用8,16,32,64)
lora_alpha=16, # 缩放因子(通常等于r或2r)
target_modules=[ # 目标模块
"q_proj", "k_proj", "v_proj", "o_proj", # 注意力层
"gate_proj", "up_proj", "down_proj" # MLP层
],
lora_dropout=0, # dropout(0最优)
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters() # 查看可训练参数比例
步骤5:训练配置
python
training_arguments = TrainingArguments(
output_dir=output_dir,
per_device_train_batch_size=1, # 根据显存调整
gradient_accumulation_steps=8, # 有效batch = batch × accumulation
learning_rate=1e-4, # LoRA常用1e-4 ~ 5e-4
num_train_epochs=1, # 训练轮数
optim="adamw_8bit", # 8bit优化器省显存
lr_scheduler_type="cosine", # 余弦学习率调度
warmup_ratio=0.03, # 预热比例
weight_decay=0.01,
max_grad_norm=0.3, # 梯度裁剪
bf16=True, # 使用bf16混合精度
logging_steps=10,
save_steps=500,
)
步骤6:启动训练
python
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
args=training_arguments,
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=2048,
packing=False, # 短序列可开启packing提高效率
)
trainer.train()
trainer.save_model(output_dir)
二、快速掌握精髓(核心要点)
🎯 精髓1:为什么用LoRA?
- 全量微调:更新所有参数,显存需求巨大
- LoRA微调:只训练低秩分解矩阵,可训练参数<1%
- 公式 :
W' = W + BA,只训练B和A两个小矩阵
🎯 精髓2:量化技术
| 量化方式 | 显存占用 | 精度损失 | 推荐场景 |
|---|---|---|---|
| 4bit | 最低 | 稍高 | 消费级显卡(24GB以下) |
| 8bit | 中等 | 较低 | 中等显卡(24-48GB) |
| FP16/BF16 | 高 | 无 | 高端显卡(80GB+) |
🎯 精髓3:关键超参数选择
python
# 学习率
learning_rate = 1e-4 # LoRA标准范围,太大容易灾难性遗忘
# LoRA秩 r
r = 16 # 简单任务8-16,复杂任务32-64
# Batch Size策略
有效batch = per_device_batch × gradient_accumulation × GPU数量
# 显存不够就减小batch,增大accumulation
# 序列长度
max_seq_length = 2048 # 根据数据长度调整,越长越吃显存
🎯 精髓4:Loss Mask(只训练回答部分)
python
# 核心思想:问题部分不计算loss,只对回答部分计算loss
# SFTTrainer通过DataCollatorForCompletionOnlyLM实现
response_template = "<|start_header_id|>assistant<|end_header_id|>\n\n"
collator = DataCollatorForCompletionOnlyLM(response_template, tokenizer=tokenizer)
🎯 精髓5:多GPU训练要点
bash
# 使用accelerate + DeepSpeed
accelerate launch train_on_multi_gpu.py --deepspeed ds_config.json
# 关键:多GPU时不要设置device_map="auto",让accelerate自动处理
三、实战速查表
单GPU训练命令
bash
python train_on_single_gpu.py
# 或后台运行
nohup python train_on_single_gpu.py > training.log 2>&1 &
多GPU训练命令
bash
accelerate launch --config_file accelerate_config.yaml train_on_multi_gpu.py
# 或使用DeepSpeed
accelerate launch --use_deepspeed train_on_multi_gpu.py --deepspeed ds_config.json
Unsloth加速(推荐)
python
from unsloth import FastLanguageModel
# Unsloth比原生快2倍,显存占用少30%
model, tokenizer = FastLanguageModel.from_pretrained(
model_name, load_in_4bit=True
)
model = FastLanguageModel.get_peft_model(model, r=16, ...)
四、常见问题解决
| 问题 | 解决方案 |
|---|---|
| 显存不足 | 减小batch_size、使用4bit量化、开启gradient_checkpointing |
| 训练不收敛 | 降低学习率、检查数据格式、增加warmup |
| 生成无限重复 | 检查是否添加EOS_TOKEN |
| Loss不下降 | 检查loss mask是否正确、数据质量是否合格 |
核心记忆口诀:
量化省显存,LoRA省参数,EOS防无限,Mask只训答,学习率要小,累积凑batch