Chapter 09

高级:DPO / 继续预训练 / 视觉模型

SFT 之外的三条进阶路线:用偏好数据对齐、往模型灌新知识、以及微调看得懂图的多模态模型。

9.1 名词地图

DPO(Direct Preference Optimization)
直接偏好优化。用"更好/更差"的成对回答训练模型偏好人类喜欢的输出,比 RLHF 简单、无需单独训奖励模型。
preference data(偏好数据)
形如 {prompt, chosen, rejected} 的三元组:同一问题下人类更喜欢 chosen、不喜欢 rejected。
RLHF
基于人类反馈的强化学习,经典对齐路线(先训奖励模型再 PPO)。DPO 是它的简化替代。
reward model(奖励模型)
给回答打分的模型,RLHF 中指导策略优化。DPO 把它隐式化,通常不需单独训练。
continued pretraining(继续预训练)
在大量领域无标注文本上继续训练,往模型灌入新知识/新语言,而非学指令格式。
catastrophic forgetting(灾难性遗忘)
学新知识时把旧能力忘掉。继续预训练要用小学习率、混入通用数据来缓解。
FastVisionModel
Unsloth 用于加载/微调视觉多模态模型(如 Llama 3.2 Vision、Qwen-VL)的入口,用法类比 FastLanguageModel。
beta(DPO 温度)
DPO 的关键超参,控制对参考模型的偏离程度。常用 0.1,越大越保守。

9.2 DPO 偏好对齐

SFT 教模型"怎么答",DPO 进一步教它"答得更让人满意"。前提是先做过 SFT,再用偏好数据 DPO。Unsloth 复用 TRL 的 DPOTrainer

from unsloth import FastLanguageModel, PatchDPOTrainer
PatchDPOTrainer()   # 打补丁启用 Unsloth 加速

from trl import DPOTrainer, DPOConfig

# 数据集需含 prompt / chosen / rejected 三列
dpo_trainer = DPOTrainer(
    model = model,
    ref_model = None,           # LoRA 下无需单独参考模型
    tokenizer = tokenizer,
    train_dataset = pref_ds,
    args = DPOConfig(
        per_device_train_batch_size = 1,
        gradient_accumulation_steps = 4,
        learning_rate = 5e-6,       # DPO 学习率比 SFT 小
        beta = 0.1,               # 偏好强度
        num_train_epochs = 1,
        bf16 = True,
        output_dir = "dpo_out",
    ),
)
dpo_trainer.train()

9.3 继续预训练

当你要让模型掌握一门它没见过的语言、或吸收大量领域文档知识时,用继续预训练。数据是纯文本(不是问答对),并建议同时给 embedding 和 lm_head 加 LoRA:

model = FastLanguageModel.get_peft_model(
    model,
    r = 128,
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                      "gate_proj", "up_proj", "down_proj",
                      "embed_tokens", "lm_head"],   # 继续预训练关键
    lora_alpha = 32,
    use_gradient_checkpointing = "unsloth",
)

# 用 UnslothTrainer + 纯文本数据,学习率很小
# learning_rate=5e-5, embedding_learning_rate=5e-6
小心灾难性遗忘

继续预训练用小学习率、并把一部分通用语料混进领域数据(如 1:1),否则模型学会新东西却忘了原本的通用能力。

9.4 视觉模型微调

Unsloth 也支持多模态模型微调,入口换成 FastVisionModel,数据里每条样本带图像 + 对话:

from unsloth import FastVisionModel

model, tokenizer = FastVisionModel.from_pretrained(
    "unsloth/Llama-3.2-11B-Vision-Instruct",
    load_in_4bit = True,
)

model = FastVisionModel.get_peft_model(
    model,
    finetune_vision_layers = True,     # 微调视觉塔
    finetune_language_layers = True,
    r = 16, lora_alpha = 16,
)

# 数据样本:{"image": PIL.Image, "messages": [...]}
# 训练用 SFTTrainer + UnslothVisionDataCollator
视觉微调的典型用途

让模型学会读特定领域的图(如报表 OCR、商品图打标、医学影像描述),或统一图文回答的风格。可选只微调语言层、只微调视觉层或两者都调。

9.5 三条路线怎么选

目标方法数据形态
学任务/风格/格式SFT(第 1-8 章)问-答对
让回答更符合偏好DPOchosen/rejected 成对
灌入新知识/新语言继续预训练纯文本
看懂图并回答视觉微调图 + 对话

9.6 小结与下一步