AI Infra 中的线性代数可以沿着一条连续的计算主线来理解:先看数据如何表示,再看不同 shape 的张量如何参与计算,最后理解这些运算怎样进入 Attention、模型压缩和数值稳定性分析。
1
2
3
4
5
6
7
8
9
10
11
12
13
数据装在哪里?
↓
不同 shape 的数据怎样计算?
↓
向量怎样比较大小和相似度?
↓
矩阵乘法怎样改变 shape?
↓
Attention 为什么是批量矩阵乘法?
↓
大矩阵为什么可以低秩压缩?
↓
SVD、LoRA 和特征值分别解决什么问题?
本文按照这条路线,重新整理 AI Infra 中最常用的线性代数基础。贯穿全文的例子统一采用:
$B=2,\qquad S=3,\qquad H=4$
也就是一次处理 2 条序列,每条序列有 3 个 token,每个 token 用一个 4 维隐藏向量表示。
1. 从数据容器开始:标量、向量、矩阵和张量
线性代数里的这些名字,本质上描述的是数据有多少个轴。
| 名称 | 示例 | shape | 直觉 |
|---|---|---|---|
| 标量 | 3.14 |
[] |
一个数字 |
| 向量 | [1, 2, 3, 4] |
[4] |
一排数字 |
| 矩阵 | 2 行 3 列 | [2,3] |
一张表 |
| 张量 | 多个矩阵继续堆叠 | [B,S,H] |
多轴数组 |
Transformer 的 hidden states 通常写作:
$X\in\mathbb{R}^{B\times S\times H}$
当 X.shape = [2,3,4] 时,它表达的是:
1
2
3
2 个 batch
每个 batch 有 3 个 token
每个 token 是一个 4 维向量
因此,一个具体 token 的隐藏表示可以写成:
$X_{b,s,:}\in\mathbb{R}^{H}$
这里的冒号表示取出该 token 在隐藏维上的全部分量。
理解高阶张量时,不需要试图在脑中画出四维、五维空间。更实用的方法是不断问:
固定前面的索引以后,最后还剩下一个什么对象?
对于 [B,S,H],固定 b 和 s 后,剩下的就是长度为 H 的 token 向量。
2. Shape、索引和 stride:逻辑结构与物理布局
shape 说明每个维度有多长,但它不一定说明数据在内存中怎样排列。stride 表示沿某个轴移动一步,需要跨过多少个底层元素。
在常见的连续布局 [B,S,H] 中,H 是最后一维,同一个 token 的隐藏分量通常连续存放。因此:
1
X[b, s, 0], X[b, s, 1], ..., X[b, s, H-1]
在内存中彼此相邻。
这件事对 AI Infra 很重要,因为同样的数学运算,如果访存模式不同,实际性能可能完全不同。transpose、permute 等操作有时只改变 shape 和 stride,并不立即搬运数据;但后续 Kernel 如果要求连续内存,就可能触发额外复制。
所以看一个张量时,需要区分两个问题:
1
2
逻辑上:每一维表示什么?
物理上:这些元素在内存中怎样排列?
3. 逐元素运算与广播:让 shape 对齐
逐元素运算表示相同位置的元素分别计算,例如:
$C_{i,j}=A_{i,j}+B_{i,j}$
当两个张量 shape 不完全相同时,框架可能使用广播。典型例子是给 hidden states 加 bias:
$X\in\mathbb{R}^{B\times S\times H},\qquad b\in\mathbb{R}^{H}$
为了理解广播,可以把 b 的 shape 对齐为:
$[H]\rightarrow[1,1,H]\rightarrow[B,S,H]$
这里的 1 表示“这个维度的长度是 1”,不是数据里的数值 1。
对于 B=2、S=3、H=4:
1
2
3
4
5
b.shape = [4]
↓ 前面补两个维度
[1,1,4]
↓ 沿 B 和 S 复用
[2,3,4]
同一个四维偏置向量会加到 6 个 token 位置上。广播发生在 B 和 S,H 中的四个分量并没有互相复制或混合。
广播一般是逻辑扩展,不一定真的预先复制出一个完整张量。但错误的 shape 也可能“恰好可以广播”,导致代码不报错、语义却错了。因此每次广播都应该明确:
- 哪些维度长度相等?
- 哪些维度长度为 1?
- 到底准备沿哪些维度复用?
4. 点积:相似度与加权求和
两个长度相同的向量可以做点积:
$x^\top y=\sum_{i=1}^{H}x_i y_i$
它有两种常用理解。
第一种是加权求和:用一个向量中的数字给另一个向量的各个分量分配权重,然后全部加起来。
第二种是方向匹配:
$x^\top y=\lVert x\rVert_2\lVert y\rVert_2\cos\theta$
点积越大,通常说明两个向量越同向;点积为负,通常说明方向相反。但点积同时受到方向和向量长度影响,因此只想比较方向时,需要归一化:
$\cos\theta=\dfrac{x^\top y}{\lVert x\rVert_2\lVert y\rVert_2}$
Attention 中用 Query 和 Key 的点积衡量匹配程度,Embedding 检索中也经常使用归一化后的点积。
5. 范数:把高维对象变成一个“规模”
范数可以理解为一把衡量“有多大”的尺子。常见向量范数包括:
$\lVert x\rVert_1=\sum_i|x_i|$
$\lVert x\rVert_2=\sqrt{\sum_i x_i^2}$
$\lVert x\rVert_\infty=\max_i|x_i|$
例如 x=[3,4]:
1
2
3
L1 范数 = 7
L2 范数 = 5
L∞ 范数 = 4
它们不是在争论哪个才是真正的长度,而是在关注不同的规模:总量、欧氏距离和最大分量。
5.1 什么叫沿 H 维归约?
对于:
$X\in\mathbb{R}^{B\times S\times H}$
沿隐藏维 H 求 L2 范数,表示对每个 token 的 H 个分量分别求长度:
$n_{b,s}=\sqrt{\sum_{h=1}^{H}X_{b,s,h}^2}$
原来每个 token 有 H 个数,归约后只剩一个数,因此:
$[B,S,H]\rightarrow[B,S]$
“沿某个维度归约”的含义就是:沿着那个轴把一组数字通过求和、平均、最大值或范数等操作合并成更少的数字。默认情况下,被归约的维度会消失;如果保留维度,则会变成长度为 1 的轴。
5.2 在模型中有什么用?
范数常用于:
- 观察参数、激活和梯度是否过大;
- 梯度裁剪;
- 向量归一化;
- 比较参考实现和优化 Kernel 的误差;
- 对权重施加正则化约束。
Transformer 中的 RMSNorm 也会沿 H 处理每个 token:
$\operatorname{RMS}(x)=\sqrt{\dfrac{1}{H}\sum_{i=1}^{H}x_i^2}$
它与 L2 范数关系密切,只是多了平均操作。目的不是丢掉 hidden states,而是用这个统计量把向量的数值规模控制在稳定范围内。
5.3 绝对误差与相对误差
比较浮点结果时,通常同时考虑:
$e_{abs}=|\hat{x}-x|,\qquad e_{rel}=\dfrac{|\hat{x}-x|}{|x|}$
当参考值接近 0 时,相对误差可能被无限放大,因此测试通常组合两种容差:
$|\hat{x}-x|\le\text{atol}+\text{rtol}\cdot|x|$
这对验证低精度计算、融合 Kernel 和算子优化是否正确非常重要。
6. 矩阵乘法:一组点积
设:
$A\in\mathbb{R}^{M\times K},\qquad B\in\mathbb{R}^{K\times N}$
那么:
$C=AB\in\mathbb{R}^{M\times N}$
shape 规则可以写成:
1
(M, K) @ (K, N) -> (M, N)
中间的 K 被归约,外侧的 M、N 保留下来。结果中的每一个元素,都是第一矩阵的一行和第二矩阵的一列做点积:
$C_{i,j}=\sum_{k=1}^{K}A_{i,k}B_{k,j}$
这就是为什么矩阵乘法不是逐元素相乘,也通常不能交换顺序。
6.1 转置为什么重要?
转置会交换矩阵的行和列:
$A\in\mathbb{R}^{M\times N}\quad\Rightarrow\quad A^T\in\mathbb{R}^{N\times M}$
Attention 中的 K 原本和 Q 一样,最后一维都是 D_h。为了让 D_h 成为矩阵乘法中间被归约的维度,需要把 K 的最后两维转置。
单位矩阵 I 表示“不改变向量”的变换,逆矩阵表示“撤销原来的变换”。不过在深度学习工程中,通常不会为了求解问题而显式计算巨大矩阵的逆,更常见的是使用数值稳定的分解或求解算法。
7. Batched Matrix Multiplication:Attention 的核心形状
多头 Attention 中:
$Q\in\mathbb{R}^{B\times N_h\times S_q\times D_h}$
$K\in\mathbb{R}^{B\times N_h\times S_k\times D_h}$
转置 K 的最后两维:
$K^\top\in\mathbb{R}^{B\times N_h\times D_h\times S_k}$
于是:
$QK^\top\in\mathbb{R}^{B\times N_h\times S_q\times S_k}$
这里真正执行矩阵乘法的是最后两维:
1
(S_q, D_h) @ (D_h, S_k) -> (S_q, S_k)
前面的 (B,N_h) 表示有多少组独立计算。换句话说,每一个 (batch, head) 都执行一次二维矩阵乘法,然后把所有结果堆叠起来。
例如:
1
2
3
4
5
B=2, Nh=4, Sq=3, Sk=5, Dh=8
Q : [2,4,3,8]
K^T : [2,4,8,5]
结果: [2,4,3,5]
总共有 2×4=8 组:
1
[3,8] @ [8,5] -> [3,5]
最终的 [S_q,S_k] 表示每个 Query token 对所有 Key token 的注意力分数。
多头注意力也不是把 token 分给不同 head。所有 head 都会看到全部 token;真正被拆分的是每个 token 的隐藏特征:
$H=N_hD_h$
8. 线性变换与仿射变换:神经网络的 Linear 层
严格的线性变换写作:
$y=Wx$
神经网络中的 Linear 层通常还包含 bias:
$y=Wx+b$
因为多了平移项 b,数学上更准确的名字是仿射变换。
从 shape 看,语言模型最后的词表投影可以写成:
$X\in\mathbb{R}^{(BS)\times H},\qquad W\in\mathbb{R}^{H\times V}$
$Y=XW\in\mathbb{R}^{(BS)\times V}$
它把每个 token 的 H 维 hidden state 投影成 V 个词表分数。矩阵乘法消掉 H,保留 token 数量 BS,并产生新的输出维度 V。
连续堆叠多个没有激活函数的线性层,最终仍然可以合并成一个线性或仿射变换。因此深层网络真正获得复杂表达能力,还依赖激活函数、Attention、归一化等非线性结构。
9. 线性相关与秩:矩阵里到底有多少独立信息?
如果一个向量可以由其他向量线性组合出来,它就没有提供新的独立方向。
矩阵的秩 rank 可以理解成:
这个矩阵里真正独立的方向有多少个。
对于:
$A\in\mathbb{R}^{M\times N}$
有:
$\operatorname{rank}(A)\le\min(M,N)$
如果一个很大的矩阵只有少量独立方向,就可以尝试用两个更小的矩阵近似:
$A\approx UV$
其中:
$U\in\mathbb{R}^{M\times r},\qquad V\in\mathbb{R}^{r\times N}$
只要 r 很小,参数量就会从 MN 降为:
$r(M+N)$
这就是低秩压缩和 LoRA 的数学起点。
10. SVD:找出矩阵最重要的方向
任意实矩阵都可以进行奇异值分解:
$A=U\Sigma V^\top$
这个公式更容易通过“一个向量怎样经过 A”来理解:
$Ax=U\bigl(\Sigma(V^\top x)\bigr)$
矩阵乘法从右向左执行:
1
2
3
4
5
x
↓ V^T:把输入改写到一组特殊方向上
↓ Σ :沿这些方向分别缩放
↓ U :把结果映射到输出方向
Ax
这里的“调整方向”不是为了多做两次无意义的旋转,而是因为矩阵最强、最弱的作用方向通常不是原坐标轴。V 找到输入空间中的重要方向,Σ 记录各方向的缩放倍数,U 给出这些方向在输出空间中的对应方向。
Σ 对角线上的数字叫奇异值:
$\sigma_1\ge\sigma_2\ge\cdots\ge0$
奇异值越大,说明矩阵沿对应方向的作用越强。如果后面的奇异值很小,就可以只保留前 r 个:
$A\approx U_r\Sigma_rV_r^\top$
这相当于保留矩阵最重要的 r 个方向,舍弃影响较弱的方向,从而得到低秩近似。
SVD 可以用于矩阵压缩、降噪和结构分析,但对巨大模型权重做完整 SVD 本身也很昂贵。工程中常用截断、随机化算法,或者直接训练低秩因子。
11. LoRA:直接训练低秩更新
LoRA 不直接修改完整预训练权重 W_0,而是冻结它,只训练一个低秩更新:
$W=W_0+\Delta W$
$\Delta W=\dfrac{\alpha}{r}BA$
其中:
$A\in\mathbb{R}^{r\times d_{in}},\qquad B\in\mathbb{R}^{d_{out}\times r}$
于是:
1
[d_out, r] @ [r, d_in] -> [d_out, d_in]
更新矩阵的最终 shape 与原权重一致,但可训练参数量从:
$d_{out}d_{in}$
变成:
$r(d_{out}+d_{in})$
LoRA 背后的假设是:模型适配新任务时,真正需要新增的更新方向可能远少于完整权重空间的维度。因此可以用较小的 r 表达主要变化。
12. 特征值与特征向量:放到最后理解
特征值并不是理解 Transformer shape 的前置条件,更适合在掌握矩阵变换以后,用来分析系统的长期行为。
对于方阵 A,如果存在非零向量 v 满足:
$Av=\lambda v$
那么:
v是特征向量,表示经过A后方向不变的特殊方向;λ是特征值,表示该方向被缩放了多少倍。
如果反复应用矩阵:
$A^k v=\lambda^k v$
那么:
1
2
3
4
|λ| > 1:这个方向不断放大
|λ| < 1:这个方向不断衰减
|λ| = 1:这个方向规模保持稳定
λ < 0 :缩放的同时发生方向翻转
这可以帮助理解动态系统稳定性、Hessian 的不同曲率方向,以及梯度经过多层 Jacobian 连乘后为什么可能爆炸或消失。
特征值主要针对方阵;神经网络中的权重矩阵经常是非方阵,所以分析一般矩阵时,奇异值往往更直接。
13. 把整条路线重新串起来
现在可以把 2.1—2.13 的内容重新组织为四层。
第一层是张量表示:
1
2
3
标量、向量、矩阵、张量
→ shape、索引、stride
→ 逐元素运算与广播
第二层是神经网络的基本计算:
1
2
3
4
5
点积与范数
→ 矩阵乘法与转置
→ Batched Matrix Multiplication
→ Attention
→ 线性层与输出投影
第三层是矩阵中的信息结构:
1
2
3
4
5
线性相关
→ 秩
→ SVD
→ 低秩近似
→ LoRA
第四层是数值和稳定性分析:
1
2
3
范数与误差
→ 激活/梯度规模
→ 特征值与系统稳定性
14. AI Infra 中读公式的统一方法
以后看到一个公式,可以固定问五个问题:
- 每个张量的 shape 是什么?
- 每一维在业务或模型中表示什么?
- 哪些维度被归约,哪些维度保留?
- 是否发生广播、转置、reshape 或数据复制?
- 计算量、访存量和浮点误差可能在哪里出现?
例如:
$Y=XW,\qquad X\in\mathbb{R}^{(BS)\times H},\qquad W\in\mathbb{R}^{H\times V}$
先不急着算数值,只看 shape:
1
(BS, H) @ (H, V) -> (BS, V)
马上就能读出:H 被归约,每个 token 得到 V 个词表分数;计算规模大约与 BSHV 成正比;输出 logits 的存储规模大约与 BSV 成正比。
对 AI Infra 来说,线性代数不只是为了推导公式。它同时决定了张量 shape、Kernel 选择、访存模式、计算量、显存占用和数值稳定性。真正值得掌握的不是孤立地背诵定义,而是能从公式一路读到实现。