工程基础:数据、损失与参数更新#
本页内容8 个部分
1. 预训练流程与阅读范围#
自回归语言模型预训练从大量文本中学习下一个 token 的条件分布。预训练工程需要明确四项内容:(1)语料组织为训练序列的规则;(2)损失的平均范围;(3)训练量与参数更新次数的对应关系;(4)训练状态的监控和恢复方式。即使模型结构相同,数据采样、损失聚合方式或参数更新频率不同,训练过程也会不同。[1]
本篇以 decoder-only 语言模型为背景,说明数据、损失、梯度与参数更新之间的关系。优化器和损失的完整推导见对应专篇。具体模型的学习率、batch 和数据配比属于配方,不能直接当作通用默认值。
2. 从语料到 next-token 目标#
本篇的计数算例采用以下配置:4 个数据并行副本,每个副本一次处理 2 条序列,累积 8 次后更新参数;每条输入有 1024 个位置,其中 960 个标签参与损失。计算时分别统计一次参数更新使用的序列数、送入模型的位置数和计入 loss 的标签数。这组配置只用于解释计数,不是推荐的预训练配方。
2.1 Tokenizer、数据采样与文档边界#
Tokenizer 把文本变成 token ID。语料需要经过清洗、去重和来源采样,再组织为有限长度的训练序列。数据来源和采样比例会影响训练序列的数据分布。语料库的 token 总数与训练中累计读取的 token 数需要分别记录,重复读取会增加后者。GPT-3 的数据混合与采样就是具体配方的实例。[1]
不同 tokenizer 对同一段文本可能得到不同的 token 数。统计数据量、比较 loss 与规划上下文长度时,应固定 tokenizer 版本。切分训练和验证数据后,还应检查重复或近似重复样本是否跨集合泄漏。
训练序列需要明确文档结束符、截断规则和拼接方式。Packing 将多个样本组织到同一序列中,以减少 padding 位置。拼接本身不阻止跨文档注意力;attention mask 决定允许读取的上下文,位置编号标识 token 的位置,监督 mask 决定哪些标签计入损失,详见 Packed Sequence。
2.2 标签对齐与有效监督位置#
下面用一个短序列说明输入与监督标签的对齐关系。假设“我、喜欢、学习、EOS”各对应一个 token,其中 EOS 是文档结束标记。在末尾补一个填充标记 PAD 后,取前四个 token 作输入、后四个作标签。该例仅示意标签对齐,不表示真实 tokenizer 必然这样切词。
| 输入位置 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| 输入 token | 我 | 喜欢 | 学习 | EOS |
| 下一 token 标签 | 喜欢 | 学习 | EOS | PAD |
| 是否进入 loss | 1 | 1 | 1 | 0 |
前三个输入位置各预测后面的一个 token;最后的 PAD 标签被忽略。EOS 在第三个标签位置参与预测,不能因为它也出现在输入中就把该标签排除。Causal attention(因果注意力)限制每个位置只读取允许的前缀;监督 mask 决定哪些标签计入 loss,两者作用不同。
把同一规则写成一般形式:原始 token 串为 ,序列 的输入位置 使用前缀 预测 ,其中 。这里 包含位置 0 到 的 token, 是送入模型的输入位置数;未移位原始串共有 个 token。
记 为模型参数, 为模型对下一 token 的条件概率。用 表示标签是否参与监督,其中 1 表示参与。下面的 遍历一次参数更新使用的全部序列,包括所有数据并行副本和累积的 microbatch。本篇的 表示自然对数。有效标签总数大于零时,先累加参与监督位置的负对数概率,再除以有效标签数:
用短序列实际计算一次 loss。假设模型给“喜欢”“学习”“EOS”这三个正确标签的概率分别为 、、,这些是手算设定。先对每个正确标签的概率取负对数,再对三个有效位置平均:
PAD 标签对应的预测概率不参与分子,也不增加分母。这个数值是损失函数的输出,参数怎样变化还取决于反向传播得到的梯度和优化器。
上面的短序列共有 4 个输入位置,但 loss 分母为 3。1024 个输入位置、960 个有效标签的训练配置也是同一种区分;输入位置数与有效标签数需要分别统计。Padding 等被忽略标签不进入分母,ignore_index 是实现排除的一种方式。[2]
交叉熵给出单个位置的损失及其对 logit 的梯度;本篇说明如何聚合多个位置的损失。实现时仍需确认移位由模型内部还是数据侧完成,避免移位两次或完全没有移位。
3. 训练量与成功更新次数#
3.1 数据量、训练量与算力预算#
设模型参数量为 ,训练累计处理的 token 数为 ,训练计算量为 ,单位为 FLOPs。固定计算预算时,扩大模型通常会减少能处理的 token;Chinchilla讨论怎样用多规模实验估计这项取舍。常规 dense Transformer 的参数相关训练计算可粗估为 ,但仍需考虑注意力、序列长度与实现开销,FLOPs 也不等于实际耗时。[3]
应记录 的计数口径:原始语料 token、重复采样后的训练 token、实际送入模型的位置数和有效监督 token 不一定相等。使用缩放定律或计算器时,应采用对应公式使用的 token 计数定义。
3.2 Microbatch、累积与数据并行#
设数据并行副本数为 ,每个副本每次前向处理的批次称为 microbatch,其中包含 条序列。每个副本累积 个 microbatch 的梯度后,尝试更新一次参数。若每批都满额,一个完整梯度累积窗口覆盖的序列数为 。固定每条输入长度为 时,模型处理的位置数为 。
代入本篇配置,一个完整梯度累积窗口的序列数为 ;每条输入 1024 个位置,处理量为 ,有效监督量为 。在每个 microbatch 的序列数、输入长度和有效标签数固定时,两项都与累积次数成正比;训练 loss 仅以有效标签数为分母。
这里乘的是数据并行副本数,不是所有 GPU 的总数。张量并行(Tensor Parallel)将同一个模型的计算分到多台设备上,这些设备不能再作为独立数据副本计入 。分布式数据并行(DDP)同步副本之间的梯度,模型并行的执行细节见并行策略。[4]
若没有跳步或丢弃的累积窗口,每次成功更新都处理 个位置,且共成功更新 次,则累计处理位置数为 。这里“成功更新”指优化器实际执行一次参数更新,不要求每个参数的增量都非零。序列长度变化、末尾批次不足额或自动混合精度(AMP)跳过参数更新时,应分别累计实际处理量、有效监督量与成功更新次数,不能只用一个 step 计数替代三者。AMP 跳过参数更新时,已送入模型的位置仍计入实际处理量。
4. 训练处理量与监督量的计算#
沿用前面的 、、、,每条输入仍有 960 个有效标签。假设没有尾批或跳步,连续成功更新 100 次,将每次更新的统计量累计起来:
| 要核对的量 | 计算 | 结果 |
|---|---|---|
| 每次更新的序列数 | 64 | |
| 每次更新处理的位置 | 65,536 | |
| 每次更新的 loss 分母 | 61,440 | |
| 100 次更新处理的位置 | 6,553,600 | |
| 100 次更新的有效监督量 | 6,144,000 |
再假设本次更新中,每个有效标签的负对数概率都是 1.5;这是为演示平均方式设定的数值。累加有效标签的损失,得到 ,平均 loss 为 。如果误除以全部处理位置,就得到 ,训练目标已被改变。
这组数仅用于核对 token 计数和损失聚合,不能据此推断任务得分或显存需求。
若各 microbatch 的有效标签数相同且大于零,对各批的有效 token 平均 loss 作等权平均,就与全局有效标签平均的目标一致。有效标签数不同时,等权平均一般不等于全部有效 token 的平均 loss;即使某次计算恰好相等,也不能保证梯度一致。要保持全局有效标签平均的目标,应按各 microbatch 的有效标签数加权。有效标签数不同的数据并行副本也需要采用同样的加权原则。
若某个 microbatch 的有效标签数为零,该批对损失分子和有效标签总数的贡献都为零,不单独计算该批的 token 平均 loss。整个累积窗口的平均 loss 仍要求有效标签总数大于零。具体推导与末尾不足额批次的处理见梯度累积。
5. 优化器、学习率调度与梯度缩放#
5.1 从梯度到参数变化#
损失函数定义优化目标,优化器根据梯度计算参数更新。SGD 与 Momentum分别介绍按当前梯度更新参数和使用历史梯度的动量估计,Adam通过一阶矩与二阶矩估计调整各坐标的更新,AdamW将权重衰减与梯度矩估计分开。矩阵参数的 Muon 更新另见 Muon。
学习率调度决定学习率系数随训练进度怎样变化;不同阶段的组合与适用场景见学习率配方。设置 warmup 或衰减前,应明确日程按成功优化步、已消费 token 还是其他量推进;改变累积步数后,一次参数更新对应的处理位置数和有效标签数可能改变。
5.2 梯度累积结束后的缩放与裁剪#
在一个梯度累积窗口内,完成各 microbatch 的前向计算和反向传播。使用 loss scaling 时,窗口内保持同一缩放因子;全部梯度累积完成后,先解除缩放,需要限制梯度范数时再裁剪。使用 PyTorch GradScaler 时,由 scaler.step 根据非有限梯度的检查结果决定是否执行参数更新,随后调用 scaler.update 更新缩放因子。[5]
训练循环给出这些机制组合的代码。实现时应分别规定优化器、学习率调度器(scheduler)和梯度缩放器(scaler)的调用条件。若日程按成功优化步推进,AMP 跳过参数更新时,scheduler 不应增加步数;scaler 仍需根据检查结果更新缩放因子。
6. 精度、显存占用与并行执行#
| 机制 | 主要改变 | 不能由名称直接推断的结果 |
|---|---|---|
| 混合精度 | 部分算子的计算 dtype 与张量存储 | 开启 autocast 不代表所有参数、梯度和优化器状态都以低精度存储 |
| 梯度累积 | 一次参数更新包含的 microbatch 数量 | 梯度累积本身不减少参数、梯度和优化器状态的元素数 |
| 激活重算 | 前向保存哪些张量,反向重算哪些片段 | 激活显存节省量取决于重算范围,重算会增加计算量 |
| 参数与状态分片 | 每台设备常驻哪些参数、梯度和状态 | 临时聚合与通信缓冲仍可能增加峰值显存 |
| 数据并行 | 各副本分别计算 microbatch 的梯度,再聚合 | 普通数据并行的每个副本仍保存完整模型,不能降低单个副本的参数存储量 |
数值格式与 loss scaling 见混合精度,模型状态和激活的分项估算见分布式训练基础,激活保存与重算的执行过程见激活重算。比较吞吐与显存时,应固定模型、输入长度、每次更新的处理位置数及损失聚合方式,并分别记录处理位置数和有效标签数。否则,单步耗时较短可能只是因为该步处理量较少。
7. 执行验证、监控与恢复#
7.1 输入、梯度与参数更新的执行检查#
先用固定小批数据核对输入、移位标签、mask 和 loss 分母,再检查梯度和参数增量中是否存在 NaN 或无穷值。结合 AMP 跳步记录,核对优化器实际执行更新的次数。再在小数据集上重复训练,检查训练 loss 是否在多次更新后总体下降,不要求每一步都下降。同时记录成功更新次数、学习率、裁剪前梯度范数、AMP 跳步次数和有效标签数。
数据量和模型扩大后,分别记录训练与验证曲线。比较候选配置时,使用相同验证集和损失聚合方式。训练 loss 降低本身不能证明下游任务得分、概率校准或语料质量改善,这些目标需要分别评估;具体模型报告通常同时给出训练设置与多项评估。[6]
7.2 监控范围与检查点恢复状态#
预训练的监控指标用于检查各层梯度、激活以及混合专家(MoE)模型的专家路由等训练状态。解释指标前,应明确统计窗口,以及统计量是在单台设备上计算还是跨设备聚合。异常发生后,按诊断页保留样本和更新状态,再逐步检查原因。
检查点(checkpoint)除了模型参数,还应保存优化器、学习率调度器、梯度缩放器的状态,以及随机状态与数据读取进度。恢复后先核对这些状态是否对应同一次保存;分布式数据加载与随机算子还可能影响逐步可复现性,成功加载权重不足以证明恢复后的训练与中断前连续执行一致。[7]
超参数计算器可辅助核对项目经验规则下的规模与预算。它给出候选配置,最终仍要用目标数据、精度和并行方式验证训练行为、峰值显存与端到端单步耗时。
参考资料#
- Language Models are Few-Shot Learners(2020). §2、附录 B:自回归预训练、数据混合与训练设置。
- CrossEntropyLoss(PyTorch 2.9). 文档:忽略标签与损失聚合。
- Training Compute-Optimal Large Language Models(2022). 原文:参数量、token 数与算力约束。
- Distributed Data Parallel(PyTorch 2.9). 文档:副本梯度同步;batch 公式为本篇设定下的直接计数。
- AMP examples(PyTorch 2.9). 梯度累积:缩放、解除缩放与有效更新边界。
- Llama 2(2023). §2:预训练数据、设置与评估的具体案例。
- PyTorch 训练恢复与可复现性. Checkpoint、Reproducibility(2.9):恢复训练状态与随机性的边界;具体数据加载进度需由训练程序另行保存。
原文小节的位置
以下小节已整理到独立文章,旧链接会直接转到对应位置。
- s1
- 01 损失函数详解
- 1 1 交叉熵损失 cross entropy loss
- 信息论基础
- 为什么用 log
- 交叉熵与 kl 散度的关系
- label smoothing
- pytorch 实现
- label smoothing 与知识蒸馏的张力
- 不用 ls 目标 one hot
- 用 ls 错误类目标 0 0111
- 1 2 对比损失 contrastive loss
- infonce loss
- 温度参数 τ 的作用
- nt xent vs infonce vs triplet loss
- 1 3 mse l1 huber loss
- 回归损失对比
- 在扩散模型中的应用
- 预测噪声 ε prediction
- 预测原始数据 x0 prediction
- 预测速度 v prediction
- flow matching 目标
- 1 4 数值稳定性 log sum exp trick
- 1 5 正则化 l1 vs l2
- l1 正则化 lasso
- l2 正则化 ridge weight decay
- 二维参数空间直觉
- l2 惩罚与权重衰减
- 1 6 dropout 详解
- 基本原理
- inverted dropout vs 原始 dropout
- 原始 dropout hinton 2012
- inverted dropout 现代标准
- 为什么 dropout 有效
- 常见 dropout 配置
- 面试追问 dropout vs droppath vs dropconnect
- s3
- 03 学习率调度策略
- 3 1 warmup 的作用与原理
- 3 2 cosine decay
- 3 3 linear decay vs cosine decay 对比
- 3 4 常见调度器变体
- warmup cosine annealing 最常用
- onecyclelr
- 3 5 数值例子
- s4
- 04 混合精度训练 amp
- 4 1 浮点数格式对比
- 4 2 fp16 训练为什么会溢出
- loss scaling 的原理
- dynamic loss scaling
- 4 3 bf16 vs fp16 优劣势
- 4 4 pytorch amp 代码示例
- s5
- 05 分布式训练概念级
- 5 1 数据并行 ddp
- 5 2 zero fsdp 全分片数据并行
- 显存组成分析 以 fp16 混合精度 adam 为例
- zero 三个阶段
- pytorch fsdp
- 5 3 模型并行
- tensor parallel 张量并行
- pipeline parallel 流水线并行
- 5 4 deepspeed vs fsdp 选择
- s6
- 06 梯度相关技巧
- 6 1 梯度累积 gradient accumulation
- 6 2 梯度裁剪 gradient clipping
- 6 3 梯度检查点 gradient checkpointing
- 显存 vs 计算的权衡
- 标准训练
- 梯度检查点
- 6 4 训练显存计算公式 细化版
- 激活显存的精确公式 transformer
- 三档参考表 fp16 mixed adamw flashattn b 1 s 2048
- 各省存技巧的量化对比
- 06 模型蒸馏在大模型落地中的作用
- knowledge distillation 核心原理
- 温度参数 的作用
- 大模型蒸馏实践方案
- oom 调参补充 配合 zero