面向实战的一篇文章讲清大模型训练核心概念与排查要点:Tokenizer如何切分与生成input_ids/labels,Embedding与位置编码的作用,logits与softmax关系,交叉熵loss与mask/ignore_index,梯度与梯度裁剪/混合精度注意事项,以及checkpoint保存与断点续训的正确姿势。
一文搞懂大模型训练常见概念:Tokenizer、Embedding、Logits、Loss、梯度与Checkpoint
在 Ai大模型训练教程 这套系列文章里,很多同学卡在同一个问题:代码能跑起来,但日志里出现的 Tokenizer、Embedding、Logits、Loss、梯度、Checkpoint 到底代表什么?它们之间又是如何串起来完成一次训练迭代的?
这篇文章不讲空泛定义,而是用「训练数据流」的视角,把这些概念放到同一条流水线上解释,并给出你在实战中最常见的排查点、观察指标与操作建议。
1)先用一条训练流水线把概念串起来
一次标准的语言模型训练(以自回归 LM 为例)可以抽象为:
- 文本输入(字符串)
- Tokenizer 把文本切成 token,并映射为 token ids(整数序列)
- Embedding 把 token ids 映射成可学习的向量(连续空间表示)
- Transformer 等网络进行前向计算,得到每个位置对词表的预测分布前的分数:logits
- 用目标 token(label)计算 loss(常见为交叉熵)
- 反向传播得到 梯度(gradients)
- 优化器更新参数(SGD/AdamW 等)
- 定期保存 checkpoint(模型权重、优化器状态、训练步数等)
后面每个概念都可以放回这条链路里理解:它在输入端、表示层、输出端还是训练控制层。
2)Tokenizer:文本如何变成模型能吃的数字
2.1 Tokenizer 到底做了什么
Tokenizer 主要完成两件事:
- 分词/切分:把字符串切成 token(可能是字、词、子词、字节片段)
- 映射:把 token 转成词表中的 id(token -> integer)
常见的分词算法包括 BPE、WordPiece、Unigram,以及面向多语言/特殊字符更稳健的 byte-level BPE。
2.2 训练里最常见的三个字段:input_ids / attention_mask / labels
在大模型训练的 dataloader 里,你经常会看到:
input_ids:token id 序列,例如[1, 345, 78, ...]attention_mask:哪些位置是有效 token,哪些是 padding(通常 1 表示有效,0 表示 pad)labels:监督信号。自回归训练常见做法是 labels = input_ids 向左/向右错位一位。
例如一句话 token ids:
input_ids: [A, B, C, D]- 目标
labels: [B, C, D,](或最后位置忽略)
这样模型在位置 i 看到 A..i 的上下文,预测下一个 token。
2.3 实操建议:Tokenizer 相关坑怎么排查
1) 词表大小与模型 config 一致
- 如果 tokenizer 的 vocab_size 和模型的 embedding 矩阵大小不一致,会直接报 shape mismatch。
解决方式:
- 要么加载匹配的 tokenizer
- 要么 resize embedding(如
resize_token_embeddings),但要清楚新增 token 的初始化方式。
2) 特殊 token 是否齐全
- 常见:
bos/eos/pad/unk。 - 训练时 padding 必须有
pad_token_id,否则 batch 对齐会困难。
3) 最大长度与截断策略
- 对长文本:要明确
max_length、truncation、stride(滑窗)策略。 - 不然你以为喂了长文,实际上大量被截断,训练效果偏离预期。
4) 数据清洗对 token 分布的影响
- 过度清洗(去标点、去换行)会改变语言结构;
- 训练日志里如果 loss 一直很高且不下降,除了学习率,也要检查是否 tokenizer 与语料域不匹配(例如代码语料却用偏自然语言的 tokenizer)。
3)Embedding:把离散 token 变成连续向量表示
3.1 Embedding 的位置:输入表示层
token id 是离散整数,神经网络不能直接用整数做语义运算,需要把它映射成向量:
Embedding matrix形状通常是[vocab_size, hidden_size]- 每个 token id 对应取出一行向量:
hidden_size维
这就是所谓的词向量,但在大模型中它会被端到端训练,不再是静态词向量。
3.2 常见的两类 embedding
- Token Embedding:来自 token id
- Position Embedding:位置编码(绝对/相对/旋转位置编码 RoPE 等)
最终进入 Transformer 的输入往往是 token embedding 与位置编码的组合(相加或其他形式)。
3.3 实操建议:Embedding 相关问题
1) 新增 token 后必须同步 embedding
- 如果你在 tokenizer 中加了新 token(如领域专用标记),模型 embedding 不扩容会报错。
2) 初始化影响收敛
- 新增 token 的 embedding 初始化如果是随机,短期可能导致 loss 波动;
- 如果能用相近 token 的平均向量初始化(例如新增
<NEW>用<unk>或一组相关 token 平均),往往更稳。
3) Embedding 是“容量入口”之一
- hidden_size 越大,embedding 参数量越大;
- 在资源有限时,减少 hidden_size 会大幅降低参数量,但也会影响表达能力。
4)Logits:模型“没归一化的预测分数”
4.1 Logits 是什么
模型前向输出通常是对词表每个 token 的打分:
- logits 形状:
[batch_size, seq_len, vocab_size] - 每个位置都有一组长度为 vocab_size 的分数
logits 不是概率,它们经过 softmax 才变成概率分布。
4.2 为什么训练用 logits 而不是概率
- 直接用 softmax 后的概率会有数值稳定性问题
- 深度学习框架通常提供 CrossEntropyLoss(内部集成 log-softmax),直接吃 logits 更稳定更快
4.3 实操建议:读懂 logits 的常见用法
1) 采样/解码阶段
top-k / top-p / temperature 都是在 logits 上动刀:
temperature:缩放 logits- top-k/top-p:截断分布
2) 训练异常排查
如果 logits 出现 NaN/Inf,往往来自:
- 学习率过大
- 混合精度溢出(fp16 下更常见)
- 梯度爆炸未做 clip
5)Loss:模型到底学得好不好,靠它量化
5.1 语言模型最常见的 loss:交叉熵
对于自回归语言模型,训练目标是“预测下一个 token”。
- 真实标签是下一个 token 的 id
- logits 经过交叉熵计算得到 loss
直观理解:
- 模型给正确 token 的概率越高,loss 越低
- loss 下降通常意味着困惑度(Perplexity)也下降(PPL = exp(loss) 在某些设定下成立)
5.2 Loss 的两个关键细节:mask 与 ignore_index
训练时序列里通常有 padding 或不参与训练的部分,需要从 loss 中排除:
- 常见做法:把不需要计算的位置 label 设成
-100(PyTorch 默认 ignore_index) - attention_mask 也可用于构造有效位置
如果你忘了 mask:
- padding token 会被当成目标学习
- loss 可能虚高或出现奇怪的下降/震荡
5.3 实操建议:如何判断 loss 是否“正常”
1) 看趋势,而不是看单点
- 正常训练:loss 下降后趋于平稳,偶有波动
- 不正常:loss 不降、剧烈震荡、突然 NaN
2) 对比训练集与验证集
- 训练 loss 降、验证 loss 升:过拟合或数据分布偏差
- 两者都不降:学习率/数据/实现问题
3) 小 batch 与梯度累积要注意等效学习率
- batch 太小 loss 会更噪;
- 梯度累积改变了“每次更新”的有效 batch,需要相应调整学习率或 warmup。
6)梯度(Gradients):参数该往哪里改、改多少
6.1 梯度是什么
梯度是 loss 对模型参数的偏导数,回答的是:
- 哪些参数应该增大/减小
- 改动幅度大概多少
训练的本质就是:
- 前向:算 logits、算 loss
- 反向:算梯度
- 更新:用优化器把梯度转成参数更新量
6.2 梯度常见现象:爆炸与消失
- 梯度爆炸:梯度范数极大,导致更新过猛,loss 变 NaN
- 梯度消失:梯度接近 0,训练几乎不动
Transformer 相对更稳定,但在大学习率、长序列、混合精度下仍可能爆炸。
6.3 实操建议:训练中如何管住梯度
1) 梯度裁剪(Gradient Clipping)
- 常用:按全局范数裁剪,例如 clip_norm=1.0
- 经验:loss 突然飙升或出现 NaN 时,先尝试加裁剪并降低学习率
2) 监控梯度范数
- 在训练日志中记录
grad_norm - 如果 grad_norm 周期性飙升,可能是学习率调度、数据批次异常或 fp16 溢出
3) 混合精度与 loss scaling
- fp16/bf16 常用来省显存提吞吐
- fp16 需要动态 loss scaling 防止 underflow/overflow
如果频繁出现 scale 回退或溢出,考虑:
- 改用 bf16(硬件支持时更稳)
- 降学习率
- 加强梯度裁剪
4) 梯度累积(Gradient Accumulation)
- 当显存不够时,用多次小 batch 累积梯度,再更新一次
注意:
- 记录 step 的概念要区分:micro step vs optimizer step
- 学习率调度器通常应按 optimizer step 计数
7)Checkpoint:训练的“存档点”,也是复现与恢复的底座
7.1 Checkpoint 通常保存什么
一个完整可恢复训练的 checkpoint 通常至少包含:
- 模型权重(model state dict)
- 优化器状态(optimizer state:动量、二阶矩等)
- 学习率调度器状态(scheduler state)
- 当前 step/epoch、随机种子状态(可选但很关键)
- 混合精度 scaler 状态(fp16 下重要)
只保存模型权重只能用于推理或“从权重继续训练但优化器重置”,无法严格续训。
7.2 实操建议:如何制定可靠的 checkpoint 策略
1) 按步数定期保存 + 按指标保存最优
- 例如每 N steps 保存一次以防中断
- 同时在验证集 loss 最低时保存 best checkpoint
2) 保留策略:rolling window 防止磁盘爆炸
- 只保留最近 K 个 checkpoint(如 3~10 个)
- 额外保留 best checkpoint
3) 断点续训必须核对三件事
- 恢复后
global_step是否正确(否则学习率曲线会错) - optimizer/scheduler 是否恢复(否则等效学习率改变)
- dataloader 的随机性是否可控(尤其是分布式、shuffle)
4) 分布式训练的 checkpoint 形式
可能是:
- 单文件合并权重
- 每张卡一份 shard(更常见于大模型)
- 你需要明确你用的框架(DeepSpeed/FSDP/Megatron 等)保存的格式,推理加载路径也不同。
8)把概念落到一次“最小可用训练步骤”的心智模型
下面用更贴近你调试训练时的视角,给出一套“每一步看什么”的检查清单:
8.1 数据进来时(Tokenizer 阶段)
- 抽样打印一条数据:原文、tokens、input_ids
检查:
- 是否有大量
<unk>(意味着 tokenizer 不适配语料) - 是否经常超过 max_length 被截断
- pad 是否正确,labels 的 ignore 是否正确
- 是否有大量
8.2 前向输出时(Embedding/Logits 阶段)
确认张量形状:
- embedding 输出
[B, T, H] - logits 输出
[B, T, V]
- embedding 输出
- 检查是否出现 NaN/Inf(越早发现越好)
8.3 计算 loss 时
- 确认 shift 是否正确(LM labels 与 input 对齐关系)
- 确认 ignore_index 生效(padding 不计入 loss)
用一个极小 batch 做 overfit 测试:
- 让模型对 1~10 条样本训练很久
- 如果 loss 仍不下降,优先怀疑实现/对齐/数据处理
8.4 反向与更新时(梯度阶段)
- 记录 grad_norm
- 开启 gradient clipping
- 确认梯度累积步数与学习率调度一致
8.5 训练过程控制(Checkpoint 阶段)
- 每隔固定 steps 保存
- 做一次“保存->退出->恢复->继续训练”的演练
- 验证恢复后 loss 曲线是否连续(突然跳变通常意味着 optimizer/scheduler 没恢复)
9)常见问答:把最易混淆的点一次讲清
9.1 Token 和 Embedding 是一回事吗?
不是。
- token 是离散符号(子词片段)
- embedding 是可学习向量,是 token 的连续表示
9.2 logits 和概率有什么区别?
- logits:未归一化分数,可正可负
- 概率:softmax(logits) 后的 0~1 且和为 1
训练更常直接用 logits 计算交叉熵以保证数值稳定。
9.3 loss 降了就一定生成效果更好吗?
不一定。
- loss 主要反映训练目标上的拟合程度
- 生成质量还受数据质量、解码策略、对齐(SFT/RLHF/DPO)影响
但在同一设定下,loss 持续下降通常是正向信号。
9.4 checkpoint 越频繁越好吗?
不是。
- 频繁保存会影响吞吐、占用 IO 和磁盘
- 建议:按风险与成本折中(例如每 500~2000 steps 一次),并保留 best + 最近 K 个。
10)小结:用“输入->表示->输出->优化->存档”掌握全局
- Tokenizer:把文本变成 token ids,决定模型看到的“离散世界”如何被切分
- Embedding:把离散 id 变成连续向量,是语义进入网络的入口
- Logits:模型对词表每个 token 的原始预测分数
- Loss:衡量预测与目标差距的标量,驱动学习
- 梯度:loss 对参数的导数,决定参数更新方向与幅度
- Checkpoint:训练的可靠存档点,支撑断点续训、复现、回滚与部署
在后续的 Ai大模型训练教程 实战篇里,你会不断在日志和代码里遇到这些词。建议你把本文当作“概念字典 + 排查清单”,每次训练异常时按流水线逐段定位:从 Tokenizer 到 Loss,再到梯度与 checkpoint 恢复,一层层缩小问题范围。
Prev:Ai大模型训练教程:从入门到实战落地的系统课程