🧠 LLM 如何预测下一个词?------ 深入 Transformer 内部
从 Token 到 Self-Attention,一文讲透大语言模型的核心工作流程
前言
当你向 ChatGPT 输入"中国的首都是",它几乎瞬间就能回答"北京"。这个看似简单的能力背后,隐藏着一套精妙的数学机制。今天,让我们走进 LLM 的内部,看看一个 token 从输入到输出,到底经历了什么。
LLM 的核心工作只有一件事------预测下一个词。
一、Token(词元):LLM 的"货币"
1.1 什么是 Token?
用户输入的自然语言首先要被切分成一个个最小处理单元,这就是 Token(词元) 。每个 token 对应一个唯一的 Token ID。
重要认知:Token 不一定是完整的"词",它可能是子词、字符,甚至是标点符号。
举个经典例子:
unhappiness → un / happi / ness
LLM 通常不会把 "unhappiness" 当作一个完整的词,而是分解为三个更小的词元。这样做的好处非常明显:
- 如果只认完整的词,模型需要记忆几十万英文单词 + 几百万中文词汇,计算量巨大
- 把词切成子词后,模型只需要掌握几万个基础积木即可组合出任意词汇
1.2 Token 词典
arduino
"我爱人工智能,自然语言处理很有趣"
→ ["我", "爱", "人工智能", ",", "自然", "语言", "处理", "很", "有趣"]
Token 查找表就像一本字典------索引小、运算效率高。目前 OpenAI 的 tokenizer 已成为事实标准,国内如 Qwen 也有自己的分词方案。
一句话总结:把 token 理解为 LLM 的"货币"。你花钱买 token,模型拿 token 做计算。
1.3 预测的大致流程
java
"你" → Token ID (57668) → LLM (内部处理) → Token ID → "好"
Token ID 本身是一个没有意义的数字,真正赋予它语义的是下一步------Embedding。
二、Embedding(语义向量):数字的"灵魂"
2.1 从 ID 到向量
Token ID(比如 57668 代表"你")只是一个编号,你无法通过加减乘除算出"好"的编号。这就像电话号码------你不可能通过一个号码推导出另一个号码。
但向量可以。
LLM 内部有一张巨大的Embedding Matrix(嵌入矩阵) ,就像一个巨大的文件柜:
yaml
Token ID 57668 → 打开第 57668 号柜子 → 取出一个高维向量(如 1024 维)
这个过程就是 Embedding------把无意义的数字,转化为携带语义信息的高维向量。
2.2 语义向量的几何之美
在多维空间中,每个词都是一个坐标点:
国王 - 男性的向量 + 女性的向量 = 王后
这不是魔法,而是向量的计算与语义迁移。语义相近的词,它们在向量空间中的距离就很近;语义上毫不相关的词(比如"国王"和"苹果"),距离就远。
模型的训练过程,本质上就是在构建这样一套精妙的几何坐标系。
三、位置编码:让"顺序"有意义
3.1 同样的词,不同的含义
"我咬了狗"
"狗咬了我"
完全相同的四个字,顺序不同,意思天差地别。
但 Embedding 向量本身不携带位置信息------"狗"这个词不管出现在第几个位置,它的语义向量都一样。所以我们需要给每个向量叠加一个位置编码(Positional Encoding,PE) ,告诉模型这个词在句子中的位置。
3.2 每个 Token 携带两类信息
| 信息类型 | 来源 | 回答的问题 |
|---|---|---|
| 语义信息 | Embedding | 这个词是什么? |
| 位置信息 | Positional Encoding | 这个词在哪里? |
四、Self-Attention(自注意力):理解上下文的关键
4.1 代词的困境
阅读下面这句话:
The animal didn't cross the street because it was too tired.
"it" 指的是谁?是 animal 还是 street?
人类凭常识推断是 animal(动物会累,街道不会)。但 LLM 怎么知道的?答案就是------Self-Attention(自注意力机制) 。
4.2 Q、K、V 三部曲
Self-Attention 把每个词的 Embedding 拆成三部分:
| 组件 | 全称 | 角色 | 比喻 |
|---|---|---|---|
| Q | Query | 我在找什么? | 搜索关键词 |
| K | Key | 我能提供什么? | 名片/标签 |
| V | Value | 我能贡献什么内容? | 实际内容 |
4.3 注意力计算过程
css
animal → (Q₁, K₁, V₁)
it → (Q₂, K₂, V₂)
street → (Q₃, K₃, V₃)
"it" 想知道自己指代谁,于是:
- 用 "it" 的 Q₂(Query) 和句中每个词的 K(Key) 做点积运算
- 得到一组注意力分数:
less
score("it" → "animal") = Q₂ · K₁ → 0.92 ✅ 最高!
score("it" → "it") = Q₂ · K₂ → 0.45
score("it" → "street") = Q₂ · K₃ → 0.18
- 分数越高 = 两个词关联越强,"animal" 得分最高,所以 "it" 指代的是 "animal"
4.4 同样的词,不同的含义
Self-Attention 还能处理一词多义:
arduino
"苹果手机" → "苹果" 关联科技产品语义
"我吃了苹果" → "苹果" 关联水果语义
同一个"苹果",通过 Self-Attention 与不同的上下文交互,就获得了不同的语义表达。这正是 Transformer 的强大之处。
五、全流程串联
让我们把整个流程串起来,看看"中国的首都是"如何变成"北京":
less
输入: "中国的首都是"
│
├── 1. Tokenization(分词)
│ → ["中国", "的", "首都", "是"]
│
├── 2. Token ID(编号)
│ → [10234, 18, 5678, 45]
│
├── 3. Embedding(查向量表)
│ → 每个 ID 变成一个高维语义向量
│
├── 4. Positional Encoding(加位置)
│ → 每个向量叠加位置信息
│
├── 5. Self-Attention(理解上下文)
│ → Q·K 计算注意力分数,提取上下文语义
│
├── 6. 预测头(输出概率)
│ → 北京: 92% | 北平: 4% | 长安: 2% | ...
│
└── 7. 采样输出
→ "北京"
六、自回归生成:一个接一个
LLM 预测完"北京"后,并不会停下来------它会把"北京"重新拼接到输入后面,继续预测下一个词:
erlang
"中国的首都是北京" → 预测 → ","
"中国的首都是北京," → 预测 → "位于"
"中国的首都是北京,位于" → 预测 → "华北"
...
这就是自回归生成(Autoregressive Generation) ------用自己刚生成的输出作为新的输入,不断循环,直到输出终止符或达到长度上限。看起来「滔滔不绝」的聊天机器人,底层不过是在不停地做这一件事:预测下一个词。
七、总结
| 组件 | 核心作用 | 一句话 |
|---|---|---|
| Tokenization | 把文字切成最小单元 | 把自然语言变成数字 |
| Embedding | 数字→语义向量 | 给 ID 注入"意义" |
| Positional Encoding | 注入位置信息 | 让"狗咬我"≠"我咬狗" |
| Self-Attention | 理解上下文关系 | Q 搜、K 匹配、V 贡献 |
把这四块拼起来,你就得到了 LLM 理解语言的基本蓝图。看似神奇的大模型,底层是清晰的数学结构和精巧的设计思想。
希望这篇文章能帮你揭开 LLM "黑盒"的一角,对 Transformer 的内部机制有一个直观的理解!🚀