导航菜单

  • 1.vector
  • 2.milvus
  • 3.pymilvus
  • 4.rag
  • 5.rag_measure
  • 7.search
  • ragflow
  • heapq
  • HNSW
  • cosine_similarity
  • math
  • typing
  • etcd
  • minio
  • collections
  • jieba
  • random
  • beautifulsoup4
  • chromadb
  • sentence_transformers
  • numpy
  • lxml
  • openpyxl
  • PyMuPDF
  • python-docx
  • requests
  • python-pptx
  • text_splitter
  • all-MiniLM-L6-v2
  • openai
  • llm
  • BPETokenizer
  • Flask
  • RAGAS
  • BagofWords
  • langchain
  • Pydantic
  • abc
  • faiss
  • MMR
  • scikit-learn
  • 一、核心思想:解决词典的“大小-覆盖度”两难问题
  • 二、BPE是什么?
  • 三、BPE分词器的工作流程
    • 阶段一:训练 - 从文本中学习合并规则
    • 阶段二:编码 - 对新文本进行分词
  • 四、BPE的优势与特点
  • 五、实际应用中的细节
  • 总结

好的,我们来详细讲解 BPE Tokenizer。它是现代自然语言处理(尤其是像GPT系列这样的模型)的基石之一。

一、核心思想:解决词典的“大小-覆盖度”两难问题 #

在传统分词方法中,我们面临一个两难选择:

  1. 词级词典:词典巨大,且无法处理未见词(Out-of-Vocabulary, OOV)。
    • 例如,如果词典里有“猫”、“老鼠”,但没有“猫抓老鼠”,模型就无法理解这个常见的短语。
  2. 字符级词典:词典极小(比如英文只有26个字母),能表示任何词,但单个token信息量少,序列过长,训练和推理效率低。
    • 例如,“apple”需要5个token a, p, p, l, e 来表示,丢失了“app”等子词的含义。

BPE的解决方案:取二者之长。它基于子词进行分词,让最常见的词或词组作为一个独立的token,而将不常见的词拆分成更有意义的子词甚至字符。


二、BPE是什么? #

BPE 是一种数据压缩算法,在2015年被引入到NLP领域用于分词。它的名字就揭示了其工作原理:

  • Byte Pair: 最初指的是在压缩数据中寻找最常相邻出现的字节对。
  • Encoding: 用一个新的、未使用的字节来替换这个频繁出现的字节对。

在NLP中,我们把“字节”换成“字符”或“子词单元”。


三、BPE分词器的工作流程 #

BPE分词器的工作分为两个独立的阶段:1. 训练 和 2. 编码。

阶段一:训练 - 从文本中学习合并规则 #

目标是基于一个训练语料库,构建一个合并规则列表。

假设我们有以下训练数据(已经过初步归一化,如小写化): "low lower newest widest"

  1. 初始化:

    • 将每个词分割成字符,并在词尾添加一个特殊的结束符 (表示单词边界)。
    • 初始词汇表是所有基础字符的集合。
      l o w </w>
      l o w e r </w>
      n e w e s t </w>
      w i d e s t </w>
      初始词典: {‘l’, ‘o’, ‘w’, ‘e’, ‘r’, ‘n’, ‘s’, ‘t’, ‘w’, ‘i’, ‘d’, ‘</w>’}
  2. 迭代合并:

    • 统计所有相邻的符号对(byte pairs)的频率。
    • 选择出现频率最高的符号对。
    • 合并这个符号对,创建一个新的符号,并将其加入到词汇表中。
    • 重复此过程,直到达到预定的合并次数(或词汇表大小)。

迭代过程演示:

  • 迭代1: 最频繁的字节对是 (e, s),出现了2次(在newest和widest中)。合并它们,创建新符号 es。

    l o w </w>
    l o w e r </w>
    n e w es t </w>   # newest -> n e w e s t -> n e w es t
    w i d es t </w>   # widest -> w i d e s t -> w i d es t

    词汇表更新: {..., ‘es’}

  • 迭代2: 最频繁的字节对现在是 (es, t),出现了2次。合并它们,创建新符号 est。

    l o w </w>
    l o w e r </w>
    n e w est </w>   # newest -> n e w es t -> n e w est
    w i d est </w>   # widest -> w i d es t -> w i d est

    词汇表更新: {..., ‘est’}

  • 迭代3: 最频繁的字节对是 (l, o),出现了2次。合并它们,创建新符号 lo。(但注意,它在两个词里都是“low”的一部分)

    lo w </w>
    lo w e r </w>
    n e w est </w>
    w i d est </w>

    词汇表更新: {..., ‘lo’}

  • 迭代4: 最频繁的字节对是 (lo, w),出现了2次。合并它们,创建新符号 low。

    low </w>
    low e r </w>
    n e w est </w>
    w i d est </w>

    词汇表更新: {..., ‘low’}

... 如此继续,我们还可以合并 (low, </w>),(n, e) 等等。

最终,我们得到的合并规则列表(按合并顺序排列)是:

  1. e s -> es
  2. es t -> est
  3. l o -> lo
  4. lo w -> low
  5. low </w> -> low</w>
  6. n e -> ne
  7. ...

这个合并规则列表和最终的词汇表就是训练好的BPE模型。


阶段二:编码 - 对新文本进行分词 #

现在,我们有一串新的文本,比如 "lowering the widest landscape",如何用训练好的模型对它分词?

  1. 预处理:将词按空格分开,并添加 。"lowering </w> the </w> widest </w> landscape </w>"
  2. 按字符分割:“l o w e r i n g </w>”, “t h e </w>”, “w i d e s t </w>”, “l a n d s c a p e </w>”
  3. 应用合并规则:

    • 我们遍历在训练阶段学到的合并规则列表(按顺序!)。
    • 对于第一个词 l o w e r i n g </w>:
      • 查看规则1 (e s -> es),不适用。
      • 查看规则2 (es t -> est),不适用。
      • 查看规则3 (l o -> lo),适用!合并:lo w e r i n g </w>
      • 查看规则4 (lo w -> low),适用!合并:low e r i n g </w>
      • 查看规则5 (low </w> -> low</w>),不适用,因为后面是 e 不是 </w>。
      • ... 继续应用后续规则,直到没有规则可以应用。
    • 最终,“lowering” 可能被分词为 [‘low’, ‘e’, ‘r’, ‘i’, ‘n’, ‘g’] 或类似的子词。
  4. 输出:将每个词应用规则后得到的子词序列作为最终的tokens。


四、BPE的优势与特点 #

  1. 平衡了效率与覆盖度:在常见的词(如“the", "ing”)和罕见的词(如“Transformer”)之间取得了很好的平衡。
  2. 有效处理未知词:即使遇到没见过的词,也能将其分解成已知的子词来理解。例如,模型没见过“ChatGPT”,但它认识“Chat”和“GPT”,就能很好地理解。
  3. 压缩率高:能有效地表示文本,序列长度介于词级和字符级之间。
  4. 语言无关性:不依赖于特定的语言规则(如空格),对黏着语(如土耳其语)、屈折语等都有效。

五、实际应用中的细节 #

  • GPT系列:使用BPE的变体Byte-level BPE,以字节为基础,实现了真正意义上的“一个分词器处理所有文本”。
  • SentencePiece:一个流行的开源库,实现了BPE以及类似算法(如Unigram LM),它的一个特点是不依赖预分词,直接将原始文本作为输入,对带空格的语言(如中文、日文)更友好。
  • WordPiece:BERT使用的算法,与BPE类似,但在选择合并哪个符号对时,它不只看频率,而是看频率和概率的综合(似然值),选择能最大程度提高语言模型似然值的对。

总结 #

BPE Tokenizer 是一个通过迭代合并频繁共现的相邻符号,从而从字符开始自动构建一个子词词汇表的过程。它的核心在于训练阶段学到的合并规则,这使得它非常灵活和强大,成为当今大语言模型不可或缺的组成部分。

访问验证

请输入访问令牌

Token不正确,请重新输入