目录
第三课里,模型拿到形状为 $[B,T]$ 的 Token IDs,做前向计算、计算 Loss,再更新参数。
但现实中的训练数据并不是整齐的矩阵,而是网页、书籍、代码、对话等长短不一的文本。它们怎样变成 GPU 能高效计算的 Batch?
数据流水线的任务,就是把杂乱文本变成形状稳定、边界清楚、浪费尽量少的 Token 矩阵。
1、原始数据不能直接训练
收集来的文本常包含重复网页、乱码、广告、导航栏、隐私信息和低质量内容。直接训练会浪费算力,甚至让模型学到错误模式。
常见处理包括:格式解析、语言识别、质量过滤、去重、安全与隐私过滤。清洗不是“越干净越好”,而是在质量、多样性和覆盖面之间取平衡。
2、Tokenize:保留文档边界
清洗后的每篇文档会被 Tokenizer 转成 Token IDs。文档末尾通常加入特殊 Token,例如 <eos>:
文档 A → [314, 923, 5621, <eos>]
文档 B → [81, 490, 207, 35, <eos>]
<eos> 告诉模型“一篇文档到这里结束”。如果完全抹掉边界,模型可能把两篇无关文章误当成连续上下文。
3、把长序列切成固定窗口
训练通常设定固定的 Sequence Length,例如 2048 或 4096。过长文档需要切开,短文档则可以拼接。
连续 Token 流:[文档A <eos> 文档B <eos> 文档C <eos> ...]
固定窗口: [--------- T ---------][--------- T ---------]
将多个短样本填入同一窗口叫 Packing。它能减少 Padding,让更多计算真正用在 Token 上。但实现时要明确:不同样本能否互相 Attention,以及 Loss 应在哪些位置计算。
4、组成 Batch
长度为 $T$ 的训练块会被组合成 Batch。若一次取 $B$ 条,输入形状就是:
\[input\_ids \in \mathbb{Z}^{B\times T}\]| 符号 | 含义 |
|---|---|
| $B$ | Batch Size,一次处理多少条序列 |
| $T$ | Sequence Length,每条序列多少个 Token |
| $V$ | Vocabulary Size,词表大小 |
更大的 $B$ 通常让梯度更稳定,但占用更多显存。显存不够时,可以用 Gradient Accumulation:连续计算几个小 Batch 的梯度,再统一更新一次参数。
5、Padding 与 Attention Mask
如果一个 Batch 内的序列长度不同,短序列会补 <pad>,使矩阵形状一致:
[A, B, C, D]
[E, F, <pad>, <pad>]
Attention Mask 告诉模型哪些位置是真实 Token,哪些只是补齐。计算 Loss 时,Padding 位置也应被忽略。
不要把它和 Causal Mask 混为一谈:
| Mask | 解决什么问题 |
|---|---|
| Padding Mask | 不读取补齐出来的空位置 |
| Causal Mask | 不读取当前位置右侧的未来 Token |
6、DataLoader:把数据送进 GPU
训练时,CPU 不断准备下一批数据,GPU 同时计算当前批。DataLoader 通常负责:
- Shuffle:打乱样本顺序,减少固定顺序带来的偏差。
- Batch:按批取出训练块。
- Collate:补齐、生成 Mask,并整理成张量。
- Prefetch:提前准备后续 Batch,减少 GPU 等待。
- Transfer:把张量复制到 GPU 显存。
如果数据准备太慢,再贵的 GPU 也只能空等。因此数据吞吐量也是训练系统的重要指标。
一次数据迭代
| 阶段 | 输入 | 输出 |
|---|---|---|
| 清洗与去重 | 原始文档 | 高质量文档 |
| Tokenize | 文本 | Token IDs + <eos> |
| Chunk / Pack | 长短不一的序列 | 固定长度训练块 |
| Shuffle / Batch | 训练块 | $[B,T]$ |
| Collate | 一个 Batch | IDs、Labels、Masks |
| Transfer | CPU Tensor | GPU Tensor |
| Forward / Backward | GPU Batch | Loss 与梯度 |
一个 Epoch 表示模型大致遍历一遍训练集;一次 Step 通常表示优化器完成一次参数更新。两者不是一回事。
记住这 5 件事
- 原始文本需要清洗、过滤和去重。
<eos>等特殊 Token 用来保留文档边界。- Chunking 和 Packing 把 Token 整理成固定长度窗口。
- Padding Mask 与 Causal Mask 解决不同问题。
- DataLoader 要尽量让 GPU 持续有数据可算。
第四课复习总图
下一课,我们可以继续看:训练一个大模型为什么这么吃显存,显存究竟花在了哪里?