66-机器学习与大模型开发数学教程-6-2 矩阵运算的数值误差分析

「ml-llm-math.zip」
链接:https://pan.quark.cn/s/35fc37047e5e

一句话版:矩阵世界的数值误差来自两头------问题本身的"体质"(条件数)算法/实现的"手法"(舍入与稳定性) 。工程上要做的,是挑好问题表述 (比如用 QR/SVD 代替 A ⊤ A A^\top A A⊤A)、用稳定算法 (正交变换、配对求和、迭代精炼)、搭配合适精度(混合精度中保留关键归约为 FP32)。


1. 误差模型:从标量到矩阵

1.1 浮点舍入模型

记机器精度(单位舍入)为 u u u(float32 约 10 − 7 10^{-7} 10−7)。一条浮点运算可近似为

fl ⁡ ( a ∘ b ) = ( a ∘ b ) ( 1 + δ ) , ∣ δ ∣ ≤ u , ∘ ∈ { + , − , × , ÷ } . \operatorname{fl}(a \circ b) = (a \circ b)(1+\delta),\quad |\delta|\le u,\quad \circ\in\{+,-,\times,\div\}. fl(a∘b)=(a∘b)(1+δ),∣δ∣≤u,∘∈{+,−,×,÷}.

将很多次运算"串起来",误差会像 γ n \gamma_n γn 一样积累:

γ n : = n u 1 − n u ≈ n u ( 当 n u ≪ 1 ) . \gamma_n := \frac{nu}{1-nu}\approx nu \quad(\text{当 } nu\ll 1). γn:=1−nunu≈nu(当 nu≪1).

1.2 前向/后向误差与条件数

  • 后向误差 :算法等价于在输入上加了一个小扰动再做精确计算。
  • 前向误差 :得到的和真解有多远。
  • 条件数 刻画问题对输入扰动的敏感度:
    对线性方程 A x = b Ax=b Ax=b,二范数条件数 κ 2 ( A ) = ∥ A ∥ 2 ∥ A − 1 ∥ 2 = σ max ⁡ / σ min ⁡ \kappa_2(A)=\|A\|2\|A^{-1}\|2=\sigma{\max}/\sigma{\min} κ2(A)=∥A∥2∥A−1∥2=σmax/σmin。

重要不等式(核心记忆):

∥ x − x ^ ∥ ∥ x ∥    ≲    κ ( A ) × (相对后向误差) ⏟ 看算法稳定性 . \frac{\|x-\hat x\|}{\|x\|}\;\lesssim\; \kappa(A)\times \underbrace{\text{(相对后向误差)}}_{\text{看算法稳定性}}. ∥x∥∥x−x^∥≲κ(A)×看算法稳定性 (相对后向误差).

读法:问题体质 κ \kappa κ × 算法"干净程度" 决定最终误差。


2. 基本矩阵运算的误差界

2.1 点积与矩阵--向量乘

  • 点积 s ^ = fl ⁡ ( x ⊤ y ) \hat s=\operatorname{fl}(x^\top y) s^=fl(x⊤y):
       ∣ s ^ − x ⊤ y ∣ ≤ γ n ∑ i ∣ x i y i ∣ \;|\hat s - x^\top y|\le \gamma_n \sum_i |x_i y_i| ∣s^−x⊤y∣≤γn∑i∣xiyi∣。
    顺序影响大 :小数加到大数可能被吞。→ 用配对求和Kahan 可显著降低误差。

  • 矩阵--向量 z ^ = fl ⁡ ( A x ) \hat z=\operatorname{fl}(Ax) z^=fl(Ax):每个输出元素是一个点积:
       ∥ z ^ − A x ∥ ≤ γ n   ∥   ∣ A ∣   ∣ x ∣   ∥ \;\|\hat z - Ax\| \le \gamma_n \, \|\,|A|\, |x|\,\| ∥z^−Ax∥≤γn∥∣A∣∣x∣∥。

2.2 矩阵乘 C = A B C=AB C=AB

经典界(逐元素或范数):

∥ C ^ − A B ∥    ≤    γ k   ∥   ∣ A ∣   ∥   ∥   ∣ B ∣   ∥ ( k = 内积长度 ) . \|\hat C - AB\| \;\le\; \gamma_k \, \|\,|A|\,\|\,\|\,|B|\,\| \quad (k=\text{内积长度}). ∥C^−AB∥≤γk∥∣A∣∥∥∣B∣∥(k=内积长度).

工程含义:分块/重排并不改变数学值,却改变累加路径 → 影响 γ k \gamma_k γk。高性能库(BLAS/GEMM)通过分块+FMA 降低误差与提升性能;混合精度时,低精乘 × 高精累加能稳很多。


3. 解线性方程与最小二乘的稳定性

3.1 正规方程的"放大器"

最小二乘 min ⁡ x ∥ A x − b ∥ 2 \min_x \|Ax-b\|_2 minx∥Ax−b∥2。若用正规方程 ( A ⊤ A ) x = A ⊤ b (A^\top A)x=A^\top b (A⊤A)x=A⊤b,条件数平方:

κ ( A ⊤ A ) = κ ( A ) 2 . \kappa(A^\top A)=\kappa(A)^2. κ(A⊤A)=κ(A)2.

这会把病态问题变得更病态 (噪声和舍入都被放大),不推荐

3.2 QR 分解(优选)

用正交 Q Q Q(不改变 2 范数)和上三角 R R R:
A = Q R ,    ⇒    R x = Q ⊤ b A=QR,\; \Rightarrow\; Rx=Q^\top b A=QR,⇒Rx=Q⊤b。

基于 Householder 反射 的 QR 后向稳定 :产生的 R ^ , Q ^ \hat R,\hat Q R^,Q^ 相当于计算了 A + E A+E A+E 的 QR,且 ∥ E ∥ ≲ γ n ∥ A ∥ \|E\|\lesssim \gamma_n\|A\| ∥E∥≲γn∥A∥。

3.3 SVD(最稳,最贵)

A = U Σ V ⊤ A=U\Sigma V^\top A=UΣV⊤,最小二乘解 x = V Σ + U ⊤ b x=V\Sigma^+U^\top b x=VΣ+U⊤b。SVD 直接拿到奇异值/秩信息,对病态问题稳如老狗,但成本最高。

3.4 LU 分解与主元选取

一般线性方程 A x = b Ax=b Ax=b:

  • 带部分选主元的 LU(GEPP) 是工业常用。稳定性受增长因子影响,多数实际问题很好。
  • Cholesky :当 A ≻ 0 A\succ 0 A≻0(对称正定),Cholesky 是后向稳定速度快一倍,优先用。

口诀:SPD → Cholesky最小二乘 → QR/SVD一般方程 → LU(带主元)别轻易用 A ⊤ A A^\top A A⊤A


4. 正交化的数值差异

  • 经典 Gram--Schmidt(CGS):易受消去影响,正交性差。
  • 改进版 MGS:更稳一些,但仍可能退化(需要再正交)。
  • Householder QR :最稳、代价略高,是推荐的默认选择
  • MGS + 再正交:在迭代 Krylov 子空间方法中常见的折中。

5. 特征值/奇异值的敏感性

5.1 对称(或正规)矩阵:稳

  • Weyl 定理 :对称 A A A 加扰动 E E E,特征值偏差 ∣ λ ^ i − λ i ∣ ≤ ∥ E ∥ 2 |\hat\lambda_i-\lambda_i|\le \|E\|_2 ∣λ^i−λi∣≤∥E∥2。
  • Davis--Kahan:特征子空间与扰动大小/谱间隙成反比,谱间隙越大越稳。
  • 奇异值 也满足 Weyl: ∣ σ ^ i − σ i ∣ ≤ ∥ E ∥ 2 |\hat\sigma_i-\sigma_i|\le \|E\|_2 ∣σ^i−σi∣≤∥E∥2。

5.2 非正规(非正交可对角化)矩阵:可能很脆

非正常矩阵的特征向量不正交,小扰动会造成巨大前向误差 (伪谱大)。工程上尽量转为对称问题 (如用 A ⊤ A A^\top A A⊤A 得到奇异值/右奇异向量,或考虑正规化/预条件),避免直接做一般非对称的特征分解除非必要。


6. 混合精度与迭代精炼(Iterative Refinement)

思路:低精粗解 + 高精残差校正

步骤(解 A x = b Ax=b Ax=b):

  1. 在低精(如 fp16/bf16)用 LU/Cholesky 得到初解 x ^ \hat x x^。
  2. 用高精(fp32/fp64)计算残差 r = b − A x ^ r=b-A\hat x r=b−Ax^。
  3. 解校正方程 A Δ x = r A\Delta x=r AΔx=r(仍可低精解,但残差高精计算), x ^ ← x ^ + Δ x \hat x\leftarrow \hat x+\Delta x x^←x^+Δx。
  4. 重复至收敛。

收敛条件(直觉):低精舍入 u low u_{\text{low}} ulow 与 κ ( A ) \kappa(A) κ(A) 满足 κ ( A )   u low ≪ 1 \kappa(A)\, u_{\text{low}} \ll 1 κ(A)ulow≪1。

在大模型/科学计算中,这一招能把低精算力 转化为高精结果(前提是问题不太病态)。


7. 选择指南(中文流程)

Ax=b


最小二乘




确定问题类型
Ax=b 还是 最小二乘?
A 是否对称正定?
Cholesky
LU+部分选主元
病态/高精需求?
SVD
Householder QR
内存/速度限制?
混合精度+迭代精炼
直接高精实现

说明 :根据矩阵结构优先选择稳定分解 ;资源紧张时上混合精度 + 精炼


8. 与机器学习的连接

  • 线性回归/岭回归 :不要手写 x = ( A ⊤ A ) − 1 A ⊤ b x=(A^\top A)^{-1}A^\top b x=(A⊤A)−1A⊤b;用 lstsq(QR/SVD)或正规化的 Cholesky(对 A ⊤ A + λ I A^\top A+\lambda I A⊤A+λI)。
  • PCA/SVD :用 SVD/随机 SVD,避免对协方差矩阵长链累加带来的误差;做中心化 并可能标准化
  • 归一化/标准化 改善 κ ( A ) \kappa(A) κ(A),提升求解质量
  • 混合精度训练 :矩阵乘可低精(bf16/fp16),归约/归一化/损失 保 FP32;出现 NaN/Inf 先看缩放/中心化损失放大
  • 图/核方法 :核矩阵常病态,优先 加核对角 λ I \lambda I λI + Cholesky ,或直接 SVD

9. 代码骨架(安全替换件)

9.1 稳定最小二乘(PyTorch 思路)

python 复制代码
import torch

def stable_lstsq(A, b, ridge=0.0):
    # A: (n,d), b: (n,) 或 (n,k)
    A = A - A.mean(0, keepdim=True)  # 中心化有助于条件数
    if ridge > 0:
        # 解 (A^T A + λI)x = A^T b,用 Cholesky,更稳
        AtA = A.T @ A
        d = AtA.shape[0]
        AtA = AtA + ridge * torch.eye(d, device=A.device, dtype=A.dtype)
        L = torch.linalg.cholesky(AtA)
        rhs = A.T @ b
        y = torch.cholesky_solve(rhs, L)  # 解 (AtA)x=rhs
        return y
    else:
        # 直接最小二乘(QR/SVD 由框架选择)
        # torch>=2.0: linalg.lstsq 使用稳健分解
        return torch.linalg.lstsq(A, b).solution

9.2 混合精度矩阵乘 + FP32 归约(Numpy/伪)

python 复制代码
import numpy as np

def matmul_mixed(A16, B16):
    # A16,B16 为 float16/bfloat16,归约在 float32
    A32 = A16.astype(np.float32)
    B32 = B16.astype(np.float32)
    return (A32 @ B32).astype(A16.dtype)  # 或保留 FP32 输出做后续稳定运算

10. 工程清单(Checklist)

  • 显式算逆,优先解线性系统/分解(solve/lstsq)。
  • 用 A ⊤ A A^\top A A⊤A 正规方程做最小二乘,优先 QR/SVD
  • SPD 问题优先 Cholesky ;一般方程用 LU+主元
  • 长链求和/点积用 配对求和/Kahan ;矩阵乘尽量走 高质量 BLAS
  • 中心化/标准化/缩放 降低条件数。
  • 混合精度下:低精乘 + 高精累加,关键归约/正交/分解保 FP32。
  • 观察 条件数 (SVD/matrix_rank/最小奇异值)并在病态时加 正则
  • 迭代精炼 把低精的速度"换"成高精的解。
  • 边界单测:全零/共线列/极小奇异值/尺度差 10^k。

11. 练习(含提示)

  1. 为何正规方程会"变差" :证明 κ 2 ( A ⊤ A ) = κ 2 ( A ) 2 \kappa_2(A^\top A)=\kappa_2(A)^2 κ2(A⊤A)=κ2(A)2。
  2. Householder 稳定性:简述为何正交变换能保持 2 范数,从而提升后向稳定。
  3. 点积实验 :对 n = 10 6 n=10^6 n=106 个随机数,比较顺序求和/配对求和/Kahan 的误差(用高精作为真值)。
  4. 最小二乘对比:在高条件数数据上比较正规方程、MGS、Householder QR、SVD 的解残差。
  5. 迭代精炼:在 bf16(或模拟低精)上做 LU 求解,再用 fp32 残差修正,观察收敛条件与速度。
  6. PCA 稳定性:模拟中心化与未中心化对协方差矩阵的影响,并比较 SVD 得到的主成分稳定性。

12. 小结

  1. 误差两因素 :问题的 κ \kappa κ (体质) × 算法的 后向稳定性(手法)。
  2. 选择稳分解 :最小二乘 QR/SVD ;SPD Cholesky ;一般方程 LU+主元 ;避免 A ⊤ A A^\top A A⊤A。
  3. 混合精度也能稳低精乘 + 高精累加 + 迭代精炼 ,再配合缩放/中心化/正则,就能"又快又准"。
相关推荐
Exclusive_Cat8 小时前
SpringAi整合Springboot搭建,配置以及测试
人工智能
@蔓蔓喜欢你8 小时前
技术博客写作:分享知识,提升影响力
人工智能·ai
500848 小时前
用 Ascend CL 从零写一个推理程序
人工智能·深度学习·机器学习·性能优化·wpf
zxsz_com_cn8 小时前
设备预测性维护实施案例解析
人工智能
Loli_Wolf8 小时前
AI 原生研发闭环:从提需到线上监测,再自动回到提需
人工智能·深度学习·算法·microsoft·ai·ai编程·harness
kishu_iOS&AI9 小时前
NLP —— Transformers库使用
人工智能·自然语言处理·迁移学习
南屹川9 小时前
【中间件】RabbitMQ消息队列实战:从入门到精通
人工智能
ftpeak9 小时前
AI开发~OpenAI专家之路:构建企业级AI应用(第三部分·上)
人工智能·ai·ai编程
MediaTea9 小时前
DL:Transformer 的基本原理与 PyTorch 实现
人工智能·pytorch·python·深度学习·transformer