# 分词与词表

URL: https://caijiao.org/nlp/tokenization
Source: docs/nlp/tokenization.md
Description: 本章介绍分词的基本原理、常见算法（如BPE、WordPiece）、以及词表（Vocabulary）的构建与使用。

分词（**Tokenization**）是自然语言处理的首要步骤之一，它将原始文本拆分成可处理的最小语言单元（token），例如词、子词或字符。

词表（**Vocabulary**）则定义了模型能识别的 token 集合，是文本与向量表示之间的桥梁。

## 一、为什么需要分词

计算机无法直接理解自然语言中的连续字符。  
例如输入句子：

> 我爱自然语言处理。

模型需要将其转换为离散单元，如：

```txt
我 / 爱 / 自然语言处理 / 。
```

或在英文中：

```txt
I / love / NLP / .
````

经过分词后，文本可映射为数字序列，方便模型计算与学习。

## 二、常见的分词方式

| 类型 | 说明 | 示例 |
|------|------|------|
| **基于空格** | 英文常用，按空格分割 | "I love NLP" → ["I","love","NLP"] |
| **基于词典** | 中文常用，匹配最长词 | "南京市长江大桥" → ["南京市","长江大桥"] |
| **基于统计** | 根据词频与互信息学习新词 | 自动识别 "自然语言处理" |
| **基于子词（Subword）** | 拆分为可组合的子单元，解决 OOV 问题 | "unbelievable" → "un"+"believ"+"able" |

## 三、常见子词算法

### 1. BPE（Byte Pair Encoding）

基于统计的合并规则。通过反复合并高频 token 对，生成稳定的子词表。  
广泛用于 GPT、RoBERTa 等模型。

### 2. WordPiece

Google 提出的改进算法，用于 BERT 系列模型。  
相比 BPE 更注重概率优化，使生成的子词更均衡。

### 3. SentencePiece

不依赖空格，直接作用于原始字节流。  
支持 **Unigram** 与 **BPE** 模式，是多语言模型常用方案。

## 四、词表（Vocabulary）

词表定义了 token 与 ID 的映射关系：

| Token | ID |
|--------|----|
| `[PAD]` | 0 |
| `[CLS]` | 1 |
| `我` | 2 |
| `爱` | 3 |
| `自然` | 4 |

词表的大小（`vocab_size`）会影响模型性能与内存占用。  
在中文中常用 20k~50k，英文常用 30k~60k。

## 五、实践示例（Python）

```python
from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained("bert-base-chinese")
text = "我爱自然语言处理"
tokens = tokenizer.tokenize(text)
ids = tokenizer.convert_tokens_to_ids(tokens)

print(tokens)
print(ids)
````

输出示例：

```txt
['我', '爱', '自然', '语言', '处理']
[2769, 4263, 704, 6421, 7032]
```

## 六、小结

* 分词是 NLP 的基础步骤，决定模型理解语言的粒度；
* 子词算法（如 BPE、WordPiece）有效解决 OOV 问题；
* 合理构建词表能平衡模型容量与泛化能力。
