真实分词器测评(篇二)

#2025/12/28 #ai

目录

回顾

前文讲解了,分词器要在词表大小和序列长度之间做权衡,并且有 BPE、WordPiece 等不同算法。

本文讲解 “分词器实战横评”。作者通过一段包含英文、大写、中文、Emoji、Python 代码(含缩进)、数学算式的复杂文本,扔给不同时代的知名分词器(从 2018 年的 BERT 到 2024 年的 StarCoder2),看看它们是如何“编译”这段代码的。

我们可以将这些分词器的演进看作是编译器前端对“边缘情况(Edge Cases)”处理能力的进化史。

1. “上古时代”的缺陷:BERT (2018) & T5 (2022)

这两类模型的分词器在处理现代生成任务时,表现出明显的“Bug”。

  • BERT (WordPiece算法):
    • Uncased版本(大小写不敏感):
      • 相当于代码里的 string.lower()。不仅丢失了大写信息,还丢失了换行符。
      • 这对写代码(依赖换行)是致命的。
    • 处理未知字符(OOV):
      • 遇到它不认识的 Emoji 或生僻字,直接抛出异常 Token —— [UNK](Unknown)。
      • 这意味着信息直接丢失,模型根本不知道你输入了什么。
    • 标记方式:
      • 使用 ## 前缀表示子词(如 ##ization)。
  • FLAN-T5 (SentencePiece算法):
    • 致命伤:
      • 它会忽略换行符和制表符。
      • 作为一个软件工程师,你知道这意味着什么——它根本无法处理 Python 代码(依赖缩进),也无法处理格式化文本。
    • 未知字符: 同样使用 <unk> 替换不认识的字符。

2. “通用时代”的进化:GPT-2 (2019)

GPT-2 引入了 字节级 BPE (Byte-level BPE),解决了一个核心痛点:不再有 [UNK]

  • 兜底机制:
    • 遇到不认识的字符(如 Emoji 或中文),它回退到字节编码
      • 虽然这会导致一个汉字变成多个 Token(效率低),但至少信息没丢,模型还能“拼”出来。
  • 保留格式:
    • 保留了换行和大小写,这让生成代码和格式化文本成为可能。

3. “现代”的极致优化:GPT-4 (2023) & Code 模型

到了现在,分词器开始针对代码和推理进行深度优化,变得非常“智能”。

  • 空格压缩(针对代码):
    • GPT-4 的分词器非常聪明,它把“四个空格”或者“两个制表符”直接合并为一个 Token
    • 意义:
      • 对于 Python 这种缩进敏感的语言,这极大地压缩了序列长度,让模型能读入更长的代码上下文。
  • 数字处理(针对数学):
    • StarCoder2 / Galactica:
      • 它们把数字切分得非常细。比如 600,以前可能是一个 Token,现在被切分成 600 三个 Token。
    • 意义: 这就像教小学生算术,一位一位地处理数字,比让模型死记硬背“600”这个整体更容易学会数学运算。
  • 专用 Token(针对工程):
    • StarCoder2:
      • 引入了 <filename><reponame>特殊 Token,让模型知道“现在我在读哪个文件”,这对于处理整个 GitHub 仓库至关重要。

4. “对话时代”的适配:Llama 2 / Phi-3

随着 ChatGPT 的爆发,分词器必须适应多轮对话

  • 结构化 Token:
    • 引入了 <|user|><|assistant|><|system|> 等特殊标记。
  • 意义:
    • 这相当于在传输协议中定义了包头(Header),让模型清楚地知道“这句话是谁说的”,从而防止指令注入,并保持对话逻辑

总结:给工程师的“选型指南”

如果把分词器比作数据预处理器:

  1. BERT类: 适合做分类任务(情感分析),不适合生成,尤其是代码生成(因为丢格式)。
  2. GPT-2/Llama类: 通用性好,无损编码(字节回退),适合绝大多数生成任务。
  3. GPT-4/StarCoder类: 对代码和数学做了特异性优化(压缩空格、拆分数字),效率更高,上下文利用率更好。

核心结论: 分词器不仅仅是切分字符串,它决定了模型“擅长”什么。如果你要训练一个写代码的模型,千万别用一个会吃掉换行符的分词器(如 T5)。