目录
我们问大模型:
法国的首都是
它接着回答“巴黎”。这看起来像是模型先理解问题,再从记忆里找出答案。实际过程没那么像人,但也不神秘:文字先被转换成一串数字,数字经过模型计算,最后得到“下一个 Token 是什么”的概率。
整条流程是:
Text → Tokenizer → Token ID → Embedding → Transformer → Hidden State → LM Head → Logits → Softmax / Sampling → Next Token → Append → 再次预测
这一篇先把流程走通。Transformer 内部的 Q、K、V 和位置编码,留到后面再讲。
1、把文字切成 Token
模型不能直接处理字符串。输入的第一站是 Tokenizer,它负责把文字切成模型认识的基本单位。
为方便理解,假设这句话被切成:
["法国", "的", "首都", "是"]
Token 不一定是一个完整的词。它也可能是单个汉字、半个英文单词、标点或空格。具体怎么切,取决于模型使用的 Tokenizer 和词表。
为什么不直接按字切?因为模型需要在词表大小、文本长度和表达能力之间做取舍。“法国”“首都”这样的常见组合如果能作为一个 Token,序列通常会更短。
2、Token ID 只是编号
Tokenizer 会在词表里查出每个 Token 的编号。假设结果是:
| Token | Token ID |
|---|---|
| 法国 | 10321 |
| 的 | 342 |
| 首都 | 8921 |
| 是 | 271 |
于是,一句话变成了整数序列:
[10321, 342, 8921, 271]
编号本身没有语义。10321 不比 342 更重要,也不表示“法国”比“的”更大。Token ID 的作用只有一个:告诉模型接下来应该查哪一行。
3、Embedding:把编号换成向量
神经网络需要的是可以参与计算的向量,不能直接拿 Token ID 当输入。因此模型内部有一张很大的表,叫 Embedding Matrix。
假设词表大小是 $V$,每个向量的长度是 $d_{model}$,这张表的形状就是:
\[E \in \mathbb{R}^{V \times d_{model}}\]每个 Token 占一行。Token ID 是 10321,就取第 10321 行:
\[x_{10321}=E[10321]\]得到的结果类似:
法国 → [0.21, -0.73, 0.14, ..., 0.09]
所以 Embedding 的动作可以简单理解为“查表”,不是拿 10321 做某种算术运算。
这张表是怎么来的?
Embedding Matrix 是模型参数的一部分。训练刚开始时,里面的数值并不懂什么是法国、巴黎或首都。模型在大量文本上不断预测下一个 Token,根据预测误差调整参数,这些向量也随之变化。
训练之后,经常出现在相似语境中的 Token,通常会在向量空间里形成一些有用的关系。例如“苹果”和“香蕉”可能比较接近,“汽车”和“卡车”也可能比较接近。
这不是人工把词义填进表格,而是模型为了做好预测逐渐学出来的。
为什么形状多了一维?
假设一次输入 $B$ 句话,每句话有 $T$ 个 Token,Token ID 的形状是:
\[[B,T]\]每个 ID 查表后都变成长度为 $d_{model}$ 的向量:
\[[B,T] \rightarrow [B,T,d_{model}]\]以 Llama 的某个配置为例,如果 $d_{model}=4096$,一个 Token ID 查表后就会变成包含 4096 个数的向量。
Embedding 还没有结合这句话的上下文
同一个 Token ID,每次查表拿到的初始向量相同。比如“苹果”出现在下面两句话里,刚查表时没有区别:
苹果发布了新手机
苹果削皮后很好吃
一个指公司,一个指水果。这个差别要等向量进入 Transformer,与周围 Token 交换信息后才会体现出来。
因此要分清两件事:
- Embedding:Token 的初始向量。
- Contextual Representation:结合当前上下文之后的向量。
4、Transformer 做了什么?
现在,“法国”“的”“首都”“是”都已经变成向量,可以进入 Transformer。
第一课先把 Transformer 看作多层重复的处理模块:
- Attention 让每个 Token 参考其他 Token 的信息。
- FFN 对每个位置的信息做进一步处理。
- 残差连接和归一化让整个计算过程更稳定。
经过多层处理,“是”所在位置的向量已经不只表示“是”这个 Token,也带上了“法国”和“首都”等上下文信息。
这一篇到这里就够了。Q/K/V、RoPE、GQA、MLA、FlashAttention、KV Cache 和 MoE 都先不展开。
5、从 Hidden State 得到候选答案
Transformer 每处理一层,向量的数值会变化,但形状通常仍是:
\[[B,T,d_{model}]\]最后一层输出的这些向量叫 Hidden State。要预测下一个 Token,模型会取序列最后一个位置的 Hidden State,交给 LM Head。
LM Head 把长度为 $d_{model}$ 的向量映射到整个词表。如果词表有 $V$ 个 Token,输出就有 $V$ 个分数:
\[\mathbb{R}^{d_{model}} \rightarrow \mathbb{R}^{V}\]这些原始分数叫 Logits。对于“法国的首都是”,结果可能类似:
| 候选 Token | Softmax 后的概率 |
|---|---|
| 巴黎 | 0.82 |
| 北京 | 0.07 |
| 伦敦 | 0.05 |
| 东京 | 0.03 |
| 其他 | 0.03 |
Softmax 把 Logits 变成总和为 1 的概率分布。模型再按照解码策略选择下一个 Token。
最简单的策略是直接选择概率最大的“巴黎”。实际生成时也可以使用 Temperature、Top-k、Top-p 等策略,在稳定和多样之间做调整。
6、生成不是一次完成的
模型选出“巴黎”后,会把它接到原来的输入后面:
法国的首都是巴黎
接着以这段新文本为条件,再预测下一个 Token。下一个可能是“。”,也可能是解释中的其他内容。
预测 → 追加 → 再预测 → 再追加……
这就是自回归生成。我们看到的一整段回答,并不是模型一次写出来的,而是一个 Token 一个 Token 接出来的。
最后看一遍形状变化
| 阶段 | 形状 | 含义 |
|---|---|---|
| Token IDs | $[B,T]$ | 输入的编号序列 |
| Embedding | $[B,T,d_{model}]$ | Token 的初始向量 |
| Transformer | $[B,T,d_{model}]$ | 多层上下文处理 |
| LM Head | $[B,T,V]$ | 映射到词表大小 |
| Softmax | $[B,T,V]$ | 每个候选 Token 的概率 |
对一次预测来说,可以只看最后一个位置的结果,因此常见到 $[B,V]$ 的 Logits。
记住这 5 件事
- 大模型的核心任务是预测下一个 Token。
- Token ID 只是编号,真正参与计算的是向量。
- Embedding 是可学习的查找表,不是人工编写的词典。
- Transformer 让 Token 交换信息,形成与当前句子有关的表示。
- 生成是一个循环:预测、追加、再预测。
下一篇再打开 Transformer 这个黑盒,看看 Attention 为什么能让 Token 彼此关联。