分词器解码步骤中的分词到单词的映射 huggingface?
Tokens to Words mapping in the tokenizer decode step huggingface?
有没有办法知道 tokenizer.decode()
函数中从标记到原始单词的映射?
例如:
from transformers.tokenization_roberta import RobertaTokenizer
tokenizer = RobertaTokenizer.from_pretrained('roberta-large', do_lower_case=True)
str = "This is a tokenization example"
tokenized = tokenizer.tokenize(str)
## ['this', 'Ġis', 'Ġa', 'Ġtoken', 'ization', 'Ġexample']
encoded = tokenizer.encode_plus(str)
## encoded['input_ids']=[0, 42, 16, 10, 19233, 1938, 1246, 2]
decoded = tokenizer.decode(encoded['input_ids'])
## '<s> this is a tokenization example</s>'
而 objective 是要有一个函数,将 decode
过程中的每个标记映射到正确的输入词,因为这里它将是:
desired_output = [[1],[2],[3],[4,5],[6]]
因为 this
对应于 id 42
,而 token
和 ization
对应于索引 [19244,1938]
=19=] input_ids
数组。
据我所知,他们没有内置方法,但您可以自己创建一个:
from transformers.tokenization_roberta import RobertaTokenizer
tokenizer = RobertaTokenizer.from_pretrained('roberta-large', do_lower_case=True)
example = "This is a tokenization example"
print({x : tokenizer.encode(x, add_special_tokens=False, add_prefix_space=True) for x in example.split()})
输出:
{'This': [42], 'is': [16], 'a': [10], 'tokenization': [19233, 1938], 'example': [1246]}
要准确获得所需的输出,您必须使用列表推导式:
#start index because the number of special tokens is fixed for each model (but be aware of single sentence input and pairwise sentence input)
idx = 1
enc =[tokenizer.encode(x, add_special_tokens=False, add_prefix_space=True) for x in example.split()]
desired_output = []
for token in enc:
tokenoutput = []
for ids in token:
tokenoutput.append(idx)
idx +=1
desired_output.append(tokenoutput)
print(desired_output)
输出:
[[1], [2], [3], [4, 5], [6]]
如果您使用快速标记器,即来自 tokenizers
库的 Rust 支持版本,编码包含一个 word_ids
方法,可用于将子词映射回其原始词。 word
与 subword
的构成取决于分词器,词是由预分词阶段生成的东西,即由空格分割,子词由实际模型生成(BPE
或 Unigram
例如)。
下面的代码通常应该可以工作,即使预标记化执行了额外的拆分。例如,我创建了自己的基于 PascalCase 拆分的自定义步骤 - 这里的 words
是 Pascal
和 Case
,接受的答案在这种情况下不起作用,因为它假定单词是用空格分隔的。
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('roberta-large', do_lower_case=True)
example = "This is a tokenization example"
encoded = tokenizer(example)
desired_output = []
for word_id in encoded.word_ids():
if word_id is not None:
start, end = encoded.word_to_tokens(word_id)
if start == end - 1:
tokens = [start]
else:
tokens = [start, end-1]
if len(desired_output) == 0 or desired_output[-1] != tokens:
desired_output.append(tokens)
desired_output
有没有办法知道 tokenizer.decode()
函数中从标记到原始单词的映射?
例如:
from transformers.tokenization_roberta import RobertaTokenizer
tokenizer = RobertaTokenizer.from_pretrained('roberta-large', do_lower_case=True)
str = "This is a tokenization example"
tokenized = tokenizer.tokenize(str)
## ['this', 'Ġis', 'Ġa', 'Ġtoken', 'ization', 'Ġexample']
encoded = tokenizer.encode_plus(str)
## encoded['input_ids']=[0, 42, 16, 10, 19233, 1938, 1246, 2]
decoded = tokenizer.decode(encoded['input_ids'])
## '<s> this is a tokenization example</s>'
而 objective 是要有一个函数,将 decode
过程中的每个标记映射到正确的输入词,因为这里它将是:
desired_output = [[1],[2],[3],[4,5],[6]]
因为 this
对应于 id 42
,而 token
和 ization
对应于索引 [19244,1938]
=19=] input_ids
数组。
据我所知,他们没有内置方法,但您可以自己创建一个:
from transformers.tokenization_roberta import RobertaTokenizer
tokenizer = RobertaTokenizer.from_pretrained('roberta-large', do_lower_case=True)
example = "This is a tokenization example"
print({x : tokenizer.encode(x, add_special_tokens=False, add_prefix_space=True) for x in example.split()})
输出:
{'This': [42], 'is': [16], 'a': [10], 'tokenization': [19233, 1938], 'example': [1246]}
要准确获得所需的输出,您必须使用列表推导式:
#start index because the number of special tokens is fixed for each model (but be aware of single sentence input and pairwise sentence input)
idx = 1
enc =[tokenizer.encode(x, add_special_tokens=False, add_prefix_space=True) for x in example.split()]
desired_output = []
for token in enc:
tokenoutput = []
for ids in token:
tokenoutput.append(idx)
idx +=1
desired_output.append(tokenoutput)
print(desired_output)
输出:
[[1], [2], [3], [4, 5], [6]]
如果您使用快速标记器,即来自 tokenizers
库的 Rust 支持版本,编码包含一个 word_ids
方法,可用于将子词映射回其原始词。 word
与 subword
的构成取决于分词器,词是由预分词阶段生成的东西,即由空格分割,子词由实际模型生成(BPE
或 Unigram
例如)。
下面的代码通常应该可以工作,即使预标记化执行了额外的拆分。例如,我创建了自己的基于 PascalCase 拆分的自定义步骤 - 这里的 words
是 Pascal
和 Case
,接受的答案在这种情况下不起作用,因为它假定单词是用空格分隔的。
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('roberta-large', do_lower_case=True)
example = "This is a tokenization example"
encoded = tokenizer(example)
desired_output = []
for word_id in encoded.word_ids():
if word_id is not None:
start, end = encoded.word_to_tokens(word_id)
if start == end - 1:
tokens = [start]
else:
tokens = [start, end-1]
if len(desired_output) == 0 or desired_output[-1] != tokens:
desired_output.append(tokens)
desired_output