拆大模型 01|一个字一个字蹦出来的回答:LLM 的工作循环
一、先破一个幻觉:AI 不是想好再回答
大部分人对大模型有个默认想象:你提问,它在"脑子里"思考、组织语言、打腹稿,然后一口气把答案说出来。
错。而且错得很离谱。
真相是:大模型在任何时刻只干一件事——猜下一个字。
你输入"今天天气真",它做的事和文字接龙里的你一模一样:基于前面的所有内容,猜下一个 token 是什么。猜出"好",把"好"接到句尾,然后基于"今天天气真好"再猜下一个……如此循环,直到它认为"话说完了"。
没错,那个能帮你写代码、改简历、装成苏格拉底跟你辩论的东西,底层就是一个极限版文字接龙大师。
这个认知落差,是理解一切大模型行为的起点。后面你会反复看到:LLM 的所有优点和所有毛病,全都是从"接龙"这个设定里长出来的。
二、文字接龙:祖传手艺,但练了万亿遍
"猜下一个字"听起来简单到侮辱智商。凭什么这个游戏能玩出 ChatGPT?
差别在两件事:练了多少次,猜错了之后怎么处理。
文字接龙你输了会怎样?朋友笑你一下,接着往下玩,什么都不会改变。而大模型的"接龙训练"是这样的:把互联网上几乎所有的文本喂进去,然后拿这些文本反复出填空题——随便挑一段,盖住其中任意一处(一个 token),只让模型看被盖住之前的内容,让它猜盖住的是什么。猜完揭开答案对一下,猜错了就调整内部参数,让它下次在同样的地方猜得更准。一段文本里每个 token 都能被盖住一次,这样的题它做了数万亿遍。
相当于一个人从出生起只玩文字接龙,玩到这个量级,而且每次接错都有人纠正。玩到最后,它对"什么内容后面通常接什么"建立了极其精细的统计直觉:
- "今天天气真"后面接"好"的概率很高,接"热"也不低,接"抽象"的概率就骤降
- "public static void"后面接"main"的概率高到几乎必然——它读过太多 Java 代码
- "1 + 1 ="后面接"2"的概率接近 100%
注意这个措辞:概率。模型不是"知道"1+1=2,而是它见过海量"1+1=2",于是"2"成了压倒性的高概率选项。这个区别现在看着像抬杠,讲到幻觉的时候(第 04 篇)你会回来给它上香。
三、Token:模型眼里的"字"不是你的字
接龙的最小单位是什么?你以为是"字"或"词"。
不是。是 token——一个介于"字符"和"单词"之间的碎片。
模型在训练前会用分词器(比如 BPE 算法)把所有文本切成 token。切法遵循一条朴素的经济学原则:常用的切细,不常用的切块。
用英文看最直观:
- 常用词 “the”、“hello” → 整词一个 token
- 生僻词 “tokenization” → 可能拆成 “token” + “ization” 两个 token
- 中文通常一个字一个 token,部分高频词(如"我们")会被合并
这个设计解释了很多灵异现象,最著名的就是**“数不清 strawberry 里有几个 r”**:
模型看到 “strawberry” 时,收到的不是 s-t-r-a-w-b-e-r-r-y 九个字母,而是 “straw” + “berry” 两个 token。分词这一步做完,字母就没了——模型手里只有这两块,你问它里面有几个 r,它没法拆开来数。早期模型答错字母,是分词这一步造成的,跟它聪不聪明没关系。(2026 年的新模型大多已经通过字符级增强训练修复了这类问题,但机理值得知道——面试时能讲出"为什么错",比背出"现在对了"更能说明你懂。)
Token 还有一个工程上的重要身份:计费单位。API 按 token 收费、上下文窗口按 token 计算,所以你迟早需要建立"一段文本 ≈ 多少 token"的直觉:英文大约 1 token ≈ 0.75 个单词,中文大约 1 字 ≈ 1~2 token。写代码预算成本时,这个直觉就是钱。
四、temperature 和 top-p:给接龙选手调性格
模型猜下一个 token 时,输出的不是单个答案,而是一张概率表:词表里每个 token 都有一个"接下来是我"的分数。比如"今天天气真"之后:
| 候选 token | 原始分数(logit) |
|---|---|
| 好 | 8.2 |
| 热 | 7.1 |
| 冷 | 6.5 |
| 抽象 | 1.3 |
| 量子 | -0.4 |
表里这些分数还不是概率,正负都有、加起来也不等于 1。中间要过一道 softmax,把每个分数换算成 0 到 1 之间、全表加起来正好 100% 的概率。temperature 作用在 softmax 之前(直接改分数差距),top-p 作用在之后(在概率上圈候选)。
第一道:temperature(温度)——把分数之间的差距拉大或压小。
- temperature → 0:所有分数先除以温度,温度越小,差距拉得越开。"好"和"热"原本只差 1.1 分,温度调到 0.1 就变成差 11 分,"好"的概率被推到接近 100%,模型变得极其稳定保守——每次都选最稳的
- temperature → 1 以上:温度大于 1,除以它反而把差距压小。温度取 2 时,"好"和"量子"原本差 8.6 分,只剩 4.3 分,冷门选项有了出头机会,模型变得发散有创意
打个比方:temperature 是给员工调性格的旋钮。调到 0,你得到一个一丝不苟、每次输出一模一样的实习生——写代码、按固定格式返回 JSON、算账,用他。调到 1.2,你得到一个才华横溢但偶尔飘走的文案——写广告语、起标题,用他。用错场景的 temperature,是新手最常见的翻车点之一。
第二道:top-p(核采样)——设置候选池门槛。
它说:把候选按概率从高到低排好,从最高的开始把概率一个个累加,累计值达到或超过 p 就停,只留下参与累加的这几个。p 是个比例,不是个数。p = 0.9 的意思是"这些候选的概率加起来占到九成"。拿上面那张表算:“好” 0.66 加"热" 0.22 是 0.88,还不到 0.9;再加"冷" 0.12,累计 0.99,超过 0.9,停——候选池就是这三个,后面的"抽象""量子"进不来。这是给发散度上的第二道保险:temperature 调高之后,靠它拦下"量子"这种离谱候选。
两个旋钮通常只调一个:它们都在管输出有多发散,同时改,效果会叠在一起,出了问题分不清是哪个参数造成的,也复现不出来。
顺带一个工程坑:temperature 调 0 也不保证 100% 复现(机理本篇思考题 1 会问,先留个悬念)。要靠"完全可复现"跑回归测试的,得在应用层加缓存或固定种子,别指望模型参数。
完整采样流程一张图:
五、生成循环:从你的提问到
现在把所有零件装回去,看一次完整的回答是怎么生成的:
用伪代码表达,就是不起眼的三层:
tokens = tokenize(your_prompt) # 你的输入
while not done:
probs = model(tokens) # 对全序列预测下一个 token 的分布
next_token = sample(probs, T, p) # 按 temperature / top-p 采样
tokens.append(next_token) # 追加到尾部
if next_token == EOS: # 模型认为话说完了
done = True
return detokenize(tokens)
三个值得注意的细节:
- 每生成一个 token,都要把整个序列重新喂一遍。"今天天气真好"生成到第 5 个字时,前 4 个字也在参与计算。序列越长计算越贵——这就是为什么长输出更费钱、为什么上下文越长响应越慢(工程上有 KV Cache 缓解,详见第 02 篇)。
- 结束符(eos)也是"猜"出来的。模型什么时候闭嘴,同样是概率行为。所以偶尔会出现回答到一半戛然而止,或者该停的时候强行加戏——都是 eos 采样没踩准。
- 最大 token 数是硬保险丝。max_tokens 到了不管模型想没想完,直接掐断。这就是有些回答"说到一半被砍"的真相。
六、逐字输出的真相:Streaming 不是特效
最后一个日常现象:网页上 AI 的回答是逐字蹦出来的,像有人实时打字。
现在你知道了:它本来就是逐字生成的。所谓"流式输出",只是服务端每生成一个 token 就推一条消息给前端,不攒着。你看到的"打字机效果"不是 UI 特效,是生成过程本身的实时直播。
反过来,那个"转圈圈等回答"的场景(比如某些 API 调用),则是客户端选择等全部生成完再一次性返回。同一个生成过程,两种呈现,差别只在一点:是一个一个往外发,还是攒够了再一起发。
为什么这个真相重要? 因为它决定了你做 AI 应用时的两个体验设计:一是首字延迟(time to first token)比总时长更影响用户感受——用户能接受看它打字,不能接受盯着转圈;二是流式模式下做内容校验,你拿到的是半句话,处理逻辑必须按"增量"设计。这两点在《拆Agent》卷三做生产化时会反复出现。
七、两条边界:它不搜索,也不打腹稿
这两条边界决定了你什么时候能信它:
- 它不搜索。 生成时只依赖训练时固化的参数和当前上下文。能联网查资料是应用层外挂的本事(RAG / 联网工具),那是第 08 篇的事。
- 它不打腹稿。 它对语言的统计规律掌握得极其精细,细到看起来像真的懂了,但它没有"想好了再说"这一步。明白这条,你就能预判它什么时候靠谱、什么时候翻车。
小结
- 大模型每一步只做一件事:基于全部上下文,预测下一个 token 的概率分布——极限版文字接龙
- Token 是切出来的碎片,常用切细、生僻切块;"数不清字母"的灵异现象根源在分词
- temperature 控发散、top-p 控候选池,两个旋钮只调一个;写代码、按固定格式返回 JSON 用低温,写文案用高温
- 生成是一个循环:预测 → 采样 → 追加 → 再预测,直到猜出结束符或撞上 max_tokens
- 逐字输出不是特效,是生成过程的直播——做 AI 应用时首字延迟比总时长更重要
思考题
- 把 temperature 设为 0 之后,同一个问题连续问十次,答案仍可能有细微差别。既然不再随机抽样了,差异从哪来?(提示:softmax 要把词表里十几万个分数加总,GPU 不会一个一个顺着加,而是分块同时加、最后再合并,分成几块、按什么顺序合并每次不一定相同。浮点数换个加法顺序,末位就会变。再想想:温度接近 0 时,两个几乎并列的候选会怎样?)
- 模型生成到第 1000 个 token 时,第 1 个 token 的信息还在参与计算吗?这对长对话的成本曲线意味着什么?(提示:本篇第五节说了"整个序列重新喂一遍",但这句省略了一个重要的工程优化——它叫 KV Cache。)
高频面试题
Q1:LLM 的推理(inference)过程是怎样的?为什么是自回归的?
A:模型基于已有 token 序列预测下一个 token 的概率分布,采样后将其追加到序列尾部,再以同样的方式预测下一个,直到生成结束符或达到 max_tokens。因为每一步的输出都成为下一步的输入,序列自己喂着自己往前长,所以叫自回归(autoregressive)。每一步里,词表里十几万个候选是同时算出来的,这一步本身很快;但下一个 token 要用上一个的结果,步与步之间只能排队。生成 1000 个 token 就得走 1000 轮,这就是长回答延迟的下限。
Q2:temperature 和 top-p 分别控制什么?生产环境怎么选?
A:temperature 在 softmax 前对 logits 做缩放(除以 T),T 越小分布越尖锐、输出越确定;top-p 在采样前把候选池截断到累计概率 p 以内的头部 token,过滤长尾。二者都控制随机性,通常只调一个:结构化输出、代码生成、分类任务用低温(0~0.3),创意文案、头脑风暴用高温(0.7~1.2)。生产上还要加 max_tokens 兜底和重试策略。
Q3:为什么早期大模型数不对 “strawberry” 有几个 r?
A:因为模型接收的不是字符序列,而是分词器切出的 token 序列。“strawberry” 被切成 “straw”+“berry” 两个 token,字母级信息在分词时被压缩了,模型没有直接的"逐字母视图"。要答对需要模型在内部反演出拼写,这依赖训练数据中的相关文本。2026 年主流模型已通过字符级训练增强大幅改善,但根因是分词机制而非"智力"。
Q4:什么是流式输出?它对应用架构有什么影响?
A:服务端每生成一个 token 就推送一条增量消息(SSE/WebSocket),而非等全部生成完。好处是首字延迟(TTFT)大幅下降,用户感知是"秒回+打字机"。架构影响:前端按增量渲染;后端处理逻辑必须面向流(如逐段解析 JSON 时需要缓冲策略);鉴权与内容审核要在流式语义下重新设计;失败恢复也更复杂——连接中断后已生成的 token 处理策略要提前定义。
系列导航:上一篇 00《大模型从哪来》 → 下一篇 02《上下文窗口与遗忘》:一次能记多长,为什么聊得越久越忘开头
更多推荐


所有评论(0)