中间激活值(Intermediate Activations),简单说就是:神经网络前向传播过程中,每一层计算出来的输出结果,在反向传播用完之前,都必须留在显存里。
假设你有一个 3 层的小网络:
输入 x → [层1] → h1 → [层2] → h2 → [层3] → 输出 y
前向传播时:
反向传播时,要计算每一层的梯度,需要用到该层的输入。比如算 layer2 的权重梯度,需要用到 $h_1$;算 layer1 的权重梯度,需要用到 $x$。
所以框架(PyTorch/TensorFlow)在训练时默认会把这些中间结果全部保存下来,等反向传播用完之后才释放。
关键在于每一层的激活值都要存,而且往往维度很高。
以一个 Transformer 为例,某一层的激活值张量形状可能是:
$$ [\text{batch\_size}, \text{seq\_len}, \text{hidden\_dim}] = [32, 512, 4096] $$
这大约是 $32 \times 512 \times 4096 \approx 6700$ 万个元素。如果用 fp16 存储,就是约 134 MB,而这只是一层。
一个 LLM 有几十层,再加上注意力矩阵($\text{seq\_len} \times \text{seq\_len}$)、FFN 中间层(通常是 hidden_dim 的 4 倍)等,激活值总量可以轻松达到几十 GB。
对比一下:
| 项目 | 量级特点 |
|---|---|
| 模型参数 | 固定,与 batch/序列长度无关 |
| 梯度 | 和参数一样大 |
| 优化器状态 | Adam 是参数的 2 倍 |
| 中间激活值 | 随 batch size、序列长度、层数线性甚至平方增长 |
所以当你把 batch size 或序列长度调大时,显存爆炸的元凶通常就是激活值。
一句话总结:中间激活值就是前向传播时每层算出来的中间结果,因为反向传播要用,所以必须暂存在显存里;它的大小随输入规模增长,是训练时显存占用的主要来源之一。
评论专区
评论加载中...登录后即可发表评论