【HuggingFace Transformer库学习笔记】基础组件学习:Tokenizer

news2024/10/6 4:10:29

基础组件——Tokenizer

在这里插入图片描述
在这里插入图片描述

(1)模型加载

from transformers import AutoTokenizer

sen = "弱小的我也有大梦想!"
# 从HuggingFace加载,输入模型名称,即可加载对于的分词器
tokenizer = AutoTokenizer.from_pretrained("model/robert-base-chinese-extractive-qa")
tokenizer

BertTokenizerFast(name_or_path='model/robert-base-chinese-extractive-qa', vocab_size=21128, model_max_length=512, is_fast=True, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}, clean_up_tokenization_spaces=True),  added_tokens_decoder={
	0: AddedToken("[PAD]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	100: AddedToken("[UNK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	101: AddedToken("[CLS]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	102: AddedToken("[SEP]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	103: AddedToken("[MASK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
}

保存到本地

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

('./roberta_tokenizer/tokenizer_config.json',
 './roberta_tokenizer/special_tokens_map.json',
 './roberta_tokenizer/vocab.txt',
 './roberta_tokenizer/added_tokens.json',
 './roberta_tokenizer/tokenizer.json')

加载本地中保存的tokenizer

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

BertTokenizerFast(name_or_path='./roberta_tokenizer/', vocab_size=21128, model_max_length=512, is_fast=True, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}, clean_up_tokenization_spaces=True),  added_tokens_decoder={
	0: AddedToken("[PAD]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	100: AddedToken("[UNK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	101: AddedToken("[CLS]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	102: AddedToken("[SEP]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	103: AddedToken("[MASK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
}

(2)句子分词

# 会将之前输入的文本,拆分成字典中对应的字词
tokens = tokenizer.tokenize(sen)			# 将sen输入给tokenizer
tokens      # 如果词表中没有对应的词,就会变成[UNK]

['弱', '小', '的', '我', '也', '有', '大', '梦', '想', '!']

(3)查看字典

tokenizer.vocab

{'##曄': 16334,
 '##絡': 18238,
 '##啼': 14639,
 '瞬': 4746,
 '##推': 16029,
 '##蔥': 18977,
 '沂': 3752,
 '嘘': 1656,
 '苜': 5730,
 '##即': 14372,
 '徉': 2524,
 'carlo': 12628,
 '##歙': 16686,
 '飛': 7606,
 '##ᵘ': 13495,
 '##蜊': 19106,
 '##85': 9169,
 '##页': 20609,
 '##ved': 11667,
 'lonzo': 12688,
 '旋': 3181,
 '##count': 12369,
 '狼': 4331,
 '次': 3613,
 '话': 6413,
...
 '1936': 9481,
 '小': 2207,
 '宜': 2139,
 '##獄': 17409,
 ...}

查看词表大小

# 查看词表大小
tokenizer.vocab_size

21128

(4)索引转换

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

[2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106]

转换成token

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

转换为string

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

简洁的一步实现方式:

# 将字符串转换为id序列,又称之为编码
ids = tokenizer.encode(sen, add_special_tokens=True)        # add_special_tokens=False时候,不显示加入标签后的id
ids     # 这个id和之前的id前后分别多了一个101和102,是因为BERT在句子前后加了标志标签

[101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102]

解码

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

'[CLS] 弱 小 的 我 也 有 大 梦 想! [SEP]'

(5)填充与截断

# 填充
ids = tokenizer.encode(sen, padding="max_length", max_length=15)        # 填充到最大长度15
ids

[101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0]
# 截断
ids = tokenizer.encode(sen, max_length=5, truncation=True)
ids     # 保留了头尾标签和从前到后的三个词

[101, 2483, 2207, 4638, 102]

(6)其他输入部分

# 先重新进行填充
ids = tokenizer.encode(sen, padding="max_length", max_length=15)
ids

[101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0]
# attention_mask:标记哪些部分是真实输入,哪些部分是填充
attention_mask = [1 if idx != 0 else 0 for idx in ids]      # tokenizer中不为0时候,将其记录为1,标记为真实填充
# token_type_ids:用来区别哪个部分是第一个句子,哪个部分是第二个句子
token_type_ids = [0] * len(ids) 
ids, attention_mask, token_type_ids

([101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

* 使用函数,直接快速调用

inputs = tokenizer.encode_plus(sen, padding="max_length", max_length=15)        # 直接调用库实现上面功能
inputs

{'input_ids': [101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0], 'token_type_ids': [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, 0, 0, 0]}
inputs = tokenizer(sen, padding="max_length", max_length=15)            # 直接调用tokenizer结果也一样
inputs

{'input_ids': [101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0], 'token_type_ids': [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, 0, 0, 0]}

(7)处理batch数据

sens = ["弱小的我也有大梦想",
        "有梦想谁都了不起",
        "追逐梦想的心,比梦想本身,更可贵"]
res = tokenizer(sens)
res

{'input_ids': [[101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 102], [101, 3300, 3457, 2682, 6443, 6963, 749, 679, 6629, 102], [101, 6841, 6852, 3457, 2682, 4638, 2552, 8024, 3683, 3457, 2682, 3315, 6716, 8024, 3291, 1377, 6586, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]}

测试循环耗时

%%time          
# 该指令可计算cell的处理时间
# 单条循环处理
for i in range(1000):
    tokenizer(sen)

CPU times: user 117 ms, sys: 0 ns, total: 117 ms
Wall time: 258 ms    

测试矩阵运算耗时

%%time
# 处理batch数据
res = tokenizer([sen] * 1000)       # 数据只需要进行tokenizer的时候,以batch方式去处理,速度最快

CPU times: user 90 ms, sys: 20.3 ms, total: 110 ms
Wall time: 30.2 ms

可以发现采用矩阵运算花费事件远小于循环事件

tokenizer

BertTokenizerFast(name_or_path='./roberta_tokenizer/', vocab_size=21128, model_max_length=512, is_fast=True, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}, clean_up_tokenization_spaces=True),  added_tokens_decoder={
	0: AddedToken("[PAD]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	100: AddedToken("[UNK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	101: AddedToken("[CLS]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	102: AddedToken("[SEP]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	103: AddedToken("[MASK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
}

* Fast/slow Tokenizer组件

在这里插入图片描述
默认加载

sen = "弱小的我也有大Dreaming!"

# 默认方式创建下,为fast,即use_fast=True
fast_tokenizer = AutoTokenizer.from_pretrained("/u01/zhanggaoke/project/transformers-code-master/model/roberta-base-finetuned-dianping-chinese")
fast_tokenizer


DistilBertTokenizerFast(name_or_path='/u01/zhanggaoke/project/transformers-code-master/model/roberta-base-finetuned-dianping-chinese', vocab_size=30522, model_max_length=512, is_fast=True, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}, clean_up_tokenization_spaces=True),  added_tokens_decoder={
	0: AddedToken("[PAD]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	100: AddedToken("[UNK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	101: AddedToken("[CLS]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	102: AddedToken("[SEP]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	103: AddedToken("[MASK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
}

加载use_fast=False

slow_tokenizer = AutoTokenizer.from_pretrained("/u01/zhanggaoke/project/transformers-code-master/model/roberta-base-finetuned-dianping-chinese", use_fast=False)
slow_tokenizer
 
 
DistilBertTokenizer(name_or_path='/u01/zhanggaoke/project/transformers-code-master/model/roberta-base-finetuned-dianping-chinese', vocab_size=30522, model_max_length=512, is_fast=False, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}, clean_up_tokenization_spaces=True),  added_tokens_decoder={
	0: AddedToken("[PAD]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	100: AddedToken("[UNK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	101: AddedToken("[CLS]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	102: AddedToken("[SEP]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
	103: AddedToken("[MASK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
}

处理时间对比

%%time
# 单条循环处理
for i in range(10000):
    fast_tokenizer(sen)


CPU times: user 729 ms, sys: 11 ms, total: 740 ms
Wall time: 774 ms    
%%time
# 单条循环处理
for i in range(10000):
    slow_tokenizer(sen)     
# 可以发现slow的方法比fast慢的多    


CPU times: user 1.74 s, sys: 0 ns, total: 1.74 s
Wall time: 1.75 s

批处理测试

%%time
# 处理batch数据
res = fast_tokenizer([sen] * 10000)

CPU times: user 1.91 s, sys: 195 ms, total: 2.11 s
Wall time: 319 ms
%%time
# 处理batch数据
res = slow_tokenizer([sen] * 10000)

CPU times: user 1.44 s, sys: 15.6 ms, total: 1.46 s
Wall time: 1.45 s

fast_tokenizer中专用的分词方式

# fast中offset_mapping,其中(0, 0)为首尾标记
inputs = fast_tokenizer(sen, return_offsets_mapping=True)
inputs

{'input_ids': [101, 100, 1829, 1916, 1855, 1750, 1873, 1810, 12802, 999, 102], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'offset_mapping': [(0, 0), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 15), (15, 16), (0, 0)]}
# 将词token去id化,其中None为首尾标记
inputs.word_ids()

[None, 0, 1, 2, 3, 4, 5, 6, 7, 8, None]

* 远程加载

from transformers import AutoTokenizer

# 当我们想要加载chatglm-6b远程代码库里的分词器时候,需要设置trust_remote_code=True
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True)       
tokenizer.save_pretrained("chatglm_tokenizer")
tokenizer = AutoTokenizer.from_pretrained("chatglm_tokenizer", trust_remote_code=True)
tokenizer.decode(tokenizer.encode(sen))

'弱小的我也有大Dreaming!'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1276997.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构:图文详解单链表的各种操作(头插法,尾插法,任意位置插入,删除节点,查询节点,求链表的长度,清空链表)

目录 一.什么是链表 二.链表的实现 节点的插入 头插法 尾插法 指定位置插入 节点的删除 删除第一次出现的关键字节点 删除所有关键字节点 节点的查找 链表的清空 链表的长度 前言:在上一篇文章中,我们认识了线性数据结构中的顺序表&#xff0…

CKafka 一站式搭建数据流转链路,助力长城车联网平台降低运维成本

关于长城智能新能源 长城汽车是一家全球化智能科技公司,业务包括汽车及零部件设计、研发、生产、销售和服务,旗下拥有魏牌、哈弗、坦克、欧拉及长城皮卡。2022年,长城汽车全年销售1,067,523辆,连续7年销量超100万辆。长城汽车面向…

兼容jlink OB arm仿真器使用(杜邦线过长导致烧写总是失败)

一、兼容jlink OB的使用: 1、设置中要选择jlink; 2、模式选择SWD模式(接三根线); 二、杜邦线过长导致stm32的stlink烧写总是失败 用ST-link烧写提示的错误信息有: Error while accessing a target reso…

【开源】基于Vue和SpringBoot的快递管理系统

项目编号: S 007 ,文末获取源码。 \color{red}{项目编号:S007,文末获取源码。} 项目编号:S007,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快…

思维模型 逆向思维

本系列文章 主要是 分享 思维模型,涉及各个领域,重在提升认知。弱者道之用反者道之动。 1 逆向思维的应用 1.1 历史典故 1 曹冲称象 这个故事讲述的是曹操的儿子曹冲如何利用逆向思维解决了称大象重量的难题。曹冲没有直接去称大象的重量,…

图解「差分」入门(“前缀和“ 到 “差分“ 丝滑过渡)

题目描述 这是 LeetCode 上的 「1094. 拼车」 ,难度为 「中等」。 Tag : 「差分」、「前缀和」 车上最初有 capacity 个空座位,车只能向一个方向行驶(不允许掉头或改变方向)。 给定整数 capacity 和一个数组 trips, 表示第 i 次旅…

神经网络 表述(Neural Networks: Representation)

神经网络 表述(Neural Networks: Representation) 1 非线性假设 我们之前学的,无论是线性回归还是逻辑回归都有这样一个缺点,即:当特征太多时,计算的负荷会非常大。 下面是一个例子: 当我们使用 x 1 x_1 x1​, x 2…

Docker下安装Tomcat

目录 Tomcat简介 Tomcat安装 免修改版Tomcat安装 Tomcat简介 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持&#x…

C++算法入门练习——最短路径-多路径

现有一个共n个顶点(代表城市)、m条边(代表道路)的无向图(假设顶点编号为从0到n-1),每条边有各自的边权,代表两个城市之间的距离。求从s号城市出发到达t号城市的最短路径条数和最短路…

almalinux centos8系统zlmediakit编译安装

脚本 # 安装依赖 gcc-c.x86_64 这个不加的话会有问题, cmake需要在线安装 sudo yum -y install gcc gcc-c libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg git openssl-devel gcc-c.x86_64 cmake mkdir -p /home/zenglg cd /home/zenglg git clon…

linux 手动安装移植 haveged,解决随机数初始化慢的问题

文章目录 1、问题描述2、安装 haveged3、问题解决4、将安装好的文件跟库移植到开发板下 Haveged是一个软件工具,用于生成高质量的熵(Entropy)源,以供计算机系统使用。熵在计算机科学中指的是一种随机性或不可预测性的度量&#xf…

JavaScript 数据结构

JavaScript 数据结构 目录 JavaScript 数据结构 一、标识符 二、关键字 三、常量 四、变量 每一种计算机编程语言都有自己的数据结构,JavaScript脚本语言的数据结构包括:标识符、常量、变量、保留字等。 一、标识符 标识符,说白了&…

【数据结构】拆分详解 - 堆

文章目录 前言一、堆是什么?二、堆的接口实现(以小堆为例)  0.声明  1. 创建,初始化  2. 销毁  3. 插入   3.1  向上调整 4. 删除   4.1 向下调整 5. 获取堆顶元素值  6. 获取有效元素个数  7. 判断是否为空 …

一线大厂Redis高并发缓存架构(待完善)

场景1:秒杀库存场景, 10000人抢100个商品 如果用普通的分布式锁实现, 最后抢到的人,要等前面99个人抢完 优化方案:可用分段锁, 降低锁的粒度, 比如1-10库存用锁product:101_1,11-20库存用锁pr…

电梯导航的小练习

目录 css代码 html代码 js代码 完整代码 效果图 需求&#xff1a;点击某个模块&#xff0c;显示对应内容 css代码 <style>*{padding: 0;margin: 0;list-style: none;}ul{display: flex;justify-content: center;position: fixed;top: 0;left: 20%;}ul>li{text-…

【解决方案】基于物联网表计的综合能源管理方案

安科瑞顾强 为加快推进国家“双碳”战略和新型能源体系建设&#xff0c;努力实现负荷准确控制和用户精细化管理&#xff0c;按照“政府主导、电网组织、政企协同、用户实施”的指导原则&#xff0c;多地成立市/县级电力负荷管理中心&#xff0c;包括浙江宁波、慈溪、辽宁大连、…

git的相关实用命令

参看文章&#xff1a;https://blog.csdn.net/qq_21688871/article/details/130158888 http://www.mobiletrain.org/about/BBS/159885.html 1、git commit后&#xff0c;但发现文件有误&#xff0c;不想push(提交到本地库&#xff0c;回退到暂存区&#xff09; git reset --sof…

sd_webui的实用插件,prompt/lama/human matting/...

热烈欢迎大家在git上star&#xff01;&#xff01;&#xff01;冲鸭&#xff01;&#xff01;&#xff01; 1.prompt优化插件 GitHub - leeguandong/sd_webui_beautifulprompt: beautifulprompt extension performs stable diffusion automatic prompt engineering on a bro…

LLM;超越记忆《第 2 部分 》

一、说明 在这篇博客中&#xff0c;我深入研究了将大型语言模型&#xff08;LLM&#xff09;提升到基本记忆之上的数学框架。我们探索了动态上下文学习、连续空间插值及其生成能力&#xff0c;揭示了 LLM 如何理解、适应和创新超越传统机器学习模型。 LLM代表了人工智能的重大飞…

集简云语聚AI新增模型测试,支持多模型同时进行交互,快速评估不同模型性能

语聚AI模型测试 在ChatGPT爆火的推动下&#xff0c;由生成式 AI 掀起的全球人工智能新浪潮就此拉开了序幕&#xff0c;人工智能也成为越来越多企业提升业务效率、优化业务流程的首选方案。 然而&#xff0c;面对层出不穷的AI模型&#xff0c;每个模型在完善度、功能性、易用性…