从流程图看懂大语言模型训练
通用大语言模型(如 DeepSeek、GPT、Llama)的训练本质上是同一个循环优化逻辑的海量扩展。流程图中的每个环节——"预测→算错→调参→判断收敛"——在 LLM 训练中被放大到了千亿参数、万亿 token 的尺度上。
本文将以构建一个类似 DeepSeek 的通用对话大模型为例,拆解从"随机婴儿"到"能写诗、写代码、解数学题"的完整蜕变过程。训练分三大阶段:预训练(Pre-training)→ 监督微调(SFT)→ 对齐训练(RLHF/DPO)。
1 LLM 训练三大阶段
阶段一:预训练
在海量无标注文本(网页、书籍、论文、代码)上学习语言规律,掌握"世界知识"。
阶段二:监督微调(SFT)
在高质量"指令-回答"对上进行有监督学习,让模型学会对话和遵循指令。
阶段三:对齐训练
通过 RLHF/DPO 等强化学习技术,让模型输出更符合人类价值观和偏好。
贯穿示例:训练类似 DeepSeek 的通用对话大模型
假设我们要从零训练一个拥有 70 亿参数的通用大语言模型(类似 DeepSeek 早期版本的大小)。
它需要能:写诗、写代码、解数学题、进行多轮对话、遵循复杂指令。训练分三个阶段完成。
2 训练步骤详解
开始训练:数据与基础设施准备
在训练开始之前,需要准备海量数据和强大的计算集群。这是 LLM 训练中最"烧钱"和"耗时"的环节之一。
- Common Crawl(网页数据,占比最大)
- Github(开源代码,用于学习编程)
- 维基百科、书籍(高质量知识)
- ArXiv 论文(学术知识)
- 需要去重、过滤、质量评分
- 数千张 NVIDIA A100/H100 GPU
- 高速 InfiniBand / NVLink 互联
- 分布式训练框架:Megatron-LM / DeepSpeed
- 数据并行 + 张量并行 + 流水线并行
# 伪代码:训练启动配置(使用 DeepSpeed)
model = TransformerLM(vocab_size=32000, hidden_size=4096, num_layers=32)
# 约 70 亿参数 = 32层 × 4096维 × 多头注意力 + FFN
# DeepSpeed 配置:ZeRO-3 优化,将参数分片到多卡
deepspeed_config = {
"train_batch_size": 4096, # 全局 batch size
"gradient_accumulation_steps": 8,
"optimizer": {"type": "AdamW", "params": {"lr": 3e-4, "betas": [0.9, 0.95]}},
"fp16": {"enabled": True}, # 混合精度训练
"zero_optimization": {"stage": 3} # 参数分片
}
training_data = load_tokens("pretrain_corpus.bin") # 数万亿 token
随机初始化参数:一张"空白的大脑"
70 亿参数的模型在"出生"时,所有权重矩阵都是小的随机数。此时如果问它"中国的首都是哪里?",它会输出完全随机的乱码。
初始化策略:使用 Xavier / Kaiming 初始化,让初始输出的方差保持适中。如果初始化太大,训练会发散;太小,则梯度消失。
输入训练数据:文本如何变成数字?
模型不认识文字,只认识数字。通过 Tokenizer(分词器),文本被拆分成最小的语义单元——Token,再映射为数字 ID。
"中国的首都是北京"
预训练不需要"问题-答案"对。直接把海量文本切成 2048 / 4096 token 长度的片段,Batch Size 通常高达 4K~8K(全局)。模型看到 "中国的首都是__",目标就是预测出 "北京"。
核心训练步骤:Next Token Prediction
模型预测:Next Token Prediction(前向传播)
给定前 N 个 token,模型预测第 N+1 个 token 是什么。这是 LLM 预训练的核心任务,也称为"自回归语言建模"。
计算错误:交叉熵损失
对于序列中的每一个位置,模型都做了一个预测。将每个位置的预测概率与真实 token 对比,计算平均损失。
调整参数:反向传播 + 优化器
计算 70 亿个参数各自的梯度,然后沿着梯度反方向更新参数。这是整个训练中最消耗算力的环节。
对于 7B 模型 + 4K 序列长度:
- 需要存储每一层的中间激活值
- 显存占用可达 数十 GB / GPU
- 使用梯度检查点(Checkpointing)来省显存
用 16 位浮点数存储大部分参数和计算,既节省显存又加速训练。但保留 32 位副本用于关键计算,防止精度不足导致的训练不稳定。
错误变小了吗?
参数更新后,在同一个 Batch 上重新计算损失(或通过梯度保证其下降)。对于大规模 LLM,通常不反复迭代同一个 Batch,而是更新一次后立即进入下一个 Batch。
还有数据?(Batch 循环)
LLM 预训练通常处理数万亿 token。以 7B 模型为例,如果全局 Batch Size = 4096,序列长度 = 4096,则每个 Step 处理约 1600 万 token。训练 1 万亿 token 需要约 60 万 Step。
参数稳定了吗?(收敛与阶段切换)
预训练结束后,模型具备了"语言能力",但还不会"好好说话"。需要进入下一阶段。
训练完成:一个 DeepSeek 式模型诞生了
经过预训练 → SFT → RLHF 三阶段后,模型从一个输出乱码的"婴儿"成长为一个能写诗、写代码、解数学题、进行深度对话的"智能体"。
# 保存最终模型
model.save_pretrained("./deepseek-7b-final")
tokenizer.save_pretrained("./deepseek-7b-final")
# 使用模型推理
prompt = "请用一首诗描述秋天的景色:"
inputs = tokenizer(prompt, return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=100, temperature=0.7)
print(tokenizer.decode(outputs[0]))
# 输出:秋风起兮白云飞,草木黄落兮雁南归……
3 LLM 三阶段训练对比
| 维度 | 预训练(Pre-training) | 监督微调(SFT) | 对齐训练(RLHF/DPO) |
|---|---|---|---|
| 数据类型 | 无标注文本(网页/代码/书籍) | 高质量指令-回答对 | 偏好对(好回答 vs 差回答) |
| 数据量 | 数万亿 token | 数十万~数百万条 | 数万条偏好数据 |
| 训练目标 | Next Token Prediction | 生成与标准答案一致的文本 | 最大化人类偏好概率 |
| 损失函数 | 交叉熵损失 | 交叉熵损失(带 mask) | DPO 损失 / PPO 奖励 |
| 计算成本 | 极高(数百万 GPU 小时) | 中等(数千 GPU 小时) | 中等(数千 GPU 小时) |
| 模型能力 | 语言理解 + 世界知识 | 对话能力 + 指令遵循 | 安全性 + 有用性 + 诚实性 |
4 训练过程动态演示
5 关键概念速查表
| 概念 | 含义 | LLM 训练中的体现 |
|---|---|---|
| Token | 文本的最小语义单元 | "中国的首都是北京" ≈ 5 个 token |
| Next Token Prediction | 预测序列中下一个 token | LLM 预训练的核心任务,自回归生成 |
| Cross-Entropy Loss | 衡量预测分布与真实分布的差距 | 每个 token 预测都算一次,取平均 |
| Attention | 让模型关注序列中相关的 token | "首都"与"北京"建立强关联 |
| SFT | 监督微调,用问答对训练 | 让模型学会对话和遵循指令 |
| RLHF | 基于人类反馈的强化学习 | 用偏好数据让输出更安全有用 |
| DPO | 直接偏好优化 | RLHF 的简化版,无需奖励模型 |
| 混合精度 | FP16/BF16 训练 | 节省显存、加速训练,但保持精度 |
6 完整流程回顾
计算损失:用交叉熵衡量每个位置预测与真实的差距,取平均
反向传播:计算 70 亿参数的梯度(链式法则)
更新参数:AdamW 优化器 + Cosine 学习率调度更新参数
重复:处理下一个 Batch,直到数万亿 token 遍历完毕
核心要点总结
流程图中的"预测→算错→调参→收敛"循环在 LLM 中被重复数万亿次。70 亿参数从随机数逐渐演化为能捕捉语言规律的"智能权重"。
预训练赋予"语言能力",SFT 赋予"对话能力",RLHF/DPO 赋予"安全与价值观"。跳过任何阶段,模型都会"偏科"。
SFT 和 RLHF 阶段的数据量远小于预训练,但对最终体验影响极大。几万多条高质量偏好数据可以改变模型的行为模式。
模型性能随参数规模、数据量、计算量的增加而可预测地提升。这是大模型"大力出奇迹"的理论基础。