报错是这么冒出来的。数据集里大部分样本不到 500 token,却有少量超过 8000 token,训练时显存峰值被这些长样本拉高。

中间走过弯路,把「直接截断会切断答案,模型学到不完整输出」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。长尾样本决定了 padding 与显存峰值。还有一种是按批内最长样本 padding,短样本浪费显存。

还有一种情况,长度统计只看了字符数,没有看 token 数。

动手时先统计 token 长度的分位数

python -c "import numpy as np;print(np.percentile(lens,[50,90,99,100]))"

然后按分位数设上限并丢弃极端样本

python filter_len.py --max-tokens 4096 --keep 0.995

批内按长度分桶减少填充浪费

python -c "print('use length grouped sampler')"

剩下的就是对必须保留的长样本单独做切分

python split_long.py --max-tokens 4096 --overlap 128

怎么算真的好了,看的是同一批现象。显存峰值下降约四成,训练速度提升,丢弃比例控制在千分之五以内,长样本内容仍被覆盖。

截断时如果只截输入不截标签,模型会被训练成“看到一半问题就给完整答案”,这类样本建议直接丢弃而不是截断。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189