背景
在使用其他組織或個人釋出的RoBERTa預訓練模型時,一般除了模型檔案之外還會有
merges.txt
和
vocab.json
。相比于BERT隻需要一個
vocab.txt
,為何RoBRETa需要2個?作用是什麼?
PS:這裡使用的是huggingface/transformers 下的 RoBRTa-base版模型。
說明
Bert采用的是字元級别的BPE編碼,直接生成詞表檔案。Roberta采用的是**byte level的BPE(BBPE)**編碼,預訓練結果中的
merges.txt
中存儲了BBPE過程中merge得到的所有token,可以簡單了解成就是字典。
vocab.json
則是一個字典中基本單元到索引的映射。轉換的過程是,根據
merges.txt
将輸入的文本tokenize化,再根據
vocab.json
中的字典映射到對應的索id。
其中
merges.txt
存放的是訓練tokenizer階段所得到的合并詞表結果。看下
merges.txt
的前6行資訊:
#version: 0.2
Ġ t
Ġ a
h e
i n
r e
第2行的
Ġ t
表示BPE合并詞典的過程,第一輪疊代中最高頻的字元是
t
,且在該
t
字元前面是空格,這裡的
Ġ
表示空格。換句話說,在第一輪疊代中,最高頻的是單詞首字元的
t
,而不是其他位置的
t
。這裡的
Ġ
表示空格,其背後含義是單詞的起始,用以區分邊界。進一步檢視
vocab.json
中的内容,可以看出
"Ġt": 326
,即
Ġt
的索引id是326。另外,由于是該檔案中的每一行都是通過合并而成,是以在一行中保留了空格,以明示2個合并源。
比如對文本:
"What's up with the tokenizer? t asks"
進行tokenization,結果如下:
tokenizer.tokenize: ['What', "'s", 'Ġup', 'Ġwith', 'Ġthe', 'Ġtoken', 'izer', '?', 'Ġt', 'Ġasks']
convert_tokens_to_ids: [2264, 18, 62, 19, 5, 19233, 6315, 116, 326, 6990]
可以看出,字元
t
對應的tokenize結果是
Ġt
,
Ġt
對應的id是326。這與預期符合。
再看下
merges.txt
中的
h e
這一行。這說明,BPE第2輪疊代中
h
和
e
是最高頻的,是以将2者合并。需要特别注意的是:這裡的
h
前面沒有空格,這說明這裡的
h
不是一個單詞的開頭,也就不存在空格。換句話說,這裡的
h
存在于某些單詞中間位置。進一步在
vocab.json
中查找
he
所對應的索引id為:
"he": 700
。
當輸入文本為:
What's up with the tokenizer? he asks lhe question
時(PS:這裡為了建構’he’的編碼,杜撰了
lhe
這個單詞),tokenization結果如下:
tokenizer.tokenize: ['What', "'s", 'Ġup', 'Ġwith', 'Ġthe', 'Ġtoken', 'izer', '?', 'Ġhe', 'Ġasks', 'Ġl', 'he', 'Ġquestion']
convert_tokens_to_ids: [2264, 18, 62, 19, 5, 19233, 6315, 116, 37, 6990, 784, 700, 864]
可以看出,将
lhe
這個單詞分割成
'Ġl'
和
'he'
2部分,其中
he
在詞典中對應的索引id為700。