module-prac

第七章:大模型的训练

“哥,大模型怎么训练出来的?像你说 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

从“怎么读输入、怎么出输出”的视角看,大语言模型有三大门派:

  1. Decoder-only(只解码) 代表:GPT 系列。思路是单向看上下文,一次预测一个 token。优点:生成强、实现简洁;缺点:做分类/检索时,可能不如双向编码器“看得全”。

  2. Encoder-only(只编码) 代表:BERT、RoBERTa。把整段文本双向编码成上下文相关的向量,然后在此之上做分类、抽取等任务。BERT 的预训练目标是两件事:

  • MLM(掩码语言模型):把句子里 15% 的位置“打码”([MASK]/原词/随机词按 80%/10%/10% 混合),让模型在看见完整上下文的同时还原被打码的词。
  • NSP(下一句预测):判断第二句是不是第一句的自然承接。 后来的 RoBERTa 干脆把 NSP 删了、多喂数据、喂更久,成绩更稳。
  1. 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、训练现场的“十大常见坑”

  1. Loss 突然 NaN:多半是学习率过大、loss scale 不合适、或梯度爆炸;先减 LR、开梯度裁剪、调低初期 batch。
  2. 显存炸:拉上混合精度、激活检查点(gradient checkpointing)、梯度累积;必要时缩短序列。
  3. 过拟合:加数据、加噪声、加权衰;看验证 PPL 曲线,别只看训练集。
  4. 发散:预热不够;尝试更长 warmup、更平滑的 LR 曲线。
  5. BERT 推理不稳:如果训练时 100% [MASK],推理没 [MASK] 就分布偏移;按 80/10/10 来。
  6. Adam 显存顶不住:考虑 Adafactor 或 8-bit 优化器;但要接受曲线更“粘人”。
  7. 初始化随性:深模型一定要配合残差缩放/注意力缩放,否则早期就“抖起来”了。
  8. 数据顺序太整齐:一定要充分 shuffle;否则模型学会“背课文”。
  9. 批量突然变大:大批容易“找山谷不找山底”,需要对应下调 LR 或用学习率线性缩放法则。
  10. 指标只看一个: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 句话)

  1. 训练 = 最小化 NLL,让模型会接“下一个 token”。
  2. 三大范式:GPT(解码)、BERT/RoBERTa(编码)、BART/T5(编解码)。
  3. Adam + 预热 + 余弦衰减 + 权重衰减 + 梯度裁剪 是常用“稳配方”。
  4. 混合精度省显存提吞吐,残差/注意力缩放保稳定。
  5. BERT 的 80/10/10 掩码为减小分布偏移;RoBERTa 删 NSP、更多数据。
  6. 先小后大、数据为王、监控到位,是阿喀琉斯之踵的解药。

“三妹,今天这口气够不够长?” “够长!而且不憋气。走,喝杯 Java——啊不,咖啡。”