LLM 到底是怎么写字的?
一次一个 token,每个都以之前的一切为条件。这个生成循环解释了流式输出、成本,以及模型为什么改不了。
先动手,再深入阅读
一步一步形成续写 · 5 分钟到目前为止的整段序列会重新喂回去。模型预测一个 token——Paris——把它接上去,再跑一遍。
模型不是先构思好一整段回答。它是一个 token 一个 token 往前垒的,没有计划,也回不了头。
就这一件事,解释了流式界面、对话成本、思维链提示为什么有效,以及模型为什么有时把自己逼进死角还继续往前走。
循环
假设你发过去 The capital of France is。
第 1 步。 模型处理这个序列,在整个词表上输出一个概率分布。␣Paris 拿走大部分概率质量,剩下由成千上万个别的 token 瓜分。
第 2 步。 采样(sampling)挑出一个 token。比如 ␣Paris。
第 3 步。 把这个 token 接在后面。序列现在是 The capital of France is␣Paris。
第 4 步。 整串再送回去。再预测一次。
如此重复,直到模型吐出停止 token 或撞上长度上限。一个 500 token 的回答,意味着过 500 遍网络。
这就是**自回归(autoregressive)**的含义:每个输出都会成为下一次输入的一部分。
四个后果
它改不了
一个 token 一旦吐出来就定死了。模型没办法回头改它。
看看这会带来什么。如果模型开头写了 The three main causes are:,而像样的原因只有两个,它会硬编出第三个——句式已经把它架住了。人类写作者会删掉这个句子。模型删不了。
这是幻觉的一个机械根源:不是无知,而是一旦承诺了某个结构,就必须填上内容。
把思考写出来真的有用
每个 token 只有一次前向计算。一个难题用一个 token 答完,就只有一次思考。
但如果模型把中间步骤写出来,每一步都是一个 token,每个 token 都有自己的一次计算——而且之前所有步骤都作为输入摆在眼前。生成出来的文本就成了工作记忆。
所以「一步一步想」不是什么心理暗示。它把一个单次计算的问题变成了多次计算。参见让模型一步步思考。
流式输出是天然的形态
token 是依次产生的,所以一出现就能发出去。流式输出(streaming)不是浮在表面的一层 UI 花活,它就是这个过程原本的形状。参见响应为什么要流式输出。
对话成本是平方级增长的
模型在两次调用之间没有记忆。每一轮都把整份历史当作输入重发一遍。
第 1 轮发 100 个 token。第 2 轮发 100 个加上回复加上新问题。第 10 轮把前面九轮产出的一切全部重发。一段 n 轮的对话,总 token 数按 n² 增长,而不是 n。
这就是为什么一份长文档可能比一段短对话还便宜,也正是 KV cache 要缓解的问题。
随机性从哪来
如果第 2 步永远挑概率最高的那个 token,输出就是确定性的——而且明显更差。贪心解码会产出重复、平淡、卡在循环里的文本。
所以采样这一步是故意引入随机性的。这就是同一个 prompt 每次给出不同答案的原因,也是设计选择,不是缺陷。控制手段见温度与 Top-p。
停下来
生成结束有三种方式:模型吐出它在训练中学到的特殊序列结束 token;撞到最大 token 数上限;或者你指定了停止序列,API 一见到它就切断。
输出被截断,通常是第二种。要么调高上限,要么少要一点。
要点回顾
- 生成是一个循环:预测分布、采样一个 token、接上去、再来一遍。
- 改不了——一旦承诺了结构就必须填满,这是幻觉的一个根源。
- 每个 token 只有一次前向计算,所以把推理写出来是真的在增加计算。
- 对话成本随长度的平方增长,因为历史每轮都要重发。
下一篇: 温度和 top-p 详解 —— 第 2 步上的那两个旋钮。