难以理解 Roberta 模型中使用的分词器
Difficulty in understanding the tokenizer used in Roberta model
from transformers import AutoModel, AutoTokenizer
tokenizer1 = AutoTokenizer.from_pretrained("roberta-base")
tokenizer2 = AutoTokenizer.from_pretrained("bert-base-cased")
sequence = "A Titan RTX has 24GB of VRAM"
print(tokenizer1.tokenize(sequence))
print(tokenizer2.tokenize(sequence))
输出:
['A', 'ĠTitan', 'ĠRTX', 'Ġhas', 'Ġ24', 'GB', 'Ġof', 'ĠVR', 'AM']
['A', 'Titan', 'R', '##T', '##X', 'has', '24', '##GB ', 'of', 'V', '##RA', '##M']
Bert 模型使用 WordPiece 分词器。任何没有出现在 WordPiece 词汇表中的词都会被贪婪地分解成子词。例如,'RTX' 被分解为 'R'、'##T' 和 '##X',其中 ## 表示它是一个子标记。
罗伯塔使用 BPE 分词器,但我无法理解
a) BPE 分词器是如何工作的?
b) G在每个标记中代表什么?
这个问题非常广泛,所以我试图给出一个侧重于手头主要问题的答案。如果您觉得需要回答其他问题,请打开另一个问题 一次一个问题,请参阅 Whosebug 的 [help/on-topic] 规则。
基本上,正如您已经正确识别的那样,BPE 是现代深度网络中任何标记化的核心。我强烈建议您阅读 original BPE paper by Sennrich et al.,其中还重点介绍了 BPE 的更多历史。
在任何情况下,任何 huggingface 模型的分词器都是预训练的,这意味着它们通常是预先从算法的训练集中生成的。诸如 SentencePiece 之类的常见实现也可以更好地理解它,但本质上该任务被定义为约束优化问题,您可以在其中指定最大数量的 k
允许的词汇(约束),然后该算法尝试在不超过 k
.
的情况下保持尽可能多的单词完整
如果没有足够的单词来覆盖整个词汇表,则使用较小的单位来近似词汇表,这会导致在您给出的示例中观察到的分裂。
RoBERTa使用了一种叫做“byte-level BPE”的变体,最好的解释大概在this study by Wang et al.中给出了。主要的好处是,据我所知,它在保持拆分质量的同时减少了词汇量。
你问题的第二部分比较容易解释;虽然 BERT 突出显示了两个后续令牌的合并(##
),但 RoBERTa 的分词器反而突出显示了新令牌的开始特定的 unicode 字符(在本例中,\u0120
,带点的 G)。我能找到的最好的理由是 this thread,它认为它基本上避免了在训练中使用空格。
a) 我建议 this 读一读。本质上,BPE (Byte-Pair-Encoding) 采用超参数 k,并尝试构造 <=k 数量的字符序列,以便能够表达训练文本语料库中的所有单词。 RoBERTa 使用 byte-level BPE,它将基本词汇表设置为 256,即有多少个 unicode 字符。
b) 带点 (Ġ) 的 G 似乎是随机选择的,它可能是任何字符。只要有a个字符可以编码 RobertaTokenizer 还利用了其他“非典型”字符进行编码,比如 'Ĵ' (u/0134) '例如,用 Ĺ (u/0139) 和 '¤' (u/0164) 编码表情符号。
from transformers import AutoModel, AutoTokenizer
tokenizer1 = AutoTokenizer.from_pretrained("roberta-base")
tokenizer2 = AutoTokenizer.from_pretrained("bert-base-cased")
sequence = "A Titan RTX has 24GB of VRAM"
print(tokenizer1.tokenize(sequence))
print(tokenizer2.tokenize(sequence))
输出:
['A', 'ĠTitan', 'ĠRTX', 'Ġhas', 'Ġ24', 'GB', 'Ġof', 'ĠVR', 'AM']
['A', 'Titan', 'R', '##T', '##X', 'has', '24', '##GB ', 'of', 'V', '##RA', '##M']
Bert 模型使用 WordPiece 分词器。任何没有出现在 WordPiece 词汇表中的词都会被贪婪地分解成子词。例如,'RTX' 被分解为 'R'、'##T' 和 '##X',其中 ## 表示它是一个子标记。
罗伯塔使用 BPE 分词器,但我无法理解
a) BPE 分词器是如何工作的?
b) G在每个标记中代表什么?
这个问题非常广泛,所以我试图给出一个侧重于手头主要问题的答案。如果您觉得需要回答其他问题,请打开另一个问题 一次一个问题,请参阅 Whosebug 的 [help/on-topic] 规则。
基本上,正如您已经正确识别的那样,BPE 是现代深度网络中任何标记化的核心。我强烈建议您阅读 original BPE paper by Sennrich et al.,其中还重点介绍了 BPE 的更多历史。
在任何情况下,任何 huggingface 模型的分词器都是预训练的,这意味着它们通常是预先从算法的训练集中生成的。诸如 SentencePiece 之类的常见实现也可以更好地理解它,但本质上该任务被定义为约束优化问题,您可以在其中指定最大数量的 k
允许的词汇(约束),然后该算法尝试在不超过 k
.
如果没有足够的单词来覆盖整个词汇表,则使用较小的单位来近似词汇表,这会导致在您给出的示例中观察到的分裂。 RoBERTa使用了一种叫做“byte-level BPE”的变体,最好的解释大概在this study by Wang et al.中给出了。主要的好处是,据我所知,它在保持拆分质量的同时减少了词汇量。
你问题的第二部分比较容易解释;虽然 BERT 突出显示了两个后续令牌的合并(##
),但 RoBERTa 的分词器反而突出显示了新令牌的开始特定的 unicode 字符(在本例中,\u0120
,带点的 G)。我能找到的最好的理由是 this thread,它认为它基本上避免了在训练中使用空格。
a) 我建议 this 读一读。本质上,BPE (Byte-Pair-Encoding) 采用超参数 k,并尝试构造 <=k 数量的字符序列,以便能够表达训练文本语料库中的所有单词。 RoBERTa 使用 byte-level BPE,它将基本词汇表设置为 256,即有多少个 unicode 字符。
b) 带点 (Ġ) 的 G 似乎是随机选择的,它可能是任何字符。只要有a个字符可以编码 RobertaTokenizer 还利用了其他“非典型”字符进行编码,比如 'Ĵ' (u/0134) '例如,用 Ĺ (u/0139) 和 '¤' (u/0164) 编码表情符号。