大模型就像一个超级预测机器,它的全部智慧就是猜下一个字——但问题是,它凭什么猜得这么准?
你有没有想过,当你给 ChatGPT 发一句“中国的首都是”,它怎么就知道接“北京”而不是“上海”?明明它只是一个接收文本、输出文本的程序,内部到底发生了什么?
今天我们就钻进 LLM 的肚子里,从 Token 开始,一步步拆解它预测下一个词的全过程。读完这篇,你会对大模型“凭空生成”文本的能力有一个立体的认知——不再是黑盒,而是有迹可循的数学魔法。
一、Token:LLM 的“最小货币单位”
我们人类看到的是“我爱人工智能”,但 LLM 不认识汉字。它只认识数字,所以第一步就是把自然语言切碎成词元(Token) 。
Token 是 LLM 处理信息的最小单元,也是计费的基本单位——它不一定是完整单词,可能是子词、字符甚至标点。
举个例子:
unhappiness 这个英文词,LLM 不会当做一个整体,而是切成 ["un", "happi", "ness"]。中文也是类似:"我爱人工智能,自然语言处理很有趣" → ["我", "爱", "人工智能", ",", "自然语言处理", "很", "有趣"]。
为什么要切得这么碎?
- 如果只认完整词,英文有几十万单词,中文更有几百万,模型根本记不过来;
- 切成子词后,模型只需掌握几万个“基础积木”,组合效率极高。
- 更小的词表意味着更快的运算和更低的显存占用。
每个 Token 在模型内部都有一个唯一的编号(Token ID),比如“你”可能是 57668。你把 Prompt 发过去,模型收到的就是一堆 Token ID 的数组。
这就是输入:一串数字。
二、Embedding:给数字赋予“灵魂”
Token ID 是纯粹的数字索引,没有语义。57668 和 57669 之间没有任何数学关系,你不能说“你”+1=“好”。
LLM 的第一步操作,就是把这个 ID 映射成一个高维向量,这个过程叫 Embedding。
Embedding 是把离散的 Token ID 变成连续的语义向量,让模型能够计算词与词之间的“距离” 。
每个 Token ID 都对应一个向量(例如 1024 维或 4096 维),这个向量可以理解为该 Token 在高维空间中的坐标。语义相近的词,它们的向量在空间里距离就近。比如“国王”和“王后”的向量距离就很近,而“苹果”离它们很远。
更有趣的是,向量之间还能做运算:
国王 - 男性 + 女性 ≈ 王后
这说明模型通过训练,不仅学到了词义,还学到了语义关系。
LLM 内部有一个巨大的 Embedding Matrix(嵌入矩阵) ,相当于一张“向量查找表”。当拿到 Token ID 57668,它直接去这张表的第 57668 行,把对应的向量“抽出来”。
但到此为止,每个 Token 还是孤立的——它们只知道自己是什么,不知道自己在句子里的位置。
三、位置编码:让每个词知道“我在哪”
考虑这两句话:
- “我咬了狗”
- “狗咬了我”
它们的 Token 完全一样,但顺序不同,意思天差地别。Embedding 本身不携带顺序信息,所以必须给每个向量叠加一个位置编码(Position Encoding) 。
位置编码告诉模型每个 Token 属于句子的第几个位置,让语义与顺序融合。
常见的做法是给每个位置生成一个固定的向量(比如用正弦余弦函数),然后直接加在 Embedding 上。这样,每个 Token 最终携带两类信息:
- 语义信息(它是什么)
- 位置信息(它在哪里)
现在,模型有了一个个带坐标和顺序的向量,但它还是不知道词与词之间的依赖关系——比如“它”指代谁?这就要靠自注意力机制了。
四、自注意力:让模型“读懂上下文”
这句英文:
The animal didn't cross the street, because it was too tired.
这里的 it 指代的是 animal 还是 street?人类一眼就懂是动物,因为“tired”常修饰动物,但模型怎么知道?
答案就是 Self-Attention(自注意力) 。
Q、K、V 三部曲
对每个 Token 的向量,模型会通过三个不同的线性变换,生成三个新向量:
- Q(Query) :查询向量,代表“我在找什么? ”——比如代词
it要找个先行词; - K(Key) :键向量,代表“我能提供什么? ”相当于一张名片,告诉别人我有什么属性;
- V(Value) :值向量,代表“我能提供什么实际内容? ”也就是具体特征细节。
还是上面那个句子。假设我们只关注 it 和 animal、street 的关系:
token1:animal -> (Q1, K1, V1)
token2:it -> (Q2, K2, V2)
token3:street -> (Q3, K3, V3)
模型要做的是:用 it 的 Query 向量去和句子中每个词的 Key 向量做点积,得到一组注意力分数:
score_it_animal = Q2 · K1
score_it_street = Q2 · K3
如果 score_it_animal 数值远大于 score_it_street,就说明 it 和 animal 的相关性更强,模型会把更多注意力放到 animal 上。然后,这些分数经过 Softmax 归一化变成权重,再分别乘以对应词的 Value 向量,最后加权求和,得到 it 位置的新表示——这个新表示里就融合了 animal 的语义细节(比如“疲倦”这个属性),从而正确地让 it 指代动物而非街道。
自注意力机制的本质就是用 Q 去找最匹配的 K,然后用 V 来提供实际内容。Q 是问题,K 是索引,V 是答案。
同样的道理可以用在歧义场景里:
- “苹果手机” → 模型会通过注意力分数发现“苹果”和“手机”强相关,它的向量就会偏向电子设备;
- “我吃了苹果” → 上下文里“吃了”这个词会拉高“苹果”作为水果的注意力分数,于是它的语义转向食物。
这就是上下文消歧的核心——不是靠词典硬查,而是靠 QKV 的动态加权。
你可能会问:Q、K、V 是怎么来的?它们都是通过模型训练学出来的权重矩阵,直接对原始向量做线性变换。我们不需要手动设计,模型自己会调整这些矩阵,让注意力分数最有利于预测下一个词。
五、从注意力到预测:概率分布和自回归
经过多层自注意力(Transformer 里的 Decoder 部分),模型已经为当前序列中的每个位置生成了富含上下文信息的向量。接下来要做的事,就是预测下一个词。
对于最后一个位置(即当前输入序列的末尾),模型会取它的向量,通过一个 线性层 + Softmax,映射成词表大小的概率分布。比如词表有 5 万个 Token,输出就是一个 5 万维的向量,每个维度代表对应 Token 成为下一个词的概率。
拿“中国的首都是”为例:
- “北京” 的概率:92%
- “北平” 的概率:4%
- “长安” 的概率:2%
- 其他所有词:共 2%
模型选择概率最高的那个(或者按温度采样),输出对应的 Token ID。然后,这个新 Token 会被追加到输入序列末尾,模型再继续预测下一个词。
这就是自回归生成:每次生成一个词,然后把新词加入上下文,再生成下一个,直到遇到结束标记或达到最大长度。
六、串起全流程:一个完整的推理过程
现在我们把所有步骤串起来,看看一次完整的生成到底经历了什么:
- 输入:“中国的首都是”
- Tokenization:切分为
["中国", "的", "首都", "是"],转成 Token ID[123, 456, 789, 101] - Embedding:每个 ID 查表得到对应的语义向量(比如 1024 维)
- 位置编码:给每个向量加上位置信息(位置 0,1,2,3 的编码)
- 多层自注意力:经过 N 层 Transformer 块,每层都有 QKV 计算,让每个位置的向量都融合上下文
- 输出概率:取最后一个位置的向量,线性变换 + Softmax,得到词表大小的概率分布
- 采样:按概率选出“北京”(概率最高),输出 Token ID
- 循环:将“北京”加入输入,继续预测下一个词……直至结束
整个过程计算量极大,但核心思路就是不断重复步骤 5~7。
七、一些你可能关心的“实战问题”
1. 为什么 Tokenization 会影响计费和效果?
因为计费按 Token 数算,而不同模型的分词器(Tokenizer)切法不一样。比如英文中 ChatGPT 可能被切成一个 Token,也可能切成 Chat + G + PT。所以相同的文本在不同模型上花费可能不同。而且切得越合理,模型理解越好——比如中文“人工智能”如果被切成“人工”和“智能”,就会丢失整体语义,所以现在主流中文模型都会把常用词保留为完整 Token。
2. 位置编码为什么重要?有没有更先进的做法?
早期用固定正弦编码,现在很多模型用可学习的位置编码,即把位置也当成参数来训练。还有 RoPE(旋转位置编码)等变体,本质都是给向量注入位置信息,只是实现方式不同。
3. 注意力机制真的能看到所有词吗?
理论上是,但实际上受限于上下文窗口(比如 8K、128K)。窗口之外的词完全看不见,这就是为什么长文本会丢失开头信息——因为注意力矩阵的计算量随窗口长度平方增长,模型只能截断。
写在最后
说白了,LLM 的推理过程可以浓缩成一句话:
把问题变成数字,通过向量空间中的注意力计算,找出最符合上下文的下一个数字,再翻译回文字。
它没有“思考”,没有“理解”,只有大规模统计模式匹配。但正是这种模式匹配的深度和广度,让它看起来像有了智能。
作为开发者,了解这些底层细节至少能给你两个直接好处:
- 调试 Prompt 时更有方向:知道模型“看”什么,才能更精准地给提示;
- 估算成本更准确:理解 Token 计数逻辑,避免账单惊吓。
下次你再调用大模型 API 时,不妨想想那一串串向量在空间中跳舞的样子——你会发现,它其实没那么神秘,反而有点可爱。
Token 是它的货币,Embedding 是它的地图,而注意力机制就是它在这张地图上寻找路径的罗盘。
祝你代码无 Bug,Token 永不浪费。