大模型的核心,竟然只是矩阵乘法?
大模型的核心,竟然只是矩阵乘法?
今天我们经常听到这些词:
大模型、Transformer、Attention、GPU、CUDA、算力、训练、推理。
听起来都很高深。
但如果把这些概念一层一层拆开,你会发现一个很有意思的事实:
现代 AI 的核心计算,大量都是矩阵运算。
尤其是大语言模型 LLM,不管是前向推理,还是训练时的反向传播,本质上都离不开矩阵乘法。
而 GPU 之所以能成为 AI 时代的核心硬件,也是因为它特别擅长做大规模并行矩阵计算。

一、文本进入模型后,先变成矩阵
神经网络不能直接理解文字。
比如一句话:
我 爱 人工智能
进入模型后,每个 token 会先被转换成一个向量。
可以简单理解成:
我 → [0.2, 0.7, -0.1, ...]
爱 → [0.5, 0.1, 0.8, ...]
人工智能 → [0.9, 0.3, 0.6, ...]
一个 token 是一个向量。
多个 token 的向量堆叠在一起,就变成了一个矩阵。
例如:
X = [seq_len, hidden_dim]
如果一句话有 4 个 token,每个 token 用 768 维向量表示,那么:
X = [4, 768]
从这一刻开始,模型后面的计算几乎都围绕这个矩阵展开。

二、Linear 层就是矩阵乘法
神经网络里最常见的结构叫 Linear 层,也叫全连接层。
它的计算公式是:
Y = XW + b
其中:
X:输入矩阵
W:权重矩阵
b:偏置
Y:输出矩阵
比如:
X: [4, 768]
W: [768, 3072]
Y: [4, 3072]
这一步其实就是一次矩阵乘法。
输入矩阵 X 乘上权重矩阵 W,得到新的输出矩阵 Y。
大模型里有大量 Linear 层,所以大模型天然就是矩阵乘法密集型程序。

三、Attention 拆开后,也是矩阵运算
Transformer 最核心的模块是 Attention。
很多人觉得 Attention 很神秘,但它拆开以后,其实也是一组矩阵运算。
首先,输入矩阵 X 会分别乘上三个权重矩阵:
Q = XWq
K = XWk
V = XWv
也就是得到 Query、Key、Value 三个矩阵。
然后计算注意力分数:
Score = QKᵀ
这又是一次矩阵乘法。
接着经过 softmax 得到注意力权重:
Attention = softmax(Score)
最后再乘上 V:
Output = Attention × V
所以 Attention 的核心路径可以概括为:
X
↓
Q = XWq
K = XWk
V = XWv
↓
Score = QKᵀ
↓
softmax
↓
Output = Attention × V
看起来复杂,其实核心就是:
矩阵乘法 + softmax + 矩阵乘法
其中最耗算力的部分,仍然是矩阵乘法。

四、MLP / FFN 也是矩阵乘法
Transformer Block 里除了 Attention,还有一个非常重要的模块:MLP,也叫 FFN。
典型结构是:
Y = Linear2(Activation(Linear1(X)))
展开以后就是:
H = XW1 + b1
H = activation(H)
Y = HW2 + b2
比如 hidden_dim 是 4096,中间层扩展到 11008:
X: [seq_len, 4096]
W1: [4096, 11008]
H: [seq_len, 11008]
W2: [11008, 4096]
Y: [seq_len, 4096]
也就是说,MLP 的主要计算是两次大矩阵乘法:
第一次:升维
第二次:降维
所以一个 Transformer Block 里:
Attention:矩阵乘法
MLP:矩阵乘法
输出投影:矩阵乘法
再加上几十层、上百层堆叠之后,大模型的计算量就非常可观了。

五、推理是矩阵运算,训练也是矩阵运算
前面讲的是模型前向传播。
也就是输入一个问题,模型输出答案。
但训练模型时,还需要反向传播。
很多人以为反向传播是另一套完全不同的东西,其实它的核心也离不开矩阵运算。
以最简单的 Linear 层为例:
Y = XW
假设损失函数对输出 Y 的梯度是:
dY
那么权重 W 的梯度是:
dW = XᵀdY
输入 X 的梯度是:
dX = dYWᵀ
你会发现:
dW = XᵀdY
dX = dYWᵀ
这两个仍然是矩阵乘法。
所以训练过程可以理解为:
前向传播:大量矩阵乘法
反向传播:大量矩阵乘法
参数更新:根据梯度更新矩阵
这就是为什么训练大模型需要极高算力。
因为训练不是只算一遍前向传播,而是还要计算大量梯度。

六、GPU 为什么特别适合 AI?
CPU 很强,但它更像一个“少量核心、每个核心很聪明”的处理器。
它擅长:
复杂逻辑
分支判断
任务调度
操作系统
数据库
业务程序
比如 CPU 里有很多硬件机制:
分支预测
乱序执行
复杂缓存
高单核性能
这些能力让 CPU 很适合处理复杂控制逻辑。
GPU 则不同。
GPU 更像一个“大量计算单元组成的并行工厂”。
它不擅长复杂分支,但特别擅长大量相似计算。
矩阵乘法刚好非常适合 GPU。
比如计算:
C = A × B
矩阵 C 里的每一个元素都可以相对独立地计算:
C[i][j] = A 的第 i 行 · B 的第 j 列
也就是:
C[i][j] = A[i][0]B[0][j]
+ A[i][1]B[1][j]
+ A[i][2]B[2][j]
+ ...
矩阵 C 有成千上万个元素,每个元素都可以分配给不同线程去算。
所以 GPU 的优势不是一个人算完整张表,而是一群线程同时算很多格子。

七、CUDA 怎么组织 GPU 并行?
在 CUDA 里,程序不是直接说“让 GPU 帮我算”。
它会把任务切成很多层:
Grid
├── Block
│ ├── Thread
│ ├── Thread
│ └── ...
├── Block
└── ...
一个 CUDA kernel 启动时,通常会写成:
kernel<<<blocks, threads>>>();
比如:
vectorAdd<<<4, 256>>>();
意思是:
启动 4 个 block
每个 block 有 256 个 thread
而 GPU 硬件里真正执行计算的是 SM,也就是 Streaming Multiprocessor。
可以简单理解成:
GPU = 很多个 SM
SM = 一个小型计算工厂
CUDA block 会被调度到 SM 上执行。
一个 block 不会跨多个 SM。
但一个 SM 可以同时驻留多个 block,并在这些 block 的 warp 之间切换执行。
这里还有一个重要概念:warp。
1 warp = 32 个线程
GPU 实际调度时,不是一个线程一个线程调度,而是按 warp 调度。
所以可以这样理解:
Block 被分配到 SM
Block 里的 Thread 被分成 Warp
SM 实际调度 Warp 执行

八、最直接的矩阵乘法为什么不够快?
最直接的矩阵乘法代码是这样的:
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < K; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
这个写法很直观。
但在 GPU 上,真正的问题不只是“要算多少次乘加”。
还有一个更重要的问题:
数据从哪里来?
数据要搬多少次?
数据能不能被复用?
GPU 上的 global memory,也就是显存,容量很大,但访问速度相对慢。
而 SM 内部的 shared memory 很快,但容量很小。

如果每个线程都反复从 global memory 读取 A 和 B 的元素,性能会被内存访问拖慢。
所以 CUDA 优化矩阵乘法时,经常会使用一个核心技巧:
Tile 分块计算
九、什么是 Tile 分块?
假设要计算:
C = A × B
我们不一次性处理整个大矩阵,而是把矩阵切成很多小块。
比如把 C 切成 16×16 的小块:
C tile = 16 × 16
每个 CUDA block 负责计算 C 的一个小块。
为了算出这个 C tile,需要从 A 中取一块,从 B 中取一块:
A tile × B tile → 累加到 C tile
如果 K 维很长,就沿着 K 方向一块一块推进:
第 1 轮:A_tile_0 × B_tile_0
第 2 轮:A_tile_1 × B_tile_1
第 3 轮:A_tile_2 × B_tile_2
...
最后累加得到 C tile。
所以 Tile 优化的核心思想是:
先把 A、B 的小块搬到 shared memory,
然后 block 内的线程反复复用这些数据,
从而减少对 global memory 的访问。

十、一个 4×4 的直观例子
假设:
A: 4 × 4
B: 4 × 4
C: 4 × 4
我们把 tile 大小设成 2×2。
那么 C 会被分成 4 个小块:
C00 C01
C10 C11
其中 C00 是左上角的 2×2 小矩阵。
为了计算 C00,需要:
A 的前 2 行
B 的前 2 列
但矩阵乘法还要沿着 K 方向累加。
所以 C00 的计算过程是:
第一轮:
A00 × B00
第二轮:
A01 × B10
两轮结果累加,得到:
C00 = A00 × B00 + A01 × B10
同理:
C01 = A00 × B01 + A01 × B11
C10 = A10 × B00 + A11 × B10
C11 = A10 × B01 + A11 × B11
也就是说:
不是 A 的一个 tile 只和 B 的一个 tile 相乘,
而是 A 沿 K 方向的多个 tile,
要依次和 B 对应位置的多个 tile 相乘,
最后把结果累加起来。

十一、为什么 Tile 能提升性能?
Tile 优化的核心不是减少数学计算量。
矩阵乘法该做多少乘加,还是要做多少乘加。
它真正优化的是:
减少慢速内存访问
提高数据复用率
让更多线程并行工作
比如 A 的一个 tile 被加载到 shared memory 后,block 内多个线程都会反复使用它。
B 的 tile 也是一样。
这样就避免了每个线程都重复从 global memory 读取同样的数据。
可以把它理解成:
global memory:仓库,很大但取货慢
shared memory:车间缓存,很小但取货快
register:手里正在用的工具,最快但最小
Tile 优化就是:
先把常用材料从仓库搬到车间,
大家在车间里反复使用,
不用每算一步都跑回仓库。
这就是 GPU 优化里非常重要的思想:
数学公式没有变,
但计算组织方式变了。

十二、从 Tile 到 FlashAttention
回到大模型。
大模型中的 Attention、MLP、Embedding 投影、输出投影,背后都有大量矩阵乘法。
训练时的梯度计算,同样是大量矩阵乘法。
所以大模型的性能,很大程度取决于:
矩阵乘法算得够不够快
显存访问够不够高效
并行度够不够高
GPU 利用率够不够满
CUDA、cuBLAS、Tensor Core、FlashAttention、PagedAttention 等优化,本质上都在围绕这些问题展开。
比如 FlashAttention 不是改变 Attention 的数学公式。
Attention 还是:
softmax(QKᵀ)V
但普通 Attention 可能会把完整的 QKᵀ 注意力矩阵写到显存里,再读出来做 softmax,再写回,再读出来乘 V。
这样会产生大量 HBM 显存读写。
FlashAttention 的核心思路是:
把 Q、K、V 分块
在 SRAM / shared memory 中局部计算
一边做 softmax
一边乘 V
尽量不保存完整的 N×N 注意力矩阵
也就是说:
数学公式没有变,
但数据搬运路径变了。
这和 Tile 矩阵乘法的思想非常像。

十三、总结
现代 AI 模型看起来非常复杂。
但从计算角度看,它的核心可以总结为一句话:
大模型 = 海量参数矩阵 + 大规模矩阵运算 + GPU 并行优化
LLM 前向传播时:
Attention 是矩阵运算
MLP 是矩阵运算
Linear 投影是矩阵运算
训练反向传播时:
梯度计算还是矩阵运算
参数更新也是围绕矩阵进行
而 GPU / CUDA 的作用,就是把这些矩阵运算切分成大量小任务,让成千上万个线程一起并行计算。
所以理解大模型计算,矩阵乘法是第一步。
理解 GPU 加速,Tile 分块是第一步。
如果你再继续往下看,就会发现:
Tensor Core 是为了更快地算矩阵乘法;
cuBLAS 是高度优化的矩阵乘法库;
FlashAttention 是 Attention 里的分块计算优化;
PagedAttention 是 KV Cache 管理上的内存优化。
很多看似高级的 AI 系统优化,背后其实都绕不开同一个问题:
怎么算得更快?
怎么少搬数据?
怎么把 GPU 喂饱?
大模型看起来像是在“理解语言”。
但从硬件视角看,它其实是在一层又一层地做矩阵乘法。
智能的表象背后,是海量矩阵、海量数据搬运,以及 GPU 上成千上万个线程的并行计算。
当你真正理解了矩阵乘法,你就已经摸到了现代 AI 计算的地基。
当你真正理解了 Tile 分块,你就已经拿到了理解 GPU 加速的第一把钥匙。