使用 HuggingFace 的流水线工具,我惊讶地发现使用快速和慢速分词器时输出存在显着差异。
具体来说,当我运行填充掩码管道时,分配给将填充掩码的单词的概率对于快速和慢速分词器来说是不同的。此外,尽管无论输入句子的数量和长度如何,快速分词器的预测都保持不变,但对于慢速分词器而言,情况并非如此。
这是一个最小的例子:
from transformers import pipeline
slow = pipeline('fill-mask', model='bert-base-cased', \
tokenizer=('bert-base-cased', {"use_fast": False}))
fast = pipeline('fill-mask', model='bert-base-cased', \
tokenizer=('bert-base-cased', {"use_fast": True}))
s1 = "This is a short and sweet [MASK]." # "example"
s2 = "This is [MASK]." # "shorter"
slow([s1, s2])
fast([s1, s2])
slow([s2])
fast([s2])
每个管道调用都会产生可以填充的前 5 个令牌[MASK]
,以及它们的概率。为简洁起见,我省略了实际输出,但分配给每个单词的概率在所有示例[MASK]
中s2
并不相同。最后 3 个示例给出了相同的概率,但第一个示例产生了不同的概率。差异如此之大,以至于两组的前 5 名并不一致。
据我所知,这背后的原因是快速和慢速分词器返回不同的输出。快速分词器通过用 0 填充将序列长度标准化为 512,然后创建一个注意掩码来阻止填充。相比之下,slow tokenizer 只填充最长序列的长度,并不会创建这样的注意掩码。相反,它将填充的令牌类型 id 设置为 1(而不是 0,这是非填充令牌的类型)。根据我对 HuggingFace 的实现(在此处找到)的理解,这些是不等价的。
有谁知道这是否是故意的?