音乐
暂未播放
数值线性代数(一):高斯消元、LU 分解与「不要显式求逆」

背景:浮点文章的下一个问题#
上一篇《浮点数与数值稳定性》回答了”误差从哪里来”:表示误差、舍入误差、消去误差,以及一个统一框架——条件数 κ 衡量”输入误差会被放大多少倍”。那篇文章里条件数只出现了一页半:定义了 κ=σmax/σmin,给了误差放大不等式,然后就收尾了。
但”误差会被放大”只是故事的一半。给定一个方程组 Ax=b,我们实际用什么算法去解?这个问题在你看论文、写 kernel 时躲不掉:
- GPU 上解线性方程组:cuSOLVER 提供
getrf/getrs/potrf一整套例程,它们是 LAPACK 的 GPU 移植——为什么接口是”分解+求解”两步,而不是一个”求逆”函数一步到位? - 部署管线里的矩阵运算:MLA 的矩阵吸收是把小矩阵乘进去而不是求逆;LoRA 权重合并是加法;量化反量化是逐元素对角操作——这些操作全是”良态”的,而”求逆”被刻意回避了。
- 数值线性代数本身:高斯消元为什么必须换主元?为什么对称正定矩阵有专属分解?为什么最小二乘要用 QR 而不用正规方程?
这一篇是”数值线性代数”系列的第一篇,专注回答:如何稳定、高效地求解 Ax=b。规划如下:
- (一)本篇:范数与条件数补全 → 高斯消元与主元策略 → LU 分解 → 分解谱系(Cholesky / QR / SVD)→ “不要显式求逆”的数值哲学;
- (二):QR 分解、Householder 变换与最小二乘问题;
- (三):迭代法——共轭梯度与大规模稀疏系统,条件数如何决定迭代次数。
下面从最能冲击直觉的现象开始。
一个反直觉的现象:Hilbert 矩阵#
考虑 n×n 的 Hilbert 矩阵,第 i 行第 j 列的元素是
Hij=i+j−11,i,j=1,2,…,n它的性质好得过分:对称、所有元素为正、且是对称正定矩阵(对任意非零向量 x 都有 xTHx>0,因为它来自内积 ∫01p(t)q(t)dt 的 Gram 矩阵)。按常识,这样的矩阵应该非常好解。
现在取 n=31,构造右端项 b=H⋅1(即 1=(1,1,…,1)T 是精确解),然后让一个”普通求解器”用浮点算术去解。结果如下:

图里蓝线是理想解 xi=1,红线是求解器算出来的解——锯齿状、来回震荡、幅度巨大。图源是 MathWorks 官方博客 Cleve’s Corner 上 Rondall Jones 的客座文章 ARLS, Automatically Regularized Least Squares,原文特意注明”这张图已经算温和了:震荡幅度经常以百万计,而不是比真解大一点”。这个例子里红色震荡的规模是 106 量级——一个元素全为正数、对称正定、看起来人畜无害的方程组,解出来却完全不能用。
求解器错了吗?没有。是问题本身病态:Hilbert 矩阵的条件数随 n 指数爆炸,κ(Hn) 大致按 e3.5n 增长。n=31 时条件数在 1040 量级,而双精度机器精度 ϵ≈2.2×10−16,于是 κ⋅ϵ≈1024——误差放大的倍数远远盖过浮点能提供的精度,任何算法、任何机器都解不出有用的结果。这个例子说明”问题病态”和”算法不稳”是两件独立的事,这正是本篇要反复使用的框架。
要理解这图,先补两样东西:度量误差的尺子(范数),以及误差被放大的倍数(条件数)。
范数:给向量和矩阵一把”尺子”#
“解的误差是 10−3“——这句话需要一个度量长度的方法。你其实早就会用范数,只是不知道这个词:向量的欧氏长度、余弦相似度公式里的分母,都是范数。数值线性代数里我们需要向量范数和矩阵范数两把尺子。
向量范数:从 L2 到 Lp#
你已经掌握的欧氏长度就是 L2 范数:
∥x∥2=i∑xi2=⟨x,x⟩其中 ⟨x,y⟩=∑ixiyi 是内积,余弦相似度 cosθ=⟨x,y⟩/(∥x∥2∥y∥2) 用的就是它。一般地,Lp 范数定义为
∥x∥p=(i∑∣xi∣p)1/p常用的是三个特例:
- p=1:L1 范数 ∥x∥1=∑i∣xi∣,曼哈顿距离;
- p=2:L2 范数,欧氏距离,由内积诱导;
- p→∞:L∞ 范数 ∥x∥∞=maxi∣xi∣,最大分量。
一个函数要被称为”范数”,必须满足三条公理:非负(∥x∥≥0,等号当且仅当 x=0)、齐次(∥cx∥=∣c∣∥x∥)、三角不等式(∥x+y∥≤∥x∥+∥y∥)。直觉上,范数就是”从原点量到 x 的距离”。选择哪种范数取决于场景:稀疏向量常用 L1(压缩感知里是凸松弛),L2 在数值线性代数里最常用,原因是它是酉不变(unitary invariant)的:对任意正交矩阵 Q(旋转/反射),∥Qx∥2=∥x∥2——旋转不改变长度,这使 L2 范数与矩阵分析配合得最干净。你之后会看到,正交矩阵不放大误差这件事,在 RoPE 那里还会再出现一次。
矩阵范数:单位球被拉伸的最长半径#
向量范数只能量”解”的长度,但误差分析里的放大倍数 κ 属于矩阵。定义矩阵的诱导范数(也叫算子范数)为
∥A∥=x=0max∥x∥∥Ax∥=∥x∥=1max∥Ax∥直观解释:把所有单位长度的向量 x 扔进 A,看输出最长能有多长,这个”最大拉伸倍数”就是 ∥A∥。其中由 L2 范数诱导出的 ∥A∥2 叫谱范数,它有一个非常漂亮的身份:
∥A∥2=σmax(A)即 A 的最大奇异值。为什么?因为 ∥Ax∥22=xTATAx,而 ATA 是对称半正定矩阵,其特征值就是奇异值的平方 σi2;在特征向量方向上 xTATAx 取到最大,开根号就是 σmax。
另一种常用矩阵范数是 Frobenius 范数,把矩阵当长向量:
∥A∥F=i,j∑aij2=i∑σi2注意它和谱范数的区别:Frobenius 范数等于奇异值平方和的平方根,谱范数等于最大奇异值——前者是”整体大小”,后者是”最强拉伸方向”。直觉上,∥A∥F 像矩阵的”总能量”,∥A∥2 像矩阵的”最大杠杆”。
铺垫:矩阵 = 线性变换的几何#
范数的几何解读依赖一个视角,这也是你数学档案里缺的一块:矩阵就是线性变换。A 把一个向量”送到”另一个向量,几何效果只有五种基本形态的组合:拉伸、压缩、旋转、反射、剪切。下图把同一张带方向箭头的方块在 5 种矩阵作用下的样子画了出来(图源:Greg Gundersen 的博客文章 The Singular Value Decomposition (SVD) 的 Figure 2):

从左到右五种变换分别对应:对角元 >1 的对角矩阵(拉伸)、对角元 <1 的对角矩阵(压缩)、正交矩阵(旋转)、带 −1 特征值的正交矩阵(反射)、非对称的三角矩阵(剪切)。后面讲条件数、特征值、RoPE 旋转矩阵时,这套几何语言会反复用到。奇异值分解 A=UΣVT 的几何含义就是:先旋转(VT)、再沿坐标轴拉伸(Σ)、最后再旋转(U)——任何线性变换都只是”转一下、拉一下、再转一下”。拉伸的倍数正是奇异值 σ1≥σ2≥⋯≥σn。
条件数:误差放大倍数的完整推导#
有了范数这把尺子,现在把上一篇只给出结论的误差放大不等式完整推导一遍。
设 A 可逆,Ax=b 的精确解为 x。现在右端项 b 受到扰动 δb(例如测量误差、或者 b 本身是浮点数),新方程组为
A(x+δx)=b+δb两边相减得 Aδx=δb,即 δx=A−1δb。两边取范数:
∥δx∥≤∥A−1∥⋅∥δb∥同时由 b=Ax 得 ∥b∥≤∥A∥⋅∥x∥,即 1/∥x∥≤∥A∥/∥b∥。两个不等式相乘,把 ∥δx∥/∥x∥ 凑出来:
∥x∥∥δx∥≤∥A∥⋅∥A−1∥⋅∥b∥∥δb∥这就是条件数不等式:左边是解的相对误差,右边是输入的相对误差乘以放大倍数。放大倍数记为
κ(A)=∥A∥⋅∥A−1∥在谱范数下,∥A∥2=σmax,∥A−1∥2=1/σmin(A−1 的奇异值就是 A 奇异值的倒数),所以
κ2(A)=σminσmax最大奇异值与最小奇异值之比。上一篇文章里你见过这个式子,现在它的每个成分都有了意义:σmax 是”最强的拉伸”,σmin 是”最弱的拉伸”,两者之比衡量这个矩阵把空间扭曲得多”扁”。
几何直觉:圆变成椭圆#
条件数的几何意义一张图就够。下图(图源同上,Greg Gundersen 的 SVD 文章 Figure 5)左边是单位圆,右边是这个圆被某个矩阵 A 映射后的像:

单位圆上的所有向量 ∥x∥=1 被 A 送到一个椭圆上,椭圆的两个半轴长度恰好是 σmax 和 σmin,方向是左奇异向量 u1,u2。理由很直接:x 沿右奇异向量 v1 时,Ax=σ1u1,长度就是 σ1。于是:
- 良态矩阵(κ≈1):椭圆接近圆,所有方向的拉伸差不多,误差无论从哪个方向进来都不被放大;
- 病态矩阵(κ≫1):椭圆被压成”雪茄”甚至”针”,σmin 方向几乎被压扁。误差一旦落进这个方向,解就会飞出去——Hilbert 矩阵就是这么回事。
配合条件数不等式:δb 恰好落在 umin(被压扁的方向)时,解的扰动 δx=A−1δb 落在 vmin 方向,被放大了 1/σmin 倍。
条件数的几个性质#
- κ(A)≥1:因为 ∥A∥⋅∥A−1∥≥∥AA−1∥=∥I∥=1。
- 缩放不变:κ(cA)=κ(A)。所以”行列式小”不是病态的判据——把 A 整体乘 1000,行列式变 106 倍,条件数纹丝不动。判断病态必须看比率,不是看绝对大小。
- 正交矩阵 κ=1:正交矩阵满足 QTQ=I,所有奇异值都是 1,圆映成圆。旋转/反射是最”温和”的矩阵,这也是为什么 RoPE 用旋转矩阵编码位置(第九节展开)。
- 有效精度:双精度下 ϵ≈2.2×10−16,条件数 κ=10k 意味着解要丢掉约 k 位十进制有效数字。经验法则:κ⋅ϵ≳1 时,解基本是噪声。Hilbert 矩阵 n=31 时 κ≈1040,κϵ≈1024,所以图里那根红线横七竖八——不是求解器的错,问题本身就没有可解性。
顺带把上一篇欠的账补上:κ 不仅衡量 Ax=b,对任意计算问题都能定义”问题条件数”。函数 f 在输入 x 处的条件数就是 ∣f′(x)∣⋅∣x∣/∣f(x)∣,衡量输入相对扰动引起的输出相对扰动。上一篇讲的”相近数相减”(catastrophic cancellation)本质上是减法 f(a,b)=a−b 在 a≈b 处条件数趋于无穷;在线 softmax 的重缩放则是把一个病态写法重排成良态写法。本篇聚焦矩阵版本。
高斯消元:人人都学过,却未必知道它有多脆弱#
消元过程与计算量#
高斯消元你课程里学过,这里从”数值稳定性”的角度重新看一遍。目标是把增广矩阵 [A∣b] 通过行变换变成上三角 [U∣b~],再回代求解。以 3×3 为例:
A=2−4−21−67−102第一步:用第 1 行消去第 2、3 行的第 1 列。乘数(multiplier)分别是 −4/2=−2 和 −2/2=−1,第 2 行减去 −2 倍第 1 行(等价于加上 2 倍),第 3 行减去 −1 倍第 1 行,得到
2001−48−1−21第二步:用第 2 行消第 3 行第 2 列,乘数 8/(−4)=−2,得到上三角 U。回代两步即可求出 x。
第 k 步消元要处理剩下的 n−k 行、每行约 n−k+1 个元素,所以总乘加次数约为
k=1∑n−1(n−k)(n−k+1)≈31n3每次乘加是 2 次浮点运算(乘+加),因此高斯消元的总计算量是 32n3 flops;回代只有 21n2,可以忽略。作为对比,矩阵乘法是 2n3 flops——消元大约只有 GEMM 的三分之一,这是个”便宜”的算法。
致命弱点:除以小主元#
消元的关键操作是除以主元(对角线元素)。如果主元很小,会发生什么?用一个经典的教科书例子(几乎所有数值线性代数教材都会讲,比如 Trefethen & Bau 的《Numerical Linear Algebra》):
{0.0001x1+x2=1x1+x2=2精确解是 x1≈0.9999,x2≈1.0001。现在假设我们只有三位十进制浮点精度(10−4 量级机器精度,相当于”极寒版”的 FP16 环境,用来放大问题)。
不换行直接消:乘数 m=1/0.0001=10000。第二行减去 m 倍第一行:(1−10000×1)x2=2−10000×1,即 −9999x2=−9998,三位精度舍入为 −1.00×104⋅x2=−1.00×104,解得 x2=1.00。回代:0.0001x1=1−1.00=0,于是 x1=0。
结果:x1=0,真解是 x1≈1——完全错了。 问题出在哪?第一步 2−10000×1=−9998 这一步:10000 和 1 相差四个数量级,大数加小数把 x1 的信息直接舍入掉了(正是上一篇讲的”大数加小数丢精度”),于是 x1 的信息在消元第一步就彻底消失。
先换行再消(把第一行和第二行交换):主元变成 1,乘数 m=0.0001。第二行变为 (1−0.0001×1)x2=1−0.0001×2,即 0.9999x2=0.9998,三位精度下 x2=1.00,回代 x1=2−1.00=1.00。
结果正确。 同样的机器、同样的精度,只是行交换了一下,结果从全错变全对。这就是部分主元(partial pivoting)的全部动机。
部分主元:把最大元换到对角线#
部分主元策略:消元到第 k 步时,在 A[k:n,k](第 k 列主元位置往下的所有元素)中挑绝对值最大的,把它所在的行和当前第 k 行交换,再以它为除数。这样保证所有乘数满足 ∣m∣≤1。
为什么”选最大的”?因为消元中真正危险的是除以很小的数:除数越小,舍入误差被放大的倍数越大。把主元选为列中绝对值最大者,就把每一步的放大倍数压到最小。而且行交换不改变方程组的解(只是重排方程顺序),换行是零成本、零风险的操作。
更严格的稳定性保证来自 Wilkinson 的经典分析:带部分主元的高斯消元是向后稳定的(第八节详细说),其误差界中的”增长因子”(growth factor)ρ=maxi,j,k∣uij∣/maxi,j∣aij∣ 在部分主元下通常很小(实践中 ρ 很少超过 10),而不换主元时 ρ 可以呈 2n−1 指数爆炸——理论最坏情况由 Wilkinson 构造的特殊矩阵达到,工程上无主元消元是绝对禁区。
还有更强的完全主元(complete pivoting):每一步在右下角整个子矩阵里挑最大元。它理论上更稳,但每次要扫 O(n2) 个元素找最大值,总代价 O(n3) 的额外比较,几乎没人用——部分主元”够好且免费”,完全主元”略好但昂贵”,这是工程上经典的取舍。
LU 分解:消元过程的矩阵语言#
高斯消元做了 n−1 轮行变换,这些行变换在矩阵语言里就是左乘初等矩阵。把每轮消元的乘数记下来,你会发现整个消元过程可以被压缩成一句话:A=LU。
从消元到分解#
设 E1,E2,…,En−1 依次是各轮消元的行变换矩阵,消元完成后有
En−1⋯E2E1A=U其中 U 是上三角。把所有的 E 移到右边:
A=(En−1⋯E1)−1U关键事实:初等行变换矩阵的逆不需要算,直接读出来。Ek 的逆就是把第 k 轮乘数的符号反过来,于是 (En−1⋯E1)−1 恰好是把各轮乘数(变号后)填到对角线下方的下三角矩阵 L,且对角线全为 1:
L=1m21⋮mn11⋯⋱mn,n−11,U=u11u12u22⋯⋱u1n⋮unn验证一个 2×2 例子:A=(2817),乘数 m21=8/2=4,消元得 U=(2013),于是
L=(1401),LU=(1401)(2013)=(2817)=A✓为什么这个平凡的重述如此重要?因为分解一次,可以反复使用:
- 求解 Ax=b 变成两步:先前代解 Ly=b(O(n2),下三角从顶往下算),再回代解 Ux=y(O(n2));
- 换一个新的右端项 b′,只需要重做两次三角求解 O(n2),分解的 2n3/3 不用重算。
带部分主元时,行交换记成一个置换矩阵 P,分解写作 PA=LU,求解流程变为 Ly=Pb,Ux=y。这就是 LAPACK 例程 getrf(分解,输出 L,U,P)和 getrs(用分解结果求解)的由来——永远两步走,永远不显式求逆。
为什么不显式求逆:成本与稳定性的双重理由#
把”求逆再相乘”和”LU 分解”对比,这是本系列最重要的工程结论,也是 John D. Cook 的经典博客文章 Don’t invert that matrix 的标题——不要对矩阵求逆。
- 成本:显式求 A−1 等价于解 n 个右端项 AX=I,成本 O(n3)(约 2n3 到 4n3 flops,取决于实现),而 LU 分解只要 2n3/3,再解任意多个右端项每个只需 O(n2)。对一个右端项来说,求逆贵 3 倍以上。
- 稳定性:求逆本身是”解 n 个方程组”,每一步都会引入舍入误差;求完逆再乘 b,误差又被乘一遍。用 John Cook 的比喻:为了回答”这家餐厅有什么菜”,你把整本菜单背下来再逐页翻——直接把菜单翻到那一页(LU 求解)又快又稳。
- 结构:A 如果稀疏、带状、对称正定,L 和 U 会继承部分结构(比如 Cholesky 的 L 保持带状),而 A−1 几乎总是稠密的——求逆会破坏所有可以利用的结构。
数值上还有一个更微妙的点:A−1 的条件数等于 A 的条件数(κ(A−1)=κ(A),因为奇异值互为倒数),所以”先求逆再乘”并不会让问题变得更好;而直接 LU 求解只需承担一次”向后误差 × 条件数”。结论是明确的:工程代码里出现 inv(A) @ b 或 A.inverse() 的地方,几乎都可以替换为分解求解,又稳又快。
与 GEMM 的联系:分块 LU#
GPU 上怎么把 LU 分解跑得快?答案是把消元分块化(blocked / panel factorization):每一轮对外层的 k 列(panel)做一次小规模消元,然后用矩阵乘更新剩余的大块子矩阵 A22←A22−L21U12。这一步是标准的 GEMM——正好复用你在这两篇《GPU GEMM 优化完全拆解(一)》《GPU GEMM 优化完全拆解(二)》里学到的分块、共享内存、寄存器分块技术。LAPACK 的 getrf 带 DGETRF 的块化实现,cuSOLVER 的 cusolverDnDgetrf 是它的 GPU 版本——GPU 上 LU 的加速路径和 GEMM 是同一套打法。这也是为什么 ”32n3 的消元” 在硬件上能以接近 GEMM 的效率运行:大部分工作都被重构成了 GEMM。
分解的谱系:Cholesky、QR、SVD#
LU 不是唯一的分解。数值线性代数的核心智慧可以浓缩成一句口号:别直接操作矩阵,先把它分解成好处理的因子。选哪种分解取决于矩阵的结构和精度要求:
| 分解 | 适用条件 | 计算量 | 数值稳定性 | LAPACK / cuSOLVER 例程 |
|---|---|---|---|---|
| LU + 部分主元(PA=LU) | 任意可逆方阵 | 32n3 | 向后稳定(主元保护) | getrf / getrs |
| Cholesky(A=LLT) | 对称正定 | 31n3 | 天然稳定,无需主元 | potrf / potrs |
| QR(A=QR) | 任意矩阵(列满秩) | 2n3(Householder) | 无条件向后稳定 | geqrf |
| SVD(A=UΣVT) | 任意矩阵 | ≳4n3 | 最稳定、最贵 | gesvd / gesvdj |
逐行解释:
- Cholesky:A=LLT,L 为下三角,无需主元也稳定——因为对称正定矩阵的所有顺序主子式为正,消元过程中主元天然远离零。计算量只有 LU 的一半(利用对称性),是”最便宜的好分解”。它出现在一切正定系统的求解里:协方差矩阵、正态分布的二次型、以及最小二乘的正规方程(不过正规方程本身条件数是原问题的平方,工程上通常用 QR 替代——这是下一篇的主题)。
- QR:A=QR,Q 正交、R 上三角。Householder 变换把消元用的”初等行变换”换成正交变换,正交变换不放大误差(κ=1),所以 QR 是求解最小二乘的标准选择。它比 LU 贵 3 倍,但换来的无条件稳定性值得。
- SVD:最贵、最稳、信息最全。奇异值谱直接告诉你秩、条件数、低秩近似——你在 MLA 完全拆解 里见过的低秩压缩,数学基础就是”截断 SVD:砍掉小奇异值”。
这张表里 U 的一列可以回答你之前一个疑问:为什么”矩阵求逆”在 LAPACK 里不是一个推荐接口?因为求逆 = 做一次 LU 分解 + 解 n 个右端项,任何”直接求逆”的算法都不会比”分解 + 三角求解”更便宜或更稳。所有严肃的数值库都围绕分解设计,逆矩阵只是一个”概念对象”。
误差分析的视角:向后误差与 Wilkinson 公式#
解决了”怎么解”,还剩最后一个理论问题:浮点算法算出的解 x^,到底错在哪?
朴素的想法是”算出 x^ 后和真解 x 比相对误差 ∥x^−x∥/∥x∥“——这叫向前误差(forward error)。但真解 x 我们永远不知道,这个定义不可操作。数值分析用了一个巧妙的视角翻转——向后误差(backward error):
x^ 是某个”邻近系统” (A+δA)x^=b 的精确解,其中 ∥δA∥ 很小。我们不去问”x^ 离真解多远”,而是问”x^ 精确地解了哪个问题,那个问题和原问题差多远”。
Wilkinson 的经典定理:带部分主元的高斯消元是向后稳定的——浮点消元算出的 x^ 精确满足
(A+δA)x^=b,∥δA∥≤cnρϵ∥A∥其中 c 是小常数,n 是矩阵规模,ρ 是增长因子,ϵ 是机器精度。也就是说:算法本身几乎不引入误差——它引入的误差和一个”精确求解扰动后系统”的人一样多。
把向后误差和条件数乘起来,就得到总误差(Wilkinson 公式的通俗版本):
∥x∥∥x^−x∥≲κ(A)⋅(向后误差)=κ(A)⋅O(nρϵ)这个分解的价值在于责任划分:条件数 κ 是问题的属性(病态与否),nρϵ 是算法的属性(稳定与否)。Hilbert 矩阵的灾难来自前者——κ≈1040 时,即使算法完美(向后误差仅 ϵ 量级),总误差照样 1024。反过来,只要 κ 中等(比如 103 以内),稳定算法在双精度下就能给出几乎全精度的解。
工程上还要注意:κ 本身通常不精确计算(精确算要 SVD,太贵)。实际做法是用 O(n2) 的估计器:LAPACK/MATLAB 的 condest(1 范数条件数估计,Higham 设计),以及基于三角因子 R 的 tricond 类例程。Cleve Moler 2026 年 4 月的博客文章 Matrix Condition and the QR Decomposition 专门讲了这条路线:先做 QR 分解,再用三角矩阵条件数估计器估算 κ(R)=κ(A)。下图的 3D 条形图来自该文,对比了多种测试矩阵(moler、parter、binomial、chebspec、cauchy 等 MATLAB Gallery 矩阵)在不同规模 n 下的估计得分:

读图要点:每组柱状的高度是”估计得分” tricond/κ,越接近 1 说明估计越准;图中可以看到不同矩阵、不同规模下估计质量的差异,以及是否启用列主元对估计的影响——这解释了为什么”带主元的 QR 三角因子估计”是生产级代码的标准做法。在推理系统里,这种估计器的意义在于诊断:当你怀疑某个矩阵运算结果可疑时,先估计条件数,再决定是怀疑算法还是怀疑问题本身。
现在回头看第一节的 Hilbert 图,可以把责任交代清楚了:红线抖动不是求解器质量差(它满足向后稳定性),而是 κ⋅ϵ≈1024——问题本身没有可解性。对这种病态问题,数值方法能做的不是”更努力地解”,而是换问题:加正则化(把 Ax=b 换成 (A+pI)x=b 之类的最小二乘变体,即 ARLS 文章里讲的 Tikhonov 正则化)、降低精度要求、或利用先验知识。这正是”ARLS, Automatically Regularized Least Squares”那篇文章的主题,也是数值线性代数与机器学习交汇的地方。
与 LLM 推理的五个连接#
这一节的目的是把前面所有数学落回你的方向。每个连接都是真实的工程事实,不是牵强附会。
1. RoPE 为什么数值友好:正交矩阵 κ = 1#
RoPE(旋转位置编码,论文 arXiv:2104.09864)把位置信息编码为对 q、k 向量施加的旋转:2 维子空间上用 (cosθsinθ−sinθcosθ) 旋转。这类旋转矩阵是正交矩阵:QTQ=I,所有奇异值为 1,κ=1。
这意味着两件事:其一,旋转保长度(∥Qx∥=∥x∥),注意力点积的模长不受位置编码破坏;其二,误差不会被旋转放大——即使 FP16/BF16 下 q、k 的表示有舍入误差,旋转也不会把它们放大 κ 倍。用前面的话说,RoPE 选择了一种”条件数最优”的线性变换。对比之下,如果位置编码用非正交矩阵(比如某些线性外推方案),数值风险是隐性的。
2. 在线 softmax 的重缩放:把病态重排成良态#
上一篇推导过在线 softmax:为防溢出,减去当前最大值 m,用 exp(xi−m) 代替 exp(xi),再乘回重缩放因子。用本篇的语言:直接算 exp 求和是病态写法(大数加小数),减去最大值把中间量压到 [0,1],等价于把一个 κ 巨大的求和重排成 κ≈1 的良态求和——同一个数学对象,不同的计算顺序,条件数天差地别。FlashAttention 的数值重缩放(论文 arXiv:2205.14135)是同一思想的流式版本。这是”算法稳定性”最重要的工程模板:不改问题,只改写法。
3. 不显式求逆:MLA 吸收、LoRA 合并、量化#
你的方向上”求逆”出现的方式,全是被刻意回避的:
- MLA 的矩阵吸收(详见《MLA 完全拆解》):把 WUK 吸收进 WQ、WU 吸收进 WO,是把小矩阵乘到大权重里,是纯乘法重组,不涉及任何求逆;
- LoRA 合并:W′=W0+BA,加法;
- 量化/反量化:scale 因子是标量,x/s 等价于乘 1/s——1×1 的”对角矩阵求逆”是平凡且 κ=1 的。
如果哪一天你在推理管线里看到显式 inv(),几乎都可以问一句:这里是不是可以用分解或直接重组替代?这是”Don’t invert that matrix”精神在 LLM 部署中的版本。
4. 奇异值谱与低秩压缩:σ_min 决定”可逆性”#
SVD 视角下,权重矩阵的低秩可压缩性来自奇异值谱衰减:大模型权重矩阵的奇异值通常快速衰减,σmin 接近零,因此矩阵”数值上不可逆”——但这恰恰是好事,说明它可以被低秩近似(截断 SVD 砍掉小奇异值方向)。MLA 的低秩 KV 压缩、SVD-LLM(arXiv:2403.17414,用 SVD 做 LLM 权重压缩)、XFP 那类码本量化,数学上都是同一个事实的利用:σmin 小 → 精确求逆无意义 → 但低秩/伪逆有意义。伪逆 A+=VΣ+UT(Σ+ 对非零奇异值取倒数)是”在秩亏矩阵上最有意义的求逆”——它恰好跳过 σ≈0 的方向,等价于数值上最稳的逆。这也是为什么数值库提供 gesvd 而不是”安全求逆”。
5. 状态空间模型与线性注意力:特征值、分块消元与谱半径#
最后两个预告性的连接,细节留给后面的文章:
- S4 论文(arXiv:2111.00396)明确讨论了数值问题:状态空间模型的 A 矩阵直接对角化在长序列下数值不稳,原因是特征向量矩阵可能病态(κ 大),于是改用正规矩阵(正规矩阵可被正交对角化,特征向量矩阵 κ=1)。这是”特征值问题也会病态”在 LLM 系统的真实案例,也是下一篇系列文章(特征值与谱)的引子。Mamba 的 ZOH 离散化要计算 (ΔA)−1(eΔA−I)ΔB——这个”除以 ΔA“的小型矩阵运算在实现中同样用级数展开回避显式求逆。
- RetNet 的分块并行(arXiv:2307.08621)在形式上与分块消元同构:序列被切成块,块内并行、块间递推,需要计算的块矩阵组合与分块高斯消元中的 Schur 补结构一致。分块、消元、递推这三件事在数值线性代数里本来就是一家。
GPU 实践:在 CUDA 里解线性方程组#
把本篇知识落到代码层面,几条可以直接用的建议:
- 用库,不要手写:解 Ax=b 用 cuSOLVER 的
cusolverDnDgetrf(LU 分解)+cusolverDnDgetrs(求解),对称正定用cusolverDnDpotrf/potrs。不要自己实现高斯消元——主元、分块、GEMM 化这些细节库都处理好了。 - 批量小矩阵:推理 kernel 里常见”对每个 token/每个样本解一个小系统”的需求,用 cuBLAS 的 batched 接口或 cuSOLVER 的 batched
getrf,不要在一个 kernel 里串行解几百个小系统。 - 手写小矩阵求逆要警觉:2×2、3×3 的显式逆矩阵公式(伴随矩阵除以行列式)偶尔手写进 kernel。除行列式等价于除以 σ1σ2,行列式接近零时误差爆炸——如果必须手写,先估 κ(2×2 可以快速估奇异值比),或者改用公式更稳的形式。
- 诊断先行:数值结果可疑时,先估计条件数再怀疑算法。用
condest的思路(基于三角因子)在 GPU 上成本很低。
小结#
这一篇的完整链条:误差来自浮点(上一篇)→ 误差被放大多少由条件数决定(本篇前段)→ 条件数巨大是问题属性,算法能控制的是”不添乱”(向后稳定)→ 高斯消元 + 部分主元是向后稳定的(本篇核心)→ 矩阵形式是 LU 分解 → 分解而不求逆,是所有数值库的设计哲学。
五个必须带走的事实:
- 条件数 κ=σmax/σmin 是”误差放大倍数”,κ⋅ϵ≳1 时解就是噪声;正交矩阵 κ=1。
- 高斯消元本身脆弱(除以小主元放大误差),部分主元用”换行”这一零成本操作保证乘数 ≤1,使算法向后稳定。
- 消元过程就是 LU 分解;分解一次 2n3/3,之后每个右端项只要 O(n2)。
- 分解谱系按”结构与精度”选择:正定用 Cholesky(n3/3)、一般用 LU、最小二乘用 QR、诊断用 SVD;求逆总是更贵更差的选择。
- 工程判断框架:病态问题换问题(正则化/降维),稳定算法换写法(重排计算顺序),两件事不要混淆。
下一篇《数值线性代数(二)》将讨论 QR 分解与最小二乘:为什么正规方程 ATAx=ATb 是陷阱(κ 平方),Householder 变换如何实现无条件稳定,以及最小二乘在你方向上的现身之处。再下一篇进入迭代法与共轭梯度:κ 如何决定迭代次数,为什么大稀疏系统必须用迭代法。
参考资料#
- Greg Gundersen, “The Singular Value Decomposition (SVD)“——本篇两幅几何图的来源(Figure 2 线性变换、Figure 5 圆到椭圆)
- Cleve’s Corner: ARLS, Automatically Regularized Least Squares——31×31 Hilbert 矩阵病态演示图来源(MathWorks 官方博客,Rondall Jones 客座)
- Cleve’s Corner: Matrix Condition and the QR Decomposition——条件数估计得分对比图来源(MathWorks 官方博客,2026 年 4 月)
- John D. Cook, “Don’t invert that matrix”——“不要显式求逆”的经典论述
- Trefethen & Bau, Numerical Linear Algebra(SIAM,DOI 10.1137/1.9780898719574)——高斯消元、主元策略与向后误差的标准教材
- N. J. Higham, Accuracy and Stability of Numerical Algorithms(SIAM,DOI 10.1137/1.9780898718027)——误差分析与条件数估计(condest)的权威参考
- Goldberg, “What Every Computer Scientist Should Know About Floating-Point Arithmetic”——浮点算术与消去误差的经典文献
- NVIDIA cuSOLVER 官方文档——GPU 上 LU/Cholesky/QR/SVD 例程(getrf/getrs/potrf/geqrf/gesvd)
- RoPE 论文:RoFormer: Enhanced Transformer with Rotary Position Embedding(arXiv:2104.09864)——旋转矩阵正交性(κ=1)的来源
- FlashAttention 论文(arXiv:2205.14135)——在线 softmax 数值重缩放
- S4 论文:Efficiently Modeling Long Sequences with Structured State Spaces(arXiv:2111.00396)——状态空间模型中特征向量矩阵病态与正规矩阵的讨论
- Mamba 论文(arXiv:2312.00752)——SSM 离散化与矩阵指数计算
- RetNet 论文:Retentive Network: A Successor to Transformer for Large Language Models(arXiv:2307.08621)——分块并行表示与分块消元的类比
- SVD-LLM 论文:Singular Value Decomposition for LLM Compression(arXiv:2403.17414)——奇异值谱与权重压缩
- Trefethen 的牛津数值线性代数讲义主页——消元、分解与稳定性讲义
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分内容可能已过时
评论区
分享你的想法,与大家交流讨论
音乐
暂未播放



