在本章教程中,我们将探讨如何使用 🤗 Transformers 来对数据进行预处理。主要的工具就是 tokenizer。你可以使用与模型配套的 tokenizer 类,或者直接使用 AutoTokenizer
类。
Tokenizer 会首先将一段文本分割成单词序列(或者单词的一部分字符、标点符号等),这些单词经常被称为 tokens。然后它会将 tokens 转换为对应的向量,同时还会根据需要加入 attention mask 等模型需要的部件。
如果你想使用一个预训练的模型,那么就必须使用它配套的 tokenizer:它会以与预训练语料集相同的方式进行分词,然后以同样的方式产生 token 对应的 id (通常被称为 vocab)。
调用 from_pretrain()
方法,可以自动下载预训练模型的 vocab 词汇表。
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('bert-base-cased')
1 基本使用
一个 PreTrainedTokenizer
有很多成员方法,不过唯一一个你需要记住的用于预处理数据的方法是 __call__()
:你只需要将输入的句子字符串喂给 tokenizer 对象就可以了。
encoded_input = tokenizer("Hello, I'm a single sentence!")
encoded_input
{'input_ids': [101, 8701, 117, 151, 112, 155, 143, 12148, 9342, 8511, 10504, 106, 102],
'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]}
它返回一个 string-list 的字典。 input_ids
就是每个单词在词汇表中的索引。我们会在下面详细展开 attention_mask
以及 token_type_ids
。
Tokenizer 可以将 token ids 解码回其对应的句子:
tokenizer.decode(encoded_input['input_ids'])
"[CLS] hello, i'm a single sentence! [SEP]"
我们看到,tokenizer 自动在 tokens 中加入了特殊的模型需要的东西(比如 [CLS]
)。并不是所有的模型都需要这些特殊的 tokens。你也可以不让 tokenizer 解码的时候加入这个特殊 tokens(只当你自己手动加入了这些特殊 tokens 时才建议这么做),传入参数 add_special_tokens=False
。即可完成。
如果你有一堆句子想同时处理,那就可以把它们放在一个列表中,然后传给 tokenizer。
batch_sentences = ["Hello I'm a single sentence",
"And another sentence",
"And the very very last one"]
encoded_inputs = tokenizer(batch_sentences)
print(encoded_inputs)
{'input_ids': [[101, 8701, 151, 112, 155, 143, 12148, 9342, 8511, 10504, 102],
[101, 8256, 9064, 11759, 9342, 8511, 10504, 102],
[101, 8256, 8174, 11785, 11785, 10148, 8429, 102]],
'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, 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, 1, 1, 1, 1, 1]]}
如果你一次传入多个句子的目的构造一个 batch,那么你可能需要:
- 将 batch 中较短的句子都填充到 maximum length
- 将 batch 中过长的句子截断到 maximum length
- 直接返回 tensors