- 长度外推性是一个训练和预测的长度不一致的问题。不一致的地方有两个地方,第一是预测的时候用到了训练时未曾见过的位置编码;第二是预测时候所处理的注意力token数量远超训练的大小。第一个问题很好理解,用到没见过的位置编码效果肯定会有下降。对于第二个问题,当token数量变大时,softmax的注意力权重就会被稀释变的特别分散,和训练时的分布不一致。
相对位置编码的问题
- 相对位置编码比较常用的是苏神的旋转位置编码,这一类相对位置编码都是对softmax之前的attention矩阵进行操作的,即加在了Q和K矩阵上。我们要判断一个模型有没有编码位置的能力,一个最简单的方案是输入一个全0向量,输出是[1,2,3,4...n]。绝对位置编码是很容易做到的,因为它和位置n相关。由于相对位置编码都是在softmax之前的,因此经过softmax之后,Attention矩阵是个和为1的行向量。那么Oi=AijVij,当v相同时,输出的O也是相同的。即模型无法识别位置信息。
- 那么有没有办法解决这个问题呢,肯定有。正是因为softmax进行了归一化才导致出现的这个问题,一个最简单的想法就是不归一化,或者改成l2 norm也行。这种方式去训练模型是work的。
- 无法输出[1,2,3,4...n]的原因是每个输入vi是相同的,但是现实中不存在这样的情况。包括bert或者是llm,都会有一些特殊的token,比如bert中的cls,sep。有了这些特殊的token标记,其实就能有效识别不同的位置了。其实cls token就相当于是一个起始标记位,后续以他为准对齐,模型就认识不同的位置了。包括最开始的cnn中,有论文就指出是padding标记导致cnn有了位置信息一样。参考
长度外推的一些方案
旋转位置编码的内插和外插
- 外插,简单来说,假如原来位置编码用三维向量表示,那外插就是直接增加一维
- 内插,就是将2000以内压缩到1000以内,比如通过除以2,1749就变成了874.5,然后转为三维向量[8,7,4.5]输入到原来的模型中。从绝对数值来看,新的[7,4,9]实际上对应的是1498,是原本对应的2倍,映射方式不一致;从相对数值来看,原本相邻数字的差距为1,现在是0.5,最后一个维度更加“拥挤”。所以,做了内插修改后,通常都需要微调训练,以便模型重新适应拥挤的映射关系。
- 进制转换,三个数字的10进制编码可以表示0~999,如果是16进制呢?它最大可以表示163−1=4095>1999。所以,只需要转到16进制,如1749变为[6,13,5],那么三维向量就可以覆盖目标范围,代价是每个维度的数字从0~9变为0~15。唯一担心的是每个维度超过9之后(10~15)模型还能不能正常比较,但事实上一般模型也有一定的泛化能力,所以每个维度稍微往外推一些是没问题的。所以,这个转换进制的思路,甚至可能不微调原来模型也有效!这个思路就是NTK-aware scaled RoPE。
- 其中,直接外推方案就是啥也不改,内插方案就是将n换成n/k,其中k是要扩大的倍数,这就是Meta的论文所实验的Positional Interpolation,里边的实验结果也证明了外推比内插确实需要更多的微调步数。
- 参考
NBCE