变形金刚 BartTokenizer::add_tokens() 不像我对后缀的预期那样工作
Posted
技术标签:
【中文标题】变形金刚 BartTokenizer::add_tokens() 不像我对后缀的预期那样工作【英文标题】:transformers BartTokenizer::add_tokens() Doesn't Work as I'd Expect for Suffixes 【发布时间】:2022-01-06 00:11:13 【问题描述】:我似乎可以毫无问题地添加标记,但如果我尝试添加后缀(即.. 前面没有初始化字符 'Ġ'
的后缀),标记器不会在其中添加空格正确的位置。这是一些非常简化的测试代码。
from copy import deepcopy
from transformers import BartTokenizer
# Get the different tokenizers
tokenizer = BartTokenizer.from_pretrained('facebook/bart-base')
tokenizer_ext = deepcopy(tokenizer)
# Note that putting Ġ after the token causes the token not to be used
num_added = tokenizer_ext.add_tokens(['-of', '_01', 'WXYZ'])
# Original sentence
print('Original')
serial = ':ARG0-of ( sense_01 :ARG1 ( urgencyWXYZ )'
print(serial)
print()
# Baseline tokenizer
print('Bart default tokenizer')
tokens = tokenizer.tokenize(serial)
out_str = tokenizer.convert_tokens_to_string(tokens)
print(tokens)
print(out_str)
print()
# extended tokenizer
print('Extended tokenizer')
tokens = tokenizer_ext.tokenize(serial)
out_str = tokenizer_ext.convert_tokens_to_string(tokens)
print(tokens)
print(out_str)
这给了...
Original
:ARG0-of ( sense_01 :ARG1 ( urgencyWXYZ )
Bart default tokenizer
[':', 'AR', 'G', '0', '-', 'of', 'Ġ(', 'Ġsense', '_', '01', 'Ġ:', 'AR', 'G', '1', 'Ġ(', 'Ġurgency', 'W', 'XY', 'Z', 'Ġ)']
:ARG0-of ( sense_01 :ARG1 ( urgencyWXYZ )
Extended tokenizer
[':', 'AR', 'G', '0', '-of', '(', 'Ġsense', '_01', ':', 'AR', 'G', '1', 'Ġ(', 'Ġurgency', 'WXYZ', ')']
:ARG0-of( sense_01:ARG1 ( urgencyWXYZ)
请注意,默认的 bart 分词器会产生与原始句子相同的输出,但扩展的分词器不会在新的后缀分词之后放置空格。即.. 它选择'('
而不是'Ġ('
。知道为什么会这样以及添加后缀标记的正确方法是什么?
【问题讨论】:
【参考方案1】:简短的回答是,在为 Bart(以及 RoBerta、GPT2 等)添加的标记的处理中存在“行为”(错误?),它明确地从相邻(左右)标记中去除空格到添加令牌的位置。我没有看到一个简单的解决方法。
添加的标记在转换器的标记器代码中以不同方式处理。首先拆分文本,使用Trie
来识别添加的标记列表中的任何标记(请参阅tokenization_utils.py::tokenize()
)。在文本中找到任何添加的标记后,然后使用现有的 vocab/bpe 编码方案对其余部分进行标记(参见tokenization_gpt2.py::_tokenize()
)
添加的标记被添加到self.unique_no_split_tokens
列表中,以防止它们被进一步分解成更小的块。处理此问题的代码(请参阅tokenization_utils.py::tokenize()
显式去除左右标记的空格。
您可以手动将它们从“不拆分”列表中删除,但随后它们可能会被分解为更小的子组件。
请注意,对于“特殊标记”,如果您在 AddedToken
类中添加标记,则可以设置 lstrip
和 rstrip
行为,但这不适用于非特殊标记。
请参阅 https://github.com/huggingface/transformers/blob/v4.12.5-release/src/transformers/tokenization_utils.py#L517 以了解删除空格的 else 语句。
【讨论】:
以上是关于变形金刚 BartTokenizer::add_tokens() 不像我对后缀的预期那样工作的主要内容,如果未能解决你的问题,请参考以下文章