PAYATHON 2026

如何选择合适的 LLMs fine-tuning 方法?

技术老齐

先用 SFT 配合 LoRA 建立基线,再根据评估结果调整

如果已有经过审核的“输入与理想输出”数据,可以先尝试监督微调(SFT)配合 LoRA;显存受限时,再考虑 QLoRA。是否采用全参数微调,要结合数据规模、训练预算和对照实验结果判断。

选择训练方案时,需要区分两个问题:

  • SFT、持续预训练、DPO 等方法,决定模型从什么训练信号中学习。
  • LoRA、QLoRA、全参数微调,决定训练哪些参数,以及如何控制资源开销。

两者可以组合,例如“用 LoRA 做 SFT”。任何组合都不能自动保证模型能处理边界情况或实现跨领域泛化,这些能力仍需通过数据设计和独立测试验证。

根据当前问题选择训练方法

当前主要问题优先考虑适用前提与限制
输出格式不稳定、任务流程不符合要求SFT有一致、可靠的输入与目标输出
显存有限,希望先验证微调是否有效LoRA;资源更紧张时考虑 QLoRALoRA 冻结基础权重并训练低秩适配器;QLoRA 在量化基础模型上训练适配器
有大量领域文本,但缺少问答标注持续预训练,再按需要做 SFT可以帮助模型适应领域文本分布,但不直接教会它按任务要求作答
模型已能完成任务,但回答质量或偏好不理想DPO 等偏好优化方法需要可信的优选与劣选回答对,不能代替事实核查
需要回答经常变化、可追溯的业务知识先评估 RAG可与微调组合;检索质量仍会影响回答
适配器实验未达目标,且数据和算力充足对照测试全参数微调训练开销更高,也需要检查原有能力是否退化

先看模型实际错在哪里。知识缺失造成的错误,未必能靠增加训练轮数解决;数据中的答案互相矛盾,换用更大的模型也解决不了标注问题。

先把数据和评估设计好

1. 按真实使用场景划分数据

先划分训练集、验证集和测试集,再做数据增强。划分时要检查近重复内容,避免把同一文档的段落、同一用户的相似对话,或同一题目的改写版本分到不同集合。

具体怎么划分,取决于想验证什么能力:

  • 验证对新客户的适应能力,按客户或组织分组。
  • 验证对未来数据的适应能力,按时间留出数据。
  • 验证跨领域泛化,留出训练中未出现的领域。
  • 验证跨任务泛化,留出整个任务类型,仅留出同一任务中的部分样本不足以验证这项能力。

随机切分得到的分数,通常不足以证明模型能够处理新领域或新任务。

2. 为边界情况标注正确行为

根据基线模型的失败样例整理错误类别,例如信息不足、条件冲突、异常格式、超长输入,以及超出任务范围的请求。

每类数据都要明确模型该怎么做。信息不足时,是追问、返回空值,还是说明无法判断?标注中的处理方式必须一致。

可以适当提高少见但重要样例的采样比例,同时保留接近真实分布的普通样例。反复使用少量边界样例,可能让模型记住措辞,或在正常输入上频繁拒答。

使用合成数据时,要检查答案是否正确,并与测试数据隔离。如果样本只改了措辞,没有引入新条件或新错误类型,对覆盖边界情况的帮助就有限。

3. 控制多任务和多领域数据的比例

直接拼接不同领域的数据,容易让样本最多的领域主导训练。应根据目标场景设置采样比例,并分别观察各任务、各领域的结果。

如果希望保留模型已有能力,可以混入经过审核、使用权限明确的通用任务数据。具体混入多少,要通过实验判断;这样做也不能保证完全消除灾难性遗忘。

用小规模实验决定后续投入

先记录未微调模型在固定提示词下的表现,再训练第一个 LoRA 基线。比较时,保持测试集、提示模板和生成参数一致。

根据实际用途选择评估指标:

任务可以观察的指标
分类Macro-F1、各类别召回率、混淆矩阵
信息抽取字段级准确率、缺失率、格式合法率
问答或生成正确性、指令遵循情况,以及人工抽样审核
边界情况各错误类型的通过率、误拒答率
泛化能力未见领域、未见任务上的独立结果

普通样例、边界样例和领域外样例的结果应分别报告,避免总体平均分掩盖局部退化。

实验中要控制变量:

  1. 固定数据和基础模型,建立可复现的基线。
  2. 分别调整学习率、训练步数、LoRA rank 或数据比例。
  3. 定期检查验证结果,保存业务指标更好的 checkpoint。
  4. 确定方案后,再用测试集做最终评估。

学习率、训练轮数和 LoRA rank 都没有通用的最优值。训练损失持续下降时,泛化能力也可能下降。如果验证表现变差,应检查是否存在过拟合、数据重复、标注噪声或训练分布偏移。

代码示例:为因果语言模型接入 LoRA

使用 Hugging Face Transformers 和 PEFT 接入 LoRA,需要本地已有兼容的模型文件。这个最小示例还要求模型注意力层包含名为 q_proj 和 v_proj 的模块。

from transformers import AutoModelForCausalLM
from peft import LoraConfig, TaskType, get_peft_model

model_path = "/path/to/local/model"

model = AutoModelForCausalLM.from_pretrained(
    model_path,
    local_files_only=True,
)

target_modules = ["q_proj", "v_proj"]
module_names = {
    name.rsplit(".", 1)[-1]
    for name, _ in model.named_modules()
}

missing = set(target_modules) - module_names
if missing:
    raise ValueError(f"Target modules not found: {sorted(missing)}")

# 示例配置,不代表适合所有模型或数据集。
lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    r=8,
    lora_alpha=16,
    lora_dropout=0.05,
    target_modules=target_modules,
    bias="none",
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

不同架构的模块名称可能不同,需要先检查 model.named_modules(),再确定适配位置。示例参数只是实验起点,这段代码只接入了适配器,尚未执行训练。运行前,还需确认所安装的库与模型实现兼容。

对话 SFT 数据可以保留角色结构,例如:

{
  "messages": [
    {"role": "user", "content": "请提取订单编号;缺失时返回 null。"},
    {"role": "assistant", "content": "{\"order_id\": null}"}
  ]
}

训练前,需要用与模型匹配的 chat template 将数据序列化。如果只监督 assistant 回答,应将其他位置以及 padding 对应的 labels 设为 -100,让损失函数忽略这些位置。训练框架是否自动处理这一步,取决于具体配置,不能仅凭数据中有 messages 字段判断。

训练和部署时容易遗漏的细节

  • 检查截断后的样本。目标回答被截断,或输入中的关键条件丢失,都会改变训练含义。
  • 保持训练与推理时的角色标记、提示模板和特殊 token 一致。
  • QLoRA 需要正确配置量化加载、计算精度及训练准备流程。仅把权重转成低精度,还没有完成 QLoRA 所需的配置。
  • 保存数据版本、基础模型标识、随机种子和训练配置。部署适配器时,使用匹配的基础模型。
  • 对指标接近的候选方案重复实验,判断收益是否稳定。最终方案应同时满足任务质量、边界情况表现和资源约束。

如果跨领域或跨任务测试出现退化,应先分析具体失败类别,再调整数据覆盖和采样比例。增加参数量或延长训练时间,都不能替代对失败原因的分析。

备注:内容仅供参考。