Byte-Pair Encoding/zh

    From Marovi AI
    This page is a translated version of the page Byte-Pair Encoding and the translation is 100% complete.
    Other languages:
    Article
    Topic area Natural Language Processing
    Prerequisites Tokenization, Language Model


    概述

    字节对编码(Byte-Pair Encoding, BPE)是一种子词分词算法,它通过在训练语料中反复合并最频繁的相邻符号对来构建词表。该方法最初由 Philip Gage 于 1994 年作为数据压缩技术提出,2015 年由 Sennrich、Haddow 和 Birch 改造用于神经机器翻译,此后成为现代语言模型(包括 GPT 系列、RoBERTa 以及众多开源大型语言模型)的基础组件。[1] BPE 在两种分词极端之间取得平衡:词级词表存在词表外(OOV)问题且嵌入表过大,而字符级词表则会产生过长的序列和较弱的归纳偏置。通过学习一个固定规模的子词单元词表来覆盖任意输入字符串而不产生未知词元,BPE 实现了跨语言和跨领域的高效开放词表建模。

    背景与动机

    早期的神经序列模型依赖于词级词表,通常上限为 3 万至 10 万个条目。超出该集合的单词会被替换为 <UNK> 令牌,从而丢失信息。这对形态丰富的语言、技术领域和稀有命名实体尤其有害。字符级模型完全避免了未知令牌的问题,但需要更长的序列,并迫使模型从零开始重新学习高频词模式。

    子词分词提供了一种折中方案。其直觉是:频繁出现的单词应保留为完整的令牌,而稀有单词则被分解为有意义的子词单元,如词素或词干。例如,"tokenization" 可被切分为 "token" 和 "ization",从而让模型与 "tokenize" 或 "modernization" 等相关形式共享表示。BPE 提供了一种简单的、数据驱动的方法,无需语言学监督即可找到这样的词表。

    算法

    BPE 的训练从一个基础词表开始,该词表包含语料中出现的所有字符(或所有字节)。每个单词被表示为这些基础符号的序列,通常带有词尾标记(如 </w>)以区分词内片段和词末片段。随后训练过程反复执行同一个操作:在整个语料中统计每个相邻符号对的频次,找出最频繁的一对,并将其合并为一个新符号加入词表。

    形式上,记 $ V_0 $ 为初始字符词表,$ C $ 为预分词后的单词的多重集,其中每个单词表示为一个符号序列。在第 $ t $迭代时,BPE 选择如下的符号对

    $ {\displaystyle (a^{*}, b^{*}) = \arg\max_{(a, b)} \; \mathrm{count}(a, b \mid C, V_{t-1})} $

    并构造新的符号 $ ab $$ C $ 中每一处相邻对 $ (a, b) $ 的出现都会被替换为 $ ab $,同时该合并规则被追加到一个有序的合并列表中。该过程持续进行,直到词表达到目标规模,通常介于 8 000 至 100 000 个令牌之间。训练的输出包含两件产物:最终词表和有序的合并规则列表。

    一个简短的示例可以说明其动态。假设语料中包含单词 "low"、"lower"、"newest" 和 "widest",其频次使得在初始化步骤之后 "es" 成为最常见的相邻对。BPE 首先将 "e" + "s" 合并为 "es",随后可能将 "es" + "t" 合并为 "est",并继续进行。经过若干次迭代后,"est"、"er" 等常见后缀以单个令牌的形式出现,而较稀有的形式仍保持分段状态。

    推理时的分词

    训练完成后,BPE 以确定性方式对新字符串进行分词。先将字符串切分为基础符号,然后按学习顺序依次应用合并规则。每一步中,算法寻找仍然适用的、已学习索引最小的合并规则,执行该规则,并不断重复,直到没有规则适用为止。给定合并列表后,所产生的令牌序列是唯一的。

    这种贪心、按优先级排序的应用方式使 BPE 编码既快速又可复现。实用实现使用以合并秩为键的优先队列,可在输入长度上达到近似线性的时间复杂度。一个微妙的结果是:除非预分词器进行规范化,否则 BPE 的分词对空白字符和大小写并非不变。包括 GPT-2 及后续模型在内的大多数现代分词器都保留大小写,并将前导空格表示为特殊字符(通常为 Ġ),因此 "the" 和 " the" 会被映射到不同的令牌。

    字节级 BPE

    字符级 BPE 的一个实际问题在于其基础词表依赖于训练语料。新语言或不常见的 Unicode 码位可能在推理时产生未知字符。随 GPT-2 引入的字节级 BPE 通过将输入视为 UTF-8 字节序列而非字符序列来规避这一问题。[2] 其基础词表固定为 256 个字节值,从而保证任意输入字符串均可被表示。字节级 BPE 完全消除了未知令牌,并能统一地处理表情符号、代码和多语言文本。当代大多数大型语言模型都采用这一变体。

    其代价是非拉丁文字在字节层面上的编码效率较低。单个汉字可能占用三个 UTF-8 字节,并需要多次合并才能整合,从而导致这些语言产生更长的令牌序列和更高的推理成本。当跨语言公平性成为目标时,有时会更倾向于使用 Unigram 模型的 SentencePiece

    与其他子词方法的比较

    WordPiece 用于 BERT,与 BPE 密切相关,但其合并选择依据似然准则而非纯频次。每一步中,WordPiece 选择其合并能在一元语言模型假设下最大化训练语料似然的符号对。在实践中,WordPiece 与 BPE 产生的词表相似,二者的取舍通常是工具链偏好问题。

    用于 SentencePieceT5 系列的一元语言模型分词器采用不同的方法。它从一个较大的候选词表开始,逐步剪除令牌以最大化语料似然,从而产生概率性切分,并通过采样支持子词正则化。此外,SentencePiece 将空白视作普通字符,允许在没有语言特定预分词规则的前提下实现端到端的分词。

    与字符级模型相比,BPE 产生的序列更短,并具有更强的词级先验。与词级模型相比,它消除了未知令牌,并在形态相关的形式之间共享参数。所得词表在不同领域具有良好的泛化能力,并已被证明是 Transformer 架构占主导地位的稳健选择。

    实现考量

    一种朴素的 BPE 实现会在每次合并后重新统计所有符号对的频次,其复杂度对词表规模呈平方级。Hugging Face Tokenizers 和 OpenAI tiktoken 等生产实现使用增量数据结构,每次合并后仅更新受影响的对,将训练时间降至与语料规模近似线性。对于推理,得益于精心实现的 Rust 或 C++ 代码,现代库可在每个 CPU 核心上达到每秒数百万个令牌的吞吐量。

    分词的选择十分重要。大多数 BPE 流水线在应用合并之前会按空白字符和标点对文本进行切分,从而防止令牌跨越词边界。具体的规则集合(包括如何处理数字、缩写和标点)在不同模型间各异,且很少有详细记录,这使得精确复现一个分词器并非易事。因此,已发布的模型通常会将合并列表与预分词器的正则表达式作为冻结产物一并发布。

    局限性与权衡

    BPE 是一种基于频次的贪心启发式方法,没有显式的语言学目标。它可能产生反直觉的切分,尤其是在低频形态变体上,并且对训练语料的组成较为敏感。在网络文本上训练得到的词表,对医学或法律文本的切分往往次优,会导致序列变长并降低下游性能,除非进行适配或词表扩展。

    BPE 编码的确定性也被认为是语言模型中隐性偏置的一个来源。由于数字是按训练语料中的频次而非数位位置进行合并的,同一个数字可能在不同上下文中被分词成不同形式,这会使算术推理变得复杂。近期的模型已开始采用按位的分词作为部分补救方案。

    最后,BPE 对每个字符串只提供一种规范的切分,这限制了模型在训练过程中接触到的替代分析。子词正则化技术,如 BPE dropout,会在训练时随机跳过部分合并,使模型见到多种合理切分,从而提升鲁棒性[3]

    参考文献

    1. Sennrich, R., Haddow, B., and Birch, A., "Neural Machine Translation of Rare Words with Subword Units," ACL 2016.
    2. Radford, A. et al., "Language Models are Unsupervised Multitask Learners," OpenAI 2019.
    3. Provilkov, I., Emelianenko, D., and Voita, E., "BPE-Dropout: Simple and Effective Subword Regularization," ACL 2020.