系列回顾:上一篇我们把概率基础打好了——随机变量、期望、方差、五种常见分布。这一篇深入一个更核心的概念:条件概率。语言模型的每一次预测,本质上就是在计算条件概率;贝叶斯定理告诉我们如何从已有证据出发更新信念。搞懂这两个概念,你就能真正理解语言模型在做什么,以及 DeepSeek R1 的训练为什么要用强化学习。
先说最重要的结论:
语言模型的本质,是一个条件概率计算器。
DeepSeek V3 生成文字时,每一步都在计算:
$$P(\text{下一个词} \mid \text{前面所有词})$$
给定"今天天气"这个上下文,下一个词是"很好"的概率是多少?是"不错"的概率是多少?是"糟糕"的概率是多少?
模型把这个条件概率估计得越准,生成的文字就越自然、越合理。
6710 亿个参数,14.8 万亿 token 的训练数据,服务于同一个目标:尽可能准确地估计这个条件概率。
这就是为什么条件概率是这整个系列里最重要的概念之一。
条件概率(Conditional Probability):在已知事件 $B$ 发生的前提下,事件 $A$ 发生的概率,记作 $P(A \mid B)$(读作"$A$ 在 $B$ 条件下的概率")。
$$P(A \mid B) = \frac{P(A \cap B)}{P(B)}, \quad P(B) > 0$$
分子是 $A$ 和 $B$ 同时发生的概率,分母是 $B$ 发生的概率。
条件概率的直觉是缩小样本空间。
原来的样本空间是 $\Omega$(所有可能结果)。知道 $B$ 发生了,样本空间缩小到 $B$(只考虑 $B$ 内部的结果)。在这个缩小的空间里,$A$ 发生的概率就是 $A \cap B$ 占 $B$ 的比例。
掷一枚公平骰子,$\Omega = \{1, 2, 3, 4, 5, 6\}$。
已知结果是偶数($B = \{2, 4, 6\}$),求结果大于 3 的概率($A = \{4, 5, 6\}$)。
不用条件概率公式,直接想:已知是偶数,样本空间缩小到 $\{2, 4, 6\}$,其中大于 3 的只有 $\{4, 6\}$,所以:
$$P(A \mid B) = \frac{2}{3}$$
用公式验证:$P(A \cap B) = P(\{4, 6\}) = \frac{2}{6} = \frac{1}{3}$,$P(B) = \frac{3}{6} = \frac{1}{2}$:
$$P(A \mid B) = \frac{1/3}{1/2} = \frac{2}{3} \checkmark$$
语言模型预测第 $t$ 个 token,给定前 $t-1$ 个 token:
$$P(x_t \mid x_1, x_2, \ldots, x_{t-1})$$
这是一个在极大"条件空间"下的条件概率:条件是前面所有词的完整序列,目标是 128K 个 token 上的概率分布。
DeepSeek V3 的 7168 维隐藏状态,就是对"前面所有词的信息"的压缩编码——它携带了计算这个条件概率所需的全部上下文信息。
由条件概率的定义,直接得到乘法公式:
$$P(A \cap B) = P(A \mid B) \cdot P(B) = P(B \mid A) \cdot P(A)$$
两件事同时发生的概率 = 一件事的概率 × 另一件事在第一件事已发生前提下的概率。
把乘法公式推广到多个事件:
$$P(A_1 \cap A_2 \cap \cdots \cap A_n) = P(A_1) \cdot P(A_2 \mid A_1) \cdot P(A_3 \mid A_1, A_2) \cdots P(A_n \mid A_1, \ldots, A_{n-1})$$
这个公式对任意分布都成立,没有独立性假设。
把链式法则用在一段文本序列 $x_1, x_2, \ldots, x_T$ 上:
$$P(x_1, x_2, \ldots, x_T) = P(x_1) \cdot P(x_2 \mid x_1) \cdot P(x_3 \mid x_1, x_2) \cdots P(x_T \mid x_1, \ldots, x_{T-1})$$
$$= \prod_{t=1}^T P(x_t \mid x_1, \ldots, x_{t-1})$$
这就是自回归语言模型(Autoregressive Language Model)的数学基础。
一段文本的概率,等于每个位置的条件概率的连乘积。GPT 系列、DeepSeek V3 都是自回归模型——每次预测一个 token,条件是前面所有已生成的 token。
训练目标(最大化数据对数似然)就是最大化这个乘积的对数:
$$\log P(x_1, \ldots, x_T) = \sum_{t=1}^T \log P(x_t \mid x_1, \ldots, x_{t-1})$$
最大化对数似然 = 最小化负对数似然(NLL)= 语言模型的训练损失,就是这么来的。
如果 $B_1, B_2, \ldots, B_n$ 是样本空间的一个划分(互斥且完备:$B_i \cap B_j = \emptyset$,$\bigcup_i B_i = \Omega$),那么对任意事件 $A$:
$$P(A) = \sum_{i=1}^n P(A \mid B_i) \cdot P(B_i)$$
直觉:把复杂情形按 $B_i$ 分类讨论,每类里算 $A$ 的概率,再按各类的先验概率加权平均。
一种疾病的患病率为 1%($P(\text{病}) = 0.01$)。
一种检测方法:患病者阳性率 99%,健康者阳性率 5%。
$$P(+ \mid \text{病}) = 0.99, \quad P(+ \mid \text{健康}) = 0.05$$
检测结果为阳性的总概率(全概率公式):
$$P(+) = P(+ \mid \text{病}) \cdot P(\text{病}) + P(+ \mid \text{健康}) \cdot P(\text{健康})$$
$$= 0.99 \times 0.01 + 0.05 \times 0.99 = 0.0099 + 0.0495 = 0.0594$$
DeepSeek V3 的 MoE 架构,每个 token 路由到不同的专家。整个模型对 token $x$ 的输出概率,可以用全概率公式理解:
$$P(\text{输出} \mid x) = \sum_{k=1}^{256} P(\text{输出} \mid x, \text{专家}=k) \cdot P(\text{专家}=k \mid x)$$
每个专家给出自己对输出的预测,门控网络给出路由到各专家的概率,最终输出是所有专家的加权混合。
贝叶斯定理(Bayes' Theorem)直接从条件概率的定义推出,只需要三行:
由乘法公式:$P(A \cap B) = P(A \mid B) \cdot P(B) = P(B \mid A) \cdot P(A)$
因此:$P(A \mid B) \cdot P(B) = P(B \mid A) \cdot P(A)$
两边除以 $P(B)$:
$$\boxed{P(A \mid B) = \frac{P(B \mid A) \cdot P(A)}{P(B)}}$$
就这么简单。但这个公式的威力是巨大的。
用机器学习的语言来理解公式里的每一项:
$$P(\theta \mid D) = \frac{P(D \mid \theta) \cdot P(\theta)}{P(D)}$$
后验 ∝ 似然 × 先验——贝叶斯学习就是用数据(似然)来更新先验信念,得到后验信念。
继续刚才的例子:检测结果为阳性,真正患病的概率是多少?
$$P(\text{病} \mid +) = \frac{P(+ \mid \text{病}) \cdot P(\text{病})}{P(+)} = \frac{0.99 \times 0.01}{0.0594} \approx 0.167$$
阳性结果下,只有 16.7% 的概率真的患病!
很多人直觉上会认为"99% 准确率的检测,阳性结果应该有 99% 的概率真的患病"。贝叶斯定理告诉我们这是错的——先验概率(患病率 1%)极大地压低了后验概率。
用自然频率理解更直觉:10000 人里,100 人患病(其中 99 人检测阳性),9900 人健康(其中 495 人假阳性)。阳性结果共 $99 + 495 = 594$ 人,真正患病的只有 99 人,比例 $99/594 \approx 16.7\%$。
贝叶斯定理最强大的地方在于:后验可以成为下一次的先验,不断用新证据更新信念。
$$\underbrace{P(\theta)}_{\text{初始先验}} \xrightarrow{\text{数据}D_1} \underbrace{P(\theta \mid D_1)}_{\text{后验1,成为新先验}} \xrightarrow{\text{数据}D_2} \underbrace{P(\theta \mid D_1, D_2)}_{\text{后验2}} \xrightarrow{\text{数据}D_3} \cdots$$
这正是神经网络训练的数学本质。
每处理一个 mini-batch,就是一次贝叶斯更新:用这批数据(似然信号)更新对模型参数($\theta$)的信念(后验)。DeepSeek V3 训练了 14.8 万亿 token,相当于做了海量次贝叶斯更新,把参数信念从随机初始化(弱先验)更新到能准确预测语言(强后验)。
两个事件 $A$ 和 $B$ 独立(Independent),当且仅当:
$$P(A \cap B) = P(A) \cdot P(B)$$
等价地,$P(A \mid B) = P(A)$——知道 $B$ 发生了,对 $A$ 的概率判断没有任何影响。
互斥(Mutually Exclusive):$A$ 和 $B$ 不能同时发生,$P(A \cap B) = 0$。
独立(Independent):知道 $B$ 发生,不影响对 $A$ 的判断,$P(A \mid B) = P(A)$。
两者完全不同。互斥的事件(只要两者都有正概率)反而是最不独立的——知道 $B$ 发生了,$A$ 必然没发生,$P(A \mid B) = 0 \neq P(A)$。
条件独立(Conditional Independence):在给定 $C$ 的条件下,$A$ 和 $B$ 独立:
$$P(A \cap B \mid C) = P(A \mid C) \cdot P(B \mid C)$$
等价地:$P(A \mid B, C) = P(A \mid C)$——已知 $C$,$B$ 对预测 $A$ 没有额外帮助。
条件独立比无条件独立更常见、更重要。很多看似相关的变量,在控制了某个共同原因之后,就条件独立了。
例子:同一篇文章里的两个词,边缘上是相关的(都和文章主题有关)。但给定文章主题(条件),两个词的出现就相对独立了——主题"解释"了它们之间的相关性。
朴素贝叶斯(Naive Bayes) 假设给定类别,所有特征条件独立:
$$P(x_1, x_2, \ldots, x_n \mid y) = \prod_{i=1}^n P(x_i \mid y)$$
这个假设极其强(通常不成立),但让模型大幅简化,参数量从指数级降到线性级。
Transformer(包括 DeepSeek V3)完全打破了这个假设:注意力机制让每个 token 的表示都依赖于序列中的所有其他 token,捕捉任意复杂的依赖关系。代价是计算量 $O(n^2)$(与序列长度的平方成正比),但换来了对语言结构的精确建模。
从贝叶斯角度,训练神经网络是在计算参数的后验分布:
$$P(\theta \mid D) \propto P(D \mid \theta) \cdot P(\theta)$$
最大后验估计(MAP) 找后验最大的参数:
$$\hat{\theta}_{MAP} = \arg\max_\theta \log P(\theta \mid D) = \arg\max_\theta [\log P(D \mid \theta) + \log P(\theta)]$$
第一项是对数似然(训练数据的拟合),第二项是对数先验(对参数的约束)。
权重衰减(L2正则化) 就是高斯先验 $P(\theta) \propto \exp(-\lambda \|\theta\|^2)$ 在 MAP 框架下的自然推论:
$$\log P(\theta) = -\lambda \|\theta\|^2 + \text{常数}$$
最大化 MAP 等价于最小化"交叉熵损失 + $\lambda \|\theta\|^2$"。DeepSeek V3 训练时用的权重衰减,贝叶斯解释就是对参数施加高斯先验,防止参数过大。
MLE 是 MAP 的特例:当先验是均匀分布($P(\theta) = \text{const}$),MAP 退化为 MLE——纯粹从数据出发,没有任何先验偏好。
第10篇讲过 LoRA 冻结原始权重 $W_0$,只训练低秩更新 $\Delta W = BA$。
贝叶斯解释:$W_0$ 是强先验(预训练模型的参数),$\Delta W$ 是在这个先验基础上做的后验更新。低秩约束 $\Delta W = BA$ 是对更新量的结构化先验——"更新量应该是低秩的"。
少量微调数据只有能力更新参数空间的一小部分方向(数据信息量有限),LoRA 恰好把更新约束在低维子空间里,符合这个贝叶斯直觉。
DeepSeek R1 的 GRPO 损失函数包含一个 KL 散度约束项:
$$\mathcal{L}_{GRPO} = -\mathbb{E}[A_i \log \pi_\theta(o_i \mid q)] + \beta \cdot D_{KL}(\pi_\theta \| \pi_{ref})$$
贝叶斯解释:
整个强化学习训练过程,就是一次大规模的贝叶斯更新:从"说话流畅但不一定推理准确"的先验,用推理正确性的奖励信号,更新到"推理准确"的后验。
虽然朴素贝叶斯已经被深度学习超越,但它是贝叶斯定理最直接的应用,值得走一遍推导,帮助理解更复杂的模型。
分类问题:给定特征 $\mathbf{x} = (x_1, \ldots, x_n)$,判断类别 $y$。
用贝叶斯定理:
$$P(y \mid \mathbf{x}) = \frac{P(\mathbf{x} \mid y) \cdot P(y)}{P(\mathbf{x})}$$
分母 $P(\mathbf{x})$ 对所有类别相同,分类时可以忽略:
$$\hat{y} = \arg\max_y P(y \mid \mathbf{x}) = \arg\max_y P(\mathbf{x} \mid y) \cdot P(y)$$
朴素独立假设:给定类别 $y$,各特征条件独立:
$$P(\mathbf{x} \mid y) = \prod_{i=1}^n P(x_i \mid y)$$
最终分类器:
$$\hat{y} = \arg\max_y \left[P(y) \cdot \prod_{i=1}^n P(x_i \mid y)\right]$$
取对数(把乘积变求和):
$$\hat{y} = \arg\max_y \left[\log P(y) + \sum_{i=1}^n \log P(x_i \mid y)\right]$$
先验 $\log P(y)$:类别频率(训练集里各类别出现比例)。
似然 $\log P(x_i \mid y)$:在类别 $y$ 下,特征 $x_i$ 出现的频率。
两项都从训练集里直接统计,无需优化。这就是朴素贝叶斯的全部。
训练集:60 封正常邮件,40 封垃圾邮件。
先验:$P(\text{正常}) = 0.6$,$P(\text{垃圾}) = 0.4$。
词频统计(简化,只看2个词):
新邮件含"免费"和"会议":
$$\text{正常分}: \log 0.6 + \log 0.05 + \log 0.30 = -0.511 + (-2.996) + (-1.204) = -4.711$$
$$\text{垃圾分}: \log 0.4 + \log 0.40 + \log 0.02 = -0.916 + (-0.916) + (-3.912) = -5.744$$
正常分 > 垃圾分,判为正常邮件。
import numpy as np import torch import torch.nn.functional as F np.random.seed(42) # ===== 1. 条件概率与贝叶斯定理:医疗检测 ===== print("===== 贝叶斯定理:医疗检测 =====\n") p_disease = 0.01 # 患病率(先验) p_pos_given_disease = 0.99 # 患病者阳性率(敏感性) p_pos_given_healthy = 0.05 # 健康者阳性率(假阳性率) p_healthy = 1 - p_disease # 全概率公式:总阳性率 p_pos = p_pos_given_disease * p_disease + p_pos_given_healthy * p_healthy # 贝叶斯定理:阳性条件下患病概率 p_disease_given_pos = (p_pos_given_disease * p_disease) / p_pos print(f"患病率(先验): {p_disease:.2%}") print(f"检测敏感性: {p_pos_given_disease:.2%}") print(f"假阳性率: {p_pos_given_healthy:.2%}") print(f"总阳性率(全概率公式): {p_pos:.4f}") print(f"阳性条件下患病概率: {p_disease_given_pos:.2%} ← 远低于直觉!") # 用自然频率验证 n = 100000 n_disease = int(n * p_disease) n_healthy = n - n_disease tp = int(n_disease * p_pos_given_disease) # 真阳性 fp = int(n_healthy * p_pos_given_healthy) # 假阳性 print(f"\n自然频率验证({n:,}人):") print(f" 患病者: {n_disease:,}人,检测阳性: {tp}人") print(f" 健康者: {n_healthy:,}人,检测阳性(假阳性): {fp}人") print(f" 阳性中真患病比例: {tp}/{tp+fp} = {tp/(tp+fp):.2%}") # ===== 2. 贝叶斯迭代更新 ===== print("\n===== 贝叶斯迭代更新 =====\n") # 估计硬币正面概率,先验 Beta(1,1)(均匀) # 每次观测更新后验 alpha, beta_param = 1.0, 1.0 # Beta先验参数 print(f"初始先验: Beta({alpha:.0f},{beta_param:.0f}), 期望={alpha/(alpha+beta_param):.3f}") observations = [1, 1, 0, 1, 1, 0, 1, 1, 1, 0] # 1=正面, 0=反面 for i, obs in enumerate(observations): alpha += obs beta_param += (1 - obs) posterior_mean = alpha / (alpha + beta_param) print(f"观测{i+1:2d}={'正面' if obs else '反面'}: " f"Beta({alpha:.0f},{beta_param:.0f}), 后验期望={posterior_mean:.3f}") true_p = sum(observations) / len(observations) print(f"\n真实正面比例: {true_p:.3f},后验期望: {alpha/(alpha+beta_param):.3f}") # ===== 3. 自回归语言模型:链式法则 ===== print("\n===== 自回归生成:概率链式法则 =====\n") # 模拟一个简单语言模型,词表 = ["猫","在","吃","鱼","狗","跑"] vocab = ["猫", "在", "吃", "鱼", "狗", "跑"] # 条件概率表(简化,手动指定) # cond_prob[context] = {next_word: prob} cond_prob = { () : {"猫": 0.4, "狗": 0.4, "鱼": 0.1, "在": 0.05, "吃": 0.04, "跑": 0.01}, ("猫",) : {"在": 0.6, "吃": 0.3, "跑": 0.08, "猫": 0.01, "狗": 0.005, "鱼": 0.005}, ("猫","在"): {"吃": 0.7, "跑": 0.2, "猫": 0.05, "狗": 0.03, "鱼": 0.015, "在": 0.005}, ("猫","在","吃"): {"鱼": 0.8, "猫": 0.1, "狗": 0.06, "在": 0.02, "吃": 0.015, "跑": 0.005}, } # 计算句子"猫 在 吃 鱼"的联合概率 sentence = ["猫", "在", "吃", "鱼"] log_prob = 0.0 print("句子「猫 在 吃 鱼」的概率分解:") context = () for word in sentence: p = cond_prob[context][word] log_prob += np.log(p) print(f" P({word} | {' '.join(context) if context else '∅'}) = {p:.3f}") context = context + (word,) if len(context) < 3 else context[1:] + (word,) joint_prob = np.exp(log_prob) print(f"\nP(猫 在 吃 鱼) = {np.exp(np.log(0.4)+np.log(0.6)+np.log(0.7)+np.log(0.8)):.5f}") print(f"对数概率(NLL = {-log_prob:.4f})") # ===== 4. MAP vs MLE:正则化的贝叶斯解释 ===== print("\n===== MAP vs MLE:正则化的贝叶斯解释 =====\n") # 用逻辑回归演示 # MLE: 最大化似然(等价于最小化交叉熵) # MAP with 高斯先验: 最大化似然 + 对数先验(等价于L2正则化) np.random.seed(0) n_samples = 50 X = np.random.randn(n_samples, 2) # 真实参数 w_true = np.array([2.0, -1.0]) y = (X @ w_true + np.random.randn(n_samples) * 0.5 > 0).astype(float) def sigmoid(z): return 1 / (1 + np.exp(-z)) def compute_loss(w, X, y, lam=0.0): """交叉熵损失 + L2正则(λ=0时是MLE)""" z = X @ w p = sigmoid(z) p = np.clip(p, 1e-7, 1-1e-7) nll = -np.mean(y * np.log(p) + (1-y) * np.log(1-p)) l2 = lam * np.sum(w**2) return nll + l2 def gradient_descent(X, y, lam=0.0, lr=0.1, n_iter=500): w = np.zeros(2) for _ in range(n_iter): z = X @ w p = sigmoid(z) grad = X.T @ (p - y) / len(y) + 2 * lam * w w -= lr * grad return w w_mle = gradient_descent(X, y, lam=0.0) w_map = gradient_descent(X, y, lam=0.1) print(f"真实参数: w = {w_true}") print(f"MLE估计(λ=0): w = {w_mle.round(3)}, ||w||² = {np.sum(w_mle**2):.3f}") print(f"MAP估计(λ=0.1): w = {w_map.round(3)}, ||w||² = {np.sum(w_map**2):.3f}") print(f"\n→ MAP的||w||²更小(高斯先验把参数往0拉),即L2正则化的贝叶斯解释") # ===== 5. GRPO的KL约束:贝叶斯先验正则化 ===== print("\n===== GRPO KL约束:先验正则化 =====\n") # 模拟:参考策略(先验)vs 训练后策略(后验) # 目标是在奖励信号驱动下更新策略,但不能离参考策略太远 torch.manual_seed(42) vocab_size = 10 # 参考策略(SFT模型,先验) logits_ref = torch.randn(vocab_size) pi_ref = F.softmax(logits_ref, dim=0) # 经过强化学习后的策略 logits_rl = logits_ref + torch.randn(vocab_size) * 2.0 # 更新后 pi_rl = F.softmax(logits_rl, dim=0) # KL散度:衡量策略偏离参考的程度 kl = (pi_rl * (torch.log(pi_rl) - torch.log(pi_ref))).sum() print(f"参考策略(先验)前5个概率: {pi_ref[:5].detach().numpy().round(3)}") print(f"RL策略(后验)前5个概率: {pi_rl[:5].detach().numpy().round(3)}") print(f"KL散度 D_KL(π_rl || π_ref): {kl.item():.4f}") beta = 0.04 # DeepSeek R1论文中的β print(f"\n假设平均奖励 = 1.5,KL惩罚 = β×KL = {beta}×{kl.item():.3f} = {beta*kl.item():.4f}") print(f"β越大,策略越不敢偏离参考(先验越强);β越小,策略更自由追求奖励(似然主导)")
这篇文章把条件概率和贝叶斯定理从直觉到公式,再到 DeepSeek 的具体应用,全部打通了。
第一,条件概率 $P(A \mid B) = P(A \cap B) / P(B)$ 的直觉是"缩小样本空间"——已知 $B$ 发生,在 $B$ 内部重新计算 $A$ 的概率。语言模型的每一步预测,就是在计算"给定前面所有词,下一个词的条件概率"。
第二,链式法则把任意序列的联合概率分解为条件概率的乘积,这正是自回归语言模型的数学基础。训练目标(最大化对数似然)就是让每一步的条件概率预测尽量准确。
第三,全概率公式把复杂问题按"原因"分类讨论,MoE 架构可以理解为对 256 个专家做全概率加权混合。
第四,贝叶斯定理 $P(\theta \mid D) \propto P(D \mid \theta) \cdot P(\theta)$ 是"用数据更新信念"的数学表达。医疗检测的例子说明先验(患病率)对后验的影响不可忽视,简单"高准确率"的直觉往往是错的。
第五,神经网络训练是贝叶斯迭代更新:每个 mini-batch 是一次用数据(似然)更新参数信念(后验)的过程。MLE 是均匀先验下的 MAP;L2 正则化是高斯先验下的 MAP;LoRA 的低秩约束是对更新量的结构化先验。
第六,GRPO 的 KL 约束也是贝叶斯正则化:参考策略是先验,奖励信号是似然,训练后的策略是后验,KL 项防止后验偏离先验太远。$\beta = 0.04$ 控制先验的强弱。
下一篇预告:
第13篇,我们讲常见概率分布:正态、均匀、伯努利分布的直觉。
第11篇已经介绍了这些分布的基本定义。第13篇会更深入——讲分布的形状、参数的意义、在不同场景下如何选择分布,以及指数族分布的统一框架(解释为什么这么多不同的损失函数有相似的数学结构)。
条件概率是一种思维方式:不是"这件事发生的概率是多少",而是"在已知这些信息的前提下,这件事发生的概率是多少"。贝叶斯定理教会我们如何更新:新证据来了,信念该怎么变。这是理性推断的核心,也是语言模型和强化学习的数学灵魂。
还没有评论,来抢沙发吧!
博客管理员
40 篇文章
还没有评论,来抢沙发吧!