讨论的是在训练大型语言模型(Transformer-based models,比如GPT等)时,文本序列的填充(padding)问题,即训练和推理时分辨填充在序列的左侧(left padding)或右侧(right padding)进行?
先说结论:常规实践时,训练时,我们通常使用右填充(right padding);在推理时,使用左填充(left padding)。当然在通常的训练推理框架中这是一个可选配置。例如,在Hugging Face的Transformers库中,默认的填充方式可以通过tokenizer的设置来选择。
为什么会有这样的常规设置?
下面先详细解释一下左右padding的含义:
1. 右填充(Right Padding): 在序列的右侧(即末尾)添加填充符号(如[PAD] token)直到达到最大长度。 例如,假设最大长度为5,一个序列为["A", "B"],右填充后变成["A", "B", "[PAD]", "[PAD]", "[PAD]"]。
2. 左填充(Left Padding): 在序列的左侧(即开头)添加填充符号。 同样的例子,左填充后变成["[PAD]", "[PAD]", "[PAD]", "A", "B"]。
padding的作用是:
一个批次(batch)中的文本序列长度不同,需通过添加特殊符号(如
[PAD]
)使所有序列等长。便于并行计算(如GPU加速),避免因长度不一致导致的计算错误。
接下来解释为什么训练是右填充,推理是左填充:
训练时,对于自回归模型(从左到右生成),我们一次处理整个序列,模型在预测下一个token时,注意力机制会关注到左侧的所有token,因此我们把填充部分放在右边,右填充确保真实token集中在左侧,模型更易学习连续依赖关系。然后通常会对填充位置计算损失时进行掩码(mask),所以填充部分不会影响训练。
在推理时,当我们使用批次推理(batch inference)并采用自回归生成时,左填充可以使得每个序列的真实内容都位于右侧,这样在生成过程中,模型每次只需要关注最新的token(即最右侧的token),而左侧的填充不会干扰生成。同时,由于模型在生成时是从左到右,左填充确保了真实内容在生成过程中始终位于模型的右侧上下文,生成文本时(如逐token生成),左填充将真实token推向右侧,使模型每次只需关注最新生成的token(右侧)。若用右填充,生成过程中真实token在左侧,而模型会根据右侧Padding token来生成新内容,效果差。