目标:系统性地理解现代大语言模型(如 GPT)背后的核心训练机制,从最基础的因果注意力开始,一直讲到正则化与泛化,形成完整的知识图谱。

前置要求:了解基本的神经网络概念(前向传播、反向传播)和线性代数基础(矩阵乘法、向量点积)。

本文将沿一条清晰的逻辑主线展开:架构设计 → 优化目标 → 学习算法 → 泛化控制。我们将从 Transformer 的核心——注意力机制出发,逐步构建起对大语言模型训练全貌的理解。

在进入正题之前,先简要说明大语言模型训练的"全景图"。一个 LLM 的诞生大致经历三个阶段:预训练(在海量文本上学习语言规律)、监督微调(SFT)(学习遵循指令)和人类偏好对齐(RLHF)(让输出更符合人类期望)。本文聚焦于这些阶段背后通用的基础机制——无论哪个阶段,都离不开注意力架构、损失函数、优化器和正则化。


0. 从文本到向量——Tokenization 与词嵌入

  在进入 Transformer 架构之前,需要先解决一个基础问题:如何将人类的文本变成模型能处理的数字? 这个过程分为两步:Tokenization(分词)和词嵌入(Embedding)。

0.1 Tokenization:将文本切分为 Token

  最朴素的做法是按空格切分,但这会面临两个严重问题:未登录词(OOV)和词表过大。现代大语言模型普遍采用字节对编码(BPE, Byte Pair Encoding)

  • 初始时,词表由单个字符(或字节)组成。
  • 统计训练语料中相邻字符对的出现频率,将最频繁的字符对合并为一个新 Token。
  • 重复此过程,直到词表达到预设大小。

类比:汉字的偏旁部首。BPE 就像学习汉字时发现"木"+“目”= “相”。常用词被编码为单个 Token(如"hello"),罕见词被拆解为子词片段(如"un"+“common”+“ly”),从而在有限词表下覆盖任意文本。

0.2 词嵌入与权重共享

  Tokenization 输出的整数序列需要映射为连续向量。词嵌入层本质上是一个查找表:

$$ \text{Embedding}(x) = E[x] \in \mathbb{R}^{d_{\text{model}}} $$

其中 $E \in \mathbb{R}^{|V| \times d_{\text{model}}}$ 是嵌入矩阵,$|V|$ 是词表大小,$d_{\text{model}}$ 是模型维度。

  一个重要的技巧是权重共享(Weight Tying):让输入嵌入矩阵和输出层(LM Head)的权重矩阵共享同一组参数。直觉上,语义相近的词在输入和输出空间中应该有相近的表示。这一技巧能大幅减少参数量,同时提升性能。


1. 因果注意力——大语言模型的"眼睛"

1.1 什么是注意力机制

  想象你正在阅读一句话:「今天天气真好,我想去____」。当你预测下一个词时,你的大脑会自动"回看"前面的每个词,并赋予不同的关注度——“天气真好"和"想去"对你预测"公园"或"散步"的贡献最大,而"今天"的贡献相对较小。

  注意力机制(Attention) 正是对这一过程的数学建模。它让模型在生成每一个新词时,能够动态地"回看"之前的所有词,并根据相关性分配不同的权重。

1.2 Q、K、V 的物理意义

  注意力机制的核心是三个向量:Query(查询)Key(键)Value(值)。它们通过线性变换从输入词嵌入中产生:

$$ Q = XW^Q, \quad K = XW^K, \quad V = XW^V $$

其中 $X$ 是输入序列的词嵌入矩阵,$W^Q$、$W^K$、$W^V$ 是可学习的参数矩阵。

类比:图书馆查书

  • Query(查询):你脑中的问题——“我想找关于深度学习的资料”
  • Key(键):每本书封面的关键词标签——“机器学习”、“烹饪”、“深度学习入门”
  • Value(值):每本书的实际内容——书页里的具体文字

注意力的计算过程就是:用你的问题(Q)去和每本书的标签(K)做匹配,匹配度越高的书,你读得越仔细(V 的权重越大)。

1.3 缩放点积注意力

  注意力的计算公式如下:

$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$

逐步拆解:

  1. $QK^T$:计算 Query 和每个 Key 的点积,得到"相关性分数”。维度为 $d_k$ 的两个向量做点积,结果的量级大约是 $d_k$。
  2. 除以 $\sqrt{d_k}$:当 $d_k$ 很大时,点积的值会很大,导致 Softmax 的输入进入梯度极小的"饱和区"。除以 $\sqrt{d_k}$ 将方差稳定在 1 附近,让梯度传播更健康。
  3. Softmax:将相关性分数转化为概率分布,确保所有权重之和为 1,且非负。
  4. 乘以 $V$:用概率分布对 Value 向量做加权求和,得到最终的注意力输出。

Softmax 的数学定义

$$ \text{softmax}(z_i) = \frac{e^{z_i}}{\sum_{j} e^{z_j}} $$

它将任意实数向量映射为一个概率分布:每个元素在 0 到 1 之间,且所有元素之和为 1。

Softmax 与 Sigmoid 函数

数值稳定性技巧:在实际实现中,直接计算 $e^{z_i}$ 可能导致数值溢出(当 $z_i$ 很大时)。解决方案是先减去最大值:

$$ \text{softmax}(z_i) = \text{softmax}(z_i - \max_j z_j) $$

这个变换在数学上完全等价(因为 $e^{z_i - c}$ 和 $e^{z_i}$ 只差一个常数因子,会被分母消掉),但数值上避免了溢出。这是所有深度学习框架(PyTorch、TensorFlow)的标准做法。

具体数值示例:假设序列长度为 3,$d_k = 2$,已知:

$$ Q = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}, \quad K = \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 1 & 1 \end{bmatrix}, \quad V = \begin{bmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \end{bmatrix} $$

第一步,计算注意力分数(暂不缩放和掩码):

$$ QK^T = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 1 \\ 0 & 1 & 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & 1 \\ 0 & 1 & 1 \end{bmatrix} $$

第二步,除以 $\sqrt{d_k} = \sqrt{2} \approx 1.414$,然后对每一行做 Softmax:

$$ \text{softmax}\left(\frac{[1, 0, 1]}{\sqrt{2}}\right) = \text{softmax}([0.707, 0, 0.707]) \approx [0.405, 0.190, 0.405] $$

第三步,用概率分布加权求和 V:

$$ \text{output}_1 = 0.405 \times [1,2] + 0.190 \times [3,4] + 0.405 \times [5,6] = [2.99, 3.82] $$

可以看到,位置 1 的输出对位置 1 和位置 3(相关性分数相同)的 Value 给予了更高的权重。

1.4 因果注意力:下三角掩码

  在传统的注意力机制中,每个位置可以看到序列中的所有位置。但对于语言模型来说,这会导致"偷看未来"——生成第 3 个词时不能让它看到第 4 个词的答案,否则就是作弊。

  因果注意力(Causal Attention) 通过一个下三角掩码矩阵来解决这个问题:

$$ M_{ij} = \begin{cases} 0 & \text{if } i \geq j \\ -\infty & \text{if } i < j \end{cases} $$

掩码加在 Softmax 之前:

$$ \text{CausalAttention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}} + M\right)V $$

被设为 $-\infty$ 的位置,经过 Softmax 后权重变为 $e^{-\infty} \approx 0$,相当于被完全屏蔽。

因果注意力掩码矩阵

类比:传话游戏中的"只能听到已说过的部分"

想象一排人玩传话游戏,每个人只能听到之前所有人说过的话,不能预知后面的人会说什么。因果注意力就是这个"隔音屏障"——第 $t$ 个位置只能看到位置 $1, 2, \ldots, t-1$ 以及位置 $t$ 自身的信息。

1.5 “只能看到第 1 到 t-1 个词"的真实含义

  这里有一个常见的误解需要澄清:当说"第 $t$ 个位置只能看到前 $t-1$ 个词"时,意思是它可以同时看到全部历史,而不仅仅是前一个词。这是一个全局视野,不是滑动窗口。

  例如,当模型生成第 10 个词时,它可以同时关注第 1 到第 9 个词中的任何一个。这正是 Transformer 相比 RNN 的一个关键优势——我们将在后文详细讨论。


2. Transformer 的配套设计

2.1 多头注意力(Multi-Head Attention)

  单个注意力头只能捕捉一种"关注模式”。但语言中的关系是多维的:一个词可能同时需要关注语法关系、语义关系、位置关系等。

  多头注意力的思路很简单:把 $d_k$ 维的 Q、K、V 拆成 $h$ 个头,每个头独立计算注意力,最后拼接起来:

$$ \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \ldots, \text{head}_h)W^O $$

其中每个头:

$$ \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) $$

类比:不同专家看同一幅画

  • 专家 A 关注颜色搭配(语法结构)
  • 专家 B 关注光影关系(语义关联)
  • 专家 C 关注视觉焦点(长距离指代)

每个人从不同角度分析,最后汇总意见,得到更全面的理解。

关于降维的"多角度学习"目的:每个头的维度是 $d_k / h$,这是一种降维操作。其目的不是压缩信息,而是让不同的头在不同的低维子空间中学习不同的注意力模式,实现"多角度学习"。

2.2 位置编码(Positional Encoding)

  注意力机制本身是"无序"的——它只关心 Q 和 K 的相似度,不关心位置。如果把句子打乱顺序,注意力的输出不会变。但语言显然有顺序:“狗咬人"和"人咬狗"意思完全不同。

  因此需要位置编码来注入位置信息。

绝对位置编码:直接给每个位置一个固定的或可学习的向量,加到词嵌入上:

$$ \text{Input} = \text{TokenEmbedding}(x) + \text{PositionEmbedding}(pos) $$

原始 Transformer 使用正弦/余弦函数生成固定编码:

$$ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d}}\right), \quad PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d}}\right) $$

相对位置编码:不编码绝对位置,而是编码"两个词之间的距离”。例如 RoPE(Rotary Position Embedding)通过旋转矩阵将相对位置信息融入 Q 和 K 的点积中,让注意力分数自然地反映位置距离。这是现代大语言模型(如 LLaMA)的主流方案。

2.3 残差连接与层归一化

每一个 Transformer 子层(注意力层或 FFN 层)都被包装在残差连接层归一化之中。原始 Transformer 采用 Post-Norm(后归一化):

$$ \text{output} = \text{LayerNorm}(x + \text{SubLayer}(x)) $$

但现代大语言模型(GPT-2 以后、LLaMA 等)普遍采用 Pre-Norm(前归一化):

$$ \text{output} = x + \text{SubLayer}(\text{LayerNorm}(x)) $$

Pre-Norm vs Post-Norm 的区别

  • Post-Norm:先做子层变换和残差相加,再归一化。优点是最终输出范围严格受控;缺点是梯度需要穿过 LayerNorm 才能到达残差路径,深层网络训练不稳定。
  • Pre-Norm:先归一化再做子层变换,残差路径上没有 LayerNorm 阻挡。梯度可以通过残差路径"无障碍"地传到最前面的层,训练更稳定,支持更深的网络。

类比:先检查还是后检查。Post-Norm 像是产品出厂后才做质检,如果不合格就要返工;Pre-Norm 像是原材料进厂前就做好质检,生产线上的每一步都用合格的材料,成品率更高。

残差连接(Residual Connection)

  类比:高速公路的出口匝道。主干道(原始信号 $x$)直接通到终点,匝道(子层变换 $\text{SubLayer}(x)$)提供额外的信息增益。即使匝道暂时施工(梯度很小),主干道依然畅通,信息不会丢失。

  残差连接的核心价值:

  • 梯度高速公路:反向传播时,梯度可以通过恒等映射直接传到前面的层,缓解深层网络的梯度消失问题。
  • 更容易学习:网络只需学习"增量修改"($\text{SubLayer}(x)$),而不是从头重新表示整个输入。

层归一化(LayerNorm)

  对同一个样本的所有特征维度做归一化:

$$ \text{LayerNorm}(x) = \gamma \cdot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta $$

其中 $\mu$ 和 $\sigma^2$ 是在特征维度上计算的均值和方差,$\gamma$ 和 $\beta$ 是可学习的缩放和偏移参数。

  LayerNorm 的作用是将每一层的激活值稳定在合理的范围内,防止数值在深层网络中逐层放大或缩小,从而加速训练收敛。


3. 前馈网络(FFN)——升维与降维

3.1 FFN 的"升维→激活→降维"结构

  每个 Transformer 层除了注意力子层之外,还有一个前馈网络(FFN)

$$ \text{FFN}(x) = W_2 \cdot \text{ReLU}(W_1 x + b_1) + b_2 $$

其中 $W_1$ 将维度从 $d_{\text{model}}$ 映射到 $d_{\text{ff}}$(通常是 $4 \times d_{\text{model}}$),$W_2$ 再映射回 $d_{\text{model}}$。

  这就是典型的升维→激活→降维结构:

  • 升维($W_1$):将输入投影到更高维的空间,增加模型的表达能力。在高维空间中,原本纠缠在一起的特征更容易被线性分离。
  • 激活(ReLU):引入非线性,让模型能够学习复杂的决策边界。
  • 降维($W_2$):压缩回原始维度,保留关键信息。

FFN 结构示意

类比:搅拌机原理。把水果(输入)放入大容量搅拌机(升维空间),充分搅拌(非线性激活),再倒回杯子(降维)。大容量搅拌机能让果汁混合得更均匀。

3.2 现代 FFN 变体:SwiGLU

  原始 Transformer 使用 ReLU 作为激活函数,但现代大语言模型(如 LLaMA、PaLM)普遍采用 SwiGLU 激活,其公式为:

$$ \text{FFN}_{\text{SwiGLU}}(x) = W_2 \left[ \text{Swish}(W_1 x) \odot (W_3 x) \right] $$

其中 $\text{Swish}(x) = x \cdot \sigma(x)$,$\sigma$ 是 Sigmoid 函数,$\odot$ 表示逐元素相乘(门控机制)。

与原始 FFN 的区别

  • 引入了门控机制(第三个矩阵 $W_3$),让模型可以动态地"选择"哪些特征通道应该被激活。
  • Swish 是一种"平滑的 ReLU",在零点附近没有突变,梯度更平滑。
  • 为了保持参数量不变,中间维度从 $4d_{\text{model}}$ 缩减为 $\frac{8}{3}d_{\text{model}}$(约 2.67 倍)。

为什么 SwiGLU 效果更好? 门控机制相当于让 FFN 有了"选择性注意力"——不是所有中间特征都一视同仁地被激活,而是根据输入动态调节。这提升了 FFN 的表达能力和参数效率。

3.3 FFN 作为键值存储器

  近年来的研究提出了一个有趣的假说:FFN 的两层权重矩阵可以看作一个键值存储器(Key-Value Memory)

  • 第一层权重 $W_1$ 的每一行是一个"键"(key),模式类似于"当输入匹配某种语义模式时激活"。
  • 第二层权重 $W_2$ 的每一列是对应的"值"(value),存储了该模式对应的输出知识。

  FFN 本质上存储了大量"如果遇到 X 模式,就输出 Y"的规则。这解释了为什么增大 FFN 的中间维度(即增加存储容量)能显著提升模型的知识存储能力。

3.4 澄清:加权操作不等于升维

  需要注意的是,注意力机制中的加权求和操作虽然涉及多个向量的组合,但它不是升维。加权求和的结果维度和单个 Value 向量相同:

$$ \text{output} = \sum_i \alpha_i V_i \in \mathbb{R}^{d_v} $$

这是一种同维度的混合,不会增加表示的维度。真正的升维是通过线性变换(如 FFN 中的 $W_1$)将特征投影到更高维的空间。


4. Transformer 相比 RNN 的优势

  在 Transformer 出现之前,循环神经网络(RNN)及其变体(LSTM、GRU)是序列建模的主流方案。Transformer 相比 RNN 有以下关键优势:

4.1 长距离依赖

  RNN 的信息必须逐步传递——第 100 个词的信息要经过 99 步才能到达第 1 个词的位置,即使有 LSTM 的门控机制,信息仍然会逐步衰减。

  Transformer 的注意力机制是直接连接——第 100 个位置可以直接关注第 1 个位置,路径长度为 $O(1)$,不存在信息衰减问题。

RNN vs Transformer 信息路径

类比:电话 vs 传话游戏。RNN 像传话游戏,信息在传递过程中逐渐失真;Transformer 像电话,任意两人可以直接通话。

4.2 并行计算

  RNN 的计算是串行的:必须先计算 $h_1$,才能计算 $h_2$,依此类推。对于长度为 $n$ 的序列,需要 $O(n)$ 步顺序计算。

  Transformer 的注意力计算是完全并行的:所有位置的 Q、K、V 可以同时计算,注意力矩阵可以一次性得出。在训练时(处理已知的完整序列),这可以充分利用 GPU 的并行计算能力,大幅加速训练。

4.3 梯度传播稳定性

  RNN 的梯度需要通过时间步逐步反向传播,链式法则的连乘效应导致梯度容易消失或爆炸(梯度消失/爆炸问题)。

  Transformer 的注意力是"一步到位"的矩阵运算,配合残差连接,梯度可以通过捷径直接传播,稳定性远优于 RNN。

4.4 KV Cache 推理加速

  在自回归生成(逐词生成)时,Transformer 有一个巧妙的优化:KV Cache

  生成第 $t$ 个词时,注意力需要用到所有前 $t-1$ 个位置的 K 和 V。但这些值在之前生成时已经计算过了,不需要重复计算。KV Cache 将已计算的 K 和 V 缓存起来,每生成一个新词只需计算新位置的 Q、K、V,然后与缓存拼接,将推理复杂度从 $O(t^2)$ 降低到 $O(t)$。

4.5 Flash Attention:内存效率的革命

  标准注意力计算需要将完整的注意力矩阵 $QK^T \in \mathbb{R}^{n \times n}$ 存储在 GPU 的 HBM(高带宽内存)中,内存复杂度为 $O(n^2)$。当序列长度 $n$ 很大时(如 8192 或更长),这成为严重的内存瓶颈。

  Flash Attention(Dao et al., 2022)通过分块计算(tiling)在线 Softmax 技术,避免了完整注意力矩阵的物化:

  • 将 Q、K、V 分成小块,每次只在 SRAM(片上缓存,速度快但容量小)中计算一块的注意力。
  • 通过在线算法,在不存储完整 $QK^T$ 矩阵的情况下,逐步计算出正确的 Softmax 输出。
  • 内存复杂度从 $O(n^2)$ 降到 $O(n)$,同时利用了 SRAM 的高速特性,实际速度反而更快。

类比:流水线作业。标准注意力像是一次性把所有食材铺满整个厨房台面再开始做菜;Flash Attention 像是流水线——每次只处理一小批食材,用完就清理台面,腾出空间处理下一批。台面(内存)占用大大减少,效率反而更高。

  Flash Attention 已成为现代 LLM 训练和推理的事实标准,几乎所有主流框架(HuggingFace、vLLM)都已集成。


5. 训练基础组件

5.1 权重、损失函数、梯度——下山比喻

  训练神经网络就像在大雾中下山:

  • 权重(Weights):你在山上的位置坐标。你的目标是找到海拔最低的山谷(最优解)。
  • 损失函数(Loss):海拔高度。它衡量你当前的"错误程度"——位置越差,海拔越高。
  • 梯度(Gradient):脚下的坡度方向。它告诉你往哪个方向走能最快降低海拔。
  • 学习率(Learning Rate):每一步的步幅大小。步幅太大可能跨过山谷(发散),步幅太小则下山太慢。

5.2 学习率与梯度下降

  梯度下降的更新公式:

$$ w_{t+1} = w_t - \eta \cdot \nabla_w L(w_t) $$

其中 $\eta$ 是学习率,$\nabla_w L(w_t)$ 是损失函数对权重 $w$ 的梯度。

  直观理解:沿着梯度的反方向(即损失下降最快的方向)移动一步。学习率 $\eta$ 控制步幅。

学习率调度:实践中,学习率通常不是固定的。最常用的策略是 Warmup + Cosine Decay

  • Warmup 阶段(前 1%~5% 步数):学习率从 0 线性增长到目标峰值 $\eta_{\text{max}}$。原因是在训练初期,模型参数几乎是随机的,梯度方向很不稳定。如果一开始就用大学习率,参数可能被"甩飞"。Warmup 给优化器(尤其是 Adam 的移动平均统计量)一个"热身"时间。
  • Cosine Decay 阶段:学习率按余弦函数缓慢衰减,公式为:
$$ \eta_t = \eta_{\text{min}} + \frac{1}{2}(\eta_{\text{max}} - \eta_{\text{min}})\left(1 + \cos\left(\frac{t - T_{\text{warmup}}}{T_{\text{total}}} \cdot \pi\right)\right) $$

这种衰减方式在训练中后期比线性衰减更"柔和",让模型有更多时间在最优解附近精细搜索。

梯度裁剪(Gradient Clipping):另一个保障训练稳定性的重要技术。当梯度的范数超过阈值 $\tau$ 时,对梯度进行等比缩放:

$$ g \leftarrow \frac{\tau}{\|g\|} \cdot g \quad \text{if } \|g\| > \tau $$

Warmup + Cosine Decay 学习率调度

类比:安全绳。梯度裁剪就像登山时的安全绳——正常行走时不受影响,但当某一步突然踩空(梯度爆炸)时,安全绳会拉住你,防止坠崖。典型的裁剪阈值为 1.0,这对几乎所有大语言模型训练都是标配。

5.3 优化器的演进

SGD(随机梯度下降)

  最基本的优化器,直接用当前梯度更新权重:

$$ w_{t+1} = w_t - \eta \cdot g_t $$

其中 $g_t = \nabla_w L(w_t)$ 是当前 mini-batch 的梯度。

  问题:梯度方向在不同 batch 之间可能剧烈波动,导致更新路径呈"之字形"震荡,收敛慢。

Momentum(动量)

  引入"速度"的概念,让更新具有惯性:

$$ v_t = \beta \cdot v_{t-1} + g_t $$$$ w_{t+1} = w_t - \eta \cdot v_t $$

其中 $\beta$ 是动量系数(通常取 0.9)。

优化器轨迹对比

类比:球滚下山坡。SGD 像一个没有惯性的点,每一步都直接转向当前最陡的方向;Momentum 像一个有质量的球,它会保持之前的速度方向,遇到小的凹凸不会轻易改变方向,在一个方向上持续加速。

Adam(Adaptive Moment Estimation)

  Adam 结合了 Momentum 和 RMSprop 的思想,维护两个移动平均:

$$ m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t \quad \text{(一阶矩:梯度的均值)} $$$$ v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 \quad \text{(二阶矩:梯度的方差)} $$

偏差修正后:

$$ \hat{m}_t = \frac{m_t}{1 - \beta_1^t}, \quad \hat{v}_t = \frac{v_t}{1 - \beta_2^t} $$

更新规则:

$$ w_{t+1} = w_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} $$

核心思想:每个参数有自己的自适应学习率。梯度变化剧烈的参数($\hat{v}_t$ 大)自动降低学习率,梯度变化平稳的参数($\hat{v}_t$ 小)保持较大学习率。

三种优化器对比

特性SGDMomentumAdam
更新方向当前梯度梯度的移动平均梯度均值 / 梯度标准差
自适应学习率有(每个参数不同)
收敛速度中等
超参数敏感度高(需精调学习率)中等低(默认参数通常可用)
泛化性能最好(有时)较好略差(需配合权重衰减)

6. 损失函数的数学本质——最大似然估计

6.1 MLE 的哲学

  训练神经网络的损失函数,其根源是最大似然估计(Maximum Likelihood Estimation, MLE)。MLE 的哲学朴素而深刻:

给定观测到的训练数据,找到一组模型参数,使得模型生成这些数据的概率最大。

  数学表述:假设训练数据为 $\{x_1, x_2, \ldots, x_N\}$,模型参数为 $\theta$,则 MLE 的目标是:

$$ \theta^* = \arg\max_\theta \prod_{i=1}^{N} p_\theta(x_i) = \arg\max_\theta \sum_{i=1}^{N} \log p_\theta(x_i) $$

取对数将连乘变为连和(对数似然),最大化对数似然等价于最小化负对数似然(NLL)

6.2 负对数似然(NLL)——通用损失框架

$$ \mathcal{L}_{\text{NLL}} = -\frac{1}{N}\sum_{i=1}^{N} \log p_\theta(x_i) $$

NLL 是几乎所有损失函数的统一框架。接下来我们看它在不同假设下如何推导出具体的损失函数。

6.3 假设误差服从正态分布 → 推导出 MSE

  对于回归任务,假设模型输出 $f_\theta(x)$ 与真实值 $y$ 之间的误差服从正态分布:

$$ p(y \mid x; \theta) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left(-\frac{(y - f_\theta(x))^2}{2\sigma^2}\right) $$

取负对数似然:

$$ -\log p(y \mid x; \theta) = \frac{(y - f_\theta(x))^2}{2\sigma^2} + \frac{1}{2}\log(2\pi\sigma^2) $$

忽略常数项,对所有样本求平均,就得到均方误差(MSE)

$$ \mathcal{L}_{\text{MSE}} = \frac{1}{N}\sum_{i=1}^{N}(y_i - f_\theta(x_i))^2 $$

直观理解假设误差是正态分布的,那么"最可能的参数"就是让预测值和真实值的差距平方和最小的那些参数。

6.4 假设类别服从多项分布 → 推导出交叉熵损失

  对于分类任务,假设输出类别服从多项分布。模型输出 logits $z$,经过 Softmax 转化为概率:

$$ p(y = k \mid x; \theta) = \text{softmax}(z_k) = \frac{e^{z_k}}{\sum_{j} e^{z_j}} $$

负对数似然为:

$$ -\log p(y = k \mid x; \theta) = -\log \frac{e^{z_k}}{\sum_{j} e^{z_j}} = -z_k + \log \sum_{j} e^{z_j} $$

这就是交叉熵损失(Cross-Entropy Loss)。对于 $N$ 个样本:

$$ \mathcal{L}_{\text{CE}} = -\frac{1}{N}\sum_{i=1}^{N} \log \frac{e^{z_{i,y_i}}}{\sum_{j} e^{z_{i,j}}} $$

其中 $z_{i,y_i}$ 是第 $i$ 个样本在正确类别上的 logit 值。

6.5 Softmax 的作用

  Softmax 将原始的 logits(可以是任意实数)转化为一个概率分布:

$$ \text{softmax}(z_k) = \frac{e^{z_k}}{\sum_{j} e^{z_j}} \in (0, 1), \quad \sum_k \text{softmax}(z_k) = 1 $$

两个关键性质

  • 归一化:输出之和为 1,符合概率的定义。
  • 突出最大值:指数函数放大了大值和小值之间的差距。如果 logits 是 $[2, 1, 0.1]$,Softmax 输出约为 $[0.659, 0.242, 0.099]$,最大的值获得了最大的概率。

6.6 交叉熵、KL 散度、负对数似然的等价关系

  这三个概念在分类问题中是等价的,但它们的直觉不同。

KL 散度(Kullback-Leibler Divergence):衡量两个概率分布 $p$(真实分布)和 $q$(模型分布)之间的"距离":

$$ D_{\text{KL}}(p \| q) = \sum_{k} p_k \log \frac{p_k}{q_k} $$

展开:

$$ D_{\text{KL}}(p \| q) = \underbrace{-\sum_{k} p_k \log q_k}_{\text{交叉熵 } H(p, q)} - \underbrace{\left(-\sum_{k} p_k \log p_k\right)}_{\text{熵 } H(p)} $$

即:

$$ D_{\text{KL}}(p \| q) = H(p, q) - H(p) $$

对于分类问题,真实分布 $p$ 是 one-hot 向量(如 $[0, 0, 1, 0]$),其熵 $H(p) = 0$。因此:

$$ D_{\text{KL}}(p \| q) = H(p, q) = -\log q_{\text{correct}} $$

这就是负对数似然!也就是说,在 one-hot 标签的分类问题中:

交叉熵 = KL 散度 = 负对数似然

直观理解

  • NLL 的视角:最大化模型生成正确标签的概率。
  • 交叉熵 的视角:用模型分布 $q$ 编码来自真实分布 $p$ 的信息,所需的平均比特数越小越好。
  • KL 散度 的视角:让模型分布 $q$ 尽量接近真实分布 $p$。

6.7 为什么分类任务不用 MSE?

  从梯度的角度可以给出清晰的解释。

  假设使用 MSE 损失 $\mathcal{L} = \frac{1}{2}(y - \hat{y})^2$,其中 $\hat{y} = \sigma(z)$ 是 Sigmoid 输出。对 logit $z$ 求梯度:

$$ \frac{\partial \mathcal{L}_{\text{MSE}}}{\partial z} = (\hat{y} - y) \cdot \sigma'(z) $$

而交叉熵损失的梯度是:

$$ \frac{\partial \mathcal{L}_{\text{CE}}}{\partial z} = \hat{y} - y $$

关键区别:MSE 的梯度多了一个 $\sigma'(z)$ 因子。当 $\sigma(z)$ 接近 0 或 1 时(Sigmoid 的饱和区),$\sigma'(z) \approx 0$,导致梯度消失。即使模型的预测完全错误($\hat{y} \approx 0$ 但 $y = 1$),梯度也接近零,模型无法学习。

  而交叉熵的梯度 $\hat{y} - y$ 不受 Sigmoid 导数的影响,即使在饱和区也能提供足够大的梯度,让模型快速修正错误。

MSE vs 交叉熵梯度对比

类比:报警系统。MSE 像一个在极端情况下失灵的报警器——当错误最严重时反而不响了;交叉熵像一个始终可靠的报警器——错误越大,警报越响。


7. 语言模型特有的评估与技巧

7.1 困惑度(Perplexity)

  困惑度是语言模型最常用的评估指标,定义为:

$$ \text{PPL} = \exp\left(-\frac{1}{N}\sum_{i=1}^{N} \log p_\theta(x_i \mid x_{\lt i})\right) = \exp(\mathcal{L}_{\text{NLL}}) $$

直观意义:困惑度可以理解为模型在每个位置的"有效选择数"。

  • PPL = 1:模型完全确定下一个词是什么(完美预测)。
  • PPL = 100:模型相当于在 100 个候选词之间犹豫不决。
  • PPL = V(词表大小):模型等于在做均匀随机猜测,完全没有学到规律。

困惑度直观理解

类比:考试中的困惑。PPL = 1 意味着你每道题都确定答案;PPL = 100 意味着每道题你都在 100 个选项中纠结;PPL = 50000 意味着你对每个空都完全没有头绪。

  困惑度越低,语言模型越好。现代大语言模型的困惑度可以降到很低的水平,这也是它们能够生成流畅文本的原因。

7.2 标签平滑(Label Smoothing)

  标准的 one-hot 标签是一种"极端自信"的表示:正确类别的概率是 1,其他都是 0。这会导致模型过度自信,logit 值趋向无穷大。

  标签平滑将 one-hot 标签"软化":

$$ y_{\text{smooth}} = (1 - \epsilon) \cdot y_{\text{one-hot}} + \epsilon \cdot \frac{1}{K} $$

其中 $\epsilon$ 是平滑系数(通常取 0.1),$K$ 是类别数。

  例如,对于 4 分类,原本的 $[0, 0, 1, 0]$ 变为 $[0.025, 0.025, 0.925, 0.025]$。

正则化效果:标签平滑防止模型对自己的预测过于自信,迫使 logit 值保持在合理范围内。这等价于在标准交叉熵基础上引入了一个 KL 散度惩罚项,鼓励模型输出分布不要太偏离均匀分布。

类比:谦虚的学习者。标签平滑像是在告诉模型:“你认为答案是 C,但也要给 A、B、D 一点可能性,不要那么绝对。“这种"谦虚"的态度让模型对未见过的数据更加鲁棒。


8. 过拟合与泛化

8.1 训练 Loss 最小 ≠ 模型最好

  一个关键的认知:训练损失(Training Loss)低不代表模型好。模型可能只是"记住"了训练数据的所有细节(包括噪声),而不是学到了真正的规律。这就像一个学生把所有习题的答案都背下来了,但遇到新题就束手无策。

  验证损失(Validation Loss)才是黄金标准。它衡量模型在未见过的数据上的表现,反映的是模型的泛化能力。

  当出现以下情况时,就是过拟合的信号:

  • 训练 Loss 持续下降,但验证 Loss 开始上升
  • 两个 Loss 之间出现"剪刀差”

8.2 早停(Early Stopping)

  早停是最简单直接的过拟合应对策略:在训练过程中持续监控验证 Loss,当验证 Loss 不再下降(甚至开始上升)时,提前终止训练。

类比:适可而止的练习。练钢琴时,刚开始你的演奏水平不断提升,但练到某个点后开始越弹越差(手指疲劳、过度适应某个版本)。聪明的做法是在最佳状态时停下来。

8.3 Dropout

  Dropout 是一种简单而有效的正则化技术:在训练时,以概率 $p$(通常为 0.1 到 0.5)随机将某些神经元的输出置为 0。

$$ \text{Dropout}(h_i) = \begin{cases} 0 & \text{with probability } p \\ \frac{h_i}{1-p} & \text{with probability } 1-p \end{cases} $$

注意除以 $(1-p)$ 是为了保持期望值不变(期望值缩放),这样推理时就不需要做任何特殊处理。

为什么 Dropout 有效?

  • 打破共适应:阻止神经元之间形成固定的"联盟"关系,迫使每个神经元独立地学习有用的特征。
  • 隐式集成:每次 Dropout 相当于训练一个不同的子网络。推理时相当于对所有子网络做集成平均,类似于随机森林的思路。
  • 增加噪声:为训练过程注入随机性,防止模型过度依赖某些特定的特征路径。

9. 正则化的深入剖析——L1 与 L2

9.1 损失函数加惩罚项

  正则化的核心思想是:在原始损失函数上添加一个惩罚项,限制模型的复杂度。

$$ \mathcal{L}_{\text{total}} = \mathcal{L}_{\text{data}} + \lambda \cdot R(w) $$

其中 $\mathcal{L}_{\text{data}}$ 是数据损失(如交叉熵),$R(w)$ 是正则化项,$\lambda$ 是正则化强度系数。

9.2 L2 正则化

L2 公式

$$ R_{L2}(w) = \frac{1}{2}\sum_{i} w_i^2 = \frac{1}{2}\|w\|_2^2 $$

(加 $\frac{1}{2}$ 是为了求导方便。)

L2 梯度

$$ \frac{\partial R_{L2}}{\partial w_i} = w_i $$

加上系数 $\lambda$ 后,L2 正则化对总损失的梯度贡献为 $2\lambda w$(有些实现中省略了 2)。注意,这个力的大小与权重成正比

类比:弹簧力。L2 正则化就像在每个权重上绑了一根弹簧,把它们拉向零。权重越大,弹簧拉力越大。这意味着:

  • 大权重受到很强的惩罚,会被快速拉小。
  • 但弹簧力永远不为零,所以权重会趋于零但不会精确为零——它们只是变得很小很小。

权重更新公式(SGD + L2)

$$ w_{t+1} = w_t - \eta \cdot (\nabla_w \mathcal{L}_{\text{data}} + 2\lambda w_t) = (1 - 2\eta\lambda)w_t - \eta \cdot \nabla_w \mathcal{L}_{\text{data}} $$

注意到 $(1 - 2\eta\lambda) < 1$,这意味着每一步更新都会让权重先"衰减"一小部分,然后再减去数据梯度。这就是权重衰减(Weight Decay) 这个名字的来源。

9.3 L1 正则化

L1 公式

$$ R_{L1}(w) = \sum_{i} |w_i| = \|w\|_1 $$

L1 梯度(次梯度)

$$ \frac{\partial R_{L1}}{\partial w_i} = \text{sign}(w_i) = \begin{cases} +1 & \text{if } w_i > 0 \\ -1 & \text{if } w_i < 0 \end{cases} $$

关键区别:L1 的梯度大小是恒定的($\pm \lambda$),与权重的大小无关。

类比:恒定摩擦力。L1 正则化像一个恒定大小的摩擦力——不管物体(权重)在什么位置,摩擦力的大小都一样。这意味着:

  • 小权重受到的"相对惩罚"很大(对于 $w = 0.001$,惩罚梯度 $1$ 比数据梯度大得多),会被直接推到零。
  • 大权重受到的"相对惩罚"很小,可以保留。
  • 因此 L1 正则化倾向于产生精确的零权重(稀疏解),相当于自动进行特征选择。

9.4 几何直觉:等高线与约束区

  另一种理解 L1 和 L2 正则化的方式是从约束优化的角度。将正则化问题等价地看作:

$$ \min_w \mathcal{L}_{\text{data}}(w) \quad \text{subject to} \quad R(w) \leq t $$

为什么损失函数的等高线是椭圆?

  在最优解附近,对损失函数做二阶泰勒展开:

$$ \mathcal{L}(w) \approx \mathcal{L}(w^*) + \frac{1}{2}(w - w^*)^T H (w - w^*) $$

其中 $H$ 是 Hessian 矩阵(二阶导数矩阵),它是正定的。令这个二次型等于常数,就得到一个椭圆的方程——椭圆的形状由 Hessian 的特征值决定。

L2 的约束区:$|w|_2^2 \leq t$ 是一个圆形(二维)或超球面。圆形与椭圆等高线的切点通常不在坐标轴上,所以解的各个分量都不为零——没有稀疏性。

L1 的约束区:$|w|_1 \leq t$ 是一个菱形(二维)或超正方体。菱形的"尖角"恰好在坐标轴上。由于椭圆等高线在扩张时最容易与菱形的尖角接触,所以切点往往在坐标轴上——对应某些分量恰好为零,即稀疏解

类比:气球膨胀碰到障碍物。损失函数的等高线像一个不断膨胀的气球。L2 的约束区是圆柱,气球碰到的是圆滑的表面,接触点不在特殊位置;L1 的约束区是钻石形,气球最容易碰到尖角——尖角恰好对应零权重。

L1 vs L2 正则化几何解释

9.5 权重衰减与 L2 正则化的关系

  在 SGD 下,L2 正则化和权重衰减是等价的。但当使用自适应学习率优化器(如 Adam)时,两者不再等价

L2 正则化:将 $2\lambda w$ 加入梯度,然后经过 Adam 的自适应缩放:

$$ w_{t+1} = w_t - \eta \cdot \frac{\hat{m}_t + 2\lambda w_t}{\sqrt{\hat{v}_t} + \epsilon} $$

权重衰减:直接在更新步骤中衰减权重,不经过自适应缩放:

$$ w_{t+1} = (1 - \lambda)w_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} $$

关键区别:在 L2 正则化 + Adam 中,正则化梯度 $2\lambda w$ 也被自适应学习率 $\frac{1}{\sqrt{\hat{v}_t}}$ 缩放了。对于梯度变化剧烈的参数($\hat{v}_t$ 大),正则化效果会被削弱,导致这些参数的权重衰减不够充分。

  AdamW(Decoupled Weight Decay)正是为了修正这个问题而提出的:将权重衰减从梯度计算中解耦出来,直接作用于权重更新,恢复了权重衰减应有的正则化效果。AdamW 是现代大语言模型训练的标准优化器。


10. 训练工程实践

  以上讨论的都是"理论层面"的机制。在实际训练大语言模型时,还需要一些工程技巧来应对计算资源和训练稳定性的问题。

10.1 混合精度训练

  标准的神经网络训练使用 FP32(32 位浮点数)存储参数、梯度和激活值。但现代 GPU 的 Tensor Core 对 FP16/BF16(16 位浮点数)有专门的加速支持,吞吐量可以翻倍甚至更多。

  混合精度训练的核心思路:用低精度(FP16 或 BF16)做前向和反向传播以加速计算,同时保留一份 FP32 的"主权重副本"用于更新,以避免精度损失。

具体流程:

  1. 维护一份 FP32 的主权重。
  2. 每次迭代时,将主权重转为 FP16/BF16,执行前向和反向传播。
  3. 得到 FP16/BF16 的梯度后,转回 FP32 来更新主权重。

FP16 vs BF16 的选择

特性FP16BF16
指数位5 位8 位
尾数位10 位7 位
动态范围较小(容易溢出)与 FP32 相同
精度较高较低
是否需要 Loss Scaling通常不需要

  BF16(Brain Floating Point)是 Google 专门为深度学习设计的格式,牺牲了一些精度但保留了和 FP32 相同的动态范围,避免了梯度上溢/下溢问题,因此在大语言模型训练中更受欢迎。

10.2 Scaling Laws——缩放定律

  Kaplan 等人(2020)和 Hoffmann 等人(2022,Chinchilla 论文)发现了一个令人惊叹的规律:大语言模型的性能(以交叉熵损失衡量)与三个因素之间存在幂律关系

$$ L(N, D) = \frac{A}{N^{\alpha}} + \frac{B}{D^{\beta}} + L_{\infty} $$

其中:

  • $N$ 是模型参数量
  • $D$ 是训练数据量(token 数)
  • $L_{\infty}$ 是不可约减的损失下限(语言本身的熵)

核心洞察

  • 参数量和数据量应该同步增长。Chinchilla 论文指出,最优配比大约是 1 个参数对应 20 个训练 token。
  • 更大的模型不一定更好:如果数据量不够,一个大模型可能还不如一个在更多数据上训练的小模型(Chinchilla 70B 优于 Gopher 280B)。
  • 计算预算的最优分配:给定固定的 GPU 算力预算,应该在模型大小和数据量之间找到最优平衡点,而不是一味地增大模型。

延伸阅读:关于模型规模与泛化能力之间的深层关系(包括双重下降现象),详见本站文章 深度学习中的双下降现象(Double Descent)与缩放定律(Scaling Law)

类比:厨师与食材。模型参数就像厨师的技艺(越多"手法"越好),训练数据就像食材的种类和数量。一个技艺超群的厨师如果只见过几种食材,做出的菜品也不会太丰富;反过来,食材再多但厨师技艺粗糙,也做不出好菜。最好的办法是两者匹配增长。


11. 全文总结与知识图谱

  让我们回顾本文的逻辑主线:

flowchart TD
    T0["Tokenization(BPE)"] --> T1["词嵌入 + 权重共享"]
    T1 --> A["因果注意力(架构核心)"]
    A --> B["Q/K/V + 缩放点积"]
    B --> C["下三角掩码(自回归)"]
    A --> D["多头注意力(多角度学习)"]
    A --> E["位置编码(RoPE / 正弦)"]
    D --> F["残差连接 + LayerNorm"]
    E --> F
    F --> G["FFN(升维-激活-降维 / SwiGLU)"]
    G --> H["Transformer Block"]
    H --> I["训练目标:最大似然估计"]
    I --> J["NLL → 交叉熵 / MSE"]
    J --> K["Softmax 转概率分布"]
    I --> L["困惑度(PPL)评估"]
    L --> M["标签平滑(正则化)"]
    H --> N["优化器:SGD → Momentum → AdamW"]
    N --> O["Warmup + Cosine Decay"]
    N --> P["梯度裁剪"]
    H --> Q["泛化控制"]
    Q --> R["过拟合 vs 欠拟合"]
    R --> S["早停 / Dropout"]
    R --> V["L1 正则化(稀疏)"]
    R --> W["L2 正则化(平滑)"]
    H --> X["混合精度训练(BF16/FP16)"]
    H --> Y["Scaling Laws(参数-数据配比)"]

架构设计层面:Tokenization(BPE)→ 词嵌入(权重共享)→ 因果注意力 + 多头机制 + 位置编码 + 残差/LayerNorm + FFN(SwiGLU)构成了 Transformer 的完整骨架,解决了 RNN 的长距离依赖和并行化难题。

优化目标层面:最大似然估计(MLE)是损失函数的数学根基,NLL 是统一框架,交叉熵和 MSE 是其在不同假设下的特例。Softmax 将 logits 转化为概率分布,困惑度提供直觉化的评估指标。

学习算法层面:从 SGD 到 Momentum 再到 AdamW,优化器通过引入动量和自适应学习率加速收敛。Warmup + Cosine Decay 学习率调度确保训练稳定启动并精细收尾。梯度裁剪为训练过程提供安全保障。

泛化控制层面:Dropout、标签平滑、L1/L2 正则化、早停等技术从不同角度防止过拟合。理解 L1(恒力→稀疏)和 L2(变力→平滑)的力学直觉,以及 AdamW 的设计动机,是正确使用正则化的关键。

工程实践层面:混合精度训练利用 BF16/FP16 加速计算,Scaling Laws 指导模型大小与数据量的最优配比。


系列导航