我们以为模型「写出了一句话」。其实它一次只往前走一个 token,然后把刚写出的 token 接回输入, 重新算一遍,再走一个。这个「吐一个、接回去、再吐一个」的循环,叫 自回归(autoregressive)生成。1
输入:「猫坐在」
→ 模型算出下一个 token 的概率分布 → 挑中「垫子」
输入:「猫坐在垫子」
→ 再算一次分布 → 挑中「上」
输入:「猫坐在垫子上」
→ 再算一次 → 挑中「。」(句号,结束)
关键的反直觉点在这里:模型并没有「想好一整句再写」。它对第 10 个字的规划, 完全发生在它已经写完前 9 个字、第 10 次调用自己的那一刻。 —— 这一条之后会反复回来咬你:它解释了为什么模型「数不清自己写了几个字」、为什么它会顺着一个错误的开头一路编下去。
模型每往前走一个 token,内部都走同一条流水线:
| 步骤 | 发生了什么 | 产物 |
|---|---|---|
| 1. 前向计算 | 把当前文本喂进网络(注意力 + 若干层),最后吐出一串「原始分数」 | logits:词表里每个 token 一个分数 |
| 2. Softmax | 把这串分数压成「加起来 = 1」的概率 | 一个概率分布 |
| 3. 采样 | 按概率从分布里挑一个 token(这一步才用到 temperature / top-p) | 1 个 token |
| 4. 拼接 & 回到第 1 步 | 把挑中的 token 接到文本末尾,重新跑 | 更长的文本 |
| 你遇到的现象 | 用「概率分布」一句话解释 |
|---|---|
| 同样的 prompt,输出每次不一样 | 第 3 步是随机采样,不是取最大值。除非你把 temperature 设 0。 |
| 调高 temperature → 更「有创意」也更容易胡说 | temperature 把分布压平,本来概率很低的怪 token 也有机会被抽中。 |
| 模型一本正经地编(幻觉) | 分布里「听起来最顺」的 token 概率最高,而「顺」≠「真」。它永远在挑最像的,不是最对的。 |
| 顺着一个错开头越编越离谱 | 第 4 步把错 token 接回输入,下一步就在「错误前提」上继续算分布。错误会自我强化。 |
| 让它「数 strawberry 里有几个 r」常出错 | 它没在「数」,它在挑下一个最可能的 token;数数不是这条流水线擅长的事。 |
下面是一组固定的 logits(模型对「猫坐在 ___ 上」给每个候选 token 打的原始分数)。 拖动 temperature,看 softmax 之后的概率分布怎么变。别背公式,先建立手感。
把滑块拖到 最左(0.1):分布几乎全压到「垫子」一个 token 上——这就是 贪婪解码 / temperature≈0,几乎确定、可复现、但呆板。 拖到 最右(2.0):分布被压平,连「薛定谔」这种离谱 token 都分到了可观概率——这就是「有创意」与「胡说」的同一个来源。
| 你的场景 | 其实是在这条流水线的哪一步做选择 |
|---|---|
| 语音客服 agent 要「稳」,话术不能跑偏 | 调低 temperature / 用 top-p 收窄——让第 3 步只在分布的「头部」挑,牺牲多样性换稳定。 |
| 要 agent 文案有变化、不千篇一律 | 反过来,适度抬高 temperature,让第 3 步能碰到分布的「腰部」。 |
| LLM 评分器(LLM-as-judge)要可复现地打分 | temperature=0,让第 3 步退化成「永远取最大」,同输入同输出。 |
| prompt 自动调优环(生成→评分→改 prompt 的闭环)在「优化 prompt」 | 本质是在改第 1 步的输入,从而改变整个分布的形状——prompt 工程 = 给分布动手术。 |
Jay Alammar — The Illustrated GPT-2: 用图把「自回归生成循环」讲透,看「Auto-Regression」那一节就够本课了(约 15 分钟)。
想要总览版心智模型:Karpathy — Intro to Large Language Models(1 小时)。
参考:
1. Alammar, The Illustrated GPT-2(autoregression);Karpathy, Intro to LLMs;3Blue1Brown, Transformers 系列。