一、AutoTokenizer、BertTokenizer的区别
AutoTokenizer是通用封装,根据载入预训练模型来自适应。
auto_tokenizer = transformers.AutoTokenizer.from_pretrained(config.pretrained_model_path)
参数:
- text (str, List[str], List[List[str]]`):就是输入的待编码的序列(或1个batch的),可以是字符串或字符串列表。
- text_pair (str, List[str], List[List[str]]`):输入待编码的序列对。
- add_special_tokens(bool, optional, defaults to True) :True就是给序列加上特殊符号,如[CLS],[SEP]
- padding (Union[bool, str], optional, defaults to False) :给序列补全到一定长度,True or ‘longest’: 是补全到batch中的最长长度,max_length’:补到给定max-length或没给定时,补到模型能接受的最长长度。
- truncation (Union[bool, str], optional, defaults to False) :截断操作,true or ‘longest_first’:给定max_length时,按照max_length截断,没给定max_lehgth时,到,模型接受的最长长度后截断,适用于所有序列(单或双)。only_first’:这个只针对第一个序列。only_second’:只针对第二个序列。
- max_length (Union[int, None], optional, defaults to None) :控制padding和truncation的长度。
- stride (int, optional, defaults to 0) :和max_length一起使用时,用于标记截断和溢出的重叠数量(不知道怎么用)。
- is_pretokenized (bool, defaults to False):表示这个输入是否已经被token化。
- pad_to_multiple_of :将序列以倍数形式padding
- return_tensors (str, optional, defaults to None):返回数据的类型,可选tf’, ‘pt’ or ‘np’ ,分别表示, 或
- return_token_type_ids (bool, optional, defaults to None):默认返回token_type_id(属于哪个句子)。
- return_attention_mask (bool, optional, defaults to none):默认返回attention_mask(是否参与attention计算)。
- return_overflowing_tokens (bool, optional, defaults to False):默认不返回溢出的token
- return_special_tokens_mask (bool, optional, defaults to False) :默认不返回特殊符号的mask信息.
最终返回一个字典:
{
input_ids: list[int],
token_type_ids: list[int] if return_token_type_ids is True (default)
attention_mask: list[int] if return_attention_mask is True (default)
overflowing_tokens: list[int] if the tokenizer is a slow tokenize, else a List[List[int]] if a ``max_length`` is specified and ``return_overflowing_tokens=True``
special_tokens_mask: list[int] if ``add_special_tokens`` if set to ``True``and return_special_tokens_mask is True
}
使用:
from transformers import AutoTokenizer #还有其他与模型相关的tokenizer,如BertTokenizer
tokenizer=AutoTokenizer.from_pretrained('bert-base-cased') #这里使用的是bert的基础版(12层),区分大小写,实例化一个tokenizer
batch_sentences=["Hello I'm a single sentence","And another sentence","And the very very last one"]
batch=tokenizer(batch_sentences, padding=True, truncation=True, return_tensors="pt")
返回的三个句子都按照batch中最长序列padding到了9个token,由于是单个句子输入,所以token_type_ids是0,padding部分的attention_mask为0,不参与attention计算。
{'input_ids':tensor([[101,8667,146,112,182,170,1423,5650,102],[101,1262,1330,5650,102,0,0,0,0],[101,1262,1103,1304,1304,1314,1141,102,0]]),'token_type_ids':tensor([[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]]),'attention_mask':tensor([[1,1,1,1,1,1,1,1,1],[1,1,1,1,1,0,0,0,0],[1,1,1,1,1,1,1,1,0]])}
二、序列对的预处理
上面是对单句输入的处理,对于序列对的处理其实是一样的道理。
batch=tokenizer(batch_sentences,batch_of_second_sentences,padding=True,truncation=True,return_tensors=“pt”)
第一个参数是第一个序列,第二个参数第二个序列,剩下也是根据需要设置是否padding,是否截断,返回什么类型的数据。
三、案例
import transformers
import config
# --------------------------------------- 使用 BertTokenizer ---------------------------------------
origin_tokenizer = transformers.BertTokenizer.from_pretrained(config.pretrained_model_path)
origin_result01 = origin_tokenizer('对比原始的分词和最新的分词器', padding=True, truncation=True, max_length=13, return_tensors='pt')
print("origin_result01 = ", origin_result01)
print("-" * 100)
origin_result02 = origin_tokenizer('展示不同的分词效果', padding=True, truncation=True, max_length=13, return_tensors='pt')
print("origin_result02 = ", origin_result02)
print("-" * 100)
origin_result03 = origin_tokenizer(*[['对比原始的分词和最新的分词器', '展示不同的分词效果']], padding=True, truncation=True, max_length=13, return_tensors='pt')
print("origin_result03 = ", origin_result03)
print("-" * 200)
origin_result04 = origin_tokenizer.convert_tokens_to_ids(origin_tokenizer.tokenize('对比原始的分词和最新的分词器'))
origin_result05 = origin_tokenizer.convert_tokens_to_ids(origin_tokenizer.tokenize('展示不同的分词效果'))
print("origin_result04 = ", origin_result04)
print("-" * 100)
print("origin_result05 = ", origin_result05)
print('\n', '*' * 400, '\n')
# --------------------------------------- 使用 AutoTokenizer ---------------------------------------
auto_tokenizer = transformers.AutoTokenizer.from_pretrained(config.pretrained_model_path)
auto_result01 = auto_tokenizer('对比原始的分词和最新的分词器', padding=True, truncation=True, max_length=13, return_tensors='pt')
print("auto_result01 = ", auto_result01)
print("-" * 100)
auto_result02 = auto_tokenizer('展示不同的分词效果', padding=True, truncation=True, max_length=13, return_tensors='pt')
print("auto_result02 = ", auto_result02)
print("-" * 100)
auto_result03 = auto_tokenizer(*[['对比原始的分词和最新的分词器', '展示不同的分词效果']], padding=True, truncation=True, max_length=13, return_tensors='pt')
print("auto_result03 = ", auto_result03)
print("-" * 200)
auto_result04 = auto_tokenizer.convert_tokens_to_ids(auto_tokenizer.tokenize('对比原始的分词和最新的分词器'))
auto_result05 = auto_tokenizer.convert_tokens_to_ids(auto_tokenizer.tokenize('展示不同的分词效果'))
print("auto_result04 = ", auto_result04)
print("-" * 100)
print("auto_result05 = ", auto_result05)
print("-" * 400)
打印结果:
C:\Program_Files_AI\Anaconda3531\python.exe C:/Users/Admin/OneDrive/WorkSpace_AI/0-基于知识库的智能问答系统-华控智加/01-意图识别/models/test.py
origin_result01 = {'input_ids': tensor([[ 101, 2190, 3683, 1333, 1993, 4638, 1146, 6404, 1469, 3297, 3173, 4638,
102]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}
----------------------------------------------------------------------------------------------------
origin_result02 = {'input_ids': tensor([[ 101, 2245, 4850, 679, 1398, 4638, 1146, 6404, 3126, 3362, 102]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}
----------------------------------------------------------------------------------------------------
origin_result03 = {'input_ids': tensor([[ 101, 2190, 3683, 1333, 1993, 4638, 1146, 6404, 1469, 3297, 3173, 4638,
102],
[ 101, 2245, 4850, 679, 1398, 4638, 1146, 6404, 3126, 3362, 102, 0,
0]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0]])}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
origin_result04 = [2190, 3683, 1333, 1993, 4638, 1146, 6404, 1469, 3297, 3173, 4638, 1146, 6404, 1690]
----------------------------------------------------------------------------------------------------
origin_result05 = [2245, 4850, 679, 1398, 4638, 1146, 6404, 3126, 3362]
****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
Ignored unknown kwarg option direction
auto_result01 = {'input_ids': tensor([[ 101, 2190, 3683, 1333, 1993, 4638, 1146, 6404, 1469, 3297, 3173, 4638,
102]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}
----------------------------------------------------------------------------------------------------
Ignored unknown kwarg option direction
auto_result02 = {'input_ids': tensor([[ 101, 2245, 4850, 679, 1398, 4638, 1146, 6404, 3126, 3362, 102]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}
----------------------------------------------------------------------------------------------------
Ignored unknown kwarg option direction
auto_result03 = {'input_ids': tensor([[ 101, 2190, 3683, 1333, 1993, 4638, 1146, 6404, 1469, 3297, 3173, 4638,
102],
[ 101, 2245, 4850, 679, 1398, 4638, 1146, 6404, 3126, 3362, 102, 0,
0]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0]])}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
auto_result04 = [2190, 3683, 1333, 1993, 4638, 1146, 6404, 1469, 3297, 3173, 4638, 1146, 6404, 1690]
----------------------------------------------------------------------------------------------------
auto_result05 = [2245, 4850, 679, 1398, 4638, 1146, 6404, 3126, 3362]
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Process finished with exit code 0
参考资料:
pytorch:Transformers入门(二)
transformers的AutoTokenizer和BertTokenizer
【Huggingface Transformers】保姆级使用教程—上
【Huggingface Transformers】保姆级使用教程—上