本文将详述目前比较常用的subtokens算法——BPE(Byte-Pair Encoding) 现在性能比较好一些的NLP模型,例如GPT、BERT、RoBERTa等,在数据预处理的时候都会有WordPiece 的过程,其主要的实现方式就是BPE(Byte-Pair Encoding)。 BPE算法通过训练,能够把上面的3个单词拆分成["lov","ed","ing","es"]几部分,这样可以把词的本身的意思和时态分开,有效的减少了词表的数量。 epub/16457/pg16457.txt # vocab = get_vocab('pg16457.txt') print('==========') print('Tokens Before BPE 'w i d e s t </w>': 3} vocab = get_vocab('pg16457.txt') print('==========') print('Tokens Before BPE
2.2 Byte-level BPE Byte-level BPE(字节级字节对编码)是传统 BPE(Byte Pair Encoding)的一种改进变体,核心区别在于操作的基本单位从字符(Character 同时传统 BPE 在处理一些特殊字符如数学公式、拼写错误的词时,可能会被当作未知字符,进而导致信息丢失。 2.2.2 Byte-Level BPE 解决了哪些问题? 如果使用传统 BPE,那么当“栓”不在训练词表中,BPE 可能直接标记为,而 Byte-Level BPE 仍能保留部分信息。 同时,Byte-Level BPE 初始词表仅 256 个字节,远小于 BPE 的数千个字符(如中文 BPE 词表可能包含 5000+ 汉字),这样训练时内存占用更低,适合大规模语料。 2.2.3 Byte-Level BPE 的局限性 虽然 Byte-Level BPE 解决了 BPE 的许多问题,但仍有一些缺点: 可读性差:生成的 token 是字节序列(如 \xe4\xbd\xa0
为了解决这一问题,BPE算法应运而生。BPE算法是一种基于子词(subword)的分词方法,能够将单词分解成更小的子词单元,从而提高模型的泛化能力和灵活性。 BPE 算法的目标是构建一个子词词汇表 V,使得每个单词 w 可以被分割成子词单元 w=v1,v2,…,vm,其中 vi∈V。 另外,BPE可以用于中文,但需要针对中文的语言特性进行适配。 实际应用中,BPE常与预分词技术结合,或通过限制子词长度、调整合并优先级来平衡效率与语义完整性,在机器翻译、预训练模型(如中文BERT)等场景中已得到有效验证。 后台回复“BPE”可免费获得上述论文和代码
的解决方法粒度太细 Subword粒度在词与字符之间,能够较好的平衡OOV问题 话不多说,和小夕一起来看一下当下最热最火三个subword算法叭o(* ̄▽ ̄*)ブ Byte Pair Encoding BPE BPE实现 import re, collections def get_stats(vocab): pairs = collections.defaultdict(int) for “est</w>”, “moun”, “tain</w>”] # 解码序列 “the</w> highest</w> mountain</w>” WordPiece WordPiece算法可以看作是BPE
的解决方法粒度太细 Subword粒度在词与字符之间,能够较好的平衡OOV问题 话不多说,和小夕一起来看一下当下最热最火三个subword算法叭o(* ̄▽ ̄*)ブ Byte Pair Encoding BPE BPE实现 import re, collections def get_stats(vocab): pairs = collections.defaultdict(int) for “est</w>”, “moun”, “tain</w>”] # 解码序列 “the</w> highest</w> mountain</w>” WordPiece WordPiece算法可以看作是BPE
本文再详细解读一下 BPE 算法的 Rust 实现思路。 前 OpenAI 工程师 Karpathy 用 70 行纯 Python 编写了 最小化 BPE 算法实现:minbpe[1]。 对应于 Python 的: minbpe/base.py 功能描述: basic.rs: 实现了 BPE 算法的最简单形式,直接对文本进行处理。 为什么要实现字节级的 BPE ?有如下几个好处: 处理未知词(OOV, Out-Of-Vocabulary)问题。 字节级 BPE 允许通过合并频繁出现的字节对来动态构建词汇表,最终词汇表的大小是可控的,这对模型的效率和性能都有积极影响。 语言无关性。
昨天总结实验数据分析的时候发现一个机器翻译的其中的一个脚本,其中用到的算法就是BPE算法,刚开始感觉很高大上的,因为总是听到带上算法帽子的东西就觉得666。 总说 BPE,(byte pair encoder)字节对编码,也可以叫做digram coding双字母组合编码,主要目的是为了数据压缩,算法描述为字符串里频率最常见的一对字符被一个没有在这个字符中出现的字符代替的层层迭代过程
选自arXiv 作者:Toan Q Nguyen、David Chiang 机器之心编译 参与:李亚洲、路雪 在本论文中,作者结合迁移学习与 BPE 方法,使用低资源的相关语言的平行数据改进同样低资源语言的神经机器翻译结果 首先,我们使用 BPE(字节对编码)的方式分离单词来增加单词重复。然后,在第一种语言对上训练模型,将其参数(包括源词嵌入)迁移到另一个模型,再在第二种语言对上继续训练。 我们的实验证明,虽然 BPE 方法和迁移学习单独用的时候表现不一致,但一起用时能提高 1.8 个 BLEU 值。 ? 表 1:土耳其语与乌兹别克语中拥有同样词根的单词示例 ?
频率/概率:算法决策合并或保留 Token 的核心依据(BPE/WordPiece 侧重频率,Unigram 侧重概率)。二、BPE 分词1. 分词器 bpe_tokenizer = BPEChineseTokenizer(vocab_size=10) bpe_tokenizer.train(corpus) # 分词测试 初始化:和BPE一样,拆分为原子单元,统计 Token 频率;2. 分词:最长匹配,这一步也同BPE一样4. BPE 和 WordPiece 是 “自底向上合并”:从单字开始,BPE 合并高频字符对,WordPiece 则优先合并能提升文本似然性的组合,二者适合处理中文常用词,实现简单且效果稳定。
├──wmt16_ende_data # WMT16 英德翻译数据 ├──wmt16_ende_data_bpe # BPE 编码的 WMT16 英德翻译数据 编码的代码 另外我们也整理提供了一份处理好的 WMT'16 EN-DE 数据以供使用(包含训练所需 BPE 数据和词典以及预测和评估所需的 BPE 数据和 tokenize 的数据)。 # base model python -u infer.py \ --src_vocab_fpathgen_data/wmt16_ende_data_bpe/vocab_all.bpe.32000 \ /vocab_all.bpe.32000 \ --trg_vocab_fpathgen_data/wmt16_ende_data_bpe/vocab_all.bpe.32000 \ --special_token /vocab_all.bpe.32000\ --trg_vocab_fpathgen_data/wmt16_ende_data_bpe/vocab_all.bpe.32000 \ --special_token
有许多生成Subword的技术,例如Byte Pair Encoding(BPE)。 /learn_bpe.py -s 10000 <train.tok.file> codes.bpe # Apply the vocabulary to the training file . /apply_bpe.py -c codes.bpe < train.tok.file> train.tok.bpe 对数据集进行BPE后,句子可能如下所示。 id=0B_bZck-ksdkpM25jRUN2X2UxMm8) 将文件解压后,可以获得以下文件: 文件名 内容 train.tok.clean.bpe.32000.en 经过BPE处理后英语训练数据, train.tok.clean.bpe.32000.de 经过BPE处理后德语训练数据,每行一个句子。 vocab.bpe.32000 经过BPE处理后的词表,每行一个Token。
示例代码 use tokenizers::tokenizer::{Result, Tokenizer, EncodeInput}; use tokenizers::models::bpe::BPE; fn main() -> Result<()> { let bpe_builder = BPE::from_files(". ; let bpe = bpe_builder .dropout(0.1) .unk_token("[UNK]".into()) .build()? ; let mut tokenizer = Tokenizer::new(Box::new(bpe)); let encoding = tokenizer.encode(EncodeInput::Single
需求目标是:【用几万个英语句子构建一个自己的小语言模型】,重点是: 不需要大模型; 使用 BPE(Byte Pair Encoding)分词; 自己训练一个小模型,满足记忆/嵌入/生成这类任务; 训练自己的 BPE tokenizer(使用 tokenizers 库)。 对语料进行 BPE 编码。 构建用于训练的输入输出对(适配模型结构,比如 GPT-style)。 Step-by-Step 实现:训练自己的 BPE 分词器 + 训练输入数据我们用 HuggingFace 的 tokenizers 来训练 BPE 分词器。 import BpeTrainerfrom tokenizers.pre_tokenizers import Whitespace# 初始化 tokenizertokenizer = Tokenizer(BPE (unk_token="[UNK]"))tokenizer.pre_tokenizer = Whitespace()# BPE 训练器配置trainer = BpeTrainer( vocab_size
hpca.se <- HumanPrimaryCellAtlasData()save(hpca.se,file = 'hpca.RData')bpe.se <- BlueprintEncodeData( )save(bpe.se,file = 'bpe.RData')使用singleR自动注释参考了胃癌文献复现中对T细胞亚群细分注释的代码# singleR注释library(celldex)library 查看不同的参考数据库的注释信息#查看注释信息情况unique(hpca.se$label.main)unique(hpca.se$label.fine)unique(bpe.se$label.main) unique(bpe.se$label.fine)通过查看两个参考数据库的注释信息,hpca.se$label.fine相较于hpca.se$label.main会分的非常细致,甚至注明了DC细胞的起源 ,如果不需要这么细节那我们选取hpca.se$label.main即可同理可以看看bpe.se数据库的注释情况,选择需要的列作为我们的labels2.
Byte Pair Encoding (BPE) Unigram Language Model Subword Sampling BPE-dropout 字节对编码(BPE) Sennrich等。 以下是BPE算法获取子词的步骤。 BPE-dropout BPE-dropout是一种有效的基于BPE的子词正则化方法,它可以对特定词进行多次分割。这将使BPE词汇表和合并表保持原始,同时更改分段过程。 如果概率为零,则子词分割等于原始BPE。如果概率为1,则子词分割等于字符分割。如果概率从0变到1,它将给出具有不同粒度的多个细分。由于此方法将模型暴露于各种子词分割中,因此可以更好地理解词和子词。 BPE删除是一个简单的过程,因为无需训练即可进行训练,而无需训练除BPE之外的任何细分,并且推理使用标准BPE。 引用 R. Sennrich, B. Haddow, and A.
软连接基本命令:建立(mklink ),删除(rmdir); 基本场景: 1 将电脑F盘下目录bpe\source下文件aa.txt和文件夹bb通过软连接连接至目录bpe\dest下 1.1命令语句: mklink /J F:\bpe\dest\aa.txt F:\bpe\icc\source\aa.txt mklink /J F:\bpe\dest\bb F:\bpe\icc\source\bb 1.2执行结果: 2 删除软连接: 2.1 基本命令: rmdir F:\bpe\dest\aa.txt rmdir F:\bpe\dest\bb 2.2 执行结果
三、BPE算法 目前主流的 LLM 都基于 BPE算法(Byte-Pair Encoding,字节对编码)来实现分词器,如 OpenAI 的 GPT 模型。 按行拆分,过滤掉空行,得到 bpe_merges。 // 使用 dictZip 函数将 bpe_merges 和其索引创建一个字典 bpe_ranks。 = bpe_file .split(/\r? bpe_merges.length)); 分词器的核心是使用BPE算法不断合并出现最频繁的字符对,将输入的文本块转换为tokens,具体过程如下: // 假设输入的文本是"let" bpe(chunk
/vocab_all.bpe.32000 \
--trg_vocab_fpath gen_data/wmt16_ende_data_bpe/vocab_all.bpe.32000 \
--special_token '' '<e>' '<unk>' \
--train_file_pattern gen_data/wmt16_ende_data_bpe/train.tok.clean.bpe.32000. python -u infer.py \
--src_vocab_fpath gen_data/wmt16_ende_data_bpe/vocab_all.bpe.32000 \
--trg_vocab_fpath gen_data/wmt16_ende_data_bpe/newstest2016.tok.bpe.32000.en-de \
--token_delimiter ' ' \
--batch_size 对于使用 BPE 的英德数据,预测出的翻译结果也将是 BPE 表示的数据,所以需要还原成原始数据才能进行正确评估。
/vocab_all.bpe.32000 \
--trg_vocab_fpath gen_data/wmt16_ende_data_bpe/vocab_all.bpe.32000 \
--special_token '' '<e>' '<unk>' \
--train_file_pattern gen_data/wmt16_ende_data_bpe/train.tok.clean.bpe.32000. python -u infer.py \
--src_vocab_fpath gen_data/wmt16_ende_data_bpe/vocab_all.bpe.32000 \
--trg_vocab_fpath gen_data/wmt16_ende_data_bpe/newstest2016.tok.bpe.32000.en-de \
--token_delimiter ' ' \
--batch_size 对于使用 BPE 的英德数据,预测出的翻译结果也将是 BPE 表示的数据,所以需要还原成原始数据才能进行正确评估。
比如鸟(birds)这个词在德语里是Vögel,用意大利语是uccelli,用法语是oiseaux,西班牙语是pájaros,在CLIP模型使用byte pair encoding(BPE)算法对输入提示句进行分词后