AI / 大模型
大模型是怎么"说话"的:从 token 到下一个词
拆开一次对话的全过程:分词、向量、Transformer、采样,以及这套机制为什么会导致幻觉和数不清字母。
用了很久 ChatGPT 之类的产品,一直把它当黑盒。这篇把一次“提问 → 回答”拆开,看看里面到底发生了什么。结论先放这:大模型做的事只有一件 —— 根据前文,预测下一个 token。 其他一切都是这件事反复执行的结果。
第一步:把文字切成 token
模型不直接读字符,而是读 token。token 是分词器(tokenizer)从海量语料里统计出来的“常见片段”,主流做法是 BPE(Byte Pair Encoding):从单个字节开始,反复把最常一起出现的两个片段合并成新片段,直到词表够大(通常几万到二十几万)。
结果大概是这样:
- 英文常见词往往是一个 token,比如
hello;长词会被拆开,比如unbelievable可能是un+believ+able - 一个汉字通常是 1 到 2 个 token,取决于分词器对中文的训练程度
- 代码里的缩进、常见关键字也会被合并成 token
每个 token 对应一个整数 id。所以模型真正看到的输入,是一串数字:[9906, 11, 1917, 0]。
这也是 API 按 token 计费、上下文长度按 token 算的原因 —— token 才是模型的基本单位。
第二步:id 变向量
整数本身没有意义,模型先查一张 embedding 表,把每个 token id 换成一个高维向量(比如 4096 维)。再加上位置信息(现在主流是 RoPE 旋转位置编码),模型就知道“这是第几个 token”。
到这里,一句话变成了一个 token 数 × 维度 的矩阵。
第三步:过几十层 Transformer
矩阵会依次穿过几十层结构相同的 Transformer block,每层做两件事:
- 自注意力(Self-Attention):每个 token 去“看”它前面所有 token,决定从谁那里汲取多少信息。“它”指代谁、这个“苹果”是水果还是公司,都在这一步被上下文消歧。
- 前馈网络(FFN):对每个 token 的向量单独做一次非线性变换。一般认为大量“知识”就存在这部分参数里。
每层的输出都会加回输入(残差连接),所以信息是一层层叠加精炼的,而不是被替换掉。注意力的细节和它带来的成本问题,我单独写在 KV Cache 那篇 里。
第四步:算出下一个词的概率
最后一层输出里,只取最后一个位置的向量,乘上一个“词表大小”的矩阵,得到每个候选 token 的分数(logits),再过 softmax 变成概率分布:
"今天天气真" → 好 0.62 | 不 0.11 | 热 0.09 | 冷 0.05 | ...
然后从这个分布里采样一个 token。常见的采样参数:
| 参数 | 作用 |
|---|---|
| temperature | logits 先除以 T 再 softmax。T 小分布更尖,输出稳定;T 大更平,输出更“有创意” |
| top-p | 只在累计概率达到 p 的那批候选里抽,砍掉长尾的离谱选项 |
| top-k | 只在概率最高的 k 个里抽 |
temperature 设成 0 基本等于每次取概率最大的那个(贪心解码),适合写代码、做抽取;写文案可以调高一点。
第五步:循环
选出的 token 拼回输入末尾,再跑一遍,得到下一个 token……直到生成结束符或达到长度上限。伪代码就这么几行:
tokens = tokenizer.encode(prompt)
while True:
logits = model(tokens)[-1] # 只要最后一个位置
next_id = sample(logits, temperature=0.7, top_p=0.9)
if next_id == EOS:
break
tokens.append(next_id)
yield tokenizer.decode([next_id]) # 这就是"流式输出"
所以回答是一个字一个字蹦出来的 —— 不是为了效果好看,而是它本来就是这么一个一个生成的。
它是怎么学会的
训练分几个阶段:
- 预训练:拿万亿级 token 的文本,任务只有一个 —— 遮住下一个 token 让模型猜,猜错就调参数。这一步让模型学会语言、常识和大量知识。
- 指令微调(SFT):用“问题 → 好回答”的数据继续训练,让它从“续写文本”变成“回答问题”。
- 偏好对齐(RLHF / DPO 等):让人或模型给多个回答排序,训练它更倾向于有帮助、无害的回答。
预训练出来的模型只会续写:你问“法国的首都是哪里?”,它可能续写成一串类似的考试题。后两步才让它成了“助手”。
理解了这个,很多现象就说得通了
幻觉。 模型优化的目标是“说出最像真的下一个词”,而不是“说真话”。当它不知道答案时,一个流畅且看起来合理的编造,在概率上往往比“我不知道”更顺。
数不清字母。 问“strawberry 里有几个 r”,模型看到的可能是 str + aw + berry 这样的几个 token,而不是 10 个字母。它得靠记忆而不是“看”来回答,所以容易错。
先想再答更准。 让模型“一步步思考”,等于让它先生成一些中间 token,后面的预测就能基于这些中间结果。计算量是跟着生成的 token 走的,多写几步就是多算几步。现在的推理模型,本质上就是把这个过程训练成了默认行为。
上下文就是全部记忆。 模型参数在对话中不会变,它“记得”你前面说的话,只是因为前面的话每次都被重新塞进了输入里。对话太长,前面的内容就会被截断或稀释。
一句话:大模型是一个极其强大的“下一个 token 预测器”,所有能力都是这件事在规模上的涌现。