主页

索引

模块索引

搜索页面

8.18. BPE

  • Byte-Pair Encoding(BPE)是一种常用于文本分词的算法,特别适用于自然语言处理中的子词级(subword-level)分词。

  • BPE 的核心思想是通过频率统计将频繁出现的字符或子词组合起来,以实现高效、紧凑的编码。

8.18.1. 核心流程

    1. 字符级初始化:开始时,将每个单词分解为单个字符的序列。例如,“hello” 可以表示为 [“h”, “e”, “l”, “l”, “o”]。

    1. 统计字符对的频率:统计数据集中所有字符对的频率(例如 “l”和“l”)出现的次数。字符对指的是在单词内相邻的字符组合。

    1. 合并频率最高的字符对:选择频率最高的字符对,将它们合并为一个新的“子词”单元。例如,如果 “l l” 是频率最高的组合,那么合并成 [“h”, “e”, “ll”, “o”]。

    1. 重复上述过程:继续统计频率最高的子词对,并重复合并操作,直到达到设定的子词单元数量,或无法继续合并为止。

    1. Start with all the characters present in the training corpus as tokens.

    1. Identify the most common pair of tokens and merge it into one token.

    1. Repeat until the vocabulary (e.g., the number of tokens) has reached the size we want.

  • 通过不断合并频繁出现的字符对或子词,BPE 会生成一套合并规则,这些规则可以应用于其他文本,使其能够通过 BPE 的方式进行分词。

8.18.2. 优点

  • 灵活性:它能够处理未见过的词汇(即没有在训练集中出现的词汇)——通过将词分解为已知的子词单元,BPE 能够较好地应对词汇的多样性。

  • 减少词汇表大小:通过子词级分词,BPE 可以有效减少词汇表的大小,同时保留高频词汇的完整性。

8.18.3. 演示示例

语料库:

"low", "lower", "newest", "wider"
  • 初始状态:每个单词分解为字符序列,如 [“l”, “o”, “w”]。

  • 第一次合并:假设频率最高的字符对是 “l o”,合并为 [“lo”, “w”]。

  • 第二次合并:如果下一步频率最高的对是 “lo w”,将其合并为一个新单元,依此类推。

8.18.4. 使用示例

from tokenizers import Tokenizer
from tokenizers.models import BPE
tokenizer = Tokenizer(BPE(unk_token="[UNK]"))

train our tokenizer on the wikitext files:

from tokenizers.trainers import BpeTrainer
trainer = BpeTrainer(special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"])
from tokenizers.pre_tokenizers import Whitespace
tokenizer.pre_tokenizer = Whitespace()

files = [f"data/wikitext-103-raw/wiki.{split}.raw" for split in ["test", "train", "valid"]]
tokenizer.train(files, trainer)

8.18.5. 使用场景

BPE 分词算法被广泛应用在许多 NLP 模型中,例如 GPT 系列、BERT 等,它们在词汇丰富的语言上能够提供较好的表现,避免了大规模词典的使用成本,同时提升了对未见词汇的适应性。

主页

索引

模块索引

搜索页面