大模型训练全流程:预训练、SFT、RLHF与线上badcase修复

很多人把"训练模型"理解成"把业务知识喂给模型"。这个理解只对了一小半。

预训练解决的是能力底座:语言、知识、推理、代码、世界模型。后训练解决的是可用性:听懂指令、按格式输出、知道什么时候拒答、偏向人类喜欢的回答。RAG解决的是动态知识和可追溯事实。线上 badcase 修复,则是在这三者之间做取舍。

真正难的不是知道 SFT、RLHF、RAG 这些名词,而是判断一个问题该放到哪里修。

一、先把训练链路说清楚

大模型训练通常分成两段:预训练和后训练。

预训练让模型学会"世界长什么样"。它从大规模文本、代码、网页、书籍、论文、问答数据里学习下一个 token 的概率分布。这个阶段不要求模型成为一个好助手,只要求它在海量语料上形成语言、知识、模式和推理的基础能力。

后训练让模型学会"应该怎么帮人"。同样一个问题,预训练模型可能补全文本、可能胡说、可能不按格式、也可能不知道自己应该遵守系统指令。SFT、RLHF、DPO、RFT 这些方法,都是在把一个会续写的模型,推向一个能对话、能执行、能拒绝、能遵守偏好的助手。

阶段 核心问题 训练信号 结果
预训练 让模型获得通用语言、知识、代码和推理能力 大规模自监督语料,下一个 token 预测 基座模型
SFT 告诉模型"什么是正确示范" prompt + 标准答案 会按示例完成任务
RLHF / DPO 告诉模型"两个答案里哪个更像人想要的" 偏好对、奖励模型、偏好优化 更符合人类偏好
RAG 给模型注入当前、私有、可追溯知识 检索到的外部文档 回答更准确,可引用来源
评测回归 判断改动有没有真的变好 离线集、线上指标、人工评审 训练能闭环

关键判断:预训练塑造能力边界,后训练塑造行为倾向,RAG补充上下文事实。不要用后训练硬塞大量动态知识,也不要指望 RAG 改掉模型的稳定行为习惯。

二、预训练到底在解决什么问题

预训练的目标不是"记住所有答案",而是把语言和世界压缩进参数里。它学到的是一组可泛化的统计结构:词语关系、事实关联、代码模式、推理链条、文体风格、常见任务形式。

Llama 2 论文里提到,基座模型使用公开来源数据预训练,并通过数据清洗、数据配比、更多 token、更长上下文等方式提升模型能力。这里有一个容易被忽略的点:预训练阶段的数据规模很大,但数据配比和清洗同样重要。更多数据不是自动等于更好数据。

预训练主要解决四类问题:

  1. 语言建模:知道句子如何继续,知道不同语言、文体、领域文本的结构。
  2. 知识吸收:在参数里形成常识、事实、概念关系和领域知识。
  3. 能力涌现:代码生成、数学推理、摘要、翻译、问答等能力,很多来自大规模预训练的泛化。
  4. 表示学习:把文本映射到模型内部的高维表示,为后续指令对齐打基础。

但预训练不擅长解决三个问题:

  • 不知道用户真正想要什么:用户问"帮我总结",模型不知道应该短一点、分点、保留风险,还是写成报告。
  • 不保证事实最新:参数里的知识有时间边界,也很难低成本更新。
  • 不保证输出可控:JSON格式、固定字段、业务话术、安全拒答,这些都不是预训练的主要目标。

所以基座模型再强,也要经过后训练。否则它像一个读过很多书的人,但没有接受过岗位培训。

三、SFT:告诉模型"好答案长什么样"

SFT(Supervised Fine-Tuning,监督微调)是后训练的第一层。它用 prompt + 理想回答训练模型,让模型模仿高质量示范。

OpenAI 文档对 SFT 的定义很直接:提供正确回答示例,引导模型行为;常见场景包括分类、翻译、特定格式生成、修复指令遵从失败。这个定义很实用,SFT 本质上就是"示范学习"。

SFT 解决的不是主观偏好,而是可明确写出标准答案的问题。

适合 SFT 的问题 原因 样本形态
固定格式输出 有明确正确格式 输入 → 标准 JSON / Markdown / 表格
业务分类 标签集合稳定 用户问题 → 类别
信息抽取 答案可校验 文本 → 字段
标准话术 企业口径明确 场景 → 回复
工具调用模式 参数和步骤可标注 用户目标 → tool call
指令遵从失败 正解可示范 bad prompt → 正确回答

SFT 的样本应该像生产请求,而不是像考试题。

{
 "system": "你是企业客服助手。回答必须使用JSON,字段为answer、risk_level、next_action。",
 "user": "用户问:我已经退款了,为什么钱还没到账?",
 "assistant": {
 "answer": "退款已发起后,到账时间通常取决于支付渠道。银行卡一般需要1-5个工作日,余额支付通常更快。",
 "risk_level": "medium",
 "next_action": "查询退款单状态,并在无法确认时转人工"
 }
}

这条样本的关键不是"退款知识",而是同时示范了角色、格式、字段、语气和处理路径。

3.1 SFT 样本怎么构造

构造 SFT 样本要从线上任务倒推,而不是从模型能力倒推。

第一步:定义任务边界。
不要写"让模型更懂客服",而要写"当用户询问退款到账时间时,输出包含解释、风险等级和下一步动作的 JSON"。

第二步:收集真实输入。
线上问题、客服工单、搜索 query、用户追问、工具调用 trace,优先级高于人工幻想题。人工构造可以补边界,但不能替代真实分布。

第三步:写标准答案。
标准答案要符合最终上线格式。训练时是什么格式,推理时也应该是什么格式。OpenAI 的微调实践也强调,训练样本格式要和推理时保持一致。

第四步:做困难样本。
如果只训练干净问题,模型会在真实线上变形。样本里要有口语、错别字、缺字段、混合意图、上下文省略、越界请求。

第五步:保留测试集。
训练集只用于更新模型,测试集只用于评估。测试集不能被训练过程反复污染,否则上线前看到的"提升"大概率是幻觉。

3.2 SFT 怎样才容易收敛

SFT 不收敛,常见原因不是模型太差,而是样本在互相打架。

  • 标注不一致:同一个意图,有的样本输出JSON,有的样本输出自然语言。
  • 任务混杂:一批样本教客服问答,另一批样本教写营销文案,没有统一路由。
  • 负样本比例异常:训练集中60%都在拒答,线上真实拒答只有5%,模型会变得过度保守。
  • 输入缺信息但答案补了信息:用户没有提供订单号,标准答案却说"你的订单已退款",模型会学会编造。
  • 指令没有重复出现:小数据微调时,训练样本里没有稳定出现系统约束,模型只能从答案里猜规则。

经验上,先把数据质量做到 80 分,再谈数据量。Llama 2 论文有一个很有参考价值的结论:他们放弃了大量低质量第三方 SFT 数据,转向几万条更高质量的标注,效果反而更好。

超参上可以按这几个方向排查:

现象 可能原因 调整方向
训练集好,测试集差 过拟合 减少 epoch、增加多样性、扩大测试集
训练集也学不好 学习不足或样本冲突 增加 epoch / 学习率,先清洗冲突样本
输出变得死板 epoch 太多或样本太单一 减少 epoch,增加等价表达
格式仍然不稳 格式示范不足 增加格式边界样本,加入自动校验
幻觉变多 答案里含输入没有的信息 删除或改写这类样本

OpenAI 微调实践里也给出类似方向:模型没有按训练数据学到时,可以增加 epoch;输出多样性下降时,减少 epoch;不收敛时再考虑调大学习率。不要一上来就盲目加大训练轮数。

四、RLHF / DPO:解决"哪个答案更好"的问题

SFT 适合教标准答案,但很多线上问题没有唯一标准答案。

比如用户让模型写一封拒绝合作的邮件。两个答案都正确,一个更礼貌,一个更简洁,一个更符合公司调性。SFT 只能告诉模型"这是一个好答案",却很难告诉模型"这个答案比另一个更好"。

这就是 RLHF 和 DPO 的位置。

InstructGPT 的训练链路很经典:先收集人工示范做 SFT,再收集模型回答的排序数据训练奖励模型,最后用强化学习优化模型。论文里提到,小得多的 InstructGPT 在人工偏好上可以超过更大的 GPT-3,这说明"更会按人类意图回答"不完全等同于"参数更多"。

RLHF 解决的是偏好对齐:

用户问题:
 "帮我写一段接口报错文案,告诉用户系统繁忙。"

回答A:
 "系统繁忙,请稍后再试。"

回答B:
 "当前访问人数较多,服务响应变慢。你可以稍后重试,未完成的操作不会重复扣费。"

偏好标注:
 preferred: B
 rejected: A
原因:
 B解释了原因,降低用户焦虑,并补充了关键风险信息。

这类偏好很难写成固定标准答案,但很适合用 pairwise preference 学。

DPO 可以理解成更直接的偏好优化。它不一定需要先训练一个独立奖励模型,而是用 preferred / non-preferred 成对数据,让模型更偏向被选择的回答。OpenAI 的 DPO 文档也建议:先用 SFT 在理想回答上打底,再用 DPO 细调偏好。

4.1 格式异常能不能用 RLHF 修

可以,但要分情况。

如果是"模型完全不知道格式",优先 SFT。比如你要求输出:

{
 "answer": "...",
 "citations": [],
 "risk_level": "low|medium|high"
}

模型经常少字段、字段名写错、类型不对。这是标准答案明确的问题,应该先用 SFT 教格式,再用解析器和重试兜底。

如果是"模型知道格式,但在复杂场景下偶尔偏离",可以用偏好优化。

线上badcase:
 用户输入很长,包含多轮历史、表格和特殊符号。
 模型答案内容正确,但JSON最后多了一句解释,导致解析失败。

SFT样本:
 输入:长上下文 + 特殊符号 + 格式要求
 输出:严格合法JSON

DPO/RLHF样本:
 preferred_output:
 严格合法JSON,无额外解释
 non_preferred_output:
 JSON后面追加"以上是我的分析"

偏好原则:
 在内容相同的前提下,能被机器稳定解析的回答优先。

这种场景下,RLHF/DPO 不是在教模型"JSON是什么",而是在强化"不要为了显得更有帮助而破坏机器协议"。

关键判断:格式类问题先 SFT,后偏好优化。SFT 教会结构,RLHF/DPO 压住坏习惯。

五、线上 badcase 应该怎么修

线上 badcase 不能一股脑丢进训练集。先分类,再决定修复手段。

badcase 类型 典型表现 优先修复方式 是否进训练
格式异常 JSON 解析失败、字段缺失 SFT + 解析校验 + DPO
指令不遵从 要短答却长篇解释 SFT / DPO
事实过期 政策、价格、库存不准 RAG / 数据源修复 通常不进
私有知识缺失 不知道公司流程 RAG 通常不进
检索错误 引错文档、漏召回 RAG 检索链优化 不优先训模型
幻觉 输入无依据却编结论 SFT + RAG + 拒答样本 视原因
过度拒答 安全词误触发 DPO/RLHF + 边界集
语气不合适 太冷、太啰嗦、太像模板 DPO/RLHF
工具调用错误 选错工具、参数错 SFT + 工具评测
复杂推理失败 多约束任务算错 RFT / 任务拆解 / 工具化 视成本

5.1 一个 badcase 修复闭环

线上发现:
 订单退款场景下,模型偶尔输出自然语言,导致前端JSON解析失败。

归因:
 不是知识缺失。
 不是检索问题。
 是格式遵从在长上下文下不稳定。

修复:
 1. 从日志中抽取真实输入,脱敏。
 2. 标注严格JSON标准答案,加入SFT。
 3. 构造DPO偏好对:
 - preferred:合法JSON
 - rejected:内容正确但多解释/少字段/字段类型错误
 4. 增加离线评测:
 - JSON parse success rate
 - required fields coverage
 - answer correctness
 5. 小流量上线,观察解析失败率和用户满意度。

这里最关键的是第 3 步。很多团队只做 SFT,不做偏好对,结果模型知道标准格式,但在线上复杂输入里仍然会"好心多说两句"。这两句话在人类看来不严重,对系统却是事故。

5.2 什么时候不要训练

不是所有问题都值得训练。

  • 事实经常变化:价格、库存、政策、活动、接口状态。用RAG或工具查实时数据。
  • 问题来自检索召回:模型没有看到正确文档,训练模型只会让它更会猜。
  • 问题来自产品逻辑:系统没有传订单状态,模型无法凭空知道。
  • 问题来自输出后处理缺失:JSON解析失败应该有schema校验、自动修复或重试。
  • 样本只有几个孤例:先进入评测集观察,不要立刻污染训练分布。

训练是慢变量。RAG、工具、prompt、后处理是快变量。线上修复要先用快变量止血,再决定要不要沉淀到训练。

六、哪些放 SFT,哪些用 RAG

一个简单判断:

行为模式进 SFT,动态事实进 RAG。

SFT 改的是模型"习惯怎么做"。RAG 给的是模型"现在应该参考什么"。

需求 更适合 SFT 更适合 RAG
固定输出格式
企业语气和话术 可辅助
工具调用策略
退款政策原文
每日价格、库存、排班
私有文档问答 不优先
对边界问题的拒答习惯 可辅助
引用来源
少样本稳定分类
长尾知识覆盖

RAG 的原始论文指出,纯参数模型在访问和精确操纵知识上仍有限,更新世界知识和提供依据也是难题。AWS 对 RAG 的解释更工程化:RAG 让模型在生成前参考训练数据之外的权威知识库,不必重新训练模型。

这就是边界。

如果你的问题是"模型不知道公司报销制度",不要微调。把制度文档放进知识库,做好分块、召回、重排、权限和引用。

如果你的问题是"模型看到制度后仍然不按公司格式答",那才考虑 SFT。

6.1 SFT 和 RAG 可以一起用

实际生产里最常见的组合是:RAG 提供事实,SFT 规定行为。

用户问题:
 "我这种情况能报销打车费吗?"

RAG提供:
 1. 公司差旅制度第3.2条
 2. 用户所在部门的补充规则
 3. 最近一次制度更新时间

SFT训练出的行为:
 1. 先给结论
 2. 再引用依据
 3. 不确定时列出缺失信息
 4. 输出固定字段:conclusion、basis、missing_info、next_action

RAG 负责"答得有依据",SFT 负责"答得像产品需要的样子"。

七、样本怎么保证泛化,而不是背题

过拟合不是只发生在小模型上。大模型微调同样会背题,尤其是样本少、格式单一、答案模板过强时。

泛化要从样本设计开始。

7.1 训练集要覆盖变化维度

同一个任务,至少覆盖这些维度:

  • 输入变化
  • 短句、长句、多轮上下文
  • 口语、错别字、缩写、夹杂英文
  • 正常请求、边界请求、恶意请求
  • 信息完整、信息缺失、信息冲突
  • 输出变化
  • 同样格式下的不同表达
  • 不同风险等级
  • 可回答、需追问、需拒答
  • 有工具结果、无工具结果、工具失败
  • 场景变化
  • 高频主路径
  • 低频长尾
  • 历史badcase
  • 人工构造的边界压力样本

不要把 1000 条几乎一样的样本当成 1000 条有效样本。它们只会让模型更自信地背同一种模式。

7.2 训练集和测试集要按场景切分

随机切分有时会高估效果。比如同一个用户问题改写了 10 个版本,随机切分后,训练集和测试集都出现相似表达,测试分数会虚高。

更好的切分方式:

切分方式 适用场景 目的
按时间切分 线上日志 模拟未来请求
按用户/会话切分 多轮对话 防止同一会话泄漏
按意图切分 分类/客服 看新意图泛化
按模板族切分 格式输出 防止背模板
按难度分层 工具调用/推理 看边界能力

7.3 用"最小必要训练"保护能力

训练集不是越多越好,训练轮数也不是越多越好。一个模型被微调得太狠,会出现能力收缩:回答变短、拒答变多、创造性下降、通用问题变差。

Llama 2 的 RLHF 迭代里观察到过能力回退:某个版本在押韵诗歌能力上变差。后来他们把之前迭代中的优秀样本重新混入,缓解了这个问题。这对业务微调很有启发:不要只拿最新 badcase 训练,否则模型会被最近的问题牵着走。

  • 使用强基座:不要指望微调用小模型补出不存在的推理能力。
  • 控制训练强度:小学习率、少epoch、早停,比猛训更稳。
  • 混入保能力样本:保留通用问答、正常闲聊、核心业务主路径,防止模型只记得badcase。
  • 做能力回归集:除了业务指标,还测通用能力、拒答率、格式成功率、工具调用成功率。
  • 偏好优化别太激进:DPO/RLHF 的强度过大,容易把模型推向单一风格。
  • 只训练需要改变的行为:知识更新走RAG,系统约束走prompt,稳定行为再进训练。

OpenAI 的 DPO 文档里有一个 beta 超参,用来控制新模型多大程度保留原行为。这个思路可以抽象成一条工程原则:微调不是重塑模型人格,而是在尽量少破坏原能力的情况下,修正稳定缺陷。

八、训练数据的标准结构

真正可用的数据集,不只是 prompt 和 answer。它应该能支持训练、评测、归因和回滚。

{
 "id": "refund_format_0001",
 "source": "online_badcase / human_annotation / synthetic_edge",
 "scenario": "refund_status",
 "task_type": "structured_output",
 "input_messages": [
 {"role": "system", "content": "输出必须是合法JSON,字段为answer、risk_level、next_action。"},
 {"role": "user", "content": "我的退款怎么还没到账?"}
 ],
 "output": {
 "answer": "退款到账时间取决于支付渠道。银行卡一般需要1-5个工作日。",
 "risk_level": "medium",
 "next_action": "查询退款单状态;无法确认时转人工。"
 },
 "metadata": {
 "difficulty": "medium",
 "contains_pii": false,
 "expected_schema": "refund_answer_v2",
 "eval_tags": ["json_parse", "required_fields", "refund_policy"]
 }
}

DPO / RLHF 偏好样本则要保留 rejected 版本。

{
 "id": "refund_preference_0007",
 "input": "用户在长上下文后询问退款到账时间,要求JSON输出。",
 "preferred": {
 "answer": "退款到账时间取决于支付渠道。银行卡一般需要1-5个工作日。",
 "risk_level": "medium",
 "next_action": "查询退款单状态;无法确认时转人工"
 },
 "rejected": {
 "answer": "退款到账时间取决于支付渠道。银行卡一般需要1-5个工作日。",
 "risk_level": "medium"
 },
 "rejected_suffix": "以上是我的分析。",
 "preference_reason": "preferred 是合法JSON,字段完整;rejected 缺少 next_action,且追加了自然语言。",
 "tags": ["format_violation", "missing_field", "extra_text"]
}

偏好样本最怕只写"preferred 更好"。要写清楚为什么更好,否则标注员、训练者、评测者都会各自理解。

九、一套可落地的训练修复流程

把训练当成一个持续系统,而不是一次性项目。

9.1 从线上日志到训练集

  1. 采集:收集用户输入、模型输出、检索文档、工具调用、后处理错误、用户反馈。
  2. 脱敏:去掉手机号、身份证、订单号、地址、姓名等敏感信息。
  3. 聚类:按错误类型聚合:格式、事实、拒答、工具、语气、推理。
  4. 归因:判断是模型行为问题、知识问题、检索问题、工具问题,还是产品链路问题。
  5. 标注:SFT写标准答案;DPO/RLHF写偏好对;RAG问题修知识库。
  6. 评测:每类badcase进入离线回归集,设置硬指标。
  7. 小流量:先灰度,不要直接全量。
  8. 回滚:保留基座、数据版本、训练参数、评测结果,能复现也能回退。

9.2 评测指标要和 badcase 类型绑定

问题类型 核心指标 不能只看
格式异常 parse success rate、schema pass rate 人工感觉回答不错
事实问答 answer accuracy、citation precision 语言流畅度
拒答问题 false refusal rate、unsafe answer rate 拒答率越高越好
工具调用 tool selection accuracy、argument accuracy 最终答案是否像对
语气风格 pairwise win rate、投诉率 句子是否更长
推理任务 step accuracy、final accuracy、cost 单条样例成功

评测集也要分层:主路径、长尾、历史 badcase、对抗样本。上线前如果只测历史 badcase,很容易修好旧问题,引入新问题。

十、几个常见误区

10.1 把知识都塞进 SFT

公司政策、商品价格、活动规则、接口状态,这些都可能变化。放进 SFT 会有两个问题:更新慢,难追溯。更好的方式是 RAG 或工具查询。

10.2 用 SFT 修所有主观偏好

"更自然一点""别那么啰嗦""多解释风险""不要像客服模板",这些是偏好问题。可以用 SFT 打底,但最终通常要靠偏好数据。

10.3 只训练正例,不训练边界

模型在线上最容易出问题的地方,往往不是主路径,而是信息缺失、规则冲突、用户输入很乱的时候。没有边界样本,模型只会在演示环境里稳定。

10.4 用训练代替系统工程

格式输出不能只靠训练。应该同时有 schema 约束、解析校验、失败重试、降级策略。训练能降低错误率,但不能替代工程护栏。

10.5 每次 badcase 都立刻训练

单个 badcase 可能是偶然采样、上游数据缺失、提示词冲突,也可能是检索失败。先归因,再决定是否进入训练。否则训练集会越来越脏。

十一、最后给一张决策表

当线上出问题时,可以按这张表快速判断。

你看到的问题 先问自己 优先方案
模型不知道某个事实 这个事实会不会更新? 会更新就 RAG / 工具
输出格式错 标准格式是否明确? 明确就 SFT + 校验
内容正确但不够好 是否存在主观偏好? DPO / RLHF
模型过度拒答 是否安全边界标错? 偏好样本 + 边界评测
引用了错误文档 模型是否拿到了正确上下文? 优先修检索
工具参数错 参数规则能否标注? SFT 工具调用样本
复杂题推理错 是否需要外部计算? 工具化 / RFT / 任务拆解
新版本通用能力下降 是否训练太集中? 减少训练强度,混入保能力样本

一句话总结:SFT 负责"示范正确做法",RLHF/DPO 负责"压住偏好问题",RAG 负责"提供当前事实",评测负责"证明没有把别的能力弄坏"。

训练不是把 badcase 堆进模型,而是把错误变成可复用的行为规则、偏好约束和评测资产。做对了,模型会越来越稳定;做错了,模型只是越来越像训练集。

参考资料

  1. OpenAI, Training language models to follow instructions with human feedback
  2. Meta AI, Llama 2: Open Foundation and Fine-Tuned Chat Models
  3. OpenAI Docs, Model optimization
  4. OpenAI Docs, Supervised fine-tuning
  5. OpenAI Docs, Fine-tuning best practices
  6. OpenAI Docs, Direct preference optimization
  7. Rafailov et al., Direct Preference Optimization: Your Language Model is Secretly a Reward Model
  8. Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
  9. AWS, What is RAG?
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐