09 课 · 大模型解码
LESSON 09 · 卷九 开口

让它开口说话

第 8 课那个模型只会吐一次分数:给一段前文,输出「下一个字」的概率分布。 它不会自己往后写一个字。要让它说话,得我们给它接一个循环:挑一个字 → 接到后面 → 再问一次,直到它吐出结束符。 这一课就把这个循环装起来,顺便把三个旋钮搞明白:温度(敢不敢冒险)、top-k / top-p(先砍掉长尾)、贪心(永远挑第一名)。 最后一站学一件更重要的事——诚实地评估

STAGE 01
接一个循环
逐字往外蹦
STAGE 02
温度
把分布压尖或抹平
STAGE 03
top-k / top-p
先砍长尾,再抽签
STAGE 04
诚实地评估
分题型、看考卷

先让它说一句话。下面就是那个循环:每点一下,它挑一个字接在后面。 三个旋钮随便拖,看结果怎么变。

招牌动画逐字生成 —— 温度、top-k、贪心,看着它一个字一个字往外蹦
十五加一百一十五等于?
真答案是「一百三」。 每一步只多看一个字,所以它只会「接龙」,算不对 —— 这正是第 14 课要解决的问题。
温度 T(只在前 k 个里抽签1.0
top-k 的 k5
看「?」后面该接谁 —— 5 个候选(灰色的被砍掉了)
留下来 21.9%
21.9%
留下来 21.8%
21.8%
留下来 20%
20%
留下来 19.8%
19.8%
留下来 16.5%
16.5%
被砍掉(原来 9.7%)
被砍掉(原来 9.4%)
被砍掉(原来 8.7%)
被砍掉(原来 8%)
被砍掉(原来 5.5%)
被砍掉(原来 0.2%)
现在已经生成到「(还没开始)」。 点「生成下一个字」或「自动播放」开始。
三个旋钮一句话记住:温度管「分布有多尖」(冒险程度)、top-k / top-p 管「先砍掉多少长尾」(别抽到离谱的字)、贪心就是「永远取第一名」。温度 只改分布形状,不改顺序
👆 拖温度:看下面那排条怎么从「一枝独秀」变成「一片平原」。 切到 top-k 把 k 调到 1,它就和贪心一模一样; 切到 top-p,p 调到 0.5 时只有前 5 个候选还能被抽到。 点「🎲 再抽一次签」= 换一批随机数,同一个模型会给出不同的答案。
它每步只看前一个字(这一课的「模型」就是从语料里数出来的下一个字分布), 所以生成的东西像模像样、却常常算错 —— 这正好说明「会接龙」和「真会算」是两件事(第 14 课解决)。
图 9-1 · 循环:前文 → 模型给分布 → 按旋钮挑一个字 → 接到后面 → 再来一次
模型只负责给分布,
「怎么挑」是的事。

三句话讲完这一课

  • 解码 = 一个循环:挑一个字 → 接到后面 → 再问一次, 直到吐出结束符。模型自己不循环,循环是我们写的。
  • 温度管「有多敢」:T < 1 更保守(分布被压尖)、T > 1 更冒险(被抹平)。 它不改顺序,只改「第二名还有没有机会」。
  • top-k / top-p 管「别抽到离谱的字」:先砍掉长尾,再在剩下的里面按比例抽签。 贪心就是「只留第一名」的极端情况。
这一课的「模型」是什么(重要,别误会)

页首那个模型不是 Transformer,而是从语料里数出来的「下一个字分布」: 看前一个字,数它在语料里后面接过谁。为什么要这么干?

语料里有下一个字统计的字:20
「?」后面一共接过 11 种字,前 5 名: 九 12.8、二 12.8、三 11.7、四 11.6、八 9.7

好处是它可复现、每个数都能核对,而「温度 / top-k / top-p / 贪心」 这套解码机制一模一样 —— 换成真模型,只是把这张分布表换成模型吐出来的那张。 等第 14 课训出真模型,这个循环一个字都不用改。

第 1 站

温度:冒险旋钮

第 8 课的最后一步吐出来的是 11 个候选字的分数。要挑一个字, 最直接的做法是永远挑最高的(贪心)——稳,但死板: 同一个问题永远同一个答案。

想让它灵活一点,就得按概率抽签。而抽签之前, 你可以先拧一个旋钮:温度。它的作用就一句话:把分布压尖(保守)或者抹平(冒险)

温度到底做了什么
把每个概率开 1/T 次方,再归一化:p′ᵢ = pᵢ^(1/T) ÷ Σ pⱼ^(1/T)

T < 1 时,大的更大、小的更小(分布变尖);T > 1 时反过来(变平)。 注意它不改大小顺序:第一名永远是第一名,改的是「第二名还有多少机会」。

同一张分布(「?」后面)最大的一份:T=0.2 → 24.1;T=0.5 → 15.8;T=1 → 12.8;T=1.5 → 11.8;T=2 → 11.2
第 1 名 ÷ 第 2 名:1.03 / 1.01 / 1.01 / 1.00 / 1.00

还有个更能说明问题的量:平均「抽中的那个字当时有多少概率」。 跑 8 遍取平均:T = 0.2 时是 41.3,T = 1.0 是 33.4, T = 2.0 是 30.4 —— 温度越高,抽中的字越冷门

动手实验温度拧一拧 —— 同一个问题跑 10 遍,会生成出几条不一样的话
温度 T0.2
直接跳到 
① 第 1 名 ÷ 第 2 名(温度越高,前两名越「平等」)
1.03
T = 0.2 时:1.03
T = 2.0 时:1.00
② 跑 10 遍,平均「抽中的字当时有多少概率」
85.6%
T = 0.2 时:85.6%
T = 2.0 时:49.9%
③ 跑 10 遍,生成出几条不同的句子
3 / 10
T = 0.2 时:3
T = 2.0 时:10
同一个问题跑 10 遍 —— 颜色和符号一样的,就是生成得一模一样的两条
1十五加一百一十五等于?九百一百一百
2十五加一百一十五等于?二十二十二十
3十五加一百一十五等于?二十二十二十
4十五加一百一十五等于?二十二十二十
5十五加一百一十五等于?二十二十二十
6十五加一百一十五等于?九百四十二十
7十五加一百一十五等于?二十二十二十
8十五加一百一十五等于?二十二十二十
9十五加一百一十五等于?九百一百一百
10十五加一百一十五等于?九百一百一百
T = 0.2:同一个问题「十五加一百一十五等于?」跑 10 遍,生成出 3 条不同的句子7 条和别人撞了,最多的一种出现了 6 次)
同一张分布、同一套设置,只有温度变了:第 1 名 ÷ 第 2 名 1.03, 抽中的字平均有 85.6% 的概率,10 条里 3 条不一样。
温度低 → 模型几乎每次都挑那几个「安全」的字,10 遍下来高度重复; 温度高 → 冷门的字也敢抽,每一遍都是新句子。温度不是「模型好不好」的旋钮,是你有多需要确定性的旋钮。
👆 拖上面的「温度 T」(或点 T = 0.2 / 2.0):三样读数同时变 —— ① 前两名越来越平等、② 抽中的字越来越冷门、③ 10 条从「挤成几条」散成「每条都不一样」。 这个实验固定一套设置:先砍长尾(只留累计概率刚过 25% 的候选,第 2 站细讲),每次最多写 6 个字 —— 所以②的数值和上面正文那组(固定 top-k = 5)不同,机制完全一样,只是固定设置不同。
先拖「温度 T」,从 0.2 一路拖到 2.0,盯住三样东西: 前两名的差距、抽中的字有多热门、10 条生成结果里有几条是重复的。 温度越低越像「背答案」(10 条挤成几条),越高越像「每次都在即兴发挥」。
图 9-2 · 温度 = 确定性旋钮:T = 0.2 时 10 遍只生成出 3 条不同的句子,T = 2.0 时 10 条全不一样
那生成「代码」「数学答案」这类任务时,温度应该调高还是调低?为什么?
第 2 站

top-k 与 top-p:先砍长尾

光有温度还不够:分布的长尾里总有几个概率很小但很离谱的字。 哪怕只有 0.5% 的概率抽到它,一旦抽中,整句话就毁了。 所以现代模型几乎都会先做一步截断

核心实验同一张分布,三种砍法 —— 砍完之后重新分配 100%
温度 T1.0
top-k 的 k3
top-p 的 p0.90
① 原始分布温度 T = 1.0
12.8%
12.7%
11.7%
11.5%
9.7%
9.6%
9.4%
8.7%
8%
5.5%
0.2%
这一列有 11 个候选,加起来 100%
② top-k = 3留 3 个,砍掉 8 个
34.4%
34.2%
31.3%
这一列有 3 个候选,加起来 100%
③ top-p = 0.90留 9 个(累计刚过 0.90 就停)
13.6%
13.5%
12.4%
12.3%
10.3%
10.2%
10%
9.2%
8.5%
这一列有 9 个候选,加起来 100%
看「?」后面该接谁。三列是同一张分布,只是「砍法」不同:
top-k:留下最可能的 3 个,砍掉 8 个 —— 砍掉之前它们一共占 37.2 的质量。
top-p:从高到低累加,累计刚过 0.90 就停,留下 9 个 —— 砍掉之前它们占 94.2
两列砍完之后都重新分配成 100%:这就是「先在靠谱的字里抽签」—— 既保留了随机性(不像贪心那么死板),又不会抽到长尾里那些离谱的字。top-k 按「个数」切,top-p 按「概率质量」切 —— 后者会随分布形状自动变宽变窄, 所以现在的模型更常用它。
👆 三个滑块随便拖:温度把分布压尖或抹平之后,同一组 k、p 切出来的东西也跟着变。 把 k 拖到 1:只剩第一名,和贪心等价。把 p 拖到 0.5:只剩前几个候选。 注意灰掉的那些条(在「原始分布」那一列还能看到它们原来的样子)。
被砍掉的候选在「原始分布」那一列还能看到(灰的)。 注意砍完要重新归一化:留下的几个重新瓜分那 100%。
图 9-3 · top-k 按「个数」切,top-p 按「概率质量」切;两者都必须重新归一化
面试常问 · 解码这几件事
  • 贪心能不能保证全局最优:不能。每一步都取最高分,得到的只是 「贪心路径」,后面可能走进死胡同 —— 这也是要采样、要 beam search 的原因。
  • 温度放在 softmax 前还是后:前(除以 T)。放后面没有意义 (概率再除一个数,加起来就不是 1 了)。
  • 为什么 top-p 比 top-k 常用:分布尖的时候 top-p 自动只留两三个, 平的时候自动放宽;top-k 不管分布什么样都留固定 k 个。
  • 它们能一起用吗:能,而且是常规操作(先温度、再 top-k、再 top-p)。 页首动画里三个旋钮就是串在一起生效的。
第 3 站

诚实地评估:分题型、看考卷

模型能说话了,接下来的问题是:它到底行不行?这件事比看起来难 —— 一不小心就会骗到自己。 下面这张表是真跑出来的实测记录(第 7 阶段的训练), 考卷是「四种题型各 150 道」:

核心实验分题型看准确率 —— 整体分数会骗人,换考卷更会骗人
训练到训练 loss 0.038(同一张考卷,每 500 步考一遍)
整体(600 道混在一起)四种题型各 150 道
57.5%
加法150 道
95.3%
减法150 道
96%
乘法150 道
13.3%
除法150 道
25.3%
2000 步时:整体 57.5%,可拆开看是—— 加法 95.3%、减法 96%、乘法 13.3%、除法 25.3%。最好和最差差了 82.7 个百分点。
只看整体 57.5%,你永远发现不了「加减已经 99%、乘除还在 30% 上下」这件事 —— 而这两件事要的解决办法完全不同。所以评估必须分题型看。
还有个细节:训练 loss 到 2000 步已经低到 0.038 了, 考卷却停在 57.5% 附近 —— 这说明它不是没练够,是容量装不下(第 14 课)。
换考卷不用重新训练 —— 自己拧「加法题占多少」试试 ↓
加法占比25%
直接跳到 
你自己出的这张考卷(600 道)加法 150 道 | 减法 150 道 | 乘法 150 道 | 除法 150
57.5
加法150 道 × 答对 95.3%
25%
减法150 道 × 答对 96%
25%
乘法150 道 × 答对 13.3%
25%
除法150 道 × 答对 25.3%
25%
同一份训练(2000 步)、同一个模型,只改考卷里加法占多少: 加法 25% → 折算分数 57.5
折算 = 95.3% × 150 + 96% × 150 + 13.3% × 150 + 25.3% × 150= 142.95 + 144 + 19.95 + 37.95 = 344.85 道答对 →344.85 ÷ 600 道 = 57.5%(也就是 57.5 分)
加法拖回 25%,你手里这张就是上面那张「四种题型各 150 道」(57.5%)。 往右拖、加法越多,分数越高 —— 因为模型恰好加减强、乘除弱。 实测记录里(8000 步那一列),把考卷从「四种题型各 150 道」(66.5%)换成 「随机抽 500 道(加法占一半多)」(94.2%), 同一份训练、同一个模型,分数直接差 27.7—— 所以看到任何分数之前,先问一句:考卷是怎么出的?
换一张考卷,同一个模型能差多少(同一份训练)↓
随机抽 500 道(加法占一半多)2000 / 4000 / 8000 步:85.2% / 91.4% / 94.2%
85.2%
四种题型各 150 道(均分)2000 / 4000 / 8000 步:57.5% / 63.5% / 66.5%
57.5%
同一份训练、同一个模型,只是换了考卷: 随机抽 500 道(加法占一半多)比「四种题型各 150 道」高出 27.9
分数是「模型 × 考卷」共同决定的。所以看到任何分数之前,先问一句:考卷是怎么出的?随机抽的考卷里加法占大头,而这个模型恰好加减强、乘除弱 —— 分数自然虚高。
👆 切上面的步数按钮,看四种题型一起涨:加减早早到 99%, 乘除爬得很慢(它们是瓶颈)。再拖「加法占比」滑块:模型一动没动, 只是考卷里加法多了几道,整体分数就跟着往上走。 这一站的数据是实测记录,来自第 7 阶段的真实训练,页面上不重算 (训练结果没法「当场算」)—— 你自己那张考卷的分数,是拿各题型的答对率照着算出来的。
两个坑:①只看整体(会把 99% 和 31% 抹平成 66%);②不交代考卷(同一份训练换张考卷能差 27.9 分)。
图 9-4 · 整体 66.5% = 加法 99.3% + 减法 98.7% + 乘法 30.7% + 除法 37.3%

这两件事合起来就是这一课最值钱的一句话:分数是「模型 × 考卷」共同决定的。 所以看到任何分数之前,先问两个问题:考卷是怎么出的?分题型看是多少?

如果你要向上级汇报「我的模型准确率 94%」,你会怎么把这句话说得诚实?
第 4 站 · 收官

把这一课钉在墙上

本课核心 · TAKEAWAY

模型只做一件事:给前文,吐下一个字的分布。要它说话, 得我们自己接一个循环:挑一个字 → 接到后面 → 再问一次 → 直到吐出结束符。 「怎么挑」就是解码策略:贪心永远取第一名(稳、死板);采样按概率抽签(灵活、可能离谱);温度把分布压尖或抹平(只改形状不改顺序,T = 0.2 时最大一份 24.1%,T = 2 11.2%);top-k / top-p 先砍掉长尾再抽签(前者按个数、后者按概率质量), 砍完必须重新归一化。 最后是评估:分数是「模型 × 考卷」共同决定的 —— 必须分题型看(同一份训练里加法 99.3%、乘法 30.7%), 也必须交代考卷(换一张差 27.9 分)。

这一课你亲手做完了

  • 接上了循环:从「十五加一百一十五等于?」开始,一个字一个字生成到 6 个字, 真答案「一百三」它常常算不对 —— 因为它只看得到前一个字。
  • 拧过温度:最大一份从 24.1(T=0.2)摊到 11.2(T=2.0);平均抽中的字从 41.3 冷到 30.4
  • 砍过长尾:top-k = 3 时留下 37.3% 的质量、砍掉 62.7%; top-p = 0.5 留 5 个、0.95 留 10 个,砍完都重新分配成 100%。
  • 验证过「top-1 = 贪心」:把 k 调到 1,生成结果完全固定。
  • 学会了诚实评估:分题型(加法 99.3% vs 乘法 30.7%,差 68.6 个百分点)、 看考卷(同一份训练换考卷差 27.9 分)。

学习小测验

已完成 0 / 60.0%答对 0
还没提交过 —— 每题先选一个选项,再点「提交」,答完就能看到诊断。
Q1模型本身只会做一件事。要让它「说话」,必须自己接一个什么?
Q2温度 T 是在哪一步起作用?
Q3把 top-k 的 k 调成 1,会发生什么?
Q4top-k 和 top-p 的区别是什么?
Q5为什么评估必须「分题型」看?
Q6同一份训练、同一个模型,为什么换张考卷分数能差二十多分?
NEXT · 第 10 课

损失函数与梯度:模型怎么知道自己错了

到这儿,前向这条路已经全部打通了:从切字一直到吐出下一个字。 可模型里的每一个数字是怎么变好的?它还一次都没学过。 下一课补上另一半:交叉熵(模型对正确答案有多惊讶)、梯度(往哪个方向拧能少惊讶一点)、学习率(一次拧多大)。 这一课之后,你就具备了「亲手把它训出来」的全部零件。

从零手册 —— 下一课:损失函数与梯度:模型怎么知道自己错了