20260414_分词器
token是LLM的基本输入单位,由分词器根据统计规则把文本拆成的子词、字符或字节,再映射成数字ID。
可拆分成四步:
- 准备语料
- 初始化基础单元(可省略)
- 统计并迭代合并
- 输出产物并用于编码、解码
训练分词器
准备语料
- 应收集覆盖目标应用场景的多样化文本,以确保泛化能力
- 必须对原始文本进行清洗与标准化,去除或屏蔽无关元数据、修正或删除乱码与非法字符、统一编码味UTF-8,对重复或近重复样本进行去重以减少训练偏移
- 敏感信息需要脱敏处理与合规检查
- 混合语料场景中需要评估占比,决定是否需要对低资源语言进行过采样或定向保留,避免词表被高频语言主导。
- 保留一小部分未参与训练的验证语料
初始化基础单元
- 常见策略包括基于空格和标点的切分、按Unicode类别划分,或直接采用字节级切分。但不是所有的分词器都需要显式地进行预分词
- 对于大多数用空格做分隔的语言可以用正则表达式按单词边界和标点进行初步切割,对中日等语言可以用逐字符或基于字的初始但原来保证覆盖性
- 预分词生成的基础单元序列将作为后续统计合并的输入,务必保存该序列与对应位置信息以便在训练过程反复高效更新。
统计并迭代合并
分词算法要解决的问题::“你好”要拆成“你”和“好”,还是合并成一个词“你好”。
粒度太细(拆得太碎)
“今天天气很好” → [“今”, “天”, “天”, “气”, “很”, “好”]
- ✅ 优点:能处理任何词,不会有未知词
- ❌ 缺点:序列太长,模型要学很多token之间的组合关系
粒度太粗(合并得太大)
“今天天气很好” → [“今天天气很好”](一个词)
- ✅ 优点:序列很短
- ❌ 缺点:遇到"今天天气不好"就变成新词,词表爆炸
理想的粒度(BPE等算法追求的)
“今天天气很好” → [“今天”, “天气”, “很”, “好”]
- ✅ 优点:
- “今天”、"天气"是常见词,可以复用
- “很”、"好"是基础字,可以灵活组合
- 序列长度适中
| 算法 | 选择标准 | example |
|---|---|---|
| BPE | 拼最常出现的 | “机器学习"中"机”、“器"经常一起出现,先拼成"机器” |
| WordPiece | 看看拼了有没有收益 | 拼了"机器"后,让"机器学习"出现的概率是否显著提升 |
| UnigramLM | 淘汰最差的 | 100个候选拼法中,淘汰掉"老出现的单个字" |
| SentencePiecer | 空格也是字符 | 不管中文英文,都按规则处理,空格也是一种符号 |
- vocab文件:记录所有token及其对应的id,是编码器和解码器的核心索引。
- merges文件:按顺序记录所有子词合并规则或概率模型。二者共同决定tokenizer的编码与解码逻辑,并确保编码的可逆。
- 如果后续需要扩表如加入新领域术语、专业词或品牌名等,建议优先采用这些方式而非完全重训tokenizer:增量训练、加入新的merges项、清理极低频token。
