BPE、Wordpiece、Unigram、SpanBERT等Tokenizer细节总结

BPE(Byte Pair Encoding)

GPT-2和Roberta用的是这种,不会产生[UNK]这个unknown字符

这部分部分摘录自https://martinlwx.github.io/zh-cn/the-bpe-tokenizer/

看以下code例子就足够理解了,核心是维护self.merges(维护一个pair->str的字典)和self.vocab(每次挑最高频的pair加入self.vocab)做训练,每次刷新一遍最新的self.splits,具体格式参考注释:

from collections import defaultdict, Counter
from pprint import pprint
from typing import Listclass BPE:def __init__(self, corpus: List[str], vocab_size: int, max_iter: int, debug: bool, ):self.corpus = corpusself.vocab_size = vocab_sizeself.vocab = []self.word_freq = Counter()self.splits = {}  # 格式:highest: [high, est</w>]self.merges = {}  # 格式:[high, est</w>]: highestself.max_iter = max_iterself.debug = debugdef train(self):"""Train a BPE Tokenizer"""# count the word frequencyfor document in self.corpus:words = document.split() #按照空格等whitespae进行splitself.word_freq += Counter(words)# initialize the self.splitsfor word in self.word_freq:self.splits[word] = list(word) + ["</w>"]if self.debug:print(f"Init splits: {self.splits}")alphabet = set()for word in self.word_freq:alphabet |= set(list(word))alphabet.add("</w>")self.vocab = list(alphabet)self.vocab.sort()cnt = 0while len(self.vocab) < self.vocab_size:if self.max_iter and cnt >= self.max_iter:breakpair_freq = self.get_pairs_freq() #格式为 {('a','b'):3,('c','d'),5}if len(pair_freq) == 0:print("No pair available")breakpair = max(pair_freq, key=pair_freq.get) #输出值最大的keyself.update_splits(pair[0], pair[1])if self.debug:print(f"Updated splits: {self.splits}")self.merges[pair] = pair[0] + pair[1]self.vocab.append(pair[0] + pair[1])if self.debug:print(f"Most frequent pair({max(pair_freq.values())} times) "f"is : {pair[0]}, {pair[1]}. Vocab size: {len(self.vocab)}")cnt += 1def update_splits(self, lhs: str, rhs: str):"""If we see lhs and rhs appear consecutively, we merge them"""for word, word_split in self.splits.items():new_split = []cursor = 0while cursor < len(word_split):if (word_split[cursor] == lhs and cursor + 1 < len(word_split) and word_split[cursor + 1] == rhs):new_split.append(lhs + rhs)cursor += 2else:new_split.append(word_split[cursor])cursor += 1self.splits[word] = new_splitdef get_pairs_freq(self) -> dict:"""Compute the pair frequency"""pairs_freq = defaultdict(int)for word, freq in self.word_freq.items():split = self.splits[word]for i in range(len(split)):if i + 1 < len(split):pairs_freq[(split[i], split[i + 1])] += freqreturn pairs_freqdef tokenize(self, s: str) -> List[str]:splits = [list(t) + ["</w>"] for t in s.split()]for lhs, rhs in self.merges:for idx, split in enumerate(splits):new_split = []cursor = 0while cursor < len(split):if (cursor + 1 < len(split) and split[cursor] == lhs and split[cursor + 1] == rhs):new_split.append(lhs + rhs)cursor += 2else:new_split.append(split[cursor])cursor += 1assert "".join(new_split) == "".join(split)splits[idx] = new_split# splits是二维数组,最终拼成一维return sum(splits, [])corpus = ["highest", "higher", "lower", "lowest", "cooler", "coolest"]bpe = BPE(corpus, vocab_size=17, debug=True, max_iter=100)
bpe.train()
print('---------------output of tokenize---------------')
print(bpe.tokenize(" ". join(corpus)))
'''
Init splits: {'highest': ['h', 'i', 'g', 'h', 'e', 's', 't', '</w>'], 'higher': ['h', 'i', 'g', 'h', 'e', 'r', '</w>'], 'lower': ['l', 'o', 'w', 'e', 'r', '</w>'], 'lowest': ['l', 'o', 'w', 'e', 's', 't', '</w>'], 'cooler': ['c', 'o', 'o', 'l', 'e', 'r', '</w>'], 'coolest': ['c', 'o', 'o', 'l', 'e', 's', 't', '</w>']}
Updated splits: {'highest': ['h', 'i', 'g', 'h', 'es', 't', '</w>'], 'higher': ['h', 'i', 'g', 'h', 'e', 'r', '</w>'], 'lower': ['l', 'o', 'w', 'e', 'r', '</w>'], 'lowest': ['l', 'o', 'w', 'es', 't', '</w>'], 'cooler': ['c', 'o', 'o', 'l', 'e', 'r', '</w>'], 'coolest': ['c', 'o', 'o', 'l', 'es', 't', '</w>']}
Most frequent pair(3 times) is : e, s. Vocab size: 13
Updated splits: {'highest': ['h', 'i', 'g', 'h', 'est', '</w>'], 'higher': ['h', 'i', 'g', 'h', 'e', 'r', '</w>'], 'lower': ['l', 'o', 'w', 'e', 'r', '</w>'], 'lowest': ['l', 'o', 'w', 'est', '</w>'], 'cooler': ['c', 'o', 'o', 'l', 'e', 'r', '</w>'], 'coolest': ['c', 'o', 'o', 'l', 'est', '</w>']}
Most frequent pair(3 times) is : es, t. Vocab size: 14
Updated splits: {'highest': ['h', 'i', 'g', 'h', 'est</w>'], 'higher': ['h', 'i', 'g', 'h', 'e', 'r', '</w>'], 'lower': ['l', 'o', 'w', 'e', 'r', '</w>'], 'lowest': ['l', 'o', 'w', 'est</w>'], 'cooler': ['c', 'o', 'o', 'l', 'e', 'r', '</w>'], 'coolest': ['c', 'o', 'o', 'l', 'est</w>']}
Most frequent pair(3 times) is : est, </w>. Vocab size: 15
Updated splits: {'highest': ['h', 'i', 'g', 'h', 'est</w>'], 'higher': ['h', 'i', 'g', 'h', 'er', '</w>'], 'lower': ['l', 'o', 'w', 'er', '</w>'], 'lowest': ['l', 'o', 'w', 'est</w>'], 'cooler': ['c', 'o', 'o', 'l', 'er', '</w>'], 'coolest': ['c', 'o', 'o', 'l', 'est</w>']}
Most frequent pair(3 times) is : e, r. Vocab size: 16
Updated splits: {'highest': ['h', 'i', 'g', 'h', 'est</w>'], 'higher': ['h', 'i', 'g', 'h', 'er</w>'], 'lower': ['l', 'o', 'w', 'er</w>'], 'lowest': ['l', 'o', 'w', 'est</w>'], 'cooler': ['c', 'o', 'o', 'l', 'er</w>'], 'coolest': ['c', 'o', 'o', 'l', 'est</w>']}
Most frequent pair(3 times) is : er, </w>. Vocab size: 17
['h', 'i', 'g', 'h', 'est</w>', 'h', 'i', 'g', 'h', 'er</w>', 'l', 'o', 'w', 'er</w>', 'l', 'o', 'w', 'est</w>', 'c', 'o', 'o', 'l', 'er</w>', 'c', 'o', 'o', 'l', 'est</w>']
'''

Wordpiece

这部分摘录自huggingface的教程 https://huggingface.co/learn/nlp-course/chapter6/6?fw=pt,Bert,DistilBERT, MobileBERT用的是这种

训练过程

Wordpiece和BPE的训练过程很像,区别在于两点:

  1. Wordpiece不再使用出现最高频的pair,而是用下面的score来筛选每一个pair
score=(freq_of_pair)/(freq_of_first_element×freq_of_second_element)
  1. Wordpiece不是在结尾填充</w>,而是把中间字符前填充##,例如“word”这个词会被分割成w,##o,##r,##d

Tokenize过程

  1. wordpiece没有像BPE一样存self.merge,而是只存了self.vocab,每次都是最长匹配
  2. wordpiece会给填充[UNK]的token,同时还有"[PAD]", “[UNK]”, “[CLS]”, “[SEP]”, "[MASK]"这些特殊token

Unigram

这部分摘录自https://huggingface.co/learn/nlp-course/chapter6/7?fw=pt,Unigram的基本思路用下面例子比较明显,其实就是把句子理解成了unigram的language model
在这里插入图片描述

HuggingFace的tokenizer梳理

这部分摘录自https://huggingface.co/docs/tokenizers/components#models,HF的Tokenizer分为以下几个components:
在这里插入图片描述

  • Normalization: 比如unicode转换、大小写转换
  • Pre-tokenizers:作用是splitting the input into words,比如ByteLevel, this technique as been introduced by OpenAI with GPT-2, a tokenizer using this only requires 256 characters as initial alphabet (the number of values a byte can have), as opposed to the 130,000+ Unicode characters.
  • Models:WordLevel、BPE、WordPiece和Unigram
  • post-processing:adding the special tokens of the tokenizer, generating the attention mask and token type IDs

Tokenizer的mask策略

部分转载自https://zhuanlan.zhihu.com/p/360982134

静态mask

输入时,随机遮盖或替换一句话里面任意字或词, 然后让模型通过上下文的理解预测那一个被遮盖或替换的部分, 之后做 的时候只计算被遮盖部分的 。

随机把一句话中 15% 的 替换成以下内容:

  1. 这些 有 80% 的几率被替换成 [ ];
  2. 有 10% 的几率被替换成任意一个其他的 ;
  3. 有 10% 的几率原封不动。

动态mask

RoBERTa中引入了动态mask的策略,原论文中将原始数据复制n份,每份都进行随机的静态mask,从而每份数据的mask结果都不太一样。huggingface中data collator使用的是动态mask,但不是复制数据,而是每一个epoch的mask策略都不同,这样就可以达到动态mask的效果了,从而使得每一个epoch的mask的情况都不同,更方便更胜内存。

whole word mask (wwm)和ernie

对于原始的 BERT,训练时,会随机选取整句中的最小输入单元 token 来进行遮盖。因为用到 Byte Pair Encoding (BPE)技术,所以也可以把这些最小单元当作是子词(subword),比如说superman,分成 super+man 两个子词。

但这样会让本来应该有强相关的一些连在一起的字词,在训练时是割裂开来的。

因此我们就会想到,那能不能遮盖掉这样连在一起的片段训练呢?当然可以。

首先想到的做法,既然现在遮盖子词,那能不能直接遮盖整个词,比如说对于 super + man,只要遮盖就两个同时遮盖掉,这便是 Google 放出的 BERT WWM 模型所做的。

ERNIE类似的思路做了一些改进:
– Basic-Level Masking: 跟bert一样对单字进行mask,很难学习到高层次的语义信息;
– Phrase-Level Masking: 输入仍然是单字级别的,mask连续短语;
– Entity-Level Masking:首先进行实体识别,然后将识别出的实体进行mask。

n-gram mask

使用n-gram(uni-gram,bi-gram, tri-gram)来做MLM任务,,即以不同的概率使用n-gram,其中 uni-gram的概率最大,bi-gram其次,tri-gram概率最小。和下面的span有一些类似。

random span mask

在这里插入图片描述

来自于论文SpanBERT: Improving Pre-training by Representing and Predicting Spans
大体过程是,对一个句子X = (x1, x2, . . . , xn), 我们选取它的一个子序列(span)进行mask。通过不断地选取span,直到选够了X中15%的token。选取的方法是,首先通过几何分布选取span的长度L,(均匀分布采样应该大家都比较熟悉,对于不均匀的分布进行采样,简单的方式是将概率进行展平然后转化为均匀分布采样的问题,例如 0.6,0.3,0.2,0.1这样的分布,可以统一切割为6,3,2,1个0.1,然后均匀采样即可,当然按照0.01之类的来进行切割也是可以的)然后,均匀随机地选取span的起始位置。选取长度时,官方的设置是 L ∼Geo(0.2),同时裁剪L使Lmax=10,于是span长度的分布如下,平均值为3.8。span masking,指的是对span中的每一个token都替换成[MASK]。

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

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

相关文章

[蓝桥杯2024]-Reverse:rc4解析(对称密码rc4)

无壳 查看ida 这里应该运行就可以得flag&#xff0c;但是这个程序不能直接点击运行 按照伪代码写exp 完整exp&#xff1a; keylist(gamelab) content[0xB6,0x42,0xB7,0xFC,0xF0,0xA2,0x5E,0xA9,0x3D,0x29,0x36,0x1F,0x54,0x29,0x72,0xA8, 0x63,0x32,0xF2,0x44,0x8B,0x85,0x…

如何在 Visual Studio 中通过 NuGet 添加包

在安装之前要先确定Nuget的包源是否有问题。 Visual Studio中怎样更改Nuget程序包源-CSDN博客 1.图形界面安装 打开您的项目&#xff0c;并在解决方案资源管理器中选择您的项目。单击“项目”菜单&#xff0c;然后选择“管理 NuGet 程序包”选项。在“NuGet 包管理器”窗口中…

详解如何品味品深茶的精髓

在众多的茶品牌中&#xff0c;品深茶以其独特的韵味和深厚的文化底蕴&#xff0c;赢得了众多茶友的喜爱。今天&#xff0c;让我们一同探寻品深茶的精髓&#xff0c;品味其独特的魅力。 品深茶&#xff0c;源自中国传统茶文化的精髓&#xff0c;承载着世代茶人的智慧与匠心。这…

03-MVC执行流程-参数解析与Model

重要组件 准备Model&#xff0c;Controller Configuration public class WebConfig {ControllerAdvicestatic class MyControllerAdvice {ModelAttribute("b")public String bar() {return "bar";}}Controllerstatic class Controller1 {ResponseStatus(H…

windows环境下安装Apache

首先apache官网下载地址&#xff1a;http://www.apachelounge.com/download/按照自己的电脑操作系统来安装 这里我安装的是win64 主版本是2.4的apache。 然后解压压缩包到一个全英文的路径下&#xff01;&#xff01;&#xff01;一定一定不要有中文 中文符号也不要有&#xff…

ansible-copy用法

目录 概述实践不带目录拷贝带目录拷贝 概述 ansible copy 常用用法举例 不带目录拷贝&#xff0c;拷贝的地址要写全 带目录拷贝&#xff0c;拷贝路径不要写在 dest 路径中 实践 不带目录拷贝 # with_fileglob 是 Ansible 中的一个循环关键字&#xff0c;用于处理文件通配符匹…

【Vue3+Tres 三维开发】02-Debug

预览 介绍 Debug 这里主要是讲在三维中的调试,同以前threejs中使用的lil-gui类似,TRESJS也提供了一套可视化参数调试的插件。使用方式和之前的组件相似。 使用 通过导入useTweakPane 即可 import { useTweakPane, OrbitControls } from "@tresjs/cientos"const {…

数字文旅重塑旅游发展新格局:以数字化转型为突破口,提升旅游服务的智能化水平,为游客带来全新的旅游体验

随着信息技术的迅猛发展&#xff0c;数字化已成为推动各行各业创新发展的重要力量。在旅游业领域&#xff0c;数字文旅的兴起正以其强大的驱动力&#xff0c;重塑旅游发展的新格局。数字文旅以数字化转型为突破口&#xff0c;通过提升旅游服务的智能化水平&#xff0c;为游客带…

HarmonyOS Next从入门到精通实战精品课

第一阶段&#xff1a;HarmonyOS Next星河版从入门到精通该阶段由HarmonyOS Next星河版本出发&#xff0c;介绍HarmonyOS Next版本应用开发基础概念&#xff0c;辅助学员快速上手新版本开发范式&#xff0c;共计42课时 第一天鸿蒙NEXT Mac版、Windows版【编辑器】和【模拟器】&a…

BootStrap详解

Bootstrap简介 什么是BootStrap&#xff1f; BootStrap来自Twitter&#xff0c;是目前最受欢迎的响应式前端框Bootstrap是基于HTML、CSS、JavaScript的&#xff0c;它简洁灵活&#xff0c;使得Web开发更加快捷 为什么使用Bootstrap&#xff1f; 移动设备优先&#xff1a;自…

Kafka 3.x.x 入门到精通(07)——Java应用场景——SpringBoot集成

Kafka 3.x.x 入门到精通&#xff08;07&#xff09;——Java应用场景——SpringBoot集成 4. Java应用场景——SpringBoot集成4.1 创建SpringBoot项目4.1.1 创建SpringBoot项目4.1.2 修改pom.xml文件4.1.3 在resources中增加application.yml文件 4.2 编写功能代码4.2.1 创建配置…

机器人-轨迹规划

旋转矩阵 旋转矩阵--R--一个3*3的矩阵&#xff0c;其每列的值时B坐标系在A坐标系上的投影值。 代表B坐标系相对于A坐标系的姿态。 旋转矩阵的转置矩阵 其实A相对于B的旋转矩阵就相当于把B的列放到行上就行。 视频 &#xff08;将矩阵的行列互换得到的新矩阵称为转置矩阵。&…

SQLite尽如此轻量

众所周知&#xff0c;SQLite是个轻量级数据库&#xff0c;适用于中小型服务应用等&#xff0c;在我真正使用的时候才发现&#xff0c;它虽然轻量&#xff0c;但不知道它却如此轻量。 下载 官网&#xff1a; SQLite Download Page 安装 1、将下载好的两个压缩包同时解压到一个…

【PG-2】PostgreSQL存储管理器

2. PostgreSQL存储管理器 src/backend/storage (base) torrestorresの机革:~/codes/postgresql-16.2/src/backend/storage$ ls Makefile buffer file freespace ipc large_object lmgr meson.build objfiles.txt page smgr sync存储管理器—smgr 通用存储管理器 …

航拍图像拼接 | 使用C++实现的无人机航拍图像拼接

项目应用场景 面向无人机航拍图像拼接场景&#xff0c;项目使用 C 实现&#xff0c;使用 harris 角点查找特征点 非极大值抑制&#xff0c;由于航拍图像没有严重的尺度旋转变化&#xff0c;使用了 berief 描述子&#xff0c;然后使用 RANSAC 求 H&#xff0c;最后进行图像拼接…

linux 中 make 和 gmake的关系

1. 关系 gmake特指GNU make。 make是指系统默认的make实现; 在大多数Linux发行版中&#xff0c;make就是GNU make&#xff0c;但是在其他unix中&#xff0c;gmake可以指代make的某些其他实现&#xff0c;例如BSD make或各种商业unix的make实现。 gmake是GNU Make的缩写。 Linux…

【算法一则】【贪心】数组中的数可以拼装成的最大数

题目 给定一组非负整数 nums&#xff0c;重新排列每个数的顺序&#xff08;每个数不可拆分&#xff09;使之组成一个最大的整数。 注意&#xff1a;输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。 示例 1&#xff1a; 输入&#xff1a;nums [10,2] …

【UnityRPG游戏制作】RPG项目的背包系统商城系统和BOSS大界面

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

二分查找-在排序数组中查找元素的第一个和最后一个位置

给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 示例 输入&#xf…

程序链接步骤2:重定位

一、链接步骤 链接步骤1“符号解析”&#xff1a; 将符号引用和符号定义建立关联后&#xff1b; 链接步骤2“重定位”&#xff1a; 将引用符号的地址“重定位”为相关联的符号定义的地址。 二、原文链接&#xff1a;https://www.jianshu.com/p/7d13ec4735ba 符号解析完成后&…