第 9 讲:上下文学习与模型对齐的意外行为

Large Language Models: Methods and Applications · Lecture 09。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

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

本篇目录

对应原课: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. 本讲导读

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 / hungry0.15
color(颜色)red / green / yellow / white0.15
size(大小)small / big0.12
price(价位)cheap / dear0.12
animal(是不是动物)yes / no0.12
flower(是不是花)yes / no0.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 种映射。给定示例,贝叶斯后验 P(θ∣示例)P(\theta \mid \text{示例}) 可以精确算出:每个示例在概念 θ 下的似然是 1−ϵ1-\epsilon(标签正确)、ϵ/(∣Yθ∣−1)\epsilon/(|\mathcal{Y}_\theta|-1)(标签在 θ 的标签空间里但不对)或 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 的示例就是推断概念的证据:

P(y∣示例,xq)=∑θP(θ∣示例) P(y∣xq,θ).P(y \mid \text{示例}, x_q) = \sum_\theta P(\theta \mid \text{示例})\, P(y \mid x_q, \theta).

这就是隐式的贝叶斯推断。在我们的世界里,右边每一项都可以精确算出来。

2.2 推断是怎样一步步进行的

代码 01 §1,一道 animal 任务的题,后验概率最大的 3 个概念:

已有的示例后验最大的 3 个概念
(没有)symbol 0.18,cat 0.15,color 0.15
carrot:noanimal 0.50,flower 0.50,animal_flip 0.01
carrot:no hen:yesanimal 0.90,flower 0.10,animal_flip 0.00
carrot:no hen:yes lilac:noanimal 0.99,flower 0.01,animal_flip 0.00

第一个示例的标签 no 就把标签空间之外的任务全部排除(剩下的只有用 yes / no 的几个);接下来要靠”哪些名词是 yes”来分辨 animal 和 flower(练习 1 手算这几步)。

2.3 示例越多越好吗?

代码 01 §2(每格:小模型 / 大模型 / 贝叶斯最优;每个 k 300 道题;预训练文档最多 24 个示例):

任务k=0k=1k=2k=4k=8k=16k=32
cat.02/.00/.001.00/1.00/1.001.00/1.00/1.001.00/1.00/1.001.00/1.00/1.001.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.001.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.50.28 / 5.10.97 / 3.50.74 / 4.5
x -> y ,(25%)0.74 / 3.70.28 / 5.40.97 / 3.60.73 / 4.8
x = y |(5%)0.76 / 4.00.29 / 5.80.97 / 3.90.74 / 5.1
x -> y ;(组合没见过)0.74 / 20.00.28 / 24.00.97 / 42.70.73 / 65.3
x ~ y &(符号没见过)0.00 / 45170.04 / 66690.83 / 154900.00 / 30445

预训练里出现过的三种格式,困惑度随格式变少见而略升,准确率几乎不变。只是组合没见过(两个符号都见过):困惑度升高十几倍,准确率却完全不变——模型照样认出了任务。符号本身没见过:困惑度上千,准确率崩溃。Gonen et al. 的趋势在极端情形下清楚可见,但它不是严格的定律:困惑度只是”熟悉程度”的一个粗略代理。


3. 示例里什么最重要

3.1 Min et al. 的发现

Min et al. (2022) 把少样本示例的标签换成随机标签,在很多分类和多选任务上,ICL 的准确率只下降一点点。他们把示例拆成四个方面分别检验:

  1. 输入和标签的对应关系(映射);
  2. 输入的分布(示例的输入像不像任务的真实输入);
  3. 标签空间(示例里出现的是不是这个任务的那些标签);
  4. 格式(输入和标签成对出现的样子)。

结论:后三者很重要,第一个出人意料地不太重要。slides 的说法是:“少样本示例的标签对不对,在分类任务里没那么要紧。”

3.2 实验:六种示例

代码 02,8 个示例,300 道题(每格:小模型 / 大模型 / 贝叶斯最优;”—“表示贝叶斯模型里没有这种情况):

任务不给示例正确标签随机标签错的标签空间输入换成别的词只有输入
cat.03/.00/.001.00/1.00/1.001.00/1.00/1.00.00/.00/.00.26/.43/—.29/.00/—
color.12/.29/.001.00/1.00/1.001.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 解读:什么时候标签的对错不重要

  1. **标签空间独一无二的任务(cat、color):随机标签和正确标签一样好。**标签空间本身就认出了任务,任务的映射早在预训练里学会了,示例里的对应关系对不对无关紧要。这就是 Min et al. 在真实 LLM 上看到的现象,贝叶斯最优给出了同样的结论。
  2. size:small / big 也被一个罕见的”反着说”任务(size_flip,先验 2%)共用。随机标签让贝叶斯最优犹豫了——一半的示例看起来像反着说——准确率掉到 68%(练习 2 精确算出这个数);小模型完全不受影响(99%)、大模型只掉到 89%。两个模型都比贝叶斯最优更”固执”地相信常见的任务。
  3. animal:yes / no 被几个任务共用,只有”对应关系”能把它们分开,随机标签让准确率退回到和不给示例差不多。symbol:映射完全靠示例给出,随机标签 = 没有信息。
  4. 错的标签空间:所有人都输出那个错的标签空间里的词,准确率归零——标签空间是最强的线索。
  5. 输入换成别的词:即使标签空间正确,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.470.45~0.630.32~0.43…0.38~0.550.143
大模型1.00~1.001.00~1.001.00~1.00…1.00~1.000.000
贝叶斯1.00~1.001.00~1.001.00~1.00…1.00~1.000.000

贝叶斯最优对顺序完全不敏感——示例是可交换的证据,乘法不在乎顺序。大模型同样不敏感,而且全对。小模型随顺序波动十几个百分点,而且整体低于 50%(查询一半是动物,乱猜也有 50%),它的 yes / no 和真实答案系统性地错位:它没认对任务。顺序敏感是”没能稳健地推断出任务”的症状。

4.3 实验:多数标签

代码 03 §2:8 个示例,其中 n 个是动物(yes);300 个查询,一半是动物(每格:预测 yes 的比例 / 准确率):

n=1n=4n=7
小模型0.17 / 0.450.15 / 0.400.62 / 0.23
大模型0.53 / 1.000.53 / 1.000.49 / 1.00
贝叶斯0.53 / 1.000.53 / 1.000.49 / 1.00

贝叶斯最优和大模型:示例里 yes 多少,对预测毫无影响——只要能认出任务,答案就由查询本身决定。小模型:7 个 yes 时,它把六成的查询都答成 yes,准确率跌到两成多——典型的多数标签偏差。(我们的小模型没有表现出近因偏差,这里不列。)

4.4 上下文校准

Zhao et al. 的补救办法分两步:

  1. 估计偏差:不需要标注数据。把查询换成一个”内容无关”的输入(例如 “N/A”),看模型对各个标签的概率。slides 的例子:情感分类的模板下,模型对 “N/A” 给出 P(Positive) = 0.618、P(Negative) = 0.382——它偏向 Positive。
  2. 抵消偏差:对 logits 做一个仿射变换 Wp+bW\mathbf{p} + \mathbf{b}(WW 是对角矩阵),让内容无关的输入的输出变成均匀的(0.5 / 0.5)。最简单的版本就是把每个查询的概率除以内容无关输入的概率,再归一化(练习 3)。生成任务则校准第一个 token 在整个词表上的概率。

代码 03 §3 用 <null> 作内容无关的输入(每格:校准前 → 校准后的准确率):

n=1n=4n=7pcfp_\text{cf}(yes) 的平均
小模型0.45 → 0.450.40 → 0.400.23 → 0.300.56
大模型1.00 → 0.751.00 → 0.771.00 → 0.780.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=2k=4k=8k=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=2k=4k=8k=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.001.000.000.000.000.000.00
弱对齐(30 步)0.761.000.540.220.000.140.00
中等(60 步)1.001.001.001.000.951.000.00
强对齐(300 步)1.001.001.001.001.001.001.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 的五条建议

  1. 更多示例:有示例很重要;在长上下文模型上,many-shot ICL 持续好于少样本(Agarwal et al. 2024)。该论文还提出两个变体:强化 ICL(reinforced ICL)——用模型自己生成、并且验证过答案正确的推理过程代替人写的推理过程;无监督 ICL(unsupervised ICL)——提示里只放输入、不放答案。many-shot ICL 在一些任务上能和监督微调相当,也能克服预训练的偏好(翻转标签、抽象标签)。
  2. 校准 logits(§4.4)。
  3. 思维链(§6)。
  4. 更好的模型:随着新一代 LLM 越来越多地经过指令微调,费力的提示工程没那么必要了,但并没有完全消失;即使今天的”预训练”模型,也常常见过不少指令跟随的数据。
  5. 把复杂任务拆成小单元:对复杂的生成任务,多次调用 LLM 通常比一个提示让它一次做完所有部分效果更好、也更容易评估。例如写短篇小说:(a) 先生成梗概;(b) 根据梗概生成人物表和事件序列;(c) 根据以上全部生成正文。拆分降低了每次调用的复杂度,也让人可以在中间介入。

slides 的总结:ICL 的工作方式可能违反直觉,但我们对什么重要、什么不重要的理解在不断进步。

7.2 用少样本评估 LLM:要做的决定

slides 用一个练习收尾:你要用少样本学习评估一个预训练 LLM 在 MMLU 验证集上的能力,怎样设计实验?要做的决定至少有:

  1. 多选题放在什么模板里?
  2. 用几个示例?
  3. 要不要额外的指令?
  4. 指令里要不要写学科(数学、经济、历史……)?
  5. 示例要不要和目标题目同一学科?
  6. 每个示例里,正确答案放在哪个选项位置?
  7. 验证集的每道题用同一个提示,还是每道题随机选示例?
  8. 判断对错时,看字母 {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 亿段对话(爬取有对话交流的网站)。
  • 微调流程:
    1. 让众包工作者和一个 LaMDA 实例聊几轮,收集几千段对话,话题不限;
    2. 另一批众包工作者给对话打分:是否合理(sensible)、具体(specific)、有趣(interesting)、安全(safe);
    3. 微调预训练的 LaMDA 来预测这些评分,得到判别器;
    4. 用判别器给从预训练数据里采样的 250 万条话语打标签;
    5. 在判别器认为”合理、具体、有趣、安全”的 80 万条话语上微调预训练的 LaMDA;
    6. 再在 4000 段对话上微调——这些对话由众包工作者修改过,加入了从网络搜索得来的事实。这让模型在推理时能发出搜索查询(第 10 讲的工具调用)。

注意第 3~5 步的思路:“用人的评分训练一个判别器,再用判别器筛选大量数据”——这正是后来 RLHF 里”奖励模型”的雏形(第 18 讲),也和第 8 讲”从偏好里学奖励模型”一脉相承。


9. 小结、常见误区、练习

9.1 小结

  1. ICL 是隐式贝叶斯推断:示例是推断”当前任务”的证据;在知道一切的小世界里,大模型几乎达到贝叶斯最优,小模型只会用最显眼的线索(标签空间)。任务一旦认出,更多示例没用;映射要从示例读出时,示例越多越好;超出见过的长度,示例反而有害。
  2. 示例里什么重要:标签空间是最强的线索,输入分布和格式也重要;“标签对错不重要”只在任务能被别的线索认出、映射已学会时成立——共享标签空间、抽象标签时,对错决定一切。
  3. 顺序与多数标签:理想的推断者对顺序和标签比例完全不敏感;这些敏感是模型没学好推断的症状。上下文校准只治”标签先验偏移”这一种病,用在没病的模型上反而有害。
  4. 先验与对齐:示例只能在预训练见过的任务里挑;先验里有对应的概念、模型又足够大时,才能跟着翻转的示例走;“有主”的标签词会压过示例。微调出的拒绝行为是浅层的:多示例、换格式能绕过,拉太紧又会过度拒绝。
  5. 思维链:它的价值来自训练数据的局部性——变量很少直接一起出现时,先推出中间变量才有用。
  6. 评估:少样本评估要做至少八个决定,每个都会改变分数和排名;不同设置的数字不能放在一起比。
  7. 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) P(size)P(size_flip)=0.120.02⋅0.9m 0.18−m0.1m 0.98−m=6⋅92m−8\frac{P(\text{size})}{P(\text{size\_flip})} = \frac{0.12}{0.02} \cdot \frac{0.9^m\, 0.1^{8-m}}{0.1^m\, 0.9^{8-m}} = 6 \cdot 9^{2m-8}。(b) m = 4 时比值是 6 > 1,m = 3 时是 6/81<16 / 81 < 1,所以 m ≥ 4。(c) m ~ Binomial(8, 0.5),P(m≥4)=1−(1+8+28+56)/256=0.637P(m \ge 4) = 1 - (1 + 8 + 28 + 56)/256 = 0.637;按 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 0.55/0.618=0.8900.55 / 0.618 = 0.890,Negative 0.45/0.382=1.1780.45 / 0.382 = 1.178;归一化后 Positive = 0.890/(0.890+1.178)=0.430.890 / (0.890 + 1.178) = 0.43。预测从 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 以上的数”的模型,能不能学会在需要的时候按一下计算器?它怎样学会”什么时候调用、用什么格式调用”?工具返回的结果被篡改了,它会怎样?

← 返回课程目录