transformers
框架主要有三个类model
类、configuration
类、tokenizer
类,这三个类,所有相关的类都衍生自这三个类,他们都有 from_pretained()
方法和 save_pretrained()
方法。
文章目录
transformers
框架主要有三个类
model
类、
configuration
类、
tokenizer
类,这三个类,所有相关的类都衍生自这三个类,他们都有
from_pretained()
方法和
save_pretrained()
方法。
Tokenizer
Tokenizer 负责为模型准备输入。大多数tokenizers 都有两种使用风格:全python实现和基于Rust library tokenizers的 fast 实现。fast 实现允许:1)大大提高了速度,尤其是在batched tokenization时,2)在 original string(字符和单词)和 token space 之间映射的额外方法(比如,获取包含给定字符或与给定token相对应的字符范围的index of the token)。当前,基于SentencePiece的 Tokenizer(针对T5,ALBERT,CamemBERT,XLMRoBERTa和XLNet模型)没有可用的“快速”实现。
有两个基类:PreTrainedTokenizer
and PreTrainedTokenizerFast
,实现在模型输入中编码字符串输入的通用方法,从本地文件或目录或库(from HuggingFace’s AWS S3 repository)提供的预训练的Tokenizer实例化/保存python和“快速”Tokenizer。
因此,PreTrainedTokenizer
和PreTrainedTokenizerFast
实现了使用所有Tokenizer的主要方法:
-
tokenizing (spliting strings in sub-word token strings), 把 tokens strings 转换成 to ids, and encoding/decoding (i.e. tokenizing + convert to integers),
-
以一种与底层结构无关的方式添加 new tokens to the vocabulary (BPE, SentencePiece…),
-
管理特殊的tokens,如 mask, beginning-of-sentence, etc(adding them, assigning them to attributes in the tokenizer for easy access)
BatchEncoding
保存 Tokenizer 的编码方法(__call__
, encode_plus
and batch_encode_plus
)的输出,且继承自 Python dictionary。当 tokenizer 是 pure python tokenizer 时,此类的行为就像标准的python字典一样,并包含由这些方法 (input_ids
, attention_mask
…)计算出的各种模型输入。当tokenizer 是 fast tokenizer 时,此类另外提供了几种高级对齐方法,可用于在原始字符串(character and words) 和 token space 进行映射(例如获取包含给定字符或与给定 token 相对应的字符范围的index of the token
@classmethod
PreTrainedTokenizer()
Parameters
model_max_length
– (Optional) int: 输入tokens的最大长度。用from_pretrained
加载时,基本所有模型默认都是512。padding_side
– 填充位置,right
(default) orleft
。additional_special_tokens
(-) – (Optional) list: a list of additional special tokens. 在此处添加所有 special tokens。将与self.additional_special_tokens
和self.additional_special_tokens_ids
关联
使用(以 BertTokenizer
为例)
加载
一般都是直接加载预训练模型,传入参数可以是本地目录也可以是模型的名字
tokenizer = BertTokenizer.from_pretrained('E:/data/transformers/bert-base-uncased')
# 可以传入的参数:
padding_side
xxx_token
可以直接调用tokenizer,(实际上是 __call__()
函数)。效果和 encode_plus()
一样。可以看下面。
词典
tokenizer.get_vocab()
tokenizer.vocab
,文件 <vocab.txt>
的内容。实际上是 tokens_to_ids
tokenizer.ids_to_tokens
,字面意思
tokenizer.get_vocab()
# {'[PAD]': 0, '[unused0]': 1, ...}
tokenizer.vocab
# OrderedDict([('[PAD]', 0), ('[unused0]', 1), ...])
tokenizer.ids_to_tokens
# OrderedDict([(0, '[PAD]'), (1, '[unused0]'), ...])
tokenizer.vocab_size
,文件 <vocab.txt>
的大小
len(tokenizer)
,tokenizer 的词典大小,包括自己添加的词和token。
tokenizer.vocab_size
# 30522
len(tokenizer) #假设添加了bos和eos
# 30524
如果添加了token,那添加的token和id的映射为added_tokens_encoder
和added_tokens_decoder
:
tokenizer.added_tokens_encoder
# {'[EOS]': 30522, '[BOS]': 30523}
tokenizer.added_tokens_decoder
# {30522: '[EOS]', 30523: '[BOS]'}
总之 len(tokenizer) == len(tokenizer.vocab) + len(tokenizer.added_tokens_encoder)
token
special token
7个预置的 speical token分别为:bos_token
, eos_token
, unk_token
, sep_token
, pad_token
, cls_token
, mask_token
,还有一个额外的:additional_special_tokens
tokenizer.SPECIAL_TOKENS_ATTRIBUTES
# ['bos_token', 'eos_token', 'unk_token', 'sep_token', 'pad_token', 'cls_token', 'mask_token', additional_special_tokens']
以上都是 tokenizer 的一个attribute,对应一个 token:
for t in tokenizer.SPECIAL_TOKENS_ATTRIBUTES: print(eval(f'tokenizer.{t}'), end=' ')
# None None [UNK] [SEP] [PAD] [CLS] [MASK] []
注意如果 tokenizer 没有某个 special token,对应的属性值为None
。
可以在加载的时候传入该 token 的值,也可以使用 add_special_tokens()
方法传入一个键为special token值为str
的字典,具体值都可以自定义,还可以传入additional_special_tokens
(当然是值为列表):
# (1)
tokenizer = BertTokenizer.from_pretrained('E:/data/transformers/bert-base-uncased', bos_token='[BOS]', eos_token='[EOS]')
# (2)
tokenizer.add_special_tokens({
'bos_token'