有多种词表文件格式:vocab.txt、tokenizer.json。
vocab.txt特殊token的介绍 [CLS] 开始 [SEP]结束,可用于分隔2个句子 [UNK]未知字符 [MASK]进行mask处 ##able 子词的后缀 [unused10] 预留位,便于扩充词表。可在不改变此表大小基础上增加tokenBert如何使用预留的[unused*] - 简书
tokenizer.json 特殊token的介绍 <s>开始 </s>结束 <pad> <unk>
BertTokenizer
- from transformers import BertTokenizer,BertTokenizerFast,AutoTokenizer
- string = '2022年06.28,今天 天气真好'
-
- tokenizer = BertTokenizer.from_pretrained('./tmp/vocab.txt')
- res= tokenizer(string)
- print(tokenizer.decode(res['input_ids'])) # [CLS] 2022 年 06. 28 , [UNK] 天 天 [UNK] 真 [UNK] [SEP]
BertTokenizerFast
- tokenizer = BertTokenizerFast.from_pretrained('./tmp')
- res= tokenizer(string)
- print(tokenizer.decode(res['input_ids'])) # <s> 2022年06.28,今天 天气真好</s>
AutoTokenizer
- import sys
- v2_path = './code'
- sys.path = [v2_path, v2_path + '/layoutlmv2_xlm/models'] + sys.path # AutoTokenizer需要一些模型相关脚本
- print(sys.path)
- import layoutlmv2_xlm # 做__init__初始化
-
- tokenizer = AutoTokenizer.from_pretrained('./tmp')
- res= tokenizer(string,
- return_offsets_mapping=True,
- # max_length=5, # 设置截断长度
- # truncation=True
- )
- print(res)
- print(tokenizer.decode(res['input_ids']))
- # {'input_ids': [0, 72392, 470, 20773, 3882, 4, 7461, 6, 70871, 5364, 1322, 2], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'offset_mapping': [(0, 0), (0, 4), (4, 5), (5, 8), (8, 10), (10, 11), (11, 13), (15, 16), (15, 17), (17, 18), (18, 19), (0, 0)]}
- # <s> 2022年06.28,今天 天气真好</s>
BertTokenizerFast比BertTokenizer快:BertTokenizerFast基于 tokenizer 库,RUST 多线程表现好;BertTokenizer基于python
BertTokenizerFast和AutoTokenizer可以处理tokenizer.json,BertTokenizer不支持(不确定是不是特例)
BertTokenizerFast和AutoTokenizer入参为词表所在文件夹,BertTokenizer入参为词表路径
AutoTokenizer基于预训练模型,自适应加载分词器,且会解析model_type等用到模型的一些文件,另外2个基于bert,可以单独使用。
decode将token转化为原来的词汇,mask、unk等处不可还原,与encode项对应,但encode一般不用,因为返回信息较少
- tokenizer = BertTokenizerFast.from_pretrained('./tmp')
- res= tokenizer.encode(string)
- print(res)
- print(tokenizer.decode(res))
- # [0, 72392, 470, 20773, 3882, 4, 7461, 6, 70871, 5364, 1322, 2]
- # <s> 2022年06.28,今天 天气真好</s>
add_tokens增加词表词汇,注意不设置add_tokens为True时,2022 仍然会分为1个词汇
- string = '2022年06.28厷厸厹厺厼厽厾叀叁参叄叅叆叇亝34'
- tokenizer = BertTokenizerFast.from_pretrained('./tmp')
- res= tokenizer(string)
- print(len(tokenizer),'before')
- print(tokenizer.decode(res['input_ids']))
- print(res)
- # tokenizer.add_special_tokens({'additional_special_tokens':['0', '1', '2', '3', '4', '5', '6', '7', '8', '9','厷']})
- tokenizer.add_tokens(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9','厷'])
- res= tokenizer(string)
- print(len(tokenizer),'after')
- print(tokenizer.decode(res['input_ids']))
- print(res)
- # 250007 before
- # <s> 2022年06.28<unk>叁参<unk>34</s>
- # {'input_ids': [0, 72392, 470, 20773, 3882, 3, 246487, 27644, 3, 10289, 2], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
- # 250008 after
- # <s> 2022年06.28厷 <unk>叁参<unk>34</s>
- # {'input_ids': [0, 72392, 470, 20773, 3882, 250007, 6, 3, 246487, 27644, 3, 10289, 2], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
add_special_tokens 增加词表词汇,作为special_token可提高优先级,如下将2022进行了拆分
- string = '2022年06.28厷厸厹厺厼厽厾叀叁参叄叅叆叇亝34'
- tokenizer = BertTokenizerFast.from_pretrained('./tmp')
- res= tokenizer(string)
- print(len(tokenizer),'before')
- print(tokenizer.decode(res['input_ids']))
- print(res)
- tokenizer.add_special_tokens({'additional_special_tokens':['0', '1', '2', '3', '4', '5', '6', '7', '8', '9','厷']})
- res= tokenizer(string)
- print(len(tokenizer),'after')
- print(tokenizer.decode(res['input_ids']))
- print(res)
- # 250007 before
- # <s> 2022年06.28<unk>叁参<unk>34</s>
- # {'input_ids': [0, 72392, 470, 20773, 3882, 3, 246487, 27644, 3, 10289, 2], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
- # 250008 after
- # <s>2022 年06.28厷 <unk>叁参<unk>34</s>
- # {'input_ids': [0, 304, 2389, 304, 304, 6, 470, 2389, 910, 6, 5, 304, 1019, 250007, 6, 3, 246487, 27644, 3, 363, 617, 2], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
- # 以下2种写法效果 相同
- tokenizer.add_special_tokens({'additional_special_tokens':['0', '1', '2', '3', '4', '5', '6', '7', '8', '9','厷']})
- # tokenizer.add_tokens(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9','厷'],special_tokens = True)
作为一个batch、作为上下文、batch和上下文的组合
- tokenizer = BertTokenizer.from_pretrained('./tmp/vocab.txt')
- res= tokenizer(['今天','西瓜美味']) # batch
- # {'input_ids': [[101, 100, 1811, 102], [101, 1947, 100, 1935, 100, 102]], 'token_type_ids': [[0, 0, 0, 0], [0, 0, 0, 0, 0, 0]], 'attention_mask': [[1, 1, 1, 1], [1, 1, 1, 1, 1, 1]]}
- res= tokenizer('今天','西瓜美味') # 上下文
- # {'input_ids': [101, 100, 1811, 102, 1947, 100, 1935, 100, 102], 'token_type_ids': [0, 0, 0, 0, 1, 1, 1, 1, 1], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}
- res= tokenizer(['今天','晴天'],['西瓜美味','雪糕美味'],padding=True) # 上下文+batch
- # {'input_ids': [[101, 100, 1811, 102, 1947, 100, 1935, 100, 102], [101, 100, 1811, 102, 100, 100, 1935, 100, 102]], 'token_type_ids': [[0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1, 1, 1]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1]]}
-
-
- print(res)
可选参数padding、trunction、max_length
is_split_into_words输入已预先进行了分词