基础知识词元化
GPT 系列 Tokenizer
会员专享GPT-2/GPT-4 的 Tokenization 方案,Regex 预处理与 tiktoken 库
在权益中心获取代码GPT-2 的 Tokenization 方案
在上一章,我们实现了基础的 BPE 算法。但 OpenAI 在 GPT-2 中并没有直接使用朴素的 BPE,而是做了一个重要的改进:Regex 预处理。
朴素 BPE 的问题
考虑这样一个场景:单词 "dog" 在文本中频繁出现,但总是伴随不同的标点符号:
dog.
dog!
dog?
dog,朴素的 BPE 可能会将这些组合都合并成单独的 tokens:
token_123 = "dog."
token_124 = "dog!"
token_125 = "dog?"
token_126 = "dog,"这导致了两个问题:
词汇表浪费:同一个单词的不同标点组合占用了多个 token 位置,浪费了有限的词汇表空间。
语义混淆:单词的语义和标点符号的语义被混在一起,模型需要学习它们之间的关系。
Regex 预处理的解决方案
GPT-2 的做法是:在应用 BPE 之前,先用正则表达式将文本分割成块。
核心思想:
防止跨类别合并:不允许 BPE 跨越某些边界进行合并,比如:
- 字母和数字之间
- 字母和标点之间
- 空格和其他字符之间
GPT-2 使用的正则表达式(简化版):
import regex as re
# GPT-2 的分割模式
gpt2_pattern = r"""'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+"""
text = "Hello, world! It's 2024."
chunks = re.findall(gpt2_pattern, text)
print(chunks)
# 输出: ['Hello', ',', ' world', '!', ' It', "'s", ' 2024', '.']这个正则表达式的作用(给初学者的直观解释):
|表示“或”,?表示“可选一次”,+表示“一个或多个”\p{L}是 Unicode 字母,\p{N}是 Unicode 数字,\s是空白[^...]表示“非某集合的字符”- 前面的
?是“可选空格”,GPT-2 会把前导空格并入 token
逐条拆解:
's|'t|'re|...:先匹配常见缩写片段,避免被拆成'和s等碎片?\p{L}+:可选空格 + 连续字母(一个单词)?\p{N}+:可选空格 + 连续数字(一个数字块)?[^\s\p{L}\p{N}]+:可选空格 + 连续标点/符号\s+(?!\S)|\s+:连续空白(包含行尾空白)
工作流程
使用 Regex 预处理后,BPE 的工作流程变为:
- 分割:用正则表达式将文本分割成块
- 独立编码:对每个块独立应用 BPE
- 拼接:将所有块的 tokens 拼接起来
登录以继续阅读
这是一篇付费内容,请登录您的账户以访问完整内容。
CookLLM文档