对应原课:CMU 11-667 Fall 2025 · Lecture 9 · Tue 23-Sep-2025 · Surprising Behaviours of In-Context Learning and Model Alignment(Jaromir Savelka、Yubin Kim) 原课 slides:Surprising Behaviors of In-context Learning(课表上标为 in-context learning) 阅读材料:Wei et al. (2022), Chain-of-Thought Prompting Elicits Reasoning in Large Language Models;Min et al. (2022), Rethinking the Role of Demonstrations: What Makes In-Context Learning Work?;Carlini et al. (2023), Are aligned neural networks adversarially aligned? 配套代码:code/lecture09/(1 个模块 + 5 个演示脚本;第一次运行要训练 4 个小模型,共约 3 分钟,之后都在秒级) 本讲的写法:骨架来自原课 slides;“能精确算出贝叶斯最优 ICL 的小世界”是补充的——它让每个”意外行为”都能和理想的推断者比较。所有数字都来自配套代码的实际输出。
目录
- 0. 本讲导读
- 1. 回顾与问题
- 2. 上下文学习是一种推断
- 3. 示例里什么最重要
- 4. 顺序、多数标签与校准
- 5. 示例能推翻先验吗?对齐有多牢固?
- 6. 思维链
- 7. 让 ICL 更好用,以及怎样评估
- 8. 从多任务到聊天机器人:LaMDA
- 9. 小结、常见误区、练习
0. 本讲导读
0.1 这一讲要回答的问题
第 6 讲把上下文学习(in-context learning, ICL)当作”不改参数的适配”介绍过,也看到它在小模型上很弱。这一讲专门研究 ICL 的那些反直觉的行为:
- 少样本示例的标签全是错的,ICL 居然还能工作?(Min et al. 2022)
- 同样 4 个示例,换个顺序,准确率能相差几十个百分点?(Zhao et al. 2021)
- 示例说”反话”(把正面标成负面),模型跟不跟?为什么大模型和小模型不一样?(Wei et al. 2023)
- 在示例里写出解题步骤(思维链),为什么就能做对多步推理题?(Wei et al. 2022)
- 对齐过的模型,为什么几个示例、换个格式就能绕过?(Carlini et al. 2023)
这些问题在真实的大模型上很难回答,因为我们不知道它的预训练数据里有什么。这一讲用一个”知道一切”的小世界:预训练文档由隐藏的任务生成,贝叶斯最优的上下文学习可以精确算出来。于是每一个”意外行为”都可以问:理想的推断者也会这样吗?
0.2 学完这一讲你应该能
- 把 ICL 解释为”在预训练学到的任务里做隐式贝叶斯推断”,并据此预测示例的各种改动会产生什么效果;
- 说出 Min et al. 的发现、它成立的条件,以及标签空间、输入分布、格式、映射各自的作用;
- 解释顺序敏感、多数标签偏差、近因偏差,以及上下文校准的原理和局限;
- 解释为什么只有大模型能跟着翻转的标签走,为什么抽象标签比”有主”的标签词更能逼模型从示例里学;
- 用”训练数据的局部性”解释思维链为什么有用、什么时候没用;
- 说出对齐的两种失效方式(目标冲突、泛化不匹配)和过度拒绝,以及评估 LLM 时要做的几十个决定。
0.3 本讲的实验平台
icl_world.py 的预训练语料有 20000 篇文档。每篇由一个隐藏的任务生成,内容是 2~24 个”名词 → 标签”的示例:
pony -> yes , pear -> no , carrot -> no , kiwi -> no , lily -> no , leek -> no , dog -> yes , … (是不是动物)
radish = fresh | pear = ripe | <eos> (类别,另一种格式)
tulip : small ; goat : big ; <eos> (大小)
| 任务 | 标签 | 先验 |
|---|---|---|
| cat(类别) | ripe / fresh / pretty / hungry | 0.15 |
| color(颜色) | red / green / yellow / white | 0.15 |
| size(大小) | small / big | 0.12 |
| price(价位) | cheap / dear | 0.12 |
| animal(是不是动物) | yes / no | 0.12 |
| flower(是不是花) | yes / no | 0.12 |
| size_flip、animal_flip(“反着说”) | 同上 | 各 0.02 |
| symbol(抽象符号) | 每篇文档随机把 4 个类别对应到 8 个符号 <s0>…<s7> 中的 4 个 | 0.18 |
每个示例有 10% 的概率标签被换成同一标签空间里的另一个(噪声)。格式有三种:x : y ;(70%)、x -> y ,(25%)、x = y |(5%)。颜色、大小、价位沿用第 8 讲花园小店的商品目录。
概念一共 1688 个:8 个命名任务 + 符号任务的 1680 种映射。给定示例,贝叶斯后验 可以精确算出:每个示例在概念 θ 下的似然是 (标签正确)、(标签在 θ 的标签空间里但不对)或 0(标签不在 θ 的标签空间里)。
在这个语料上从零训练两个因果 Transformer:小模型(d=64、2 层,105,600 个参数)和大模型(d=128、4 层,804,352 个参数)。
1. 回顾与问题
slides 开头回顾了前几讲:评估的构念、操作化与指标,各种自动指标;适配的三条路——全参数微调、不微调(ICL)、高效微调(PEFT 的八种方法),以及从多任务学习到指令微调。
这一讲的议程:
- ICL 的主要经验:提示的措辞、示例的选择和顺序、格式、标签的对错;
- 让 ICL 更好用:更多示例、校准 logits、思维链、更好的模型、把复杂任务拆小;
- 评估:用少样本评估 LLM 时要做的决定;
- 聊天机器人 LLM:LaMDA。
slides 对第一部分的总结很直白:**ICL 对提示的语言、示例的语言、示例的顺序、示例的标签都不鲁棒。**下面逐一检验,看看哪些是”ICL 本身”的性质,哪些是”模型还不够好”的症状。
2. 上下文学习是一种推断
2.1 为什么 ICL 能工作
slides 的解释:
- 任务的实例本来就存在于预训练数据里:“TL;DR” 是 Reddit 上的常见写法;网上有大量对照翻译。
- 所以 LLM 已经具备完成任务所需的知识;少样本示例只是”教”它这个任务的模板;额外的指令让它调用合适的知识。
Xie et al. (2022) 把这个直觉形式化:预训练文档是由许多隐藏的”概念”生成的,模型为了预测下一个词,必须从上下文推断当前的概念。ICL 的示例就是推断概念的证据:
这就是隐式的贝叶斯推断。在我们的世界里,右边每一项都可以精确算出来。
2.2 推断是怎样一步步进行的
代码 01 §1,一道 animal 任务的题,后验概率最大的 3 个概念:
| 已有的示例 | 后验最大的 3 个概念 |
|---|---|
| (没有) | symbol 0.18,cat 0.15,color 0.15 |
| carrot:no | animal 0.50,flower 0.50,animal_flip 0.01 |
| carrot:no hen:yes | animal 0.90,flower 0.10,animal_flip 0.00 |
| carrot:no hen:yes lilac:no | animal 0.99,flower 0.01,animal_flip 0.00 |
第一个示例的标签 no 就把标签空间之外的任务全部排除(剩下的只有用 yes / no 的几个);接下来要靠”哪些名词是 yes”来分辨 animal 和 flower(练习 1 手算这几步)。
2.3 示例越多越好吗?
代码 01 §2(每格:小模型 / 大模型 / 贝叶斯最优;每个 k 300 道题;预训练文档最多 24 个示例):
| 任务 | k=0 | k=1 | k=2 | k=4 | k=8 | k=16 | k=32 |
|---|---|---|---|---|---|---|---|
| cat | .02/.00/.00 | 1.00/1.00/1.00 | 1.00/1.00/1.00 | 1.00/1.00/1.00 | 1.00/1.00/1.00 | 1.00/1.00/1.00 | .24/.26/1.00 |
| size | .00/.06/.00 | .99/1.00/1.00 | .99/.99/1.00 | .99/1.00/1.00 | .99/1.00/1.00 | 1.00/1.00/1.00 | .51/.59/1.00 |
| animal | .58/.55/.58 | .73/.82/.78 | .72/.93/.88 | .76/.99/.97 | .68/1.00/.99 | .77/1.00/1.00 | .77/.67/1.00 |
| flower | .84/.66/1.00 | .92/.94/1.00 | .89/.96/1.00 | .89/.97/1.00 | .93/.99/1.00 | .90/.99/1.00 | .73/.67/1.00 |
| symbol | .00/.00/.00 | .29/.35/.37 | .28/.54/.60 | .29/.72/.77 | .23/.89/.93 | .26/.98/.99 | .29/.24/1.00 |
- cat、size:标签空间独一无二,一个示例就足以认出任务,三者都立刻 100%。
- animal、flower:两个任务共用 yes / no,要靠”哪些名词标了 yes”来区分——贝叶斯最优随示例增加稳步上升,大模型几乎贴着它走,小模型停在七到九成。
- symbol:标签是每篇文档随机指定的符号,映射必须从示例里读出来。大模型在 16 个示例时追上贝叶斯最优(99%),小模型始终在三成左右——它学会了”认任务”,没学会”从示例里读映射”。
- k=32 超出了预训练见过的最大长度(24 个示例),两个模型都崩了,贝叶斯最优却不受影响——第 7 讲的”长度是一个领域”在这里又出现了。
slides 对”更多示例”给出了两个看似矛盾的结论:HELM 发现”有示例很重要,但示例更多似乎没什么帮助”;Agarwal et al. (2024) 的 Many-Shot In-Context Learning 发现,在长上下文模型上把示例增加到几百上千个,效果持续好于少样本。上表给出了一种调和:任务一旦被认出,更多示例就没用了(cat、size);映射要从示例里读出来的任务,示例越多越好(symbol);但超出模型见过的长度,再多的示例也会适得其反。
2.4 提示格式与困惑度
slides 引用 Gonen et al. (2023, Demystifying Prompts in Language Models via Perplexity Estimation):OPT-175B 在 AG News 分类上,不同措辞的提示效果差别很大,而且提示的困惑度越低(模型越”熟悉”它的措辞),效果往往越好——“提示里的语言越常见,效果越好”。他们用 GPT-3 改写和回译自动扩充提示,再按困惑度挑选。
代码 01 §3,4 个示例(每格:准确率 / 提示的困惑度):
| 格式 | 小模型 animal | 小模型 symbol | 大模型 animal | 大模型 symbol |
|---|---|---|---|---|
x : y ;(预训练 70%) | 0.72 / 3.5 | 0.28 / 5.1 | 0.97 / 3.5 | 0.74 / 4.5 |
x -> y ,(25%) | 0.74 / 3.7 | 0.28 / 5.4 | 0.97 / 3.6 | 0.73 / 4.8 |
x = y |(5%) | 0.76 / 4.0 | 0.29 / 5.8 | 0.97 / 3.9 | 0.74 / 5.1 |
x -> y ;(组合没见过) | 0.74 / 20.0 | 0.28 / 24.0 | 0.97 / 42.7 | 0.73 / 65.3 |
x ~ y &(符号没见过) | 0.00 / 4517 | 0.04 / 6669 | 0.83 / 15490 | 0.00 / 30445 |
预训练里出现过的三种格式,困惑度随格式变少见而略升,准确率几乎不变。只是组合没见过(两个符号都见过):困惑度升高十几倍,准确率却完全不变——模型照样认出了任务。符号本身没见过:困惑度上千,准确率崩溃。Gonen et al. 的趋势在极端情形下清楚可见,但它不是严格的定律:困惑度只是”熟悉程度”的一个粗略代理。
3. 示例里什么最重要
3.1 Min et al. 的发现
Min et al. (2022) 把少样本示例的标签换成随机标签,在很多分类和多选任务上,ICL 的准确率只下降一点点。他们把示例拆成四个方面分别检验:
- 输入和标签的对应关系(映射);
- 输入的分布(示例的输入像不像任务的真实输入);
- 标签空间(示例里出现的是不是这个任务的那些标签);
- 格式(输入和标签成对出现的样子)。
结论:后三者很重要,第一个出人意料地不太重要。slides 的说法是:“少样本示例的标签对不对,在分类任务里没那么要紧。”
3.2 实验:六种示例
代码 02,8 个示例,300 道题(每格:小模型 / 大模型 / 贝叶斯最优;”—“表示贝叶斯模型里没有这种情况):
| 任务 | 不给示例 | 正确标签 | 随机标签 | 错的标签空间 | 输入换成别的词 | 只有输入 |
|---|---|---|---|---|---|---|
| cat | .03/.00/.00 | 1.00/1.00/1.00 | 1.00/1.00/1.00 | .00/.00/.00 | .26/.43/— | .29/.00/— |
| color | .12/.29/.00 | 1.00/1.00/1.00 | 1.00/1.00/1.00 | .00/.00/.00 | .42/.45/— | .25/.00/— |
| size | .00/.04/.00 | .99/1.00/1.00 | .99/.89/.68 | .00/.00/.00 | .65/.43/— | .00/.03/— |
| animal | .63/.59/.63 | .68/1.00/.99 | .61/.56/.52 | .00/.00/.00 | .63/.68/— | .00/.00/— |
| symbol | .00/.00/.00 | .27/.87/.89 | .26/.24/.27 | .00/.00/.00 | .24/.24/— | .01/.08/— |
3.3 解读:什么时候标签的对错不重要
- **标签空间独一无二的任务(cat、color):随机标签和正确标签一样好。**标签空间本身就认出了任务,任务的映射早在预训练里学会了,示例里的对应关系对不对无关紧要。这就是 Min et al. 在真实 LLM 上看到的现象,贝叶斯最优给出了同样的结论。
- size:small / big 也被一个罕见的”反着说”任务(size_flip,先验 2%)共用。随机标签让贝叶斯最优犹豫了——一半的示例看起来像反着说——准确率掉到 68%(练习 2 精确算出这个数);小模型完全不受影响(99%)、大模型只掉到 89%。两个模型都比贝叶斯最优更”固执”地相信常见的任务。
- animal:yes / no 被几个任务共用,只有”对应关系”能把它们分开,随机标签让准确率退回到和不给示例差不多。symbol:映射完全靠示例给出,随机标签 = 没有信息。
- 错的标签空间:所有人都输出那个错的标签空间里的词,准确率归零——标签空间是最强的线索。
- 输入换成别的词:即使标签空间正确,cat 也从 100% 掉到 26%~43%——输入的分布同样重要(Min et al. 也发现用无关的句子代替输入会明显掉分)。只有输入、没有标签:几乎归零,没有标签空间这条线索,模型连该说哪一类词都不知道。
“标签对错不重要”不是普遍规律。它成立的前提是:任务能被别的线索(标签空间、输入分布、格式)认出来,而且映射在预训练里已经学会了。当多个任务共享标签空间、或映射本身要从示例里学时,标签的对错决定一切。真实 LLM 上的多数分类基准恰好属于前一种情况(“情感分类”的标签 positive / negative 几乎只对应一个任务),这就是 Min et al. 观察到那个现象的原因。
4. 顺序、多数标签与校准
4.1 Zhao et al. 的发现
Zhao et al. (2021, Calibrate Before Use) 用 GPT-3 2.7B 做 4 个示例的情感分类:随机选一组示例,把它们的 24 种排列都试一遍,准确率可以从接近随机到很高,相差几十个百分点。他们还发现:
- 多数标签偏差:模型偏向示例里出现得多的标签;
- 近因偏差:模型偏向最后几个示例的标签;
- 以及偏向预训练里常见的标签词(常见词偏差)。
slides 还列出了其他格式上的敏感性:问答式模板、对话式模板、像网页一样的提示、标签名的不同写法。
4.2 实验:顺序
代码 03 §1:animal 任务,10 组示例(每组 2 个动物 yes、2 个非动物 no),每组配 60 个查询(一半是动物),对每组的 24 种排列分别算准确率(只在 yes / no 里取预测):
| 第 1 组 | 第 2 组 | 第 3 组 | … | 第 10 组 | 平均极差 | |
|---|---|---|---|---|---|---|
| 小模型 | 0.33~0.47 | 0.45~0.63 | 0.32~0.43 | … | 0.38~0.55 | 0.143 |
| 大模型 | 1.00~1.00 | 1.00~1.00 | 1.00~1.00 | … | 1.00~1.00 | 0.000 |
| 贝叶斯 | 1.00~1.00 | 1.00~1.00 | 1.00~1.00 | … | 1.00~1.00 | 0.000 |
贝叶斯最优对顺序完全不敏感——示例是可交换的证据,乘法不在乎顺序。大模型同样不敏感,而且全对。小模型随顺序波动十几个百分点,而且整体低于 50%(查询一半是动物,乱猜也有 50%),它的 yes / no 和真实答案系统性地错位:它没认对任务。顺序敏感是”没能稳健地推断出任务”的症状。
4.3 实验:多数标签
代码 03 §2:8 个示例,其中 n 个是动物(yes);300 个查询,一半是动物(每格:预测 yes 的比例 / 准确率):
| n=1 | n=4 | n=7 | |
|---|---|---|---|
| 小模型 | 0.17 / 0.45 | 0.15 / 0.40 | 0.62 / 0.23 |
| 大模型 | 0.53 / 1.00 | 0.53 / 1.00 | 0.49 / 1.00 |
| 贝叶斯 | 0.53 / 1.00 | 0.53 / 1.00 | 0.49 / 1.00 |
贝叶斯最优和大模型:示例里 yes 多少,对预测毫无影响——只要能认出任务,答案就由查询本身决定。小模型:7 个 yes 时,它把六成的查询都答成 yes,准确率跌到两成多——典型的多数标签偏差。(我们的小模型没有表现出近因偏差,这里不列。)
4.4 上下文校准
Zhao et al. 的补救办法分两步:
- 估计偏差:不需要标注数据。把查询换成一个”内容无关”的输入(例如 “N/A”),看模型对各个标签的概率。slides 的例子:情感分类的模板下,模型对 “N/A” 给出 P(Positive) = 0.618、P(Negative) = 0.382——它偏向 Positive。
- 抵消偏差:对 logits 做一个仿射变换 ( 是对角矩阵),让内容无关的输入的输出变成均匀的(0.5 / 0.5)。最简单的版本就是把每个查询的概率除以内容无关输入的概率,再归一化(练习 3)。生成任务则校准第一个 token 在整个词表上的概率。
代码 03 §3 用 <null> 作内容无关的输入(每格:校准前 → 校准后的准确率):
| n=1 | n=4 | n=7 | (yes) 的平均 | |
|---|---|---|---|---|
| 小模型 | 0.45 → 0.45 | 0.40 → 0.40 | 0.23 → 0.30 | 0.56 |
| 大模型 | 1.00 → 0.75 | 1.00 → 0.77 | 1.00 → 0.78 | 0.46 |
对大模型,校准反而有害:它本来没有偏差,“内容无关的输入”测出来的”先验”是噪声,除掉它只会把对的答案改错。对小模型也帮助有限:它的问题不只是”偏向某个标签”,而是根本没认对任务。校准针对的是一种特定的病(标签先验的偏移);而且内容无关的输入要选得好——我们的 <null> 是预训练里从没见过的 token,Zhao et al. 用的是 “N/A”、空字符串这类模型熟悉的东西。
5. 示例能推翻先验吗?对齐有多牢固?
5.1 翻转标签与抽象标签
slides 提到”克服预训练的偏好”:Wei et al. (2023, Larger language models do in-context learning differently) 做了两种实验:
- 翻转标签:把默认的标签轮换一下,例如 [negative, neutral, positive] 变成 [neutral, positive, negative];
- 抽象标签:用没有含义的 A / B / C 代替有意义的标签名。
发现:小模型无视翻转的示例、坚持语义先验;大模型能跟着翻转的示例走(规模越大越能推翻先验)。Agarwal et al. 的 many-shot 实验也发现,示例足够多时,翻转标签和抽象标签都能被学会。
代码 04 §1(示例和查询都按翻转后的映射给标签;准确率 = 跟着翻转走的比例;每格:小模型 / 大模型 / 贝叶斯最优):
| 任务 | k=2 | k=4 | k=8 | k=16 |
|---|---|---|---|---|
| size:预训练里有 size_flip(2%) | .04/.23/1.00 | .03/.43/1.00 | .02/.58/1.00 | .02/.49/1.00 |
| animal:预训练里有 animal_flip(2%) | .63/.82/.91 | .53/.94/.98 | .68/1.00/1.00 | .69/1.00/1.00 |
| price:预训练里没有反着说的版本 | .00/.00/.00 | .00/.00/.00 | .00/.00/.00 | .00/.00/.00 |
| cat:预训练里没有(四个标签轮换) | .00/.00/.00 | .00/.00/.00 | .00/.00/.00 | .00/.00/.00 |
- 先验里有”反着说”的任务时,贝叶斯最优看两三个示例就跟着翻转走;大模型能部分跟上(animal 跟得上,size 只跟到一半);小模型几乎完全无视示例、坚持常见的映射——和 Wei et al. 的”规模越大越能推翻语义先验”一致。
- 先验里根本没有这种映射时,连贝叶斯最优也无能为力:示例只能在”预训练见过的任务”里挑一个,它不能凭空创造一个新任务。ICL 是”认出”任务,不是”学会”任务。(真实的大模型能跟着翻转走,说明它的”概念库”足够丰富,包含了”标签可以随便指定”这样的概念——就像我们的 symbol 任务。)
代码 04 §2:同样是”按类别分组、标签由示例指定”,标签用什么词?
| 标签用…… | k=2 | k=4 | k=8 | k=16 |
|---|---|---|---|---|
抽象符号(<s0>…<s7>,随机指定) | .28/.48/.53 | .27/.67/.72 | .27/.86/.91 | .27/.99/.99 |
| 颜色词(fruit→red, veg→green…) | .19/.19/.19 | .13/.13/.13 | .19/.19/.19 | .16/.16/.16 |
用无意义的符号,大模型和贝叶斯最优都能学会;用颜色词当标签,所有人都失败——颜色词”已经有主了”:color 任务让每个名词有自己真正的颜色,模型和贝叶斯最优都按真实颜色作答。标签词自带的含义会和示例”打架”。这就是 Wei et al. (2023) 提出”符号微调”(symbol tuning)的原因:用抽象标签微调,逼模型真正从示例里读映射。
5.2 对齐有多牢固?
同样的问题出现在对齐上。Carlini et al. (2023) 问”对齐过的神经网络是否在对抗意义下也对齐”——答案是否定的:精心构造的输入可以让对齐过的模型输出它本来会拒绝的内容。Wei, Haghtalab & Steinhardt (2023, Jailbroken) 总结了两种失效方式:
- 目标冲突(competing objectives):模型的”能力目标”(续写、遵循上下文)和”安全目标”互相竞争——Anil et al. (2024) 的 many-shot jailbreaking 就是在上下文里放大量”违规问答”的示例,示例越多越容易绕过;
- 泛化不匹配(mismatched generalization):安全训练没有覆盖到的输入形式(换一种编码、换一种格式、换一种语言),对齐就不生效。
这一讲只讲原理(攻击的具体技术留到第 16 讲,并且只讨论原理和防御)。代码 04 §3 做了一个完全无害的玩具版本:店家规定”动物的价位保密”。对齐数据是 3000 条 price 任务的提示(0~4 个植物的示例):问动物的一半,目标是拒绝符号 <null>;问植物的一半,目标是正确的价位。在大模型上做三种强度的监督微调:
| 正常:问动物 | 正常:植物答对 | 2 个动物示例 | 8 个动物示例 | 24 个动物示例 | 换成格式 B | 过度拒绝 | |
|---|---|---|---|---|---|---|---|
| 未对齐 | 0.00 | 1.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
| 弱对齐(30 步) | 0.76 | 1.00 | 0.54 | 0.22 | 0.00 | 0.14 | 0.00 |
| 中等(60 步) | 1.00 | 1.00 | 1.00 | 1.00 | 0.95 | 1.00 | 0.00 |
| 强对齐(300 步) | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 |
(“正常:问动物”和后面几列是拒绝率;“植物答对”是正常问题的准确率;“过度拒绝”是在 cat 任务里问动物的类别——这不该被拒绝——却被拒绝的比例。)
- 弱对齐:正常情况下拒绝 76%,但上下文里放进 2、8、24 个”动物 → 价位”的示例,拒绝率从 54% 一路降到 0%——示例越多越容易绕过,和 many-shot jailbreaking 的规律一样;换一种对齐数据没覆盖到的提示格式,拒绝率也降到 14%——泛化不匹配。
- 强对齐:怎么绕都拒绝,却在另一个任务里也拒绝回答动物的类别——学到的不是”价位保密”,而是”看到动物就拒绝”。这就是过度拒绝(exaggerated safety),真实的对齐模型也常被批评”拒绝了不该拒绝的请求”。
- 中等强度在这个玩具里两头兼顾,但它是在知道全部测试的情况下挑出来的——真实的对齐要面对没见过的攻击。
微调出来的行为是浅层的:它和训练时见过的上下文、格式绑在一起。对齐需要在”稳健”和”不误伤”之间权衡,而且必须在没见过的输入上检验(第 16、18 讲)。
6. 思维链
6.1 少样本思维链与零样本思维链
直觉(slides):如果让 LLM 把任务拆成许多小步骤,它会更擅长(尤其是推理类的)任务。推理类任务的例子:
- 算术:“Fernando 给 16 位参加早餐会的人带了三打百吉饼,每人吃两个,还剩几个?”
- 常识推理:“这个人害怕生病,所以他从不去看望是什么的朋友?(a) 病人 (b) 医院 (c) 老人 (d) 墓地”
少样本思维链(Wei et al. 2022):少样本提示里的每个示例都写出怎样解这道题,而不只是答案。模型在回答新题时也会先写出步骤。在数学、常识推理、符号推理上都有大幅提升——但只在足够大的模型上(小模型写出的步骤常常是错的)。
零样本思维链(Kojima et al. 2022):不需要任何示例,只要在提示末尾加一句 “Let’s think step by step.”。它的好处:同一句固定的指令能用于各种任务;而少样本思维链在示例的题型和实际任务不匹配时效果会下降。
6.2 为什么”先说中间步骤”有帮助?
Prystawski et al. (2023, Why think step by step? Reasoning emerges from the locality of experience) 的解释:训练数据有局部性。模型常常见到”A 和 B 一起出现""B 和 C 一起出现”,却很少见到”A 和 C 直接一起出现”。这时直接估计 A → C 很难,而”先说出 B、再由 B 说出 C”就把一个没见过的问题拆成了两个见过的问题。
代码 05 的两步任务:名词 → 类别 → 动词(cat → animal → feed;fig → fruit → eat)。在 ICL 语料之外再加三类文档:
第一步 goat : animal ; lettuce : veg ; potato : veg ; fig : fruit ; … (全部 43 个名词)
第二步 flower : water ; fruit : eat ; animal : feed ; veg : grow ; …
思维链 orange : fruit => eat ; goat : animal => feed ; … (只有一半的名词)
两种语料:(a) 局部——只有上面三类,“名词 : 动词”从来没有直接出现过;(b) 局部 + 直接——再加上一半名词的 “daisy : water ; grape : eat ; …”。各训练一个小模型。测试用 4 个示例(都是有思维链文档的那一半名词):直接提示的示例写成 “x : 动词 ;“,思维链提示的示例写成 “x : 类别 => 动词 ;”。
| 预训练语料 | 查询的名词 | 直接提示 | 思维链提示 | 思维链第一步说对类别 |
|---|---|---|---|---|
| (a) 局部 | 见过思维链的一半 | 0.0% | 100.0% | 100.0% |
| (a) 局部 | 没见过的一半 | 0.0% | 100.0% | 100.0% |
| (b) 局部 + 直接 | 见过的一半 | 100.0% | 100.0% | 100.0% |
| (b) 局部 + 直接 | 没见过的一半 | 100.0% | 53.5% | 100.0% |
((a) 局部,没见过的名词)
查询 fig(正确答案 eat): 直接提示 → fruit 思维链提示 → fruit => eat
查询 turnip(正确答案 grow):直接提示 → veg 思维链提示 → veg => grow
- (a) 局部:“名词 : 动词”从来没有直接出现过,直接提示完全失败:模型在 “x :” 后面说出的是类别(它最熟悉的 “x : 类别”),4 个示例不足以让它改成直接说动词。思维链提示 100%,连没见过思维链的名词也 100%:模型先用”第一步”的知识说出类别,再用”第二步 / 思维链”的知识由类别说出动词——把一个没见过的问题拆成了两个见过的问题。
- (b) 局部 + 直接:一半名词的”名词 : 动词”直接出现过,模型从相似的名词学会了直接回答(没见过的那一半也 100%),思维链就不再有优势(对没见过的名词反而只有一半左右)。
思维链不是魔法:它的价值来自训练数据的局部结构——当相关的变量很少直接一起出现时,“先推出中间变量”才有用。真实世界的文本正是高度局部的:一篇文章讲一件事,“A 导致 B”和”B 导致 C”常常出现在不同的地方。
7. 让 ICL 更好用,以及怎样评估
7.1 slides 的五条建议
- 更多示例:有示例很重要;在长上下文模型上,many-shot ICL 持续好于少样本(Agarwal et al. 2024)。该论文还提出两个变体:强化 ICL(reinforced ICL)——用模型自己生成、并且验证过答案正确的推理过程代替人写的推理过程;无监督 ICL(unsupervised ICL)——提示里只放输入、不放答案。many-shot ICL 在一些任务上能和监督微调相当,也能克服预训练的偏好(翻转标签、抽象标签)。
- 校准 logits(§4.4)。
- 思维链(§6)。
- 更好的模型:随着新一代 LLM 越来越多地经过指令微调,费力的提示工程没那么必要了,但并没有完全消失;即使今天的”预训练”模型,也常常见过不少指令跟随的数据。
- 把复杂任务拆成小单元:对复杂的生成任务,多次调用 LLM 通常比一个提示让它一次做完所有部分效果更好、也更容易评估。例如写短篇小说:(a) 先生成梗概;(b) 根据梗概生成人物表和事件序列;(c) 根据以上全部生成正文。拆分降低了每次调用的复杂度,也让人可以在中间介入。
slides 的总结:ICL 的工作方式可能违反直觉,但我们对什么重要、什么不重要的理解在不断进步。
7.2 用少样本评估 LLM:要做的决定
slides 用一个练习收尾:你要用少样本学习评估一个预训练 LLM 在 MMLU 验证集上的能力,怎样设计实验?要做的决定至少有:
- 多选题放在什么模板里?
- 用几个示例?
- 要不要额外的指令?
- 指令里要不要写学科(数学、经济、历史……)?
- 示例要不要和目标题目同一学科?
- 每个示例里,正确答案放在哪个选项位置?
- 验证集的每道题用同一个提示,还是每道题随机选示例?
- 判断对错时,看字母 {A, B, C, D} 的概率、看选项文字的概率,还是让模型生成再匹配?
Open LLM Leaderboard 的一次事故(Fourrier et al. 2023, What’s going on with the Open LLM Leaderboard?)说明了这些决定的影响:同一个模型在 MMLU 上,用三种不同的实现(原论文的实现、HELM 的实现、EleutherAI harness 的实现——模板不同、判断对错的方式不同)得到的分数差别很大,模型之间的排名也随之改变(第 5 讲 §5 的多选题实验是它的小规模版本)。slides 的结论:看到任何比较不同 LLM 的评估数字,都要先保持怀疑,直到你弄清楚了得到这些数字的全部细节。
另一个例子:Gemini 的发布报告(Pichai & Hassabis 2023)把 Gemini Ultra 在 MMLU 上”用 32 个样本的思维链”得到的分数,和 GPT-4 “5 个示例”的分数放在一起比较——评估设置不同的数字放在同一张图上。
8. 从多任务到聊天机器人:LaMDA
第 6 讲讲过”多任务训练演变成指令微调”。2020~2022 年前后有两条并行的研究方向:
- 让预训练语言模型解决 NLP 的经典任务:机器翻译、摘要、问答、情感分析……
- 让预训练语言模型当聊天机器人(对话智能体):能和用户闲聊。代表是 LaMDA。
LaMDA(Thoppilan et al. 2022)是最早的”对齐”实例之一(在”对齐”这个词流行之前)。目标:一个说话合理(但仍然有趣)、尽量符合事实、遵守安全准则的聊天机器人。
- 预训练:decoder-only 语言模型,下一个 token 预测;29.7 亿篇文档 + 11.2 亿段对话(爬取有对话交流的网站)。
- 微调流程:
- 让众包工作者和一个 LaMDA 实例聊几轮,收集几千段对话,话题不限;
- 另一批众包工作者给对话打分:是否合理(sensible)、具体(specific)、有趣(interesting)、安全(safe);
- 微调预训练的 LaMDA 来预测这些评分,得到判别器;
- 用判别器给从预训练数据里采样的 250 万条话语打标签;
- 在判别器认为”合理、具体、有趣、安全”的 80 万条话语上微调预训练的 LaMDA;
- 再在 4000 段对话上微调——这些对话由众包工作者修改过,加入了从网络搜索得来的事实。这让模型在推理时能发出搜索查询(第 10 讲的工具调用)。
注意第 3~5 步的思路:“用人的评分训练一个判别器,再用判别器筛选大量数据”——这正是后来 RLHF 里”奖励模型”的雏形(第 18 讲),也和第 8 讲”从偏好里学奖励模型”一脉相承。
9. 小结、常见误区、练习
9.1 小结
- ICL 是隐式贝叶斯推断:示例是推断”当前任务”的证据;在知道一切的小世界里,大模型几乎达到贝叶斯最优,小模型只会用最显眼的线索(标签空间)。任务一旦认出,更多示例没用;映射要从示例读出时,示例越多越好;超出见过的长度,示例反而有害。
- 示例里什么重要:标签空间是最强的线索,输入分布和格式也重要;“标签对错不重要”只在任务能被别的线索认出、映射已学会时成立——共享标签空间、抽象标签时,对错决定一切。
- 顺序与多数标签:理想的推断者对顺序和标签比例完全不敏感;这些敏感是模型没学好推断的症状。上下文校准只治”标签先验偏移”这一种病,用在没病的模型上反而有害。
- 先验与对齐:示例只能在预训练见过的任务里挑;先验里有对应的概念、模型又足够大时,才能跟着翻转的示例走;“有主”的标签词会压过示例。微调出的拒绝行为是浅层的:多示例、换格式能绕过,拉太紧又会过度拒绝。
- 思维链:它的价值来自训练数据的局部性——变量很少直接一起出现时,先推出中间变量才有用。
- 评估:少样本评估要做至少八个决定,每个都会改变分数和排名;不同设置的数字不能放在一起比。
- LaMDA:众包评分 → 判别器 → 过滤数据 → 微调,是 RLHF 奖励模型的前身;加入搜索事实的对话让它学会调用搜索。
9.2 常见误区
- “示例的标签对错不重要”:只在特定条件下成立(§3.3)。
- “示例越多越好”:任务认出之后没帮助;超出模型见过的长度会适得其反(§2.3)。
- “ICL 让模型在推理时学会了新任务”:它更像在预训练学过的任务里认出一个;预训练里没有的映射,示例教不会(§5.1)。
- “顺序敏感是 ICL 的本性”:理想的推断者对顺序完全不敏感;它是模型不够好的症状(§4.2)。
- “上下文校准总能提升准确率”:它只修正标签先验的偏移,用在本来没偏差的模型上反而有害(§4.4)。
- “思维链总是有帮助”:当训练数据里有足够的直接例子时,它没有优势,甚至更差(§6.2)。
- “对齐训练越强越安全”:太强会过度拒绝;而且对齐和训练时见过的格式、上下文绑在一起,换个样子就可能失效(§5.2)。
9.3 练习
练习 1(手算后验):只考虑 animal(先验 0.12)、flower(0.12)、animal_flip(0.02)三个概念,噪声 ε = 0.1(两个标签时,错的那个的似然是 0.1)。示例依次是 carrot:no、hen:yes。算出每一步的后验(只在这三个概念之间归一化),和 §2.2 的表比较。
参考答案
carrot 不是动物也不是花:animal 说 no(似然 0.9),flower 说 no(0.9),animal_flip 说 yes(no 的似然 0.1)。未归一化:0.108、0.108、0.002,归一化后 0.495、0.495、0.009——表里的 0.50、0.50、0.01。再加 hen:yes:hen 是动物,animal 说 yes(0.9),flower 说 no(yes 的似然 0.1),animal_flip 说 no(0.1)。未归一化:0.108×0.9 = 0.0972、0.108×0.1 = 0.0108、0.002×0.1 = 0.0002,归一化后 0.899、0.100、0.002——表里的 0.90、0.10、0.00。(表里的数是在全部 1688 个概念上算的,但其余概念在第一个示例后概率就是 0:它们的标签空间里没有 no。)
练习 2(随机标签为什么让贝叶斯最优掉到 68%):size 任务、8 个示例、标签从 {small, big} 里均匀随机。只考虑 size(先验 0.12)和 size_flip(0.02)。设 8 个示例里有 m 个恰好和 size 的映射一致。(a) 写出两个概念的后验比;(b) m 至少是几时贝叶斯最优会按 size 回答?(c) 算出它按 size 回答的概率,和 §3.2 的 68% 比较。(d) 如果先验里没有 size_flip 呢?
参考答案((c)、(d) 用代码验证过)
(a) 。(b) m = 4 时比值是 6 > 1,m = 3 时是 ,所以 m ≥ 4。(c) m ~ Binomial(8, 0.5),;按 size 回答时查询就答对,所以准确率约 64%,和观察到的 68%(300 道题的抽样波动)一致。(d) 只剩 size 一个用 small / big 的概念,任何标签组合都只能是”带噪声的 size”,贝叶斯最优 100%(作者用代码把 size_flip 的先验设成 0 后验证:1.00)。这正是 Min et al. 现象成立的条件:标签空间唯一确定任务。
练习 3(上下文校准):内容无关的输入得到 P(Positive) = 0.618、P(Negative) = 0.382。一个查询的模型输出是 P(Positive) = 0.55。校准后是多少?预测会变吗?
参考答案
除以内容无关的概率:Positive ,Negative ;归一化后 Positive = 。预测从 Positive 变成了 Negative。如果模型真的偏向 Positive,这是在纠正偏差;如果它对这个查询的 0.55 本来就是对的,校准就把它改错了——§4.4 里大模型的情况。
练习 4(思考:k=32 为什么崩了):§2.3 里两个模型在 k=32 时都崩了,贝叶斯最优不受影响。给出两种解释(结合第 4 讲和第 7 讲),并设计实验区分它们。
参考答案
解释一:位置编码外推(第 4 讲)——32 个示例约 130 个 token,超出了训练时的最大长度(24 个示例约 100 个 token),正弦位置编码在没见过的位置上表现不可靠。解释二:长度分布本身是一个领域(第 7 讲)——模型学会了”一篇文档大约有多少个示例”,从来没见过 32 个示例的文档。区分:(1) 换成相对位置编码(RoPE / ALiBi)或不加位置编码再训练,看 k=32 是否恢复——恢复则主要是位置编码的问题;(2) 保持位置编码不变,训练时把文档长度分布改成”2~8 个和 24~32 个”(中间留空),测 k=16——如果中间长度也失败,说明是长度分布的问题(第 7 讲的内插实验)。
练习 5(思考:Min et al. 现象在什么任务上会失效):根据 §3.3,举出两个真实 NLP 任务,在这些任务上”随机标签几乎不掉分”不太可能成立,并说明原因。
参考答案(举例)
(1) 标签空间被多个任务共用的二分类:例如”这两句话意思相同吗?yes / no”——yes / no 这对标签在网上对应成千上万种任务,只看标签空间认不出是哪个任务,必须靠”哪些输入对应 yes”。(2) 标签和输入之间的映射本身就是要学的东西:例如公司内部的工单分类(标签是内部类别代码,预训练里没有这些代码的含义),或者把颜色映射到一套任意的编码——这相当于我们的 symbol 任务,随机标签就等于没有信息。另外,**标签词有歧义或”有主”**的任务(标签用了日常词、但含义和日常不同)也会出问题(§5.1 的颜色词)。
练习 6(动手:去掉”反着说”的任务):在 icl_world.py 里把 size_flip 的先验设为 0(并重新归一化),不重新训练模型,只重算 §3.2 里 size 任务”随机标签”一格的贝叶斯最优。预测结果,再运行验证。
参考答案
1.00(见练习 2(d))。注意模型不会变——它是在有 size_flip 的语料上训练的;这只是改变了”理想推断者”的先验。这说明”随机标签掉不掉分”完全取决于预训练的任务分布里有没有”别的任务也用这个标签空间”。
练习 7(思考:设计一个思维链没用的训练集):按 §6.2 的逻辑,设计一种训练数据,使得思维链提示不如直接提示。
参考答案
让”直接”的关系大量出现,而”中间步骤”很少或带噪声:例如训练数据里有全部名词的 “x : 动词” 直接示例,却只有很少的 “x : 类别” 示例,或者”类别 → 动词”的示例里有不少错误。这时直接回答是”见过的一步”,思维链反而要经过两个不可靠的步骤,错误会累积。§6.2 的 (b) 已经部分看到这一点:直接示例存在时,思维链对没见过的名词只有 53.5%。这也提醒:对强模型来说,强行要求写出步骤不一定有益,尤其当步骤本身容易出错时。
练习 8(思考:怎样评估过度拒绝):§5.2 用”在 cat 任务里问动物”来测过度拒绝。如果要评估一个真实对齐模型的过度拒绝,你会怎样构造测试集?要注意什么?
参考答案
构造一批形式上像”该拒绝的请求”、实际上完全无害的提示:包含敏感词但意图正当(“怎样杀死一个卡住的 Python 进程”)、涉及敏感话题的正当用途(医学、历史、安全研究的科普问题)、和受限内容同一领域但不同任务(就像”问动物的类别”不同于”问动物的价位”)。同时保留一批真正该拒绝的请求作对照,两者一起报告(只报拒绝率或只报有用率都会误导)。注意:测试集要不断更新、不公开给模型方(否则会被针对性地”修好”——第 7 讲的打补丁问题);要覆盖不同的格式、语言和上下文长度(泛化不匹配);要人工检查”拒绝”的判定(模型可能部分回答、部分拒绝)。
练习 9(思考:为 MMLU 评估做决定):对 §7.2 的 8 个决定,选出你认为最可能大幅改变模型之间的排名的两个,并说明理由。
参考答案(一种看法)
(1) 判断对错的方式(看字母概率、看选项文字概率、还是生成后匹配):小模型或没有指令微调的模型常常不会稳定地输出字母,“看字母概率”会严重低估它们,而”看选项文字概率”受选项长度影响(第 5 讲 §5);同一个模型在不同方式下能差十几个百分点,而且不同模型受影响的程度不同,排名因此改变——Open LLM Leaderboard 的 MMLU 风波正是这样。(2) 模板和指令:模型对提示格式的熟悉程度不同(§2.4),一个模型熟悉的格式可能正是另一个模型不熟悉的;换模板会让不同模型的分数朝不同方向移动。相比之下,示例的数量(5 个 vs 3 个)对强模型的影响通常较小(任务一旦认出,更多示例没用——§2.3)。
9.4 延伸阅读
- 原课阅读:Wei et al. (2022)(思维链);Min et al. (2022), Rethinking the Role of Demonstrations;Carlini et al. (2023), Are aligned neural networks adversarially aligned?
- ICL 的机制:Xie et al. (2022), An Explanation of In-context Learning as Implicit Bayesian Inference;Olsson et al. (2022), In-context Learning and Induction Heads;Wei et al. (2023), Larger language models do in-context learning differently;Wei et al. (2023), Symbol tuning improves in-context learning in language models
- 敏感性与校准:Zhao et al. (2021), Calibrate Before Use;Gonen et al. (2023), Demystifying Prompts in Language Models via Perplexity Estimation;Sclar et al. (2024)(格式敏感性)
- 示例数量:Agarwal et al. (2024), Many-Shot In-Context Learning;Liang et al. (2022)(HELM)
- 思维链:Kojima et al. (2022), Large Language Models are Zero-Shot Reasoners;Prystawski et al. (2023), Why think step by step? Reasoning emerges from the locality of experience
- 对齐的脆弱性:Wei, Haghtalab & Steinhardt (2023), Jailbroken: How Does LLM Safety Training Fail?;Anil et al. (2024), Many-shot Jailbreaking;Röttger et al. (2024), XSTest(过度拒绝)
- 评估与聊天机器人:Fourrier et al. (2023), What’s going on with the Open LLM Leaderboard?;Thoppilan et al. (2022), LaMDA
- 本仓库的相关内容:第 6 讲 §2(提示与 ICL 的来源);第 7 讲 §4(长度是一个领域);CMU17-630(提示工程整门课);CS324 第 5 讲(涌现与上下文学习)
9.5 下一讲预告
LaMDA 的最后一步,是让模型学会在需要时发出搜索查询。语言模型算不准大数乘法、不知道今天的日期、记不住长尾的事实——那就让它调用工具。第 10 讲:LLM 的工具调用。在花园集市里,第 7 讲那个”不会算 20 以上的数”的模型,能不能学会在需要的时候按一下计算器?它怎样学会”什么时候调用、用什么格式调用”?工具返回的结果被篡改了,它会怎样?