> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/llm_internals/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/llm_internals/di-er-bu-fen-xun-lian-pian/06_training_techniques/6.4_batch_sequence.md).

# 6.4 批次与序列长度：效率与质量的平衡

批次大小（Batch Size）和序列长度（Sequence Length）是影响训练效率、模型质量和显存占用的两个关键变量。6.3.4 节讲梯度累积时，把有效批次大小当成一个已经定好的目标——显存放不下就多累积几步凑上去；至于这个目标该定到多大，那一节没有回答。本节先给这个数字划出上界，再转向与它一起吃掉显存的另一个变量：序列长度。

## 6.4.1 批次大小的影响

**大批次的优势**：

* 更稳定的梯度估计（减少噪声）：大批次时，单个样本的异常值对梯度的影响被平均化
* 更高的 GPU 利用率：矩阵乘法的计算与显存访问比例更优
* 更快的训练吞吐量：更少的参数更新迭代次数

**大批次的风险**：

* **泛化性能下降**：过大的批次可能导致梯度太“平滑”，使模型更容易陷入尖锐的（泛化差的）局部最优。相反，适度的梯度噪声实际上有助于找到更平坦（泛化更好）的最优区域
* **内存瓶颈**：直接增大物理批次会线性增加显存占用，很快就会达到硬件限制
* **学习率的敏感性增加**：大批次通常需要调整学习率，这增加了超参数调优的复杂度

**实践中的折中**：现代训练通常使用**梯度累积**（见[6.3.4](/llm_internals/di-er-bu-fen-xun-lian-pian/06_training_techniques/6.3_regularization.md)）来在显存约束下达成大的有效批次大小。物理批次大小主要受单卡显存、序列长度和并行策略约束；梯度噪声与学习率调度则由全局有效批次决定。梯度累积可以在不直接增大物理批次的情况下模拟更大的有效批次。

原始 Transformer 使用约 25,000 词元/批次进行训练。现代大语言模型的批次规模要大得多——GPT-3 使用 320 万词元/批次，Llama 3 更是从初始阶段的 400 万词元/批次逐渐增大到 1600 万词元/批次。这些是全局训练批次，通常由数据并行、张量并行、流水线并行、上下文并行、micro-batch 调度和必要的梯度累积共同实现，而不是靠单节点显存直接承载。

### 临界批量：为什么不能靠加卡无限扩数据并行

上面那些数字看起来像是「显存和工程能力允许多大就多大」，但其实存在一个与硬件无关的上界。[McCandlish 等人提出的**梯度噪声尺度**](https://arxiv.org/abs/1812.06162)——本质上是梯度在样本之间的信噪比——可以预测「最大有用批量」：训练在批量小于噪声尺度时几乎能**线性并行**，越过之后会相对迅速地切换到「继续加并行几乎没有收益」的区间。这个转折点通常称为**临界批量**（critical batch size）。

这条结论有两个反直觉之处，恰恰是它有用的地方。**其一，噪声尺度会随训练推进而增大**：模型越准，样本之间的梯度分歧越小、信噪比越高，可用的批量也就越大——这正是 Llama 3 从 400 万逐步升到 1600 万的依据，也是「批量预热」（batch size warmup）这类做法的来源，而不是拍脑袋的调参。**其二，噪声尺度主要取决于任务复杂度，而不强依赖模型规模本身**——所以不能简单地认为「模型更大就该配更大的批」。

对分布式训练，这个上界有一个直接后果：**数据并行的可扩展性是有天花板的**。当卡数继续增加、全局批量已经越过临界批量时，再加卡换不来收敛速度，只会摊薄每卡的计算量。此时唯一的出路是把新增的卡投到别的并行维度上——张量并行、流水线并行、上下文并行（[7.3](/llm_internals/di-er-bu-fen-xun-lian-pian/07_distributed_training/7.3_model_tensor_parallel.md)、[7.4 节](/llm_internals/di-er-bu-fen-xun-lian-pian/07_distributed_training/7.4_pipeline_hybrid.md)）。**「为什么大规模训练非要搞三维并行」这个问题的答案，一半在显存，另一半就在这里。**

## 6.4.2 序列长度的管理

序列长度直接影响注意力计算的内存占用（$$O(n^2)$$ 的时间和空间复杂度）和模型能捕捉的最大上下文范围。

**填充与打包**：同一批次中的序列需要统一长度。传统做法是将短序列填充到最大长度，但这浪费了大量计算。**序列打包**（Sequence Packing）是一种更高效的方法——将多个短序列拼接在一起填满一个完整的训练样本，并配合 block-diagonal/block-triangular attention mask、FlashAttention varlen 的 `cu_seqlens`，或等价的序列边界元数据，确保不同序列之间不交互。`position_ids` 只能重置位置编号，不能阻断样本间 attention。这种方法可以提升显存和计算的利用率，特别是在处理包含大量短文本的数据集时。

**动态长度策略**：一些训练框架支持多种优化策略：

* **按长度分组**：将相近长度的序列放入同一批次，减少填充浪费
* **渐进式长度扩展**：在训练过程中逐步增加序列长度——先用短序列（如 512 tokens）快速迭代以建立基础特征，后期切换到长序列（如 4096 tokens）以学习长距离依赖
* **长度采样**：按某种分布随机采样序列长度，而非固定值，以提升模型对变长输入的鲁棒性

**长序列训练的挑战**：随着序列长度增加，注意力的 $$O(n^2)$$ 复杂度迅速成为瓶颈。现代优化包括：

* **FlashAttention**：通过 IO 优化减少显存访问，避免保存完整的 $$n \times n$$ 注意力矩阵
* **分组查询注意力（GQA）**：减少 Key/Value 头数量，让多个 Query 头共享 K/V，降低 KV 缓存和相关访存开销
* **梯度检查点**（见 6.4.3）：以计算换显存

## 6.4.3 显存占用分析

训练 Transformer 时的显存主要被四部分占用。下表是未分片 Adam 训练的教学化口径，实际占比会随精度、ZeRO/FSDP 分片、序列长度、激活重计算和并行策略显著变化：

| 组成部分  | 占用比例   | 说明                      |
| ----- | ------ | ----------------------- |
| 模型参数  | \~20%  | 权重矩阵                    |
| 梯度    | \~20%  | 与参数同等大小                 |
| 优化器状态 | \~40%  | Adam 需要存储一阶/二阶矩（2 倍参数量） |
| 激活值   | \~20%+ | 用于反向传播，随序列长度和批次大小增长     |

表 6-1：训练时显存占用的典型分布

这个分析表明，在未分片 Adam 训练中，**优化器状态常是最大的显存消耗者之一**——这正是 ZeRO 等优化技术的主要优化目标（见[第七章](/llm_internals/di-er-bu-fen-xun-lian-pian/07_distributed_training/7.2_zero.md)）。但在长上下文和大 micro-batch 场景下，激活值也可能成为主导瓶颈。

**梯度检查点**（Gradient Checkpointing，也叫激活重计算）是一种以计算换显存的技术：不保存所有层的激活值，而是只保存部分层的激活值，其他层的激活值在反向传播时重新计算。经典均匀链式分析可把激活显存降到约 $$O(\sqrt{L})$$（$$L$$ 为层数），但现代 Transformer 的实际节省和额外计算开销取决于选择性重计算策略。
