跳转至

22 - 大语言模型原理

⚠️ 时效性说明:本章涉及前沿模型/价格/榜单等信息,可能随版本快速变化;请以论文原文、官方发布页和 API 文档为准。

大语言模型原理图

📌 导航提示:本章从机器学习视角提供LLM概览。详细LLM技术教程请参考 LLM学习/ 目录;LLM应用与实践请参考 LLM应用/ 目录。


🗺️ LLM在ML体系中的位置

Text Only
机器学习
└── 深度学习
    └── 自然语言处理
        └── 预训练语言模型
            └── 大语言模型 (LLM) ← 当前前沿

LLM是ML发展的自然延伸:更大的模型 + 更多的数据 + 更强的算力 = 涌现出传统ML不具备的能力。


📏 Scaling Law:规模定律

Scaling Law是理解LLM的关键框架,揭示了性能与三个变量的幂律关系:

变量 含义 趋势
模型参数量 N 网络权重数量 ↑ 对数线性提升性能
数据量 D 训练token数 ↑ 对数线性提升性能
计算量 C FLOPs ≈ 6ND(训练所需算力)

3.1 Kaplan Scaling Laws (2020)

OpenAI在2020年发表的奠基性研究,首次系统性地量化了模型性能与规模的关系。

核心数学形式

\[L(N) = \left(\frac{N_c}{N}\right)^{\alpha_N}, \quad L(D) = \left(\frac{D_c}{D}\right)^{\alpha_D}\]

其中: - \(L\):交叉熵损失(越低越好) - \(N\):模型参数量 - \(D\):训练数据量(token数) - \(N_c, D_c\):常数项,代表"临界规模" - \(\alpha_N, \alpha_D\):幂律指数

Kaplan的关键发现

参数 估计值 含义
\(\alpha_N\) ≈ 0.076 参数量每增加10倍,损失下降约15%
\(\alpha_D\) ≈ 0.095 数据量每增加10倍,损失下降约20%
\(N_c\) \(8.8 \times 10^{13}\) 理论上的参数临界点
\(D_c\) \(5.4 \times 10^{13}\) 理论上的数据临界点

组合损失函数

\[L(N, D) = \left(\frac{N_c}{N}\right)^{\alpha_N} + \left(\frac{D_c}{D}\right)^{\alpha_D} + E\]

其中 \(E\) 是不可约损失(irreducible loss),代表任务的理论下界。

Kaplan结论:在固定计算预算下,优先扩大模型规模比增加数据更有效。

3.2 Chinchilla Scaling Laws (2022)

DeepMind的Chinchilla研究修正了Kaplan的结论,提出了不同的最优分配策略。

核心公式

\[L(N, D) = \frac{A}{N^\alpha} + \frac{B}{D^\beta} + E\]

Chinchilla参数估计

参数 估计值 与Kaplan对比
\(\alpha\) ≈ 0.34 显著大于Kaplan的0.076
\(\beta\) ≈ 0.28 显著大于Kaplan的0.095
\(A\) ≈ 406.4 -
\(B\) ≈ 410.7 -
\(E\) ≈ 1.69 -

3.3 Chinchilla最优计算分配

计算预算约束

\[C = 6ND \quad \text{(训练FLOPs)}\]

最优分配推导

在固定计算预算 \(C\) 下,最小化损失 \(L(N, D)\)

\[\min_{N, D} L(N, D) \quad \text{s.t.} \quad 6ND = C\]

使用拉格朗日乘数法求解:

\[N_{opt} \propto C^{\alpha_N / (\alpha_N + \alpha_D)}, \quad D_{opt} \propto C^{\alpha_D / (\alpha_N + \alpha_D)}\]

Chinchilla最优解

\[N_{opt} \approx 0.6 \cdot C^{0.5}, \quad D_{opt} \approx 0.3 \cdot C^{0.5}\]
计算预算 (FLOPs) 最优参数量 最优数据量 (tokens) 典型模型规模
\(10^{20}\) 440M 9B 小型模型
\(10^{21}\) 1.4B 29B GPT-2规模
\(10^{22}\) 4.4B 91B 中型模型
\(10^{23}\) 14B 288B LLaMA-13B
\(10^{24}\) 44B 912B Chinchilla-70B
\(10^{25}\) 139B 2.9T GPT-3.5规模

Kaplan vs Chinchilla对比

Python
# 对比两种Scaling Law的最优分配策略
import numpy as np

def kaplan_optimal(C):
    """Kaplan: 优先扩大模型"""
    # Kaplan建议 N ∝ C^0.73, D ∝ C^0.27
    N = 0.1 * (C ** 0.73)
    D = C / (6 * N)
    return N, D

def chinchilla_optimal(C):
    """Chinchilla: 模型和数据平衡扩展"""
    # Chinchilla定律: C ≈ 6ND, 且N与D等比例增长
    # 即 N ∝ C^0.5, D ∝ C^0.5, 满足 6*N*D = C
    N = (C / 6) ** 0.5  # N = sqrt(C/6)
    D = (C / 6) ** 0.5  # D = sqrt(C/6), 使得 6*N*D = C
    return N, D

# 以GPT-3的计算预算为例 (约3.14 × 10^23 FLOPs)
C = 3.14e23

N_kaplan, D_kaplan = kaplan_optimal(C)
N_chinchilla, D_chinchilla = chinchilla_optimal(C)

print(f"计算预算: {C:.2e} FLOPs")
print(f"\nKaplan最优: N={N_kaplan/1e9:.1f}B, D={D_kaplan/1e9:.1f}B tokens")
print(f"Chinchilla最优: N={N_chinchilla/1e9:.1f}B, D={D_chinchilla/1e9:.1f}B tokens")
print(f"\nGPT-3实际: N=175B, D=300B tokens")
print(f"→ GPT-3更接近Kaplan策略(模型偏大,数据偏少)")

3.4 实践中的调整

现代LLM的偏离

模型 参数量 训练数据 偏离Chinchilla原因
LLaMA-7B 7B 1T tokens 数据远超最优(~20x),推理效率优先
LLaMA-65B 65B 1.4T tokens 数据仍超最优,兼顾推理和训练
GPT-4 ~1.8T(推测) ~13T(推测) 推理成本主导,数据效率优先

偏离原因分析

  1. 推理成本:小模型推理更快,因此用更多数据训练小模型
  2. 数据质量:高质量数据稀缺,需要更大的模型来补偿
  3. 后训练:SFT和RLHF阶段会进一步提升性能
  4. 领域适应:特定领域可能需要不同的最优分配

🌊 涌现能力理论

4.1 什么是涌现能力

定义:涌现能力(Emergent Abilities)是指模型在达到一定规模后突然出现、而较小模型完全不具备的能力。

数学描述

\[\text{Performance}(N) = \begin{cases} \approx \text{Random} & N < N_{critical} \\ \text{Sharp Improvement} & N \approx N_{critical} \\ \text{Plateau} & N \gg N_{critical} \end{cases}\]

4.2 主要涌现能力

能力 描述 临界规模 典型任务
上下文学习 (ICL) 从示例中学习新模式 ~1B Few-shot learning
思维链推理 (CoT) 分步骤解决复杂问题 ~10B 数学推理、逻辑推理
指令遵循 理解并执行复杂指令 ~100B 多步骤任务执行
代码生成 生成可执行代码 ~10B 程序合成
数学推理 解决数学问题 ~100B GSM8K, MATH

4.3 临界规模点量化

Wei et al. (2022) 的实证研究

Python
# 涌现能力的量化分析示例
import matplotlib.pyplot as plt
import numpy as np

# 模型规模(参数量,单位:B)
model_sizes = [0.1, 0.3, 1, 3, 10, 30, 100, 280]

# 模拟不同任务的性能曲线
def emergence_curve(N, N_crit, max_perf=100):
    """涌现能力的Sigmoid模型"""
    k = 10 / N_crit  # 陡峭度
    return max_perf / (1 + np.exp(-k * (N - N_crit)))

# 不同任务的临界规模
tasks = {
    "算术运算": 10,
    "思维链推理": 30,
    "多语言理解": 5,
    "代码生成": 10,
    "数学问题": 100,
}

plt.figure(figsize=(12, 6))
for task, N_crit in tasks.items():
    perf = [emergence_curve(N, N_crit) for N in model_sizes]
    plt.plot(model_sizes, perf, 'o-', label=f'{task} (临界点: {N_crit}B)')

plt.xscale('log')
plt.xlabel('模型参数量 (B)')
plt.ylabel('任务性能')
plt.title('涌现能力与模型规模的关系')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

4.4 涌现能力的理论解释

假设1:组合性假设 - 大模型学会了将基础能力组合成复杂能力 - 数学表示:\(\text{Complex} = f(\text{Basic}_1, \text{Basic}_2, ..., \text{Basic}_n)\)

假设2:临界数据假设 - 某些能力需要足够的训练数据才能触发 - 稀有模式在小数据集上无法有效学习

假设3:表示空间假设 - 大模型的表示空间维度更高 - 可以编码更复杂的语义关系

假设4:优化动力学假设 - 大模型的损失景观不同 - 存在小模型无法到达的局部最优

4.5 涌现能力的争议

Skepticism (Schaeffer et al., 2023): - 涌现可能是评估指标的"幻觉" - 使用非线性指标(如Exact Match)会产生突然跃升的假象 - 线性指标(如Token Accuracy)显示平滑提升

反驳观点: - 实际应用中,Exact Match等指标更有意义 - 即使是"幻觉",这种"幻觉"具有实用价值


🏋️ 训练稳定性

5.1 Loss Spike问题

定义:训练过程中损失突然大幅上升,可能导致训练崩溃。

Loss Spike的典型模式

Text Only
Loss
  │     ╱╲
  │    ╱  ╲╱╲
  │   ╱      ╲___
  │  ╱           ╲
  │ ╱             ╲
  │╱               ╲
  └──────────────────→ Training Steps
       ↑ Loss Spike

主要原因

原因 机制 缓解策略
学习率过大 优化步长超过损失曲面的曲率 学习率预热、梯度裁剪
数据异常 罕见或错误数据导致梯度爆炸 数据过滤、异常检测
梯度爆炸 梯度在反向传播中指数增长 梯度裁剪、LayerNorm
参数漂移 长期训练导致参数偏离最优 学习率衰减、权重衰减

5.2 梯度问题与缓解

梯度爆炸/消失的数学分析

对于深度为 \(L\) 的网络:

\[\frac{\partial L}{\partial W_1} = \frac{\partial L}{\partial h_L} \prod_{l=2}^{L} \frac{\partial h_l}{\partial h_{l-1}} \cdot \frac{\partial h_1}{\partial W_1}\]

\(\|\frac{\partial h_l}{\partial h_{l-1}}\| > 1\) 时梯度爆炸,\(< 1\) 时梯度消失。

缓解策略

Python
import torch
import torch.nn as nn

class StableTransformerBlock(nn.Module):
    """稳定的Transformer块,包含多种梯度稳定技术"""

    def __init__(self, d_model, n_head, dropout=0.1):
        super().__init__()
        # 1. Pre-LayerNorm(比Post-LN更稳定)
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)

        self.attn = nn.MultiheadAttention(d_model, n_head, dropout=dropout)
        self.ffn = nn.Sequential(
            nn.Linear(d_model, 4 * d_model),
            nn.GELU(),  # GELU比ReLU更平滑
            nn.Linear(4 * d_model, d_model),
        )
        self.dropout = nn.Dropout(dropout)

        # 2. 可学习的缩放因子(用于稳定训练初期)
        self.attn_scale = nn.Parameter(torch.ones(1) * 0.1)
        self.ffn_scale = nn.Parameter(torch.ones(1) * 0.1)

    def forward(self, x):
        # Pre-LN结构
        # 3. 残差连接 + 缩放
        attn_out, _ = self.attn(self.norm1(x), self.norm1(x), self.norm1(x))
        x = x + self.attn_scale * self.dropout(attn_out)

        ffn_out = self.ffn(self.norm2(x))
        x = x + self.ffn_scale * self.dropout(ffn_out)

        return x


def gradient_clipping(model, max_norm=1.0):
    """梯度裁剪:防止梯度爆炸"""
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)
    return model


def adaptive_gradient_clipping(model, clip_factor=0.01):
    """自适应梯度裁剪(AGC):根据参数范数动态调整"""
    for param in model.parameters():
        if param.grad is not None:
            param_norm = torch.norm(param)
            grad_norm = torch.norm(param.grad)
            max_norm = param_norm * clip_factor
            if grad_norm > max_norm and grad_norm > 0:
                param.grad.data.mul_(max_norm / grad_norm)
    return model

5.3 学习率调度策略

1. Warmup策略

\[\eta_t = \eta_{base} \cdot \min\left(1, \frac{t}{T_{warmup}}\right)\]
Python
def warmup_lr(step, warmup_steps, base_lr):
    """线性预热学习率"""
    return base_lr * min(1.0, step / warmup_steps)

2. Cosine Decay

\[\eta_t = \eta_{min} + \frac{1}{2}(\eta_{max} - \eta_{min})\left(1 + \cos\left(\frac{t}{T}\pi\right)\right)\]
Python
import math

def cosine_decay_lr(step, total_steps, max_lr, min_lr=0):
    """余弦衰减学习率"""
    ratio = step / total_steps
    return min_lr + 0.5 * (max_lr - min_lr) * (1 + math.cos(math.pi * ratio))


def cosine_decay_with_warmup(step, warmup_steps, total_steps, max_lr, min_lr=0):
    """带预热的余弦衰减(LLM训练标准配置)"""
    if step < warmup_steps:
        # 线性预热
        return max_lr * step / warmup_steps
    else:
        # 余弦衰减
        ratio = (step - warmup_steps) / (total_steps - warmup_steps)
        return min_lr + 0.5 * (max_lr - min_lr) * (1 + math.cos(math.pi * ratio))


# 可视化学习率调度
def plot_lr_schedule():
    import matplotlib.pyplot as plt

    total_steps = 100000
    warmup_steps = 2000
    max_lr = 6e-4
    min_lr = 6e-5

    steps = list(range(total_steps))
    lrs = [cosine_decay_with_warmup(s, warmup_steps, total_steps, max_lr, min_lr)
           for s in steps]

    plt.figure(figsize=(12, 4))
    plt.plot(steps, lrs)
    plt.axvline(x=warmup_steps, color='r', linestyle='--', label=f'Warmup End ({warmup_steps})')
    plt.xlabel('Training Steps')
    plt.ylabel('Learning Rate')
    plt.title('Cosine Decay with Warmup Learning Rate Schedule')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.show()

plot_lr_schedule()

3. WSD(Warmup-Stable-Decay)策略

现代LLM(如Llama 3)采用的策略:

Python
def wsd_schedule(step, warmup_steps, stable_steps, decay_steps, max_lr, min_lr):
    """
    WSD学习率调度:Warmup -> Stable -> Decay

    优点:
    1. 稳定阶段便于checkpoint选择
    2. 衰减阶段快速收敛
    3. 适合继续预训练
    """
    if step < warmup_steps:
        return max_lr * step / warmup_steps
    elif step < warmup_steps + stable_steps:
        return max_lr
    else:
        decay_progress = (step - warmup_steps - stable_steps) / decay_steps
        return min_lr + (max_lr - min_lr) * 0.5 * (1 + math.cos(math.pi * decay_progress))

5.4 训练稳定性最佳实践

技术 作用 典型配置
Pre-LayerNorm 稳定梯度流 所有Transformer层
梯度裁剪 防止梯度爆炸 max_norm=1.0
学习率Warmup 稳定训练初期 前1-2%步数
权重衰减 防止过拟合 0.1
Dropout 正则化 0.1(大模型可降低或不用)
混合精度训练 加速+正则化效果 BF16/FP16
μP (Maximal Update Parametrization) 超参数迁移 简化大模型调参

完整的训练配置示例

Python
from dataclasses import dataclass

@dataclass
class LLMTrainingConfig:
    """LLM训练稳定性配置"""

    # 模型配置
    hidden_size: int = 4096
    num_layers: int = 32
    num_heads: int = 32

    # 优化配置
    learning_rate: float = 3e-4
    weight_decay: float = 0.1
    beta1: float = 0.9
    beta2: float = 0.95  # AdamW的beta2,比默认0.999更小

    # 学习率调度
    warmup_steps: int = 2000
    lr_scheduler: str = "cosine"
    min_lr_ratio: float = 0.1  # 最终LR = max_lr * 0.1

    # 梯度控制
    max_grad_norm: float = 1.0
    grad_clip_type: str = "global"  # global或adaptive

    # 批次配置
    batch_size: int = 4_000_000  # 总token数
    gradient_accumulation_steps: int = 1

    # 精度配置
    dtype: str = "bf16"  # bf16比fp16更稳定
    grad_dtype: str = "fp32"  # 梯度用fp32保持精度

核心洞察: - 三者需要同步扩展,单一增长回报递减 - Chinchilla Law:最优策略是模型和数据同比例扩大(非一味加大模型) - 涌现能力:部分能力(思维链推理、上下文学习等)在模型达到特定规模后突然出现 - 训练稳定性:大模型训练需要精心设计的稳定性策略,包括梯度裁剪、学习率调度和正则化


🔄 训练范式概述

LLM的训练是一个多阶段流程:

阶段 目标 数据 一句话描述
预训练 (Pre-training) 学习语言知识 万亿级无标注文本 通过下一词预测任务学习世界知识和语言规律
监督微调 (SFT) 学会遵循指令 十万级高质量指令-回答对 让模型学会"对话"和"遵循指令"的格式
RLHF / DPO 对齐人类偏好 人类偏好排序数据 让模型输出更安全、有用、符合人类期望
Text Only
原始文本 → [预训练] → 基座模型 → [SFT] → 指令模型 → [RLHF/DPO] → 对齐模型
            (知识)              (格式)               (价值观)

🔗 LLM与传统ML的关系

维度 传统ML LLM
学习范式 从标注数据学习特定映射 从海量文本学习通用表示
任务适配 每个任务训练独立模型 一个模型适应多种任务(Prompt/ICL)
特征工程 核心环节(人工设计) 几乎消除(端到端学习)
样本需求 任务相关标注数据 预训练无需标注,下游少样本即可
可解释性 部分模型可解释 黑盒,可解释AI是活跃研究方向
评估方式 准确率/F1等标准指标 新增:人类评估、MMLU等综合基准

关键联系: - LLM的优化仍是梯度下降 + 反向传播,与传统ML一脉相承 - 正则化、学习率调度、数据质量等ML基本功在LLM训练中同样至关重要 - 传统ML在表格数据、低延迟推理等场景依然不可替代


📋 面试要点

  1. 什么是Scaling Law? → 模型性能与参数量、数据量、计算量呈幂律关系;Chinchilla Law强调数据和模型需同步扩展
  2. 预训练→SFT→RLHF三阶段各解决什么问题? → 知识获取 → 指令遵循 → 人类偏好对齐
  3. LLM的涌现能力有哪些? → 上下文学习(ICL)、思维链推理(CoT)、指令遵循等,小模型不具备
  4. LLM vs 传统ML各自的优势场景? → LLM:自然语言理解与生成;传统ML:表格数据、低延迟、高可解释性需求

✏️ 练习

  1. 体系定位分析:绘制一张思维导图,展示从线性回归到LLM的技术演进路径,标注各阶段的核心突破点(表示学习、注意力机制、预训练、Scaling Law等)。

📖 下一步学习23-可解释AI与因果推断.md | LLM详细教程 → LLM学习/ | LLM应用实践 → LLM应用/