一、按训练目标 / 训练阶段(日常说的 SFT、偏好、强化微调)
1. 普通微调(SFT 监督指令微调)
就是你说的「普通微调」,最基础一环
- 全称:Supervised Fine-Tuning 监督微调
- 数据:标准问答、对话、领域标准答案(单条正样本)
- 作用:教会模型听懂指令、固定输出格式、学习行业知识(法律 / 医疗 / 代码)
- 例子:给模型几千条客服问答,让它学会标准回复
2. 继续预训练微调 CPT(领域知识扩充微调)
很多人容易忽略,属于前置知识微调
- 数据:无标注领域长文本(行业文档、书籍、论文)
- 作用:给底座模型灌入全新专业知识,先扩充知识库,再做 SFT
- 场景:垂直行业专用大模型,如医疗、金融专属底座
3. 偏好微调(离线偏好对齐,DPO/ORPO/KTO)
你说的「偏好微调」,不带强化学习,现在工业主流替代 RLHF
- DPO 直接偏好优化(最常用) 用「同一个问题,好回答 vs 差回答」成对偏好数据,纯监督损失,不用奖励模型、不用 PPO 强化。
- ORPO 对比偏好优化 一步融合 SFT + 偏好对齐,省去单独 SFT 阶段,轻量化训练。
- KTO 知识偏好优化 侧重区分有用 / 无用回答,适合客服、知识库场景。
4. 强化微调(RLHF 人类反馈强化学习,PPO)
你说的「强化微调」,唯一带奖惩函数 + 强化训练的对齐方案 完整三步:
- SFT 基础微调 → 2. 训练奖励模型(打分 / 奖惩函数) → 3. PPO 强化学习迭代优化
- 特点:依靠奖惩函数引导模型生成人类更喜欢的回答,对齐价值观、安全、人性化;缺点算力大、训练不稳定。 衍生强化对齐:GRPO(推理专用强化微调,数学 / 代码提升巨大)
5. 对比微调 CPT Contrastive Prompt Tuning
小众辅助微调,区分正负样例,提升意图识别、上下文区分能力。
二、按参数更新方式(PEFT 参数高效微调,所有上面的微调都能搭配)
不是训练目标,但日常开发都会区分「全量微调 / LoRA 微调」
- 全参数微调 Full FT 更新模型全部权重,效果最好,显存成本极高,仅 7B 以下小模型偶尔使用。
- LoRA 低秩适配器微调(主流) 冻结主模型,只训练少量低秩矩阵,显存消耗极低,单卡可训 70B。
- QLoRA 量化 LoRA 4bit 量化底座,极致省显存,低配显卡微调超大模型。
- Adapter / P-Tuning v2 前缀微调 插入额外小网络 / 可学习 prompt,适合分类、小样本任务。
最简流水线顺序(通用大模型训练流程)
底座预训练 → CPT 领域预训练(可选)→ SFT 普通微调 → DPO 偏好微调 / RLHF 强化微调
一句话区分你提到的三类
- 普通 SFT:教模型「标准答案怎么说」
- 偏好 DPO:教模型「哪个回答更好」(纯监督,无强化)
- 强化 RLHF:用奖惩函数 + PPO 反复试错,强制模型往高分回答靠拢(带强化训练)
RLHF为例
1. 环境准备
首先,确保安装了必要的库:
bash
pip install trl peft transformers datasets
2. 完整的修正版代码
python
import re
from datasets import Dataset
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import LoraConfig
from trl import GRPOConfig, GRPOTrainer
# ================= 1. 准备数据集 =================
# 模拟一个包含 prompt 和 ground_truth 的数据集
data = [
{"prompt": "1+1等于几?", "ground_truth": "2"},
{"prompt": "中国的首都是哪里?", "ground_truth": "北京"},
]
dataset = Dataset.from_list(data)
# ================= 2. 编写正确的奖惩逻辑 =================
# 注意:trl 的 reward_funcs 接收的参数是 (completions, **kwargs)
# kwargs 中会自动包含数据集里的其他字段(如 ground_truth)
# 返回值必须是一个包含浮点数的列表,长度等于 completions 的数量
# 奖惩逻辑1:格式奖励(强制模型使用 <answer> 标签)
def format_reward(completions, **kwargs):
pattern = r"<answer>(.*?)</answer>"
rewards = []
for completion in completions:
# 检查模型输出是否包含正确的标签
match = re.search(pattern, completion[0]["content"])
if match:
rewards.append(0.5) # 格式正确,给 0.5 分(好的)
else:
rewards.append(0.0) # 格式错误,给 0 分(坏的)
return rewards
# 奖惩逻辑2:准确率奖励(检查答案是否与标准答案一致)
def accuracy_reward(completions, ground_truth, **kwargs):
rewards = []
for completion, gt in zip(completions, ground_truth):
content = completion[0]["content"]
match = re.search(r"<answer>(.*?)</answer>", content)
if match and match.group(1).strip() == str(gt).strip():
rewards.append(1.0) # 答案正确,给 1 分(极好)
else:
rewards.append(0.0) # 答案错误,给 0 分(坏)
return rewards
# ================= 3. 配置并启动微调 =================
# 这里使用一个小模型作为示例,实际可替换为 Qwen 等模型
model_id = "Qwen/Qwen2.5-0.5B-Instruct"
# 配置 GRPO 训练参数
training_args = GRPOConfig(
output_dir="./qwen-grpo-output",
num_train_epochs=3,
per_device_train_batch_size=2,
logging_steps=5,
learning_rate=5e-5,
)
# 配置 LoRA 进行高效微调
peft_config = LoraConfig(
task_type="CAUSAL_LM",
r=8,
lora_alpha=16,
lora_dropout=0.05,
)
# 初始化 GRPO 训练器
trainer = GRPOTrainer(
model=model_id,
args=training_args,
train_dataset=dataset,
reward_funcs=[format_reward, accuracy_reward], # 【核心】注入奖惩逻辑
peft_config=peft_config,
)
# 开始训练!模型会根据奖惩函数的反馈不断调整权重
if __name__ == "__main__":
trainer.train()
💡 核心修正点说明:
- 奖励函数签名 :
trl的奖励函数必须接收completions作为第一个参数,数据集里的其他字段(如ground_truth)会通过**kwargs自动传入。 - 返回值格式 :奖励函数必须返回一个列表 ,列表的长度必须与传入的
completions长度严格一致。 - 数据结构 :
completions是一个嵌套列表,每个元素是[{"content": "模型生成的文本"}],所以提取文本时需要用completion[0]["content"]。