来自 知乎
总的来说是为了计算效率,所以把长度限制在了512。
To speed up pretraing in our experiments, we pre-train the model with sequence length of 128 for 90% of the steps. Then, we train the rest 10% of the steps of sequence of 512 to learn the positional embeddings.
当然,最最本质的原因还是在于BERT中的Positional Embedding和Transformer中的Positional Embedding实现方式不一样,后者是通过公式计算得到的,而前者本质上则是一个可学习的参数,也就是说每个位置所对应的向量就类似于Token Embedding中每个词对应的词向量。
class PositionalEmbedding(nn.Module):
"""
位置编码。
*** 注意: Bert中的位置编码完全不同于Transformer中的位置编码,
前者本质上也是一个普通的Embedding层,而后者是通过公式计算得到,
而这也是为什么Bert只能接受长度为512字符的原因,因为位置编码的最大size为512 ***
# Since the position embedding table is a learned variable, we create it
# using a (long) sequence length `max_position_embeddings`. The actual
# sequence length might be shorter than this, for faster training of
# tasks that do not have long sequences.
———————— GoogleResearch
https://github.com/google-research/bert/blob/eedf5716ce1268e56f0a50264a88cafad334ac61/modeling.py
"""
def __init__(self, hidden_size, max_position_embeddings=512, initializer_range=0.02):
super(PositionalEmbedding, self).__init__()
self.embedding = nn.Embedding(max_position_embeddings, hidden_size)
self._reset_parameters(initializer_range)
因此,除非是你自己从零开始训练一个模型,否则如果你使用的是谷歌开源的预训练模型,那么这个词表的大小将会被限制在512。 当然,你依旧可以突破这个限制,那就是自己在从新初始化Positional Embedding中的向量,然后对前512个进行替换,后面的就自己在对于语料上训练微调。