1. 随机变量与概率分布:模型输出的基础
在LLM中,随机变量最直观的体现就是模型预测的下一个token。每个时刻,模型都会输出一个概率分布,表示词汇表中每个token可能是"下一个词"的概率。
直观理解
想象模型在处理句子"我喜欢北京的"后需要预测下一个词。此时,模型会为词汇表中的每个候选token分配一个概率:
- "天安门":0.3
- "故宫":0.25
- "美食":0.2
- "文化":0.15
- 其他词:0.1
这个分布通过softmax函数从模型的logits输出转换而来:
python
# logits是模型输出的未归一化对数概率
logits = model(input_ids)[:, -1, :] # 获取最后一个位置的logits
probabilities = torch.softmax(logits, dim=-1) # 转换为概率分布
深层意义
概率分布不仅让模型能够进行采样生成,还能反映模型的不确定性程度。分布的形状(是否集中、平坦或有多个峰值)揭示了模型对当前预测的信心程度。
2. 条件概率:语言模型的核心
LLM是自回归(autoregressive)模型,即通过计算条件概率 P ( x t ∣ x < t ) P(x_t | x_{<t}) P(xt∣x<t) 来生成序列。整个序列的联合概率分解为一系列条件概率的乘积:
P ( x 1 , x 2 , ... , x T ) = ∏ t = 1 T P ( x t ∣ x < t ) P(x_1, x_2, \dots, x_T) = \prod_{t=1}^T P(x_t | x_{<t}) P(x1,x2,...,xT)=t=1∏TP(xt∣x<t)
实际运作方式
当模型生成文本时,每一步都依赖于前面已生成的所有内容:
- 第一步: P ( x 1 ) P(x_1) P(x1) - 生成第一个token(无条件)
- 第二步: P ( x 2 ∣ x 1 ) P(x_2|x_1) P(x2∣x1) - 基于第一个token生成第二个
- 第三步: P ( x 3 ∣ x 1 , x 2 ) P(x_3|x_1,x_2) P(x3∣x1,x2) - 基于前两个token生成第三个
以此类推,形成条件概率链。
例子说明
假设模型在生成一个句子:
- 首先生成"我"(假设概率为0.1)
- 然后基于"我"生成"喜欢"(条件概率为0.3)
- 接着基于"我喜欢"生成"学习"(条件概率为0.2)
整个序列"我喜欢学习"的联合概率为:0.1 × 0.3 × 0.2 = 0.006
这种条件概率框架使LLM能够捕捉语言的上下文依赖性,这是它们强大能力的关键所在。
3. 最大似然估计:训练的统计基础
LLM训练的核心目标是最大化训练数据的似然概率,等价于最小化负对数似然(即交叉熵损失):
L ( θ ) = − ∑ t log P θ ( x t ∣ x < t ) \mathcal{L}(\theta) = -\sum_{t}\log P_\theta(x_t | x_{<t}) L(θ)=−t∑logPθ(xt∣x<t)
为什么使用对数?
对数变换有几个重要优势:
- 将乘法转换为加法,避免小数值相乘导致的数值下溢
- 使优化过程更加稳定
- 与信息论中的交叉熵概念直接对应
训练示例
考虑训练过程中的一个小批量文本:"我爱北京天安门":
python
def compute_loss(model, tokens):
# tokens: [batch_size, sequence_length]
logits = model(tokens[:, :-1]) # 预测除最后一个token外的所有位置
targets = tokens[:, 1:] # 目标是下一个token
# 计算每个位置的负对数似然
loss = F.cross_entropy(
logits.view(-1, vocab_size),
targets.view(-1),
reduction='none'
)
# 返回平均损失
return loss.mean()
通过最小化这个损失函数,模型参数θ将被调整以增大训练数据的概率,从而"学习"语言的统计模式。
4. 期望与方差:衡量模型行为
期望值 E [ f ( X ) ] \mathbb{E}[f(X)] E[f(X)] 和方差 Var [ X ] \text{Var}[X] Var[X] 在LLM中有多种应用:
期望的应用
-
评估指标计算:计算平均惊讶度(negative log-likelihood)或平均困惑度
python# 计算平均惊讶度 def average_surprisal(model, text): tokens = tokenize(text) log_probs = model.log_probs(tokens) return -log_probs.mean().item()
-
信息提取:在多次采样中提取"稳定"信息
python# 通过多次采样获取稳定答案 responses = [model.generate(prompt) for _ in range(10)]
方差的应用
-
不确定性量化:高方差表示模型对某些预测的不确定性高
python# 计算预测方差 logits = model(input_ids) probs = F.softmax(logits, dim=-1) entropy = -torch.sum(probs * torch.log(probs), dim=-1) # 高熵≈高方差≈高不确定性
-
多样性控制:在生成时,可以基于方差调整采样策略
方差和期望共同帮助我们理解模型的统计行为,不仅在评估模型性能时有用,也为生成策略提供了理论指导。
5. 贝叶斯定理:从先验到后验
虽然传统LLM训练不直接使用贝叶斯方法,但贝叶斯思想在多个方面得到应用:
P ( θ ∣ D ) ∝ P ( D ∣ θ ) P ( θ ) P(\theta | D) \propto P(D | \theta)P(\theta) P(θ∣D)∝P(D∣θ)P(θ)
实际应用
-
参数正则化:权重衰减可看作对参数的高斯先验
python# L2正则化(权重衰减) loss = task_loss + weight_decay * sum(p.pow(2).sum() for p in model.parameters())
-
小样本学习:少样本(few-shot)提示可视为后验更新
- 没有示例时,模型使用先验P(θ)
- 提供few-shot示例后,模型更新为后验P(θ|少量示例)
-
推理校准:后验调整可以改善模型预测
python# 简单的后验校准示例 def calibrate_probabilities(probs, temperature=1.0, label_smoothing=0.0): # 温度缩放 scaled_logits = torch.log(probs) / temperature calibrated = F.softmax(scaled_logits, dim=-1) # 标签平滑(混合均匀先验) if label_smoothing > 0: uniform = torch.ones_like(calibrated) / calibrated.size(-1) calibrated = (1 - label_smoothing) * calibrated + label_smoothing * uniform return calibrated
贝叶斯框架为我们提供了整合先验知识和更新置信度的强大工具,这在微调、迁移学习和不确定性建模中特别有价值。
6. 采样方法:平衡确定性与创造性
生成文本时,我们需要从模型的概率分布中采样。不同采样策略影响生成文本的多样性和质量:
温度采样
调整温度T可以控制分布的平滑度:
P T ( x ) ∝ P ( x ) 1 / T P_T(x) \propto P(x)^{1/T} PT(x)∝P(x)1/T
python
def temperature_sampling(logits, temperature=1.0):
# temperature=0会变成贪婪搜索
# temperature<1使分布更尖锐(更确定)
# temperature>1使分布更平坦(更多样)
scaled_logits = logits / temperature
probs = F.softmax(scaled_logits, dim=-1)
next_token = torch.multinomial(probs, num_samples=1)
return next_token
- 温度接近0:贪婪搜索,总是选最高概率词
- 温度为1:保持原始分布
- 温度大于1:增加低概率事件的采样机会
Top-k与Nucleus采样
这些方法通过截断分布尾部来减少低质量样本:
python
def top_k_sampling(logits, k=50):
# 只保留概率最高的k个token
values, indices = torch.topk(logits, k)
probs = F.softmax(values, dim=-1)
next_token = indices[torch.multinomial(probs, num_samples=1)]
return next_token
def nucleus_sampling(logits, p=0.9):
# 保留累积概率达到p的最小token集合
sorted_logits, sorted_indices = torch.sort(logits, descending=True)
cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
# 找到第一个累积概率超过p的位置
sorted_indices_to_keep = cumulative_probs <= p
# 在某些情况下,我们至少保留一个token
if torch.sum(sorted_indices_to_keep) == 0:
sorted_indices_to_keep[0] = True
indices_to_keep = sorted_indices[sorted_indices_to_keep]
logits_to_keep = logits[indices_to_keep]
probs = F.softmax(logits_to_keep, dim=-1)
next_token = indices_to_keep[torch.multinomial(probs, num_samples=1)]
return next_token
这些采样方法直接影响生成文本的质量,是LLM应用中的关键决策点。温度和采样策略的选择取决于任务要求:
- 事实性问答:低温度,偏好确定性高的输出
- 创意写作:较高温度,允许更多样的输出
- 代码生成:通常使用较低温度但带nucleus采样,平衡正确性和多样性
7. 马尔可夫性:序列依赖的表示
虽然Transformer架构理论上可以考虑任意长的上下文,但实际上,LLM仍然是一种强化版的马尔可夫模型:当前token的生成依赖于固定长度窗口内的历史。
马尔可夫性与上下文窗口
标准马尔可夫模型假设:
P ( x t ∣ x < t ) = P ( x t ∣ x t − k , ... , x t − 1 ) P(x_t | x_{<t}) = P(x_t | x_{t-k}, \ldots, x_{t-1}) P(xt∣x<t)=P(xt∣xt−k,...,xt−1)
LLM则扩展为:
P ( x t ∣ x < t ) = P ( x t ∣ x m a x ( 1 , t − C ) , ... , x t − 1 ) P(x_t | x_{<t}) = P(x_t | x_{max(1,t-C)}, \ldots, x_{t-1}) P(xt∣x<t)=P(xt∣xmax(1,t−C),...,xt−1)
其中C是上下文窗口长度(如GPT-3为2048,Claude 3为200k+)。
有限记忆的影响
上下文窗口限制导致的问题包括:
- 无法引用超出窗口的信息
- 长文档理解中的一致性挑战
- 对长文本生成的连贯性约束
这种有限马尔可夫性质启发了许多改进方向,如长上下文模型、外部内存机制、检索增强等。
8. 蒙特卡洛估计:基于采样的评估
蒙特卡洛方法通过多次随机采样来估计统计特性,在LLM中有重要应用:
应用场景
-
不确定性估计:通过多次采样估计预测的置信区间
pythondef estimate_confidence_interval(model, prompt, n_samples=100): # 生成多个回答 responses = [model.generate(prompt) for _ in range(n_samples)] # 分析回答的分布(例如,对于是/否问题) yes_count = sum(1 for r in responses if "是" in r[:10]) confidence = max(yes_count, n_samples - yes_count) / n_samples return confidence
-
多样性度量:评估生成结果的多样性
pythondef measure_diversity(model, prompt, n_samples=10): responses = [model.generate(prompt) for _ in range(n_samples)] # 计算生成文本之间的平均相似度 similarities = [] for i in range(n_samples): for j in range(i+1, n_samples): sim = compute_similarity(responses[i], responses[j]) similarities.append(sim) return sum(similarities) / len(similarities)
-
集成预测:整合多次预测结果以提高准确性
pythondef ensemble_prediction(model, prompt, n_samples=10): predictions = [model.generate(prompt) for _ in range(n_samples)] # 可以通过投票、平均或更复杂的方法整合结果 return most_common(predictions)
蒙特卡洛方法帮助我们更好地理解模型行为的统计特性,特别是在处理高度不确定或多样化输出的场景中。
9. 随机过程与序列建模:统计依赖的捕捉
语言生成可视为一种离散时间随机过程,LLM通过自注意力机制捕捉这一过程中的统计依赖:
自注意力与随机过程
Transformer的自注意力机制计算:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dk QKT)V
这实际上是在估计序列中各位置之间的统计依赖强度。注意力权重可以解释为:位置j对预测位置i的影响程度。
深层统计依赖
LLM通过多层注意力捕捉复杂的统计依赖:
- 浅层可能关注局部语法模式
- 深层可能捕捉全局语义依赖
- 多头注意力则并行捕捉不同类型的依赖关系
这种分层设计使LLM能够学习句法、语义和篇章层面的统计规律,从而生成连贯且有意义的文本。
10. 校准:确保概率预测的可靠性
模型校准衡量预测概率与实际频率的一致性:
校准重要性
假设模型以90%的置信度预测某些事实,如果模型校准良好,这些预测约90%应该是正确的。
python
def expected_calibration_error(probs, correct):
"""
计算预期校准误差
probs: 预测概率
correct: 对应的正确与否标记(0/1)
"""
# 将概率分成几个bin
n_bins = 10
bins = np.linspace(0, 1, n_bins + 1)
bin_indices = np.digitize(probs, bins) - 1
ece = 0
for bin_idx in range(n_bins):
# 找到落在这个bin中的预测
mask = bin_indices == bin_idx
if not np.any(mask):
continue
bin_probs = probs[mask]
bin_correct = correct[mask]
# 计算这个bin中的平均概率和准确率
avg_prob = np.mean(bin_probs)
avg_acc = np.mean(bin_correct)
# 加权绝对误差
ece += np.abs(avg_prob - avg_acc) * (np.sum(mask) / len(probs))
return ece
校准方法
- 温度缩放:通过除以温度参数调整logits
- Platt缩放:学习线性变换校准概率
- 模型集成:多个模型预测结合可提高校准性
良好的校准对于许多应用至关重要,如医疗诊断、金融预测和自动决策系统,因为它们需要依赖模型不仅给出正确答案,还要准确报告自己的确定性。
11. 似然比与对比评估:模型比较的工具
似然比是比较两个概率模型的强大工具:
P model1 ( x ) P model2 ( x ) \frac{P_{\text{model1}}(x)}{P_{\text{model2}}(x)} Pmodel2(x)Pmodel1(x)
实际应用
-
对抗训练:通过似然比区分真实vs生成文本
pythondef discriminator_loss(real_data, generated_data, model1, model2): # 计算似然比,用于区分真实数据和生成数据 real_log_probs_1 = model1.log_probs(real_data) real_log_probs_2 = model2.log_probs(real_data) real_ratio = torch.exp(real_log_probs_1 - real_log_probs_2) gen_log_probs_1 = model1.log_probs(generated_data) gen_log_probs_2 = model2.log_probs(generated_data) gen_ratio = torch.exp(gen_log_probs_1 - gen_log_probs_2) # 优化目标:增大真实数据的比值,减小生成数据的比值 loss = -torch.mean(torch.log(real_ratio)) - torch.mean(torch.log(1 - gen_ratio)) return loss
-
模型选择:比较不同模型对数据的拟合能力
pythondef compare_models(test_data, model_a, model_b): log_probs_a = model_a.log_probs(test_data) log_probs_b = model_b.log_probs(test_data) # 如果比值>1,则模型A更适合数据 log_ratio = log_probs_a - log_probs_b return log_ratio.mean()
-
倾向性得分:用于评估生成偏好
pythondef calculate_preference_score(model, prompt_a, prompt_b): completion = model.generate(prompt_a) # 计算完成后的文本在两个不同提示下的对数概率 log_prob_a = model.conditional_log_prob(completion, prompt_a) log_prob_b = model.conditional_log_prob(completion, prompt_b) # 返回倾向性得分 return log_prob_a - log_prob_b
似然比是评估和比较概率模型的强大工具,在模型选择、假设检验和对抗学习中都有广泛应用。
概率论视角的综合应用
这些概率论概念不是孤立的,而是形成了一个连贯的理论框架,支撑着LLM的各个方面:
-
从训练到推理的完整流:
- 模型定义:条件概率分布 P ( x t ∣ x < t ) P(x_t|x_{<t}) P(xt∣x<t)
- 训练目标:通过最大似然估计优化参数
- 推理方法:通过各种采样策略从概率分布中生成样本
- 评估标准:困惑度、校准误差等概率度量
-
不确定性的系统处理:
- 表示:概率分布的熵
- 传播:通过采样和蒙特卡洛方法
- 量化:方差、置信区间
- 通信:校准的概率输出
-
概率框架的实际价值:
- 提供理论基础解释模型行为
- 指导采样策略的选择
- 启发新的训练和推理方法
- 评估模型性能的系统标准