【Transformers基础入门篇3】基础组件之Tokenizer


本文为 https://space.bilibili.com/21060026/channel/collectiondetail?sid=1357748的视频学习笔记

项目地址为:https://github.com/zyds/transformers-code


一、Tokenizer 简介

在过去,自然语言预训练模型出来前,做NLP,数据预处理是比较麻烦的,一般有以下几个步骤。

  • step1 分词: 使用分词器对文本数据进行分词(字、字词)
  • step2 构建词典:根据数据集分词的结果,构建词典映射(这一步并不绝对,如果采用预训练词向量,词典映射要根据词向量文件进行处理)
  • step3 数据转换:根据构建好的词典,将分词后处理的数据做映射,将文本序列转换为数字序列
  • step4 数据填充与截断: 在以Batch输入到模型的方式中,需要对过短的数据进行填充,过长的数据进行截断,保证数据长度符合模型能接受的范围,同时batch内的数据维度大小一致。

现在,Transformers中的Tokenizer, 可以完成上面的所有操作。 再也不需要安装各种库,来回找各种词典啦。

二、Tokenizer基本使用

(不同的模型有不同的tokenizer,AutoTokenizer可以自动适配 )

# 先从transformers 导入 AutoTokenizer 
from transformers import AutoTokenizer
sen = "弱小的我也有大梦想!"

2.1 加载保存

# 从HuggingFace加载,输入模型名称,即可加载对于的分词器
tokenizer = AutoTokenizer.from_pretrained("../../models/models_roberta-base-finetuned-dianping-chinese")
tokenizer

# tokenizer 保存到本地
tokenizer.save_pretrained("./roberta_tokenizer")

输出
在这里插入图片描述

# 从本地加载tokenizer
tokenizer = AutoTokenizer.from_pretrained("./roberta_tokenizer/")
tokenizer

2.2 句子分词

借助 tokenizer.tokenize 方法,将中文拆分成一个一个字

tokens = tokenizer.tokenize(sen)
tokens

输出
在这里插入图片描述

2.3 查看词典

tokenizer.vocab # 查看词典
tokenizer.vocab_size # 查看词典的大小

有些是一个字,有些有#号。 #号指做一些子词,如把一个完整的词分成字词,让词表更小。
输出如下:
在这里插入图片描述

2.4 索引转换

# 将词序列转换为id序列
ids = tokenizer.convert_tokens_to_ids(tokens)

# 将id序列转换为token序列
tokens = tokenizer.convert_ids_to_tokens(ids)

# 将token序列转换为string
str_sen = tokenizer.convert_tokens_to_string(tokens)

以上方法还是需要分词,略微麻烦,但tranformers还有 更便捷的实现方式。

# 将字符串转换为id序列,又称之为编码
# add_special_tokens 指特殊的标志符,和模型有关,如Bert开始有 CLS , 末尾有SEP
ids = tokenizer.encode(sen, add_special_tokens=True) # 设置为False则没有这些
ids

输出如下:前面多了101,后面多了102. 根具体的模型有关
在这里插入图片描述

# 将id序列转换为字符串,又称之为解码
str_sen = tokenizer.decode(ids, skip_special_tokens=False)
str_sen

在这里插入图片描述

2.5 填充与截断

# 填充
ids = tokenizer.encode(sen, padding="max_length", max_length=15)
ids

输出多了三个0
在这里插入图片描述

# 截断
ids = tokenizer.encode(sen, max_length=5, truncation=True) 
ids

截断需要注意,是包括开始、终止符号的。
在这里插入图片描述

2.6 其他输入

我们的模型在进入transormer模型,有一些特殊的事项,当句子出现填充,要告诉模型哪些是填充,这时候需要 attention mask,如果自己写。
如像Bert模型,会有token type id,来区别两个句子,到底哪个句子是第一个句子。

ids = tokenizer.encode(sen, padding="max_length", max_length=15)
attention_mask = [1 if idx != 0 else 0 for idx in ids]
token_type_ids = [0] * len(ids)
ids, attention_mask, token_type_ids

transormers便捷方式调用:

inputs = tokenizer.encode_plus(sen, padding="max_length", max_length=15)
inputs

返回结果是一个dict是,包括的input_idx,token_type_ids,attention_mask
在这里插入图片描述
tokenizer.encode_plustokenizer(input)是一样的效果。
大部分情况,都是直接用tokenizer的方法。

inputs = tokenizer(sen, padding="max_length", max_length=15)

三、Fast/Slow Tokenizer

3.1 FastTokenizer

  • 基于Rust实现,速度蒯
  • offsets_mapping, word_ids

有一个参数use_fast=False来控制。

fast_tokenizer = AutoTokenizer.from_pretrained("../../models/models_roberta-base-finetuned-dianping-chinese")

FastTokenizer 可以返回 offsets_mapping和word_ids。 但SlowTokenizer 会报错

sen = "弱小的我也有大Dreaming!"
inputs = fast_tokenizer(sen, return_offsets_mapping=True)
inputs

输出看offet_mapping. 在这里插入图片描述
将word_id可以和offer_mapping对应起来。 在77这个位置,token产生了两个(7-12)和(12-15)

inputs.word_ids()

如这里的dreaming拆分成了两个。如第7个 Dreaming 拆成了两个7、
在这里插入图片描述
word_ids()对命名实体识别有帮助,offer_mapping更多在QA上。

3.2 SlowTokenizer

  • 基于python实现,速度慢。
  • 不支持 offsets_mapping和word_ids
slow_tokenizer = AutoTokenizer.from_pretrained("../../models/models_roberta-base-finetuned-dianping-chinese", use_fast=False)

四、特殊Tokenizer的加载

from transformers import AutoTokenizer
# 当想加载个人实现的分词器,需要trust_remote_code,配置文件里有配置的分词代码.py文件。
tokenizer = AutoTokenizer.from_pretrained("Skywork/Skywork-13B-base", trust_remote_code=True)
tokenizer.save_pretrained("skywork_tokenizer")
tokenizer = AutoTokenizer.from_pretrained("skywork_tokenizer", trust_remote_code=True)
tokenizer.decode(tokenizer.encode(sen))

如chatglm3-6b,除了模型文件外,还针对分词器写了tokenization_chatglm.py 文件。
当我们想加载这个分词器时,就必须 trust_remote_code=True

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>