LLM Basics · 系列第 1 篇
LLM Internals: Inside the Transformer
今天的 LLM 能写文章、写代码、翻译、总结,甚至拆解复杂项目,但 LLM 本质是做 Next Token Prediction:
给定前面所有 token,预测下一个 token 的概率分布,再采样出一个词,重复这个过程。
"我今天吃了一碗"后面可能接"面""饭"或"汤",模型要依据上下文判断哪个候选词更合理。那么从"一段文字"到"下一个 token"之间,究竟发生了什么计算?
文字 → Token → Embedding → Transformer Block ×N → Linear → Softmax → 采样
沿着这张图往下走,其实就是三件事:文字怎么变成向量、向量之间怎么建立联系并被加工、加工后的向量又怎么算出下一个词。
一、为什么需要 Transformer
RNN 的两个瓶颈
在 Transformer 之前,主流方案是 RNN(循环神经网络):按顺序读文字,读一个词更新一次状态,再把状态带到下一个词——像"排队传话"。这个方法有两个明显瓶颈:
一是长距离依赖:文本越长,前面的信息要经过多步才能传到后面,传递过程中容易被压缩、稀释甚至丢掉。
二是无法高效并行:第 10 个词的计算依赖第 9 个词,大规模数据情况下,串行处理效率低。
RNN 逐步传递 vs Attention 直接建立连接
Attention 的理解:共享白板
Attention(注意力机制)把"排队传话"换成"共享白板":当模型处理某个 token 时,不依赖前一步传来的压缩信息,而是让它直接查看上下文里的其他 token,按相关程度借用信息。每个词都能越过距离直接对话,长距离依赖和串行瓶颈也就不再是问题。
二、Token 与 Embedding:文字如何变成向量
STEP 11. 分词(Tokenization)→ Token ID
一段文字先被切分成若干 token,每个 token 对应词表里的一个整数 ID。现代大模型词表通常在 10 万级别(比如 128,000)。
2. Embedding → 高维向量
每个 Token ID 经过 Embedding 层,变成一个高维向量(几千维量级)。含义相近的词,在向量空间里距离更近——"猫"和"狗"比"猫"和"汽车"更接近。这些向量本身也是训练学出来的参数。
3. 加入位置编码
Embedding 向量还要加上位置编码(如 RoPE),告诉模型"这个词在句子的第几个位置"。Attention 本身不感知顺序——没有位置编码,模型无法区分"猫吃鱼"和"鱼吃猫"。
做完这三步,一段文字就变成了一串带位置信息的向量,可以送进 Transformer 的核心部分:Attention。
三、Transformer Block(上):Attention 机制
STEP 2每个 token 都要计算自己与其他所有 token 的"相关程度",再按相关程度加权借用其他 token 的信息,更新自己的表示。这个过程可以理解成一次相关性检索:当前 token 提出问题,其他 token 给出线索,模型判断该参考谁。
Q、K、V 是什么
每个 token 的向量会分别乘以三个可学习的矩阵 Wq、Wk、Wv,生成三个不同的向量,扮演三种角色:
- Q(Query,提问者):"我想找什么信息?"——代表当前 token 的查询意图
- K(Key,被检索者):"我有什么标签?"——代表每个 token 的索引信息
- V(Value,实际内容):"我实际携带的信息"——最终被借用的内容
一个常见类比:Q 是你在图书馆里的搜索关键词,K 是每本书的书名标签,V 是书的实际内容。关键词和标签越匹配,就从那本书里借用越多内容。
五步计算过程
- 线性变换生成 Q、K、V——每个 token 的向量分别乘以 Wq、Wk、Wv
- Q 和所有 K 做点积——点积越大,说明两个 token 越相关
- Scale(缩放)——点积结果除以
√d(向量维度的平方根),防止数值过大导致梯度消失,这也是论文里 "scaled dot-product attention" 名字的来源 - Softmax → 注意力权重——把相似度分数变成概率分布,所有权重加起来等于 1
- 权重 × V,加权求和 → 新向量——按注意力权重对所有 V 向量加权求和,得到融入了上下文信息的新向量,代表"当前 token 在这个语境下的含义"
新向量 = Σ attention_weight(i) × V(i)
多头注意力
语言里同时存在多个层面的关系,单个注意力机制只能关注一种模式。多头注意力并行运行多个独立的注意力"视角",每个头学习不同的关系,例如:
| 头 | 关注的关系 | 例子 |
|---|---|---|
| 语法关系 | 动词和其主语/宾语 | "猫追老鼠"里,"追"关注"猫"和"老鼠" |
| 指代关系 | 代词指向谁 | "小明去了超市,他买了苹果"里,"他"关注"小明" |
| 位置邻近 | 相邻的几个词 | 注意力矩阵接近对角线 |
| 语义相关 | 无论距离远近,语义相近的词互相关注 | "喜欢"和"喜爱"在长句中会互相注意到对方 |
多个头的输出拼接在一起,再经过一次线性变换,得到最终的注意力输出。多头 = 同时用多个角度理解句子,再综合所有视角的信息。
四、Transformer Block(下):加工、传递与稳定训练
STEP 3Attention 只解决了 token 之间的"交流",交流完之后还需要加工、传递、稳定这三件事——这正是 FFN、残差连接、LayerNorm 各自要解决的问题,四者组合在一起,才是一个完整的 Transformer Block。
FFN:加工信息
FFN(Feed-Forward Network,前馈网络)通常接在 Attention 后面,两者分工完全不同:
| 模块 | 处理方式 | 作用 |
|---|---|---|
| Attention | token 之间互相交流 | 跨 token 通信,收集上下文信息 |
| FFN | 每个 token 独立处理 | 消化、转化信息,单 token 变换 |
Attention 本质上是线性操作(加权求和),没有真正的"加工"能力;FFN 提供非线性变换(两层神经网络 + 激活函数),是模型真正"消化信息"和"存储知识"的地方。FFN 的参数量约占整个模型的 2/3,是 Transformer 里参数最密集的部分。
残差连接
深层神经网络有两个根本问题:信号衰减——每层都对输入做变换,经过多层后原始信息几乎消失;梯度消失——训练时梯度往回传,每经过一层就乘以一个小于 1 的数,传到底层时接近 0,参数无法更新。
解法是:输出 = x + F(x)。每层只需要学"相比输入,应该改变多少"(增量),而不是从头生成一份全新的表示。
残差流:Attention 和 FFN 都向主干贡献增量,而不是替换主干
残差流是整个模型唯一的信息主干,贯穿所有层。Attention 和 FFN 只是挂在主干旁边的"处理站",负责往主干上叠加增量——Block 之间传递的是这条不断被叠加丰富的残差流,而不是某一层的输出。
LayerNorm
深层网络的另一个问题是数值稳定:每层做矩阵乘法,数值可能每层都变大一点,几十层叠下来可能增长到极端量级,导致梯度爆炸、训练崩溃。
解法:在每层结束后,对每个 token 的向量做标准化——均值归零、方差归一,保证进入下一层的数值永远在合理范围内。
完整 Block 六步流程
这里用的是 Pre-Norm(LayerNorm 放在子层前面),也是现代 LLM 的主流做法。经典架构图(2017 年原论文)画的其实是 Post-Norm——Add & Norm 排在 Attention / Feed Forward 之后。两者顺序相反:Post-Norm 归一化会"经过"残差流,深层堆叠时容易不稳定;Pre-Norm 让残差流全程不被归一化触碰,训练更稳,因此被后来的模型普遍采用。
一个完整的 Block 包含两组完全对称的结构:
第一组:处理 token 之间的关系
- LayerNorm:先把残差流的数值稳定住
- Multi-Head Attention:token 之间互相交流,收集上下文信息
- 残差相加:
x = x + Attention(LayerNorm(x))
第二组:处理单个 token 的信息加工
- LayerNorm:再次归一化,防止数值偏移
- FFN:每个 token 独立加工信息
- 残差相加:
x = x + FFN(LayerNorm(x))
x' = x + Attention(LayerNorm(x))
x' = x' + FFN(LayerNorm(x'))
Block 结束后,把残差流传给下一个 Block,重复这个过程 N 次。
为什么堆很多层
不同深度的层往往学到不同层次的语言能力(实验观察到的大致规律):
| 层次 | 更可能处理的内容 |
|---|---|
| 浅层 | 词性、标点、相邻关系、表面语法模式 |
| 中层 | 主谓宾结构、从句关系、代词指向 |
| 中深层 | 世界知识、语义理解、事实记忆 |
| 深层 | 多步推理、任务规划、复杂跨段落整合 |
五、Linear 与 Softmax:从向量到下一个 Token
STEP 4经过 N 层 Transformer Block 之后,最后一个位置的向量已经融合了全部上下文信息,接下来要把这个向量变成"下一个 token 是谁"的概率分布。
Linear:线性变换为何能预测下一个 Token
这一步在架构图里通常标为 Linear,也就是"预测头"——一个把词向量维度映射回词表空间的线性层。它的权重矩阵 W 形状是 [词表大小 × 词向量维度],每一行代表词表里一个 token 的"期望特征向量"。这个线性变换本质上是在做相似度匹配——找出当前上下文向量 h 和哪个 token 的"期望方向"最接近,那个 token 的概率就最高:
logit[i] = h · W[i]ᵀ (点积 = 相似度)
点积越大 → logit 越大 → Softmax 后概率越高 → 模型越倾向于预测这个 token。
W 矩阵是怎么学会的?训练时,每当上下文后面跟着某个正确 token,就计算 Loss 并反向传播,把 W 里对应那一行和当前隐藏状态 h 的方向调得更近一点。经过海量样本的调整,W 的每一行最终学到了"什么样的上下文应该预测我"。
Softmax:把分数变概率
P(token_i) = exp(logit_i) / Σ exp(logit_j)
Softmax 保证所有 token 的概率加起来等于 1,形成合法的概率分布。最后按温度参数控制的随机程度进行采样,得到下一个 token。
六、完整推理流程:把所有步骤串起来
Token → Embedding + 位置编码(变成向量)
→ × N 层 Transformer Block(残差流不断叠加丰富)
→ Linear(词向量维度 → 词表维度 logit)
→ Softmax(logit → 概率分布)
→ 采样(概率 → 下一个 Token)
→ 重复
总结
Attention 负责跨 token 交流:我应该参考上下文里的谁?
FFN 负责逐 token 加工:拿到信息后,我该怎么消化和变换?
残差连接 负责保留信息主干:原始信息怎样穿过很多层不被冲淡?
LayerNorm 负责稳定数值:每一层的输入怎样保持在可控范围?
Linear + Softmax 负责收尾:把融合了上下文的向量,变回一个可以采样的概率分布。