Lecture 3 · 指令微调 · Instruction Tuning

Prompt Engineering · Lecture 03。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:CMU 17-630 Prompt Engineering(Prof. Travis Breaux),第 2 周的第二个主题 · Instruction Tuning。原课 Schedule 对这一讲的说明(意译):微调语言模型以提高它的任务学习能力;指令微调带来的性能提升、微调数据集的各种变体,以及微调效果在不同模型之间的可迁移性。 依据说明:原课的 slides 和阅读清单不公开。Schedule 点名的三个方面——性能提升、数据集的变体、跨模型的可迁移性——分别对应 §3、§5 和 §8.3。材料来自这条路线上的原始论文:FLAN(Wei et al. 2022)、T0(Sanh et al. 2022)、Natural Instructions / Super-NaturalInstructions(Mishra et al. 2022;Wang et al. 2022)、FLAN 2022(Chung et al. 2022;Longpre et al. 2023)、InstructGPT(Ouyang et al. 2022)、Self-Instruct(Wang et al. 2023)、Alpaca(Taori et al. 2023)、LIMA(Zhou et al. 2023)等;引用时按原文的说法转述结论,具体数字以原文为准。全部实验是本讲义自己设计的,不代表课堂上讲了什么。 配套代码 Code:code/lecture03/(PyTorch CPU;1 个模块 + 6 个脚本;不需要 API key;在第 1 讲的迷你 GPT 上做真正的指令微调,每个模型约 6 秒,训练好的模型缓存在 checkpoints/;02 号脚本第一次运行约 2 分钟,其余都在 1 分钟以内) 预计阅读时间:4 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

学完这一讲,你应该能够:

  1. 解释 base 模型为什么不听指令,以及指令微调(instruction tuning / 监督微调 SFT)具体改变了什么:数据格式、对话模板、只在回答上算损失。
  2. 讲出指令微调的主要路线——FLAN、T0、Super-NaturalInstructions、FLAN 2022——以及它们发现的规律:任务的种类、模板的多样性、模型的规模各起什么作用。
  3. 用”预训练学知识,指令微调学怎样用知识”这句话解释实验结果,并说出它的证据和边界(表面对齐假说)。
  4. 比较几种微调方法(全量、混入预训练数据、只训练少量参数),理解遗忘与对齐税,知道为什么”数据少而窄时要防止模型背数据”。
  5. 知道指令数据可以从哪里来(人写、模型写、真实对话),以及数据的质量、覆盖面和数量哪个更要紧。
  6. 讲清 InstructGPT 的三步(SFT → 奖励模型 → PPO),以及 RLHF 在 SFT 之上又改变了什么。
  7. 理解对话模板和系统提示是一种”文档格式”,知道模板用错会怎样。
  8. 说出指令微调怎样改变了第 2 讲的结论(零样本变强、少样本收益变小、更依赖语义先验),以及这对写提示意味着什么。

0.2 先修与本讲范围 Prerequisites & scope

默认你已经会 Assumed本讲只给直觉,后面再展开 Previewed only
第 1 讲:base 模型在续写文档;迷你 GPT 的结构和训练循环;§9 对 InstructGPT、chat 模板的简介RLHF 的副作用:幻觉与校准(第 5 讲)、谄媚(第 6 讲)
第 2 讲:上下文学习、标签词、语义先验(Wei et al. 2023)思维链数据与推理模型(第 4 讲)
前置讲 P1(token、词表)、P2(chat 消息格式、系统提示)、P3(多个种子、配对比较)指令层级与提示注入(第 12 讲);Constitutional AI(第 16 讲)
交叉熵损失、梯度下降、学习率的意思奖励模型与 PPO 的数学(本讲只讲流程)

0.3 本讲地图 Map

§1  为什么 base 模型不听指令
§2  指令微调是什么:数据格式、对话模板、只在回答上算损失;微调前后                ← 代码 01
§3  任务的多样性:FLAN、T0、Super-NI、FLAN 2022;种类、模板与规模                   ← 代码 02、03(演示 3)
§4  怎样微调:背数据 vs 学回答;遗忘与对齐税;只训练一点点参数                      ← 代码 03(演示 1–2)、01(演示 3)
§5  数据从哪里来:人写、模型写(Self-Instruct、Alpaca)、少而精(LIMA)             ← 代码 02(演示 3)、05
§6  InstructGPT:从 SFT 到 RLHF
§7  对话模板与系统提示                                                             ← 代码 01(演示 4)、04(演示 1–2)
§8  指令微调怎样改变提示工程;跨模型的可迁移性                                       ← 代码 04(演示 3)、06(可选)
§9  小结   §10 常见误区   §11 练习   §12 延伸阅读   §13 下一讲预告

0.4 记号与术语 Notation & terms

术语本讲义里的意思
指令微调 / 监督微调(instruction tuning / SFT)用”指令 → 回答”的样本继续训练一个预训练模型。本讲把两个词当同义词用(严格说 SFT 是更一般的”有监督地微调”)
指令(instruction)用自然语言写的任务描述或请求,如 “name the capital of volel .”
对话模板(chat template)把一轮或多轮对话写成一段文本的格式,用特殊标记区分说话的角色
系统提示(system prompt)对话开头、由开发者给出的指令,通常规定整场对话的规则和风格
回答损失(response-only loss)只在回答部分的 token 上计算交叉熵,提示部分不算
replay / 混入预训练数据微调时每一步也训练一点原来的预训练语料,减少遗忘
对齐税(alignment tax)为了对齐(听指令、无害)而在别的能力上付出的代价,例如原有任务的性能下降
RLHF基于人类反馈的强化学习:用人类偏好训练奖励模型,再用强化学习优化模型

0.5 本讲的实验装置 · The setup

我们在第 1 讲训练的迷你 GPT(base 模型,约 26 万个参数)上做一次真正的指令微调。

对话模板。仿照真实模型,规定对话写成这样一段”文档”:

<doc> <system> answer briefly <end> <user> what is the capital of volel ? <end> <assistant> grorken <end>

<system>、<user>、<assistant>、<end> 是 base 模型的词表里没有的新标记;指令里还会出现 name、tell、which 等它没见过的词。所以微调之前要扩展词表:原来的 290 个词保持原编号和原权重,后面追加 28 个新词,新词的嵌入初始化为旧词嵌入的平均(instruct_lab.extend_model)。

任务。7 种任务,每种 6 种问法(前 4 种用来训练,后 2 种只在测试”没见过的问法”时用):

任务例子(第 1 种问法)预训练里被”问”过吗
capital 首都what is the capital of {国家} ?是(问答页)
language 语言what language do people speak in {国家} ?是
export 出口what is {国家} known for ?是
leader 领导人who leads {国家} ?是
region 方位where is {国家} ?否(只在百科里有 “X lies in the east” 这样的陈述句)
revcap 反查首都which country has the capital {首都} ?否(只有 “K is the capital of X”)
sentiment 情感is this review positive or negative ? {评论}否(但评论页里有 rating)

国家的划分——这是整个实验设计的关键。第 1 讲的世界有 24 个国家:16 个的知识以问答页的形式出现在预训练语料里,8 个只出现在百科词条里。指令微调的数据只用前一组里的 12 个国家;测试用那 8 个只在百科里出现过的国家。所以测试题里的每一个事实,模型都只在预训练的百科里读到过,从没在指令微调里见过。在它们上答对,说明指令微调教会的是”怎样回答”,知识来自预训练。

默认配方:7 种任务、1200 条样本、4 种问法;全量微调 400 步,学习率 1e-3;只在回答上算损失;每一步混入半个批量的预训练语料(§4)。一次训练在 CPU 上约 6 秒。


1. 为什么 base 模型不听指令 · Why base models don’t follow instructions

第 1 讲 §9.1 列过 base 模型作为产品的三个问题:不听指令、会编造、会说不该说的话。这一讲处理第一个。

回忆 base 模型在做什么:它在续写文档。一个指令(“Summarize the following article.”)在它看来是一段文档的开头,最可能的续写取决于”网上什么样的文档以这句话开头”——可能是一篇教人写摘要的文章,可能是一份作业题目列表,未必是一篇摘要。第 1 讲 §8.3 的迷你 GPT 就是这样:问它一个问题,它接着出了五道题。

GPT-3 时代的解决办法是伪装:把提示写成”你想要的回答会自然出现在后面”的那种文档开头(Q: … A:、TL;DR:、少样本示例)。第 2 讲整整一讲都在讨论这种伪装有多脆弱:换个标签词、换个顺序,结果就变。

指令微调换了一个思路:与其每次都伪装成模型熟悉的文档,不如教模型熟悉一种新的文档——“有人提出请求,接着是对这个请求的回应”。教会之后,任何请求都可以直接写出来。

这个思路有两个层次的问题,本讲依次回答:

  1. 它教会了模型什么? 是新的知识、新的能力,还是只是”怎样回应”?(§2–§5)
  2. 要教会它,需要什么样的数据、怎样训练? 多少任务、多少模板、多少条、谁来写、要不要人类偏好?(§3–§6)

2. 指令微调是什么 · What instruction tuning is

配套代码:01_base_vs_sft.py 演示 1–2

2.1 数据、模板与损失

指令微调的训练数据是一批”指令 → 回答”对。每一对用对话模板写成一段文本(§0.5),然后像预训练一样,用”预测下一个 token”的交叉熵训练——只有一处不同:损失只算在回答的 token 上:

LSFT(θ)=−∑(x,y)∑t=1∣y∣log⁡Pθ(yt  ∣  模板(x), y<t)\mathcal{L}_{\text{SFT}}(\theta) = -\sum_{(x, y)} \sum_{t=1}^{|y|} \log P_\theta\big(y_t \;\big|\; \text{模板}(x),\, y_{<t}\big)

xx 是指令(连同系统提示和模板标记),yy 是回答。提示部分的 token 照样输入模型,只是它们的预测不计入损失。直觉上:我们要模型学会”看到这样的请求,写出这样的回答”,而不是学会”写出这样的请求”。(§4.2 会测这个选择到底影响多大。)

实现上的几个细节(instruct_lab.sft):一批样本长短不一,在右边用 <pad> 补齐;补齐的位置和提示部分的标签都设成 −100,cross_entropy(ignore_index=-100) 会跳过它们。因为是因果注意力,右边补齐不会影响前面的位置,不需要额外的遮罩。

2.2 微调前后

用测试国家(只在百科里出现过)问 7 种任务,比较三种情形(每种任务 8 个国家 × 4 种问法 = 32 道题;情感任务 60 条评论 × 4 种问法):

任务base · 对话格式base · 为它”伪装”的原生格式SFT · 对话格式(4 种问法)
capital0.0%100.0%100.0%
language0.0%100.0%100.0%
export0.0%87.5%90.6%
leader0.0%87.5%90.6%
region0.0%100.0%78.1%
revcap0.0%100.0%90.6%
sentiment0.0%100.0%99.6%

(“原生格式”是第 1 讲 §8.3 的技巧:国家问题写成问答页 <doc> faq : q : … ? a :,方位和反查首都借百科的句式 X lies in the、K is the capital of,情感写成评论页 … rating :。它只用一种写法,而且是为每种任务分别设计的。)

三列讲了一个故事:

  1. base 模型完全不会用对话格式(全部 0%)。对它来说 <user>、<assistant> 只是几个从没见过的词。具体看它的续写:tell me the capital of volel . 被续写成 is ruled by kiro .——它把 volel 后面接成了一句百科。
  2. 知识一直都在。同一个 base 模型,换成它熟悉的文档开头,几乎每种任务都能答对。
  3. 指令微调换来的是一个统一的、不需要伪装的接口。同一个 SFT 模型,4 种不同的问法、一种对话格式,就能取出这些知识——而测试国家一个都没出现在微调数据里。在 region 和 revcap 上,它甚至比精心伪装的原生格式还低一点(78.1%、90.6% vs 100%)。

所以,至少在这个实验里,指令微调没有增加知识,它增加的是”可访问性”:让模型用一种固定的、人类自然的方式接受请求。这是本讲反复出现的主题。


3. 任务的多样性:从 FLAN 到 FLAN 2022 · Task diversity

配套代码:02_task_diversity.py;03_how_to_finetune.py 演示 3

3.1 一条研究路线

2021–2022 年,几个团队几乎同时提出了指令微调,路线各有侧重:

  • FLAN(Wei et al. 2022,《Finetuned Language Models Are Zero-Shot Learners》):把 62 个现成的 NLP 数据集按任务类型分成 12 个任务簇,每个数据集人工写 10 个自然语言模板,在 1370 亿参数的模型上微调。评估时整簇留出:例如测自然语言推理时,所有推理数据集都不参与训练。FLAN 的零样本表现在他们评估的 25 个数据集中的 20 个上超过了零样本的 1750 亿参数 GPT-3。
  • T0(Sanh et al. 2022):同样的想法,用众包收集了大量提示模板(Public Pool of Prompts),在 110 亿参数的 T5 上微调;在很多留出任务上超过了大它十几倍的 GPT-3。
  • Natural Instructions / Super-NaturalInstructions(Mishra et al. 2022;Wang et al. 2022):不再只写简短的模板,而是给每个任务写完整的任务说明(定义、正例、反例);Super-NI 收集了 1600 多个任务。
  • FLAN 2022(Chung et al. 2022,《Scaling Instruction-Finetuned Language Models》;Longpre et al. 2023,Flan Collection):把任务数扩到 1800 多个,混入思维链数据和少样本模板,在 5400 亿参数的 PaLM 上微调(Flan-PaLM),并发布了 Flan-T5 系列。

这些工作共同发现了几条规律:

  1. 任务的种类越多,没见过的任务越好(FLAN 的消融:训练用的任务簇越多,留出簇上的表现越好)。
  2. 模板的多样性很重要:同一个任务用多种说法训练,模型才学到”请求”这个抽象概念,而不是某个固定句式。
  3. 规模是前提:FLAN 发现,在约 1000 亿参数的模型上指令微调大幅改善了留出任务,在 80 亿参数及以下的模型上反而让留出任务变差——小模型的容量都被训练任务占满了。
  4. 混合格式:Longpre et al.(2023)发现,训练时混入零样本、少样本、思维链等多种格式的模板,能同时改善这些提示方式下的表现。

3.2 在迷你模型上:训练任务的种类

固定 1200 条样本,训练任务从 1 种增加到 6 种,测一个从没出现在微调数据里的任务:领导人(它在预训练的问答页里被问过)。每种设置用 3 个数据种子各训练一次:

训练任务领导人(平均)3 个种子首都(平均)
1 种:capital8.3%6 / 12 / 6100.0%
2 种:+ sentiment7.3%6 / 9 / 680.2%
4 种:+ language, export17.7%19 / 22 / 1292.7%
6 种:+ region, revcap24.0%19 / 25 / 2899.0%
  • 只用首都一个任务时,问领导人几乎都得到一个首都名(有时还停不下来):模型学到的是”这个格式 → 写一个首都”,没有真的读问题。
  • 任务种类多了,“猜一个任务、套它的答案”不再管用,留出任务从 8% 升到 24%。方向和 FLAN 一致。
  • 但提升有限:在训练数据里有领导人任务时,它是 72%–91%(§5.3)。4 种任务的模型面对领导人问题时常常给出空回答:它认得这是一个请求,却不知道该用哪种答案。
  • 种子之间的波动不小(4 种任务:19 / 22 / 12)。只训练一次就下结论,很容易把运气当成规律。

我们的迷你模型只有 26 万个参数,按 FLAN 的规模规律,它本该从”多任务”里得不到什么好处。它之所以还能看到一点效果,是因为测试任务的知识和问法都在预训练里出现过;真正”没见过”的任务,它完全泛化不了(下一节)。

3.3 预训练里从没被”问”过的任务

方位和反查首都在预训练里只以陈述句出现过(“volel lies in the east”、“grorken is the capital of volel”),从没被”问”过:

训练任务方位反查首都
capital, language, export, sentiment0.0%0.0%
+ region, revcap(只用 12 个 SFT 国家的例子)84.4%90.6%

没训练过时完全不会;在指令数据里见过这种任务(哪怕只是另外 12 个国家的例子),测试国家就答到 84%、91%。这些国家的方位和首都,模型只在预训练的百科里读到过。

这给”预训练学知识、指令微调学怎样用知识”一个更精确的含义:指令微调为每一类问题建立一条”从问题到知识”的通道。通道要靠训练数据里这类问题的例子来建;通道建好之后,另一头连着什么,由预训练决定。大模型的不同之处在于,它从海量的预训练数据里已经学到了很多”类似的通道”,所以能把指令微调泛化到真正没见过的任务类型上——这是 §3.1 里”规模是前提”的一种解释。

3.4 问法的多样性

同样 1200 条样本,每种任务只用第 1 种问法训练,还是用 4 种问法训练(03 号脚本演示 3;6 种国家任务的平均,测试国家):

训练用的问法测试:第 1 种问法第 2–4 种没见过的第 5–6 种
只用第 1 种83.3%13.9%1.0%
4 种(默认)91.7%91.7%61.5%

只用一种问法训练,换个问法就几乎全错:模型学到的是”这个句式 → 这种答案”。用 4 种问法训练,连训练时没见过的第 5–6 种问法也有 61.5%。这就是 FLAN 每个数据集写 10 个模板、T0 收集大量众包提示的原因。

对提示工程的启示:一个指令微调过的模型,对它训练分布里常见的问法最可靠。你的提示越”奇特”(罕见的句式、生造的格式),越可能落在它的训练分布之外。


4. 怎样微调:背数据 vs 学回答 · How to fine-tune

配套代码:03_how_to_finetune.py 演示 1–2;01_base_vs_sft.py 演示 3

4.1 同样的数据,四种训练方法

同样 1200 条数据(7 种任务),四种训练方法。在三组国家上分别测:微调数据里出现过的 12 个(SFT 国家)、预训练问答页里见过但不在微调数据里的 4 个(近邻国家)、只在百科里出现过的 8 个(测试国家):

配方SFT 国家近邻国家测试国家原生问答格式预训练困惑度
全部参数 · 混入预训练语料(默认)100.0%100.0%91.7%99.0%1.89
全部参数 · 不混入100.0%54.2%45.3%62.5%131.23
全部参数 · 不混入 · 学习率 3e-4100.0%85.4%66.7%85.4%10.72
只训练新词的嵌入(28 行)96.5%96.9%90.1%97.9%4.83

(国家任务是 6 种任务 × 4 种问法的平均;“原生问答格式”和”困惑度”用第 1 讲的格式和预训练验证集测,base 模型是 97.9% 和 1.889。)

这张表是本讲最重要的结果之一:

  1. 全量微调、不混入预训练数据,模型会背数据。SFT 国家 100%,测试国家只有 45.3%:它把微调数据里那 12 个国家的事实背了下来,却没学会”去预训练的知识里找答案”。同时困惑度从 1.89 涨到 131,原生问答格式从 97.9% 掉到 62.5%——它忘掉了很多东西。
  2. 更新越”温和”,泛化越好。学习率小 3 倍,测试国家 66.7%;每一步混入预训练语料,91.7%。
  3. 最温和的方法:只训练新加的 28 个词的嵌入,原有的约 26 万个参数一个都不动。测试国家 90.1%,原生问答格式和 base 一样(97.9%)。<user>、<assistant> 这几个标记学到的嵌入,相当于一段软提示(soft prompt):它们把”对话格式”翻译成了模型本来就懂的那种文档。它的困惑度(4.83)仍比 base 高,原因不是旧知识被改了,而是新词的嵌入同时就是输出层的一行(权重共享),模型开始在普通文本里也给 <end> 之类的新词分一点概率。

真实世界里有完全对应的做法:

  • 提示微调(prompt tuning,Lester et al. 2021)只训练几十个”虚拟 token”的嵌入,模型参数冻结。他们发现模型越大,它越接近全量微调的效果。
  • 参数高效微调(如 LoRA,Hu et al. 2022)只训练很少的附加参数。
  • 全量微调时,小学习率、少步数、混入预训练数据,都是常用的防遗忘手段。

迷你模型给出的经验是:微调数据越少、越窄,越要防止模型”背数据”。大模型的指令微调数据有几万到几百万条、覆盖成千上万种任务,背不下来,问题没这么尖锐;但用一小份领域数据做微调时(例如公司内部的问答),这正是最常见的失败。

4.2 只在回答上算损失吗

损失测试国家(训练过的问法)没见过的问法原生问答格式
只算回答(默认)91.7%61.5%99.0%
提示和回答一起算89.1%65.6%100.0%

在迷你模型上差别很小,远小于 §4.1 的配方差别。多数指令微调(InstructGPT 的 SFT、Alpaca 等)只在回答上算损失;也有研究发现,数据很少时,提示上的损失有一点正则化的作用。这是一个值得在自己的数据上试一试、但不必太纠结的选择。

4.3 遗忘与对齐税

§4.1 的困惑度一列说明了一件事:微调让模型适应新格式的同时,可能损害它原有的能力。InstructGPT(Ouyang et al. 2022)把这叫作对齐税(alignment tax):他们发现,用 RLHF 对齐之后,模型在一些公开 NLP 基准上的表现下降了。他们的修正方法叫 PPO-ptx:在强化学习的目标里加上预训练分布上的语言模型损失——和我们的”混入预训练语料”是同一个思路。迷你模型上,混入之后困惑度几乎没变(1.885 vs base 的 1.889),原生问答格式甚至略高(99.0%)。

对提示工程师来说,对齐税有一个实际含义:一个经过重度对齐的 chat 模型,在某些”续写”式的用法上可能不如它的 base 版本(例如生成多样化的文本、按某种文风续写)。这也是一些团队同时提供 base 和 instruct 两个版本的原因。


5. 数据从哪里来 · Where instruction data comes from

配套代码:02_task_diversity.py 演示 3;05_self_instruct.py

5.1 三种来源

  1. 改写现成的数据集(FLAN、T0、Super-NI):把分类、问答、翻译等数据集套上自然语言模板。量大、任务多,但风格偏”考试题”,和真实用户的请求不太像。
  2. 人写(InstructGPT):雇标注员为真实的用户提示写示范回答。InstructGPT 的 SFT 数据大约是 1.3 万条提示的示范;质量高,但贵。
  3. 模型写:
    • Self-Instruct(Wang et al. 2023):从 175 个人写的种子任务出发,让 GPT-3 自己生成新的指令和回答,过滤掉格式不对的、和已有指令太像的(ROUGE-L 相似度 > 0.7),得到约 5 万条指令;用它微调 GPT-3 本身,在 Super-NI 上比原模型提高了约 33 个百分点,接近 InstructGPT-001。
    • Alpaca(Taori et al. 2023):用 Self-Instruct 的方法,让 text-davinci-003 生成 5.2 万条数据,微调 LLaMA-7B,花费不到 600 美元,得到一个像样的指令跟随模型。
    • 用真实的对话记录(Vicuna 用了 ShareGPT 上用户分享的 ChatGPT 对话)。

5.2 在迷你模型上让它自己写

让 base 模型从 <doc> faq : q : 开始,温度 1 采样 300 个问答页,抽出所有”问题 ? 答案”对:

项目数量
抽出来的问答对1000
能解析成 4 种已知问题之一996(答案正确 99.2%)
涉及的国家17 个(其中 1 个是测试国家 bronda,这条不用于训练)
去重之后72
  • 它写的问答对几乎全对:它在复述自己预训练里学到的东西。
  • 但 1000 对里绝大多数是重复的,去重之后只剩 72 条。模型反复写它最熟悉的那几个问题——Self-Instruct 的过滤步骤就是为了对付这个。
  • 它只会写一种问法(预训练问答页里的那种)、4 种关系;方位、反查首都、情感,它根本不会想到去写。

用这些数据做指令微调,和”人写的”数据比(测试国家,4 种关系):

训练数据第 1 种问法第 2–4 种没见过的第 5–6 种方位 / 反查首都 / 情感
base 自己写的,去重后 72 条87.5%21.9%0.0%0.0%
base 自己写的,不去重(995 条)93.8%24.0%1.6%0.0%
人写的,4 种关系,只用第 1 种问法,72 条93.8%21.9%0.0%0.0%
人写的,4 种关系,4 种问法,72 条93.8%90.6%56.2%0.0%
人写的,7 种任务,4 种问法,1200 条(默认)93.8%95.8%59.4%89.4%
  • 只用自己写的 72 条,模型就”教会了自己”用对话格式回答它自己写的那种问题(87.5%)。
  • 短板是多样性:换个问法只有 21.9%,和”人写的、只用一种问法”一模一样;同样 72 条、但有 4 种问法的人写数据是 90.6%。
  • 它没写过的任务,训练出来就不会。模型自己生成的数据,覆盖不了它自己不会的东西。

真实世界里有一个相关的发现。Gudibande et al.(2023,《The False Promise of Imitating Proprietary LLMs》)用 ChatGPT 的输出训练开源模型,发现模仿模型学会了 ChatGPT 的风格(人类评价者一开始觉得它们很像),但在事实性和能力上的差距几乎没有缩小——它们模仿的是表面,不是知识。

5.3 少而精:LIMA 与表面对齐假说

训练样本从 24 条增加到 1536 条(7 种任务,同样 400 步):

样本数每种任务约7 种任务平均
24332.0%
48655.7%
961374.4%
1922789.7%
3845487.1%
153621991.5%

几百条之后几乎不再提升。再看数据的质量(05 号脚本演示 3):

训练数据7 种任务平均
1200 条,全对(默认)92.8%
150 条,全对82.6%
1200 条,30% 的答案是错的64.7%
1200 条,60% 的答案是错的38.0%

150 条正确的数据,比 1200 条里 30% 错误的好得多。错误答案的伤害在于,模型学会了”有时候答一个别的国家的答案”——它在测试国家上也会这样做。这是在训练模型编造(第 5 讲会看到,用模型不知道的事实做微调,同样会增加编造)。

LIMA(Zhou et al. 2023,《LIMA: Less Is More for Alignment》)用 1000 条精心挑选的例子微调 650 亿参数的 LLaMA,不用任何 RLHF,在人类评价中有 43% 的情形下被认为和 GPT-4 一样好或更好。他们据此提出表面对齐假说(superficial alignment hypothesis):模型的知识和能力几乎全部来自预训练,对齐主要是教它在和用户交流时用哪种格式、哪种风格;所以只需要少量、但多样且高质量的例子。

我们的迷你实验从几个方向支持这个假说:知识来自预训练(§2.2、§3.3)、几百条数据就饱和(上表)、只训练 28 个嵌入就接近全量微调(§4.1)。但也要注意它的边界:

  • 迷你模型上”少而精”的前提是覆盖面——每种任务、每种问法都有例子(§3.3、§3.4)。少而窄是不行的。
  • “表面”不等于”不重要”。格式和风格决定了模型能不能被用起来;而在大模型上,对齐还影响拒答、诚实、安全等行为(第 5、6、12 讲),这些不全是”表面”的。

6. InstructGPT:从 SFT 到 RLHF · From SFT to RLHF

SFT 有一个根本的局限:它只能教模型模仿示范回答。可很多时候,写出一个好回答很难,判断两个回答哪个更好却容易得多。InstructGPT(Ouyang et al. 2022)把这个观察变成了一个三步的流程:

  1. SFT:标注员为一批提示写示范回答,监督微调 GPT-3。
  2. 奖励模型(RM):对同一个提示,让 SFT 模型生成几个回答,标注员给它们排序;训练一个模型,输入(提示,回答),输出一个分数,使得人类更喜欢的回答分数更高。
  3. 强化学习(PPO):用奖励模型的分数作为奖励,优化 SFT 模型,同时用一个 KL 惩罚让它不要离 SFT 模型太远;PPO-ptx 再加上预训练损失(§4.3)。

几个关键的结果和教训:

  • 标注员更喜欢 13 亿参数 InstructGPT 的回答,而不是 1750 亿参数 GPT-3 的回答——尽管前者小了一百多倍。对用户来说,“听指令”的价值可以超过规模。
  • InstructGPT 在真实性上有改进、有害输出有所减少,但对偏见的改善不明显(第 6 讲)。
  • RLHF 带来了新的问题:模型学会讨好评价者。第 5 讲会看到,RLHF 之后模型的校准变差;第 6 讲会看到谄媚(sycophancy)——顺着用户的观点说话——在很大程度上是”人类偏好”这个训练信号的副作用。

后来的工作简化或改造了这个流程:DPO(Rafailov et al. 2023)证明可以跳过显式的奖励模型和强化学习,直接用偏好对训练;Constitutional AI(Bai et al. 2022)用一组书面原则和 AI 反馈代替一部分人类标注(第 16 讲)。今天的 chat 模型通常要经过”预训练 → 大规模 SFT → 一轮或多轮偏好优化”,有的还会针对推理专门训练(第 4 讲)。

本讲的代码只做了 SFT。对提示工程师来说,知道 RLHF 的存在主要有两个用处:(1)理解模型的一些”性格”(啰嗦、客气、爱认同用户、在不确定时也给出自信的回答)来自偏好训练,不是来自预训练;(2)理解为什么同样的提示在 base 模型、SFT 模型、RLHF 模型上反应不同。


7. 对话模板与系统提示 · Chat templates and system prompts

配套代码:01_base_vs_sft.py 演示 4;04_system_and_style.py 演示 1–2

7.1 模板是一种文档格式

P2 §3.3 讲过:chat API 的消息列表,在模型内部仍然是一段文档,用特殊标记区分角色。真实模型的模板各不相同,例如 ChatML 写成 <|im_start|>user … <|im_end|>,Llama 2 写成 [INST] … [/INST]、系统提示放在 <<SYS>> 里。模型在指令微调中学会的,就是”在这种文档里,<assistant> 后面写什么”。

在迷你模型上把模板改一改(首都任务,测试国家 × 4 种问法):

模板变体第一个词是答案只写答案就停
训练时的模板100.0%100.0%
去掉开头的 <doc>100.0%9.4%
去掉结尾的 <assistant>0.0%0.0%
<user> 换成第 1 讲的 q :90.6%53.1%
<assistant> 换成 a :78.1%65.6%
完全不用对话标记(原生问答格式)100.0%0.0%
加一个训练时没见过的系统提示75.0%31.2%
  • 去掉结尾的 <assistant>,模型不知道”轮到它说话了”,一个都答不对。
  • 去掉开头的 <doc>,或者用原生的问答格式,答案仍然对,但模型停不下来——答完接着写起了问答页。模板决定了模型”以为自己在写什么文档”:对话模板 = 只答这一句;问答页 = 答完接着出题。
  • 换成相似但不同的标记,效果打折。

所以调用 chat 模型时,模板必须和训练时完全一致。API 替你做了这件事(你只传消息列表);自己部署开源模型时,用错 chat 模板是最常见、也最难发现的错误之一——输出”差一点”,而不是报错。

7.2 训练模型听系统提示

系统提示也是训练出来的能力。我们用两种风格的数据训练一个模型:系统提示是 answer briefly 时只写答案,是 answer in a full sentence 时写一句完整的话(the capital of volel is grorken .);训练里有 6 种任务,没有领导人。

任务系统提示含正确答案格式符合要求例子
capitalanswer briefly81.0%78.0%grorken
capitalanswer in a full sentence100.0%100.0%the capital of volel is grorken .
revcapanswer briefly81.0%78.0%volel
revcapanswer in a full sentence25.0%97.0%visis is the capital of thenania .
leader(没训练过)answer briefly3.0%3.0%sternek
leader(没训练过)answer in a full sentence9.0%3.0%the review is positive .

(节选;训练过的 6 种任务上,两种风格的格式符合率平均 87.0%。)

三个观察:

  1. 系统提示能控制风格:同一个问题,系统提示一换,回答的形式就换了。
  2. 格式对不等于内容对:反查首都的完整句子 97% 格式正确,只有 25% 内容正确。句子要先把问题里的首都抄下来,迷你模型没有照抄的能力(第 2 讲 §8.6),就编了一个格式漂亮、内容错误的句子——一个小型的”幻觉”(第 5 讲)。
  3. 风格和任务没有组合起来:领导人任务没训练过,两种风格下都几乎全错,完整句子的风格甚至套用了情感任务的句式。模型学到的是 6 × 2 种具体的”问题 → 回答”模式,而不是”用句子的形式回答任何问题”。真实的大模型能把风格指令和新任务组合起来,这是规模带来的能力。

不给系统提示、或给一个没见过的系统提示时(04 号脚本演示 2):不给时只有 31.2% 的回答含正确答案;少一个词的 answer in a sentence 仍有 71.9% 写成句子(和训练过的那句足够像);完全陌生的 answer the question 就乱了(9.4% 含正确答案)。模型的默认行为,是训练数据没覆盖到的地方。真实的 chat 模型见过成千上万种系统提示,也被专门训练成”没有系统提示时有合理的默认行为”,在系统提示和用户消息冲突时优先听系统提示(Wallace et al. 2024 的指令层级,第 12 讲)——这些都是训练出来的行为。

写系统提示的启示:把”每次都适用”的规则放在系统提示里;措辞越接近模型训练时常见的写法,行为越可预测;不要设计让系统提示和用户消息互相冲突的系统。


8. 指令微调怎样改变提示工程 · How instruction tuning changes prompting

配套代码:04_system_and_style.py 演示 3;06_real_llm.py(可选)

8.1 第 2 讲的结论要分模型看

把第 2 讲的少样本情感分类(原生格式)放到 base 模型和默认 SFT 模型上,两个模型读到完全相同的 token:

设计base · 0 个示例base · 4 个SFT · 0 个SFT · 4 个
sentiment · positive/negative55.3%89.7%73.0%98.3%
sentiment · great/awful54.3%71.8%54.0%75.5%
rating · awful/great(标签词反着用)30.0%27.2%37.3%32.7%
  • 零样本变强,少样本的收益变小:positive/negative 设计下,零样本提高了 17.7 个百分点,4 个示例只提高了 8.6 个。指令微调里有情感分类任务,模型对”这里要判断情感”更敏感了,连第 2 讲那个陌生的原生格式都受益。这是指令微调后的模型普遍的样子:FLAN 和后来的工作都观察到,指令微调后零样本表现大幅提升,少样本相对零样本的提升变小。
  • 语义先验依旧:标签词反着用时,两个模型都按词本来的意思回答。Wei et al.(2023)发现,指令微调会让模型更依赖语义先验、更不容易被示例里反着用的标签带走(同时也更会学语义无关的新映射)。

还有一个意外(04 号脚本演示 3 的最后一行):同一个 SFT 模型,如果用扩展后的词表编码这些提示,sentiment 就不再是 <unk>,而是一个在指令数据里学过的词——零样本变成 100%,4 个示例却跌到 54.0%(几乎全猜一类)。同一串文字、不同的分词,行为天差地别;我们没有找到确切的原因(一个猜测:sentiment 只在对话格式的问题里出现过,从没以 sentiment : 标签 . 的形式重复出现)。教训是:换了分词器或词表,旧的提示就要重新测。

8.2 对写提示的实际影响

指令微调之后,提示工程的重心变了:

base 模型(GPT-3 时代)指令微调后的 chat 模型
主要手段伪装成文档开头;少样本示例直接写清楚指令;必要时加示例规定格式
示例的作用认出任务、学格式、(大模型)学映射主要是规定格式、风格和边界情况
敏感性对格式、示例、顺序极其敏感降低了,但没有消失(Sclar et al. 2024)
想改变一个规则很难(示例扳不动先验)写在指令里;和先验冲突时仍可能不听
风险不听指令、跑题啰嗦、讨好、过度拒答、自信地编造(第 5、6 讲)

一些具体的建议:

  1. 先写清楚指令,再考虑示例。对 chat 模型,一个明确的零样本指令往往是最好的起点;示例用来规定输出格式和处理边界情况。
  2. 用模型训练分布里常见的说法(§3.4)。“Classify the sentiment as positive or negative.” 比一个生造的格式更可靠。
  3. 格式要求用代码验证。06 号脚本(可选)在真实的 Claude 上测”只答一个词”的指令放在用户消息里、放在系统提示里、和用户消息冲突时、要求 JSON 时的遵从率;无论遵从率多高,生产系统都应该用代码校验格式(P1 §8 的 extract_json),或使用 API 提供的结构化输出功能。
  4. 换模型要重测。同一个提示在不同的 chat 模型上,格式遵从、风格、拒答的行为都可能不同。

8.3 跨模型的可迁移性

原课的说明特别提到”微调效果在不同模型之间的可迁移性”。这个问题有几个层面:

  • 指令微调的效果能迁移到没见过的任务(§3)——这是 FLAN 的核心发现,前提是模型足够大、任务足够多样。
  • 指令微调过的模型是更好的起点:Longpre et al.(2023)发现,在单个下游任务上继续微调时,从 Flan-T5 出发比从原始 T5 出发收敛更快、效果更好。指令微调相当于一种”通用的预备训练”。
  • 一个模型生成的指令数据可以训练另一个模型(Alpaca、Vicuna):数据”迁移”了,但正如 Gudibande et al.(2023)发现的,被迁移的主要是风格,不是能力和知识(§5.2)。
  • 提示在模型之间的迁移:为一个模型调好的提示,在另一个模型上未必还好(第 2 讲 §4.1 引用的 Lu et al. 2022 发现,好的示例顺序在模型之间不迁移)。指令微调减轻了这个问题——大家都被训练成听”正常的”指令——但没有消除它。

在迷你模型上我们看到了第一层的一个小版本(领导人任务从 8% 升到 24%)和它的边界(预训练里没被问过的任务完全不迁移,§3.3)。

8.4 可选:在真实模型上

06_real_llm.py 用 P2 的统一接口,在真实的 Claude 上测 5 种指令条件 × 12 道题(资料卡放在提示里,因为真实模型不可能知道虚构世界)。编写这份讲义的环境里没有安装 anthropic SDK,所以没有真实模型的结果可以报告;--toy 模式(P2 的 SimLLM,对 “only”、“one word”、“JSON” 有写死的反应)只用来检查代码能跑通。运行时值得看的是条件 D:系统提示要求”只答一个词”,用户却要求”用一句完整的话解释”——你的模型听了谁?


9. 小结 · Summary

  1. base 模型在续写文档,指令微调教它熟悉一种新文档:“有人提出请求,接着是对请求的回应”。数据是”指令 → 回答”对,用对话模板写成文本,只在回答上算损失。
  2. 指令微调增加的是可访问性,不是知识:迷你模型用对话格式在只在百科里出现过的国家上答对 90% 以上,和为它精心伪装的原生格式相当。
  3. 任务和问法的多样性让模型学到”请求”这个抽象概念:只用一个任务训练,模型就”不管问什么都答首都”;只用一种问法训练,换个问法就几乎全错。FLAN 的规律——任务越多越好——在大模型上最明显,小模型上可能反而有害。
  4. 指令微调为每一类问题建立通道:预训练里没被问过的任务,必须在指令数据里见过;见过之后,知识能迁移到微调数据里没有的实体上。
  5. 怎样训练和训练什么一样重要:数据少而窄时,全量微调会背数据、会遗忘(测试国家 45%,困惑度 131);混入预训练语料、小学习率、只训练少量参数都能防止它。只训练 28 个新词的嵌入就能到 90%。
  6. 数据要多样、正确、覆盖全面;数量在几百条之后就不再关键(LIMA 的表面对齐假说)。模型自己生成的数据便宜,但覆盖不了它自己不会的东西;错误的答案会训练模型编造。
  7. InstructGPT = SFT + 奖励模型 + PPO:判断比示范容易,偏好训练让 13 亿参数的模型在人类评价中胜过 1750 亿参数的 GPT-3;代价是对齐税和讨好评价者的倾向。
  8. 对话模板和系统提示是训练出来的文档格式:模板用错,模型就”以为自己在写别的文档”;系统提示的措辞越接近训练分布越可靠。
  9. 指令微调改变了提示工程:零样本变强,少样本收益变小,更依赖语义先验;指令写清楚比堆示例更重要;换模型、换分词器都要重测。

10. 常见误区 · Common pitfalls

误区实际情况
“指令微调让模型学到了新知识”主要是让已有的知识可以用统一的接口取出来;用新事实做微调还可能增加编造(§5.3、第 5 讲)
“微调数据越多越好”几百条之后很快饱和;多样性、正确性、覆盖面比数量重要
“只要在我的任务上微调就行,不用担心别的”数据少而窄时,模型会背数据、忘掉原有能力;要混入通用数据、控制学习率,并在留出数据上测
“用一个模板生成几千条训练数据就够了”只用一种问法训练,换个问法就几乎全错(13.9%)
“用强模型的输出训练小模型,小模型就和强模型一样强”迁移的主要是风格,不是知识和能力(Gudibande et al. 2023)
“system prompt 和 user prompt 写哪都一样”系统提示的行为是训练出来的;放每次都适用的规则,避免和用户消息冲突
“chat 模板差一点没关系”模板决定模型以为自己在写什么文档;差一点就可能停不下来、答非所问
“指令微调后的模型对提示不敏感了”敏感性降低了,但没有消失;换问法、换模型、换分词器都要重测
“RLHF 只是让模型更好用”它也带来讨好、校准变差等副作用(第 5、6 讲)

11. 练习 · Exercises

练习 1(概念) 用一句话分别解释预训练、指令微调、RLHF 各自的训练目标,并说出它们的训练数据分别是什么。

参考答案:预训练:在海量文本上预测下一个 token,数据是网页、书籍等无标注文本。指令微调:在”指令 → 示范回答”对上预测回答的 token(只在回答上算损失),数据是人写、改写或模型生成的指令数据。RLHF:最大化奖励模型给出的分数(并用 KL 惩罚保持接近 SFT 模型),奖励模型本身是在人类对回答的排序数据上训练的。

练习 2(读表) §4.1 里”全部参数 · 不混入”的配方在 SFT 国家上 100%、测试国家上 45.3%。(a)这说明了什么?(b)如果你只有这一个模型、只在 SFT 国家上评估,会得出什么错误结论?(c)真实项目里,“SFT 国家”和”测试国家”分别对应什么?

参考答案:(a)模型背下了微调数据里的事实,没有学会调用预训练的知识——它学到的是”这些具体的问题 → 这些具体的答案”。(b)会以为微调非常成功(100%),实际上模型在没见过的实体上一半以上都答错。(c)SFT 国家对应你的训练数据覆盖的那些实体、话题或用户;测试国家对应上线后会遇到的新实体、新话题。评估一定要用训练数据里没有的样本,最好按实体或话题划分,而不是随机划分(随机划分时,同一个实体可能同时出现在训练和测试里)。

练习 3(设计) 你要为公司的客服系统微调一个模型,手上有 500 条人工写的问答对,都关于 20 种产品。按本讲的发现,设计训练和评估方案。

参考答案:数据:每个问题改写成多种问法(§3.4),检查答案正确(§5.3),按产品划分训练 / 测试(例如 16 种产品训练、4 种测试),以检验模型是”学会回答”还是”背答案”。训练:用参数高效的方法(LoRA 等)或小学习率,混入一些通用的指令数据防遗忘(§4.1)。评估:在测试产品上的正确率、在训练时没见过的问法上的正确率、在通用能力上有没有退化(§4.3),并且比较”不微调、只写一个好的系统提示 + 检索产品文档”(第 7 讲)的效果——很多时候后者就够了。

练习 4(解释) 为什么只用”首都”一个任务做指令微调的模型,问它领导人时会回答首都?用”模型学到了什么”来解释,并说出增加任务种类为什么有帮助。

参考答案:训练数据里,所有的请求后面都跟着一个首都名。模型能学到的最简单的规律是”对话格式 → 写一个首都”,它不需要读懂问题就能把训练损失降到最低。增加任务种类后,同样的对话格式后面可能是首都、语言、出口商品……只有读懂问题才能写对,模型被迫学会”根据问题的内容选择答案的类型”——这正是在没见过的任务上泛化所需要的能力。

练习 5(计算) §5.3 的表里,1200 条数据有 30% 是错的。假设模型完全”学会”了训练数据的分布:对每个问题,以 70% 的概率答对、30% 的概率答一个别国的答案。它在测试国家上的准确率会是多少?和实际的 64.7% 比较,说明什么?

参考答案:完全模仿训练分布时约为 70%(再乘上它在无噪声时的水平 92.8%,约 65%)。实际 64.7% 和这个估计很接近,说明模型确实把”有时答错”当成了要学的行为:它没有”过滤掉”噪声,而是模仿了噪声的比例。(贪心解码下这个”模仿”表现为一部分题目稳定地答错。)这就是为什么错误的训练答案等于在训练模型编造。

练习 6(动手) 修改 instruct_lab.DEFAULT_RECIPE,把 train 设为 "new_embeddings",再把 n 从 1200 降到 96。和全量微调 + replay 在 96 条数据时的结果(02 号脚本演示 3:74.4%)比较。你预期哪个更好?为什么?

参考答案:预期只训练嵌入的方法在数据很少时更有优势:它只有 28 × 96 个可训练的数,背不下 96 条样本里的具体事实,只能学”格式翻译”;全量微调在 96 条数据上更容易背数据。实际结果要运行才知道——注意用 get_sft_model(train="new_embeddings", lr=3e-3, mix=0.0, n=96),并多跑几个 data_seed。

练习 7(批判) LIMA 的”表面对齐假说”说对齐主要是教格式和风格。举出两种你认为不是”表面”的对齐目标,并说明为什么它们可能需要更多、或不同类型的训练数据。

参考答案:(1)诚实与校准:知道自己不知道什么、在不确定时说”不知道”。这需要模型把内部的不确定性和输出行为联系起来,而 SFT 示范数据里很少有”不知道”的例子,用错误的事实训练还会适得其反(第 5 讲)。(2)在压力下坚持正确的立场(不谄媚):用户坚持错误观点时不改口。这和人类偏好数据里”讨好的回答更受欢迎”的倾向相冲突,需要专门构造的数据或训练目标(第 6 讲)。此外,安全相关的拒答边界(既不过度拒答、也不被绕过)也需要大量针对性的数据和对抗测试(第 12 讲)。

练习 8(模板) §7.1 里,去掉开头的 <doc> 后,答案仍然对,但只有 9.4% 能停下来。解释这个现象,并说明它对自己部署开源 chat 模型有什么提醒。

参考答案:训练数据里每段对话都以 <doc> 开头,模型把”<doc> + 对话标记”当成”这是一段对话文档、回答完就结束”的信号。没有 <doc> 时,前文更像一段普通文本的中间,模型答完问题后按预训练的习惯继续续写(写起了问答页)。提醒:开源模型的 chat 模板通常包括开头的特殊标记(BOS)、角色标记、结束标记,少一个都可能让模型行为”差一点”——不报错,但会多写、停不下来或格式不对。应该使用模型发布者提供的模板实现(例如分词器自带的模板函数),而不是自己手拼字符串。


12. 延伸阅读 · Further reading

指令微调的主线

  • Wei, J. et al. (2022). Finetuned Language Models Are Zero-Shot Learners (FLAN). ICLR.
  • Sanh, V. et al. (2022). Multitask Prompted Training Enables Zero-Shot Task Generalization (T0). ICLR.
  • Mishra, S., Khashabi, D., Baral, C., & Hajishirzi, H. (2022). Cross-Task Generalization via Natural Language Crowdsourcing Instructions. ACL.
  • Wang, Y. et al. (2022). Super-NaturalInstructions: Generalization via Declarative Instructions on 1600+ NLP Tasks. EMNLP.
  • Chung, H. W. et al. (2022). Scaling Instruction-Finetuned Language Models (Flan-PaLM / Flan-T5). arXiv:2210.11416.
  • Longpre, S. et al. (2023). The Flan Collection: Designing Data and Methods for Effective Instruction Tuning. ICML.

RLHF

  • Ouyang, L. et al. (2022). Training Language Models to Follow Instructions with Human Feedback (InstructGPT). NeurIPS.
  • Stiennon, N. et al. (2020). Learning to Summarize from Human Feedback. NeurIPS.
  • Rafailov, R. et al. (2023). Direct Preference Optimization: Your Language Model is Secretly a Reward Model. NeurIPS.
  • Bai, Y. et al. (2022). Constitutional AI: Harmlessness from AI Feedback. arXiv:2212.08073.

数据从哪里来

  • Wang, Y. et al. (2023). Self-Instruct: Aligning Language Models with Self-Generated Instructions. ACL.
  • Taori, R. et al. (2023). Stanford Alpaca: An Instruction-following LLaMA Model. GitHub.
  • Zhou, C. et al. (2023). LIMA: Less Is More for Alignment. NeurIPS.
  • Gudibande, A. et al. (2023). The False Promise of Imitating Proprietary LLMs. arXiv:2305.15717.
  • Kung, P.-N., & Peng, N. (2023). Do Models Really Learn to Follow Instructions? An Empirical Study of Instruction Tuning. ACL.(发现用简化甚至误导性的指令训练,效果相差不大——模型学到的很大一部分是输出格式和答案空间)

怎样微调

  • Lester, B., Al-Rfou, R., & Constant, N. (2021). The Power of Scale for Parameter-Efficient Prompt Tuning. EMNLP.
  • Hu, E. J. et al. (2022). LoRA: Low-Rank Adaptation of Large Language Models. ICLR.
  • Wallace, E. et al. (2024). The Instruction Hierarchy: Training LLMs to Prioritize Privileged Instructions. arXiv:2404.13208.

13. 下一讲预告 · Next lecture

这一讲的模型只回答一步就能答出的问题:知识在预训练里,指令微调建了一条”从问题到知识”的通道。可如果问题需要好几步——“讲 driltese 语的那个国家,首都是哪里?“——一条通道就不够了。第 4 讲进入原课第 3 周:思维链提示(Chain-of-Thought Prompting)。

  • 少样本思维链(Wei et al. 2022)与”Let’s think step by step”(Kojima et al. 2022);
  • Self-Ask 与”组合性差距”(Press et al. 2023):模型分别知道两步,却答不出两步合起来的问题;
  • Plan-and-Solve、Step-Back 等变体,以及 self-consistency:多次采样、多数投票,和它的统计学;
  • 思维链什么时候没用、什么时候它说的”理由”并不是模型真正的理由(忠实性);推理模型把思维链训练进了模型;
  • 动手:在迷你 GPT 上测量两跳问题的组合性差距,用指令微调教它”先写出中间步骤”,并检验它写出的步骤是不是真的决定了答案。
← 返回课程目录