图解大模型
Transformer 与注意力基础
我们现在使用的基本都是补全模型(decoder-only),尤其是代码智能体。
上下文长度(上下文窗口)是模型一次可以处理的最大词元(token)数量。
模型具有自回归特性:每生成一个新词元,就把它追加进上下文,再预测下一个。
按注意力可见范围,常见两类:
- 编码模型(Encoder):通常双向,每个位置可以看整句,适合理解、分类等。
- 解码模型(Decoder,如 GPT 系):因果(只能看过去与当前),适合逐词生成。
LLM 常见训练阶段:
- 语言建模(预训练):目标是较好地预测下一个词元,多用无标注的大规模文本。
- 微调(后训练):针对特定任务继续训练,多用有标注或按任务构造好的数据。
无监督大致指数据没有人工任务标签;有监督指数据按任务打了标签或提供了标准答案。
如何训练分词器
分词器把原始文本切成词元,并建立词表(每个词元对应一个整数 id)。
研发侧主动设定的是:词表规模上限、切分算法(如 BPE)、特殊符号等。训练分词器本身通常是在语料上统计合并规则,得到一份固定词表与切分规则;它一般不随 LLM 权重一起用梯度更新。
词表大小会直接决定后面嵌入矩阵的行数。更细的训练流程留待后续展开。
如何嵌入
LLM 内部的词元嵌入,是一张可学习的查找表:词元 id → 长度为
整张表就是嵌入矩阵
文本嵌入
文本嵌入是把整段文本变成一个向量,常用于 RAG、语义搜索、分类等,例如给互联网搜索结果做向量化。
它和上面「词元嵌入矩阵」相关但场景不同:一个是模型内部每个词元的表示;一个是整段文本的汇总向量,供检索等下游使用。
贪心解码
每次都选概率最高的那个词元,就是贪心解码。
它发生在 LLM 的输出阶段。温度设为 0 时,通常等价于按输出分布取最大概率词元。
温度等是推理超参,不是训练学到的权重。
Transformer 支持并行计算
相对早期逐步依赖前一隐状态的循环结构,Transformer 的自注意力可以在序列长度维上并行计算,训练更吃得开并行算力。
一次前向大致是:
- 对当前输入序列查嵌入、加位置信息,得到表示矩阵
(形状:序列长度 × )。注意: 是这一步前向即时得到的,不是训完永久固定的一张表。 - Transformer 每层准备可训练权重
、 、 (查询、键、值)。 - 用
分别乘这三个权重:
直觉上:
:我要寻找什么? :我有什么特征,可以与你匹配? :匹配上之后,我实际提供什么信息?
- 自注意力:让一个词元从其他词元的表示里,取对自己有用的信息。核心先算分数:
- Softmax:分数本身加起来不一定是 1,需要 Softmax 变成一组权重。
- 加权求和:用注意力权重对
加权,得到每个词元融合了其他位置信息后的新表示。这就是该层注意力的输出(多头时还要再投影,见下一节)。
矩阵从哪来
LLM 里出现的矩阵,按身份可以分成三类。一句话:研发定结构与规则;训练改权重数值;前向用当前输入算出中间量。
flowchart TD design[研发主动设定] learn[训练学得的参数] compute[前向即时算出] design -->|"决定形状、规则、初始化方案"| learn learn -->|"前向乘法与非线性"| compute
研发主动设定
这些不是「学」出来的权重值,而是架构与训练配置:
、层数、头数、 (中间层常约 ) - 依据:算力与效果折中,常复用已验证的架构配方(如 GPT 系)。
- 词表大小、上下文长度
- 依据:分词器与业务场景,以及显存、吞吐预算。
以及 FFN 权重的形状 - 依据:由
、 、 等推出来,不是手填矩阵里的每个数。
- 依据:由
- 初始化方案(如正态、Xavier 等)、因果掩码规则、激活函数种类
- 依据:训练稳定性;解码器「只能看过去」的任务约束。
- 温度等解码超参
- 依据:推理策略,不属于训练学到的权重。
研发定的是:有哪些矩阵、多大、怎么初始化、掩码怎么铺。不手填注意力分数里的具体数字。
训练学得的参数
初始按方案随机(或约定初值),再用反向传播更新:
- 词元嵌入矩阵
- 每层注意力的
、 、 ,以及多头合并后的 - FFN 的
、 、 、 - LayerNorm 的
、 (通常初值接近「几乎不做额外缩放/平移」) - (若采用)可学习位置嵌入、输出词表投影 / lm_head
直接回答常见疑问:
前向即时算出
每条输入、每一步都会变,一般不存成「模型参数」:
- 本步输入表示
(查嵌入 + 位置信息之后) 、 、 - 分数矩阵
、掩码后的分数、Softmax 权重、加权后的注意力输出、FFN 中间激活等
因果掩码本身通常也是按规则构造的,不参与梯度更新。
多头注意力
例如 2 头注意力,就需要算两套
因果掩码
由
填负无穷是因为 Softmax 时
因果掩码和 Softmax 的完整计算
输入:小明、喜欢、打、球。
假设正在计算「打」:按因果掩码,可以关注「小明、喜欢、打」,不能看「球」。
- 注意力得分:
- 应用因果掩码:
- Softmax 先指数化:
- 注意力权重:
缩放点积注意力
向量维度变大时,点积往往也变大,Softmax 后的权重会极端尖锐。
所以要缩放,除以:
Feed Forward Network 前馈神经网络
经典 Transformer FFN:
先把维度扩大到大约原来的 4 倍,再压回原维度。扩大是为了给特征组合和非线性变换更大的中间空间;
激活函数引入非线性,提升表达能力。常见例子:
升维之后再做一次线性变换,把维度降回
残差连接与层归一化
如果 Transformer 有几十层甚至上百层,每一层都对向量做复杂变换,信息容易在层层计算中走偏,训练也会更难。
残差连接:不要让每一层都从头构造结果,而是:
这样设计主要有两点:
保留信息的直通路径
即使某个模块只产生很小的变化,原来的表示仍可通过相加路径传下去。改善深层网络的梯度传播
对输入求导:
这里的
层归一化在归一化什么
在 Transformer 中,LayerNorm 通常针对每个 Token 自己的特征向量做归一化,而不是把一句话里所有 Token 混在一起算。
例如「小明喜欢打球」经嵌入等计算后,假设四个 Token、每个维度为 3:
这是一个
- 4:Token 数量
- 3:每个 Token 的特征维度
LayerNorm 分别处理每一行。例如第二行
第一步:计算均值
代入:
第二步:计算方差
方差衡量各数值相对均值的偏离程度:
代入:
标准差:
第三步:标准化
逐个计算:
因此:
可学习的缩放和平移
真实的 LayerNorm 还有两个可学习参数:
:控制缩放 :控制平移
完整公式:
其中:
:很小的数,避免分母为零 :逐元素相乘 :训练中学得的参数
为什么归一化后还要允许缩放和平移?因为模型不一定希望每个特征始终保持均值 0、方差 1。归一化提供稳定的数值基础,可学习参数再允许模型调到适合自己的数值范围。