在使用 HuggingFace 的 RobertaTokenizer 之前,我是否需要先对文本进行预标记?(不同的打磨)

All*_*n-J 4 huggingface-transformers huggingface-tokenizers

在 Huggingface 中使用 Roberta 标记器时,我感到很困惑。

>>> tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
>>> x = tokenizer.tokenize("The tiger is ___ (big) than the dog.")
['The', '?tiger', '?is', '?___', '?(', 'big', ')', '?than', '?the', '?dog', '.']
>>> x = tokenizer.tokenize("The tiger is ___ ( big ) than the dog.")
['The', '?tiger', '?is', '?___', '?(', '?big', '?)', '?than', '?the', '?dog', '.']
>>> x = tokenizer.encode("The tiger is ___ (big) than the dog.")
[0, 20, 23921, 16, 2165, 36, 8527, 43, 87, 5, 2335, 4, 2]
>>> x = tokenizer.encode("The tiger is ___ ( big ) than the dog.")
[0, 20, 23921, 16, 2165, 36, 380, 4839, 87, 5, 2335, 4, 2]
>>>
Run Code Online (Sandbox Code Playgroud)

问题(big)并且( big )有不同的标记化结果,这也会导致不同的标记 id。我应该使用哪一种?这是否意味着我应该先对输入进行预标记化,( big )然后再进行 RobertaTokenization?还是真的无所谓?

其次,似乎BertTokenizer没有这样的困惑:

>>> tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
>>> x = tokenizer.tokenize("The tiger is ___ (big) than the dog.")
['the', 'tiger', 'is', '_', '_', '_', '(', 'big', ')', 'than', 'the', 'dog', '.']
>>> x = tokenizer.tokenize("The tiger is ___ ( big ) than the dog.")
['the', 'tiger', 'is', '_', '_', '_', '(', 'big', ')', 'than', 'the', 'dog', '.']
>>>
Run Code Online (Sandbox Code Playgroud)

BertTokenizer 使用 wordpieces 给我相同的结果。

有什么想法可以帮助我更好地理解 RobertaTokenizer,我知道它正在使用字节对编码?

Jin*_*ich 5

Hugingface 的 Transformers 的设计使您不应该进行任何预标记化。

RoBERTa 使用具有无损预标记化的 SentecePiece。即,当你有一个标记化的文本时,你应该总是能够说出标记化之前文本的样子。The ?(即?,原始 SentecePiece 中一个奇怪的 Unicode 下划线)表示当您取消标记时应该有一个空格。结果big?big最终成为不同的令牌。当然,在这个特定的上下文中,它没有多大意义,因为它显然仍然是同一个词,但这是您为无损标记化付出的代价以及 RoBERTa 是如何训练的。

BERT 使用 WordPiece,它不会遇到这个问题。另一方面,原始字符串和标记化文本之间的映射并不那么简单(这可能不方便,例如,当您想突出显示用户生成的文本中的某些内容时)。