Tokenizer
Tokenizer
是NLP pipeline
的核心组件之一。Tokenizer
的目标是:将文本转换为模型可以处理的数据。模型只能处理数字,因此Tokenizer
需要将文本输入转换为数字输入。
通常而言有三种类型的Tokenizer
:Word-based Tokenizer
、Character-based Tokenizer
、Subword Tokenizer
。
Word-based Tokenizer
:通常很容易设置和使用,只需几条规则,并且通常会产生不错的结果。
例如,我们可以通过应用Python
的split()
函数,通过空格将文本tokenize
为单词:
但是,Word-based Tokenizer
最终会得到一些非常大的词表vocabulary
。如,Transformer-XL
将得到一个大小为267735
的词表。如此庞大的词表将迫使模型学习一个巨大的embedding matrix
,这导致了空间复杂度和时间复杂度的增加。一般而言,transformers
模型的词表规模很少超过50K
,尤其是当它们仅在一种语言上进行训练时。
Character-based Tokenizer
:将文本拆分为字符,而不是单词。这有两个主要好处:
词表规模要小得多(通常只有几十甚至几百)。unknown token
要少得多(因为任意单词都可以从字符构建)。
但是,Character-based Tokenizer
有两个不足:
首先,tokenize
之后得到字符表示,其意义不大:每个字符本身并没有多少语义。例如,学习字母"t"
的有意义的representation
,要比学习单词"today"
的representation
困难得多。因此,Character-based Tokenizer
往往伴随着性能的损失。
然而这又因语言而异,例如,在中文中每个字符比拉丁语言中的每个字符包含更多的信息。
其次,相比较word-based tokenization
,character-based tokenization
得到更大量的token
,这增大了模型的负担。例如,使用word-based tokenizer
,一个单词只会是单个token
;但是当使用character-based tokenizer
时,一个单词很容易变成10
个或更多的token
。
Subword-based Tokenizer
:它是word-based tokenizer
和character-based tokenizer
的折衷。
subword tokenization
算法依赖于这样一个原则:不应将常用词拆分为更小的子词subword
,而应将低频词分解为有意义的子词。这使得我们能够使用较小的词表进行相对较好的覆盖,并且几乎没有unknown token
。
例如:"football"
可能被认定是一个低频词,可以分解为"foot"
和"ball"
。而"foot"
和"ball"
作为独立的子词可能出现得更高频,同时"football"
的含义由"foot"
和"ball"
复合而来。
subword tokenization
允许模型具有合理的词表规模,同时能够学习有意义的representation
。此外,subword tokenization
通过将单词分解成已知的子词,使模型能够处理以前从未见过的单词。
技术交流
技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。
相关资料、数据、技术交流提升,均可加我们的交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。
方式①、添加微信号:dkl88194,备注:来自CSDN + 技术交流
方式②、微信搜索公众号:Python学习与数据挖掘,后台回复:加群
一、Subword Tokenization 算法
有三种常见的subword tokenization
算法:Byte Pair Encoding: BPE
、WordPiece
、Unigram
。1.1 BPE
Byte Pair Encoding: BPE
来自于论文《Neural Machine Translation of Rare Words with Subword Units》()
。
BPE
是一种简单的数据压缩技术,它迭代式地替换序列中最频繁的字节对。我们不是合并频繁的字节对,而是合并频繁的字符或字符序列。
首先,我们用character vocabulary
初始化symbol vocabulary
,将每个单词表示为一个字符序列,加上一个特殊的单词结束符</w>
,这允许我们在tokenization
后恢复原始的tokenization
。
然后,我们迭代地计算所有symbol pair
,并用新的symbol
'AB'
替换最频繁的symbol pair
('A','B')
。每个merge
操作产生一个新的symbol
,它代表一个character n-gram
。
同时,每个merge
代表一个规则。
最终的symbol vocabulary
大小等于initial vocabulary
的大小,加上merge
操作的次数(这是算法唯一的超参数)。
下面的显示了一个最小化的Python
实现。在实践中,我们通过索引所有pair
并增量更新数据结构来提高效率:
示例:
注意,初始的vocab
已经将单词拆分为字符序列,并用' '
分隔。这个步骤被称作pre-tokenization
。
在机器翻译任务上,有两种应用BPE
的方法:
学习两个独立的编码,一个用于source vocabulary
、另一个用于target vocabulary
。
这种方法的优点是:在文本和词表规模方面更紧凑,并且更能保证在相应语言的训练文本中看到每个subword
单元。
学习两个vocabulary
的并集上的编码,称之为joint BPE
。
这种方法的优点是:提高了source tokenization
和target tokenization
之间的一致性。如果我们独立地应用BPE
,相同的name
在两种语言中可能被不同地tokenization
,这使得神经模型更难学习subword
单元之间的映射。
Byte-level BPE
:包含所有基础字符base character
的base vocabulary
可能非常大,例如,将所有unicode
字符(一共65536
个,即2
个字节的表示范围)作为基础字符。
为了获得更小的base vocabulary
,GPT-2
使用byte
作为base vocabulary
。这是一个聪明的技巧,它强制base vocabulary
的大小为256
(一个字节的表示范围),同时确保每个基本字符都包含在vocabulary
中。GPT-2
具有50257
的词表大小,其对应于256
个byte-base token
、一个特殊的文本结束token
、以及通过50000
次merge
所学到的symbol
。
相比之下,使用传统BPE
的GPT
的词表规模为40478
,其中包含478
个基本字符,并在40000
次merge
后停止训练。
来自Hugging Face
上的例子:
假设在pre-tokenization
之后,我们得到了如下的单词及其频次的集合:
将所有单词拆分到字符,则我们得到:
此时base vocabulary
为:
然后,BPE
计算每个可能的symbol pair
,然后挑选出现频次最高的symbol pair
。
此时,频次最高的symbol pair
是:将"u"
后面跟着"g"
的symbol pair
合并为"ug"
。
此时单词及其频次的集合为:
此时base vocabulary
为:
BPE
然后确定下一个最常见的symbol pair
,即"u"
后面跟着"n"
。因此,BPE
将"u", "n"
合并为"un"
。
下一个最常见的symbol pair
,即"h"
后面跟着"ug"
。因此,BPE
将"h", "ug"
合并为"hug"
。
此时单词及其频次的集合为:
此时base vocabulary
为:
假设BPE
的训练在这个时刻结束,那么所学习的所有merge rule
将被应用于新的单词。例如:
单词"bug"
被tokenized
为["b", "ug"]
。单词"mug"
被tokenized
为["<unk>", "ug"]
,因为symbol
"m"
不在base vocabulary
中。
1.2 WordPiece
与BPE
一样,WordPiece
(《Japanese and korean voice search》()
)从一个小的词汇表开始,并学习merge
规则。二者之间的区别在于merge
的方式不同:WordPiece
不是选择最高频的pair
,而是通过如下公式计算每个pair
的得分:
(1)score(t1,t2)=freq(t1,2)freq(t1)×freq(t2)
其中:
t1 和 t2 为两个token
,t1,2 为它们merge
之后得到的新的token
。freq(t) 为token
t 在语料库中出现的频次。
选择score
最高的一对token
等价于:
(2)maxt1,t2score(t1,t2)=maxt1,t2freq(t1,2)/Nfreq(t1)/N×freq(t2)/N=maxt1,t2logp(t1,2)−[logp(t1)+logp(t2)]
其中:N 为语料库中的token
总数。
因此WordPiece
的物理意义为:通过将 t1,t2 合并为 t1,2 之后,语料库的对数似然的增量最大化。
来自Hugging Face
上的例子:
假设在pre-tokenization
之后,我们得到了如下的单词及其频次的集合:
将所有单词拆分到字符,则我们得到:
注意:WordPiece
通过添加前缀(在BERT
中是##
)来识别子词,这可以识别一个子词是否是单词的开始。这里通过将前缀添加到单词内的每个字符来拆分的,单词的首字符不添加前缀。
此时的base vocabulary
为:
然后,WordPiece
计算每个可能的symbol pair
,然后挑选score
最高的symbol pair
。
学到的第一个merge
是("##g", "##s") -> ("##gs")
。注意,当我们合并时,我们删除了两个token
之间的##
,所以我们添加"##gs"
到词表中。
此时单词及其频次的集合为:
此时base vocabulary
为:
我们继续这样处理,直到达到我们所需的词汇量。
tokenization
算法:WordPiece
和BPE
中的tokenization
的不同在于:WordPiece
仅保存最终词表,而不保存学到的merge rule
。
在应用时,从待tokenized
的单词开始,WordPiece
找到词表中能够匹配到的最长的子词,然后对单词进行拆分。例如,如果我们使用上面例子中学到的词表来tokenize
单词"hugs"
:
首先,单词从头开始能匹配到的词表中的最长子词是"hug"
,所以我们在那里拆分并得到["hug", "##s"]
。然后,我们继续匹配剩下的"##s"
。刚好能够匹配到词表中的子词"##s"
。
最终,"hugs"
的tokenization
是["hug", "##s"]
。
如果使用BPE
, 我们将按顺序应用学习到的merge rule
,并将其tokenize
为["hu", "##gs"]
,所以编码不同。
当tokenization
无法在词表中找到子词时,整个单词被tokenize
为unknown
。 例如"bum"
,由于"##m"
不在词表中,由此产生的tokenization
将只是["[UNK]"]
, 不是["b", "##u", "[UNK]"]
。
这是与BPE
的另一个区别:BPE
只会将不在词汇表中的单个字符tokenize
为unknown
。 例如"bum"
,由于"##m"
不在词表中,由此产生的tokenization
是["b", "##u", "[UNK]"]
。
1.3 SentencePiece
SentencePiece
(《Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates》()
)中经常使用Unigram
算法。
Unigram
算法假设每个子词都是独立出现的,因此一个子词序列 x=(x1,⋯,xM) 出现的概率是每个子词出现概率的乘积,即:
(3)P(x)=∏i=1Mp(xi)∀ixi∈V,∑x∈Vp(x)=1.0
其中:x 为子词,p(x) 为子词出现的概率,V 为词表。
对于给定的句子 X ,其最佳tokenization
为:
其中:S(X) 为句子 X 的所有候选tokenization
。
如果我们已知词表 V 以及每个子词出现的概率 p(x) ,则 x∗ 可以通过维特比算法求解得到。
现在的问题是,给定一个训练语料库 D ,如何获得词表 V 以及每个子词出现的概率 p(x) 。Unigram
利用EM
算法来求解如下的边际似然marginal likelihood
L:
(5)L=∑s=1|D|logP(X(s))=∑s=1|D|log(∑x∈S(X(s))P(x))
其中:X(s) 表示语料库 D 中的第 s 个句子。
这里Unigram
将 p(x) 视作隐变量。
为求解 L ,Unigram
采用了迭代式算法:
首先,启发式地从训练语料库中获取一个足够大的seed vocabulary
。
一种选择方法是:使用所有字符、以及语料库中最高频的substring
。
重复以下步骤,直到词表规模 |V| 达到预期的值:
固定词表,通过EM
算法优化 p(x) 。对每个子词 xi 计算 lossi ,其中 lossi 表示当 xi 从当前词表移除时,似然 L 降低的数值。根据 lossi 进行降序排列,保留top
η% 的子词(例如,80%
)。
注意,我们总是在词表中保留单个character
从而防止out-of-vocabulary
。
最终的词表 V 包含了语料库中的所有单个字符、也包括了一些character-based tokenization
结果、甚至包括一些word-based tokenization
结果。因此Unigram
算法是这三者的混合体。
来自Hugging Face
上的例子:
假设在pre-tokenization
之后,我们得到了如下的单词及其频次的集合:
seed vocabulary
采用初始词表的所有严格子字符串(即,不包含它自身):
对于每个单词,考虑tokenization
概率最高的。例如,对于"pug"
:
tokenization
为["p", "u", "g"]
的概率为:
(6)P([“p”,“u”,“g”])=P(“p” )×P(“u” )×P(“g” )=5210×36210×0=0.000389
这里210
为词表中所有token
的频次之和。
tokenization
为["pu", "g"]
的概率为:
(7)P([“pu”,“g”])=P(“pu” )×P(“g” )=5210×0=0.0022676
Unigram
选择对单词进行tokenization
最高的那个:
所以,"pug"
将被标记为["p", "ug"]
或者["pu", "g"]
,取决于首先遇到这些 中的哪一个。注意,在更大的语料库中这样的相等的情况很少见。
通常在语料库中找到所有可能的tokenization
并计算它们的概率,一般来说会有点困难。因此需要利用维特比算法。
这里我们得到每个单词的最佳tokenization
:
现在我们需要计算从词表中删除每个token
如何影响损失。然后我们根据这个损失对token
进行排序,选择top
η% 的token
。
二、算法原理
对于BPE, WordPiece, Unigram
这三个算法,我们采用相同的语料库如下:2.1 BPE
训练算法:
为了对新文本进行tokenization
,我们对其进行pre-tokenization
、拆分为单个字符,然后应用学到的所有merge
规则。
2.2 WordPiece
训练算法:
为了对新文本进行tokenization
,我们对其进行pre-tokenization
,然后对每个单词寻找从头开始匹配到的最大子词并进行拆分。然后不断重复这种拆分。
2.3 Unigram
训练算法:
为了对新文本进行tokenization
,我们对其进行pre-tokenization
,然后对每个单词进行维特比解码。
三、Hugging Face Tokenizer 库
安装:
使用不同subword tokenization
算法的Transformer-based
模型:
GPT, GPT-2, RoBERTa, BART, DeBERTa
等模型使用了BPE
,其中GPT-2
使用了byte-level BPE
。
BERT, DistilBERT, MobileBERT, Funnel Transformers, MPNET
等模型使用了WordPiece
。
注意,Google
从未开源WordPiece
训练算法的实现,因此Hugging Face
中的实现是Hugging Face
基于已发表文献的最佳猜测,它可能不是100%
正确的。
AlBERT, T5, mBART, Big Bird, XLNet
等模型使用了Unigram
。
tokenizer
应用于文本的流程如下,其中包括:
Normalization
:标准化步骤,包括一些常规清理,例如删除不必要的空格、小写、以及删除重音符号。
Transformers tokenizer
有一个属性叫做backend_tokenizer
它提供了对Tokenizers
库中底层tokenizer
的访问。backend_tokenizer
的normalizer
属性可以获取执行标准化的normalizer
。而normalizer
的normalize_str()
方法执行标准化。
Pre-tokenization
:tokenizer
不能单独在原始文本上进行训练。相反,我们首先需要将文本拆分为小的单元,例如单词。这就是pre-tokenization
步骤。基于单词的tokenizer
可以简单地基于空白和标点符号将原始文本拆分为单词。这些词将是tokenizer
在训练期间可以学习的子词边界。
backend_tokenizer
的pre_tokenizer
属性可以获取执行pre-tokenization
的pre_tokenizer
。而pre_tokenizer
的pre_tokenize_str()
方法执行pre-tokenization
。
请注意tokenizer
如何跟踪单词的偏移量。
由于我们使用的是BERT tokenizer
,pre_tokenizer
涉及对空格和标点符号进行拆分。而其他tokenizer
可以有不同的规则。例如,GPT-2 tokenizer
和T5 tokenizer
:
GPT-2 tokenizer
也会在空格和标点符号上拆分,但它会保留空格并将它们替换为Ġ
符号。注意,与BERT tokenizer
不同,GPT-2 tokenizer
不会忽略双空格。
与GPT-2 tokenizer
一样,T-5 tokenizer
保留空格并用特定token
(即"_"
)替换它们。但是,T-5 tokenizer
只在空格上拆分,而不拆分标点符号。注意,T-5 tokenizer
默认在句子的开头添加了一个空格(即,_hello
),并忽略了are
和u
之间的双空格。
Model
:执行tokenization
从而生成token
序列。
Postprocessor
:针对具体的任务插入special token
,以及生成attention mask
和token-type ID
。
Tokenizers 库
旨在为每个步骤提供多个选项,从而方便用于自由地组合。
3.1 Normalizers
class tokenizers.normalizers.Normalizer
:所有normalizer
的基类。
方法:
normalize(normalized)
:执行标准化(原地操作)。如果你仅仅想知道在原始字符串上执行标准化的结果,建议使用normalize_str()
。
参数:normalized
,被执行标准化的字符串。
normalize_str(sequence) -> str
:执行标准化,返回标准化后的字符串。
参数:sequence
,被执行标准化的字符串。
class tokenizers.normalizers.BertNormalizer
:Bert normalizer
,包括清理文本(移除控制字符并替代以空格)、移除重音、处理中文字符(中文字符周围添加空格)、字母转小写。
其它的一些normalizer
:
class tokenizers.normalizers.Sequence(normalizers)
:将一组normalizer
拼成一个序列,以给定的顺序依次执行各个normalizer
。
示例:
3.2 Pre-tokenizers
class tokenizers.pre_tokenizers.PreTokenizer()
:所有pre-tokenizer
的基类。
方法:
pre_tokenize(pretok)
:执行pre-tokenize
(原地操作)。如果你仅仅想知道在原始字符串上执行pre-tokenize
的结果,建议使用pre_tokenize_str()
。
参数:pretok
,被执行标准化的字符串。
pre_tokenize_str(sequence) -> List[Tuple[str, Offsets]]
:执行pre-tokenize
,返回结果字符串序列以及每个结果的偏移量。
参数:sequence
,被执行pre-tokenize
的字符串。
class tokenizers.pre_tokenizers.BertPreTokenizer()
:BertPreTokenizer
,在每个空格和标点符号上拆分。每个标点符号被视为一个独立的单元。
class tokenizers.pre_tokenizers.ByteLevel(add_prefix_space = True, use_regex = True)
:ByteLevel PreTokenizer
,将给定字符串的所有字节替换为相应的表示并拆分为单词。
参数:
add_prefix_space
:是否在第一个单词前面添加空格,如果第一个单词前面目前还没有空格。use_regex
:如果为False
则阻止该pre_tokenizer
使用GPT2
的正则表达式来在空格上拆分。
方法:
alphabet() -> List[str]
:返回所有字母组成的字符的列表。由于ByteLevel PreTokenizer
作用在byte level
,因此字母表里有256
个不同的字符。
class tokenizers.pre_tokenizers.CharDelimiterSplit(delimiter)
:CharDelimiterSplit
,简单地在给定的char
上拆分,类似于.split(delimiter)
。
参数:delimiter
:一个字符,指定拆分的分隔符。
class tokenizers.pre_tokenizers.Digits(individual_digits = False)
:Digits
,利用数字来拆分。
参数:individual_digits
,一个布尔值,如果为True
则每个数字都单独处理(如"123"
被拆分为"1", "2", "3"
);否则数字被整体处理(如"123"
被视为一个整体)。
class tokenizers.pre_tokenizers.Metaspace(replacement = '_', add_prefix_space = True )
:Metaspace pre-tokenizer
,用给定的replacement
字符来代替任意空白符,并在空白符上执行拆分。
参数:
replacement
:一个字符串,指定替换字符,必须只有一个字符。默认为SentencePiece
中的配置。add_prefix_space
:一个布尔值,是否在首个单词之前没有空格的时候添加一个空格。
class tokenizers.pre_tokenizers.Punctuation( behavior = 'isolated' )
:Punctuation pre-tokenizer
,在标点符号上进行拆分。
参数:behavior
:指定拆分之后如何处理标点符号。可以为"removed", "isolated", "merged_with_previous", "merged_with_next", "contiguous"
。
class tokenizers.pre_tokenizers.Split( pattern, behavior, invert = False )
:Split PreTokenizer
,基于指定的模式和行为来拆分。
参数:
pattern
:一个字符串或正则表达式,指定拆分模式。behavior
:一个字符串,指定拆分之后如何处理这个模式。可以为"removed", "isolated", "merged_with_previous", "merged_with_next", "contiguous"
。invert
:一个布尔值,指定是否翻转pattern
。
class class tokenizers.pre_tokenizers.UnicodeScripts()
:这个pre-tokenizer
在不同的language family
上进行拆分。遵从SentencePiece Unigram
的实现。
class tokenizers.pre_tokenizers.Whitespace()
:这个pre-tokenizer
在使用如下的正则表达式进行拆分:\w+|[^\w\s]+
。
class tokenizers.pre_tokenizers.WhitespaceSplit()
:这个pre-tokenizer
在空格上拆分,类似于.split()
。
示例:
3.3 Models
class tokenizers.models.Model()
:所有Model
的基类。
每个model
代表一个实际的tokenization
算法。
方法:
get_trainer() -> Trainer
:返回关联的Trainer
,该Trainer
用于训练该model
。
id_to_token(id) -> str
:返回id
关联的token
字符串。
参数:id
:待转换的ID
。
token_to_id(token) -> int
:返回token
字符串关联的整数id
。
参数:token
:待转换的token
字符串。
tokenize( sequence ) -> A List of Token
:把给定的字符串执行tokenize
,返回一个token
序列。
参数:sequence
:一个字符串。
save( folder, prefix) -> List[str]
:在指定的目录中保存model
。其中被创建的文件使用指定的前缀。如果目录中已有同名的文件,则直接覆盖同名文件。
参数:
folder
:模型保存的目录。prefix
:一个字符串,指定被保存的各种文件的文件名前缀。
返回值:一个字符串列表,表示被保存的各种文件的文件名。
class tokenizers.models.BPE
:BPE
模型。
参数:
vocab
:一个字典Dict[str, int]
,指定字符串key
及其id
,表示词表。merges
:token pair
的列表List[Tuple[str, str]]
,表示merge
规则。cache_capacity
:一个整数,指定BPE cache
包含的单词数量。BPE cache
能够通过保存多个单词的merge
操作的结果来加速该过程。dropout
:一个浮点数,指定BPE dropout
比例。取值在0.0 ~ 1.0
之间。unk_token
:一个字符串,指定unknown token
。continuing_subword_prefix
:一个字符串,指定当该子词不是单词的首个子词时,子词的前缀,。end_of_word_suffix
:一个字符串,指定当该子词是单词的最后一个子词时,子词的后缀。fuse_unk
:一个布尔值,指定是否将连续的多个unknown token
合并为单个unknown token
。
方法:
from_file( vocab, merges, **kwargs) -> BPE
:从文件中初始化一个BPE
。
参数:
vocab
:vocab.json
文件的路径。merges
:merges.txt
文件的路径。
该方法等价于:
read_file( vocab, merges) -> A Tuple
:从文件中加载词表和merge
规则。
参数:参考from_file()
。
class tokenizers.models.Unigram( vocab )
:Unigram
模型。
参数:
vocab
:由字符串和浮点数组成的元组的列表List[Tuple[str, float]]
,指定token
及其score
,如[("am", -0.2442), ...]
class tokenizers.models.WordLevel( vocab, unk_token )
:WordLevel
模型。
参数:参考BPE
模型。
方法:
from_file( vocab, un_token) -> WordLevel
:从文件中初始化一个WordLevel
。
参数:
vocab
:vocab.json
文件的路径。un_token
:一个字符串,指定unknown token
。
read_file(vocab) -> Dict[str, int]
:从文件中读取词表。
参数:参考from_file
。
class tokenizers.models.WordPiece( vocab, unk_token, max_input_chars_per_word)
:WordPiece
模型。
参数:
vocab
:一个字典Dict[str, int]
,指定字符串key
及其id
,表示词表。unk_token
:一个字符串,指定unknown token
。max_input_chars_per_word
:一个整数,指定一个单词中允许的最大字符数。
方法:
from_file(vocab, **kwargs) -> WordPiece
:从文件中初始化一个WordPiece
。
参数:vocab
:vocab.json
文件的路径。
read_file(vocab) -> Dict[Str, int]
:从文件中读取词表。
参数:参考from_file
。
3.4 Trainers
class tokenizers.trainers.BpeTrainer
:BPE Trainer
,用于训练BPE
模型。
参数:
vocab_size
:一个整数,表示final vocabulary
大小,包括所有的token
和字母表alphabet
。min_frequency
:一个整数,表示一个pair
的频次至少为多少时才考虑被merge
。show_progress
:一个布尔值,指定在训练期间是否展示进度条。special_tokens
:一个字符串列表,指定special token
。limit_alphabet
:一个整数,指定字母表中最多保持多少个不同的字符。initial_alphabet
:一个字符串列表,指定初始的字母表。如果字符串包含多个字符,那么仅考虑首个字符。这个字母表可以包含训练数据集中不存在的字符。continuing_subword_prefix
:一个字符串,如果子词不是单词的首个子词,那么添加这个前缀。end_of_word_suffix
:一个字符串,如果子词是单词的末尾子词,那么添加这个后缀。
class tokenizers.trainers.UnigramTrainer
:Unigram Trainer
,用于训练Unigram
模型。
参数:
vocab_size, show_progress, special_tokens
:参考BpeTrainer
。shrinking_factor
:一个浮点数,指定在训练的每个step
需要对词表规模缩放多少比例(即,保留top
的多少)。unk_token
:一个字符串,指定unknown token
。max_piece_length
:一个整数,指定token
的最大长度(字符个数)。n_sub_iterations
:一个整数,指定裁剪词表之前执行EM
算法的迭代次数。
class tokenizers.trainers.WordLevelTrainer
:WordLevel Trainer
,用于训练WordLevel
模型。
参数:参考BpeTrainer
。
class tokenizers.trainers.WordPieceTrainer
:WordPiece Trainer
,用于训练WordPiece
模型。
参数:参考BpeTrainer
。
3.5 Post-processors
class tokenizers.processors.BertProcessing( sep, cls)
:BERT
的Post-processor
。
参数:
sep
:一个(str, int)
的元组,给出[SEP] token
及其id
。cls
:一个(str, int)
的元组,给出[CLS] token
及其id
。
方法:
num_special_tokens_to_add(is_pair)
:返回需要添加到single/pair
句子的special token
的数量。
参数:is_pair
:一个布尔值,指定预期的输入是单个句子还是句子对。
process(encoding, pair=None, add_special_tokens=True)
:对指定的encoding
执行后处理。
参数:
encoding
:单个句子的encoding
,类型为tokenizer.Encoding
。pair
:一对句子的encoding
,类型为tokenizer.Encoding
。add_special_tokens
:一个布尔值,指定是否添加special token
。
BertProcessing
会把[SEP] token
和[CLS] token
添加到被tokenized
的token
序列中。
class tokenizers.processors.ByteLevel( trim_offsets = True)
:ByteLevel BPE
的Post-processor
。
参数:
trim_offsets
:一个布尔值,是否从生成的offsets
中移除空格。
方法:参考BertProcessing
。
这个Post-processor
会小心地裁剪offsets
。默认情况下,ByteLevel BPE
可能会在生成的token
中包含空格。如果你不希望offsets
中包含这些空格,则可以使用这个Post-processor
。
class tokenizers.processors.RobertaProcessing( sep, cls, trim_offsets=True, add_prefix_space=True)
:Roberta
的Post-processor
。
参数:
sep,cls
:参考BertProcessing
。trim_offsets
:参考ByteLevel
。add_prefix_space
:一个布尔值,指定是否在pre-tokenization
阶段启用了add_prefix_space
。这个参数是为了配合trim_offsets
使用。
方法:参考BertProcessing
。
class tokenizers.processors.TemplateProcessing(single, pair, special_tokens)
:这是一个Post-processor
的模板,以便将special token
添加到相关的每个输入序列。、
参数:
single
:一个模板字符串或模板字符串列表,用于单个输入序列。如果是字符串,那么使用空格来拆分token
。
pair
:一个模板字符串或模板字符串列表,用于一对输入序列。如果是字符串,那么使用空格来拆分token
。
模板的标准格式为<identifier>(:<type_id>)
。
模板中可以基于type_id
来占位,如"[CLS] $0, $1, $2 [SEP]"
,此时identifier
默认为A
。模板中也可以基于sequence identifier
来占位,如"[CLS] $A, $B [SEP]"
,此时type_id
默认为0
。模板中也可以同时使用type_id
和sequence
来占位,如"[CLS] $A:0 [SEP]"
。
special_tokens
:一个元组序列,指定每个模板字符串使用的special token
及其id
。
或者是一个字典,键包括:"id"
,指定special token id
;"ids"
,指定关联的ID
;"tokens"
:指定关联的token
。
方法:参考BertProcessing
。
以BERT tokenizer
为例,它需要两个special token
:[CLS]
(用于第一个句子的开头)、[SEP]
(用于每个句子的结尾)。最终结果看起来如下所示:
其中这一对输入序列的type-id
如下:
此时可以应用TemplateProcessing
为:
注意:[SEP]:1
表示最后一个[SEP]
的type_id = 1
。
3.6 Decoders
class tokenizers.decoders.BPEDecoder(suffix = '</w>')
:BPE
解码器。
参数:suffix
:一个字符串,用来表示单词结尾的后缀。在解码过程中,这个后缀将被替换为空格。
方法:
decode(tokens)
:解码给定的token
列表,返回解码后的字符串。
class tokenizers.decoders.ByteLevel()
:ByteLevel
解码器,用于ByteLevel PreTokenizer
配合使用。
方法:参考BPEDecoder
。
class tokenizers.decoders.CTC( pad_token = '<pad>', word_delimiter_token = '|', cleanup = True)
:CTC
解码器。
参数:
pad_token
:一个字符串,由CTC
使用来分隔一个新的token
。word_delimiter_token
:一个字符串,表示单词的分隔符token
,它将被空格符替代。cleanup
:一个字符串,指定是否清理一些人工增加的token
,如标点符号之前的空格。
方法:参考BPEDecoder
。
class tokenizers.decoders.Metaspace(replacement='▁', add_prefix_space =True)
:Metaspace
解码器。
参数:
replacement
:一个字符串,指定编码时的替换字符(必须为单个字符)。默认为'▁'
(U+2581
),被SentencePiece
所使用。add_prefix_space
:一个布尔值,指定编码时是否启用了add_prefix_space
。
方法:参考BPEDecoder
。
class tokenizers.decoders.WordPiece(prefix='##', cleanup=True)
:WordPiece
编码器。
参数:
prefix
:一个字符串,指定编码时的prefix
。cleanup
:一个布尔值,指定是否清理一些人工增加的token
,如标点符号之前的空格。
方法:参考BPEDecoder
。
3.7 Tokenizer
class tokenizers.Tokenizer(model)
:Tokenizer
,它处理原始文本输入并输出一个Encoding
对象。
参数:
model
:一个Model
对象,代表Tokenizer
使用到的核心算法,如tokenizers.models.BPE
等等。
属性:
decoder
:一个Decoder
对象,代表Tokenizer
使用到的解码器,如tokenizers.decoders.BPEDecoder
。
model
:一个Model
对象,代表Tokenizer
使用到的核心算法。
normalizer
:一个Normalizer
对象,用于对输入进行标准化。
padding
:一个字典,如果开启padding
,则它给出当前的padding
参数。
该属性无法被set
,可以用enable_padding()
来开启。
post_processor
:一个PostProcessor
对象,用于后处理。
pre_tokenizer
:一个PreTokenizer
对象,用于前处理。
truncation
:一个字典,如果开启truncation
,则它给出当前的truncation
参数。
该属性无法被set
,可以用enable_truncation()
来开启。
方法:
add_special_tokens(tokens) -> int
:添加指定的special token
到Tokenizer
。
参数:tokens
:一个字符串列表或AddedToken
列表,指定被添加的special token
。这些special token
被添加到词表。
返回值:词表中被新增的token
数量。如果special token
已经位于词表中,那么它就不是新增的了。
这些special token
不会被model
处理(即,不会被拆分为多个token
),并且在解码期间从输出中被删除。
add_tokens(tokens) -> int
:添加指定的token
到Tokenizer
。
参数和返回值:参考add_special_tokens
。
这些token
不会被model
处理(即,不会被拆分为多个token
)。
decode( ids, skip_special_tokens = True) -> str
:解码得到字符串。
参数:
ids
:一个整数序列,表示待解码的token id
。skip_special_tokens
:一个布尔值,指定是否从解码结果中移除special token
。
decode_batch( sequences, skip_special_tokens = True) -> List[str]
:解码一个batch
的字符串。
参数:
sequences
:一个batch
的整数序列,表示待解码的token id
。skip_special_tokens
:参考decode
。
enable_padding(direction = 'right', pad_id = 0, pad_type_id = 0, pad_token = '[PAD]', length = None, pad_to_multiple_of = None)
:启用padding
功能。
参数:
direction
:一个字符串,指定填充方式,可以是左填充'left'
或右填充'right'
。pad_id
:一个整数,指定pad token
的id
。pad_token
:一个字符串,指定pad token
字符串。length
:一个整数,指定填充后的字符串长度。如果为None
,则选择batch
中的最长序列的长度。pad_to_multiple_of
:一个整数,假设为 n ,那么填充后的长度与 2n 对齐。例如,length=250
,但是pad_to_multiple_of=8
,那么将填充到长度为256
。
enable_truncation( max_length, stride=0, strategy = 'longest_first', direction='right')
:启用truncation
功能。
参数:
max_length
:一个整数,指定截断后的字符串长度。
stride
:一个整数,指定在溢出序列中,需要包含前一个序列的长度。
溢出序列指的是被截断后的尾部序列。如abcdefg
,截断长度为4
,stride=2
,那么截断方式为:abcd, cdef, efg
。
strategy
:一个字符串,指定截断的策略。可以为:"longest_first"
、"only_first "
、"only_second"
。
其中"only_first "
、"only_second"
用于句子对,仅对第一个句子或第二个句子进行截断。
direction
:一个字符串,指定截断方向。可以为:"left"
、"right"
。
encode(sequence, pair = None, is_pretokenized = False, add_special_tokens = True) -> Encoding
:编码指定的句子或句子对,返回编码结果。
参数:
sequence
:一个InputSequence
对象,指定输入的句子。如果is_pretokenized =True
,那么sequence
是PreTokenizedInputSequence
对象;否则是TextInputSequence
对象。pair
:一个InputSequence
对象,指定输入的句子pair
。如果is_pretokenized =True
,那么sequence
是PreTokenizedInputSequence
对象;否则是TextInputSequence
对象。is_pretokenized
:一个布尔值,指定输入是否已经被pre-tokenized
。add_special_tokens
:一个布尔值,指定是否添加special token
。
encode_batch(input, is_pretokenized = False, add_special_tokens = True) -> List[Encoding]
:编码一个batch
的句子或句子对,返回编码结果。
参数:
input
:TextInputSequence
或者PreTokenizedInputSequence
的一个列表。参考encode()
。is_pretokenized/add_special_tokens
:参考encode()
。
from_buffer( buffer ) -> Tokenizer
:从buffer
中创建并返回一个Tokenizer
。
参数:buffer
:一个bytes
,包含了已经序列化好的Tokenizer
。
from_file( path) -> Tokenizer
:从文件中创建并返回一个Tokenizer
。
参数:path
:一个本地JSON
文件,包含了已经序列化好的Tokenizer
。
from_pretrained(identifier, revision = 'main', auth_token = None) -> Tokenizer
:从Hugging Face Hub
上的已有文件来创建并返回一个Tokenizer
。
参数:
identifier
:一个字符串,用于指定Hugging Face Hub
上的一个模型,它包含一个tokenizer.json
文件。revision
:指定选择Hugging Face Hub
上的模型的哪个git branch
或者git commit id
。auth_token
:一个字符串,指定auth token
从而用于访问Hugging Face Hub
上的私有repository
。
from_str(json) -> Tokenizer
:从字符串中创建并返回一个Tokenizer
。
参数:json
:一个有效的JSON
字符串,表示已经序列化好的Tokenizer
。
get_vocab( with_added_tokens = True) -> Dict[str, int]
:返回词表(token
及其id
)。
参数:
with_added_tokens
:一个布尔值,指定是否包含added token
。
get_vocab_size( with_added_tokens = True) ->int
:返回词表的大小。
参数:参考get_vocab()
。
id_to_token(id) -> str
:将id
转换回字符串。如果id
不在词表中,则返回None
。
参数:id
:一个整数,表示要转换的id
。
no_padding()
:关闭padding
。
no_truncation()
:关闭truncation
。
num_special_tokens_to_add( is_pair)
:返回预期要添加到单个句子或者句子对中的special token
的数量。
参数:is_pair
:一个布尔值,表示要计算单个句子的还是句子对的special token
数量。
post_process(encoding, pair = None, add_special_tokens = True ) -> Encoding
:final
后处理。
参数:
encoding
:一个Encoding
对象,表示对单个句子的编码结果。pair
:一个Encoding
对象,表示对句子对的编码结果。add_special_tokens
:一个布尔值,指定是否添加special token
。
后处理步骤包括:
根据truncation
参数执行截断(根据enable_truncation()
来开启)。应用PostProcessor
。根据padding
参数执行填充(根据enable_padding()
来开启)。
save(path, pretty=True)
:将Tokenizer
保存到指定路径的文件。
参数:
path
:一个字符串,指定保存文件的路径。pretty
:一个布尔值,指定保存的JSON
文件是否需要被pretty formated
。
to_str(pretty = False) -> str
:返回一个字符串代表被序列化的Tokenizer
。
token_to_id(token) -> int
:将给定的token
转换为对应的id
。如果token
不在词表中,则返回None
。
参数:token
:一个字符串,指定待转换的token
。
train(files, trainer = None)
:利用给定的文件来训练Tokenizer
。
参数:
files
:一个字符串列表,指定用于训练Tokenizer
的文件路径。trainer
:一个Trainer
对象,指定用于训练Model
的trainer
。
该方法从文件中一行一行地读取,保留所有的空格和换行符。
train_from_iterator(iterator, trainer=None, length=None)
:利用给定的迭代器来训练Tokenizer
。
参数:
iterator
:一个Iterator
对象,对它迭代的结果返回字符串或者字符串列表。trainer
:一个Trainer
对象,指定用于训练Model
的trainer
。length
:一个整数,指定iterator
中的序列数量,这用于提供有意义的进度跟踪。
tokenizers.InputSequence
:代表所有类型的输入序列,作为Tokenizer
的输入。
如果is_pretokenized=False
,则为TextInputSequence
;如果is_pretokenized=True
,则为PreTokenizedInputSequence
。
tokenizers.TextInputSequence
:一个字符串,代表一个输入序列。
TextInputSequence
就是str
的别名。
tokenizers.PreTokenizedInputSequence
:一个pre-tokenized
的输入序列,可以为一个字符串列表、或者一个字符串元组。
PreTokenizedInputSequence
是Union[List[str], Tuple[str]]
的别名。
tokenizers.EncodeInput
:代表所有类型的、用于batch
编码的输入序列,作为Tokenizer
的batch
编码的输入。
如果is_pretokenized=False
,则为TextEncodeInput
;如果is_pretokenized=True
,则为PreTokenizedEncodeInput
。
tokenizers.TextEncodeInput
:用于编码的文本输入,可以为TextInputSequence
的一个元组、或者长度为2
的列表。
TextEncodeInput
是Union[str, Tuple[str, str], List[str]]
的别名。
tokenizers.PreTokenizedEncodeInput
:pre-tokenized
的、用于编码的文本输入。可以为PreTokenizedInputSequence
的一个序列、或者一对序列(每个元素为PreTokenizedInputSequence
的元组或者长度为2
的列表)。
PreTokenizedEncodeInput
是Union[List[str], Tuple[str], Tuple[Union[List[str], Tuple[str]], Union[List[str], Tuple[str]]], List[Union[List[str], Tuple[str]]]]
的别名。
class tokenizers.AddedToken(content, single_word=False, lstrip=False, rstrip=False, normalized=True)
:代表要被添加到Tokenizer
中的一个token
。
参数:
content
:一个字符串,指定token
的内容。single_word
:一个布尔值,指定该token
是否仅匹配单个word
。例如,该值为True
时,"ing"
不会匹配单词"playing"
;改值为False
时,"ing"
可以匹配单词"playing"
。lstrip
:一个布尔值,指定是否移除该token
的所有左侧空格。rstrip
:一个布尔值,指定是否移除该token
的所有右侧空格。normalized
:一个布尔值,指定该token
是否匹配输入文本的normalized
版本。
class tokenizers.Encoding()
:Encoding
代表Tokenizer
的输出。
属性:
attention_mask
:一个整数列表,给出attention mask
,表示哪些token
应该被attended
(1
对应的) 、哪些不应该被attended
(0
对应的)。
ids
:一个整数列表,给出编码后的ID
列表。
n_sequences
:一个整数,返回Encoding
中包含多少个句子。
offsets
:元组(int, int)
的一个列表,指定每个token
的偏移量(相对于文本开头)。通过这个offsets
以及给定的文本,你可以获取对应的token
。
overflowing
:overflowing Encoding
的一个列表。当使用截断时,Tokenizer
会根据需要将输出分成尽可能多的部分,从而匹配指定的max length
。这个字段允许你检索所有截断之后的、后续的片段。
当你使用句子对时,overflowing pieces
将包含足够多的变化,从而覆盖所有可能的组合,同时考虑到所提供的max length
。
sequence_ids
:一个整数列表,表示序列的id
(一个序列就是一个句子)。每个id
代表一个句子并关联到该句子的每个token
。
注意,如果token
属于任何句子(如special token
),那么它的sequence_id
为None
。
special_token_mask
:一个整数列表,指定哪些token
是special token
、哪些不是。
tokens
:一个字符串列表,表示生成的token
序列。
type_ids
:一个整数列表,表示生成的type ID
。常用于序列分类或问答任务,使得语言模型知道每个token
来自于哪个输入序列。
它和
sequence_ids
相同的功能。
word_ids
:一个整数列表,指定每个单词的位置编号(用于指示哪些token
是属于同一个单词)。它们表示每个token
关联的单词的位置。
如果输入是pre-tokenized
,那么它们对应于给定的input label
的ID
;否则它们对应于所使用的PreTokenizer
定义的单词索引。
例如,如果
word_ids = [0,0,0,1]
,那么表明前三个token
都属于同一个单词,第四个token
属于另一个单词。
words
:一个整数的列表,指定生成的单词的索引。将来被废弃,推荐使用word_ids
属性。
方法:
char_to_token(char_pos, sequence_index=0) -> int
:返回包含指定字符的token
是token
序列中的第几个token
。
参数:
char_pos
:一个整数,指定目标字符在输入序列的哪个位置。sequence_index
:一个整数,指定目标字符位于哪个句子。
char_to_word(char_pos, sequence_index=0) -> int
:返回包含指定字符是该句子中的第几个单词。
参数:参考char_to_token()
。
merge( encodings, growing_offsets = True ) -> Encoding
:合并encoding
列表到final Encoding
。
参数:
encodings
:一个Encoding
列表,表示待合并的encoding
。growing_offsets
:一个布尔值,指定合并过程中,偏移量是否需要累加。
pad(length, direction = 'right', pad_id = 0, pad_type_id = 0, pad_token = '[PAD]' )
:将Encoding
填充到指定长度。
参数:
length
:一个整数,指定要填充到的长度。direction
:一个字符串,指定填充方式,可以是左填充'left'
或右填充'right'
。pad_id
:一个整数,指定pad token
的id
。pad_type_id
:一个整数,指定pad token
对应的type ID
。pad_token
:一个字符串,指定pad token
字符串。
set_sequence_id(sequence_id)
:设定为当前Encoding
中的所有token
设置sequence_id
。
参数:sequence_id
:一个整数,指定sequence_id
。
token_to_chars(token_index) -> Tuple[int, int]
:获取指定token
的偏移量。通过这个偏移量,我们可以从原始的输入序列中获取到该token
。
参数:token_index
:被编码的序列中的token
的索引。
token_to_sequence(token_index) -> int
:获取指定token
的sequence id
。
参数:token_index
:被编码的序列中的token
的索引。
对于单个句子的输入,返回结果通常是0
;对于句子对的输入,如果token
位于第一个句子则返回0
;如果位于第二个句子则返回1
。
token_to_word(token_index) -> int
:获取包含指定token
的单词是该句子中的第几个单词。
参数:token_index
:被编码的序列中的token
的索引。
truncate(max_length, stride=0, direction='right')
:截断Encoding
到指定的长度。
参数:
max_length
:一个整数,指定要截断到的长度。stride
:一个整数,指定每个overflowing
片段包含前一个片段的长度(以token
为基本单位)。direction
:一个字符串,指定截断方向。可以为'right'
或'left'
。
如果Encoding
代表多个序列,那么截断之后,这个信息被丢失。结果被认为是单个序列。
word_to_chars(word_index, sequence_index = 0) -> Tuple(int, int)
:返回指定的单词在原始句子中的区间。
参数:
word_index
:一个整数,指定了目标单词的索引。sequence_index
:一个整数,指定目标单词位于哪个句子。
word_to_tokens(word_index, sequence_index = 0) -> Tuple(int, int)
:返回指定的单词在token
序列中的区间。
参数:参考word_to_chars
。
class tokenizers.tools.Annotation(start: int, end:int, label:str)
:一个Annotation
,用于可视化。
参数:
start
:一个整数,指定位于字符串中的开始位置。end
:一个整数,指定位于字符串中的结束位置。label
:一个字符串,指定label
字符串。
class tokenizers.tools.EncodingVisualizer(tokenizer: Tokenizer, default_to_notebook: bool = True, annotation_converter:typing.Union[typing.Callable[[typing.Any], tokenizers.tools.visualizer.Annotation], NoneType] = None )
:构建一个EncodingVisualizer
。
参数:
tokenizer
:一个Tokenizer
对象,表示tokenizer
实例。default_to_notebook
:一个布尔值,指定是否渲染html
输出从而适配notebook
。annotation_converter
:一个可调用对象,它通常是一个lambda
函数,接受一个任意类型的输入并返回一个Annotation
对象。
方法:
__call__(text: str, annotations: typing.List[tokenizers.tools.visualizer.Annotation] = [], default_to_notebook: typing.Optional[bool] = None )
:对给定的文本构建一个可视化。
参数:
text
:一个字符串,指定需要被tokenize
的字符串。annotations
:text
对应的一个列表的注解。可以是一个Annotation
类,或者通过一个转换函数返回一个Annotation
。default_to_notebook
:一个布尔值,如果为True
则渲染html
字符串到notebook
;否则直接返回一个html
字符串。
四、Tokenizer 库的应用
4.1 从头开始训练 WordPiece
代码:
要在Transformers
中使用这个tokenizer
,我们必须将它封装在一个PreTrainedTokenizerFast
类中。
如果是Transformers
已有的模型,如BERT
,那么就可以用对应的PreTrainedTokenizerFast
子类,如BertTokenizerFast
。
或者也可以直接使用PreTrainedTokenizerFast
,方法为:
注意:我们必须手动设置所有special token
,因为PreTrainedTokenizerFast
无法从tokenizer
对象推断出这些special token
。
虽然
tokenizer
有special token
属性,但是这个属性是所有special token
的集合,无法区分哪个是CLS
、哪个是SEP
。
最后,这些wrapped_tokenizer
可以使用save_pretrained()
方法或push_to_hub()
方法来保存到Hugging Face Hub
。其中save_pretrained()
方法会保存三个文件:'tokenizer_config.json'
、'special_tokens_map.json'
、'tokenizer.json'
。
4.2 从头开始训练 BPE
代码:
我们可以把训练好的tokenizer
封装在一个PreTrainedTokenizerFast
类中,从而在Transformers
中使用:
直接使用GPT2TokenizerFast
:
使用PreTrainedTokenizerFast
类:
4.3 从头开始训练 Unigram
代码:
我们可以把训练好的tokenizer
封装在一个PreTrainedTokenizerFast
类中,从而在Transformers
中使用:
直接使用XLNetTokenizerFast
:
使用PreTrainedTokenizerFast
类:
五、Tokenizer in Transformers
tokenizer
负责为模型准备input
。大多数tokenizer
有两种风格:基于Python
的实现、以及基于Rust library Tokenizer
的"Fast"
实现。
这个"Fast"
实现的优点:在batched tokenization
、以及原始字符串到token space
之间的方法上(如,获得给定token
的span
时),获得显著的加速。
PreTrainedTokenizer
基类和PreTrainedTokenizerFast
基类实现了通用的方法,它们都依赖于SpecialTokensMixin
、以及包含通用方法的PreTrainedTokenizerBase
。
5.1 PreTrainedTokenizerBase
class PreTrainedTokenizerBase(**kwargs)
:PreTrainedTokenizer
和PreTrainedTokenizerFast
的基类。
参数:
model_max_length
:一个整数,指定transformer model
的输入的max
长度(以token
为单位衡量)。当tokenizer
采用from_pretrained()
被加载时,model_max_length
被设置为transformer model
关联的max_model_input_sizes
值。
如果未提供,则默认为VERY_LARGE_INTEGER
(等于int(1e30)
)。
padding_side
:一个字符串,指定填充发生在哪一侧。可以为'right'
或'left'
。默认从相同名字的class attribute
中选取。
truncation_side
:一个字符串,指定截断发生在哪一侧。可以为'right'
或'left'
。默认从相同名字的class attribute
中选取。
model_input_names
:一个字符串列表,指定模型的前向传播所接受的input
的列表,如["token_type_ids", "attention_mask"]
。默认从相同名字的class attribute
中选取。
bos_token
:一个字符串或者AddedToken
,表示句子开始的special token
。self.bos_token
将和self.bos_token_id
关联。
eos_token
:一个字符串或者AddedToken
,表示句子结束的special token
。self.eos_token
将和self.eos_token_id
关联。
unk_token
:一个字符串或者AddedToken
,表示out-of-vocabulary token
的special token
。self.unk_token
将和self.unk_token_id
关联。
sep_token
:一个字符串或者AddedToken
,表示同一个输入中分隔两个不同句子的special token
。self.sep_token
将和self.sep_token_id
关联。
pad_token
:一个字符串或者AddedToken
,表示padding token
的special token
。self.pad_token
将和self.pad_token_id
关联。
cls_token
:一个字符串或者AddedToken
,表示cls token
的special token
。self.cls_token
将和self.cls_token_id
关联。
mask_token
:一个字符串或者AddedToken
,表示mask token
的special token
。self.mask_token
将和self.mask_token_id
关联。
additional_special_tokens
:字符串或者AddedToken
的一个元组或列表,表示额外的special token
。可以确保它们不会被tokenization
过程所拆分。self.additional_special_tokens
将和self.additional_special_tokens_ids
关联。
class attribute
(被派生类所重写):
vocab_files_names
:一个字典Dict[str, str]
,键为每个模型的初始化方法中的针对vocabulary file
的keyword name
,值为vocabulary file
的文件名。pretrained_vocab_files_map
:一个字典的字典Dict[str, Dict[str, str]]
,high-level
的键为每个模型的初始化方法中的针对vocabulary file
的keyword name
,low-level
的键为预训练模型的简称short-cut-name
,值为预训练的词表文件的url
。max_model_input_sizes
:一个字典Dict[str, int]
,键为预训练模型的简称,值为该模型的序列输入的最大长度。如果模型没有最大输入大小,则为None
。pretrained_init_configuration
:一个字典的字典,Dict[str, Dict[str, Any]]
,键为预训练模型的简称,值为包含特定参数的字典。当使用from_pretrained()
方法加载tokenizer
时,这些参数将传递给针对该预训练模型的tokenizer class
的初始化方法。model_input_names
:字符串的一个列表,指定模型的前向传播所接受的input
的列表。padding_side
:一个字符串,指定填充发生在哪一侧。truncation_side
:一个字符串,指定截断发生在哪一侧。
方法:
__call__
:核心方法,用于执行tokenization
过程从而为模型准备输入。
参数:
text
:一个字符串、字符串的列表、字符串的列表的列表,指定需要被编码的序列或batched
序列。每个序列可以是一个字符串(原始文本)、或者字符串的列表(pretokenized
字符串)、或者字符串的列表的列表(batched
的pretokenized
字符串)。
此外,如果你提供了字符串的列表,那么必须设置is_split_into_words
参数从而消除歧义。如果is_split_into_words=True
,此时字符串的列表代表pretokenized
字符串;如果is_split_into_words=False
,此时字符串的列表代表batched
的原始字符串。
text_pair
:一个字符串、字符串的列表、字符串的列表的列表,指定需要被编码的序列或batched
序列。格式的解释参考text
。
text_target
:一个字符串、字符串的列表、字符串的列表的列表,指定需要被编码的target text
的序列或batched
序列。格式的解释参考text
。
text_pair_target
:一个字符串、字符串的列表、字符串的列表的列表,指定需要被编码的target text
的序列或batched
序列。格式的解释参考text
。
add_special_tokens
:一个布尔值,指定是否使用与模型相关的special token
来编码序列。
padding
:一个布尔值、字符串、或PaddingStrategy
,指定启用填充并控制填充。可以为:
True
或"longest"
:填充到batch
中最长的序列。如果仅提供单个序列,则不填充。"max_length"
:填充到由max_length
所指定的最大长度,或填充到模型可接受的最大输入长度(如果max_length
参数未提供)。False
或"do_not_pad"
(默认值):不填充。此时batch
的输出可能具有不同的序列长度。
truncation
:一个布尔值、字符串、或TruncationStrategy
,指定启用截断并控制截断。可以为:
True
或"longest_first"
:截断到由参数max_length
指定的最大长度,或截断到模型可接受的最大输入长度(如果max_length
参数未提供)。
如果输入是序列的pair
,那么将同时截断第一个序列和第二个序列,然后根据两两组合进行笛卡尔积得到多个结果。假设第一个序列为abc
,第二个序列为xyz
,假设max_length=2
,那么得到四个结果:(ab, xy), (c, xy), (ab, z), (y,z)
。
"only_first"
:截断到由参数max_length
指定的最大长度,或截断到模型可接受的最大输入长度(如果max_length
参数未提供)。
如果输入是序列的pair
,那么仅截断第一个序列。
"only_second"
:截断到由参数max_length
指定的最大长度,或截断到模型可接受的最大输入长度(如果max_length
参数未提供)。
如果输入是序列的pair
,那么仅截断第二个序列。
False
或"do_not_truncate"
(默认值):不截断。此时batch
的输出可能出现超过模型可接受的最大输入长度。
max_length
:一个整数控制,控制truncation/padding
使用的最大长度。如果未设置或者为None
,则使用预定义的model maximum length
。如果模型没有特定的maximum input length
(如XLNet
),那么truncation/padding
到最大长度的能力将被禁用。
stride
:一个整数,默认为0
。如果return_overflowing_tokens = True
,那么返回的overflowing token
将包含被截断的序列的末尾的一些token
,那么stride
参数将指定truncated sequence
和overflowing sequence
之间的重叠token
的数量。
is_split_into_words
:一个布尔值,指定提供的输入字符串是否已经被pre-tokenized
。如果为True
,那么tokenizer
假设输入已被拆分为单词,那么tokenizer
将对这些单词进行tokenize
。
pad_to_multiple_of
:一个整数,指定将序列填充到指定的倍数。这对于在NVIDA
硬件上使用Tensor Cores
非常有用。
return_tensors
:一个字符串或TensorType
,指定返回张量而不是返回python
整数列表。可以为:"tf"
(TensorFlow
张量)、"pt"
(Pytorch
张量)、"np"
(np.ndarray
对象)。
return_token_type_ids
:一个布尔值,指定是否返回token type ID
。如果为None
,则将根据特定tokenizer
的默认值(由return_outputs
属性来定义)来返回token type ID
。
return_attention_mask
:一个布尔值,指定是否返回attention mask
。如果为None
,则将根据特定tokenizer
的默认值(由return_outputs
属性来定义)来返回attention mask
。
return_overflowing_tokens
:指定是否返回overflowing token sequence
。如果为sequence pair
或者batched
的sequence pair
,并且truncation_strategy = 'longest_first'/True
,那么抛出异常而不是返回overflowing token
。
return_special_tokens_mask
:一个布尔值,指定是否返回special tokens mask
。
return_offsets_mapping
:一个布尔值,指定是否为每个token
返回(char_start, char_end)
的偏移量。
这仅在从PreTrainedTokenizerFast
继承的fask tokenizer
上可用。如果使用Python tokenizer
,则抛出NotImplementedError
异常。
return_length
:一个布尔值,指定是否返回被编码的input
的长度。
verbose
:一个布尔值,指定是否打印更多信息和警告。
**kwargs
:关键字参数,传递给self.tokenize()
方法。
返回值:一个BatchEncoding
对象。
as_target_tokenizer()
:临时设置tokenizer
对target
进行编码(一对句子的第二个句子)。对seq-to-seq
模型关联的tokenizer
非常有用,这些模型需要对label
序列进行稍微不同的处理。
batch_decode()
:通过调用decode
方法将token id
的列表的列表(内层列表表示一个序列,外层列表表示batch
)转换成字符串的列表。
参数:
sequences
:tokenized input id
的列表,表示解码的id
序列。它可以从__calll__
方法返回而来。skip_special_tokens
:一个布尔值,指定是否从解码结果中移除special token
。clean_up_tokenization_spaces
:一个布尔值,指定是否清理tokenization
空格。kwargs
:关键字参数,将传递给具体于底层模型的decode()
方法。
返回值:一个字符串列表,表示解码结果。
batch_encode_plus()
:对序列的一个列表、或者sequence pair
的一个列表进行tokenize
和prepare
。该方法被废弃,推荐使用__call__()
方法。
参数:
batch_text_or_text_pairs
:一个batch
的序列、或者一个batch
的sequence pair
。其它参数参考__call__()
方法。
返回值:一个BatchEncoding
对象。
build_inputs_with_special_tokens(token_ids_0: List[int], token_ids_1: Optional[List[int]] = None) -> List[int]
:向model input
中插入special token
。
参数:
token_ids_0
:一个整数列表,指定第一个tokenized
序列。token_ids_
:一个整数列表,指定第二个tokenized
序列。
返回值:一个整数列表,表示插入了special token
之后的model input
。
注意,这里面的实现并没有添加special token
,并且该方法需要被子类所重写。
clean_up_tokenization(out_string: str) -> str
:执行一些简单的英文tokenization artifact
(如标点符号前的空格,以及缩写形式)。
参数:out_string
:待清理的文本。
返回值:清理后的文本。
convert_tokens_to_string(tokens: typing.List[str]) -> str
:将一个token
序列转换成单个字符串。
参数:tokens
:一个token
序列。
返回值:转换后的字符串。
最简单的转换方式为" ".join(tokens)
,但是我们可能需要移除sub-word
的某些前缀(如##
)。
create_token_type_ids_from_sequences(token_ids_0: List[int], token_ids_1: Optional[List[int]] = None) -> List[int]
:创建token type ID
。
参数:
token_ids_0
:一个整数列表,指定第一个tokenized
序列。token_ids_
:一个整数列表,指定第二个tokenized
序列。
返回值:一个整数列表,表示token type ID
。
decode()
:把token id
的一个序列转换成字符串,类似于self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))
。
参数:
token_ids
:tokenized input id
的列表,它可以从__calll__
方法返回而来。其它参数参考batch_decode()
。
返回值:解码后的字符串。
encode()
:将一个字符串转换为token id
序列,它类似于self.convert_tokens_to_ids(self.tokenize(text))
。
参数:
text
:指定待编码的第一个字符串。可以为一个字符串、一个字符串的列表(表示tokenized string
)、一个整数的列表(通过convert_tokens_to_ids
将tokenized string
转换而来)。text_pair
:指定待编码的第二个字符串。格式参考text
。其它参数参考batch_encode_plus()
方法 。
返回值:文本对应的tokenized id
。
encode_plus()
:对序列或sequence pair
进行tokenize
和prepare
。该方法被废弃,推荐使用__call__()
方法。
参数:
text/text_pair
:参考encode()
方法。其它参数参考batch_encode_plus()
方法 。
返回值:一个BatchEncoding
对象。
from_pretrained(pretrained_model_name_or_path: Union[str, os.PathLike], *init_inputs, **kwargs)
:从一个预定义的tokenizer
中初始化一个PreTrainedTokenizerBase
(或者派生类)的对象。
参数:
pretrained_model_name_or_path
:一个字符串或者os.PathLike
对象,指定预定义的tokenizer
的位置。可以为:
一个字符串,指定托管在huggingface.co
上的model repo
中的预定义tokenizer
的model id
。有效的model id
可以位于root-level
,如bert-base-uncased
;也可以位于某个namespace
下,如huaxz/bert-base-german-cased
。包含vocabulary
文件的目录的路径,这些vocabulary
被tokenizer
所要求。这个路径可以由save_pretrained()
方法来得到。指向单个vovabulary file
的文件名(被废弃,因为无法应用于所有派生类),例如BERT/XLNet
的tokenizer
只需要单个vocabulary file
。
cache_dir
:一个字符串或者os.PathLike
对象,指定下载的predefined tokenizer
词表文件被缓存的目录。
force_download
:一个布尔值,指定是否强制下载词表文件并覆盖已被缓存的版本(如果已经存在的话)。
resume_download
:一个布尔值,指定是否删除未完整接收的文件。否则,如果存在这样的文件,将尝试恢复下载。
proxies
:一个字典,指定协议或端口的代理服务器,如{'http': 'foo.bar:3128', 'http://hostname': 'foo.bar:4012'}
。
use_auth_token
:一个字符串或布尔值,指定authorization token
用于认证。如果为True
,则使用huggingface-cli
登录时所生成的token
(存储在~/.huggingface
)。
local_files_only
:一个布尔值,指定是否仅依赖于本地文件而不尝试下载任何文件。
revision
:一个字符串,指定要使用的specific model version
。它可以是git branch
名称、git tag
名称、或者git commit id
。因为huggingface.co
依赖于git-based
系统。
subfolder
:一个字符串,如果相关文件位于huggingface.co
模型的model repo
的子目录中时,需要指定该参数。
inputs
:其它的位置参数,用于传递给Tokenizer__init__()
方法。
kwargs
:其它的关键字参数,用于传递给Tokenizer__init__()
方法。可以用于设置special token
,如bos_token, eos_token,...
。
返回值:一个初始化好的tokenizer
。
get_special_tokens_mask(self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False) -> List[int]
:获取special token mask
。
参数:
token_ids_0
:一个整数列表,指定第一个序列的token id
。token_ids_1
:一个整数列表,指定第二个序列的token id
。already_has_special_tokens
:一个布尔值,指定token list
是否已经使用special token
进行了格式化。
返回值:一个整数列表,每个元素取值为0
或1
,其中1
代表该位置是special token
。
get_vocab() -> Dict[str, int]
:获取词表,它是一个token
字符串到token id
的字典。
当token
位于词表中时,tokenizer.get_vocab()[token]
等价于tokenizer.convert_tokens_to_ids(token)
。
pad()
:填充单个encoded input
或者batch encoded input
到指定的长度(或batch
内的最大长度)。注意,对于fask tokenizer
,直接调用__call__()
方法要比encode() + pad()
方法快得多。
参数:
encoded_inputs
: 单个tokenized input
,或者batched
的tokenized input
。其它参数:参考__call__()
。
返回值:一个BatchEncoding
对象。
prepare_for_model()
:
参数:
ids
:一个整数列表,指定第一个序列的tokenized input id
。pair_ids
:一个整数列表,指定第二个序列的tokenized input id
。其它参数:参考__call__()
。
返回值:一个BatchEncoding
对象。
对input id
的序列、input id
的一对序列进行prepare
,以便模型可以使用。它添加special token
、截断序列。
注意,如果pair_ids
不是None
,且truncation_strategy ='longest_first' / True
,那么抛出异常。
prepare_seq2seq_batch()
:为翻译任务准备model input
。
参数:
src_texts
:一个文档序列,指定source
文本。tgt_texts
:一个文档序列,指定target
文本。max_length
:一个整数,指定编码器输入的最大长度。如果为None
,则使用预定义的model maximum length
。如果模型没有特定的maximum input length
(如XLNet
),那么truncation/padding
到最大长度的能力将被禁用。max_target_length
:一个整数,指定解码器输入的最大长度。如果为None
,则使用max_length
值。其它参数:参考__call__()
。
返回值:一个BatchEncoding
对象。
push_to_hub()
:将tokenizer
文件上传到Model Hub
(对应于本地repo clone
的远程repo path
或repo name
)。
参数:
repo_id
:一个字符串,指定你的tokenizer
要被push
到的repository
的名字。它应该包含你的organization name
。use_temp_dir
:一个字符串,指定在将文件推送到Hub
之前是否使用临时目录来存储文件。如果没有repo_id
名字的目录,则默认为True
;否则默认为False
。commit_message
:一个字符串,指定git commit mesage
。默认为"Upload tokenizer"
。private
:一个字符串,指定被创建的repository
是否是private
的。use_auth_token
:参考from_pretrained()
。max_shard_size
:一个整数或者字符串,仅用于模型,指定checkpoint
被分片之前的最大的大小。checkpoint
将被分片使得每个文件低于这个大小。默认为"10GB"
。如果是字符串,需要指定单位。create_pr
:一个布尔值,指定是否创建一个PR
还是直接commit
。
register_for_auto_class(auto_class = 'AutoTokenizer')
:以指定的auto class
来注册当前的class
。仅用于自定义的tokenizer
,因为库中的tokenizer
已经映射到AutoTokenizer
。
参数:auto_class
:一个字符串或type
,指定这个新的tokenizer
注册到哪个class
。
save_pretrained()
:保存full tokenizer state
。
参数:
save_directory
:一个字符串或者os.PathLike
对象,指定将tokenizer
保存到哪里。
legacy_format
:一个布尔值,仅适用于fast tokenizer
。如果为None
,那么如果存在legacy format
就以该格式保存tokenizer
;如果不存在legacy format
就以统一的JSON
格式保存tokenizer
。其中,legacy format
具有tokenizer specific vocabulary
文件和独立的added_tokens
文件。
如果为False
,则将仅以统一的JSON
格式保存tokenizer
。如果为True
,则以legacy format
格式保存tokenizer
。
legacy format
格式与slow tokenizer
是不兼容的,因此无法加载到slow tokenizer
中。
filename_prefix
:一个字符串,指定添加到tokenizer
保存文件的文件名前缀。
push_to_hub
:一个布尔值,指定是否在保存之后将tokenizer
推送到Hugging Face Hub
上。你可以设置repo_id
指定推送到哪个repository
,默认为repo_id = save_directory
。
kwargs
:传递给push_to_hub()
方法的关键字参数。
返回值:字符串的一个元组,表示被保存的文件名。
save_vocabulary(save_directory: str, filename_prefix: typing.Optional[str] = None ) -> Tuple(str)
:仅保存tokenizer
的词表(vocabulary + added tokens
)。该方法不会保存configuration
以及special token
。
参数和返回值:参考save_pretrained()
。
tokenize(text: str, pair: typing.Optional[str] = None, add_special_tokens: bool = False, **kwargs ) -> List[str]
:将一个字符串转换为token
序列,用unk_token
来替代unknown token
。
参数:
text
:一个字符串,指定被tokenized
文本。pair
:一个字符串,指定第二个被tokenized
文本。add_special_tokens
:一个布尔值,指定是否添加special token
,其中这些special token
关联了对应的模型。kwargs
:关键字参数,传递给底层的model spedific encode
方法,参考__call__()
。
返回值:一个字符串列表,表示被token
序列。
truncate_sequences()
:
参数:
ids
:一个整数列表,表示第一个序列的tokenized input id
。可以通过对一个字符串执行toenize() + convert_token_to_ids()
来获得。pair_ids
:一个整数列表,表示第二个序列的tokenized input id
。num_tokens_to_remove
:一个整数,指定使用截断策略要移除的token
的数量。truncation_strategy/stride
:参考__call__()
方法。
返回值:一个元组,分别给出了truncated ids
、truncated pair_ids
、以及overflowing token
的列表。
注意:如果截断策略为"longest_first"
且提供了sequence pair
或者batched
的sequence pair
,则overflowing token
为空列表。
5.2 SpecialTokensMixin
class transformers.SpecialTokensMixin(verbose = True, **kwargs)
:由PreTrainedTokenizer
和PreTrainedTokenizerFast
派生的mixin
,用于处理关于special token
的特定行为。
参数:
bos_token
:一个字符串或AddedToken
,指定代表句子开头的special token
。eos_token
:一个字符串或AddedToken
,指定代表句子结尾的special token
。unk_token
:一个字符串或AddedToken
,指定代表out-of-vocabulary token
的special token
。sep_token
:一个字符串或AddedToken
,指定代表同一个输入中分隔两个不同句子的special token
。pad_token
:一个字符串或者AddedToken
,指定代表padding token
的special token
。self.pad_token
将和self.pad_token_id
关联。cls_token
:一个字符串或者AddedToken
,指定代表cls token
的special token
。mask_token
:一个字符串或者AddedToken
,指定代表mask token
的special token
。additional_special_tokens
:字符串或者AddedToken
的一个元组或列表,指定代表额外的special token
。
方法:
add_special_tokens(special_tokens_dict: typing.Dict[str, typing.Union[str, tokenizers.AddedToken]]) -> int
:添加一个special token
的字典(如eos,pad,cls
)到encoder
中。如果special token
不在vocabulary
中,则添加这些special token
。
参数:special_tokens_dict
:一个字典,key
为special token
的名字(如'bos_token', 'eos_token',..
等等),值为special token
的取值。
返回值:新增到vocabulary
中的token
的数量。
注意:当vocabulary
添加了新的special token
之后,词表规模发生了变化,此时你需要resize token embedding matrix
从而使得embedding matrix
匹配词表。方法是调用resize_token_embeddings()
方法。
add_tokens(new_tokens: typing.Union[str, tokenizers.AddedToken, typing.List[typing.Union[str, tokenizers.AddedToken]]], special_tokens: bool = False ) -> int
:添加新的token
到tokenizer class
中。如果新token
不在词表中,则会被添加到词表中。
参数:
new_tokens
:一个字符串、AddedToken
、或者str/AddedToken
的字符串,指定被添加到tokenizer
中的token
。special_tokens
:一个布尔值,指定是否可用于指定token
为一个special token
。
返回值:新增到词表中的token
数量。
注意:当vocabulary
添加了新的special token
之后,词表规模发生了变化,此时你需要resize token embedding matrix
从而使得embedding matrix
匹配词表。
sanitize_special_tokens() -> int
:检查词表中的token
并返回词表中的token
数量。
class transformers.tokenization_utils_base.TruncationStrategy(value, names = None, module = None, qualname = None, type = None, start = 1 )
:TruncationStrategy
的枚举类。
class transformers.CharSpan(start: int, end: int)
:原始字符串中的character span
。
参数:
start
:一个整数,指定字符的开始位置。end
:一个整数,指定字符的结束位置。
class transformers.TokenSpan(start: int, end: int)
:原始字符串中的token span
。
参数:
start
:一个整数,指定token
的开始位置。end
:一个整数,指定token
的结束位置。
5.3 PreTrainedTokenizer
class transformers.PreTrainedTokenizer(**kwargs)
:所有slow tokenizer
的基类,继承自PreTrainedTokenizerBase
。
PreTrainedTokenizer
在所有tokenizer
之上以统一的方式包含added token
,因此我们不必处理各种底层字典结构的specific vocabulary augmentation
方法(如BPE
、sentencepiece
、…)。
参数:参考PreTrainedTokenizerBase
。
class attribute
(被派生类所重写):参考PreTrainedTokenizerBase
。
方法:
convert_ids_to_tokens(ids: typing.Union[int, typing.List[int]], skip_special_tokens: bool = False ) -> str or List[str]
:解码,将token id
序列转换为token
序列。
参数:
ids
:一个整数或整数序列,指定需要被转换的token id
。skip_special_tokens
:一个布尔值,指定是否从解码结果中移除special token
。
返回值:一个字符串或字符串序列。
convert_tokens_to_ids(tokens: typing.Union[str, typing.List[str]] ) -> int or List[int]
:编码,将token
序列转换为token id
序列。
参数:tokens
:一个字符串或字符串序列,表示单个token
或token
序列。
返回值:一个整数或整数序列。
get_added_vocab() -> Dict[str, int]
:返回词表中的added token
。
返回值:一个字典,key
为added token
,值为对应的id
。
num_special_tokens_to_add( pair: bool=False) -> int
:返回需要添加到single/pair
句子的special token
的数量。
参数:is_pair
:一个布尔值,指定预期的输入是单个句子还是句子对。
prepare_for_tokenization(text: str, is_split_into_words: bool = False, **kwargs ) -> Tuple[str, Dict[str, Any]]
:执行tokenization
之前的任何必要的转换。
参数:
text
:一个字符串,指定被处理的文本。is_split_into_words
:一个布尔值,指定输入是否已经被pre-tokenized
。如果为True
,那么tokenizer
假定input
已经被拆分为单词了。
返回值:一个元组,分别表示处理后的文本、以及处理后的kwargs
。
这个方法应该从kwargs
中弹出参数,并返回剩余的kwargs
。我们在编码过程的最后测试kwargs
,从而确保所有的参数都被使用。
tokenize(text: str, **kwargs ) -> List[str]
:将字符串转换为token
序列。
参数:
text
:一个字符串,指定被处理的文本。**kwargs
:关键字参数,被传给prepare_for_tokenization()
方法。
返回值:一个字符串列表,表示token
序列。
其它方法参考PreTrainedTokenizerBase
。
5.4 PreTrainedTokenizerFast
class transformers.PreTrainedTokenizerFast(*args, **kwargs)
:所有fast tokenizer
的基类,继承自PreTrainedTokenizerBase
。
PreTrainedTokenizerFast
在所有tokenizer
之上以统一的方式包含added token
,因此我们不必处理各种底层字典结构的specific vocabulary augmentation
方法(如BPE
、sentencepiece
、…)。
参数:参考PreTrainedTokenizerBase
。
class attribute
(被派生类所重写):参考PreTrainedTokenizerBase
。
方法:
set_truncation_and_padding()
:一个上下文管理器,为fast tokenizer
定义截断策略和填充策略。一旦设置好之后,后面就延续这个设置。
参数:参考PreTrainedTokenizerBase.__call__()
方法。
默认的tokenizer
都是没有填充、没有截断的。在该方法管理的代码段,可以使用指定的策略;一旦退出该代码段,则又恢复回没有填充、没有截断的策略。
train_new_from_iterator(text_iterator, vocab_size, length = None, new_special_tokens = None, special_tokens_map = None, **kwargs) -> PreTrainedTokenizerFast
:返回一个新的tokenizer
,这个new tokenizer
与原始tokenizer
具有相同的类型但是在text_iterator
上训练得到(使用原始tokenizer
相同的默认值,如special token
)。
参数:
text_iterator
:一个生成器或者字符串列表,指定训练语料库。对text_iterator
迭代的结果是字符串。vocab_size
:一个整数,指定新tokenizer
期待的词表大小。length
:一个整数,指定text_iterator
中的总的文本数量。这用于有意义的进度跟踪。new_special_tokens
:一个str/AddedToken
的列表,指定添加到新tokenizer
中的new spiecial token
。special_tokens_map
:一个字典,用于为新tokenizer
重新命名某些special token
,即old special token name -> new special token name
。kwargs
:关键字参数,用于传递给trainer
。
返回值:一个PreTrainedTokenizerFast
对象。
有两种方法来检查tokenizer
是快的还是慢的:
通过tokenizer.is_fast
属性。通过Encoding
对象(tokenizer
编码的结果)的encoding.is_fast
属性。
5.5 BatchEncoding
class class transformers.BatchEncoding()
:BatchEncoding
持有__call__(), encode_plus(), batch_encode_plus()
等方法的输出。
参数:
data
:一个字典,键为'input_ids', 'attention_mask',...
。该数据由__call__/encode_plus/batch_encode_plus
等方法返回。encoding
:EncodingFast
或EncodingFast
的序列。如果tokenizer
是一个fast tokenizer
,那么它将输出额外的信息,如,从word/character space
到token space
的映射。那么EncodingFast
就用于保存这些额外的信息。tensor_type
:一个字符串或者TensorType
。你可以指定一种类型从而将整数列表转换为对应的张量类型。prepend_batch_axis
:一个布尔值,指定在整数列表转换为对应的张量类型时,是否添加一个batch axis
。n_sequences
:一个整数,指定生成当前BatchEncoding
的序列的数量。
BatchEncoding
派生自python
字典,因此可以直接用作一个字典。此外,它还有一些自定义的方法。
方法:
char_to_token(batch_or_char_index: int, char_index: Optional[int] = None, sequence_index: int = 0) -> int
: 返回encoded output
中指定索引(索引相对于原始文本)的character
所在位置的token
的索引。
参数:
batch_or_char_index
:一个整数,如果原始输入是一个batch
,则指定character
位于第几个样本;如果原始输入是单个序列,则指定character
的索引。char_index
:一个整数,配合batch_or_char_index
使用,则它指定character
位于batch
内哪个样本的哪个索引。sequence_index
:一个整数,如果输入是一对句子,则指定character
位于是第一个句子还是第二个句子。
返回值:一个整数,表示对应的token
的索引。
调用方式:
char_to_word(batch_or_char_index: int, char_index: Optional[int] = None, sequence_index: int = 0) -> int or List[int]
: 返回encoded output
中指定索引(索引相对于原始文本)的character
所在的word
的索引。
参数:参考char_to_token()
。
返回值:一个整数或整数列表,表示对应的word
的索引。
convert_to_tensors(self, tensor_type: Optional[Union[str, TensorType]] = None, prepend_batch_axis: bool = False)
:将内部内容转换为张量。
参数:参考BatchEncoding.__init__()
方法。
sequence_ids( batch_index: int = 0) -> List[Optional[int]]
:返回sequence id
的列表,列表中每个元素表示每个token
的sequence id
(即,是样本内的第几个句子)。
参数:batch_index
:一个整数,指定batch
内第几个序列。
返回值:一个整数列表。
sequence id
表示原始句子的id
:
None
:表示special token
。0
:表示token
对应的单词位于第一个句子。1
:表示token
对应的单词位于第二个句子。
to(device: Union[str, torch.device]) -> BatchEncoding
:将BatchEncoding
移动到指定的设备上,仅用于PyTorch
。
参数:device
:一个字符串或者torch.device
,指定指定的设备。
返回:相同的BatchEncoding
,但是位于指定的设备上。
token_to_chars(batch_or_token_index: int, token_index: Optional[int] = None) -> CharSpan
:返回token
在原始字符串中的区间。
参数:
batch_or_token_index
:一个整数,如果原始输入是一个batch
,则指定token
位于第几个样本;如果原始输入是单个样本,则指定token
的索引。token_index
:一个整数,配合batch_or_token_index
使用,则它指定token
位于batch
内哪个样本的哪个索引。
返回值:一个CharSpan
,表示对应的字符的区间([a,b)
这种半闭半开区间)。
调用方式:
token_to_sequence(batch_or_token_index: int, token_index: Optional[int] = None) -> int
:返回token
在原始输入的第几个句子。
token_to_word(batch_or_token_index: int, token_index: Optional[int] = None) -> int
:返回token
在原始输入的word
的索引。
参数:参考token_to_chars
。
返回值:一个整数,表示word
的索引。
tokens( batch_index: int = 0) -> List[str]
:返回指定batch
索引处的token
列表。
参数:batch_index
:一个整数,指定batch
索引。
返回值:一个字符串列表,表示token
列表。
word_ids( batch_index: int = 0) -> List[Optional[int]]
:返回指定batch
索引处的token
对应的word
索引的列表。
参数:参考tokens()
。
返回值:一个整数列表,表示每个token
对应的word
索引。special token
被映射到None
。
word_to_chars(batch_or_word_index: int, word_index: Optional[int] = None, sequence_index: int = 0) -> CharSpan
:返回指定的单词在原始字符串中的区间。
参数:
batch_or_word_index
:一个整数,如果原始输入是一个batch
,则指定word
位于第几个样本;如果原始输入是单个样本,则指定word
的索引。word_index
:一个整数,配合batch_or_word_index
使用,则它指定word
位于batch
内哪个样本的哪个索引。sequence_index
:一个整数,指定目标单词位于第一个句子还是第二个句子。
返回值:一个CharSpan
。
word_to_tokens( batch_or_word_index: int, word_index: Optional[int] = None, sequence_index: int = 0) -> Optional[TokenSpan]
:返回指定的单词对应的token
的索引。
参数:参考word_to_chars
。
返回值:一个TokenSpan
。
words( batch_index: int = 0) -> List[Optional[int]]
:返回指定batch
处每个token
对应的单词的索引。
参数:
batch_idex
:一个整数,指定获取batch
中第几个样本。
返回值:一个整数列表,表示每个单词的索引。
special token
将被映射到None
。相同单词的不同token
被映射到相同的单词索引。
示例:
5.6 应用
编码:直接调用__call__()
方法:
或者依次调用tokenize
和convert_tokens_to_ids
:
解码:通过decode()
方法实现:
一个batch
的输入:填充:
截断序列:
longest_first
截断:
only_second
截断方式:
only_first
截断方式:
非零的stride
叠加only_second
截断方式:
如果觉得《通俗易懂讲解大模型:Tokenizer》对你有帮助,请点赞、收藏,并留下你的观点哦!