跳转至

Tokenization and Multilinguality

3091 个字 10 行代码 9 张图片 预计阅读时间 31 分钟

这一章的核心问题是:

Language model 看到的不是 raw text,而是 token sequence。那么 token 应该怎么定义?

Tokenization 看起来像一个预处理细节,但它会在模型训练之前就决定很多事情:

  • 模型能直接观察到什么语言单位
  • 同一段文本会变成多长的 sequence
  • embedding matrix 需要多大
  • 稀有词、拼写、错别字、多语言文本会不会被合理表示
  • 不同语言用户在 token 数和 API 成本上是否公平

tokenization-lm-pipeline-15

Important

Tokenizer 不是中性的。

它决定了 string token IDs 的映射,也就决定了模型最底层的输入单位。

What is a token?

自然语言里没有唯一正确的切分方式。

例如:

We'd sat back on the grass, and time flew by as we looked at the Milky Way.

可以按很多层级切分:

  • Character / byte
    • W, e, ', d, ...
  • Morpheme
    • looked = look + -ed
    • Milky = milk + -y
  • Word
    • whitespace-separated words
  • Phrase / entity
    • Milky Way 可以作为一个整体实体

对语言学来说,word, morpheme, phrase 都有意义;但对 LM 来说,关键是选择一种可计算、可扩展、泛化好的单位。

Tokenizer in Language Models

language model 来说:

  • Token
    • 模型学习和预测的基本单位
  • Tokenization
    • text 切成 tokens 的过程
  • Vocabulary
    • tokenizer 已知的 token 集合
  • Token IDs
    • vocabulary 中每个 token 的整数编号

流程大致是:

\[ \text{text} \xrightarrow{\text{tokenizer}} \text{token ids} \xrightarrow{\text{embedding lookup}} \text{embeddings} \xrightarrow{\text{LM}} \text{next-token distribution} \]

模型不能直接读取 raw string,所以必须先有一个从 string embedding sequence 的映射。

Tip

Tokenizer 通常在核心 LM 之外训练或定义。

因此 tokenization 会在模型训练前就影响模型的输入形状和学习难度。

Tokenization 主要影响两个效率维度:

  • Sequence length
    • token 越细,序列越长,attention 的计算和显存压力越大
  • Vocabulary size
    • token 越粗,词表越大,embedding matrix output projection 越大

可以把 tokenization 看成一个 tradeoff

\[ \text{long sequence, small vocab} \quad \leftrightarrow \quad \text{short sequence, large vocab} \]

Word Tokenization

最直接的方案是 word tokenization

  • 先按 whitespace punctuation 切分文本
  • corpus 中选出 top \(V\) frequent words 作为 vocabulary
  • 每个 word 大致对应一个 embedding

优点:

  • token 通常有清楚的语义
  • sequence length 相对短
  • 一个 token embedding 比较容易解释

word-level vocabulary 会遇到严重问题。

首先是 Zipf's law

词的频率和它的 rank 大致成反比。

也就是说,少数高频词出现很多次,大量低频词只出现很少次。语言还在不断变化,新词、缩写、拼写变体都会出现。

第二个问题是 out-of-vocabulary (OOV)

  • 测试时出现词表外单词怎么办?
  • rule-based preprocessing 可以修正一部分 typo,但不可靠
  • UNK token 会把很多不同词压成同一个符号,丢失内部结构

例如:

Zipf's law is importaNt in NLP.

如果 importaNt 不在 vocabulary 里,word tokenizer 可能只能把它变成 UNK。模型看不到它和 important 之间的拼写关系。

Warning

Word tokenization 的核心缺陷是 coverage

词表不可能完整覆盖语言里的所有词、拼写变体、新词和跨语言文本。

Character and Byte Tokenization

另一个极端是 character-level byte-level tokenization

  • character-level:token Unicode character
  • byte-level:token byte,例如 UTF-8 bytes
  • byte character 不完全一样:
    • 一个 emoji 可能是 1 character,但占多个 bytes
    • 一个中文字符通常也会占多个 UTF-8 bytes

优点:

  • vocabulary 很小
  • 几乎没有 OOV
  • 模型可以直接观察 spelling character composition
  • typo、罕见词、新词更有覆盖能力

缺点:

  • sequence length 很长
  • 更难直接形成 word / phrase 级别表示
  • 对普通 Transformer 来说,长序列会显著增加计算成本

因此,character / byte tokenization 的问题不是表示不了文本,而是计算是否高效、模型是否容易从低层单位归纳出高层结构。

Subword Tokenization

Subword tokenization 试图折中:

高频词可以作为完整 token,低频词可以拆成多个 subword

tokenization-subword-tradeoff-22

这种方法的直觉是:

  • corpus statistics 决定 vocabulary
  • 高频片段更可能被合并成一个 token
  • 低频词最坏也能退化成 byte / character sequence
  • coverage efficiency 之间取得平衡

常见 subword 方法包括:

  • Byte Pair Encoding (BPE)
    • byte / character 开始,反复合并最常见的相邻 token pair
  • WordPiece
    • BPE 类似,但合并标准更接近最大化数据 likelihood
  • Unigram Language Model
    • 从较大的候选 subword 集合开始,逐步删掉 token

本章重点是 BPE,因为它简单、确定、实现高效,也是现代 LLM 中非常常见的 tokenizer family

Byte Pair Encoding

BPE 训练需要两个输入:

  • training corpus \(D\)
  • desired vocabulary size \(N\)

tokenization-bpe-training-algorithm-25

训练过程可以概括为:

  1. corpus pre-tokenization,例如先按 whitespace 切分
  2. 初始化 vocabulary \(V\),包含 corpus 中出现的 bytes
  3. corpus 表示成 byte sequence
  4. \(|V| < N\) 时重复:
    • 统计 corpus 中所有相邻 token pair 的频率
    • 找到最高频 pair \((v_i, v_j)\)
    • 合并成新 token \(v_n = v_i v_j\)
    • corpus 中所有这个 pair 替换成新 token

用公式写就是:

\[ v_n = v_i v_j \]

其中:

\[ n = |V| + 1 \]

每次 merge 后,corpus tokenization 都会变化,所以 bigram frequency table 也要重新计算或增量更新。

Important

BPE 学到的不是语言学意义上的 morpheme

它学到的是在训练语料中高频、可压缩的相邻片段。

BPE example intuition

假设语料是:

Peter Piper picked a peck of pickled peppers

pre-tokenize 后可以用 _ 表示 word boundary

Peter, _Piper, _picked, _a, _peck, _of, _pickled, _peppers

初始化时 token bytes,例如:

P e t e r _ P i p e r _ p i c k e d ...

如果 _ + p 出现最多,就先合并为 _p;如果 c + k 高频,就合并为 ck;之后可能继续合并出_pe , _pi , _pick token

这个过程会把频繁出现的字符序列压缩成更大的 subword

Test-time BPE

训练结束后,BPE tokenizer 保存的是一个 ordered merge list

test time tokenize 一个新词时:

  1. 先把输入拆成 bytes
  2. 按训练得到的 merge list 顺序应用 merge
  3. 不能 merge 的部分保持为更小 token

tokenization-bpe-testtime-54

例如 _pier 可能会经历:

_ p i e r
_p i e r
_p i er
_pi er

因为 merge list 中可能有_ + p -> _p ,e + r -> er , _p + i -> _pi,但没有足够规则把整个 _pier 合成一个 token

Tip

BPE 的强项是 deterministic compression

它避免了 word-level OOV,同时比 character / byte sequence 短得多。

Whitespace Is Not Universal

许多 tokenizer 会先做 whitespace pre-tokenization,但这并不总合理:

  • 中文、日文、泰文等语言不一定用 whitespace 分词
  • multi-word expression 可能跨越 whitespace,例如 on the other hand
  • 有些语言中的 word boundary 本身就不容易用简单规则定义

SentencePiece 的重要点是:

  • 它是 tokenizer library,不是单一算法
  • 可以实现 BPE Unigram LM
  • whitespace 当成 vocabulary 中的基本符号处理
  • 常用于 T5, Llama 2, XLM-R, Gemma 等模型

SuperBPE 则进一步尝试放松 whitespace 限制,先学 subword,再学习跨 whitespace 的更大 token,以减少词表或推理成本。

Where Subword Tokenization Breaks

BPE 是很强的工程折中,但它并没有解决所有问题。

Spelling

Subword model 看到的是 subword chunks,不是 character sequence

tokenization-spelling-case-59

例如 strawberry

  • GPT-2 可能看到的是str ,aw , berry
  • 某些新 tokenizer 可能直接把整个 strawberry 当成一个 token

这两种情况都不等价于模型直接看到了:

s t r a w b e r r y

因此模型在 character-level tasks 上会遇到天然困难:

  • 数某个字母出现几次
  • 拼写一个词
  • 反转字符串
  • 判断 typo

Important

如果 tokenizer 没有把 character 暴露给模型,模型就必须从 subword embedding 中反推出 character 信息。

这不是它训练时最自然的输入单位。

一个 typo 还可能改变后续所有 BPE merge boundary,使 token sequence 完全不同,从而影响鲁棒性。

Glitch Tokens

Glitch token 来自 tokenizer LM 训练数据的不匹配。

tokenization-glitch-tokens-61

典型情况是:

  • BPE tokenizer 在一个 corpus 上训练
  • LM 在另一个 corpus 上训练
  • 某些 token 因为 tokenizer corpus 中高频而进入 vocabulary
  • 但这些 token LM training corpus 中很少出现,甚至几乎没有出现
  • 对应 embedding 训练不足,行为可能异常

著名例子是 SolidGoldMagikarp

  • 它因为某些数据分布进入 tokenizer vocabulary
  • 但语言模型训练中几乎没有足够上下文学习它的含义
  • 模型面对它时可能无法稳定复述或解释

这不只是趣事,还会带来实际问题:

  • 浪费 vocabulary slots
  • 引入未充分训练的 embedding
  • 形成 adversarial attack surface

Warning

Tokenizer training data LM training data 最好保持一致或至少分布接近。

否则 tokenizer 可能把模型几乎没学过的字符串做成独立 token

Why Multilinguality Matters

世界上有超过 7000 种被记录的语言,而英语只是其中一部分:

  • 大约 20% 的世界人口会说英语
  • native English speakers 只占更小比例
  • 现实 NLP 需求包括 translation, cross-lingual retrieval, code-switching

但互联网语料极不均衡:

  • Common Crawl 中英语比例很高
  • 很多 low-resource languages 在网页语料中占比极小
  • labeled data, tools, benchmarks 也集中在 high-resource languages

因此 multilingual NLP 的目标不是“让英语模型顺便支持别的语言”,而是让模型在不同语言上都能可靠、低成本地工作。

Multilingual Language Modeling

Multilingual LM 在架构上并不特殊:

  • 仍然可以是 Transformer encoder / decoder / encoder-decoder
  • 仍然使用 MLM CLM 等训练目标
  • 主要区别是 tokenizer LM training data 使用多语言 corpus

流程可以写成:

\[ \text{text in many languages} \rightarrow \text{train multilingual tokenizer} \rightarrow \text{train LM} \]

Cross-lingual Transfer

Multilingual LM 的一个重要现象是 cross-lingual transfer

模型只在一种语言的 labeled data finetune,却能在另一种语言上 zero-shot 使用。

tokenization-cross-lingual-transfer-67

例如:

  1. 预训练时,XLM-R 在多语言语料上做 masked language modeling
  2. Finetune 时,只用英语 sentiment labels
  3. 推理时,把模型用于法语、德语、中文等语言

直觉是:多语言预训练让模型学到某种 shared representation space。只要不同语言的表达在这个空间中对齐,英文监督信号就可能迁移到其他语言。

Vocabulary Overlap

Vocabulary overlap 会影响 cross-lingual transfer

如果不同语言之间有共享 token

  • 共享 token embedding 可以成为跨语言桥梁
  • 即使是 false friends,也可能帮助模型建立跨语言 representation
  • 更高 overlap 往往有利于 transfer,但效果依赖具体任务

但还有另一个问题:每种语言都需要足够的 vocabulary allocation

如果把很多语言塞进固定大小 vocabulary

  • high-resource language 可能占据大量 token
  • low-resource language 可能被切得更碎
  • 增大 vocab 可以缓解覆盖问题,但会增加 embedding softmax 成本

The Curse of Multilinguality

Cross-lingual transfer 听起来像解决低资源语言问题的捷径,但并不完全。

Curse of multilinguality 指的是:

增加语言数量一开始有助于 transfer,但在固定模型容量下,语言继续增加会导致性能下降。

原因包括:

  • 模型参数有限
  • tokenizer vocabulary 有限
  • 每种语言分到的训练容量和表示空间有限
  • 高资源语言和低资源语言之间会竞争模型容量

因此,多语言建模不是简单地“加入更多语言”。它需要在语言覆盖、模型容量、数据采样、tokenizer design 之间做权衡。

Tokenization Fairness

多语言场景下,tokenization 本身会引入不公平。

tokenization-unfairness-71

同一段语义等价的文本,不同语言可能被切成完全不同数量的 tokens

这会造成几个后果:

  • Cost unfairness
    • token 计费的 API 中,某些语言表达同样意思要付更多钱
  • Context unfairness
    • 同样的 context window,某些语言能放入的信息更少
  • Quality unfairness
    • token sequence 更长、更碎时,模型更难建模,性能可能下降

一个常用指标是 subword fertility

\[ \text{subword fertility} = \frac{\text{number of subword tokens}}{\text{number of words}} \]

subword fertility 越高,说明平均每个 word 被拆成更多 subword。研究中常观察到它和 downstream performance 有负相关。

Important

多语言 tokenization 的公平性问题不是训练之后才出现的。

它在 tokenizer 阶段就已经开始了。

Revisiting Character and Byte Models

多语言建模也让 character / byte tokenization 重新变得有吸引力。

原因是:

  • byte / character vocabulary 可以覆盖几乎所有语言
  • 未见过的语言也可以被表示
  • 不容易出现 OOV
  • 不会因为稀有字符串进入 vocabulary 而产生同样形式的 glitch token
  • spelling character-level manipulation 更自然

问题仍然是 sequence length

因此新的方向通常不是简单回到普通 character Transformer,而是设计更高效的 byte-level architecture

tokenization-mrt5-byte-compression-73

例子包括:

  • CANINE
    • character-level counterpart to mBERT
  • ByT5
    • byte-level seq2seq model
  • MrT5
    • 动态删除部分 bytes,让模型只在必要位置保留长序列
  • Byte Latent Transformer / HAT / H-Nets
    • hierarchical latent tokenization 思路降低 byte-level 建模成本

可以把这些方向理解成:

\[ \text{raw bytes / characters} \rightarrow \text{learned compression} \rightarrow \text{higher-level representations} \]

Tip

Byte-level model 并不是放弃 tokenization

更准确地说,它把“什么是有用的语言单位”从固定 tokenizer 中移到模型结构和训练过程中学习。

Summary of Tokenization and Multilinguality

  • Tokenization 决定 LM 的基本输入单位,不只是预处理细节
  • Word tokenization 语义清楚、序列短,但有 OOV long-tail 问题
  • Character / byte tokenization 覆盖强、词表小,但 sequence length 很长
  • Subword tokenization coverage efficiency 之间折中
  • BPE byte 开始,反复合并最高频相邻 token pair,最终得到 merge list
  • BPE 没有 OOV,但会在 spelling、typo、character-level tasks 上暴露问题
  • Glitch tokens 往往来自 tokenizer corpus LM training corpus 的不匹配
  • Multilingual LM 依赖多语言 tokenizer 和多语言预训练,能产生 cross-lingual transfer
  • Vocabulary overlap 有利于跨语言迁移,但固定容量下会出现 multilinguality tradeoff
  • Tokenization 会造成语言间 token 数、API 成本和上下文利用的不公平
  • Character / byte models 重新受到关注,因为它们更适合覆盖多语言和字符级现象,但需要更高效的架构