首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >大语言模型的基石:Transformer 入坑笔记(三) - 注意力机制和 Transformer

大语言模型的基石:Transformer 入坑笔记(三) - 注意力机制和 Transformer

作者头像
owent
发布2026-06-28 09:16:22
发布2026-06-28 09:16:22
630
举报
文章被收录于专栏:owentowent

背景

接上文 《大语言模型的基石:Transformer 入坑笔记(二) - 基本原理和 Word Embeddings》,继续我们的 Attention Is All You Need/Transformer 学习之旅。

首先简单了解下传统的方案。

卷积神经网络(CNN)

卷积神经网络(CNN)似乎更适合静态数据(比如图片处理、提取特征等)。 所谓静态数据,是指每个数据组都单独和目标矩阵运算,通过卷积层、池化层、全连接层等输出。 每个数据组都单独运算所以可以大规模并发,但是数据组之间也缺乏关联。 我大概看了下原理,和我们要关注的 Transformer 关系不大,先略过了。

循环神经网络(RNN)

我们处理文本的时候,需要让神经网络知道上下文关系。 比如一句话: “我上午要去图书馆借书,下午去参加比赛。晚饭前我会把它还掉。” 那么在这里,系统需要知道“它”指的是“书”。

传统循环神经网络(RNN)的方法就是把后续数据叠加到前文输入里来传递上下文表达。 这里不详细铺开循环神经网络(RNN)的原理和过程,因为不是我们要关注的重点。大致了解一下流程和问题即可。

比如我们要把 I love llamas 翻译成中文。 典型的 RNN encoder-decoder 会先把源句子读成隐藏状态,Decoder 再按顺序生成目标 Token。每一步都会依赖上一步的隐藏状态和已经生成的 Token。

Step

Input

Output

1

I love llamas

2

I love llamas 我

3

I love llamas 我爱

羊驼

注意: 词向量、隐藏状态以及最终计算输出的w、b矩阵都是不同的。

显然这里有两个问题。一是同一个序列里的每一步都依赖上一步结果,并行度受限。二是内容太长时,早期信息会逐渐被隐藏状态压缩掉,长距离依赖容易丢。 当然有一些方法一定程度缓解这个问题,但是也不是我们要关注的 Transformer 的重点就也略过了。

Transformer

那前面两种模型都有各自的问题。俗话说小孩子才做选择,大人我全都要。怎么办呢?于是 Transformer 来了。

这有个非常好的工具 Transformer Explainer,可以把 Transformer 里的各个步骤拆开看,很适合理解整体流程。 这个工具甚至还发了篇 Paper:《Transformer Explainer: Learning LLM Transformers with Interactive Visual Explanation and Experimentation》

注意力机制并不是 《Attention Is All You Need》 的首创,之前已经有人把它用来缓解传统神经网络在长距离依赖上的问题。 这篇论文真正激进的地方,是把循环和卷积从主干里拿掉,只用注意力搭出完整序列模型。还是先贴 Transformer 的基本框架:

图 1:Transformer 模型架构(来自 《Attention Is All You Need》)。左侧为 Encoder,右侧为 Decoder,Encoder block 和 Decoder block 各重复 N 次。

Positional Encoding

一上来,仍然是把输入数据做 Embedding。具体方式和原理前面解释过了,这里就不复述了。 然后差异点是,现在还要融合 Positional Encoding 矩阵,表示词所在的位置。

2610-add-positional-encoding.png
2610-add-positional-encoding.png

为什么需要 Positional Encoding 矩阵呢?因为 Transformer 的注意力层本身不会天然知道 Token 的先后顺序;如果不额外加入位置信息,模型很难区分“我爱你”和“你爱我”这种同词不同序的输入。Positional Encoding 矩阵的公式如下:

$$ \begin{aligned} \mathbf{PE}{(\text{pos}, 2i)} &= \sin\left(\frac{\text{pos}}{10000^{2i/d{\text{model}}}}\right) \ \mathbf{PE}{(\text{pos}, 2i+1)} &= \cos\left(\frac{\text{pos}}{10000^{2i/d{\text{model}}}}\right) \end{aligned} $$

如果序列长度为 L,模型维度为 d_{model},位置编码矩阵 PE 的维度就是 L \times d_{model}。然后:

  • pos :词在序列中的位置(从 0 开始)。其中序列长度为 L,则 0 \le pos < L
  • d_{model} :模型的总维度(如 512、768、1024 等,Transformer 论文里是 512)
  • i :维度索引对(2i2i+1 成对出现,0 \le i < d_{model}/2

位置公式不是定死的,只要满足几个条件即可。

  • 唯一标识: 每个位置必须有独一无二的编码向量
  • 相对距离可感知: 模型能判断“相隔 k 个位置”的关系,而不仅是绝对位置
  • 平滑过渡: 相邻位置的编码应该相近,反映位置的连续性
  • 值域有界: 编码值不能过大或过小,避免破坏词嵌入的数值分布

Transformer 的方案使用的是正弦和余弦函数,值域范围是 -1 \le PE \le 1,距离感知推导如下:

利用三角函数加法公式:\sin(a+b) = \sin a \cos b + \cos a \sin b,令 a = pos \cdot w_i, b = k \cdot w_i(其中 w_i = \frac{1}{10000^{2i/d_{\text{model}}}}),则:

$$ \begin{aligned} \mathbf{PE}{(\text{pos}+k, 2i)} &= \sin(\text{pos}\cdot w_i + k\cdot w_i) \ &= \underbrace{\sin(\text{pos}\cdot w_i)}{\mathbf{PE}{(\text{pos},2i)}} \underbrace{\cos(k\cdot w_i)}{\text{仅与}k\text{有关}} + \underbrace{\cos(\text{pos}\cdot w_i)}{\mathbf{PE}{(\text{pos},2i+1)}} \underbrace{\sin(k\cdot w_i)}_{\text{仅与}k\text{有关}} \end{aligned} $$

同理: \mathbf{PE}{(\text{pos}+k, 2i+1)} = \mathbf{PE}{(\text{pos},2i+1)}\cos(k\cdot w_i) - \mathbf{PE}_{(\text{pos},2i)}\sin(k\cdot w_i)

所以是满足这些条件的。不过要注意的是,原始公式没有“超过某个位置就不能用”的硬上限;它可以外推,但最长波长的量级大约是 10000 \times 2\pi,序列长度远超训练范围后效果不能只靠公式保证。现代长上下文模型通常还会配合 RoPE、ALiBi、位置插值、分块或稀疏注意力等方案。 最后,显然对确定的总维度,这个位置编码矩阵是可以提前算好的。

注意力机制

Transformer 注意力机制核心部分叫做 self-attention (自注意力)。基本流程可以理解为:当前 Token 拿着 Query 去和所有 Key 做匹配,再按匹配权重汇总对应的 Value。 当然这些数据都是向量。可以这么理解:

  • 查询(Q):当前 Token 想找什么信息。
  • 键(K):每个 Token 对外提供的匹配索引。
  • 值(V):真正被加权汇总的信息内容。

实际计算时,同一份输入矩阵 X 会分别乘以三组可训练权重矩阵,得到 QKV 三组向量。图里把维度压成 4 格只是为了画得清楚;真实模型里,X \in \mathbb{R}^{L \times d_{model}}W^Q/W^K \in \mathbb{R}^{d_{model} \times d_k}W^V \in \mathbb{R}^{d_{model} \times d_v}

Q/K/V 线性投影示意图

图 2:Q/K/V 线性投影。Self-Attention 使用同一份输入 X,通过三组不同的权重矩阵生成后续注意力计算需要的 Query、Key 和 Value。

图 3:Scaled Dot-Product Attention(左)与 Multi-Head Attention(右)。左侧展示 Q/K/V 的注意力计算流程,右侧展示 h 个并行注意力头拼接后再线性投影的结构。

对于单个单头的注意力,计算公式如下:

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

这里的 d_k 是 Key 向量的维度。除以 \sqrt{d_k} 是为了把点积结果拉回更合适的数值范围,避免维度变大后 softmax 太容易进入饱和区。W^QW^KW^V 这些矩阵也是训练出来的。

$$ \begin{aligned} X &\in \mathbb{R}^{L \times d_{model}} \ W^Q &\in \mathbb{R}^{d_{model} \times d_k} \ W^K &\in \mathbb{R}^{d_{model} \times d_k} \ W^V &\in \mathbb{R}^{d_{model} \times d_v} \end{aligned} $$

$$ \begin{aligned} Q &= XW^Q \in \mathbb{R}^{L \times d_k} \ K &= XW^K \in \mathbb{R}^{L \times d_k} \ V &= XW^V \in \mathbb{R}^{L \times d_v} \end{aligned} $$

相当于把每个 Token 都投影到 Query、Key、Value 三个表示空间中。

2610-self-attention-qkv-calc.png
2610-self-attention-qkv-calc.png

然后计算每个 Q 和每个 Key 的相似程度,也表达了每个 Token 对其他 Token 的注意程度,即 QK^T。这里的 \frac{1}{\sqrt{d_k}} 是一个缩放,用于控制方差,让点积的方差和输入向量的维度无关。

这个缩放项可以直接推出来。先看某一个 Query 向量 q 和 Key 向量 k 的点积:

s = q \cdot k = \sum_{i=1}^{d_k} q_i k_i

为了只看维度带来的影响,先假设这些分量彼此独立,均值为 0,方差为 1。单项乘积的期望为:

\mathbb{E}[q_i k_i] = \mathbb{E}[q_i]\mathbb{E}[k_i] = 0

方差为:

$$ \begin{aligned} \mathrm{Var}(q_i k_i) &= \mathbb{E}[q_i^2 k_i^2] - \mathbb{E}[q_i k_i]^2 \ &= \mathbb{E}[q_i^2]\mathbb{E}[k_i^2] \ &= 1 \end{aligned} $$

点积是 d_k 个这样的项相加,所以:

\mathrm{Var}(s) = \mathrm{Var}\left(\sum_{i=1}^{d_k} q_i k_i\right) = d_k

也就是说,d_k 越大,QK^T 里的分数波动越大,标准差大约是 \sqrt{d_k}。把它除以 \sqrt{d_k} 后:

$$ \mathrm{Var}\left(\frac{s}{\sqrt{d_k}}\right) = \frac{\mathrm{Var}(s)}{d_k} = 1 $$

如果 q_ik_i 的方差不是 1,而是 \sigma_q^2\sigma_k^2,点积方差会变成 d_k\sigma_q^2\sigma_k^2,这个缩放项同样能消掉由 d_k 带来的那部分放大。

Softmax 对这个尺度很敏感。它的梯度是:

$$ \frac{\partial \mathrm{softmax}(z)_i}{\partial z_j} = \mathrm{softmax}(z)i \left(\mathbf{1}{i=j} - \mathrm{softmax}(z)_j\right) $$

如果 z 里的某个分数远大于其他分数,Softmax 会非常接近 one-hot:最大项接近 1,其他项接近 0。这时上面的梯度项也会接近 0,反向传播很难把注意力权重再调回来。在 float 精度有限时,指数函数的差距还可能直接把小概率压到接近 0。除以 \sqrt{d_k} 不是为了改变排序,而是让 logits 的尺度别随着 d_k 增大而失控,减轻 Softmax 饱和和梯度变小的问题。

最后再 Softmax 归一化。

2610-self-attention-qkv.png
2610-self-attention-qkv.png

这个图里还有一次 Mask 遮挡。它的作用是模拟阅读和写作过程:生成当前位置时,后面的词还没看到,所以不应该参与注意力计算。

\mathrm{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) 的结果是一个 L \times L 的注意力权重矩阵,再乘以 V 后得到 L \times d_v 的输出。现代化LLM有些支持1M上下文,不可能真的 1M * 1M 这么夸张的计算量,肯定是通过稀疏注意力 / 滑动窗口 / 分块注意力或其他方式分块计算的。然后把计算量从 O(L^2) 压到接近 O(Lw),其中 w 是窗口大小。

到这里,单头注意力 的主要流程就结束了。

每个注意力头都有自己的一组 W^Q, W^K, W^V,会学到一类匹配偏好,但单头表达能力有限。为了让模型同时看不同关系,就引入了 多头注意力。

多头注意力 就是让多个注意力头并行计算,再把结果拼接起来。

$$ \operatorname{MultiHead}(X) = \operatorname{Concat}(\operatorname{head}_1, \dots, \operatorname{head}_h)W^O \ \text{where } \operatorname{head}_i = \operatorname{Attention}(XW_i^Q, XW_i^K, XW_i^V) $$

这里又引入了一个新的投影矩阵:W^O \in \mathbb{R}^{hd_v \times d_{model}},其中 h 是并行的注意力头数(原论文 h = 8)。它负责把拼接后的表示重新投影到 d_{model} 维度。

到这里,多头注意力 的计算过程就完成了。当然后面还会经过 残差连接(Residual Connection)和 LayerNorm;再通过 前馈神经网络(FFN) 执行非线性变换。MoE、激活函数、归一化位置这些优化又是另一个层面的内容,已经超出这篇入门笔记的范围,这里先不展开。

《Attention Is All You Need》 论文里的 Position-wise FFN 由两个线性变换组成,中间接一个 ReLU 激活函数:FFN(x) = \max\left(0, xW_1 + b_1\right)W_2 + b_2。输入和输出维度为 d_{model} = 512,中间层维度为 d_{ff} = 2048

整个模型的注意力整合

我们再回到整体的架构图。

在整体架构里,无论是左边 Encoder 的 self-attention (自注意力) 层,还是右边的 self-attention (自注意力) 层 和 encoder-decoder attention 层,都是多层堆叠出来的。 《Attention Is All You Need》 论文的堆叠层数 N = 6

在左边的 Encoder 的每层堆叠 中,除了第 1 层外,Q、K、V 都来自上一层的输出。

第一层:

H_E^{0} = \operatorname{Dropout}\left(\operatorname{Emb}{src}(X) + PE{src}\right)

然后对后面每一层:

$$ \begin{aligned}

A_E^{l} &= \operatorname{MHA}\left(H_E^{l-1}, H_E^{l-1}, H_E^{l-1}\right) \

\tilde{H}_E^{l} &= \operatorname{LayerNorm}\left(H_E^{l-1} + \operatorname{Dropout}\left(A_E^{l}\right)\right) \

F_E^{l} &= \operatorname{FFN}\left(\tilde{H}_E^{l}\right) \

H_E^{l} &= \operatorname{LayerNorm}\left(\tilde{H}_E^{l} + \operatorname{Dropout}\left(F_E^{l}\right)\right) \end{aligned} \qquad l = 1, \dots, N $$

  • Encoder 的每一层都有自己的 W^Q,W^K,W^V,W^O 和 FFN 参数。
  • Encoder self-attention 里,Q/K/V 都来自同一个输入:第一层来自 Embedding + PE,后续层来自上一层输出。
  • Encoder 不需要 mask,因为输入序列一次性全部可见,每个 token 可以 attend 到所有输入位置。
  • PE: Positional Encoding 不逐层重复添加。位置信息已经混进了 H^0,后面通过残差连接、Attention 和 FFN 一层层传下去。

然后:

$$ \begin{aligned} Q_E^l &= H_E^{l-1} W_{E}^{Q,l} \ K_E^l &= H_E^{l-1} W_{E}^{K,l} \ V_E^l &= H_E^{l-1} W_{E}^{V,l} \end{aligned} \qquad l = 1,\dots,N $$

右边 Decoder 包含两段注意力计算:Decoder masked self-attentionDecoder encoder-decoder attention。其中:

第一层:

H_D^{0} = \operatorname{Dropout}\left(\operatorname{Emb}{tgt}(Y{<t}) + PE_{tgt}\right)

然后对后面每一层:

$$ \begin{aligned} A_D^{l} &= \operatorname{MaskedMHA}\left(H_D^{l-1}, H_D^{l-1}, H_D^{l-1}\right) \

\tilde{H}_D^{l} &= \operatorname{LayerNorm}\left(H_D^{l-1} + \operatorname{Dropout}\left(A_D^{l}\right)\right) \

C_D^{l} &= \operatorname{MHA}\left(\tilde{H}_D^{l}, H_E^{N}, H_E^{N}\right) \

\hat{H}_D^{l} &= \operatorname{LayerNorm}\left(\tilde{H}_D^{l} + \operatorname{Dropout}\left(C_D^{l}\right)\right) \

F_D^{l} &= \operatorname{FFN}\left(\hat{H}_D^{l}\right) \

H_D^{l} &= \operatorname{LayerNorm}\left(\hat{H}_D^{l} + \operatorname{Dropout}\left(F_D^{l}\right)\right) \end{aligned} \qquad l = 1, \dots, N $$

这段公式要拆开看:

  • MaskedMHA:Q/K/V 都来自 Decoder 当前层输入,并且使用 causal mask。
  • Cross-attention MHA:Q 来自 masked self-attention 后的 \tilde{H}_D^l,K/V 来自 Encoder 最后一层输出 H_E^N
  • PE 表示 Positional Encoding,MHA 表示多头注意力计算。

然后右边的第一段 Decoder masked self-attention,Q、K、V 都来自 Decoder 自己。

$$ \begin{aligned} Q_{D,\mathrm{self}}^l &= H_D^{l-1} W_{D,\mathrm{self}}^{Q,l} \ K_{D,\mathrm{self}}^l &= H_D^{l-1} W_{D,\mathrm{self}}^{K,l} \ V_{D,\mathrm{self}}^l &= H_D^{l-1} W_{D,\mathrm{self}}^{V,l} \end{aligned} \qquad l = 1,\dots,N $$

而右边的第二段 Decoder encoder-decoder attention,也常叫 cross-attention。这里 K、V 来自左边 Encoder 多层堆叠后的最终结果 H_E^N,Q 来自 Decoder 当前层 masked self-attention 之后的 \tilde{H}_D^l。所以右侧的 Output Embedding 会先进入 Decoder self-attention,再作为 cross-attention 的 Query 来源。

$$ \begin{aligned} Q_{D,\mathrm{cross}}^l &= \tilde{H}D^l W{D,\mathrm{cross}}^{Q,l} \ K_{D,\mathrm{cross}}^l &= H_E^N W_{D,\mathrm{cross}}^{K,l} \ V_{D,\mathrm{cross}}^l &= H_E^N W_{D,\mathrm{cross}}^{V,l} \end{aligned} \qquad l = 1,\dots,N $$

在语言模型的 Decoder 端,多层 Transformer block 会先得到每个位置的 hidden state;最后通过 lm_head 映射到词表维度,为每个 Token 生成一个 logit,再经过 softmax 得到概率分布。GPT-2 这类模型的 FFN/MLP 中间层常用 GELU,但输出词表 logits 的那一层本质上还是线性投影。

2610-mlp-t-k-to-probability.png
2610-mlp-t-k-to-probability.png

这张图也能解释现在 LLM 里 temperature、top_p / top_k 这些采样参数的作用。 如果是贪心解码,就直接选概率最高的那个词;如果是采样解码,就会在筛选后的概率分布里抽样。

这里也能看出 LLM 的底层目标:在当前上下文里预测下一个 Token 的概率分布。 所以它输出的往往是训练数据、后训练和解码策略共同推出来的高概率结果。这也导致了,如果某些情况下 “真理往往掌握在少数人手中” 的时候,大语言模型就掌握不了真理。

怎么训练 $W^Q$、$W^K$、$W^V$、$W^O$ ?

对于一组注意力矩阵来说,W^QW^KW^VW^O 是同时训练出来的,具体训练方法和上一章 《大语言模型的基石:Transformer 入坑笔记(二) - 基本原理和 Word Embeddings》 的基本原理一致。主线就是 前向计算 -> loss -> 反向传播 -> 同时更新参数。

代码语言:javascript
复制
flowchart TD
    S["训练样本
输入 tokens + 目标 tokens"] --> E["Embedding + Positional Encoding"]

    subgraph F["前向传播"]
        E --> P["线性投影
Q = XW^Q
K = XW^K
V = XW^V"]
        P --> A["Attention
softmax(QK^T / sqrt(d_k))V"]
        A --> C["多头拼接
Concat(head_1, ..., head_h)"]
        C --> O["输出投影
Concat(heads) W^O"]
        O --> N["后续层
Add and Norm / FFN / 输出层"]
        N --> Y["预测词表概率"]
    end

    subgraph L["损失函数"]
        Y --> CE["Cross Entropy Loss
和真实目标 token 对比"]
    end

    subgraph B["反向传播"]
        CE --> G["计算梯度
dL/dW^Q
dL/dW^K
dL/dW^V
dL/dW^O"]
        G --> U["优化器更新
Adam / AdamW"]
        U --> W["同时更新
W^Q, W^K, W^V, W^O"]
    end

    W -. "下一批数据继续训练" .-> E

训练样本就是大量的语料文本。更新矩阵参数时,仍然是:

$$ \begin{aligned} W_i^Q &\leftarrow W_i^Q - \eta \frac{\partial \mathcal{L}}{\partial W_i^Q} \ W_i^K &\leftarrow W_i^K - \eta \frac{\partial \mathcal{L}}{\partial W_i^K} \ W_i^V &\leftarrow W_i^V - \eta \frac{\partial \mathcal{L}}{\partial W_i^V} \ W^O &\leftarrow W^O - \eta \frac{\partial \mathcal{L}}{\partial W^O} \end{aligned} \qquad i = 1,\dots,h $$

不同 attention head / layer 的区别主要来自:

  • 结构位置不同:同样叫 attention,看到的输入不一样。比如第 1 层看到的是 H^0 = Embedding(X) + PE,第 6 层看到的是前 5 层加工后的结果 H^5
  • 参数初始化不同:只要初始随机矩阵不同,后续训练轨迹就可能分化。
  • 训练过程中梯度不同:每个 head 对 loss 的贡献不同,更新方向也不同。

除了结构位置、初始化和梯度路径,attention head 的差异还会受到 mask、位置编码、head 维度、W^O 的混合方式、残差连接、LayerNorm、Dropout 以及训练数据分布影响。数据类型确实会影响最终学到的模式,比如代码语料多了以后,某些 head 可能对括号、缩进、变量引用更敏感;这些都是同一套参数在反复训练中自然形成的偏好,不是人工设定的。

W^Q 的优化

后面看公开模型配置时,会遇到 q_lora_rank 这个字段。它不是 Transformer 原论文里的标准概念,而是 DeepSeek、Kimi 这类模型在 Attention 投影里使用的低秩结构参数。

普通 Attention 里,Query 通常是一次线性投影:

Q = XW^Q

如果输入维度是 d_{model},所有 attention head 拼起来后的 Query 维度是 h \cdot d_q,那么:

W^Q \in \mathbb{R}^{d_{model} \times (h \cdot d_q)}

q_lora_rank 的实现不会直接用一个完整的大矩阵做 Query 投影,而是先压到一个较小的中间维度,再投影回所有 head 需要的 Query 维度:

C^Q = XW^{DQ}
Q = C^QW^{UQ}

其中:

W^{DQ} \in \mathbb{R}^{d_{model} \times r_q}
W^{UQ} \in \mathbb{R}^{r_q \times (h \cdot d_q)}

这里的 r_q 就是 q_lora_rank。也就是说,它是 Query 投影里的低秩瓶颈维度。

不同模型的 Attention 配置字段不完全一样。以后面表格里的 Kimi-K2.7-Code 为例,hidden_size = 7168q_lora_rank = 1536,64 个 attention head,每个 head 的 Query 维度按 qk_nope_head_dim + qk_rope_head_dim = 128 + 64 = 192 计算,所有 head 拼起来就是:

64 \times 192 = 12288

如果直接做完整 W^Q

7168 \times 12288 \approx 88.1M

如果拆成 q_lora_rank = 1536 的两段低秩投影:

7168 \times 1536 + 1536 \times 12288 \approx 29.9M

所以 q_lora_rank 的主要作用是减少 Query 投影的参数量和计算规模。

这里的 LoRA 容易和微调里的 LoRA adapter 混淆。常见 LoRA 微调是冻结原始矩阵,再额外训练一个低秩增量:

W’ = W + AB

而这些模型配置里的 q_lora_rank 更像是模型结构本身就把 Query 投影设计成低秩分解:

W^Q \approx W^{DQ}W^{UQ}

这两个矩阵从预训练开始就是模型参数的一部分,不是后面外挂上去的微调插件。

混合专家模型(MoE)

原始 Transformer 里,FFN/MLP 层是 dense 的:一个 Token 经过这一层时,会走这层的全部 FFN 参数。MoE 的想法是把 FFN/MLP 换成多组 Expert,再让 Router 为每个 Token 只选其中一小部分。

这个思路很符合直觉。写代码时不太需要心理学专家,做数学题时也不太需要一个擅长社交闲聊的专家;如果每个 Token 都让所有专家参与计算,参数容量是上去了,推理成本也会一起上去。于是就有了 混合专家模型(MoE)

混合专家模型(MoE) 通常是在 Transformer block 里,把 前馈神经网络(FFN/MLP) 从一套 dense MLP 换成多个 Expert。拿到输入 hidden state 后,Router 只会选中一个或几个 Expert 参与计算。

Router 层会根据输入 hidden state 给每个 Expert 打分,再按概率或 top-k 规则选取要激活的 Expert。

最简单的策略可以是只选分数最高的一个 Expert;选更多 Expert 会增加每个 Token 的计算容量,但也会增加推理成本和路由负载。

模型加载时通常仍要加载全部专家,所以内存/显存占用看的是总参数;但每次计算只激活子集,所以实际计算量会小得多。

MoE Router 也有自己的可训练参数,比如:

$$ s = hW^R + b^R \ p = \operatorname{softmax}(s) $$

其中:

  • h 是进入 MoE 层前的 hidden state;
  • W^R 是 Router 的权重矩阵;
  • s 是每个 Expert 的打分;
  • p 是每个 Expert 被选中的概率;
  • 然后取 top-k 个 Expert 参与计算。

专家数量是训练前先定好的,专家“负责什么”通常不是人工指定的,而是在训练过程中自己分化出来的。

混合专家模型(MoE) 还有个参数 moe_intermediate_size,可以理解为每个 MoE Expert 内部 FFN/MLP 的中间层维度。 如果模型用的是 SwiGLU 这类结构,单个 Expert 通常有三组矩阵:

  • gate_proj: d_{model} -> d_{moe}
  • up_proj: d_{model} -> d_{moe}
  • down_proj: d_{moe} -> d_{model}

所以单个 Expert 参数量粗略是:3 \times d_{model} \times d_{moe},也就是 3 \times hidden_size \times moe_intermediate_size

一般来说,在其它条件不变、训练数据和训练预算也足够的前提下,moe_intermediate_size 变大,单个 Expert 的表达能力会更好。 但它不是越大越好,收益会递减,也很容易被训练预算、推理成本和路由质量这些瓶颈卡住。

最后有一个经验可以先记住:总参数量更像模型容量的上限,单次任务效果还要看激活参数、路由质量、训练数据、后训练和解码策略。

大语言模型的参数量参考

一个 decoder-only Transformer 的参数量大致来自这几块:

  • 词表 Embedding:V \times d_{model}。如果输出层 lm_head 不和 Embedding 共享权重,再加一份 V \times d_{model}
  • Attention:普通 MHA 可以粗略看成每层 Q/K/V/O 四个投影,约 4d_{model}^2。现在很多模型用了 GQA、MLA、DSA、LoRA rank 等变体,实际要按配置和代码算,不能只套这个公式。
  • Dense FFN/MLP:如果是 SwiGLU,常见是 gate_proj、up_proj、down_proj 三个矩阵,约 3 \times d_{model} \times d_{ff}
  • MoE 专家层:每个专家通常也是一套 SwiGLU MLP,单专家约 3 \times d_{model} \times d_{moe}。总参数要乘以全部专家数;激活参数只乘以每个 token 实际选中的专家数,再加 shared expert 和 attention 等固定会走的参数。
  • 路由器、Norm、位置编码、MTP、视觉编码器等:通常不是最大头,但开放模型的官方总参数和自己按专家层粗算之间的差额,往往就在这些结构里。

所以 MoE 模型的“总参数”和“激活参数”不是一个概念。总参数是模型权重的完整规模;激活参数是处理单个 token 时实际走过的权重规模。下面的拆分只算权重数量,不算 KV cache、优化器状态,也不把量化后的存储大小混进来。

系列

当前公开口径

参数结构是否公开

备注

GPT

OpenAI 模型页当前推荐 GPT-5.5 用于复杂推理和编码 10

未公开

GPT-4 技术报告明确说没有继续披露 architecture、model size、hardware、training compute 等细节 11。我没有找到 GPT-5.5 的官方参数量、词表、维度、层数。

Claude

Anthropic 文档当前提到 Claude Fable 5、Claude Mythos 5,并建议复杂任务从 Claude Opus 4.8 起步 12

未公开

官方文档给的是模型能力、上下文、平台支持等产品信息,没有公开参数量、词表、维度、层数。

Gemini

Gemini API 模型页当前在 Gemini 3 家族里列出 Gemini 3.1 Pro、Gemini 3.5 Flash 等模型 13

未公开

官方 API 文档公开的是上下文、输入输出能力、稳定/预览状态,没有公开结构参数。

虽然官方没有给确切的参数文档,但是我们能从网上搜索别人的评测估算或者拿公开 MoE 模型做参照:DeepSeek-V4-Pro 是 1.6T / 49B activated,Kimi-K2.7-Code 是 1T / 32B activated,GLM-5 报告口径是 744B / 40B active。Google 早年的 GLaM 论文也公开过 1.2T 参数的稀疏激活 MoE 模型21。这些模型给了一个大致范围:前沿 MoE 的总参数可以上 T,单 token 激活参数通常是几十 B 到一两百 B 这个量级。

另外还有两条第三方/官方材料参考。第一,Klu 汇总 GPT-4 的公开研究和 SemiAnalysis 等资料,给过一个常被引用的拆法:GPT-4 约 1.8T 总参数,16 个专家,每个约 111B,top-2 激活,再加约 55B shared attention,单次推理约 280B 参数参与22。第二,Gemini 3 Pro 官方模型信息确认它是 sparse MoE Transformer,并明确说这种结构会把总模型容量和每 token 计算/服务成本拆开23。所以下面闭源模型那张表只能看量级作为参考。

系列

估算结构

总参数量级

单 token 激活量级

参数组成预估

GPT-5.5

以 GPT-4 的 1.8T / 约 280B active 传闻拆法为下界,再考虑两代后的推理/代码能力提升。更像稀疏 MoE + 路由/推理预算组合,而不是单个超大 dense 模型。

2T-5T

100B-300B

专家 MLP 约 85%-95%;attention、shared dense、router、Norm 等约 5%-15%;Embedding + lm_head 通常 1B-5B。多模态 encoder、工具/代码专用头可能另算。

Claude Fable 5 / Mythos 5

官方只说 Fable 是最强广泛发布模型、Mythos 是受限可用模型,二者 1M context、128k output、同价。按这个定位,5T 可以作为 MoE 总参数的高位估计。

2T-5T

80B-250B

如果总参数接近 5T,大概率是大量 routed experts 堆出来的 MoE 总量;真正每 token 激活的仍是 top-k 专家 + shared dense/attention。Embedding + lm_head 仍然大概率只是几 B。

Claude Opus 4.8

Opus 4.8 价格大约是 Fable/Mythos 的一半,官方定位也是 Opus-tier 而不是最高 Mythos/Fable tier。

1T-3T

50B-180B

比 Fable/Mythos 小一档更合理;如果是 MoE,专家 MLP 是大头;如果是 dense,总参数和激活参数会接近,但 5T dense 对延迟和成本都太重。

Gemini 3.1 Pro / 3.5 Flash

Gemini 3 Pro 官方确认 sparse MoE;1.5 Pro 报告也说 MoE 让总参数容量和单 token 成本解耦。Pro 和 Flash 很可能不是同一组激活规模。

Pro: 1T-3T;Flash: 0.2T-1T

Pro: 50B-150B;Flash: 10B-60B

专家 MLP 约 80%-95%;attention 和长上下文相关模块占剩余主要部分;视觉、音频、视频 encoder 可能是几亿到几十亿参数,并且不一定计入语言模型本体。

开源模型的参数计算就简单多了,可以直接拿 https://huggingface.co 上的模型信息和 config.json 来参考,其中 DeepSeek 和 Kimi 的总参数/激活参数来自模型信息;GLM-5.2 模型信息 18 链接到 GLM-5 技术报告,报告中给出同系 GLM-5 架构为 744B 总参数、40B 激活参数,GLM-5.2 的模型信息没有单独重复一张参数表。

模型

官方总量/激活量

词表

隐藏维度

层数

Attention

MoE 配置

上下文

DeepSeek-V4-Pro

1.6T / 49B activated 14

129,280 15

7,168

61

128 heads,1 KV head,q_lora_rank=1536

384 routed experts,6 selected/token,1 shared expert,moe_intermediate_size=3072

1,048,576

Kimi-K2.7-Code

1T / 32B activated,视觉编码器 400M 16

163,840(模型信息写 160K)17

7,168

61,其中 1 层 dense

64 heads,64 KV heads,q_lora_rank=1536

384 routed experts,8 selected/token,1 shared expert,moe_intermediate_size=2048

262,144

GLM-5.2

GLM-5 技术报告口径为 744B / 40B active 20

154,880 19

6,144

78,其中前 3 层 dense

64 heads,64 KV heads,q_lora_rank=2048,DSA/IndexShare

256 routed experts,8 selected/token,1 shared expert,moe_intermediate_size=2048

1,048,576

按上面的公式拆一下,会更容易理解这些数字为什么这么大。

模型

Embedding + lm_head

单专家参数

MoE 总专家参数粗算

每 token 激活的 MoE 专家参数粗算

说明

DeepSeek-V4-Pro

$2 \times 129280 \times 7168 \approx 1.85B$

$3 \times 7168 \times 3072 \approx 66.1M$

$61 \times (384 + 1) \times 66.1M \approx 1.55T$

$61 \times (6 + 1) \times 66.1M \approx 28.2B$

模型信息给 1.6T / 49B。差额主要来自 attention、路由器、Norm、HCA/CSA/MTP 等固定结构。

Kimi-K2.7-Code

$2 \times 163840 \times 7168 \approx 2.35B$

$3 \times 7168 \times 2048 \approx 44.0M$

$60 \times (384 + 1) \times 44.0M \approx 1.02T$

$60 \times (8 + 1) \times 44.0M \approx 23.8B$

模型信息写 1T / 32B,属于四舍五入后的公开口径;还有 1 层 dense MLP、attention 和 400M 视觉编码器。

GLM-5.2

$2 \times 154880 \times 6144 \approx 1.90B$

$3 \times 6144 \times 2048 \approx 37.7M$

$75 \times (256 + 1) \times 37.7M \approx 727.6B$

$75 \times (8 + 1) \times 37.7M \approx 25.5B$

GLM-5 报告给 744B / 40B;除专家层外,还有前 3 层 dense MLP、attention、DSA/IndexShare、MTP 等结构。

可以看到,现代 MoE 大模型的参数大头几乎都在专家 MLP 里,Embedding 反而只是十亿级。

最后

当前基本原理的入门就到这里了。如果真的要做相关业务,还得继续往训练、推理、并行、显存、数据和评测这些细节里钻,这就留到以后再说了。

我本人并非 AI 领域从业者,可能有理解不到位的地方,欢迎指正。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 卷积神经网络(CNN)
  • 循环神经网络(RNN)
  • Transformer
    • Positional Encoding
    • 注意力机制
    • 整个模型的注意力整合
    • 怎么训练 $W^Q$、$W^K$、$W^V$、$W^O$ ?
    • W^Q 的优化
    • 混合专家模型(MoE)
  • 大语言模型的参数量参考
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档