用于语言模型的令牌:Go 中的字节对编码

主要观点:现代大型语言模型的基本货币单位是“token”,新模型有长上下文窗口,API 按 token 定价,还出现新单位如 TPM。介绍了 token 是“单词碎片”,以及常用的字节对编码(BPE)算法用于将文本分割成 token,包括训练过程(先假设每个字节是一个 token,然后合并成对的 token 到更长的 token 并添加到词汇表,直到达到所需大小)、编码过程(贪婪地应用学习到的 token)等,还提到了实际中用于 OpenAI 的 GPT-4 的词汇表 cl100k_base 及分裂正则表达式,最后给出了完整的 Go 语言实现和在线演示,包括一个带有 Web UI 和 WebAssembly 的全在线演示,能实时展示文本的 token 化过程。

关键信息:

  • 基本货币单位:现代大型语言模型的基本货币单位是“token”,新模型有长上下文窗口,API 按 token 定价,如 TPM(tokens per minute)。
  • token 定义:token 是“单词碎片”,对于英语语言,一个 token 约等于 4 个字符或 3/4 个单词。
  • BPE 算法:用于数据压缩,后被用于机器学习任务的“单词分割”即 tokenization。输入是任意文本,输出是代表相同文本的 token 列表,每个 token 是一个整数标识符,可在词汇表中查找以重现输入文本。算法有重要预处理步骤,即将输入文本分割成单词,不同模型/词汇表使用不同的正则表达式进行分割。
  • 训练过程:先假设每个字节是一个 token,然后合并成对的 token 到更长的 token 并添加到词汇表,直到达到所需大小。例如对于输入“i'm blue dabadee dabadam”,先为每个字节创建一个 token,然后统计每个字节对的出现次数,找到出现次数最多的字节对创建新 token 并替换,重复此过程直到达到所需词汇表大小。
  • 实际词汇表和分裂正则表达式:用于 OpenAI 的 GPT-4 的词汇表是 cl100k_base,包含 100k 个 token 及 256 个字节大小的 token,分裂正则表达式是(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}|?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+,注意标准 regexp 包不支持其中的?!(负向前瞻),需使用第三方库 regexp2 实现。
  • 在线演示:作者实现了一个带有 Web UI 和 WebAssembly 的全在线演示,将 Go 实现的 BPE 编译为 WebAssembly 二进制,通过 JavaScript 监听文本框输入并发送给 Go 函数进行 token 化,能实时展示“边输入边更新 token”的效果,底部的选择按钮可查看 token 的数值 ID。

重要细节:

  • 训练过程中,初始时每个字节是一个 token,词汇表最小为 256,然后统计字节对出现次数,找到最常见的字节对创建新 token 并替换,重复此过程直到达到所需词汇表大小。
  • 编码过程是贪婪的,按学习到的 token 顺序应用,输入是任意文本、分裂正则表达式和词汇表,例如对于输入“yada daba”,先按分裂正则表达式分割成字节,然后应用学习到的 token 进行编码。
  • 实际演示中,每个单词(除收缩词外)是一个单独的 token,因为词汇表较大,可尝试输入更长的单词或编程语言中的非平凡变量名观察效果。
  • 对于语言的适用性,BPE 算法是语言无关的,但本文主要聚焦于英语。
  • 性能影响:使 tokenization 面向单词,可轻松实现流式 tokenization 而不依赖于之前的单词。
  • 实现细节:Go 语言实现的训练在train.go文件中,编码器在encode.go文件中,测试文件在 tiktoken_tokenize_test.go中,可下载的 cl100k_base 编码文件在作者的样本仓库中。
阅读 123
0 条评论