有没有一种方法可以获取在BERT中已生成特定令牌的子字符串的位置?

时间:2020-08-14 13:09:15

标签: tokenize bert-language-model huggingface-transformers huggingface-tokenizers

我正在为BERT模型(Hugging Face库)提供句子。这些句子通过预训练的分词器分词。我知道您可以使用解码功能将令牌从令牌转换回字符串。

string = tokenizer.decode(...)

但是,重建并不完美。如果使用无大小写的预训练模型,则大写字母会丢失。同样,如果令牌生成器将一个单词拆分为2个令牌,则第二个令牌将以“ ##”开头。例如,“冠状病毒”一词分为两个标记:“冠状病毒”和“ ##病毒”。

所以我的问题是:是否有一种方法可以获取创建每个令牌的子字符串的索引? 例如,使用字符串“东京报告近370例新的冠状病毒病例,创下新的单日记录”。第9个令牌是与“病毒”相对应的令牌。

['[CLS]', 'tokyo', 'to', 'report', 'nearly', '370', 'new', 'corona', '##virus', 'cases', ',', 'setting', 'new', 'single', '-', 'day', 'record', '[SEP]']

我想告诉我令牌'## virus'来自原始字符串中位于子字符串索引37和41之间的'virus'子字符串。

sentence = "Tokyo to report nearly 370 new coronavirus cases, setting new single-day record"
print(sentence[37:42]) # --> outputs 'virus

1 个答案:

答案 0 :(得分:1)

据我所知,它们不是内置方法,但是您可以自己创建一个方法:

import re
from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

sentence = "Tokyo to report nearly 370 new coronavirus cases, setting new single-day record"

b = []
b.append(([101],))
for m in re.finditer(r'\S+', sentence):
  w = m.group(0)
  t = (tokenizer.encode(w, add_special_tokens=False), (m.start(), m.end()-1))

  b.append(t)

b.append(([102],))

b

输出:

[([101],),
 ([5522], (0, 4)),
 ([2000], (6, 7)),
 ([3189], (9, 14)),
 ([3053], (16, 21)),
 ([16444], (23, 25)),
 ([2047], (27, 29)),
 ([21887, 23350], (31, 41)),
 ([3572, 1010], (43, 48)),
 ([4292], (50, 56)),
 ([2047], (58, 60)),
 ([2309, 1011, 2154], (62, 71)),
 ([2501], (73, 78)),
 ([102],)]