Skip to content

2.3 大模型训练流程:从 Pre-training 到 RLHF

上一节我们拆解了 Transformer 架构——自注意力机制让模型能够"同时看到"序列中的每一个 token,位置编码赋予了它顺序感,前馈网络和残差连接则把深层表达稳稳地堆叠起来。如果你已经理解了"输入 token → 嵌入 → 多层注意力与 FFN → 输出概率分布"这条数据流,那么一个自然的问题就是:这个架构里的几千亿个参数,到底是怎么获得那些令人惊叹的能力的? 模型不是生来就会写代码、做翻译、回答问题的——它需要经历一个极其庞大的训练过程。本节就来回答"大模型是怎么训练出来的"这个问题。


从两个阶段说起:Pre-training 与 Post-training

大模型的训练并非一步到位,而是分为两大阶段。

第一阶段是预训练(Pre-training)。在这个阶段,模型阅读数万亿个 token 的文本——网页、书籍、代码、论文、对话——通过不断预测"下一个 token 是什么"来学习语言的统计规律和世界的知识。这一阶段耗费的算力占整个训练流程的 99% 以上,是大模型能力的"地基"。

第二阶段是后训练(Post-training),也常被称为对齐(Alignment)。预训练完的模型只是一个"续写机器"——你给它一段文字,它接着往下写,但它并不理解什么是"好的回答"。后训练的目标,就是把这个"续写机器"变成一个"有用的助手"。这通常包括监督微调(SFT)和基于人类反馈的强化学习(RLHF)两个子步骤。第 4 章会深入讲解这些方法的实现细节,本节只需理解它们在整个训练流程中的位置和作用即可。

一个直观的类比:预训练像是让一个人"读万卷书",走遍天下,博览群书,积累了海量的知识和语言能力;后训练则像是让这个人"学礼仪"——学会听人说话、理解意图、给出有帮助且无害的回答。


预训练:读万卷书

预训练是大模型训练的核心,也是算力消耗最大的环节。我们用"读万卷书"这个类比来理解它的本质。

一个孩子从出生到上大学,大约读了十几年书,接触的文本量也许在几亿到几十亿个 token 的量级。而 Llama 3 的预训练数据是 15 万亿(15T)个 token——相当于一个人不眠不休读上几十万年才能读完的内容。模型通过阅读如此庞大的语料,学会了语法、语义、常识、推理、代码、多语言等方方面面的能力。

为什么"读万卷书"有效? 因为语言是世界的投影。文本中包含了人类对世界的全部描述——物理规律在物理课本里,编程逻辑在代码仓库里,历史事件在百科全书里,人际交往的智慧在小说和对话里。模型通过预测下一个 token,被迫去理解这些文本背后的模式和规律。当一个模型见过足够多的"if it rains, the ground will be __"之后,它自然学会了因果关联;当它见过足够多的 Python 代码之后,它自然理解了缩进和语法。

预训练的完整流程可以概括为以下几个步骤:

1. 数据收集  →  2. 数据清洗  →  3. 分词与编码

4. 模型初始化  →  5. 分布式训练  →  6. 模型保存与检查点

                            7. 评估  →  8. 安全对齐  →  9. 发布

下面逐步展开。


训练数据:不止于多,更要精

以 Llama 3 为例,其训练数据约 15T tokens,来源覆盖极其广泛:

数据来源大致占比说明
网页文本~50%Common Crawl 等公开网页爬取
代码~15%GitHub 等代码仓库
书籍~10%电子书、学术论文、技术文档
维基百科~5%高质量百科知识
对话数据~5%论坛、问答平台
其他~15%新闻、数学、多语言等

网页文本占了半壁江山,但网页数据质量参差不齐——有精心编写的文章,也有垃圾内容、重复内容、甚至有害信息。因此数据清洗是预训练中极其关键的一环。

数据清洗的关键步骤包括:

  • 去重:同一篇文章可能在数千个网站被转载,不去重的话模型会浪费算力反复学习相同内容,甚至过拟合。常用方法有 MinHash(近似相似度检测)和 SimHash(指纹哈希),能在大规模数据上快速识别重复。
  • 质量过滤:通过语言检测筛选目标语言、用小模型计算困惑度(perplexity)来过滤低质量文本——如果一个文本的困惑度异常高,说明它很可能是乱码或低质量内容。
  • 有害内容过滤:使用分类器识别并移除暴力、色情、仇恨言论等内容。
  • PII 脱敏:个人身份信息(手机号、身份证号、邮箱等)需要被检测并替换或删除,防止模型在生成时泄露隐私。

一个值得记住的事实:原始爬取数据经过清洗后,通常只有 30%~50% 会被保留用于训练。也就是说,15T tokens 的训练数据背后,原始数据可能是 30T~50T tokens。数据质量远比数据量重要——这一点我们在后面的"常见误区"中还会讨论。


Scaling Law:模型越大越好吗?

理解了预训练在做什么,下一个关键问题是:我们怎么决定建多大的模型、用多少数据来训练? 这就引出了大模型领域最重要的经验规律之一——Scaling Law(缩放定律)。

2020 年,OpenAI 发表了一篇具有里程碑意义的论文,研究了模型损失(loss)与三个因素之间的关系:模型参数量 N、训练数据量 D 和计算量 C。他们发现了一个惊人的规律:

模型的测试损失与参数量、数据量、计算量之间呈现幂律关系。

数学表达为:

L(N) = (N_c / N)^α_N    —— 模型参数量越大,损失越小
L(D) = (D_c / D)^α_D    —— 训练数据越多,损失越小
L(C) = (C_c / C)^α_C    —— 计算量越大,损失越小

其中 α ≈ 0.05~0.1

用直觉来理解这个公式在说什么:

想象你在爬山。山越高(模型越大),你能看到越远的风景(性能越好)。但每往上走一步,消耗的体力也呈指数级增加。Scaling Law 告诉我们的是"山的高度"和"体力消耗"之间的数学关系——你花两倍的算力,大约能换来 10%~15% 的损失降低。这不是线性回报,而是边际递减的。

但关键在于:这个递减不会停止。 只要你持续增加算力、数据和参数,模型的损失就会持续下降。这正是 2020 年以来大模型持续变大的理论基础——它不是盲目"堆大",而是有数学规律支撑的。

Chinchilla 定律:算力的最优分配

OpenAI 的 Scaling Law 告诉我们"越大越好",但没告诉我们"在固定算力预算下,到底应该把预算花在更大的模型上,还是更多的数据上"。

2022 年,DeepMind 发表了 Chinchilla 论文,回答了这个问题:

对于给定的计算预算,最优的模型大小和训练数据量应该等比例增长。

具体来说,最优配置是每 1 个参数搭配约 20 个训练 token

最优配置:每 1 个参数配 20 个 tokens

例如:
- 1B 参数模型  →  最优训练数据量约 20B tokens
- 7B 参数模型  →  最优训练数据量约 140B tokens
- 70B 参数模型 →  最优训练数据量约 1.4T tokens
- 405B 参数模型 → 最优训练数据量约 8.1T tokens

Chinchilla 定律的直觉解释: 想象你要建一座图书馆。模型参数量是"书架的大小",训练数据是"书的数量"。如果你有一个巨大的书架但只有几本书,书架大部分是空的——浪费了空间。如果你有海量书籍但书架太小,很多书没地方放——知识装不下。最优策略是让书架和书"匹配增长"。

实际中的偏离:为什么很多模型"过度训练"?

Chinchilla 定律说的是"训练算力最优"的配置,但实际中很多模型选择偏离这个最优——用比 Chinchilla 建议更多的数据来训练一个相对小的模型。比如 Llama 3 405B 参数的模型用了 15T tokens 训练,而 Chinchilla 最优只需约 8T。

原因在于推理成本。模型训练是一次性的投入,但推理是持续的开销。一个 70B 的模型经过过度训练后可能达到 405B 模型的能力,但每次推理只需要不到 1/5 的算力。当模型部署后要服务数以亿计的用户请求时,推理成本的节省远远超过训练时多花的钱。这就是所谓的"小模型 + 大数据"策略——训练时多花一些,推理时长期省钱。


算力估算:训练一个大模型要多少钱?

理解了 Scaling Law,我们来算一笔实际的账:训练一个 GPT-4 或 Llama 3 级别的模型,到底需要多少算力?

算力估算的核心公式:

总计算量 C ≈ 6 × N × D

其中:
N = 模型参数量
D = 训练 token 数

这个公式的意思是:训练过程中,每个参数需要对每个 token 做约 6 次浮点运算(前向传播 2 次 + 反向传播 4 次)。这个公式虽然简化了很多细节,但作为数量级估算已经足够准确。

以 GPT-3(175B 参数,300B tokens)为例:

C = 6 × 175B × 300B = 3.15 × 10^23 FLOPs

使用 10,000 块 A100 GPU(每块 312 TFLOPS,假设 50% 利用率):

训练时间 ≈ 3.15 × 10^23 / (10,000 × 312 × 10^12 × 0.5 × 3600)
         ≈ 56 天

成本估算(A100 租赁价约 $2/小时):
≈ 10,000 × 56 × 24 × $2 ≈ $2,700 万

以 Llama 3 405B(405B 参数,15T tokens)为例:

C = 6 × 405B × 15T ≈ 3.65 × 10^25 FLOPs

GPU 时 = 6 × 405B × 15T / (GPU_TFLOPS × 利用率)
       ≈ 7.7 × 10^7 GPU 时(基于 A100-80GB)

如果使用 16,000 块 H100 GPU:
训练时间 ≈ 7.7 × 10^7 / (16,000 × 989 × 0.5 × ... ) ≈ 54 天

成本估算(H100 租赁价约 $4/小时):
≈ 16,000 × 54 × 24 × $4 ≈ $8,300 万

GPT-4 级别模型的估算则更为惊人。GPT-4 的参数量据估计在 1.8 万亿左右(MoE 架构),训练数据量可能超过 13T tokens:

C ≈ 6 × 1.8T × 13T ≈ 1.4 × 10^26 FLOPs

需要约 25,000 块 A100/H100 持续运行约 90~100 天
仅 GPU 租赁成本就在 $1 亿~$2 亿之间

下表汇总了几个代表性模型的训练成本估算:

模型参数量训练数据估计 FLOPsGPU 集群规模估计训练天数估计成本
GPT-3175B300B3.15 × 10²³10,000 × A100~56 天~$2,700 万
Llama 3 70B70B15T6.3 × 10²⁴6,000 × H100~7 天~$400 万
Llama 3 405B405B15T3.65 × 10²⁵16,000 × H100~54 天~$8,300 万
GPT-4(估算)~1.8T~13T+~1.4 × 10²⁶~25,000 × A100/H100~90-100 天~$1-2 亿

注意:以上均为粗略估算。实际训练涉及大量工程开销(数据预处理、检查点保存与恢复、通信开销、利用率波动等),且 GPU 利用率通常在 35%~50% 之间。此外,硬件成本只是总成本的一部分——研发团队的人力成本、数据采购成本、基础设施成本同样不可忽视。


分布式训练:一个人搬不动,就一群人一起搬

当你需要 16,000 块 GPU 同时训练一个模型时,怎么让它们高效协作?这就需要分布式训练策略。

分布式训练的本质是:把一个太大的任务拆分到多块 GPU 上,让它们并行工作。 但拆分的方式不同,效率和适用场景也大不相同。我们用生活中的类比来理解几种主要的并行策略。

1. 数据并行(Data Parallelism, DP)

类比:100 个学生做同一套卷子的不同题目

数据并行是最直观的策略:每块 GPU 上都有一份完整的模型副本,但训练数据被均分。如果 batch size 是 1,000 条数据、有 100 块 GPU,那每块 GPU 各处理 10 条数据,各自算出梯度后,再汇总求平均,统一更新模型参数。

GPU 0: 完整模型 + 数据块 0 → 算梯度 → ┐
GPU 1: 完整模型 + 数据块 1 → 算梯度 → ├→ AllReduce 平均梯度 → 更新参数
GPU 2: 完整模型 + 数据块 2 → 算梯度 → ┤
...                                  ┘
GPU N: 完整模型 + 数据块 N → 算梯度 → ┘
  • 优点:实现简单,加速效果好
  • 限制:每块 GPU 必须装得下完整的模型。如果模型大到单卡放不下(比如 405B 参数的模型仅参数就需要约 810GB 显存,远超单卡 80GB),数据并行就无能为力了

2. 张量并行(Tensor Parallelism, TP)

类比:一个太大的零件,一群工人各自负责一部分

当单层网络的参数矩阵大到一块 GPU 装不下时,就把单个层的参数按行或按列切分到多块 GPU 上。每块 GPU 计算矩阵的一部分,然后通过通信把结果拼起来。

原始矩阵乘法:   Y = X × W          (W 太大,一块 GPU 放不下)

张量并行(列切分): W = [W₁ | W₂]
  GPU 0: Y₁ = X × W₁   ┐
  GPU 1: Y₂ = X × W₂   ┘ → Y = [Y₁ | Y₂](拼接结果)
  • 适用场景:单个层或注意力头的参数过大
  • 代价:GPU 之间需要频繁通信(每层都要交换中间结果),对网络带宽要求极高。通常只在同一个服务器内部(如 8 块 GPU 通过 NVLink 连接)使用

3. 流水线并行(Pipeline Parallelism, PP)

类比:工厂流水线——产品经过一道道工序

当模型层数太多时,把不同的层放到不同的 GPU 上。数据像在流水线上一样,从第一组 GPU 流到最后一组。

GPU 0: 第 1-10 层   →   GPU 1: 第 11-20 层   →   GPU 2: 第 21-30 层   →   GPU 3: 第 31-40 层
  • 优点:可以把超深模型分散到很多卡上
  • 代价:如果朴素实现,前一段在算的时候后面段的 GPU 就在"发呆"(气泡效应),效率不高。解决方案是微批次——把一个大 batch 切成多个小 micro-batch,让流水线持续有活干

4. 序列并行(Sequence Parallelism, SP)

当输入序列非常长(如几十万 token 的长上下文)时,单层内的激活值在序列维度上太大。序列并行把长序列切分到多块 GPU 上,每块处理序列的一段。

5. ZeRO(Zero Redundancy Optimizer)

DeepSpeed 提出的 ZeRO 是一种"显存零冗余优化"策略,它不改变计算方式,而是把显存中那些"每块 GPU 都存了一份但内容一样"的东西切分开,让每块 GPU 只存一部分。

训练过程中,显存主要被四样东西占用:模型参数、梯度、优化器状态(Adam 需要存 momentum 和 variance)、激活值。在朴素的数据并行中,每块 GPU 都存了全部的前三样——这是巨大的冗余。ZeRO 分三个级别逐步消除这些冗余:

  • ZeRO-1:只切分优化器状态。每块 GPU 只存优化器状态的 1/N,显存节省约 4 倍
  • ZeRO-2:切分优化器状态 + 梯度。显存节省约 8 倍
  • ZeRO-3:切分优化器状态 + 梯度 + 参数。显存节省 N 倍(N 为 GPU 数量),代价是前向和反向传播时需要临时从其他 GPU 获取参数片段,通信开销增大

实际训练中,这些策略通常组合使用。例如训练 Llama 3 405B 时,可能同时使用数据并行(跨多台服务器)、张量并行(服务器内部 8 块 GPU)和流水线并行(把 126 层分散到多个服务器组),再加上 ZeRO 优化显存。这种组合被称为 3D 并行

策略原理生活类比适用场景
数据并行 (DP)每卡完整模型 + 切分数据100 个学生做同套卷子不同题模型能放进单卡
张量并行 (TP)切分单层参数到多卡大零件分给多个工人各做一部分单层参数太大
流水线并行 (PP)不同层分到不同 GPU工厂流水线,层层传递层数太多
序列并行 (SP)切分长序列到多卡长卷子撕成几段分发长上下文
ZeRO切分优化器状态/梯度/参数仓库分区存储,用谁取谁通用显存优化

后训练概要:从"续写机器"到"有用助手"

预训练完成后,我们得到的是一个"基础模型"(base model)。它擅长续写文本——给它一段开头,它能流畅地接下去。但如果你直接问它"请解释一下什么是梯度下降",它可能不会直接回答,而是可能续写出"请解释一下什么是反向传播"、"请解释一下什么是学习率"之类的话——因为它的训练目标是"预测下一个 token",而不是"回答问题"。

后训练的目的就是把这种"续写能力"转化为"对话能力"。主要分两步:

第一步:监督微调(Supervised Fine-Tuning, SFT)

收集大量高质量的"指令-回答"对,让模型学习"当用户问问题时,应该直接给出有帮助的回答"。这就像教一个博览群书但不会社交的人——"别人问你问题的时候,你应该这样回答"。

第二步:基于人类反馈的强化学习(RLHF)

SFT 之后的模型已经能回答问题了,但回答的质量参差不齐。RLHF 的核心思想是:让人类对模型的多个回答进行排序或评分,训练一个"奖励模型"来自动评估回答质量,然后用强化学习算法(如 PPO)来优化模型,让它生成更高质量的回答。

RLHF 的三步流程:

  1. 训练奖励模型:用人类标注的偏好数据(回答 A 比回答 B 好)训练一个能自动打分的模型
  2. 强化学习优化:让大模型生成回答,奖励模型打分,用 PPO 等算法更新大模型参数,使其倾向于生成高分回答
  3. 迭代:不断重复上述过程

此外,近年来还出现了 DPO(Direct Preference Optimization)等新方法,省去了训练独立奖励模型的步骤,直接用偏好数据优化模型,实现更简单但效果不逊于 RLHF。这些方法的深入实现将在第 4 章展开。

经过 SFT + RLHF 后训练的模型,就是我们日常使用的 ChatGPT、Llama Chat、Qwen Chat 等"对话模型"了。


训练显存估算实战

理解了理论,我们来看一个实际的代码示例——估算训练一个大模型需要多少显存。这个估算在规划训练任务时非常实用。

python
def estimate_training_memory(model_params_b, batch_size, seq_len,
                              hidden_size, n_layers, dtype='fp16'):
    """
    估算训练大模型所需的显存

    参数:
        model_params_b: 模型参数量(个,如 7e9 表示 70 亿)
        batch_size: 每个 GPU 的 batch size
        seq_len: 序列长度
        hidden_size: 隐藏层维度
        n_layers: 层数
        dtype: 数据类型,'fp16' 或 'fp32'
    """
    bytes_per_param = 2 if dtype == 'fp16' else 4

    # 1. 模型参数:每个参数占 bytes_per_param 字节
    model_mem = model_params_b * bytes_per_param

    # 2. 梯度:与参数同等大小
    grad_mem = model_params_b * bytes_per_param

    # 3. 优化器状态(Adam 需要存 momentum 和 variance 两个状态)
    #    ZeRO-1 优化的就是这部分
    optimizer_mem = model_params_b * bytes_per_param * 2

    # 4. 激活值(粗略估算)
    #    每层激活 ≈ batch_size × seq_len × hidden_size × bytes_per_param
    activation_mem = batch_size * seq_len * hidden_size * n_layers * bytes_per_param

    total = model_mem + grad_mem + optimizer_mem + activation_mem
    return {
        '模型参数 (GB)': model_mem / 1e9,
        '梯度 (GB)': grad_mem / 1e9,
        '优化器状态 (GB)': optimizer_mem / 1e9,
        '激活值 (GB)': activation_mem / 1e9,
        '总计 (GB)': total / 1e9
    }


# 估算 7B 模型(Llama-7B 级别)训练显存
mem = estimate_training_memory(
    model_params_b=7e9, batch_size=4, seq_len=2048,
    hidden_size=4096, n_layers=32, dtype='fp16'
)
print("=== Llama-7B 训练显存估算(无优化)===")
for k, v in mem.items():
    print(f"  {k}: {v:.1f}")

# 输出示例:
#   模型参数 (GB): 14.0
#   梯度 (GB): 14.0
#   优化器状态 (GB): 28.0
#   激活值 (GB): 4.3
#   总计 (GB): 60.3
# → 一块 80GB A100 勉强够用,但几乎没有余量

从上面的估算可以看到,一个 7B 模型的训练需要约 60GB 显存,单块 80GB 的 A100 勉强够用。如果换成 70B 模型,参数量是 10 倍,显存需求就是约 600GB——任何单卡都无法满足,必须使用分布式训练策略。


用 HuggingFace 探索预训练数据

理解了数据的重要性,我们可以用代码实际看看预训练数据长什么样。HuggingFace 的 FineWeb 数据集是一个经过清洗的高质量网页文本集合:

python
from datasets import load_dataset

# 以流式方式加载预训练数据集(避免一次性下载 TB 级数据)
dataset = load_dataset("HuggingFaceFW/fineweb",
                       split="train",
                       streaming=True)

# 查看前 5 条数据
for i, sample in enumerate(dataset.take(5)):
    text = sample['text'][:200]
    print(f"样本 {i+1}: {text}...")
    print(f"长度: {len(sample['text'])} 字符\n")

运行这段代码,你会看到各种网页文本——博客文章、新闻报道、技术教程等。这些就是大模型"读万卷书"时所看的"书页"。


常见误区

在理解了大模型训练的全流程后,我们来澄清几个常见的误解。

误区一:"训练 = 微调"

很多人把"训练大模型"笼统地理解为微调,这是不准确的。大模型的完整训练流程包含预训练和后训练两大阶段,而微调(Fine-tuning)只是后训练的一部分。预训练是"从零开始读万卷书",微调是"在已有的基础上学特定技能"。两者的算力差距可能达到 1,000 倍以上——预训练 GPT-3 级别模型需要数千万美元,而微调一个 7B 模型只需要几百到几千美元。第 4 章会详细讲解微调的实践方法。

误区二:"数据越多越好,不管质量"

这是一个非常危险的误解。Scaling Law 告诉我们数据量很重要,但这有一个前提——数据必须是高质量的。如果把大量低质量文本(重复内容、乱码、机器生成的低质文本)混入训练数据,模型不仅不会变强,反而会被"带坏"。业界有一个经验法则:"1 条高质量数据胜过 100 条低质量数据。" Meta 在训练 Llama 3 时,花在数据清洗上的工程量不亚于模型架构设计本身。

误区三:"模型越大一定越聪明"

Scaling Law 确实表明模型越大损失越低,但"损失低"不等于"实际任务表现好"。一个经过高质量数据训练和对齐的 7B 模型,在特定任务上可能超过一个用低质量数据训练的 70B 模型。此外,过大的模型带来巨大的推理成本和部署难度——不是所有场景都需要最大最强的模型。选择模型时应该以"任务需求 + 部署成本"为导向,而非一味追求参数量。

误区四:"Scaling Law 一定会持续有效"

Scaling Law 是基于当前观察到的经验规律,它会在什么时候"撞墙"目前还是开放问题。一些研究者担心高质量训练数据可能在未来几年内被"用完",也有观点认为模型架构的改进比单纯增大参数更可持续。保持对前沿研究的关注很重要。


本节小结

要点核心内容
训练两阶段Pre-training(读万卷书)→ Post-training(学礼仪对齐)
预训练目标预测下一个 token,学习语言的统计规律和世界知识
训练数据15T+ tokens,多来源,严格清洗后仅保留 30%~50%
数据清洗去重、质量过滤、有害内容过滤、PII 脱敏
Scaling Law损失与参数量/数据量/算力呈幂律关系,越大越好但边际递减
Chinchilla 定律固定算力下,参数与 token 数 1:20 最优;实际常过度训练以降低推理成本
算力公式C ≈ 6 × N × D,GPT-4 级别训练成本约 $1-2 亿
分布式训练DP / TP / PP / SP / ZeRO 组合使用(3D 并行)
后训练概要SFT(监督微调)+ RLHF(强化学习对齐),详见第 4 章
数据质量远比数据量重要,是模型性能的关键变量

回到本节开头的类比:预训练就像"读万卷书"——让模型通过阅读数万亿 token 的文本,积累语言能力和世界知识。Scaling Law 告诉我们"读得越多、脑子越大,就越聪明",而 Chinchilla 定律进一步指出"脑子大小和读书量要匹配才高效"。但"读万卷书"只是第一步——后训练阶段让这个"博学之人"学会"行万里路"——理解他人意图、给出有帮助的回答、避免有害输出。这两者结合,才造就了我们今天使用的大语言模型。


参考资料

  1. Scaling Laws for Neural Language Models (Kaplan et al., 2020)
    https://arxiv.org/abs/2001.08361

  2. Training Compute-Optimal Large Language Models (Chinchilla, DeepMind 2022)
    https://arxiv.org/abs/2203.15556

  3. The Llama 3 Herd of Models (Meta, 2024) — 训练细节公开
    https://ai.meta.com/research/publications/the-llama-3-herd-of-models/

  4. DeepSpeed ZeRO — 微软分布式训练框架
    https://www.deepspeed.ai/tutorials/zero/

  5. 大模型训练成本估算 (InfoQ)
    https://www.infoq.cn/article/7PLg3xWRqJ0GqNvYDfBM


预训练让模型"读万卷书",后训练让它"学做助手"。但训练好的模型在真正使用时,并不是简单地"一个 token 接一个 token 地选概率最高的那个"—— temperature、top-k、top-p 等采样策略会显著影响生成文本的多样性和质量。beam search 和各种解码策略背后,是对"确定性"与"创造性"的权衡。下一节我们将进入推理与采样的世界,看看模型在"说出每一句话"时,到底经历了怎样的决策过程。