跳转至

P6-2.5 补充学习:从运营观察值看见 tokenizer 家族差异

Section ID: P6-2.5 Version: v2026.07.26

BPE、WordPiece、SentencePiece 不是需要背下来的名称清单。即使是同一个字符串,使用的 tokenizer 不同,片段边界、token 数、空白处理、稀有表达处理也会不同。这个差异会直接连接到成本预测、检索 chunk、长文档输入,以及混合标记文档的长度感觉。

这个补充学习的中心,不是记住三个算法家族的所有细节。它是把家族名称读成切分字符串的标准,再观察这种标准差异什么时候会出现在成本、chunk、混合标记长度预测中。

家族名称指向切分标准

如果 tokenization 会改变成本和 chunk,下一步问题就是为什么不同模型切分字符串的感觉会略有不同。读这个差异时最常遇到的名称是 BPE、WordPiece、SentencePiece。

与其先背三个名称,不如先抓住把字符串切成片段的标准在哪里分开。这样才能把长度感觉、稀有词处理、空白解释差异放在同一条轴上读。

tokenizer 家族是什么意思

tokenizer 是把文本转换成模型计算单位的一组规则。这里通常同时包含两件事。

  • 决定哪些片段经常使用的片段词表(vocabulary)
  • 决定怎样把原始字符串分成这些片段的分割规则

BPE、WordPiece、SentencePiece就是制作这类 tokenizer 的代表性家族名称。

token 边界分开的标准

同一个句子也会因为下面标准不同而出现差异。

  • 把哪一种表达看成一个片段
  • 对空白有多强的信任
  • 把稀有词拆成几个片段

这些标准一变,token 数、长度感觉、chunk 边界也会一起变化。所以模型卡或课程经常会另外说明这个模型使用哪一种 tokenizer 家族。

flowchart TD
  A["在模型卡或课程中<br/>看到 tokenizer 名称"]
  B["它是什么的名称?<br/>代表性 tokenizer 家族"]
  C["它怎样切分?<br/>分词方式的线索"]
  D["差异会在哪里出现?<br/>token 数 / chunk 边界"]
  E["后续要重新查看的判断<br/>成本 / 检索 / 长度管理"]

  A --> B
  B --> C
  C --> D
  D --> E

这个图只短短地展示 tokenizer 名称会连接到 token 边界、长度感觉、空白解释差异。

三者的共同点是什么

BPE、WordPiece、SentencePiece 的共同点是,它们都是试图把文本变成适合计算的 subword 片段的家族。差异会出现在更常尝试合并什么、哪一种片段词表更能解释字符串、是否可以把空白固定为边界这样的切分标准中。

因此看到这三个名称时,与其把它们背成目的完全不同的技术,不如读成在同一个目标下制作和选择片段的标准不同。

各家族的切分标准

BPE(Byte Pair Encoding)

BPE 可以读成从很小的片段开始,然后反复把经常一起出现的片段对(pair)合并成更大片段的感觉。

一开始从字符或 byte 这样更小的单位出发,然后在训练语料(corpus)中不断合并经常一起出现的组合,逐渐形成 th、ing、token 这样更大的片段。这里的语料是为了训练或分析而收集的文本集合。所以第一次读 BPE 时,与其说一开始就知道单词,不如说经常一起出现的片段逐渐固定下来更接近。

第一次读时先抓住下面几点。

  • 起点是更小的片段。
  • 把经常一起出现的片段合并成更大的片段。
  • 稀有词也不是完全读不了,而是可以拆成多个片段来读。

例如 tokenization 这个字符串如果经常出现,一开始可能被切得更细,后来 token、ization 这类常用片段可能逐渐固定成更大的单位。这里重要的不是先背单词词典,而是把反复出现的片段逐渐变大。

WordPiece

WordPiece 可以读成更强烈地意识到选择哪一种片段词表,才能更有效地解释句子的家族。它和 BPE 一样使用 subword 片段,但比起单纯把经常相邻的片段对合并,更适合读成更关注这个片段词表能多好地解释整个句子。

第一次比较时,下面区分尤其重要。

  • BPE 也会把片段变大,但 WordPiece 更直接地把哪些片段应该放进词表当成问题。
  • 即使完整单词不在词表里,也会拆成更小的 subword 片段来读。
  • 在 BERT 系列说明中,经常和 subword、longest match、[UNK] 这些表达一起出现。

例如 unhappiness 这样的表达即使没有完整地出现在词表里,也可以拆成 un、happi、ness 这类已经存在的片段来读。这里要抓住的核心不是遇到未知词是否马上丢掉,而是是否尽量用已经知道的片段来解释。

WordPiece 中常见的 longest match 感觉也可以在这里理解。它表示从左到右读字符串,如果当前词表里有更长的片段,就优先使用那个片段。所以 BERT uses WordPiece 这句话不只是一个专有名词,而更适合理解成BERT 有把单词切成更小意义片段来读的规则。

SentencePiece

SentencePiece 可以读成不预设空白已经是完美单词边界,而是更直接处理包含空白在内的字符串本身。因此它常被说明为不仅适合英语这类空白熟悉的语言,也比较适合空白边界不稳定或语言混合的环境。

第一次看到 SentencePiece 时,先看下面几点。

  • 不因为有空白就把它当成绝对边界。
  • 以整个字符串为对象制作片段。
  • 更接近直接处理不同语言中单词边界感觉不同的问题。

例如处理韩语、英语、数字、符号混在一起的句子时,人会先用眼睛看空白。但在 SentencePiece 家族的说明中,会重新决定空白也是字符串的一部分,哪些片段反复有用。所以 this model uses SentencePiece 这一行也是一个线索:这个模型可能不会把空白当作绝对标准。

极简比较三者

名称 一句话说明 先想起的问题
BPE 把经常贴在一起的小片段逐渐合并成更大片段 什么反复一起出现
WordPiece 更关注哪一种片段词表能更好解释句子 哪些片段放入词表更好
SentencePiece 更直接处理包含空白在内的整个字符串 多大程度信任空白是单词边界

这张表不是要求你背下严格算法差异。首先要抓住的是三者都是 subword 家族,但各自更强烈关注的标准略有不同。

读取 tokenizer 家族时的误解

1. 认为三者目的完全不同

这三个名称不是目的完全不同的独立装置。它们都是把包含稀有词在内的字符串稳定转换成可计算片段的家族。差异不在目的本身,而在制作和选择片段的感觉。

2. 认为未知词会立刻读不了

这些家族重要的理由之一是,即使完整词未知,也能把它重新拆成更小片段来读。如果词表里没有这个词,是不是就结束了这种感觉,正好连接到 subword 家族出现的理由。

3. 认为背名字才是核心

重要的不是背名字。你应该能想起这个模型以什么单位读取字符串、它多信任空白、它怎样拆分稀有表达。

这个区分为什么用于实际判断

代表性 tokenizer 家族不是为了背细节比较,而是为了解释 LLM 怎样读取字符串。如果不知道这些名称,下面问题就难以互相连接。

  • 为什么同样意思的句子在不同模型中 token 数可能不同
  • 为什么有些模型会和按空白理解的单词感觉不同地切分
  • 为什么在稀有词、混合标记、长术语中长度感觉经常失准

也就是说,这里需要的不是背三个专有名词,而是拥有一个标准来读取模型按什么标准切分字符串。

学完这个区分后,应该能用下面标准自我检查。

学完名称后应该能做到的事 现在还不必做的事
说明 BPE、WordPiece、SentencePiece 是什么的名称 直接实现 merge 规则
理解三者都是 subword 家族 追踪论文公式和训练细节
说明空白、稀有词、片段词表视角差异 重新训练一个 tokenizer

各家族切分标准的案例与示例

案例 1. 按重复片段标准读取 BPE

在 tokenization 这个表达经常出现的语料中,不需要假设 tokenizer 从一开始就知道整个单词。它可以从更小片段开始,之后 token、ization 这种经常一起出现的片段逐渐固定下来。

这个案例中,人最容易先使用的标准是把 tokenization 看成一个英语单词。这个标准的限制在于,tokenizer 不会原样跟随单词词典。看到 BPE 这个名称时,应该先问这个字符串是从哪些重复片段长出来的。

案例阶段 这个场景中的值 要确认的结果
人最先看的标准 tokenization 是一个单词 预期它会被整体处理成一个单词
这个标准的限制 经常相连的片段可能分别固定 会看见 token 与 ization 这样的片段边界
家族名称改变的问题 BPE 是反复放大小片段对的感觉 先问什么反复一起出现

因此 BPE 案例要收住的句子是这个。BPE 不是背诵对象,而是反复贴在一起的小片段会固定成更大计算片段的切分标准。

案例 2. 按词表片段标准读取 WordPiece

像 unhappiness 这样整体陌生的表达,也可以用 un、happi、ness 这样的 subword 片段来解释。BERT 系列说明中 WordPiece、subword、longest match、[UNK] 一起出现,也是因为这一点。

这个案例中,人最容易先使用的标准是词表里没有这个单词,模型就读不了。这个标准的限制在于,它忽略了 subword 家族不是用完整单词,而是用已有片段词表来解释字符串。看到 WordPiece 这个名称时,应该先问哪些片段放进词表,才能更好解释整个字符串。

案例阶段 这个场景中的值 要确认的结果
人最先看的标准 unhappiness 整体陌生 预期会被当作未知词处理
这个标准的限制 可以用 un、happi、ness 等片段解释 片段词表的构成比完整单词更重要
家族名称改变的问题 WordPiece 是用词表片段解释字符串的感觉 先问哪些片段放进词表更好

因此 WordPiece 案例要收住的句子是这个。WordPiece 不是遇到未知词就马上放弃,而是尽量用已有 subword 片段解释字符串的切分标准。

案例 3. 按空白边界标准读取 SentencePiece

在韩语句子、英语产品名、数字、符号混合的输入中,只靠空白决定单词边界很难。SentencePiece 家族可以理解成不把空白当作绝对边界,而是在包含空白标记的整个字符串中寻找重复片段。

这个案例中,人最容易先使用的标准是空白就是单词边界。这个标准的限制在于,韩语、英语产品名、数字、符号混合时,仅靠空白很难稳定决定计算片段。看到 SentencePiece 这个名称时,应该先问空白是否可以被信任为绝对边界。

案例阶段 这个场景中的值 要确认的结果
人最先看的标准 有空白就看见单词边界 预期按空白切分就足够
这个标准的限制 韩语、英语、数字、符号混合 只靠空白很难稳定决定片段边界
家族名称改变的问题 SentencePiece 查看包含空白的整个字符串 先问空白能否固定为单词边界

因此 SentencePiece 案例要收住的句子是这个。SentencePiece 不只是多语言模型中常见的名称,而是让我们重新询问应该多信任空白边界的切分标准。

输入场景中分开的 tokenization 标准

读完三个名称后,读者常再次卡住的地方是所以现在应该先问什么问题。这时与其先看名称本身,不如先选择当前输入中什么问题更突出。

现在最先看到的场景 最先提出的问题 更直接连接的家族
相同片段似乎反复经常一起出现 经常一起出现的小片段是否固定成更大片段? BPE
整体不存在的词必须尽量用已有 subword 片段解释 把哪些片段放入词表更有利于解释整个字符串? WordPiece
空白、语言混合、数字、符号混在一起,很难照样信任空白边界 是否需要不把空白当绝对边界,而重新查看整个字符串? SentencePiece

这张表的目的不是机械匹配三种家族。它是为了让你在读模型卡或 tokenizer 说明时,马上选择现在应该先确认的是重复片段、词表片段选择,还是空白边界处理。

tokenizer 家族比较中会变化的东西

代表性 tokenizer 只读说明很难留下感觉。必须直接用一次,才会立刻看见人看到的单词和模型读取的片段怎样错开。

直接使用时,特别会看到下面三点。

  • 同样意思的句子,表达稍微改变,片段数也可能改变。
  • 空白、符号、数字、英文混合会大幅摇晃长度感觉。
  • 同一个字符串也可能因 tokenizer 家族不同而拥有不同片段边界。

这个经验重要,是因为代表性家族名称不再停留为抽象专有名词,而会变成实际片段边界感觉。如果一次也没直接用过,读者即使读到tokenizer 家族不同这句话,也很容易回到单词数和字符数感觉。

小比较中看见的差异

在深入处理代表 tokenizer 之前,像下面这样做一个很小的比较,也能看见片段边界差异。

  1. 准备两三个意思相同的句子。
  2. 制作一个混入数字、符号、英文、缩写的版本。
  3. 查看每个句子被分成几个片段。
  4. 确认片段边界在哪里改变。

例如可以直接比较下面的句子。

要比较的字符串 先观察的点
회의는 내일 열립니다. 作为比较基准的简单句
회의는 내일 10:00 AM에 열립니다. 加入数字和英文后片段数怎样增加
회의는 내일 10:00 AM, Zoom 링크 포함입니다. 符号和英文混合怎样进一步摇晃边界

这个小练习的目的不是选择哪一种家族最好。首先需要的是亲手确认人眼看起来相似的句子,在模型侧可能会被不同地切分。

选择性执行示例:把同一个输入放入三个家族

代表 tokenizer 不应该停在知道名称。执行环境准备好时,最好实际各用一次。不过这个例子不是只靠安装包就一定能完成的基本执行示例。即使安装了 transformers 和 sentencepiece,第一次执行的环境也可能需要从 Hugging Face 下载 tokenizer 文件。如果没有网络,或者本地缓存没有文件,程序可能会在 AutoTokenizer.from_pretrained(...) 阶段停止。

因此本节分成两个层次。下面代码是直接确认实际 tokenizer 输出的选择性执行示例。无法马上执行的环境中,先阅读保存的观察值 CSV p6-2-5-tokenizer-family-observations.csv和后续结果表。CSV 的一行表示把一个输入放入某个 tokenizer 后得到的 token count 和代表片段。

示例目标有三点。

  • 在真实输入中各用一次 BPE、WordPiece、SentencePiece。
  • 确认同一个字符串也可能因家族不同而拥有不同片段边界和 token 数。
  • 直接观察数字、英文、符号、混合标记怎样摇晃长度感觉。

示例模型可以这样设置。

家族 示例模型 这个例子中要看的内容
BPE gpt2 经常一起出现的片段怎样被捆起来
WordPiece bert-base-uncased subword 片段与 longest match 感觉怎样出现
SentencePiece google/mt5-small 不把空白当绝对标准的感觉怎样出现

直接操作的值是 samples 列表。放入韩语、英语、数字、URL、代码片段,查看 TOKEN COUNT 和 TOKENS 在哪里不同。观察顺序固定如下。

观察顺序 要确认的值 解读标准
1 TOKEN COUNT 即使意思相同,长度感觉是否也因家族而不同
2 TOKENS 人看到的单词边界是否和 tokenizer 片段边界错开
3 TOKEN IDS 片段字符串是否变成 vocabulary 编号序列
# 比较 BPE、WordPiece、SentencePiece tokenizer 如何把相同输入字符串切成 token 片段和 ID 的示例。
from transformers import AutoTokenizer

# 操作变量:在这里增加句子或改变表达,token 片段和 token 数会改变。
samples = [
    "회의는 내일 열립니다.",
    "회의는 내일 10:00 AM에 열립니다.",
    "회의는 내일 10:00 AM, Zoom 링크 포함입니다.",
    "tokenization",
    "tokenization helps models read rare words",
]

tokenizers = {
    "BPE / gpt2": AutoTokenizer.from_pretrained("gpt2"),
    "WordPiece / bert-base-uncased": AutoTokenizer.from_pretrained("bert-base-uncased"),
    "SentencePiece / google/mt5-small": AutoTokenizer.from_pretrained("google/mt5-small"),
}

for name, tokenizer in tokenizers.items():
    print(f"\n=== {name} ===")
    for text in samples:
        pieces = tokenizer.tokenize(text)
        ids = tokenizer.convert_tokens_to_ids(pieces)
        print(f"\nTEXT: {text}")
        print("TOKENS:", pieces)
        print("TOKEN COUNT:", len(pieces))
        print("TOKEN IDS:", ids)

上面的代码是直接确认代表 tokenizer 用法的说明型示例。同时,因为改变 samples 列表就会改变 token 片段和 token 数,所以也可以扩展成小实验。不需要背下准确 token 字符串。应该把哪一种输入变化会大幅改变 token 数、哪一种家族会把边界切得更细、空白和符号会留下成什么片段和问题、解说一起读。

如果执行失败,先区分失败原因。transformers import 失败是包依赖问题,如果停在 from_pretrained(),则是 tokenizer 文件下载或本地缓存问题。必须先做这个区分,才不会把示例核心误解成安装问题。这里要学的不是下载流程,而是不同家族怎样不同地切分同一个输入。

观察问题 解说
同一个句子中,哪一个家族切得更细 因为各家族的片段词表和分割规则不同,同一个字符串也会有不同 token 数。这里要确认的中心概念是不同模型切分字符串的标准不同。
加入数字、:、,、英文缩写时 token 数变化多大 混合标记可能比人看到的字符数更快增加 tokenizer 看到的片段数。这个问题确认 BPE、WordPiece、SentencePiece 都在解决同一问题,但不会制造同一边界。
看起来像一个英语单词,实际是否会拆成多个 subword 片段 像 tokenization 这样熟悉的单词,也可能拆成 token 和 ization 系列片段。这个解说连接到代表家族按 subword 片段而不是完整单词读取。
韩语和英语混合时,空白基准的单词感觉多容易破裂 空白对人很方便,但并非所有 tokenizer 都把空白当作绝对单词边界。这个问题让你按包含空白的字符串处理这一标准读取 SentencePiece。

特别建议实际比较下面两组。

要比较的输入 直接确认的事
회의는 내일 열립니다. vs 회의는 내일 10:00 AM에 열립니다. 加入数字和英文后片段数增加多少
tokenization vs tokenization helps models read rare words 单词一个和整个句子中的片段边界怎样不同

输出片段与 token 数的差异

执行上面的示例代码后,可以观察到如下形式的差异。下面数值是按照保存观察值 CSV 的同一标准整理的示例。由于具体片段可能随 library 和 tokenizer 文件版本变化,下面表格应读怎样阅读家族差异,而不是唯一固定正答。

输入 BPE gpt2 WordPiece bert-base-uncased SentencePiece google/mt5-small
회의는 내일 열립니다. 24 17 8
회의는 내일 10:00 AM에 열립니다. 31 23 11
회의는 내일 10:00 AM, Zoom 링크 포함입니다. 39 30 16
tokenization 2 2 3
tokenization helps models read rare words 7 7 9

只先看数字,也能马上看出几点。

  • 同一个韩语句子中,gpt2 BPE 切得非常细。
  • bert-base-uncased WordPiece 也把韩语细分,但有些情况下把句子前部处理成 [UNK]。
  • mt5-small SentencePiece 保留了 회의、▁내、▁열、립니다 这样更大的片段。
  • tokenization 看起来像一个单词,但三种家族都没有只把它保留成一个单独片段。
  • 数字和英文混入后,三种家族的 token 数都增加了,但增加幅度不同。

只看代表片段,差异会更清楚。

家族 实际看到的代表片段 这里应该读出的含义
BPE gpt2 ['Ġ10', ':', '00', 'ĠAM'],韩语被分割成许多破碎的 byte 型片段 byte-based BPE 可能把韩语读得很细
WordPiece bert-base-uncased ['[UNK]', 'ᄂ', '##ᅢ', ...],['token', '##ization'] 英语中心 WordPiece 会把部分韩语留成 [UNK],并把已知片段接成 subword
SentencePiece google/mt5-small ['▁', '회의', '는', '▁내', '일', '▁열', '립니다', '.'] 它可以基于包含空白的字符串,保留较大的片段来读取

英语句子中也能看见差异。tokenization helps models read rare words 是:

  • BPE gpt2: token, ization, Ġhelps, Ġmodels, Ġread, Ġrare, Ġwords
  • WordPiece bert-base-uncased: token, ##ization, helps, models, read, rare, words
  • SentencePiece google/mt5-small: ▁, token, ization, ▁help, s, ▁models, ▁read, ▁rare, ▁words

也就是说,即使是在看一个英语单词的场景中,怎样切分 tokenization、怎样标记空白、是否把 helps 整体保留或拆成 help 与 s,实际也会不同。

读者应该从这个结果收住的判断是这个。模型卡或 tokenizer 说明中出现 BPE、WordPiece、SentencePiece 这些名称时,与其背名字本身,不如确认应该想起重复片段、词表片段、包含空白的字符串中的哪一种切分标准。

这个示例的核心,是养成把家族名称读成实际片段边界的习惯。看到 tokenization 类型差异什么时候出现时,也应该先想起这些标准差异。

如果已经把家族名称读成实际片段边界,就应该能把同一观察值重新连接到成本、chunk、长度预测问题。

差异出现在运营场景中的瞬间

知道 tokenizer 家族名称并不马上足够。实际重要的是这个差异什么时候开始出现。

本节核心不是先问哪一种家族更好。首先要看的,是差异出现的场景。

同样意思但成本感觉分开时

人会把 환불 정책을 알려줘 和 환불 관련 정책을 간단히 설명해 줘 看成相似问题。但根据 tokenizer,관련、간단히、설명해 这样的表达如果被切得更细,实际 token 数和成本就可能不同。

也就是说,同样意思不保证同样输入成本。

上面实际运行 tokenizer 的结果也确认了这种感觉。

输入 BPE gpt2 WordPiece bert-base-uncased SentencePiece google/mt5-small
회의는 내일 열립니다. 24 17 8
회의는 내일 10:00 AM에 열립니다. 31 23 11

即使是同一个日程通知场景,数字和英文一加上去,三种家族的 token 数都增加了,而且增加幅度并不相同。这个差异就是同样意思也可能拥有不同成本感觉的实际样子。

检索 chunk 被尴尬截断时

把段落切得好看,不一定会变成有利于检索的 chunk。如果核心条件和例外条款被撕到不同片段中,检索结果可能只带来原则而漏掉例外。

这个场景中,token 片段边界可能比按空白看的段落更重要。

实际片段示例能让原因更清楚。

  • BPE gpt2 有把韩语切得很细的倾向,所以人看成一组的短语也可能散成更多片段。
  • WordPiece bert-base-uncased 会把韩语一部分处理成 [UNK],再把其他部分接成 subword,因此语言混合区间可能和人预期的边界不同。
  • SentencePiece google/mt5-small 保留了 회의、▁내、▁열、립니다 这样更大的片段,显示同一个句子也可能留下相对较大的意义单位。

这里的核心不是哪一种家族一定更好。切 chunk 时,人以为的意义单位和实际 token 片段单位错开多少,会动摇检索质量。

混合标记文档中长度感觉摇晃时

韩语说明句中混入英文产品名、版本字符串、URL、代码片段后,即使人眼看起来是短句,实际 token 数也可能快速增加。

这个场景中,混合标记密度会比表面句子长度成为更重要的判断标准。

上面例子的第三个输入也很好地展示了同一场景。

输入 BPE gpt2 WordPiece bert-base-uncased SentencePiece google/mt5-small
회의는 내일 10:00 AM, Zoom 링크 포함입니다. 39 30 16

人看同一个句子时,可能只觉得是稍微加入数字和产品名的日程通知。但实际上,10:00、AM、Zoom、링크 这些区间会按家族不同方式切分,token 数差距会变大。这就是混合标记文档中长度预测经常失准的原因。

把同一场景压缩成运营备忘,可以写成下面这样。

最先看到的现象 直接放过会产生的误判 更安全的下一步判断
意思相似的请求,看起来成本也会相似 不看实际 token 数差异就过度信任预算 实际比较同一意图请求组的 token 数
段落自然分开,所以 chunk 看起来安全 核心条件可能在 chunk 边界被切掉 连 token 边界一起确认条件句在哪里断开
句子看起来短,所以输入也像是短的 在混合标记区间反复出现长度预测失准 单独检查数字、URL、代码片段多的区间

极简图示

flowchart TD
  A["同一个 tokenizer 问题"]
  B["相似请求<br/>token 数是否不同?"]
  C["chunk 边界<br/>核心条件是否留在一起?"]
  D["后续检索 / 成本<br/>下游行为是否改变?"]

  A --> B
  A --> C
  B --> D
  C --> D

这个图中要确认的是,tokenizer 差异不会只停留为名称差异。同样意思的句子如果切分方式不同,token 数、chunk 边界、后续检索和成本判断也可能一起改变。

在运营场景中重新看 tokenization 差异

场景 最先提出的问题
相似请求之间成本差异是否很大 片段边界在哪里反复分开
检索 chunk 是否总是切掉核心条件 意义单位是否留在同一个 token 组里
混合标记文档中长度预测是否经常失准 空白基准的单词感觉和实际字符串处理错开多少

运营场景案例与示例

案例 1. 运行三个退款问题模板时

환불 정책을 알려줘、환불 관련 정책을 간단히 설명해 줘、환불이 가능한 조건만 짧게 정리해 줘 看起来是同一个意图,但根据 tokenizer,片段边界和 token 数可能以不同方式增加。

这个案例的问题场景,是把同一意图请求作为模板反复发送。人最先使用的标准是意思相似,成本也会相似。这个标准的限制在于,表达稍微变长或加上修饰语时,按 tokenizer 类型不同,片段数可能会以不同方式增加。

案例阶段 这个场景中的观察值 要确认的结果
人最先看的标准 三个句子都是退款政策问题 预期可以看成同一成本组
标准的限制 增加了 관련、간단히、가능한 조건만 等表达 各家族可能用不同方式切分新增表达
差异出现的瞬间 同一意图组中,某个表达的 token 数反复更大 成本差异可能先表现为片段数差异,而非意义差异
改变后的判断 比较常用模板的实际 token 数 把成本跳高的表达换成更短或更稳定的表达

因此这个案例要收住的句子是这个。tokenization 类型差异比理论说明更早出现在同样意思的请求为什么成本不同这个场景中。

案例 2. 政策 chunk 总是尴尬断开时

연차는 3일 전 신청 和 긴급 병가는 사후 보고 가능 必须留在同一个依据组中,但如果 token 片段和 chunk 边界错开,检索结果可能只带来原则而漏掉重要例外。

这个案例的问题场景,是按段落看起来自然的政策文档在检索中经常出错。人最先使用的标准是段落切得好看,所以 chunk 也应该没问题。这个标准的限制在于,chunk 实际上不是按字符数或段落数切,而是在 token 数和 token 边界上切。

案例阶段 这个场景中的观察值 要确认的结果
人最先看的标准 原则句和例外句在相近段落里 预期检索上下文也会一起抓到
标准的限制 同一短语的片段数因 tokenization 类型不同而不同 即使 chunk size 相同,边界位置也可能不同
差异出现的瞬间 检索结果只带来原则,漏掉例外条件 可能不是检索质量问题,而是 chunk 边界问题
改变后的判断 确认条件和例外是否留在同一个 token 组中 不按段落形状,而按 token 边界重新看 chunk size 与 overlap

因此这个案例要收住的句子是这个。tokenization 类型差异会在检索器出错的结果背后,以必要意义单位是否留在同一个 token 组中这个 chunk 边界问题显现。

案例 3. 混合标记文档中成本跳高时

混入 SDK v2.1、Authorization、长 URL、代码片段的句子,token 数可能比表面看起来增长得更快。同一文档中,某些 tokenizer 可能把这些区间读得更细,另一些 tokenizer 可能把它们保留成更大片段。

这个案例的问题场景,是文档看起来不长,但实际输入长度经常跳高。人最先使用的标准是只是几行短句,输入也应该短。这个标准的限制在于,数字、版本字符串、URL、代码片段、大小写混合,对 tokenizer 来说可能会拆成多个片段。

案例阶段 这个场景中的观察值 要确认的结果
人最先看的标准 SDK v2.1、Authorization、URL 是短标记 预期输入长度也很小
标准的限制 数字、点、斜线、大写字母、代码片段混合 空白基准单词感觉和实际片段边界错开
差异出现的瞬间 混合标记区间比普通句子的 token 数增长幅度更大 长度预测失败集中在特定标记区间
改变后的判断 单独检查混合标记密度高的句子 对 URL、代码、版本字符串考虑单独压缩或分离策略

因此这个案例要收住的句子是这个。tokenization 类型差异比起普通句子,在数字、英文、符号、代码混合区间中,以长度感觉崩塌的方式更清楚地显现。

失败场景中看见的 tokenization 差异

读 tokenization 类型差异时常见的失误是,即使想起了三个家族名称,也仍然不能马上选择现在的问题应该读成哪一个场景。这时与其问哪一个家族更好,不如先选择现在最先看见的失败是什么。

现在最先看见的失败 最先提出的问题 先重新查看的轴
意思相似的请求,成本差异却比预期大很多 表达稍微改变时,token 数在哪里拉开得更多? 成本差异
段落自然,但检索结果总是漏掉核心条件或例外 人看成一组的意义单位是否在 token 边界处分开? chunk 边界
数字、URL、英文、代码片段混在一起的文档中,长度感觉持续失准 混合字符串标记是否比空白基准单词感觉影响更大? 混合标记长度预测

这张表的目的不是重新解释 tokenizer 家族。它是为了在看到真实运营场景时,先分辨现在显现的差异是成本问题、chunk 问题,还是混合标记长度问题。

这里要收住的判断很明确。tokenization 类型差异不是名称差异,而是在成本差异、chunk 边界、混合标记长度预测中实际出现的观察值。

练习:把观察值分流到失败场景

不要把tokenization 类型差异停留为抽象比较。把同一个输入放进不同家族时会出现什么差异,再确认一次。

基于上面示例代码结果,直接分流三个场景。每个问题先自己回答,再和下面解说比较。

练习 1. 找出成本差异出现的瞬间

观察值:

输入 BPE gpt2 WordPiece bert-base-uncased SentencePiece google/mt5-small
회의는 내일 열립니다. 24 17 8
회의는 내일 10:00 AM에 열립니다. 31 23 11

先自己回答。

  • 加上数字和英文后,各家族 token 数分别增加了几个?
  • 这个差异是在说明哪一个家族更好,还是在说明成本差异什么时候出现?

解说:BPE 是 31 - 24 = 7 个,WordPiece 是 23 - 17 = 6 个,SentencePiece 是 11 - 8 = 3 个。这里的答案不是特定家族的优劣。即使是同一个日程通知,数字和英文一加上去,各家族增加幅度就不同。因此 tokenization 类型差异可能首先出现在成本预测场景中。

练习 2. 找出 chunk 边界差异出现的瞬间

观察值:

家族 韩语句子中看到的代表片段
BPE gpt2 韩语被细分成许多 byte 型片段
WordPiece bert-base-uncased 一部分是 [UNK],一部分是带 ## 的 subword 片段
SentencePiece google/mt5-small 회의、▁내、▁열、립니다 这类相对较大的片段

先自己回答。

  • 人看成一组的韩语短语,在哪一侧更有被细碎打散的风险?
  • 这个差异为什么会在检索 chunk 中成为问题?

解说:这个观察值中,BPE gpt2 和 WordPiece bert-base-uncased 更明显地把韩语短语打散。SentencePiece google/mt5-small 相对保留了较大的韩语片段。这个差异说明,即使段落看起来自然,实际 token 组中意义单位也可能分开。因此 tokenization 类型差异可能表现为检索结果漏掉条件或例外的 chunk 边界问题。

练习 3. 找出混合标记长度预测摇晃的瞬间

观察值:

输入 BPE gpt2 WordPiece bert-base-uncased SentencePiece google/mt5-small
회의는 내일 10:00 AM에 열립니다. 31 23 11
회의는 내일 10:00 AM, Zoom 링크 포함입니다. 39 30 16

先自己回答。

  • 加上 Zoom 링크 포함 后,各家族 token 数分别增加了几个?
  • 这个场景中,在成本、chunk、混合标记长度预测三者中,应该先重新查看哪一个轴?

解说:BPE 是 39 - 31 = 8 个,WordPiece 是 30 - 23 = 7 个,SentencePiece 是 16 - 11 = 5 个。三者都增加了,但增加幅度不同。这个场景的核心不是单纯成本计算,而是 10:00、AM、Zoom、링크 这样数字、英文、符号、韩语混合的区间会摇晃长度感觉。因此先重新查看的轴是混合标记长度预测。

这个练习的目标不是从三个家族中选一个正答。需要的是读出tokenization 类型差异实际出现在成本、chunk、混合标记长度预测中的瞬间。

检查清单

  • 能否说明同样意思的句子也可能有不同 token 数?
  • 能否说明 tokenization 类型差异可能出现在 chunk 边界和长度预测问题中?
  • 是否理解应该先看差异什么时候出现,而不是先问哪一个家族更优秀?
  • 能否说明直接使用代表 tokenizer 会显露字符数感觉和实际片段边界之间的差异?

出处与参考资料