Day 01 · AI Infra 全景与学习环境

DAY 01 · AI INFRA ROADMAP · 60 DAYS 从一条 prompt,到一颗 GPU kernel 第一天的目标不是写代码,而是建立"全局地图"—— 把 AI Infra 这个庞大的领域拆成四层, 把一次推理的完整链路画在脑子里, 然后跑通你人生第一个 LLM 推理脚本。 ...

五月 14, 2026

AI 数学基础

线性代数 向量与向量空间 - 向量与向量空间 - 什么是向量 - 向量是一个有方向的量 - 几何视角:空间中从原点出发的一支箭头,方向和长度都有意义 - 代数视角:一组有序的数字 - 示例 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505104026041.png,96,87) - 这是一个三维向量,每个数字对应一个坐标轴上的分量。 - 词嵌入 - 一个词(token)会被映射成一个几百甚至几千维的向量 - 比如 "猫" 这个词可能被表示成一个 768 维的向量——你可以把它想象成 768 个坐标轴上的一个点 - 语义相近的词在这个空间里位置接近 - 向量的基本运算 - 向量加法 - 两个向量相加,对应分量分别相加 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505104141640.png,287,77) - 几何意义: 把 $\vec{b}$ 的起点接到 $\vec{a}$ 的终点,结果是合向量。 - 在 LLM 里的例子:有研究发现,词向量之间存在近似的语义关系 - vec("国王")−vec("男人")+vec("女人")≈vec("女王") - 标量乘法 - 用一个数(标量)乘以向量,每个分量都乘以这个数 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505111258217.png,172,77) - 几何意义:把向量拉伸或压缩 - 点积 - 定义 - 两个同维度向量的点积 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505114508393.png,360,73) - 示例 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505114528207.png,483,99) - 几何意义 - 点积有另一种等价写法 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505114553768.png,165,50) - 其中 $\theta$ 是两向量之间的夹角 - 关键洞察 - 点积可以衡量两个向量"有多相似"。 - 这正是 Attention 机制里 Query 和 Key 做点积的本质——算两个向量的相关程度 - 向量范数(Norm) - 范数衡量向量的"长度"或"大小" - L2 范数(最常用) - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505115921185.png,251,61) - 就是我们熟悉的欧几里得距离 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505115946653.png,276,63) - L1 范数 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505120034974.png,255,43) - 各分量绝对值之和,在正则化(防止过拟合)中常用。 - 余弦相似度 - 把点积和范数组合起来,就得到余弦相似度——LLM 里衡量语义相似性的核心工具 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505120438471.png,383,76) - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/05/20260505120456734.png,389,164) - 余弦相似度只关心方向,不关心长度 - 两个词的向量可能长度不同,但如果方向相同,说明它们在语义上是一致的 - 向量空间 - 满足以下条件的集合叫向量空间 - 元素(向量)之间可以相加,可以被标量乘 - 在这个集合里做加法和乘法,结果还在这个集合里 - 最关键的概念是维度(Dimension):向量空间需要多少个基向量来描述其中所有的点 - GPT-2 用 768 维的向量空间来表示词义,GPT-3 用 12288 维。维度越高,理论上能编码的信息越丰富 - Numpy 代码 - ```python import numpy as np # ─── 1. 创建向量 ─────────────────────────────────────── a = np.array([1, 2, 3], dtype=float) b = np.array([4, -1, 2], dtype=float) print("向量 a:", a) print("向量 b:", b) # ─── 2. 向量加法与标量乘法 ───────────────────────────── print("\n向量加法 a + b:", a + b) print("标量乘法 2 * a:", 2 * a) # ─── 3. 点积 ────────────────────────────────────────── dot_product = np.dot(a, b) print("\n点积 a · b:", dot_product) # 手动验证 manual_dot = sum(a[i] * b[i] for i in range(len(a))) print("手动计算点积:", manual_dot) # ─── 4. L2 范数 ──────────────────────────────────────── norm_a = np.linalg.norm(a) norm_b = np.linalg.norm(b) print("\n‖a‖₂ =", norm_a) print("‖b‖₂ =", norm_b) # ─── 5. 余弦相似度 ───────────────────────────────────── cos_sim = dot_product / (norm_a * norm_b) print("\n余弦相似度(a, b):", cos_sim) # ─── 6. 模拟词嵌入:哪个词和"猫"最相似? ────────────── # 用随机向量模拟(实际中是模型学习出来的) np.random.seed(42) embedding_dim = 8 # 简化为 8 维演示 word_vectors = { "猫": np.random.randn(embedding_dim), "狗": np.random.randn(embedding_dim), "汽车": np.random.randn(embedding_dim), "小猫": np.random.randn(embedding_dim), } # 手动让"猫"和"小猫"更相似 word_vectors["小猫"] = word_vectors["猫"] + np.random.randn(embedding_dim) * 0.3 def cosine_similarity(v1, v2): return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)) query = word_vectors["猫"] print("\n与"猫"的余弦相似度:") for word, vec in word_vectors.items(): if word != "猫": sim = cosine_similarity(query, vec) print(f" {word}: {sim:.4f}") ``` 矩阵基本运算 - 矩阵基本运算 - 矩阵是什么 - 是数字排列成的二维表格,用行数 x 列数描述它的形状(称为"维度"或"shape") - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/07/20260507220522540.png,142,68) - 这是一个 2×3 矩阵(2 行 3 列)。用 $A_{ij}$​ 表示第 i 行第 j 列的元素,比如 $A_{12} = 2$ - 矩阵的本质是线性变换。 - 描述的是"把一个向量变成另一个向量"的规则。 - 矩阵与向量的乘法 - 计算规则 - 矩阵 $A(m \times n)$ 乘以向量 $\vec{x}$(n 维),结果是一个 m 维向量 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/07/20260507221328789.png,353,92) - 结果的每一行,就是矩阵那一行与向量做点积。 - 具体例子 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/07/20260507221813500.png,388,92) - 一个 3×2 的矩阵,把一个 2 维向量变成了 3 维向量。 - 维度变了——这正是"变换"的含义。 - 几何直觉 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/07/20260507221947557.png,126,66) - 该矩阵可以把任意 2D 向量逆时针旋转 90 度 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/07/20260507222314744.png,114,66) - 原来朝右的向量,变成了朝上的向量。矩阵就是这样编码变换规则的。 - 矩阵 A 乘以向量 $\vec{x}$ 等于把 $\vec{x}$ 所在的空间拉伸、旋转、投影到另一个空间。 - LLM 中的应用 - Transformer 里,每个 token 的向量 $\vec{x}$ 乘以权重矩阵 $W_Q$​,得到 Query 向量 - $\vec{q} = W_Q\vec{x}$ - 这就是一次线性变换——把输入向量投影到"Query 空间" - 矩阵乘法 - 计算规则 - 两个矩阵相乘:$A(m\times k) \times B (k\times n) = C(m\times n)$ - 关键约束 - A 的列数必须等于 B 的行数(都是 k)。 - 结果矩阵 C 的第 i 行第 j 列 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/07/20260507224234717.png,165,72) - 即 A 的第 i 行与 B 的第 j 列做点积。 - 具体例子 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/07/20260507224403814.png,121,212) - 矩阵乘法的本质:变换的复合 - 单独看计算规则很枯燥。真正重要的是它的意义 - 矩阵 AB 表示"先做变换 B,再做变换 A"。 - 就像函数复合 $f(g(x))$,矩阵乘法是在组合两个线性变换。 - 神经网络的多层结构,本质上就是多个矩阵变换串联在一起,每一层都对数据做一次变换。 - 矩阵乘法的重要性质 - 不满足交换律 - $AB \neq BA$(大多数情况下) - 先旋转再缩放,和先缩放再旋转,结果不同——顺序很重要。 - 满足结合律 - $(AB)C=A(BC)$ - 这让我们可以灵活选择计算顺序(影响效率,不影响结果) - 转置 - 把矩阵的行和列互换,记作 $A^T$ - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509003910492.png,283,81) - $A_{ij}^T=A_{ji}$ - 转置的重要性质 - $(AB)^T=B^TA^T$ - $(\vec{a}^T\vec{b}) = \vec{a}\cdot \vec{b}$ - 转置把向量点积统一进了矩阵符号 - LLM 的直接应用 - Attention 公式里的 $QK^T$ 就是对 K 做转置后再和 Q 相乘,目的是让每个 Query 向量和每个 Key 向量都算一次点积,得到注意力分数矩阵。 - 逆矩阵 - 对于方阵(行数=列数) A,如果存在矩阵 $A^{-1}$ 使得 $AA^{-1}=A{-1}A=I$ - 其中 I 是单位矩阵,对角线全是 1,其余是 0,那么 $A^{-1}$ 叫做 A 的逆矩阵 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509004417750.png,115,77) - 单位矩阵就像数字里的 1,乘以任何矩阵都不改变它:$AI=IA=A$ - 几何直觉:A 把空间做了某种变换,$A^{-1}$ 就是吧这个变换撤销,还原回去 - 注意:不是所有方阵都有逆矩阵。如果矩阵把空间"压扁"了(比如把三维压成二维),就无法恢复,这样的矩阵不可逆 - 在 LLM 里,矩阵是怎么用的 - Transformer 输入是一个序列,比如 4 个 token,每个 token 用 8 维向量表示,整体表示成矩阵 X,形状(4x8) - 要生成 Query、Key、Value,分别乘以三个权重矩阵 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509004625263.png,279,31) - 这三个矩阵乘法,就是在把输入向量投影到三个不同的子空间,分别用于"我在找什么"(Q)、"我有什么"(K)、"我的内容是什么"(V)。 - 注意力分数:$score=QK^T$ - Q 是 $4\times d_k$,$K^T$ 是 $d_k\times 4$,结果是 $4\times 4$ 的矩阵 - 结果是每个 token 和其他每个 token 的相关程度 - 整条公式 $QK^T$ 的每一个元素,就是一对 Query 和 Key 向量的点积 - Numpy 实战 - ```python import numpy as np # ─── 1. 矩阵与向量的乘法 ────────────────────────────── A = np.array([[1, 2], [3, 4], [5, 6]]) # 3×2 矩阵 x = np.array([1, -1]) # 2 维向量 result = A @ x # @ 是矩阵乘法运算符 print("A @ x =", result) # 应得 [-1, -1, -1] # ─── 2. 矩阵乘法 ────────────────────────────────────── B = np.array([[1, 2], [3, 4]]) C = np.array([[5, 6], [7, 8]]) print("\nB @ C =\n", B @ C) print("C @ B =\n", C @ B) print("交换律不成立:", np.allclose(B @ C, C @ B)) # False # ─── 3. 转置 ────────────────────────────────────────── M = np.array([[1, 2, 3], [4, 5, 6]]) print("\n原矩阵 shape:", M.shape) # (2, 3) print("转置后 shape:", M.T.shape) # (3, 2) print("转置:\n", M.T) # ─── 4. 模拟 Attention 里的 QK^T ────────────────────── np.random.seed(0) seq_len = 4 # 4 个 token d_model = 8 # 每个 token 8 维 d_k = 4 # Query/Key 的维度 # 输入序列矩阵:4 个 token,每个 8 维 X = np.random.randn(seq_len, d_model) # 权重矩阵(实际中是训练得到的) W_Q = np.random.randn(d_model, d_k) W_K = np.random.randn(d_model, d_k) # 计算 Q 和 K Q = X @ W_Q # shape: (4, 4) K = X @ W_K # shape: (4, 4) # 计算注意力分数矩阵 scores = Q @ K.T # shape: (4, 4) print("\nQ shape:", Q.shape) print("K^T shape:", K.T.shape) print("注意力分数矩阵 shape:", scores.shape) print("注意力分数矩阵:\n", scores.round(2)) # 每个元素 scores[i][j] 就是第 i 个 token 对第 j 个 token 的注意力分数 print("\ntoken 0 对所有 token 的注意力分数:", scores[0].round(2)) ``` 线性变换的几何直觉 - 线性变换的几何直觉 - 核心洞察:矩阵的列=基向量的去向 - 什么是基向量 - 二维平面最自然的一组基向量 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509005936990.png,141,61) - 任何 2D 向量都可以写成基向量的组合 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509005955004.png,108,54) - 矩阵的读法 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509010125456.png,111,61) - $\hat{i}$ 经过 A 变换后,落在 $\begin{bmatrix} 2 \\ 1 \end{bmatrix}$ - $\hat{j}$ 经过 A 变换后,落在 $\begin{bmatrix} -1 \\ 3 \end{bmatrix}$ - 线性变换有一个神奇的性质:它保留了向量加法和数乘。 - 只要你知道基向量被变到哪里,整个空间所有向量的去向就都确定了 - 这就是矩阵能用一组数字描述整个变换的原因 - 矩阵×向量,本质是用向量的分量作为系数,对矩阵的列做线性组合 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509010714977.png,244,59) - 几种常见的线性变换 - 缩放 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509152812843.png,61,60) - $\hat{i}$ 拉到 [2,0], $\hat{j}$ 拉到 [0,2],整个空间被均匀放大 2 倍 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509152901112.png,57,59) - 不均匀缩放,横向拉伸 3 倍,纵向不变。 - 旋转 - 逆时针旋转角度 $\theta$ - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509153055957.png,164,55) - 错切 (Shear) - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509153129655.png,59,55) - $\hat{i}$ 不动,$\hat{j}$ 从 [0,1] 移动到 [1,1]。整个空间像被协推的扑克牌 - 投影 (Projection) - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509153234697.png,58,60) - $\hat{i}$ 不动,$\hat{j}$ 压扁到原点,整个 2D 平面被投影到 $x$ 轴,降了一维 - 这个变换是不可逆的,一旦把平面压扁成一条线,无法恢复 - 反射 (Reflection) - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509153344443.png,74,57) - $\hat{i}$ 翻到 [-1,0],整个空间沿 y 轴镜像翻转 - 行列式:变换的缩放因子 - 行列式 $det(A)$ 是一个数 - 这个变换把单位面积或体积放大缩小了多少倍 - 几何意义 - $\hat{i}$ 和 $\hat{j}$ 围成的单位正方形,面积是 1 - 变换后,这两个向量会围成一个平行四边形,这个平行四边形的面积就是 $|det(A)|$ - 二阶行列式公式 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509153655269.png,164,60) - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509153803344.png,408,167) - det(A) = 0 -> 矩阵不可逆 -> 变换降低了维度 - 秩 (Rank):变换后的输出维度 - 秩 (rank(A)) 是另外一个数 - 回答:变换后,所有向量落到的空间有几维 - 直观理解 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509154254876.png,93,55) - [2,4] = 2x[1,2],两列共线,无论 $\hat{i}$ 和 $\hat{j}$ 落到哪里,它们都在一条直线上 - 整个 2d 平面被压成了一条 1D 直线,rank(A) = 1 - 如果两列线性无关(不共线),秩为 2,变换后仍然是 2D 平面,满秩 - 满秩 vs 不满秩 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509155152785.png,531,126) - 秩的另一种表述 - rank(A) = A 的列向量中线性无关的最大个数 - 也等于行向量中线性无关的最大个数,行秩=列秩 - 线性相关与无关 - 一组向量是线性相关的,意味着其中某个向量可以由其他向量的线性组合得到 - n 个线性无关的向量,才能"撑起"一个 n 维空间 - 如果你有 100 个向量,但它们都共线(线性相关),实际上只描述了一条 1D 直线 - 连接到 LLM - 为什么 LLM 用高维向量 - GPT-3 用 12288 维的词向量 - 维度越高,能容纳的"线性无关方向"越多,理论上能编码越丰富的语义特征 - 情感、词性、领域、时态、语气……每个特征可以是一个独立的方向。 - 低秩的危险 - 如果训练出的某个权重矩阵秩很低,意味着它实际上只在少数几个方向上有效,浪费了表达能力 - 这是"模型坍缩"的一种数学表现 - LoRA 的精妙之处 - LoRA(Low-Rank Adaptation)微调的核心思想:微调时新增的参数变化矩阵 $\delta W$ 通常是低秩的 - 如果 $\delta W$ 是 1024x1024 的矩阵,参数量是约 100 万。但如果它的秩只有 8,可以分解成:$\delta W = A\cdot B$ - 其中 A 是 1024 x 8,B 是 8 x 1024,参数量降到约 1.6 万 - Attention 的几何意义 - $Q=XW_Q$,这是在用矩阵 $W_Q$ 把输入向量变换到 Query 空间 - $W_Q$ 的秩决定了 Query 空间的自由度—能从输入里提取多少个独立的"问题"。 - 可视化代码 - ```python import numpy as np import matplotlib.pyplot as plt def plot_transformation(matrix, title): """可视化一个 2x2 矩阵的变换效果""" # 原始基向量 i_hat = np.array([1, 0]) j_hat = np.array([0, 1]) # 变换后 i_new = matrix @ i_hat j_new = matrix @ j_hat # 画一个网格点 x = np.linspace(-2, 2, 9) y = np.linspace(-2, 2, 9) X, Y = np.meshgrid(x, y) points = np.stack([X.ravel(), Y.ravel()]) transformed = matrix @ points fig, axes = plt.subplots(1, 2, figsize=(10, 5)) # 原空间 axes[0].scatter(points[0], points[1], c='lightblue', s=10) axes[0].arrow(0, 0, *i_hat, head_width=0.1, color='red', label='i_hat') axes[0].arrow(0, 0, *j_hat, head_width=0.1, color='green', label='j_hat') axes[0].set_title("变换前") axes[0].set_xlim(-3, 3); axes[0].set_ylim(-3, 3) axes[0].grid(True); axes[0].axhline(0); axes[0].axvline(0) axes[0].set_aspect('equal') # 变换后空间 axes[1].scatter(transformed[0], transformed[1], c='lightcoral', s=10) axes[1].arrow(0, 0, *i_new, head_width=0.1, color='red') axes[1].arrow(0, 0, *j_new, head_width=0.1, color='green') axes[1].set_title(f"变换后\ndet={np.linalg.det(matrix):.2f}, " f"rank={np.linalg.matrix_rank(matrix)}") axes[1].set_xlim(-5, 5); axes[1].set_ylim(-5, 5) axes[1].grid(True); axes[1].axhline(0); axes[1].axvline(0) axes[1].set_aspect('equal') plt.suptitle(title); plt.tight_layout(); plt.show() # ─── 试试不同的变换 ─────────────────────────────── # 1. 缩放 plot_transformation(np.array([[2, 0], [0, 1.5]]), "缩放:x 方向 2 倍,y 方向 1.5 倍") # 2. 旋转 45 度 theta = np.pi / 4 plot_transformation( np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]), "旋转 45 度" ) # 3. 错切 plot_transformation(np.array([[1, 1], [0, 1]]), "错切") # 4. 投影到 x 轴(注意 det=0, rank=1) plot_transformation(np.array([[1, 0], [0, 0]]), "投影到 x 轴(降维!)") # 5. 反射 plot_transformation(np.array([[-1, 0], [0, 1]]), "沿 y 轴反射") ``` 特征值与特征向量 - 特征值与特征向量 - 变换中不变的方向 - 一个矩阵作用于空间,所有向量都被旋转、拉伸、扭曲。绝大多数向量变换后,方向都改变了 - 但有些特殊的向量——它们经过变换后,方向不变,只是被拉长或缩短 - 这种"在变换中保持方向"的向量,就叫做特征向量(eigenvector)。它被拉伸的倍数,叫做特征值(eigenvalue) - 形式化定义 - 特征值方程 - $A\vec{v}=\lambda\vec{v}$ - 矩阵 A 作用在向量 $\vec{v}$ 上,结果等于把 $\vec{v}$ 缩放 $\lamda$ 倍 - $\lamda$ 是特征值(一个标量,可以是正、负、零,甚至复数) - 几何含义 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509211904890.png,438,253) - 关键洞察:特征向量给出的是矩阵变换的"主轴"。沿着这些主轴,复杂的矩阵变换简化成了简单的"拉伸" - 怎么求特征值 - 推导 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509212329174.png,460,246) - 行列式为 0 意味着矩阵把空间压扁了,存在一些非零向量被压成了零向量——那些被压扁的方向就是特征方向 - 实际计算 - 求特征值 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509213017060.png,589,239) - 求特征向量 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509213047640.png,502,350) - 特征分解 - 如果 $n\times n$ 矩阵 A 有 n 个线性无关的特征向量,可以写成 $A=PDP^{-1}$ - 公式解析 - $P$ 是把特征向量按列排起来的矩阵 - $D$ 是对角矩阵,对角线上是对应的特征值 - $P^{-1}$ 是 $P$ 的逆矩阵 - 几何含义 - 任何复杂的线性变换 A,都可以分解成三步简单操作: - $P^{-1}$: 把空间转一下,让特征方向对齐到坐标轴 - $D$: 沿坐标轴各方向独立缩放(因为 D 是对角矩阵) - $P$: 把空间转回来 - 整个复杂变换,本质上就是沿着特征方向的简单缩放 - 矩阵的 n 次幂 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/09/20260509213619982.png,250,40) - 计算量从 100 次矩阵乘法降到 n 次标量幂运算 - 这是 PageRank、马尔可夫链稳态分析的核心计算技巧 - PCA:特征值的经典应用 - PCA(主成分分析,Principal Component Analysis)是降维最常用的算法。它的数学本质就是特征分解 - 问题背景 - 假设你有 1000 个数据点,每个是 768 维向量 - 可视化、分析都很困难 - 能不能找到 2 个最重要的"方向",把数据投影到这两个方向上,保留尽可能多的信息 - PCA 的答案:找数据协方差矩阵的特征向量,按特征值大小排序,取前 k 个 - 为什么有效 - 协方差矩阵 C 描述了数据在各维度的"散布情况" - 它的特征向量给出了数据散布最大的方向——这些就是"主成分" - 特征值越大,说明数据沿那个方向变化越剧烈,包含的信息越多 - 如果你的 1000 个数据点几乎都集中在一条直线附近 - 那条直线就是第一主成分(最大特征值对应的特征向量) - 用它一个维度就能描述大部分信息 - PCA 的步骤 - 把数据矩阵 X 中心化:每一列减去该列均值 - 计算协方差矩阵:$C=\frac 1{n-1}X^TX$ - 对 C 做特征分解:$C=PDP^{-1}$ - 选 D 中最大的 k 个特征值对应的特征向量,组成投影矩阵 W - 降维后的数据: $X_{new}=XW$ - 连接到 LLM - 词嵌入的可视化 - GPT 的 768 维词向量没法直接看。 - 用 PCA 把它降到 2D 或 3D,就能在散点图上观察 - "国王""女王""公主"这些词是否聚在一起? - 这是分析模型语义的常用手段。 - 模型权重分析 - Transformer 的注意力矩阵分析中,研究者会看注意力权重矩阵的特征值分布 - 如果特征值过于集中(少数几个特征值很大,其他都很小) - 说明模型在过度关注某些方向,可能存在退化现象。 - RoPE 位置编码的内在结构 - 旋转位置编码(RoPE)本质上是用一组旋转矩阵作用在 Query 和 Key 上 - 这些旋转矩阵的特征值(在复数域)正是 $e^{i\theta}$,对应频率的位置信息 - 模型压缩的根基 - 特征分解的更一般形式 SVD是各种模型压缩、剪枝、低秩近似的数学基础 - Numpy 代码实现 - ```python import numpy as np import matplotlib.pyplot as plt # ─── 1. 求特征值和特征向量 ──────────────────────────── A = np.array([[3, 1], [0, 2]], dtype=float) eigenvalues, eigenvectors = np.linalg.eig(A) print("特征值:", eigenvalues) # [3., 2.] print("特征向量(按列):\n", eigenvectors) # 验证 A v = λ v v0 = eigenvectors[:, 0] # 第一个特征向量 λ0 = eigenvalues[0] print("\nA @ v0 =", A @ v0) print("λ0 * v0 =", λ0 * v0) print("两者相等:", np.allclose(A @ v0, λ0 * v0)) # ─── 2. 验证特征分解 A = P D P^(-1) ──────────────── P = eigenvectors D = np.diag(eigenvalues) A_reconstructed = P @ D @ np.linalg.inv(P) print("\n重构 A:\n", A_reconstructed) print("与原 A 相等:", np.allclose(A, A_reconstructed)) # ─── 3. 用特征分解快速算 A^10 ────────────────────── A10_naive = np.linalg.matrix_power(A, 10) A10_eigen = P @ np.diag(eigenvalues**10) @ np.linalg.inv(P) print("\n两种方法算 A^10 是否一致:", np.allclose(A10_naive, A10_eigen)) # ─── 4. 手写 PCA 并可视化 ─────────────────────────── np.random.seed(42) # 生成一些 2D 数据:长椭圆形分布 n = 200 mean = [0, 0] cov = [[3, 2], [2, 2]] data = np.random.multivariate_normal(mean, cov, n) # Step 1: 中心化 data_centered = data - data.mean(axis=0) # Step 2: 协方差矩阵 C = (data_centered.T @ data_centered) / (n - 1) # Step 3: 特征分解 eigvals, eigvecs = np.linalg.eigh(C) # eigh 用于对称矩阵,更稳定 # Step 4: 按特征值从大到小排序 idx = np.argsort(eigvals)[::-1] eigvals = eigvals[idx] eigvecs = eigvecs[:, idx] print("\n协方差矩阵的特征值:", eigvals) print("第一主成分(最大特征值方向):", eigvecs[:, 0]) print("第二主成分:", eigvecs[:, 1]) # 可视化:原数据 + 两个主成分方向 plt.figure(figsize=(8, 8)) plt.scatter(data[:, 0], data[:, 1], alpha=0.5, label='数据') # 画两个主成分方向(用特征值缩放表示重要程度) origin = data.mean(axis=0) for i, (val, vec) in enumerate(zip(eigvals, eigvecs.T)): plt.arrow(*origin, *(vec * np.sqrt(val) * 2), head_width=0.15, color=['red', 'green'][i], label=f'PC{i+1} (λ={val:.2f})', linewidth=2) plt.axis('equal') plt.grid(True) plt.legend() plt.title("PCA:特征向量指出数据散布最大的方向") plt.show() # ─── 5. 降维:把 2D 数据投影到 1D ───────────────── # 只用第一主成分 W = eigvecs[:, 0:1] # shape (2, 1) data_1d = data_centered @ W print(f"\n降维前 shape: {data.shape}") print(f"降维后 shape: {data_1d.shape}") # 计算保留的"信息比例" info_kept = eigvals[0] / eigvals.sum() print(f"用 1 维保留了 {info_kept:.1%} 的信息") ``` SVD (奇异值分解) - SVD (奇异值分解) - 为什么需要 SVD - 特征分解 $A = PDP^{-1}$ 有两个限制 - 只能用于方阵(行数=列数) - 不是所有的方阵都能分解(要求有 n 个线性无关的特征向量) - 任何 $m\times n$ 的矩阵都能做 SVD 分解,没有任何限制 - SVD 公式 - 对任意矩阵 $A$ ($m\times n$) $A=U\Sigma V^T$ - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/10/20260510154340941.png,429,164) - 奇异值通常按从大到小排列:$\sigma_1 \ge \sigma_2 \ge ... \ge \sigma _r \ge 0$, r 是矩阵的秩 - 几何解释 - 矩阵代表线性变换。SVD 说的是——任何线性变换,都可以分解成"旋转 → 缩放 → 旋转"三步 - 把向量 $\vec{x}$ 应用矩阵 $A$: $A\vec{x} = U\Sigma V^T\vec{x}$ - $V^T\vec{x}$: 对 $\vec{x}$ 做 一次旋转/反射 - $\Sigma(\cdot)$: 沿坐标轴各方向独立缩放(缩放倍数=奇异值) - $U(\cdot)$: 再做一次旋转/反射 - 与特征分解的对比 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/10/20260510154940144.png,461,207) - 奇异值的含义 - 衡量矩阵的重要方向 - 最大的奇异值 $\sigma_1$ 对应矩阵最"主要"的变换方向;后面的奇异值一次描述次要方向。 - 决定矩阵的秩 - 非零奇异值的个数 = 矩阵的秩 - 衡量矩阵的"信息含量" - 如果一个矩阵的奇异值快速衰减,说明矩阵的信息几乎全在前两个方向上,后面的方向可以安全丢弃 - SVD 与 LoRA - 问题背景 - 微调一个 7B 参数的 LLM,要更新所有参数代价极大 - LoRA 的观察:微调时的参数变化 $\Delta W$ 通常是低秩的——也就是说,虽然 $\Delta W$ 是个大矩阵,它真正有效的"主方向"很少 - LoRA 的做法 - 不直接学习 $\Delta W$,而是学习两个小矩阵 A 和 B $\Delta W \approx BA$ - 如果 $\Delta W$ 是 4096x4096,参数量是 1700 万 - 如果用 LoRA 设秩为 8,则 A 是 8x4096,B 是 4096x8,参数量约 6.5 万,减少 250 倍 - SVD 在 LLM 中的其他应用 - 词嵌入分析 - 对一个 $50000\times 768$ 的词嵌入矩阵做 SVD,看奇异值衰减情况,可以判断词嵌入空间的有效维度 - Attention 矩阵分析 - 研究 Transformer 注意力权重矩阵的奇异值分布,可以诊断模型是否出现"注意力坍缩"——所有注意力都集中在少数几个 token 上 - 模型压缩 - 把训练好的权重矩阵做 SVD,丢弃小奇异值,用低秩矩阵替代,可以压缩模型大小 - 推荐系统的根基 - 经典的协同过滤推荐算法,本质就是对"用户-物品评分矩阵"做 SVD 低秩近似 - NumPy 代码实战 - ```python import numpy as np import matplotlib.pyplot as plt # ─── 1. 基本 SVD 分解 ───────────────────────────────── np.random.seed(42) A = np.random.randn(5, 3) # 一个 5x3 的非方阵 U, sigma, VT = np.linalg.svd(A, full_matrices=False) print("A shape:", A.shape) print("U shape:", U.shape) # (5, 3) print("奇异值:", sigma) # 长度为 3 的数组 print("V^T shape:", VT.shape) # (3, 3) # 验证 A = U Σ V^T A_reconstructed = U @ np.diag(sigma) @ VT print("\n重构误差:", np.linalg.norm(A - A_reconstructed)) # ─── 2. 验证 U 和 V 是正交矩阵 ──────────────────────── print("\nU^T @ U =\n", (U.T @ U).round(4)) # 应近似为单位矩阵 print("\nV @ V^T =\n", (VT @ VT.T).round(4)) # 应近似为单位矩阵 # ─── 3. 低秩近似:用 SVD 压缩图像 ───────────────────── # 创建一个简单的"图像"(一个矩阵) np.random.seed(0) image = np.zeros((50, 50)) # 加几个明显的结构 image[10:20, 10:40] = 1 image[25:35, 15:35] = 0.7 image[40:48, 5:45] = 0.5 image += np.random.randn(50, 50) * 0.1 # 对图像做 SVD U, sigma, VT = np.linalg.svd(image) # 用不同 k 值重构 fig, axes = plt.subplots(1, 5, figsize=(15, 3)) axes[0].imshow(image, cmap='gray') axes[0].set_title(f"原图\n所有 50 个奇异值") axes[0].axis('off') for i, k in enumerate([1, 3, 10, 30]): image_k = U[:, :k] @ np.diag(sigma[:k]) @ VT[:k, :] axes[i+1].imshow(image_k, cmap='gray') info_kept = (sigma[:k]**2).sum() / (sigma**2).sum() axes[i+1].set_title(f"k={k}\n信息保留 {info_kept:.1%}") axes[i+1].axis('off') plt.suptitle("SVD 低秩近似:用前 k 个奇异值还原矩阵") plt.tight_layout() plt.show() # ─── 4. 奇异值衰减图 ────────────────────────────────── plt.figure(figsize=(8, 4)) plt.plot(sigma, 'o-') plt.yscale('log') plt.xlabel('奇异值序号') plt.ylabel('奇异值大小(对数尺度)') plt.title('奇异值衰减情况') plt.grid(True) plt.show() # ─── 5. 模拟 LoRA:用低秩分解近似一个权重矩阵 ─────── # 假设原始权重矩阵 W = np.random.randn(1024, 1024) * 0.01 # 假设这是"微调后的变化"——故意构造成低秩的 np.random.seed(1) B_true = np.random.randn(1024, 8) A_true = np.random.randn(8, 1024) delta_W_true = B_true @ A_true # 真实秩为 8 的变化 # 用 SVD 提取最佳秩-8 近似 U, sigma, VT = np.linalg.svd(delta_W_true) k = 8 delta_W_approx = U[:, :k] @ np.diag(sigma[:k]) @ VT[:k, :] print("\n--- LoRA 模拟 ---") print(f"原始 ΔW 参数量: {1024 * 1024:,}") print(f"LoRA 形式 (B + A) 参数量: {1024 * k + k * 1024:,}") print(f"压缩比: {1024 * 1024 / (1024 * k + k * 1024):.1f}x") print(f"近似误差: {np.linalg.norm(delta_W_true - delta_W_approx):.6f}") ``` - SVD vs 特征分解 vs PCA 总结 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/10/20260510161623378.png,546,158) - 有趣的关系 - 对对称正定矩阵,特征分解和 SVD 等价 - PCA 可以通过对中心化数据矩阵 X 直接做 SVD 实现,比先算协方差矩阵更稳定

五月 5, 2026

AIInfra 学习

GPU 体系结构 + CUDA 入门 + Profiling AIInfra 全景 + 学习内容 - AIInfra 全景 & 学习内容 - 理论部分 - AIInfra 是什么 - AI Infra 不是一个单一的东西,而是一整套支撑「让模型在合适的硬件上、以合适的成本、稳定地训练和服务用户」的技术栈 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/10/20260510163128065.png,726,300) - 一条 prompt 的完整生命周期 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/10/Clipboard_Screenshot_1778404995.png,500,400) - 训练 vs 推理的关键差异 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/10/20260510180216416.png,655,286) - 动手部分 - 环境检查清单 - ```bash # 1. 操作系统 uname -a # 期望 Linux x86_64,推荐 Ubuntu 22.04 cat /etc/os-release # 2. GPU & 驱动 nvidia-smi # 看到 GPU 型号、驱动版本、CUDA 版本 nvidia-smi topo -m # 看 GPU 间互联拓扑(NVLink/PCIe) # 3. CUDA Toolkit nvcc --version # 没装就先装,建议 12.x # 4. Python 环境(推荐 uv 或 conda) python --version # 3.10 / 3.11 都可 pip --version ``` - 装 PyTorch + transformers - ```bash # 用 conda 建一个干净环境 conda create -n aiinfra python=3.10 -y conda activate aiinfra # PyTorch(按你的 CUDA 版本选,下面以 CUDA 12.1 为例) pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # 推理常用库 pip install transformers accelerate sentencepiece ``` - 验证 ```python # check.py import torch print("torch:", torch.__version__) print("cuda available:", torch.cuda.is_available()) print("device count:", torch.cuda.device_count()) print("device name:", torch.cuda.get_device_name(0)) ``` - 跑通第一个 LLM 推理 - 选一个小模型(千万别第一次就拉 70B),比如 Qwen2.5-0.5B-Instruct 或 TinyLlama-1.1B: - ```python # first_infer.py import time, torch from transformers import AutoTokenizer, AutoModelForCausalLM model_id = "Qwen/Qwen2.5-0.5B-Instruct" # 国内可换镜像 tok = AutoTokenizer.from_pretrained(model_id) model = AutoModelForCausalLM.from_pretrained( model_id, torch_dtype=torch.float16, device_map="cuda" ) prompt = "用一句话解释什么是 KV Cache。" inputs = tok(prompt, return_tensors="pt").to("cuda") torch.cuda.synchronize() t0 = time.time() out = model.generate(**inputs, max_new_tokens=128, do_sample=False) torch.cuda.synchronize() t1 = time.time() print(tok.decode(out[0], skip_special_tokens=True)) print(f"\n耗时 {t1-t0:.2f}s, 生成 {out.shape[1]-inputs.input_ids.shape[1]} tokens") ``` - 监控 ```bash watch -n 0.5 nvidia-smi # 观察显存占用、SM 利用率 ``` Linux 容器回顾 - Linux/容器基础回顾 - 理论部分 - Linux 进程隔离三件套 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/10/20260510201727118.png,716,170) - 需要记住的几个 namespace:pid、net、mnt、uts、ipc、user - GPU 不在 namespace 隔离范围内 —— 这就是为什么需要 nvidia-container-toolkit - NUMA、CPU 亲和性、与 GPU 的关系 - 一台 8 卡 GPU 服务器,CPU 和 GPU 之间的距离不是均等的 - ``` [ NUMA Node 0 ] [ NUMA Node 1 ] CPU0–47 CPU48–95 ├─ GPU0 (PCIe) ├─ GPU4 ├─ GPU1 ├─ GPU5 ├─ GPU2 ├─ GPU6 └─ GPU3 └─ GPU7 ``` - 如果你的数据加载进程在 NUMA 0,但用的是 GPU 4,每条数据都要跨 NUMA 走 UPI,吞吐立即掉一截 - ```bash numactl --hardware # 看 NUMA 拓扑 numactl --cpunodebind=0 --membind=0 python train.py # 绑到 NUMA 0 taskset -c 0-15 python ... # 绑到具体 CPU 核 nvidia-smi topo -m # 看 GPU 与 CPU 的拓扑距离 (PIX/PHB/NODE/SYS) ``` - 训练任务的 dataloader worker 必须和它要喂的 GPU 在同一个 NUMA node 上 - 容器与 GPU:为什么需要 nvidia-container-toolkit - 普通容器只能隔离 CPU/内存/网络,看不到 GPU 设备 - 驱动在宿主机,CUDA Toolkit 在容器里 - 宿主机驱动版本必须 ≥ 容器里 CUDA 编译要求的最低版本 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/10/20260510203843759.png,585,612) - 动手部分 - 操作 namespace 和 cgroup - 直观感受「容器不过是一组 namespace + cgroup 的进程」 - ``` # 1. 用 unshare 起一个独立 PID namespace 的 shell sudo unshare --pid --fork --mount-proc bash ps aux # 只看到几个进程!这就是 PID namespace exit # 2. 看自己进程的 namespace ls -l /proc/self/ns/ # 3. cgroup v2:看当前 shell 的资源限制 cat /proc/self/cgroup cat /sys/fs/cgroup/memory.max 2>/dev/null || echo "no limit" ``` - 安装 nvidia-container-toolkit - ```bash distribution=$(. /etc/os-release; echo $ID$VERSION_ID) curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \ | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list \ | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \ | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt-get update sudo apt-get install -y nvidia-container-toolkit sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker ``` - 验证 ```bash docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi ``` - 写自己的 AI Infra 开发镜像 - ```dockerfile # 基础镜像:CUDA 12.4 + cuDNN + Ubuntu 22.04 FROM nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04 ENV DEBIAN_FRONTEND=noninteractive \ LANG=C.UTF-8 \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 # 系统依赖 RUN apt-get update && apt-get install -y --no-install-recommends \ python3.10 python3-pip python3.10-venv \ git curl wget vim numactl htop \ build-essential ninja-build \ && rm -rf /var/lib/apt/lists/* RUN ln -sf /usr/bin/python3.10 /usr/bin/python && \ ln -sf /usr/bin/pip3 /usr/bin/pip # Python 依赖 RUN pip install --no-cache-dir \ torch==2.4.0 torchvision \ --index-url https://download.pytorch.org/whl/cu124 RUN pip install --no-cache-dir \ transformers accelerate sentencepiece \ jupyterlab ipython \ nvitop py-spy WORKDIR /workspace CMD ["bash"] ``` - 构建 + 运行 ```bash docker build -t aiinfra-dev:0.1 . # 跑起来,挂载工作目录、暴露 jupyter 端口 docker run --rm -it \ --gpus all \ --shm-size=8g \ -v $PWD:/workspace \ -p 8888:8888 \ aiinfra-dev:0.1 ``` - NUMA 绑定 - 多卡机器 ```bash # 先看拓扑 nvidia-smi topo -m numactl --hardware # 把推理脚本绑到 GPU0 同 NUMA 的 CPU 上 CUDA_VISIBLE_DEVICES=0 numactl --cpunodebind=0 --membind=0 \ python first_infer.py ``` GPU 硬件与体系结构 - GPU 硬件与体系结构 - 理论部分 - 一张图看懂 GPU - 以 NVIDIA H100 (Hopper) 为例 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/11/20260511002451179.png,756,565) - H100 一共有 132 个 SM(消费卡 4090 是 128 SM,A100 是 108 SM) - SM 是 GPU 的核,所有的 CUDA kernel 都在 SM 上执行 - 算力:FP16/BF16 Tensor Core ≈ 989 TFLOPS,FP8 ≈ 1979 TFLOPS - 显存带宽:HBM3 ≈ 3 TB/s - L2 Cache:50 MB(A100 是 40MB) - NVLink:单卡对外 900 GB/s(A100 600 GB/s,4090 没 NVLink) - SM 内部 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/11/20260511003227058.png,561,620) - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/11/20260511003301355.png,686,280) - 关键洞察 - Warp Divergence:一个 warp 里 32 个线程如果走不同分支(if/else),GPU 会 顺序执行两条路径,性能直接腰斩。这就是为什么 GPU 不擅长复杂控制流 - Tensor Core 是深度学习的命门 - CUDA Core 一条指令算 1 个 FMA(乘加) - Tensor Core 一条指令算 数百个 FMA - 所以 H100 标称的 989 TFLOPS 几乎全来自 Tensor Core,CUDA Core 只有 ~67 TFLOPS - 如果你的 kernel 没用上 Tensor Core,就只用了 GPU 7% 的算力 - 显存层级:从 Register 到 HBM - GPU 是带宽为王的设备 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/05/11/20260511003449699.png,713,234) - 核心结论 - 访问 HBM 比访问 Register 慢 500 倍 - 所以高性能 kernel 的核心套路就是:把数据从 HBM 搬到 Shared Memory,重复使用 - 这正是 FlashAttention 的核心思想 -

五月 5, 2026

钉钉天元 AI 实践

客户情报 + 销售助理

三月 18, 2026

ChromeAI 安装

实验元数据 (Meta Data) 实验编号/标题:ChromeAI 安装 ...

三月 17, 2026

LLM 复习

预备知识 - 预备知识 - 线性代数 - 向量与矩阵乘法 - 向量与向量乘法 - 内积 - 计算:对应元素相乘再相加,结果是一个标量 - $a\cdot b=\sum_{i=1}^n a_ib_i$ - 几何意义:衡量两个向量的相似度 - 如果内积为 0,向量正交 - 内积也可以表示为 $||a||||b||cos(\theta)$,即 a 在 b 方向上的投影长度乘以 b 的长度 - 外积 - 计算:一个列向量乘以一个行向量,结果是一个矩阵 - 意义:构造一个秩为 1 的矩阵。在 SVD 中,复杂的举证就是由多个这样的秩 1 矩阵加权累加的 - 列空间 - 定义 - 想象矩阵 A 的每一列都是一个导航箭头(向量) - 如果 A 有两列 a1,a2,那么这两根箭头张开所能到达的所有地方,就是一个平面 - 这个平面就是矩阵 A 的列空间 - 列空间就是利用矩阵里的列向量,通过加减、缩放所能拼凑出的所有可能的结果向量的集合 - 矩阵与向量的乘法 - 假设有矩阵 A 和向量 x - 线性组合 - 矩阵 A 乘以向量 x,等价于将 A 的列向量按照 x 中的元素进行加权求和 - 结果向量 b 必然落在矩阵 A 的列空间内 - 线性变换 - 将矩阵 A 看作一个函数或算子,它把输入向量 x 旋转、伸缩或投影到了一个新的位置 - 特征值/特征向量的学习,本质就是在寻找这个变换中方向不变的特殊向量 - 矩阵与向量的乘法 - 行乘列(传统定义) - C 中第 i 行第 j 列的元素,是 A 的第 i 行与 B 的第 j 列的内积 - 列变换视角 - 把 B 看作一组列向量[b1,b2,...,bn],那么 AB 的结果就是[Ab1,Ab2,...,Abn] - 意义:矩阵 A 同时对 B 的每一列进行了相同的线性变换 - 分块矩阵乘法 - 将大矩阵划分为子矩阵进行运算 - 是计算机高性能计算和处理大数据时的核心原理 - 关键运算性质 - 不满足交换律:一般情况下 AB!=BA,矩阵乘法的顺序至关重要 - 满足结合律:A(BC)=(AB)C,意味着在计算长链乘法时,可以通过改变计算顺序来优化计算量 - 转置性质:$(AB)^T=B^TA^T$ - 范数 - 定义:范数是一个将向量映射到非负实数的函数,直观可以理解为衡量向量的大小或长度 - 没有范数,无法定义距离,也无法优化模型 - 性质 - 非负性:||x||>=0,且只有当 x 是零向量时,范数才是 0 - 齐次性:$||kx||=|k|\cdot ||x||$,向量放大 k 倍,长度也放大 k 倍 - 三角不等式:||x+y||<=||x||+||y||,两边之和大于第三边 - 常见的向量范数 - 公式 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/02/22/20260222152155557.png,192,81) - L1 范数 - 计算:所有元素绝对值之和。$||x||_1=\sum|x_i|$ - 几何:只能沿格子线走 - 特性:会倾向于让向量中的许多元素变为 0,从而产生稀疏性 - 应用:L1正则化,用于特征选择,剔除不重要的变量 - L2 范数 - 计算:元素平方和再开方。$||x||_2=\sqrt{\sum x_i^2}$ - 几何:计算两点之间的直线距离(最直观的距离) - 特性:对大数值非常敏感,处处可导,计算方便 - 应用:L2 正则化,防止模型过拟合;深度学习中的权重衰减。 - $L\infty$ 范数 - 计算:向量中绝对值最大的那个元素的值 - 应用:用于衡量最坏情况下的误差 - 矩阵范数 - Frobenius 范数 - 计算:把矩阵看成一个大向量,所有元素的平方和再开方 - 用途:衡量两个矩阵之间的距离,用于矩阵分解(SVD 或推荐系统)的损失函数。 - 基 - 定义 - 在向量空间里,基就是坐标系 - 在二维平面上,习惯用 x 轴 (1,0) 和 y 轴(0,1) 作为基。 - 任何一个点 (3,4) 都可以看作是:在 x 轴方向走 3 步,在 y 轴方向走 4 步。 - 基决定了观察和描述向量的视角。 - 特征值与特征向量 - 定义 - 对于一个方阵 Ai,如果存在一个非零向量 v 和一个标量 $\lambda$,满足如下等式 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/02/22/20260222172925249.png,88,37) - 那么 v 就是特征向量,$\lambda$ 就是对应的特征值 - 特征值分解 - 如果一个 nxn 矩阵 A 有 n 个线性无关的特征向量,它可以被分解为 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/02/22/20260222173125585.png,119,42) - Q:由特征向量组成的矩阵 - $\Lambda$ (Lambda):对角矩阵,对角线上是对应的特征值 - 奇异值分解 - 数学定义 - 对于任何 m*n 的矩阵 A,都可以分解为 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/02/22/20260222153210370.png,107,40) - U(m x n 阶):左奇异值向量矩阵,它是正交矩阵(各列互相垂直且长度为 1),代表了变换后的输出空间的基。 - $\sum$ (m x n 阶):奇异值矩阵,只有对角线有值,称为奇异值($\sigma_1,\sigma_2, \dots$$),按从小到大排列,代表了每个方向上的权重或重要性。 - $V^T$ (n x n 阶):右奇异向量矩阵的转置,也是正交矩阵,代表了输入空间的基。 - 几何直观 - 如果把矩阵 A 看作一个变换,SVD 告诉我们这个变换可以拆为 3 步: - $V^T$(旋转):将输入向量旋转到特定的方向,使其与奇异向量对齐。 - $\sum$(缩放):在这些特定的方向上进行拉伸或压缩,奇异值越大,拉伸幅度越大。 - U (旋转):再次旋转,将结果映射到最终的输出空间。 - 概率统计 - 最大似然 - 有一组数据 $D={x_i}^n_{i=1}$,选择了一个参数化模型 p(x|θ) - 似然:把数据当成已发生的事实,把 θ 当成变量,问在这个 θ 下,数据出现的可能性有多大 - 最大似然估计:选一个 $\hat\theta$ 让 L(θ) 最大

二月 22, 2026

概率统计

- 概率论 - 基础概念 - 概率 - 描述可能性的数值 - 随机变量 - 事件所有可能出现的状态 - 分类 - 离散型随机变量 - 连续型随机变量 - 概率分布 - 每个状态出现的可能性 - 举例 - 娱乐圈明星投资互联网公司 - 娱乐新闻 20% - 科技新闻 80% - 新闻类型-随机变量 x - 概率分布 P(x) - 娱乐新闻概率 60% - 科技新闻概率 20% - 体育新闻概率 20% - 联合概率 - 增加另外一个随机变量 y - 区分新闻属于国内还是国外 - 由 x 和 y 联合起来确定新的概率分布 - 用 P(x, y) 来表示 - 边缘概率 - 离散型随机变量 - 通过联合概率 P(x,y) 在 y 上求和,可以得到 P(x) - 连续型随机变量 - 通过联合概率 P(x,y) 在 y 上积分,得到 P(x) - P(x) 就是边缘概率 - 作用 - 我们只需要研究单个事件对概率分布的影响 - 边缘概率可以去除不需要关系的事件 - 忽略掉 y 事件 - 可以将联合概率转换为非联合概率 - 条件概率 - 举例 - 100 篇有 30 篇是国际新闻 - 30 篇有 5 篇是科技新闻 - 科技新闻出现国际新闻的概率 - 某个事件受其他事件影响后出现的概率 - 国际新闻中出现科技新闻的概率是 5/30 = 16.67% - 科技新闻中出现国际新闻的概率是 5/20 = 25% - 概率论研究的就是概率间互相转换的关系 - 概率和统计 - 概率对数据产生的过程进行建模,研究某种模型产生的数据有什么特性 - 统计是通过已知的数据,推导产生这些数据的模型是怎么样的 - 随机变量 - 没发生运算前,普通变量的值不会发生变化,取值确定后,就是一个固定的值 - 随机变量的值不固定,结果的不确定性,导致了随机变量取值的不确定性 - 离散型 - 抛硬币出现的正反、每周下雨的天数 - 可以直接求和得出 - 连续型 - 汽车每小时行驶的速度、银行排队的时间 - 必须用积分计算 - 概率分布 - 概率分布描述的是随机变量的概率规律 - 离散分布模型 - 伯努利分布 - 是单个随机变量的分布 - 取值只有两种 0 和 1 - 通过参数 λ 控制变量为 1 的概率 - $P(x=0)=1-\lambda\\P(x=1)=\lambda$ - $P(x)={\lambda}^x(1-\lambda)^{1-x}\space\space x\in\{0,1\}$ - 抛硬币属于伯努利分布 - 分类分布 - 描述了一个具有 k 个不同状态的单个随机变量 - k = 2 的时候,变为伯努利分布 - $P(x=k)={\lambda}_k$ - 连续分布模型 - 正态分布 - $\frac{1}{\sqrt{2\pi\sigma^2}} \exp\left(-\frac{(x - \mu)^2}{2\sigma^2}\right)$ - $\mu$ 是均值,$\sigma$ 是标准差 - ![](https://an-img.oss-cn-hangzhou.aliyuncs.com/2026/01/26/20260126204259715.png,160,120) - 越靠近中心点 $\mu$ 出现的概率越高 - 随着远离 $\mu$,出现的概率先加速下降,然后减速下降 - 蓝色区域代表的是这个区域的面积,也是数据取值在这个范围的概率 - 期望值 - 是每次随机结果出现概率乘以其结果的综合 - 是所以结果的加权平均值 - 使用期望值的两要素 - 这个问题可能出现不同的情况,各种情况的出现满足了一定的概率分布 - 每种情况都对应一个数值,这个数值代表了具体的应用含义 - 联合概率 - 由多个随机变量决定的概率是联合概率 - 概率分布就是联合概率分布 - x 和 y 的联合概率使用 P(x,y) 表示 - 边缘概率 - P(x,y) 对 y 求和或积分 - 条件概率 - 计算了给定某个随机变量下,另一个随机变量出现的概率 - 给定随机变量 x,随机变量 y 的条件概率用 P(y|x) 表示 - 贝叶斯定理 - $P(x,y)=P(x|y)\times P(y)\\P(y,x)=P(y|x)\times P(x)$ - $P(x|y)\times P(y)=P(x,y)=P(y,x)=P(y|x)\times P(x)\\P(x|y)=\frac{P(y|x)\times P(x)}{P(y)}$ - P(x) 是先验概率,因为它是从数据统计中得到的,不需要经过贝叶斯定理的推算 - P(y|x) 是给定 x 之后 y 出现的概率,在统计学中,也把 P(y|x) 写作似然函数 L(y|x) - P(x|y) 是通过贝叶斯定理推算而来,因此称为后验概率 - 核心思想是通过先验概率和条件概率估算后验概率 - A/B 测试 - 简介 - 为同一个目标指定两个或多个方案,让一部分用户使用 A 方案,另一部分用户使用 B 方案,记录下每个部分用户的使用情况,看哪个方案产生的结果更好 - 两组数据差异的原因 - 两个分布的差异 - 显著性差异 - 采样引起的差异 - 无显著性差异 - 显著性差异 - 研究多组数据之间的差异是由于不同的数据分布还是由于采样的误差导致 - 假设检验 - 虚无假设/原假设 (H0) - 事先对随机变量的参数或总体分布作出一个假设,然后利用样本信息判断这个假设是否合理 - 对立假设 (H1) - 和原假设对立,如果证明虚无假设不成立,那么可以推出对立假设 - 步骤 - 1. 认为原假设成立,计算其会导致什么结果 - 2. 如果单次实验出现了小概率事件,则拒绝原假设 H0,并接受对立假设 H1 - 3. 如果不会产生小概率事件,那么不能拒绝原假设 H0,从而接受它 - 小概率 - 把概率不超过 0.05 的事件称为小概率事件,记为 α,并称它为显著性水平 - 显著性检验 - 判断多组数据之间的差异,是采样导致的偶然,还是由于不同数据分布导致的必然 - 假设是多个数据分布之间没有差异 - 如果样本发生概率小于显著性水平,证明小概率事件发生了,拒绝原假设 - P 值 - P 值的 P 代表 Probability,就是当 H0 假设为真时,样本出现的概率 - 如果 P 值很小,说明观测值与假设 H0 的期望值有很大的偏离,H0 发生的概率很小 - 方差分析 (F 检验) - 检验两组或多组样本的均值是否具有显著性差异

八月 3, 2025