概率与统计 入门

读懂任何 LLM 训练论文之前所需的最少概率与统计。5 个短小主题,涵盖「概率到底是什么」、 概率分布及其「加起来等于 1」的约束、条件概率、期望 / 均值 / 方差,以及在每个语言模型背后 默默运行的对数概率。除高中代数外,不假定任何先验数学。

01

概率(Probability)

一个 0 到 1 之间的数,表示我们对某件事发生有多确信。

抛一枚均匀硬币。在它落地之前,你说不出是正面还是反面 —— 但你说出一件有用的事: 两个结果感觉上「一样可能」。概率 就是把这种感觉钉成一个数。正面对应 0.5,反面也是 0.5。形式化写法是 P(正面) = 0.5 —— 读作「正面的概率是二分之一」。

这个数永远落在闭区间 [0, 1]。两端是人人都知道的两种极端情况, 只是换了套正式的外衣:

  • P(事件) = 0 —— 事件不可能发生。硬币立在边上还长出翅膀飞走。
  • P(事件) = 1 —— 事件一定发生。明天太阳照常升起(差不多)。
  • P(事件) = 0.5 —— 不偏不倚,就像一次抛硬币。
  • P(事件) = 0.99 —— 几乎必然,但还差那么一点。
  • P(事件) = 0.001 —— 不太可能,但并非不可能。
01P = 0不可能
1 / 5
沿着 0 到 1 的数轴走一遍 —— 每一步停在一个有代表性的概率上。

这个数有两种等价的读法,平时都用得上:

  • 作为长期频率。把硬币抛一百万次,大约有五十万次落到正面。 概率就是次数比例最终收敛到的那个数。
  • 作为信念强度。就算只抛一次,在抛之前你也愿意 50/50 下注。 概率就是你对某个结果押注的强度。

为什么用一个数就够?因为一旦有了它,很多后续问题就靠几步算术就能答出来:P(非正面) = 1 − P(正面) = 0.5;两次独立抛掷都是正面, 概率是 0.5 × 0.5 = 0.25;两次中至少一次是正面, 概率是 1 − 0.25 = 0.75。整套「可能会发生什么」的演算, 归根结底就是对 [0, 1] 之间的几个数做加减乘。

概率并不只属于硬币和骰子。一切「不确定」的事都有一个概率,只是没人写下来而已:

  • 天气。「明天 70% 概率下雨」= P(下雨) = 0.7
  • 垃圾邮件过滤。每封邮件都被打一个分数;超过阈值就进垃圾箱。
  • 医学检测。阳性不等于得病 —— 它只是把概率向上挪一截。
  • 体育比分。「热门 1.4 赔率」≈ 庄家给出的隐含概率 0.71 左右。
  • LLM。「The quick brown」之后下一个 token 是 cat 的概率,模型会算出来。

值得先记住的几个记号。P(A) 表示事件 A 的概率。P(A 且 B) —— 也写作 P(A ∩ B)P(A, B) —— 表示两者都发生的概率。P(A 或 B) —— 也写作 P(A ∪ B) —— 表示至少一个发生的概率。 而 P(非 A),写作 P(¬A)P(Aᶜ), 按定义等于 1 − P(A)

在 Transformer 里:每个 LLM 的最后一层, 都会为「下一个可能 token」各输出一个 [0, 1] 之间的数 —— 词表里每个词片段一个,加起来是几万个。生成下一个 token 时,模型就按这些数挑一个。 你最喜欢的聊天机器人写下的每一个字,都起源于这一段区间里的一个概率值。 后面四节会讲这些数字如何组合、求和、做条件、最终从数据里学出来。

02

概率分布(Probability Distribution)

把每个结果的概率列在一起 —— 而且加起来必须等于 1。

一枚硬币给出两个概率:P(正面) = 0.5P(反面) = 0.5。 一颗六面骰子给出六个,每面 1/6 ≈ 0.167。一个 10 万词表的语言模型给出 10 万个。 把所有可能结果的概率打包在一起,得到的就是 概率分布 —— 还是「每个结果一个数」,只是一次看全。

每个概率分布都遵循两条规则,值得直接背下来:

  • 每个数都在 [0, 1] 里 —— 每一项都是合法的概率。
  • 所有数加起来正好等于 1 —— 必须有件事发生。

「加起来等于 1」这条规则才是真正的核心。乍看像是教条,直到想起它为什么成立: 如果列举出所有可能发生的结果,那么以概率 1(也就是「一定」)其中之一发生。 你以后会做的概率运算 —— 把分数归一成概率、把概率拆成几种子情况、计算边缘概率 —— 十有八九都是为了让数字加起来变成 1。

一个简单的分布:明天的天气有四种互斥结果:

  P(晴)    = 0.55
  P(多云)  = 0.25
  P(雨)    = 0.15
  P(雪)    = 0.05
  ─────────────────
  总和     = 1.00 ✓
1.00多云总和 = 0.00
1 / 5
每个结果按概率填一格 —— 全部填完,总和正好是 1。

四个数,每个都在 [0, 1],加起来等于 1。这就是一个分布。你可以读出任何单一结果的概率, 也可以把结果打包:P(降水) = P(雨) + P(雪) = 0.20。 打包就是相加 —— 因为这四个结果互斥(此模型里同一天不会又下雨又下雪), 它们把所有可能性划分得干干净净。

到处都会碰到两种分布形态,规则都是上面那两条,只是「记账方式」不同:

  • 离散分布。结果是有限(或可数)多个。一枚硬币、一颗骰子、词表里的一个 token、 一个分类标签。分布就是一串数字,「求和」就是普通的求和。
  • 连续分布。结果取自一段连续区间 —— 身高(厘米)、温度、时间。 这时不再是一串数,而是一条密度曲线 p(x); 概率藏在曲线下的面积里;「加起来等于 1」变成「总面积等于 1」。 直觉一样,只是换成了微积分的记号。

最有名的连续分布是 正态分布(高斯分布)—— 你在每张分数图上都见过的那条钟形曲线。 它只需要两个数就能描述:峰在哪里(μ,均值)和钟有多宽(σ,标准差)。 成人身高、测量误差、神经网络初始化权重时加的噪声,差不多都服从正态分布。

离散这一侧,LLM 里的主力是 类别分布(categorical distribution) —— 正是上面那张天气表的结构,只是宽得多。语言模型每挑一个下一个 token, 都是在整张词表上的类别分布里采样。

分布是怎么得到的?主要有两种方式,都很熟悉:

  • 从计数得到。把骰子掷 6000 次,其中 1003 次是 4 点, 那么经验估计就是 P(4) ≈ 1003/6000 ≈ 0.167。 所有计数除以总次数,得到的概率天然加起来等于 1。
  • 从分数经 softmax 得到。一个公式 —— softmax(zᵢ) = exp(zᵢ) / Σⱼ exp(zⱼ) —— 把任意一串实数变成一个合法的概率分布。这一步值得仔细拆开看,因为每个 LLM 都用它。

softmax 在做什么。输入是一串实数分数 (z₁, z₂, …, z_n) —— 正、负、任意,无所谓。输出是同样长度的一串数,每一项都落在 [0, 1], 加起来正好等于 1。一个合法的概率分布,永远成立。

为什么需要它。神经网络最后一层不过是一组加权和 —— 输出可以是 −5.217.8,什么都行。要把这些分数当概率来用, 必须(a)让每一项非负,(b)让它们加起来等于 1。 你可能会想用一个更简单的办法:把所有分数平移到非负,再除以总和。 但平移会丢信息 —— −2−10 平移后都变成「小正数」, 哪怕原本它们在「信心强度」上差了很多。而且一旦所有分数恰好相互抵消, 除以总和就变成除以 0。Softmax 用「先取指数」一招把这两个问题都绕开。

三步配方。给定 logits (z₁, z₂, …, z_n):

  • 每一项取指数:exp(zᵢ)。任何实数的指数都是正的。
  • 求和:S = Σⱼ exp(zⱼ)
  • 每一项除以总和:softmax(zᵢ) = exp(zᵢ) / S

具体例子。在提示词「The quick brown」之后, LLM 给三个候选续写打分:

                fox       dog       hen
  logit       4.50      3.20      0.80
  exp        90.02     24.53      2.23
  ──────────────────────────────────────
                     sum = 116.78
  softmax     0.77      0.21      0.02   ✓ 合计 = 1.00

看看指数干了什么。foxdog 在 logit 上只差了 1.3, 但经过 softmax 之后,foxdog 大约 3.7 倍更可能。doghen 在 logit 上差 2.4, 但在概率上差 10 倍指数会把差距放大: logit 上一点点优势,经过 softmax 就变成概率上明显的差距。 这就是它的设计意图 —— 把一组模糊的「相对排名」,变成一个清晰可采样的概率地形。

logitexpsoftmaxfox4.5090.020.77dog3.2024.530.21hen0.802.230.02S = 116.78合计 = 1.00三个原始 logit —— 是实数,还不是概率。
1 / 4
三个 logit → exp → 求和 → 概率。指数把 logit 上的小差距,放大成概率上的大差距。

在 Transformer 里:LLM 最后一层,会为词表中的每个 token 输出一个实数分数 —— 叫 logit。Softmax 一行代码就把这整个 logit 向量(几万个数)变成词表上的一个 类别分布。这就是模型用来采样下一个 token 的分布。 你读到的每一次聊天回复,都是从几千个这样的分布里,各抽一个 token 拼起来的。

03

条件概率(Conditional Probability)

在 B 已经发生的前提下,A 的概率。

在地球上随便挑一个成年人,他拥有智能手机的概率大约是 P(智能手机) ≈ 0.7。 现在把镜头拉近:挑一个住在东京的成年人,这个概率可能跳到 0.95。 同一个问题,起始范围不同 —— 答案就变了。第二个数就是 条件概率, 写作 P(智能手机 | 住在东京),读作「他住东京的条件下, 他有智能手机的概率」。

那根竖线 | 就是这套记号的全部诀窍,读作「在……条件下」: 竖线右边的事是你已知必然成立的;竖线左边的事是你在那个前提下要问的。P(A | B) 就是「已知 B 的情况下,A 的概率」。

定义的机械形式只有一行:

P(A | B) = P(A 且 B) / P(B)

看着抽象,图像却很具体。在条件 B 下,你只关心 B 成立的那一片; 在这一片里,有多少比例同时也满足 A?这个比例就是 P(A | B)。 分母 P(B) 把这一片重新「拉回」一个总和为 1 的合法分布; 分子 P(A 且 B) 是两者的重叠部分。

具体例子。假设每 1000 个成年人里:

  · 有手机,住东京     =  19  ←  A 且 B
  · 有手机,不住东京   = 681
  · 没手机,住东京     =   1
  · 没手机,不住东京   = 299
  ────────────────────────────
  合计                = 1000

  P(有手机)            = 700 / 1000 = 0.70
  P(住东京)            =  20 / 1000 = 0.02   ← P(B)
  P(有手机 且 住东京)  =  19 / 1000 = 0.019  ← P(A 且 B)

  P(有手机 | 住东京)   = 0.019 / 0.02 = 0.95
有手机无手机其他东京6811929911000 个成年人,按是否有手机 × 是否住东京统计
1 / 4
把「东京」这一列圈出来,扔掉其余行,在那一小片里算比例 —— 这就是条件概率。

注意发生了什么。P(有手机) 在全体里是 0.7;一旦只看 20 个东京居民这一片, 他们里有 19 个有手机,条件概率就跳到 0.95。条件化本质是一次放大镜操作: 把 B 不成立的行扔掉,再把剩下的部分重新归一化。

如果条件化「不改变答案」,即 P(A | B) = P(A), 就说 A 和 B 独立。知道 B 发生了,对 A 一点信息都没有。 两次抛硬币是独立的:第一次正面还是反面,第二次都还是 50/50。否则就是依赖的: 知道 B 会改变你对 A 的信念。现实世界里几乎所有有意思的事件对都是依赖的 —— 条件概率之所以是机器学习的核心杠杆,原因就在这里。

把定义稍微挪一挪,就得到 ML 论文里随处可见的 链式法则:

P(A 且 B) = P(A | B) · P(B) = P(B | A) · P(A)

计算「A 且 B」的联合概率有两种走法,挑哪个方向更顺手就用哪个。 把两边右手项画上等号,再两边同除以 P(B), 就得到 贝叶斯定理:P(A | B) = P(B | A) · P(A) / P(B) —— 这个公式让你把条件方向翻转过来。医学检测、垃圾邮件过滤、整个贝叶斯推断的领域, 都是这一步重新整理的延伸。

一个经典陷阱:P(A | B)P(B | A) 不是同一个数。P(下雨 | 人行道湿) 很高 —— 人行道湿大多是下雨造成的;P(人行道湿 | 下雨) 也很高(甚至可以是 1)。 再看 P(患病 | 阳性)P(阳性 | 患病):即使灵敏度 99% (P(阳性 | 患病) = 0.99),只要这个病很罕见,大多数阳性其实是假阳性。 同样几个数,条件方向反过来,结论可能天差地别。贝叶斯定理就是把两者重新串起来的那道桥。

在 Transformer 里:LLM 输出的每一个概率,本质都是条件概率。 让它续写「法国的首都是」时,模型在计算 P(下一个 token | 前面所有 token) —— 请仔细看那根竖线:整段 prompt 在竖线右边,要预测的在竖线左边。 训练 LLM 就是用海量文本去估计这个庞大的条件分布:语料里每一段文本, 模型都被问「在你已经看到的内容下,接下来是什么?」生成,就是同一招正向跑一遍, 一次一个条件概率。一篇聊天回复就是一连串条件概率,由上面的链式法则把它们拼起来。

04

期望、均值与方差

两个数把一整个分布压缩成「它落在哪里」和「它有多分散」。

一个分布可能有几十、几千、甚至无穷多项 —— 多到没法一眼看清。 所以我们把它压缩成几个摘要数字。绕不开的两个是 均值(分布平均落在哪里) 和 方差(它在均值附近散得多开)。

假设你转一个转盘,可能赢 4 种不同金额,概率列在下面:

  奖金  $0     $10    $50    $1000
  P     0.70   0.20   0.09   0.01

转一次「平均」会赢多少?当然单次拿不到这个数 —— 单次只会出 4 个奖金里的一个。 但如果转 100 万次,把每次奖金平均一下,长期平均值就会收敛到 期望(也叫 期望值 或就叫 均值),记作 E[X]。 公式是「结果乘以概率,再求和」:

E[X] = Σ xᵢ · P(xᵢ)

对这个转盘:

  E[X] = 0·0.70 + 10·0.20 + 50·0.09 + 1000·0.01
       =  0     +  2      +  4.5    +  10
       = 16.5
结果P贡献$00.70·0.7 = 0$100.210·0.2 = 2$500.0950·0.09 = 4.5$10000.011000·0.01 = 10E[X]= 0把每个奖金按概率加权,再相加。
1 / 5
四个贡献依次加进来 —— 期望就是它们的加权和。

平均每转一次能赢 $16.50 —— 虽然没有任何一次会正好赢到这个数。 均值是一个加权平均:每个结果被它发生的频率加权。 极少出现的结果(比如 $1000 大奖)只贡献它那一小份; 常见结果(比如 $0)把整个均值往低处压。

一个概念,三种说法。均值平均数期望 三个词经常混用,但区分一下还是有好处:

  • 一串数的均值 —— 算术平均。全部加起来,除以个数。mean([2, 4, 9]) = 5
  • 分布的期望 —— 如果你不停从该分布里采样,算术平均最终会收敛到的值。 同一个想法,从概率视角看。
  • 样本均值 —— 基于你实际抽到的样本,对底层期望的经验估计。 样本越多,它越逼近真实期望。

均值告诉你分布落在哪里,却没告诉你它有多散。 想象两种收益分布,均值都是 0:一个是「每天稳赚 0」的存折, 另一个是「+100 / −100 各 50%」的轮盘。均值一样,体感却天差地别。 所以我们需要第二个数来度量「分散」。

这个数就是 方差,记作 Var(X)。 思路:看每个结果偏离均值多远,把这些偏差平方 (一来变正,二来让大偏差权重更大),然后取这些平方偏差的期望:

Var(X) = E[(X − μ)²]

这里 μ(希腊字母 mu)只是 E[X] 的简写 —— 统计学里习惯用 μ 表示均值。对我们这个转盘(μ = 16.5):

  Var(X) = (0 − 16.5)²·0.70
         + (10 − 16.5)²·0.20
         + (50 − 16.5)²·0.09
         + (1000 − 16.5)²·0.01
         = 190.575 + 8.45 + 101.0025 + 9672.7225
         ≈ 9972.75

方差很大,被那个罕见的 $1000 奖项主宰着。 方差有个不太顺手的地方:它的单位是平方(这里是「美元的平方」), 所以通常我们改报它的平方根 —— 标准差 σ = √Var(X)。 对这个转盘,σ ≈ $99.86。它和均值同单位, 所以你能说「典型奖金落在 $16.50 ± $99.86」,这种比较才有意义。

三个到处都用得上的实用事实:

  • 期望的线性。E[X + Y] = E[X] + E[Y],永远成立。 就算 X 和 Y 互相纠缠也没关系 —— 不需要独立性。 这是初等概率里最出乎意料的强大恒等式。
  • 方差与常数。Var(aX) = a² · Var(X) —— 方差按平方缩放。 每个奖金翻倍,方差会变成原来的 4 倍。
  • 独立和的方差。当 X 和 Y 独立时,Var(X + Y) = Var(X) + Var(Y) —— 方差相加。 这就是「平均多个独立测量能压低噪声」的原理:Var(n 个的平均) = σ² / n, 所以 σ1/√n 的速度收缩。

在 Transformer 里:训练每个 LLM 用的 损失函数 —— 交叉熵 —— 本质上就是一个期望:把每个 token 的损失,在整个训练语料上平均, 梯度下降去最小化这个平均值。方差则出现两次:LayerNorm 把每个 token 向量 重新调整成「均值 0、方差 1」,以保持激活值稳定; 梯度下降在每个 mini-batch 上看到的梯度噪声本身就有方差 —— 所以批量越大,训练曲线越平滑(平均更多样本,噪声以 √n 速度被压低)。 现代 ML 的三个核心套路 —— 最小化平均损失、归一化激活、批量化梯度 —— 全是均值与方差的具体应用。

05

对数概率(Log Probability)

概率小到可怕,而且要连乘;它们的对数是不大不小的数,而且只要相加。

实际工程里,概率有个问题:它们小得非常快。一段特定句子出现在野外的概率大约是10⁻³⁰;一段 100 词的段落?10⁻³⁰⁰。 这些数小到无法存进 64 位浮点数 —— double 类型能表示的最小正数大约是 10⁻³⁰⁸, 再小就直接四舍五入到 0 了。把一堆概率连乘下去,很快就跌出这道悬崖。

解药是取 对数。一个数的对数,回答的是「e(约 2.718)的多少次方等于它?」 例如 log(0.5) ≈ −0.693log(0.01) ≈ −4.605log(10⁻³⁰⁰) ≈ −690.78。极小的正概率, 变成不大不小的负数,既好存又好算。

线性 P010.50.010.0001log P-100三个概率 —— 三个数量级 —— 都挤在左边一小段。
1 / 3
同样三个概率,在线性轴上挤成一堆;取 log 后,差距一目了然。

对数有三条性质,刚好让它和概率天造地设。三条都源自同一条规则 log(a · b) = log(a) + log(b):

  • 乘法变加法。N 个独立事件的联合概率是 p₁ · p₂ · … · pN —— 这个连乘会下溢。 取对数后,变成 log p₁ + log p₂ + … + log pN —— 无论你加多少项都不会爆。
  • 大小顺序保持不变。对数单调递增 —— p > q 当且仅当log p > log q。所以只要你做的是比较或排序 (哪个 token 最可能?哪个分类得分最高?),比较 log 给出完全相同的答案。 原本想最大化的东西,可以直接最大化它的 log。
  • 数值范围被压平。概率分布在 [0, 1],但有意思的事情大多挤在 0 附近 ——0.0010.0001 视觉上很像,可发生频率却差 10 倍。 取 log 后,它们成了 −6.91−9.21,差异一目了然。 基于梯度的优化器看到的「损失地形」干净得多。

约定:ML 里默认是 自然对数(以 e 为底),写作 log ln。有些教材用以 2 为底(单位是 bit)或以 10 为底,但定性行为完全一样 —— 换底只是给所有对数乘上一个常数。

一个具体例子。用一个简陋的语言模型,把句子「the cat sat」的概率, 按第 3 节的链式法则拆开来算:

  P("the cat sat")
    = P(the) · P(cat | the) · P(sat | the cat)
    = 0.04   · 0.001        · 0.0002
    = 0.000000008   ← 才三个 token 就够呛;100 个 token 没救。

  log P("the cat sat")
    = log(0.04) + log(0.001) + log(0.0002)
    = −3.22     + −6.91      + −8.52
    = −18.65        ← 三个数相加,稳稳的,不会下溢。

同样的信息,两种尺度。乘法在浮点寄存器里直接归零;加法是个体感舒服的 −18.65。 100 个 token 的序列,连乘根本走不到终点,而加法只是越加越负到几百而已。 每个 LLM 的打分流程、每次困惑度计算、每个束搜索排序器,都在 log 空间里跑,原因就在这。

读 ML 论文时立刻会撞上的两个相关量:

  • 负对数似然(NLL)。就是 −log P。我们翻个符号, 让「更可能」对应更小的数 —— 优化器都喜欢这样(它们都做最小化)。 最大化似然和最小化 NLL 是同一件事。
  • 交叉熵损失。每个 LLM 的训练目标:L = −Σ log P(正确 token | 之前的 tokens),在语料上求平均。 就是「在每个位置上,把正确答案的概率取负对数,然后求和」。 换个名字的 NLL,但你在论文里看到的总是「cross-entropy」这个词。

还有一个常见招式:log-sum-exp。在 log 空间里把几个概率相加(比如把若干条推理路径的 log-prob 合并成一个总概率),要小心,因为 log(p + q) ≠ log p + log q。技巧是 log(Σ exp(log pᵢ)),每个框架都把这件事封装成数值稳定的 logsumexp。第 2 节的 softmax,就是它的一个应用。

在 Transformer 里:模型输出的是 logits,真正喂进损失函数的是log_softmax(logits) —— 也就是对数概率。 训练循环计算 cross_entropy = −mean(log P(正确 token)),然后反向传播。 推理时,束搜索和采样按「累积对数概率」给候选续写排序 —— 每延伸一个 token 就把这个 token 的 log-prob 加上去。 本文里我们写作 P(x) 的每一个概率,在真实训练 / 推理代码里, 几乎都是以 log P(x) 的形态存储和操作的。 数学上是同一件事,只是浮点寄存器能活下来。