采样方法:AI 探索可能性空间


文档摘要

采样方法:AI 探索可能性空间 本节摘要:采样是 AI 探索可能性空间的方式。语言模型处理完 prompt 后吐出 5 万个 logit(词表每词一个),要从中选一个——总选最高概率则每次回答相同且无趣,均匀随机选则是胡言乱语,答案介于两端,由采样控制。但采样远不止文本生成:强化学习采样轨迹估策略梯度,VAE 从学到的分布采样并反向传播穿过随机性,扩散模型采样噪声再迭代去噪生成图像,Monte Carlo 估无闭式解的积分,MCMC 探索无法枚举的高维后验。每个生成式 AI 系统都是采样系统。

采样方法:AI 探索可能性空间

本节摘要:采样是 AI 探索可能性空间的方式。语言模型处理完 prompt 后吐出 5 万个 logit(词表每词一个),要从中选一个——总选最高概率则每次回答相同且无趣,均匀随机选则是胡言乱语,答案介于两端,由采样控制。但采样远不止文本生成:强化学习采样轨迹估策略梯度,VAE 从学到的分布采样并反向传播穿过随机性,扩散模型采样噪声再迭代去噪生成图像,Monte Carlo 估无闭式解的积分,MCMC 探索无法枚举的高维后验。每个生成式 AI 系统都是采样系统。本节从均匀随机数出发,讲透逆 CDF、拒绝采样、重要性采样、Monte Carlo、Metropolis-Hastings、Gibbs;再给 LLM 的温度/top-k/top-p(核采样),VAE 的重参数化技巧(把随机性移到无参源使采样可微),离散采样的 Gumbel-Softmax,以及分层采样;最后连上扩散模型——每一步去噪都是一次重参数化采样。

对应原课程:Phase 01 · Lesson 16 · sampling-methods(原英文 phases/01-math-foundations/16-sampling-methods/docs/en.md)。前置:第 6、7 节(概率、贝叶斯)。

学习目标

阅读完本节,你应当能够:

  1. 从零实现逆 CDF、拒绝采样、重要性采样,只用均匀随机数。
  2. 为语言模型 token 生成实现温度、top-k、top-p(核)采样。
  3. 解释重参数化技巧为何能让反向传播穿过采样(VAE)。
  4. 运行 Metropolis-Hastings MCMC 从未归一化目标分布采样。

一、问题与直觉

采样在 AI 与机器学习中扮演四种基本角色:

  • 生成:语言模型、扩散模型、GAN 都靠采样产出输出,采样算法直接控制创意、连贯性、多样性。
  • 训练:SGD 采样 mini-batch,Dropout 采样要关闭的神经元,数据增强采样随机变换,重要性采样在 RL(PPO、TRPO)中重加权样本降梯度方差。
  • 估计:许多量无闭式解——数据分布上的期望损失、能量模型的配分函数、贝叶斯推断的证据——Monte Carlo 用样本平均近似它们。
  • 探索:MCMC 探索贝叶斯后验,进化策略采样参数扰动,Thompson 采样在 bandit 中平衡探索与利用。

核心挑战:你只能直接从简单分布(均匀、正态)采样。其余一切,都需要方法把简单样本转换成目标分布的样本。

1.1 均匀随机采样

每个采样方法从这里开始。均匀随机数生成器产生 [0,1) 的值,等长子区间概率相等:U ~ Uniform(0,1),E[U]=0.5,Var(U)=1/12。从 n 个离散项均匀采样:生成 U 返回 floor(n·U);从连续 [a,b] 采样:a + (b-a)·U

关键洞见:一个均匀随机数恰好包含从任何分布产生一个样本所需的随机性,技巧在于找到正确的变换。

1.2 逆 CDF 法(逆变换采样)

累积分布函数 CDF 把值映成概率:F(x) = P(X ≤ x),非降、F(-∞)=0F(+∞)=1、把实轴映到 [0,1]。逆 CDF 把概率映回值。若 U ~ Uniform(0,1),则 X = F⁻¹(U) 服从目标分布。

算法:1. 生成 u ~ Uniform(0,1);2. 返回 F⁻¹(u) 为何有效:P(X ≤ x) = P(F⁻¹(U) ≤ x) = P(U ≤ F(x)) = F(x)

指数分布示例:PDF f(x)=λ·exp(-λx)(x≥0),CDF F(x)=1-exp(-λx)。解 F(x)=ux = -ln(1-u)/λ;因 (1-U) 与 U 同分布,故 x = -ln(u)/λ。能写出闭式 F⁻¹ 时此法完美;正态分布无闭式逆 CDF,改用 Box-Muller 或数值近似。离散版:把 CDF 做成累积和,生成 U,找首个累积超过 U 的下标——这就是第 6 节 sample_categorical 的做法。

1.3 拒绝采样

无法逆 CDF 但能(可能未归一地)算目标 PDF 时,拒绝采样可用:

目标分布 p(x)(可算,可能未归一);提议分布 q(x)(可采样);界 M 使 p(x) ≤ M·q(x) 对所有 x 算法: 1. 采样 x ~ q(x) 2. 采样 u ~ Uniform(0,1) 3. 若 u < p(x)/(M·q(x)) 接受 x;否则拒绝,回第 1 步 接受率 = 1/M

M 越紧接受率越高。低维(1~3)拒绝采样好用;高维接受率指数衰减,这是拒绝采样的维度灾难。

1.4 重要性采样

有时你不需要目标分布 p(x) 的样本,而要在 p(x) 下估某期望,且你只有另一分布 q(x) 的样本:

目标:估 E_p[f(x)] = ∫ f(x)·p(x) dx 改写:E_p[f(x)] = ∫ f(x)·(p(x)/q(x))·q(x) dx = E_q[f(x)·w(x)],w(x) = p(x)/q(x) 是重要性权重 估计:E_p[f(x)] ≈ (1/N)·Σ f(x_i)·w(x_i),x_i ~ q(x)

这在强化学习里至关重要。PPO(近端策略优化)用旧策略 π_old 采轨迹却要优化新策略 π_new,重要性权重 = π_new(a|s)/π_old(a|s),PPO 截断这些权重防新策略偏离过远。方差取决于 q 与 p 的相似度——差异大时少数样本获巨权主导估计,自归一化重要性采样除以权重和缓解:E_p[f(x)] ≈ Σ w_i·f(x_i)/Σ w_i

1.5 Monte Carlo 估计

Monte Carlo 用随机样本平均近似积分,大数定律保证收敛:

目标:估 I = ∫_D g(x) dx 方法:1. 从 D 均匀采样 x_1,...,x_N;2. I ≈ (Vol(D)/N)·Σ g(x_i) 误差:O(1/√N),与维度无关

误差率与维度无关,这正是 Monte Carlo 在高维(网格积分不可行处)统治的原因。估 π:从 [-1,1]² 均匀采样 (x,y),数多少落单位圆内 x²+y²≤1,π ≈ 4·(圆内数)/(总数)估期望:E[f(X)] ≈ (1/N)·Σ f(x_i),x_i ~ p(x),估计方差 = Var(f(X))/N。

1.6 MCMC:Metropolis-Hastings

MCMC 构造一个平稳分布为目标分布 p(x) 的马尔可夫链;足够多步后,链上样本(近似)来自 p(x)。

目标 p(x)(已知到归一化常数);提议 q(x'|x) Metropolis-Hastings: 1. 从某 x_0 开始 2. 对 t=1,2,...,T: a. 提议 x' ~ q(x'|x_t) b. 算接受比 α = [p(x')·q(x_t|x')] / [p(x_t)·q(x'|x_t)] c. 以概率 min(1,α) 接受:若 u<α(u~Uniform(0,1))则 x_{t+1}=x',否则 x_{t+1}=x_t 3. 丢弃前 B 个样本(burn-in),返回其余

对称提议(q(x'|x)=q(x|x'))时比值简化为 p(x')/p(x),即原始 Metropolis 算法。为何有效:接受规则保证细致平衡——在 x 且移到 x' 的概率等于在 x' 且移到 x 的概率;细致平衡蕴含 p(x) 是链的平稳分布。

实战要点:burn-in(丢弃链达平衡前的早期样本);thinning(每 k 个留一个降自相关);提议尺度太小则链慢(高接受、慢探索),太大则多拒(低接受、原地卡);高维高斯提议的最优接受率约 0.234。

1.7 Gibbs 采样

Gibbs 是多元分布 MCMC 的特例:不一次在所有维提议,而是每次从条件分布更新一个变量:

目标 p(x_1, x_2, ..., x_d) 每次迭代 t: 采样 x_1^{t+1} ~ p(x_1 | x_2^t, x_3^t, ..., x_d^t) 采样 x_2^{t+1} ~ p(x_2 | x_1^{t+1}, x_3^t, ..., x_d^t) ... 采样 x_d^{t+1} ~ p(x_d | x_1^{t+1}, ..., x_{d-1}^{t+1})

Gibbs 要求能从每个条件 p(x_i | x_{-i}) 采样,许多模型都直白:贝叶斯网络(条件由图结构给)、高斯混合(条件是高斯)、Ising 模型(每个自旋的条件只依赖邻居)。接受率恒为 1(每个提议都接受),因从精确条件采样自动满足细致平衡。局限:变量高度相关时,Gibbs 一次更新一维无法做大对角移动,混合慢。

1.8 温度采样(LLM 用)

语言模型输出词表每个 token 的 logit,softmax 转概率。温度在 softmax 前重缩放 logits:p_i = exp(z_i/T) / Σ exp(z_j/T)

T=1.0:标准 softmax(原始分布) T→0: argmax(确定性,总选最高 logit) T→∞: 均匀(所有 token 等概) T<1: 锐化分布(更自信、更少样性) T>1: 平坦分布(更不自信、更多样性)

为何有效:logit 除以 T<1 放大差异。z₁=2、z₂=1,除以 T=0.5 得 4 与 2,差距变大,softmax 后最高 logit 的 token 占比更大。实战:T=0.0 贪心解码(事实问答);0.3~0.7 略创意(代码生成);0.7~1.0 平衡(通用对话);1.0~1.5 创意写作、头脑风暴;>1.5 越来越随机,少有用。温度不改变哪些 token 可行,只改变分配给每个 token 的概率质量。

1.9 top-k 采样

top-k 把候选集限制为概率最高的 k 个 token,重归一化后采样:

1. 算所有 V 个 token 的 softmax 概率 2. 按概率降序排 3. 只保留前 k 个 4. 重归一化:p_i' = p_i / Σ(前 k 的 p_j) 5. 从重归一化分布采样 k=1:贪心;k=V:不过滤;k=40:典型,去掉长尾不可能 token

top-k 防模型选词表分布长尾里极不可能的 token(错字、胡言)。问题是 k 固定不顾上下文:模型自信时(一个 token 占 95%)k=40 仍允 39 个替代;模型不确定时(概率散在 1000 token 上)k=40 砍掉合理选项。

1.10 top-p(核)采样

top-p 动态调整候选集大小:不固定 token 数,而保留累积概率超过 p 的最小集合:

1. 算 softmax 概率,降序排 2. 找最小的 k 使前 k 概率和 ≥ p 3. 只保留这 k 个,重归一化后采样 p=0.9:保留覆盖 90% 概率质量的 token;p=1.0:不过滤;p=0.1:极 restrictive,近贪心

模型自信时核采样保留少(可能 2~3 个),不确定时保留多(可能 200),这种自适应使核采样通常比 top-k 产出更好文本。常见组合:温度 0.7 + top-p 0.9(通用);温度 0.0 贪心(确定性任务)。top-k 与 top-p 可组合:先 top-k 再在其上 top-p。

1.11 重参数化技巧(VAE 用)

变分自编码器(VAE)把输入编码成潜空间分布、从中采样、再解码样本。问题是无法对采样操作反向传播:z ~ N(μ,σ²),随机性阻断梯度流,d/dμ [从 N(μ,σ²) 采样] = ???

重参数化技巧把随机性与参数分离:

重参数化采样: ε ~ N(0, 1) (固定随机噪声,无参数) z = μ + σ·ε (参数的确定性函数) 现在 z 是 μ、σ 的确定性可微函数:d(z)/d(μ)=1,d(z)/d(σ)=ε,梯度流过 μ、σ。

这有效是因为 N(μ,σ²)μ + σ·N(0,1) 同分布。关键洞见:把随机性移到无参源(ε),再把样本表成参数的可微变换。 VAE 训练循环:编码器输出 μ 与 log(σ²) → 采样 ε ~ N(0,1) → 算 z = μ + σ·ε → 解码 z 重建输入 → 通过步骤 4、3、2、1 反向传播(可能,因步骤 3 可微)。没有重参数化技巧,VAE 无法用标准反向传播训练——这一洞见让 VAE 变得可行。

1.12 Gumbel-Softmax(可微离散采样)

重参数化技巧对连续分布(高斯)有效。离散分类分布需不同方法,Gumbel-Softmax 提供可微近似。

Gumbel-Max 技巧(不可微):从对数概率 log(p₁)...log(pₖ) 的分类分布采样:① 每类采 g_i ~ Gumbel(0,1)(g = -log(-log(u)),u~Uniform(0,1));② 返回 argmax(log(p_i) + g_i)——产生精确分类样本。

Gumbel-Softmax(可微近似):用软 softmax 替代硬 argmax:y_i = exp((log(p_i)+g_i)/τ) / Σ exp((log(p_j)+g_j)/τ)。温度 τ 控制近似:τ→0 趋 one-hot(硬分类);τ→∞ 趋均匀;τ=1 软近似。前向用 straight-through 估计器:前向用硬 argmax,反向用软 Gumbel-Softmax 梯度。应用:VAE 离散潜变量、神经架构搜索、硬注意力、离散动作 RL。

1.13 分层采样

标准 Monte Carlo 可能在样本空间留空隙。分层采样把空间划成层、每层强采:

把 [0,1] 分 N 等层 [0,1/N),[1/N,2/N),...,每层内均匀采一点 x_i = (i + u_i)/N,u_i ~ Uniform(0,1),i=0,...,N-1 分层采样方差恒 ≤ 标准 Monte Carlo,f 平滑时改进最大,逐段常数函数时精确。

应用:数值积分(拟 Monte Carlo);训练数据划分(保证每折类别平衡);NeRF(沿相机射线分层采样)。

1.14 与扩散模型的联系

扩散模型通过采样过程生成图像。前向过程在 T 步内给图像加高斯噪声直到变纯噪声;反向过程学习去噪,逐步恢复原图。

前向(已知):x_t = √(α_t)·x_{t-1} + √(1-α_t)·ε,ε ~ N(0,I);T 步后 x_T ~ N(0,I) 反向(学习):x_{t-1} = (1/√(α_t))·(x_t - (1-α_t)/√(1-ᾱ_t)·ε_θ(x_t,t)) + σ_t·z,z ~ N(0,I) 每步去噪都是一次采样。

与本节方法的联系:每步去噪用重参数化技巧(采噪声、施加确定性变换);噪声调度 {α_t} 是温度退火;训练用 Monte Carlo 估 ELBO;祖先采样是马尔可夫链(每步只依赖当前态)。整个生成过程是迭代采样:从噪声开始,每步依学到的去噪模型采一个稍不嘈杂的版本。

二、从零实现

完整源码见 phases/01-math-foundations/16-sampling-methods/code/sampling.py(10 个步骤,带可视化)。关键骨架:

import math, random def sample_exponential_inverse_cdf(lam): # 逆 CDF return -math.log(random.random()) / lam def rejection_sample(target_pdf, proposal_sample, proposal_pdf, M): # 拒绝采样 while True: x = proposal_sample(); u = random.random() if u < target_pdf(x) / (M * proposal_pdf(x)): return x def importance_sampling_estimate(f, target_pdf, proposal_pdf, proposal_sample, n): # 重要性采样 total = 0 for _ in range(n): x = proposal_sample(); w = target_pdf(x) / proposal_pdf(x) total += f(x) * w return total / n def monte_carlo_pi(n): # Monte Carlo 估 π inside = sum(1 for _ in range(n) if (lambda x, y: x*x + y*y <= 1)(random.uniform(-1,1), random.uniform(-1,1))) return 4 * inside / n def metropolis_hastings(target_log_pdf, proposal_sample, proposal_log_pdf, x0, n, burn_in): samples = []; x = x0 for i in range(n + burn_in): x_new = proposal_sample(x) log_alpha = (target_log_pdf(x_new) + proposal_log_pdf(x, x_new) - target_log_pdf(x) - proposal_log_pdf(x_new, x)) if math.log(random.random()) < log_alpha: x = x_new if i >= burn_in: samples.append(x) return samples def top_p_sample(logits, p): # 核采样 probs = softmax(logits) indexed = sorted(enumerate(probs), key=lambda x: -x[1]) cumsum = 0; selected = [] for idx, pr in indexed: cumsum += pr; selected.append((idx, pr)) if cumsum >= p: break s = sum(pr for _, pr in selected) return weighted_choice([(idx, pr/s) for idx, pr in selected]) def reparam_sample(mu, sigma): # 重参数化 return mu + sigma * random.gauss(0, 1)

三、框架对比

NumPy 与 SciPy 的生产版:

rng = np.random.default_rng(42) exponential_samples = rng.exponential(scale=2.0, size=10000) # 直接采样,无需逆 CDF from scipy import stats normal = stats.norm(loc=0, scale=1) print(normal.cdf(1.96), normal.ppf(0.975)) # CDF 与逆 CDF(百分位点函数) logits = np.array([2.0, 1.0, 0.5, 0.1, -1.0]) probs = np.exp(logits - logits.max()) / np.exp(logits - logits.max()).sum() token = rng.choice(len(logits), p=probs) # 分类采样

大规模 MCMC 用专用库:PyMC(全贝叶斯建模,NUTS 自适应 HMC)、emcee(集合 MCMC)、NumPyro/JAX(GPU 加速 MCMC)。你从零搭过,现在知道这些库调用在做什么。

四、可复用产物

  • code/sampling.py:全部采样方法的从零实现,含「温度/top-k/top-p 如何改变 token 分布」「MCMC 链轨迹」「重参数化让梯度流过采样」的可视化演示。
  • 一份采样方法决策框架:按任务(生成/估计/探索)选对方法的查找表。

源码见 phases/01-math-foundations/16-sampling-methods/code/

五、练习

  1. (Easy) 实现柯西分布的逆 CDF 采样(CDF F(x)=0.5+arctan(x)/π),生成 1 万样本,画直方图对比真 PDF,观察重尾。
  2. (Medium) 用拒绝采样从 Beta(2,5) 采样,提议用 Uniform(0,1),画接受样本对比真 Beta PDF,算理论接受率。
  3. (Medium) 用 Monte Carlo 估 sin(x) 在 [0,π] 的积分,分别用 1000、1 万、10 万样本,比较各误差,验证误差 O(1/√N)。
  4. (Hard) 实现 Metropolis-Hastings 从 2D 分布 p(x,y) ∝ exp(-(x²y² + x² + y² − 8x − 8y)/2) 采样,画样本与链轨迹,实验不同提议标准差。
  5. (Hard) 搭完整文本生成 demo:给 10 词词表与 logits,用 (a) 贪心、(b) 温度 0.7、(c) top-k=3、(d) top-p=0.9 各生成 20 token 序列,比 5 次运行的输出多样性。

本节要点回顾

  1. 采样是所有生成式 AI 的机制——LLM、扩散、GAN 都靠采样,采样策略控制创意、连贯性、多样性。
  2. 逆 CDF 法:X = F⁻¹(U) 把均匀样本转成任意已知 CDF 分布的样本,精确高效(指数分布 x = -ln(u)/λ)。
  3. 拒绝采样:从简单提议采、按 target/proposal 比接受,精确但高维接受率指数衰减(维度灾难)。
  4. 重要性采样:用 q(x) 的样本估 p(x) 下的期望,加权 w=p/q,是 PPO 的核心。
  5. Monte Carlo:样本平均近似积分,误差 O(1/√N) 与维度无关,故统治高维。
  6. MCMC(Metropolis-Hastings):构造平稳分布为目标的马尔可夫链,接受比保证细致平衡,只需比值故归一化常数相消。
  7. Gibbs 一次更新一维,从条件分布采,接受率 100%,但变量高度相关时混合慢。
  8. LLM 采样三旋钮:温度(除 logits)、top-k(固定候选数)、top-p(自适应候选数),可组合。
  9. 重参数化技巧:z = μ + σ·ε(ε 无参),让采样可微,VAE 训练的关键洞见。
  10. Gumbel-Softmax 是离散分类采样的可微近似;扩散模型每步去噪都是一次重参数化采样。

下一节,我们回到最古老的数学问题——线性方程组:高斯消元、LU/QR/Cholesky 分解、最小二乘正规方程、条件数,以及为何它们就是线性回归与岭回归的底层数学。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U