在自然语言处理(NLP)中,BPE(Byte Pair Encoding,字节对编码)是子词分词的核心算法之一,其核心价值是解决 “基于词的分词” 的词汇外(OOV)问题和 “基于字符的分词” 的语义颗粒度不足问题,为语言模型提供更高效、更灵活的输入表示。它已成为现代 NLP 模型(尤其是 Transformer 架构系列)的标准预处理组件,具体使用场景、流程和典型案例如下:

一、BPE 在 NLP 中的核心使用场景

BPE 的设计初衷是平衡 “语义完整性” 和 “词汇表规模”,因此在需要处理多语言、罕见词、大规模文本的 NLP 任务中尤为重要,主要场景包括:

任务类型 核心需求 BPE 的作用
神经机器翻译(NMT) 处理源语言 / 目标语言中的罕见词(如专业术语、人名),避免翻译中断 将罕见词拆分为训练过的常见子词,让模型能基于子词推断语义,提升翻译准确性
大语言模型(LLM) 控制词汇表大小(避免百万级词表导致的参数爆炸),同时覆盖多语言 以字节为基础构建子词表,天然支持多语言(无需依赖特定语言词典),降低模型计算和内存开销
文本生成(如对话、摘要) 生成过程中避免出现 “未知词标记(<UNK>)”,保证输出流畅性 即使生成未见过的新词(如新兴网络用语),也能拆分为已知子词,减少<UNK>的出现
低资源语言处理 低资源语言语料少、词典不完善,易出现 OOV 问题 基于字节启动分词,无需预先构建词典,仅通过少量语料就能训练出覆盖核心语义的子词表

二、BPE 在 NLP 中的完整使用流程

BPE 在 NLP 中的使用分为训练阶段(构建子词表) 和推理阶段(分词) 两步,流程与原始算法一致,但会根据 NLP 任务进行适配(如添加特殊标记、调整合并策略)。

1. 训练阶段:为特定任务构建子词表

核心目标是从任务相关的大规模语料库中,学习高频子词组合,生成固定大小的子词表(如 32k、50k、100k 词表),步骤如下:

  1. 数据预处理

    • 收集任务语料(如翻译任务的双语语料、LLM 的多语言文本),进行清洗(去重、去噪声);
    • 对每个单词进行初始拆分:拆分为 “字节 / 字符 + 词尾特殊标记(如</w>)”,目的是区分 “词内子词” 和 “词尾子词”(避免不同单词的子词混淆,如 “apple” 的 “app” 和 “apply” 的 “app” 需明确是否为词尾)。
      示例:单词 “apple” 的初始表示为 a p p l e </w>,频率假设为 100;“app” 的初始表示为 a p p </w>,频率假设为 50。
  2. 统计与合并迭代

    • 统计当前所有 “相邻字符对” 的频率(如上述示例中,(a,p)频率为 150、(p,p)频率为 150、(p,l)频率为 100 等);
    • 选择频率最高的字符对进行合并,生成新子词(如合并(p,p)pp);
    • 用新子词更新所有单词的表示(如 “apple” 变为 a pp l e </w>,“app” 变为 a pp </w>);
    • 重复 “统计 - 合并” 步骤,直到达到预设的词汇表大小(如 32k)或合并次数上限,最终生成包含 “基础字符 + 合并子词” 的子词表。
  3. 子词表优化

    • 移除极低频率的子词(避免词表冗余);
    • 加入任务必需的特殊标记(如<PAD>用于补全、<UNK>用于极端 OOV、<SOS>/<EOS>用于句子边界)。
2. 推理阶段:对输入文本进行分词

核心目标是将新输入的文本,按照训练好的子词表拆分为子词序列,作为模型的输入(Token),步骤如下:

  1. 输入预处理

    • 将输入文本按空格拆分为单词(或按语言规则进行初步分词,如中文先按字符拆分);
    • 对每个单词重复 “训练阶段的初始拆分”:字符 +</w>(如输入 “apples” 拆分为 a p p l e s </w>)。
  2. 贪心合并(最长匹配)

    • 遍历当前单词的字符序列,从左到右尝试匹配子词表中最长的子词
    • 匹配成功后,将该子词作为一个 Token,剩余部分继续重复匹配,直到整个单词拆分完成。
      示例:若子词表包含ppappleapp,则 “apples” 的拆分过程为:
      a p p l e s </w> → 先匹配pp(剩余a l e s </w>)→ 再匹配a(剩余l e s </w>)→ 最终拆分为 a pp l e s </w>(若apples未在词表中)。
  3. 输出 Token 序列

    • 将所有单词的子词 Token 拼接,形成最终的输入序列,传入模型(如 Transformer 的嵌入层)。

三、BPE 在主流 NLP 模型中的应用案例

现代 NLP 模型几乎都基于 BPE 或其变体(如 WordPiece、Unigram)设计分词方案,以下是典型案例:

1. GPT 系列模型(OpenAI)
  • 使用方案:采用 BPE 的改进版(Byte-level BPE),直接以字节(Byte) 为初始单位(而非字符),天然支持所有 Unicode 字符(包括多语言、表情符号)。
  • 词表规模:GPT-2 使用 50k 词表,GPT-3/GPT-4 使用 100k + 词表;
  • 核心优势:无需依赖任何语言的字符集(如中文的 UTF-8 字符、英文的 ASCII),能处理多语言混合文本(如 “Hello 世界”),且 OOV 率极低。
2. BERT 系列模型(Google)
  • 使用方案:采用 BPE 的变体WordPiece(核心差异:合并时选择 “使模型困惑度最低” 的字符对,而非纯频率最高),本质仍是 BPE 的贪心逻辑;
  • 词表规模:默认 32k 词表,针对英文优化(包含大量英文子词);
  • 核心优势:更适配双向语言模型(BERT)的语义理解需求,减少歧义子词(如 “apple” 和 “apply” 的子词拆分更贴合语义)。
3. T5 模型(Google)
  • 使用方案:采用 Byte-level BPE,词表规模为 32k;
  • 核心优势:支持多语言任务(如翻译、摘要),通过 BPE 的子词拆分,让模型在低资源语言(如斯瓦希里语)上也能高效学习。
4. 神经机器翻译(如 OpenNMT)
  • 使用方案:早期 NMT(如 2015 年 Sennrich 的工作)直接使用标准 BPE,为源语言和目标语言分别构建子词表;
  • 核心价值:解决了传统基于词的 NMT 中 “罕见词翻译错误” 的问题,例如将 “unhappiness” 拆分为 “un”+“happiness”,模型可基于 “un-” 的否定语义推断翻译结果。

四、BPE 在 NLP 中的优势与局限性(结合任务视角)

优势
  1. 解决 OOV 问题:罕见词、新词可拆分为常见子词,避免模型输出<UNK>,尤其适合多语言和低资源语言任务;
  2. 控制词表规模:相比 “基于词的分词”(词表可能达百万级),BPE 的词表通常为 32k-100k,大幅降低模型嵌入层的参数数量(如 32k 词表 ×512 维度 = 16M 参数,远少于百万级词表);
  3. 无语言依赖:基于字节 / 字符启动,无需预先构建语言词典,适配多语言场景;
  4. 计算开销低:训练和分词均为贪心算法,逻辑简单,可高效处理大规模语料。
局限性
  1. 语义无关的合并:仅基于频率合并,不考虑子词的语义关联性(如 “apple” 的 “app” 和 “application” 的 “app” 语义不同,但会被合并为同一子词);
  2. 分词不一致性:同一子词在不同单词中可能有不同含义,可能干扰模型理解(如 “cat” 在 “cat” 和 “category” 中语义不同);
  3. 对词表大小敏感:词表过小时,常见词会被过度拆分(如 “apple” 拆为a p p l e </w>),增加模型输入长度;词表过大时,易出现低频子词,浪费参数。

五、BPE 的常见变体(NLP 任务适配)

为弥补 BPE 的局限性,NLP 领域衍生出多个变体,核心差异在于 “合并 / 选择子词的策略”:

变体名称 核心改进 适用场景
WordPiece(BERT) 合并时选择 “使模型困惑度(Perplexity)最小” 的字符对,而非纯频率 双向语言模型(如 BERT、RoBERTa),需更精准的语义子词
Unigram(T5、XLM) 从大词表中迭代删除 “对模型贡献最小” 的子词,保留高频且语义关键的子词 多语言任务,能更好地平衡不同语言的子词分布
Byte-level BPE(GPT) 以字节为初始单位,而非字符 支持全 Unicode 字符,适合多语言、表情符号等复杂文本

综上,BPE 是 NLP 从 “基于词的处理” 迈向 “子词级处理” 的关键技术,其核心思想(贪心合并高频单元)至今仍是主流模型分词方案的基础,也是理解现代 LLM 和翻译模型输入处理逻辑的核心前提。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐