大模型数学速成(02):矩阵乘法——神经网络的基本变换
上一篇我们约定:列 = token,形状 [768, 1024] 表示 768 维特征 × 1024 个 token。接下来几乎所有 Transformer 层都在做同一件事——矩阵乘法:对每个 token 的特征向量做线性变换。
这一篇搞懂 $y = W \cdot x + b$ 在算什么、「握手规则」为什么必须成立,并用 3 维 × 2 token 的手算例子建立直觉。Q/K/V 三次投影留到下一篇。
这是「大模型数学速成」系列的第 2 篇。建议先读 第 01 篇:张量、维度与「列 = token」。下一篇讲 Q/K/V 投影——同一输入,三种角色。
一、一句话概括
矩阵乘法 = 对每个 token 的特征向量做一次线性变换(旋转 + 拉伸 + 平移),把信息从一个「语义空间」映射到另一个「语义空间」。
神经网络里一层线性层,本质上就是一次矩阵乘法加偏置;堆叠多层非线性激活,才形成复杂的表达能力。
二、生活类比:调咖啡
1 | 输入向量 x = [咖啡豆量, 水量, 奶量] ← 原始配方 |
- W:变换规则——每种原料如何组合成新属性的权重
- b:每台机器出厂就设好的「默认加料」
- x:当前这杯咖啡的配方(一个 token 的特征向量)
同一台「咖啡机」W 可以连续处理多杯不同配方(多个 token)——规则相同,输入不同,输出不同。
三、数学公式(单个 token)
对于输入向量 $\mathbf{x} \in \mathbb{R}^d$ 和权重矩阵 $\mathbf{W} \in \mathbb{R}^{m \times d}$:
$$
\mathbf{y} = \mathbf{W} \mathbf{x} + \mathbf{b}
$$
展开第 $i$ 个输出分量:
$$
y_i = \sum_{j=1}^{d} W_{ij} \cdot x_j + b_i
$$
直觉:输出的第 $i$ 个数 = 输入所有维度的加权求和 + 偏置。$W_{ij}$ 表示「输入第 $j$ 维对输出第 $i$ 维有多重要」。
整段序列时,把每个 token 的列向量分别乘同一个 W(见下文手算例子)。
四、握手规则:W 的列数 = x 的行数
两个矩阵能相乘,中间两个维度必须相同:
1 | W · x = y |
在本系列约定下(第 01 篇):
| 矩阵 | 形状示例 | 行 = ? | 列 = ? |
|---|---|---|---|
| 权重 W | [768, 768] |
输出特征维 | 输入特征维 |
| 输入 x | [768, 1024] |
输入特征维 | token 个数 |
| 输出 y | [768, 1024] |
输出特征维 | token 个数(通常不变) |
所以 W 的列数 = x 的行数——不是人为规定,而是矩阵乘法维度约束的必然结果。
五、手算例子:3 维 × 2 个 token
把 768 维缩小成 3 维,1024 个 token 缩小成 2 个,数字可以一眼看清。
权重 W(3 行 × 3 列):
1 | 输入特征→ |
输入 x(3 行 × 2 列,每列一个 token):
1 | token_0 token_1 |
计算 $y = W \cdot x$:
对 token_0 的列向量 $[1,2,3]^\top$:
$$
\begin{bmatrix} 5 \ 2 \ 6 \end{bmatrix} =
\begin{bmatrix} 2&0&1 \ 0&1&0 \ 1&1&1 \end{bmatrix}
\begin{bmatrix} 1 \ 2 \ 3 \end{bmatrix}
$$
对 token_1 的列向量 $[4,5,6]^\top$:
$$
\begin{bmatrix} 14 \ 5 \ 15 \end{bmatrix} =
\begin{bmatrix} 2&0&1 \ 0&1&0 \ 1&1&1 \end{bmatrix}
\begin{bmatrix} 4 \ 5 \ 6 \end{bmatrix}
$$
合并:
1 | token_0 token_1 |
三个关键观察:
- W 的列数(3)= x 的行数(3) → 才能对每个输入维度加权求和
- x 有几列,y 就有几列 → 2 个 token 进,2 个 token 出
- 各列独立、共用同一个 W → 并行化的基础
六、维度对不上会怎样?
1 | 错误示例: W 是 [768, 512],x 是 [768, 1024] |
就像咖啡机只设计了 512 种原料旋钮,配方却有 **768 种原料——接口对不上,框架直接报错。
常见踩坑:把 PyTorch 的 [batch, seq, hidden] 和 ggml 的 [hidden, seq] 搞混,导致 W 与 x 维度传反——先确认 第 01 篇 的约定再写公式。
七、并行计算与偏置 b
为什么「列 = token」利于并行?
矩阵乘法对每一列独立:
1 | y[:, 0] = W · x[:, 0] + b ← token_0 |
同一个 W、同一个 b,重复 N 次——GPU 上正好按列(或 batch 维)并行。Transformer Prefill 阶段一次处理整段 prompt,就是在做这种批量矩阵乘。
偏置 b 做什么?
$\mathbf{b} \in \mathbb{R}^{m}$ 是与输入无关的固定加量,形状为 [m, 1] 广播到每一列:
$$
y_{ij} = \sum_k W_{ik} x_{kj} + b_i
$$
类比:无论配方如何,咖啡机都会默认加「一勺糖」——W 负责按原料调配,b 负责整体平移。有些层(如部分 RMS Norm 路径)省略 b,但线性投影层通常保留。
八、Transformer 里矩阵乘法出现在哪?
典型 Encoder / Decoder 块中,矩阵乘是「主力运算」:
| 位置 | 权重形状(典型) | 输入 → 输出 | 作用 |
|---|---|---|---|
| Q/K/V 投影 | [768, 768] × 3 |
[768, S] → [768, S] |
同一特征变三种角色(下篇详讲) |
| 注意力输出投影 | [768, 768] |
[768, S] → [768, S] |
多头拼接后再线性变换 |
| FFN 升维 | [3072, 768] |
[768, S] → [3072, S] |
中间层变宽 |
| FFN 降维 | [768, 3072] |
[3072, S] → [768, S] |
压回原嵌入维 |
| 输出词表投影 | [vocab, 768] |
[768, S] → [vocab, S] |
logits,预测下一 token |
共同规律:列数 S(token 数)在方阵线性层中通常不变;变的是行数(特征维)——与 第 01 篇 的总结一致。
九、与训练 / 推理的关系
- 训练:反向传播对 W 求梯度,本质仍是矩阵运算;W 在训练中不断更新
- 推理:W 从 checkpoint 加载后固定;每次前向只是用当前激活 x 去乘 W
- 计算量:大模型推理 FLOPs 的大头来自这些
[768,768]、[768,3072]级别的矩阵乘——理解握手规则,是看性能分析文档的第一步
十、小结
| 问题 | 答案 |
|---|---|
| 线性层在算什么? | 对每个 token 列向量做 $W \cdot x + b$ |
| 握手规则? | W 的列数 = x 的行数(特征维) |
| token 数变吗? | 方阵层通常不变 |
| 为何能并行? | 各 token 列独立,共用 W 和 b |
| 下一步? | 同一 x 乘三套不同的 W → Q/K/V(第 03 篇) |
大模型数学速成系列第 2 篇完。下一篇我们讲 Q/K/V 投影——权重 $W_q, W_k, W_v$ 是什么、与激活 Q/K/V 有何区别。
系列导航
| 篇号 | 标题 | 状态 |
|---|---|---|
| 01 | 张量、维度与「列 = token」 | ✅ |
| 02 | 矩阵乘法:神经网络的基本变换(本篇) | ✅ |
| 03 | Q/K/V 投影:同一输入,三种角色 | 下一篇 |
完整大纲见工作区 docs/MATH_SERIES_OUTLINE.md。










