系列回顾:上一篇我们把向量讲透了——它是深度学习里特征的基本表示单位,点积是衡量相似度的核心工具。这一篇我们来讲矩阵。矩阵是神经网络的"变换引擎",全连接层、注意力机制、MoE 路由,骨子里全是矩阵乘法。把这篇搞懂,你就能真正看明白 DeepSeek V3 里每一个 $W$ 矩阵在做什么。
如果向量是"一列数字",那矩阵就是"一张数字表格"。
但这个描述太平淡了,没有揭示矩阵的真正意义。
更好的理解是:矩阵是一台向量变换机器。 给它一个向量,它输出另一个(可能维度不同的)向量。神经网络每一层,本质上就是一个矩阵——接受上一层的向量输出,乘以权重矩阵,生成下一层的向量输入。
DeepSeek V3 里,注意力机制里的 $W_Q, W_K, W_V, W_O$ 是矩阵,前馈网络里的 $W_1, W_2$ 是矩阵,MLA 压缩和解压用的投影矩阵也是矩阵,连 token embedding 查找表也是矩阵。整个网络,从输入到输出,就是一系列矩阵乘法串联在一起。
理解矩阵,就是理解神经网络的骨架。
矩阵是一个按行列排列的二维数字数组。一个 $m$ 行 $n$ 列的矩阵写作:
$$A = \begin{pmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{pmatrix}$$
记为 $A \in \mathbb{R}^{m \times n}$,读作"$m$ 乘 $n$ 的矩阵"。
下标 $a_{ij}$ 表示第 $i$ 行第 $j$ 列的元素,规律是先行后列。
举个具体的例子,一个 $2 \times 3$ 的矩阵:
$$A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix}$$
这个矩阵有 2 行 3 列,共 6 个元素。$a_{12} = 2$(第 1 行第 2 列),$a_{23} = 6$(第 2 行第 3 列)。
方阵(Square Matrix):行数等于列数,$m = n$。很多重要的矩阵操作(如行列式、特征值)只对方阵定义。
单位矩阵(Identity Matrix) $I$:对角线全是 1,其余都是 0。
$$I_3 = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix}$$
单位矩阵是矩阵里的"1"——任何矩阵乘以单位矩阵,结果不变:$AI = IA = A$。
零矩阵(Zero Matrix) $O$:所有元素都是 0。
对角矩阵(Diagonal Matrix):只有对角线上有非零元素。
$$D = \begin{pmatrix} 3 & 0 & 0 \\ 0 & 7 & 0 \\ 0 & 0 & 2 \end{pmatrix}$$
对角矩阵做的事情是"各维度独立缩放"——不同维度乘以不同的比例系数,互不干扰。
两个形状相同的矩阵,对应位置的元素相加:
$$\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} + \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix} = \begin{pmatrix} 6 & 8 \\ 10 & 12 \end{pmatrix}$$
注意:形状不同的矩阵不能直接相加(维度不匹配)。但深度学习框架里有"广播(Broadcasting)"机制,允许在某些情况下自动扩展维度,这是工程上的便利,数学上需要小心理解。
矩阵乘以一个标量,每个元素都乘以这个数:
$$3 \times \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} = \begin{pmatrix} 3 & 6 \\ 9 & 12 \end{pmatrix}$$
这两个操作和向量的加法、标量乘法完全类似,不难理解。
矩阵 $A$ 的转置 $A^T$,就是把行和列互换——第 $i$ 行变成第 $i$ 列。
$$A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} \implies A^T = \begin{pmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{pmatrix}$$
原来是 $2 \times 3$,转置后变成 $3 \times 2$。
转置有几条常用性质:
$$(A^T)^T = A \quad \text{(转置两次回到原来)}$$
$$(AB)^T = B^T A^T \quad \text{(乘积的转置,顺序要反转!)}$$
$$(A + B)^T = A^T + B^T$$
第二条性质很重要,乘积转置时顺序必须反转,这在推导梯度公式时会反复用到(第5篇里矩阵乘法的梯度公式,用的就是这条性质)。
深度学习里,转置出现的最典型场景:
注意力机制里的 $QK^T$,就是把 Key 矩阵转置后和 Query 矩阵相乘,让每个 Query 向量和每个 Key 向量做点积。
矩阵乘法 $C = AB$,要求: - $A$ 的列数 = $B$ 的行数
如果 $A \in \mathbb{R}^{m \times k}$,$B \in \mathbb{R}^{k \times n}$,那么 $C \in \mathbb{R}^{m \times n}$。
结果矩阵 $C$ 的行数来自 $A$,列数来自 $B$,"中间的 $k$ 消掉了"。
这个规则是硬性要求,维度不匹配就没法相乘,PyTorch 里会直接报错。
$C$ 的第 $i$ 行第 $j$ 列元素,等于 $A$ 的第 $i$ 行和 $B$ 的第 $j$ 列做点积:
$$c_{ij} = \sum_{k=1}^{K} a_{ik} b_{kj} = a_{i1}b_{1j} + a_{i2}b_{2j} + \cdots + a_{iK}b_{Kj}$$
一个 $2 \times 2$ 的完整例子:
$$\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix}$$
计算 $c_{11}$:第1行 $(1, 2)$ 点积 第1列 $(5, 7)$:$1 \times 5 + 2 \times 7 = 19$
计算 $c_{12}$:第1行 $(1, 2)$ 点积 第2列 $(6, 8)$:$1 \times 6 + 2 \times 8 = 22$
计算 $c_{21}$:第2行 $(3, 4)$ 点积 第1列 $(5, 7)$:$3 \times 5 + 4 \times 7 = 43$
计算 $c_{22}$:第2行 $(3, 4)$ 点积 第2列 $(6, 8)$:$3 \times 6 + 4 \times 8 = 50$
$$\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix} = \begin{pmatrix} 19 & 22 \\ 43 & 50 \end{pmatrix}$$
矩阵乘法的本质:结果矩阵的每个元素,都是一行和一列的点积。
矩阵乘法最常见的用途是:矩阵乘以向量,把一个向量变换成另一个向量。
$$\vec{y} = W\vec{x}$$
$W \in \mathbb{R}^{m \times n}$,$\vec{x} \in \mathbb{R}^n$,结果 $\vec{y} \in \mathbb{R}^m$。
这就是神经网络全连接层在做的事情:权重矩阵 $W$ 把 $n$ 维输入向量变换成 $m$ 维输出向量。
举个具体例子,把 3 维向量变换成 2 维:
$$\begin{pmatrix} 1 & 0 & 2 \\ 3 & 1 & 0 \end{pmatrix} \begin{pmatrix} 1 \\ 2 \\ 3 \end{pmatrix} = \begin{pmatrix} 1 \times 1 + 0 \times 2 + 2 \times 3 \\ 3 \times 1 + 1 \times 2 + 0 \times 3 \end{pmatrix} = \begin{pmatrix} 7 \\ 5 \end{pmatrix}$$
矩阵乘法对向量做的是线性变换:旋转、缩放、拉伸、投影……
不同的矩阵代表不同的变换:
神经网络的权重矩阵是"学出来的变换"——通过训练,模型学会了什么样的线性变换能把输入特征转化成有用的表示。
结合律:$(AB)C = A(BC)$,顺序不能变,但可以先算任意一对
分配律:$A(B + C) = AB + AC$
不满足交换律:$AB \neq BA$(大多数情况下)
最后一条极其重要。矩阵乘法的顺序不能随意交换,这和普通数字乘法完全不同。深度学习代码里的维度错误,很多都是因为矩阵顺序搞反了。
现在把全连接层(也叫线性层、Dense 层)从头到尾写清楚。
输入向量 $\vec{x} \in \mathbb{R}^n$,权重矩阵 $W \in \mathbb{R}^{m \times n}$,偏置向量 $\vec{b} \in \mathbb{R}^m$:
$$\vec{z} = W\vec{x} + \vec{b}$$
输出 $\vec{z} \in \mathbb{R}^m$,维度从 $n$ 变成了 $m$。
这是最基础的全连接层操作,对应 PyTorch 里的 nn.Linear(n, m)。
nn.Linear(n, m)
实际训练时,不是一次处理一个样本,而是一批(batch)样本同时处理,提高 GPU 利用率。
把 $B$ 个样本堆成一个矩阵 $X \in \mathbb{R}^{B \times n}$(每行是一个样本):
$$Z = XW^T + \vec{b}$$
其中 $Z \in \mathbb{R}^{B \times n}$,$W^T$ 是权重矩阵的转置(因为样本是行向量,所以需要转置)。
注意:这里的 $+ \vec{b}$ 用了广播机制,偏置向量 $\vec{b} \in \mathbb{R}^m$ 自动复制了 $B$ 次,加到每个样本的输出上。
整个 batch 的计算,就是一次大矩阵乘法。 GPU 对大矩阵乘法有极其高效的并行实现,这是深度学习在 GPU 上跑得快的根本原因。
一个 $n \to m$ 的全连接层,参数量是:
$$\text{参数量} = m \times n + m = m(n + 1)$$
其中 $m \times n$ 是权重矩阵的参数,$m$ 是偏置的参数。
DeepSeek V3 里,注意力层的 $W_Q \in \mathbb{R}^{d_k \times d}$,$d = 7168$,$d_k = 128 \times 128 = 16384$,光这一个矩阵就有 $7168 \times 16384 \approx 1.17$ 亿参数。61 层,4 个注意力矩阵,就已经是几十亿参数了。这也是为什么大模型叫"大"模型——主要大在这些权重矩阵上。
注意力机制是 Transformer 的核心,我们在后面有专门的篇章详细讲,但现在用矩阵运算的视角预览一下,让你有整体感。
输入序列的隐藏状态矩阵 $H \in \mathbb{R}^{n \times d}$($n$ 个 token,每个 $d$ 维)经过三次线性变换,得到 Query、Key、Value 三个矩阵:
$$Q = H W_Q, \quad K = H W_K, \quad V = H W_V$$
其中 $W_Q, W_K, W_V \in \mathbb{R}^{d \times d_k}$ 是三个可学习的权重矩阵。
然后计算注意力输出:
$$\text{Attention}(Q, K, V) = \text{Softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$
拆开来看:
第一步 $QK^T$:$Q \in \mathbb{R}^{n \times d_k}$ 乘以 $K^T \in \mathbb{R}^{d_k \times n}$,结果是 $\mathbb{R}^{n \times n}$ 的注意力分数矩阵。这个矩阵的第 $i$ 行第 $j$ 列,就是第 $i$ 个 token 的 Query 和第 $j$ 个 token 的 Key 的点积——衡量"token $i$ 应该关注 token $j$ 多少"。
第二步 $\text{Softmax}(\cdot / \sqrt{d_k})$:对每一行做 Softmax,把注意力分数变成概率分布(每行加和为 1)。除以 $\sqrt{d_k}$ 是为了防止点积值太大导致 Softmax 梯度消失。
第三步 乘以 $V$:用注意力权重对 Value 做加权平均,$\in \mathbb{R}^{n \times d_k}$。
整个过程全是矩阵乘法,GPU 可以高效并行执行。
这是初学者最容易搞混的地方,我们仔细捋一下:
结果矩阵是 $n \times n$ 的,这就是著名的"注意力矩阵"。第 $i$ 行表示第 $i$ 个 token 对所有其他 token 的注意力权重。
这也是 Transformer 计算复杂度 $O(n^2)$ 的来源——序列越长,这个矩阵越大,计算量平方级增长。DeepSeek V3 用了多种技术(MLA、稀疏注意力等)来缓解这个问题。
除了矩阵乘法,深度学习里还有一种操作:逐元素乘法(Element-wise Multiplication),也叫 Hadamard 乘积,符号是 $\odot$。
$$\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} \odot \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix} = \begin{pmatrix} 1 \times 5 & 2 \times 6 \\ 3 \times 7 & 4 \times 8 \end{pmatrix} = \begin{pmatrix} 5 & 12 \\ 21 & 32 \end{pmatrix}$$
就是对应位置的元素分别相乘,形状不变(两个矩阵形状必须相同)。
逐元素乘法和矩阵乘法的区别:
DeepSeek V3 使用的 SwiGLU 激活函数里,就有逐元素乘法:
$$\text{SwiGLU}(x, W, V) = \text{SiLU}(xW) \odot (xV)$$
两个线性变换的结果,逐元素相乘,产生门控效果——一个分支控制另一个分支"开多大门"。
对于方阵 $A$,如果存在矩阵 $A^{-1}$ 使得:
$$AA^{-1} = A^{-1}A = I$$
就说 $A^{-1}$ 是 $A$ 的逆矩阵。
类比:数字 $3$ 的"逆"是 $\frac{1}{3}$,因为 $3 \times \frac{1}{3} = 1$。矩阵的逆就是矩阵版的"倒数"。
不是所有方阵都有逆矩阵。如果矩阵的某几行(或列)线性相关(互相可以由其他行/列表示),矩阵就是奇异矩阵(Singular Matrix),不可逆。
逆矩阵在深度学习的日常计算里不直接出现——求逆的计算代价高($O(n^3)$),而且大多数情况下可以用其他方式绕过。
但在理解深度学习的理论时会出现,比如: - 最小二乘法的解析解:$\theta = (X^TX)^{-1}X^Ty$(但实际工程里用梯度下降代替) - 理解为什么某些初始化方式更好:权重矩阵接近奇异时,梯度传播会出问题
矩阵乘法 $C = AB$,其中 $A \in \mathbb{R}^{m \times k}$,$B \in \mathbb{R}^{k \times n}$,需要 $m \times k \times n$ 次乘法和 $m \times (k-1) \times n$ 次加法,总计算量大约是 $O(mkn)$。
对于 DeepSeek V3 的一个全连接层,$m = k = n = 7168$,计算量是 $7168^3 \approx 3.68 \times 10^{11}$,也就是大约 3680 亿次浮点运算——仅仅是一层的一次前向传播。
CPU 做不了这件事。
现代 GPU(比如 H800)有数千个计算核心,可以把大矩阵切成小块,数千块同时计算,利用并行性把时间压缩到毫秒级。
更深一层:GPU 里有专门的矩阵乘法加速单元,叫做 Tensor Core,针对特定数据类型(如 FP16/BF16)的矩阵乘法做了硬件级别的优化,效率比通用计算核心高一个数量级。
这就是为什么深度学习爆发的时机,和 GPU 算力爆发的时机完全吻合——矩阵乘法是核心计算瓶颈,GPU 恰好是做这件事最快的硬件。
DeepSeek V3 训练用了 2048 块 H800 GPU,里面大量时间都在做矩阵乘法。
现在把 DeepSeek V3 里出现的主要矩阵汇总一下,让你对整体有感性认识:
DeepSeek V3 用了 MLA(Multi-head Latent Attention),和标准 Transformer 的矩阵略有不同:
MLA 的思路是:与其把完整的 K 和 V 矩阵缓存起来,不如只缓存压缩后的低维表示(512 维),推理时再用解压矩阵还原。这让 KV Cache 的大小从原来的 $n \times 7168 \times 2$(每层)缩减到 $n \times 512$,节省了大量显存。
DeepSeek V3 的前馈网络用了 MoE(混合专家)结构,有 256 个专家,每次只激活少数几个:
每个专家本质上是两个矩阵:
另外还有共享专家,维度更大。加上门控网络的路由矩阵,整个 FFN 部分有大量矩阵参数。
这些矩阵大多数时候是"稀疏激活"的——256 个专家里,每次只激活 8 个,其余的矩阵不参与这个 token 的计算。这是 MoE 节省计算量的核心设计。
这篇文章把矩阵运算从基础到应用完整过了一遍。
第一,矩阵是向量变换的工具,$m \times n$ 的矩阵把 $n$ 维向量变换成 $m$ 维向量。神经网络的每一层,本质上就是一个带偏置的矩阵乘法加激活函数。
第二,矩阵乘法的规则:前矩阵列数必须等于后矩阵行数,结果矩阵每个元素是对应行列的点积。乘法不满足交换律,顺序极其重要。
第三,批量处理时,把所有样本堆成矩阵,一次大矩阵乘法搞定整个 batch。这是 GPU 加速深度学习的根本操作。
第四,注意力机制就是三个矩阵乘法:$HW_Q$、$HW_K$、$HW_V$ 生成 Q、K、V,然后 $QK^T$ 计算注意力分数,最后乘以 $V$ 得到输出。$QK^T$ 是 $n \times n$ 的矩阵,这是 Transformer 计算复杂度 $O(n^2)$ 的来源。
第五,逐元素乘法($\odot$)和矩阵乘法是两种完全不同的操作,形状要求和几何意义都不同。DeepSeek V3 的 SwiGLU 激活函数里用到了逐元素乘法。
第六,DeepSeek V3 的 MLA 通过低维压缩矩阵,把 KV Cache 从 7168 维压缩到 512 维,大幅节省推理时的显存占用——这是矩阵低秩分解思想的工程应用。
下一篇预告:
第8篇,我们讲点积与相似度,深入解析注意力机制的核心操作。
向量的点积我们已经讲过了,但注意力机制里的点积有一些特别的设计考量:为什么除以 $\sqrt{d_k}$?Softmax 之后的归一化有什么作用?多头注意力为什么要分头?这些问题,下一篇一一解答。
矩阵是神经网络的骨架,矩阵乘法是深度学习的心跳。GPU 加速的本质,就是让这颗心跳得更快。
还没有评论,来抢沙发吧!
博客管理员
40 篇文章
还没有评论,来抢沙发吧!