2026年4月19日

LLM Fine-tuning(LoRA / RLHF / DPO)

大模型的 Fine-tuning 不是"训一次",而是一套从预训练到对齐的完整流程:

知识库机器学习llmfine-tuninglorarlhfdpomachine-learning

LLM Fine-tuning(LoRA / RLHF / DPO)

先把结论放前面

大模型的 Fine-tuning 不是"训一次",而是一套从预训练到对齐的完整流程:

Pretraining → 学会语言规律(大量无监督文本)
SFT(Supervised Fine-tuning) → 学会遵循指令(高质量指令-回复对)
RLHF / DPO → 学会和人类偏好对齐(比 SFT 更难表达的品质:有用、无害、诚实)

LoRA / QLoRA 是降低 Fine-tuning 显存和计算成本的方法,不是替代 RLHF 的东西。

为什么这个问题值得单独讲

LLM 的训练和 Fine-tuning 是目前工业界和学术圈最活跃的领域,但概念最容易混:

  • SFT 和 RLHF 是什么关系?
  • LoRA 是替代 RLHF 还是只是降低成本?
  • DPO 为什么比 RLHF 简单,简化了什么?
  • 什么时候该 Fine-tune,什么时候该用 Prompt Engineering?

Pre-training → SFT → RLHF 完整链路

Pretraining(预训练)

用海量无监督文本(互联网爬取),训练语言模型预测下一个 token。目标是学会语言本身

训练数据:The Pile、RedPajama、RefinedWeb 等万亿 token 级数据集。

损失函数:标准 Language Modeling Loss(Next Token Prediction)。

# 预训练伪代码
for batch in dataloader:
    tokens = tokenize(batch["text"])
    logits = model(tokens)
    loss = cross_entropy(logits[:, :-1], tokens[:, 1:])
    loss.backward()

SFT(Supervised Fine-tuning)

用高质量的指令-回复对(Instruction-Response pairs),教模型"怎么回答问题"。

训练数据:人工标注的指令数据(如 OpenAI 的 InstructGPT 数据集)。

# SFT 伪代码
for batch in dataloader:
    tokens = tokenize(batch["instruction"], batch["response"])
    logits = model(tokens)
    # 只在回复部分算损失
    loss = cross_entropy(logits[:, :-1], tokens[:, 1:])
    loss.backward()

SFT 能解决什么问题:教会模型遵循指令格式、回答问题的结构(不要自言自语、不要拒绝不存在的知识)。

SFT 不能解决什么问题:安全性(有 Toxic 输出)、对齐(符合人类偏好的回答风格)。

RLHF(Reinforcement Learning from Human Feedback)

RLHF 解决的是"SFT 能教会模型回答问题,但不能保证回答质量符合人类偏好"的问题。

核心流程

  1. Reward Model 训练:收集人类偏好数据(同一问题,两个回答,哪个更好),训练 Reward Model 预测人类偏好。

  2. PPO 强化学习:用 Reward Model 的信号,通过 PPO(Proximal Policy Optimization)算法优化 SFT 模型,让它产生 Reward 更高的输出。

# RLHF Step 1: Reward Model
preference_data = [
    {"question": "...", "response_a": "...", "response_b": "...", "label": "a"}
]
# 训练 Reward Model 预测"哪个回答更好"

# RLHF Step 2: PPO
for batch in ppo_iterations:
    responses = sft_model.generate(question)
    rewards = reward_model(question, responses)
    ppo_update(sft_model, rewards)  # 用 PPO 算法更新模型

RLHF 的问题

  • 需要大量人类偏好标注(成本高)
  • PPO 训练不稳定(KL 散度约束需要仔细调)
  • Reward Model 可能被 hacking(模型学会"骗"Reward Model)

DPO(Direct Preference Optimization)

DPO 是 2023 年提出的方法,直接用偏好数据优化语言模型,不需要训练 Reward Model,也不需要 PPO,大幅简化了 RLHF。

核心思想:把 RLHF 的 Reward Model 建模融进策略本身,直接从偏好数据里学习。

Loss 函数

DPO Loss = - log σ( r(x,y_w) - r(x,y_l) - β × KL(π_θ(y|x) || π_ref(y|x)) )
  • y_w:人类偏好的回答
  • y_l:人类不偏好的回答
  • π_θ:当前模型
  • π_ref:参考模型(SFT 模型)
  • β:KL 散度惩罚系数

为什么 DPO 更好

维度 RLHF DPO
训练稳定性 不稳定(PPO 难调) 稳定(直接优化)
需要 Reward Model 需要 不需要
需要 PPO 需要 不需要
人类偏好数据效率
工程复杂度
效果 在简单对齐任务上接近 RLHF

DPO 的弱点:对于复杂的多维度偏好(如"既要有用又要有害性低"),DPO 的表现不一定比 RLHF 更好。

LoRA / QLoRA:降低 Fine-tuning 成本

全参数 Fine-tuning 的问题

GPT-3(175B 参数)的全参数 Fine-tuning 需要:8×A100(80GB)× 100+ 小时。这不是普通团队能承受的。

LoRA(Low-Rank Adaptation)

核心思想:冻结预训练模型的原始权重 W₀,在旁边额外训练两个低秩矩阵 A 和 B。推理时,原始权重 + 低秩更新的效果和全参数 Fine-tuning 接近。

原始前向:      h = W₀ · x
LoRA 前向:     h = W₀ · x + (B · A) · x

其中 A ∈ ℝ^(r×k),B ∈ ℝ^(k×r),r 是秩(rank),通常 r = 4, 8, 16, 64。

秩 r 的选择:

  • r = 4-8:轻量,适合简单任务(如情感分类)
  • r = 16-64:标准,效果和全参数 Fine-tuning 接近
  • r = 128+:接近全参数 Fine-tuning

显存节省:全参数 Fine-tuning 需要保存梯度 + 优化器状态(FP32 优化器),LoRA 只需要保存 A 和 B 两个矩阵 + 优化器状态。175B 模型从 1.2TB 显存降到 350GB(8 倍压缩)。

QLoRA(Quantized LoRA)

QLoRA = LoRA + NF4(4-bit NormalFloat 量化)。

核心步骤

  1. 把预训练模型量化为 NF4(4-bit 量化)
  2. 用 LoRA 在量化模型上 Fine-tuning
  3. 合并 LoRA 权重回量化模型

效果:65B 模型可以在 48GB 显存(如单张 A100)上 Fine-tuning。

LoRA 的常见配置

from peft import LoraConfig, get_peft_model

lora_config = LoraConfig(
    r=16,                     # rank,越大越接近全参数微调
    lora_alpha=32,            # 缩放系数,通常 = 2×rank
    target_modules=[          # 应用 LoRA 的模块
        "q_proj", "k_proj",   # Transformer 的 Q 和 K
        "v_proj", "o_proj",  # V 和 O
        "gate_proj", "up_proj", "down_proj"  # FFN 层
    ],
    lora_dropout=0.05,
    bias="none",              # 不训练 bias
    task_type="CAUSAL_LM"
)

model = get_peft_model(base_model, lora_config)
# 可训练参数从 7B × 4 bytes × 2 ≈ 56GB → 约 80MB

LoRA 的变体

DoRA(Weight-Decomposed LoRA):把 LoRA 的更新分解为幅度(magnitude)和方向(direction),效果比标准 LoRA 更好,尤其在高 rank 设置下。

QLoRA / QA-LoRA:LoRA + 量化,结合两种压缩手段。

Instruction Tuning(指令微调)

Instruction Tuning 和 SFT 本质上是同一件事,但侧重点不同:

  • SFT:强调"用监督数据 Fine-tune",解决模型遵循指令的问题
  • Instruction Tuning:强调"数据是格式化的指令",通常是 Instruction-Input-Output 三元组

常见数据集:

  • Alpaca(Stanford):用 Self-Instruct 生成
  • Vicuna:ChatGPT 对话数据
  • WizardLM:用 LLM 生成复杂指令
  • FLAN:Google 的大规模指令微调数据集

什么时候该 Fine-tune,什么时候该 Prompt Engineering

场景 推荐方法
需要模型学习新知识(新事实、新领域) Fine-tuning(SFT)
需要模型改变输出风格 Fine-tuning(SFT)
需要模型遵循复杂格式 Fine-tuning(SFT)
知识已经存在于模型里,只是没被激活 Prompt Engineering
只需要给模型更多上下文 RAG
需要实时更新的知识 RAG(Fine-tuning 不是为此设计的)
需要模型和特定行为对齐 RLHF / DPO

常见误区:用 Fine-tuning 来让模型学习新知识是低效的——训练数据量有限,无法覆盖所有知识边角情况。RAG 才是处理实时知识的正确工具,Fine-tuning 的价值在于改变风格和结构。

DeepSpeed + ZeRO

DeepSpeed 是微软的分布式训练库,和 LoRA 是互补的——LoRA 降低单卡显存,DeepSpeed 让训练分布到多卡。

ZeRO(Zero Redundancy Optimizer):把优化器状态、梯度、模型参数分片到不同 GPU:

  • ZeRO-1:优化器状态分片(显存节省约 4 倍)
  • ZeRO-2:优化器状态 + 梯度分片(显存节省约 8 倍)
  • ZeRO-3:全部参数分片(显存节省约 N 倍,N = GPU 数)
# DeepSpeed 配置
ds_config = {
    "zero_optimization": {
        "stage": 3,
        "offload_param": {"device": "cpu"},  # 显存不够时把参数放到 CPU
        "offload_optimizer": {"device": "cpu"}
    },
    "bf16": {"enabled": True}  # BF16 训练
}

如果放到面试里怎么讲

"SFT 和 RLHF 是什么关系?"

SFT 是用高质量指令数据做监督学习,让模型学会回答问题;RLHF 是用人类偏好数据做强化学习,让模型学会产生"更好的"回答。SFT 解决的是"怎么回答",RLHF 解决的是"什么算好回答"。通常的流程是先 SFT 再 RLHF。

"LoRA 为什么能省显存?"

LoRA 冻结原始权重,在旁边训练两个低秩矩阵 A 和 B。我只需要保存 A 和 B 的梯度 + 优化器状态,不需要保存整个模型的梯度。全参数 Fine-tuning 175B 模型需要 1.2TB 显存,LoRA 只需要约 350GB。

最后记几个点

  1. Pretraining 学语言规律,SFT 学遵循指令,RLHF/DPO 学人类偏好
  2. 全参数 Fine-tuning = SFT + 梯度;LoRA = 低秩矩阵 Fine-tuning,不需要梯度
  3. RLHF 需要 Reward Model + PPO,DPO 不需要,两者都在学习"什么算好回答"
  4. DPO 比 RLHF 简单稳定,但在复杂多维度对齐任务上不一定更好
  5. LoRA 节省显存,DeepSpeed ZeRO 分布式训练,两者可以叠加
  6. QLoRA = NF4 量化 + LoRA,65B 模型可在单张 A100(48GB)上 Fine-tuning
  7. 知识类问题用 RAG,风格/格式/行为类问题用 Fine-tuning

跨库关联

本文件是 LLM Fine-tuning 的概览视图,详细内容拆分到 大模型知识库 的各专题中: