第七章:大模型的训练
“哥,大模型怎么训练出来的?像你说 Java 那样,给我整明白点儿呗。”
“三妹,先别急,深呼吸——吸气、呼气。好了,咱今天就把‘大模型的训练’这摊事儿,从入门到上手、从理念到落地,一口气讲透。”
01、先把“训练”说清楚:教模型学会“下一个词”
如果只用一句话概括:训练大语言模型,就是让它在给定上下文时,尽可能准确地预测“下一个 token(词/子词/字符)”。
换成人话:你说“我今天喝了…”,它要接“咖啡/奶茶/冰可乐”,而不仅是瞎猜。
数学上,自回归语言模型把一句话拆成一串条件概率:
p(x₁) · p(x₂|x₁) · p(x₃|x₁:₂) · … · p(x_L|x₁:L-1)。
我们把所有训练样本的负对数似然(NLL)加总,最小化它,就在做所谓的最大似然估计(MLE)。这就是 GPT 系列的基本盘。
02、三大流派:Decoder-only、Encoder-only、Encoder–Decoder
从“怎么读输入、怎么出输出”的视角看,大语言模型有三大门派:
Decoder-only(只解码) 代表:GPT 系列。思路是单向看上下文,一次预测一个 token。优点:生成强、实现简洁;缺点:做分类/检索时,可能不如双向编码器“看得全”。
Encoder-only(只编码) 代表:BERT、RoBERTa。把整段文本双向编码成上下文相关的向量,然后在此之上做分类、抽取等任务。BERT 的预训练目标是两件事:
- MLM(掩码语言模型):把句子里 15% 的位置“打码”([MASK]/原词/随机词按 80%/10%/10% 混合),让模型在看见完整上下文的同时还原被打码的词。
- NSP(下一句预测):判断第二句是不是第一句的自然承接。 后来的 RoBERTa 干脆把 NSP 删了、多喂数据、喂更久,成绩更稳。
- Encoder–Decoder(编解码) 代表:BART、T5。思路是“输入双向看,输出单向生”。BART 会对输入做“打乱/遮盖”等破坏,再要求模型复原;T5 则把一切任务都改写成“文本到文本”:给提示、要答案。
03、从数据到 token:训练前的“备料工序”
大模型的胃口,叫做 token。
- 清洗:去重、去广告、去脚本/HTML 垃圾,过滤有害/低质内容。
- 分词:BPE/Unigram 等把文本切成子词;分词器和词表(vocab)决定了“读音节还是读汉字”。
- 打包:把样本拼成固定长度(如 2K/4K/8K tokens),超过就滑窗或截断,不够就 padding。
- 顺序:训练时要随机打散,否则模型会“背书”。
- 计量单位:一切成本与曲线,几乎都以 token 为基本单位(而不是“条数据”)。
04、目标函数怎么选?按“活儿的类型”来
自回归(Decoder-only): NLL/交叉熵,标签是“下一个 token”,训练时用 teacher forcing(把真值喂进下一步),推理时改用自回归生成。
MLM(Encoder-only): 让模型在看见两边上下文的前提下还原被掩码词;BERT 的15% 掩码位采用“80% [MASK]、10% 原词、10% 随机词”的混合策略,是为了减少训练/推理分布偏移(推理时没有 [MASK])。
去噪/Span corruption(Encoder–Decoder): BART/ T5 通过“打散/挖空片段”,让模型把被破坏的文本修回去。这种目标对生成与理解都很友好。
05、优化器和学习率:让损失“顺着坡往下滚”
“二哥,SGD 不香吗?” “香,但坡太陡/太坑的时候,得加点‘助滑剂’。”
Adam:给梯度加一阶/二阶动量(滑得更稳),每个维度都有自适应步长;参数量 ×4 的显存开销(权重、梯度、两套动量)。 典型配置(GPT-3 风格):β₁=0.9、β₂=0.95、ε=1e-8;线性预热若干 token(如 3.75e8),然后余弦退火到 10%;配合权重衰减 0.1、梯度裁剪。
AdaFactor:把二阶矩从 O(m×n) 压到 O(m+n)(存行和列),省显存,但训练更挑剔;T5 曾经用它啃下了大规模训练。
学习率日程: Transformer 系列很依赖 warmup(预热)来稳定早期训练,后期常用余弦/指数衰减。没有预热,梯度和层归一化的配合容易数值不稳。
06、混合精度与显存账本:省下来的,都是速度
混合精度(FP16/BF16 + FP32 主权重):
- 前后向大多用 16 位,主权重保 FP32;
- Loss scaling 避免小梯度在 FP16 下被“冲成 0”;
- 显存近乎减半,吞吐暴涨。 这已是大模型训练的“默认姿势”。
07、初始化与稳定性:天生就要“会走路”
- 常见做法:Xavier/He 初始化。
- GPT-2/3 里,还对残差路径做了 1/√N 的缩放(N 是残差层数),以抑制深层堆叠带来的不稳定。
- T5 在注意力里引入 1/√d 的额外缩放(和 q·kᵀ/√d 的思想一致),也是为稳定训练服务。
08、批大小、序列长度与吞吐:三角关系别硬拧
- 有效批大小 = 每卡批大小 × 卡数 × 梯度累积步。
- 长序列会指数级吃掉显存与算力,但带来更强的长程建模能力;实践里常常**“先短后长”:先用较短上下文把模型“带起来”,后期再增大上下文窗**继续训练。
- 梯度累积是低显存“装作很大批”的常用技法。
09、评估与早停:别只盯训练集“翻车赛”
- 困惑度(Perplexity, PPL):语言模型常用指标,越低越好。
- 拆分验证集,监控 PPL 和下游任务表现;
- 隐式正则化来自随机优化、数据噪声、早停;显式正则化有权重衰减、dropout 等(比例别太大,生成质量会受影响)。
10、典型门派的“训练食谱”
10.1 GPT 系(Decoder-only)
- 目标:最大似然,自回归下一个 token。
- 优化器:Adam / AdamW(配权重衰减)。
- 日程:线性 warmup → 余弦退火。
- 技巧:混合精度、梯度裁剪、残差缩放、初始化微调。
10.2 BERT / RoBERTa(Encoder-only)
- 目标:MLM(+ 早期 BERT 的 NSP)。
- 掩码策略:15% 位置;80% [MASK]、10% 原词、10% 随机词,降低训练/推理分布差异。
- 数据:RoBERTa 更“豪横”,更多语料、更久训练,并移除 NSP,普遍更强。
10.3 BART / T5(Encoder–Decoder)
- 目标:去噪式预训练(打乱/挖空→复原)。
- 统一范式:T5 把分类/抽取/翻译都写成“文本到文本”的提示模板,一把梭。
11、训练现场的“十大常见坑”
- Loss 突然 NaN:多半是学习率过大、loss scale 不合适、或梯度爆炸;先减 LR、开梯度裁剪、调低初期 batch。
- 显存炸:拉上混合精度、激活检查点(gradient checkpointing)、梯度累积;必要时缩短序列。
- 过拟合:加数据、加噪声、加权衰;看验证 PPL 曲线,别只看训练集。
- 发散:预热不够;尝试更长 warmup、更平滑的 LR 曲线。
- BERT 推理不稳:如果训练时 100% [MASK],推理没 [MASK] 就分布偏移;按 80/10/10 来。
- Adam 显存顶不住:考虑 Adafactor 或 8-bit 优化器;但要接受曲线更“粘人”。
- 初始化随性:深模型一定要配合残差缩放/注意力缩放,否则早期就“抖起来”了。
- 数据顺序太整齐:一定要充分 shuffle;否则模型学会“背课文”。
- 批量突然变大:大批容易“找山谷不找山底”,需要对应下调 LR 或用学习率线性缩放法则。
- 指标只看一个:PPL 低≠一切都好;对话、摘要、翻译、检索等下游要组合拳评测。
12、从 0 到 1:给你的“训练项目作战清单”
“三妹,按这个清单做,能少走很多弯路。”
阶段 A:备料
- 定义任务:只生成?要分类?要检索?
- 准备数据:规模、来源、清洗标准,敏感内容过滤;
- 定词表/分词器:中文可选字级 or 子词级;
- 设定序列长度与窗口策略。
阶段 B:模型与配置
- 选架构:Decoder-only / Encoder-only / Encoder–Decoder;
- 规模:层数、头数、隐藏维度、FFN 倍数;
- 初始化:Xavier/He + 残差缩放(1/√N)/注意力缩放(1/√d)。
阶段 C:优化与日程
- 优化器:Adam/AdamW(β₁=0.9,β₂=0.95),权重衰减 0.1;
- 学习率:线性 warmup → 余弦退火;
- 稳定化:混合精度、loss scaling、梯度裁剪。
阶段 D:训练工程
- 有效批:梯度累积撑起来;
- 监控:训练/验证 loss、PPL、显存、吞吐、学习率;
- Checkpoint:按步/按时保存;
- 断点续训:随机种子与环境锁定保证可复现。
阶段 E:评估与迭代
- 验证集多样化:风格、领域、长度分布;
- 指标板:PPL + 任务指标(准确率、F1、BLEU、ROUGE…);
- 错误分析:长尾、幻觉、格式错误;
- 再训练:数据再清洗、增量继续预训练(CPT),或任务微调(SFT)。
13、门派详解:BERT、RoBERTa、BART、T5、GPT 的“性格差异”
- BERT:更像“读题高手”。通过 MLM+NSP 学到双向上下文,做分类/抽取稳、快;但要生成长文本就不擅长。
- RoBERTa:删 NSP,多喂数据、多训几轮,更“憨厚耐造”。
- BART:编码器像 RoBERTa,解码器像 GPT;去噪训练让它既能读又会写。
- T5:一切皆“文本到文本”,统一范式让多任务训练特别丝滑。
- GPT:自回归生成王者;训练简单直接,配合warmup + 余弦衰减 + AdamW + 残差缩放,就能“稳中有进”。
14、为什么“预训练 + 微调”这么香?
- 预训练学的是“共性”:语言规律、世界常识、语义结构;
- 微调学的是“个性”:某任务的格式与约束(如情感分类、法律问答、代码补全)。 BERT 体系把这条路铺平了,T5 把任务统一了,GPT 把生成做大了——殊途同归:先学会说话,再学会“说到点子上”。
15、工程味儿的“实战 Tips”
- 先小后大:先用较小模型/序列快速迭代 pipeline,确定没坑再加规模。
- 数据优先级 > 算法花活:清洗 1% 的噪声,可能等于多训好几轮。
- 监控别减配:把 LR、梯度范数、显存、吞吐、loss scale 都挂在 dashboard 上。
- 日志要可追:模型哈希、代码版本、依赖版本、数据快照都要记录。
- 容错思维:显存紧张时,优先混合精度 + 累积;仍不够就 checkpoint/缩序列。
16、像讲 Java 那样收个尾:拥抱变化,但别忘了基本功
“二哥,学大模型训练,有‘钱秃’吗?” “哈哈,这问题眼熟。答案也眼熟:有。不过先别想‘发不发’,先把基本功练扎实——目标函数、优化器、学习率、初始化与稳定性,这些都是‘内功心法’。外功(并行、分布式、推理加速)以后慢慢补。只要路子正,慢慢就会快。”
17、超短总结(给忙人看的 6 句话)
- 训练 = 最小化 NLL,让模型会接“下一个 token”。
- 三大范式:GPT(解码)、BERT/RoBERTa(编码)、BART/T5(编解码)。
- Adam + 预热 + 余弦衰减 + 权重衰减 + 梯度裁剪 是常用“稳配方”。
- 混合精度省显存提吞吐,残差/注意力缩放保稳定。
- BERT 的 80/10/10 掩码为减小分布偏移;RoBERTa 删 NSP、更多数据。
- 先小后大、数据为王、监控到位,是阿喀琉斯之踵的解药。
“三妹,今天这口气够不够长?” “够长!而且不憋气。走,喝杯 Java——啊不,咖啡。”