BertTokenizerFast与BertTokenizer有什么不同?

transformers 载入BERT时,有两个分词器,BertTokenizerFast和BertTokenizer有何不同?

from transformers import BertTokenizerFast, BertTokenizer

fast_tokenizer = BertTokenizerFast.from_pretrained('./bert_base/')
tokenizer = BertTokenizer.from_pretrained('./bert_base/')
input = "cvpr的论文"

先演示 BertTokenizerFast

#直接用类名,会返回BERT输入的三要素:input_ids、token_type_ids、attention_mask
fast_sample = fast_tokenizer(input, max_length=256, truncation=True, add_special_tokens=True, return_offsets_mapping=True) #默认添加2个起止字符, truncation代表是否截断

输出:{'input_ids': [101, 10718, 11426, 4638, 6389, 3152, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1], 'offset_mapping': [(0, 0), (0, 2), (2, 4), (4, 5), (5, 6), (6, 7), (0, 0)]}}

# tokenize方法只返回分词结果
fast_sample = fast_tokenizer.tokenize(input, max_length=256, truncation=True) 

输出:['cv', '##pr', '的', '论', '文']}

# encode 方法只返回token在vocabulary中的index,即input_ids
fast_sample = fast_tokenizer.encode(input, max_length=256, truncation=True)

输出:[101, 10718, 11426, 4638, 6389, 3152, 102]

# encode_plus与直接调用类名返回结果一致
fast_sample = fast_tokenizer.encode_plus(input, max_length=256, truncation=True, return_offsets_mapping=True, add_special_tokens=True) 

输出:{'input_ids': [101, 10718, 11426, 4638, 6389, 3152, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1], 'offset_mapping': [(0, 0), (0, 2), (2, 4), (4, 5), (5, 6), (6, 7), (0, 0)]}

再看 BertTokenizer

# 与 fast 相比,无法使用 return_offsets_mapping 参数,无法直接返回token在句中的起止位置
sample = tokenizer(input, max_length=256, truncation=True, add_special_tokens=True)

输出: {'input_ids': [101, 10718, 11426, 4638, 6389, 3152, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1]}

# 与 fast 相比,无法使用max_length与truncation参数
sample = tokenizer.tokenize(input)

输出:['cv', '##pr', '的', '论', '文']

#与fast中的encode一致
sample = tokenizer.encode(input, max_length=256, truncation=True) #只返回token在vocabulary中的index,即input_ids

输出: [101, 10718, 11426, 4638, 6389, 3152, 102]

# 与 fast 相比,无法使用 return_offsets_mapping 参数,无法直接返回token在句中的起止位置
sample = tokenizer.encode_plus(input, max_length=256, truncation=True,  add_special_tokens=True) 

输出:{'input_ids': [101, 10718, 11426, 4638, 6389, 3152, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1]}]

此外二者增加新词的操作也一致,例如cvpr中的pr被单独切分为##pr,可以将pr添加为单独的token。

special_tokens_dict = {'additional_special_tokens': ["pr"]}
tokenizer.add_special_tokens(special_tokens_dict)
fast_tokenizer.add_special_tokens(special_tokens_dict)
print(fast_tokenizer.tokenize(input)) #['cv', 'pr', '的', '论', '文']
print(tokenizer.tokenize(input)) #['cv', 'pr', '的', '论', '文']

二者都支持基本的分词+编码,其实实际用起来二者差不多,BertTokenizerFast使用C++实现,速度较快。而且fast自带 offset_mapping参数,可以再NER任务中更好的找到token在sentence中的位置。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勤奋的懒猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值