Tokenizers 与上下文窗口详解
Tokenizers 与上下文窗口详解
“Tokenizers 是大模型的门卫——它决定了哪些文本能进来,以什么形式进来。”
一、什么是 Token?
人类读写的是文字,但大模型读写的是 Token。Token 是文本的最小处理单元,它不是简单的”字”或”词”,而是由分词器(Tokenizer)根据一定规则将文本切分后的片段。
举例来说,对于句子 “我不喜欢打游戏”:
| 分词方式 | Token 序列 |
|---|---|
| 按字分 | ["我", "不", "喜", "欢", "打", "游", "戏"] — 7个 Token |
| 按词分 | ["我", "不", "喜欢", "打游戏"] — 4个 Token |
| BPE(GPT-4等) | ["我不", "喜欢", "打游", "戏"] — 4个 Token |
同一个句子,不同的分词器会产生完全不同的 Token 序列,导致相同的文字消耗的 Token 数量不同。
二、主流分词算法
2.1 BPE(Byte Pair Encoding)
BPE 是当前最流行的分词算法,GPT 系列、LLaMA 等主流大模型都使用它。
核心思想:从字符开始,迭代地合并出现频率最高的 token 对。
训练过程(以 “aaabde” 为例):
1 | 初始词表:['a', 'b', 'd', 'e'] |
优点:
- 可以用较小的词表表示任意文本(包括罕见词、新词)
- 平衡了词边界(word boundary)和词表大小(vocabulary size)
- 词表通常在 3万~10万 token 之间
GPT-4 的 Tokenizer 就是 BPE 的变种,据说词表约 10 万个左右。
2.2 WordPiece(BERT 使用)
WordPiece 的思想与 BPE 类似,但合并的标准不是”最高频率”,而是”最大化语言模型 likelihood”。
1 | # BPE 合并标准:频率最高的 token 对 |
BERT 的词表约 3 万个 token,对中文采用了字级别的切分(每个汉字一个 token),因此中文文本的 token 消耗通常是字数的 1.5~2 倍。
2.3 Unigram(SentencePiece 使用)
与 BPE 和 WordPiece 自下而上合并不同,Unigram 是自上而下——从大词表开始,迭代地删除对损失函数贡献最小的 token。
LLaMA、Chinchilla 等模型使用 SentencePiece(基于 Unigram),支持多语言统一词表,不需要语言特定的预处理。
三、中英文 Token 消耗对比
| 文本 | 中文字符数 | 英文单词数 | 大致 Token 数(中文) | 大致 Token 数(英文) |
|---|---|---|---|---|
| “你好世界” | 4 | — | 4~6 | — |
| “Hello, world!” | — | 2 | — | 2~4 |
| 一篇 1000 字的文章 | 1000 | — | 500~800 | — |
| 一篇 500 词的英文文章 | — | 500 | — | 600~750 |
粗略经验:
- 英文:1 Token ≈ 0.75 个单词 ≈ 4 个字符
- 中文:1 Token ≈ 0.5~1.5 个汉字
- 代码:Token 消耗通常高于普通文本
一个实用的工具是 OpenAI 的 Tokenizer 工具,可以直观地看到任意文本被如何切分。
四、上下文窗口(Context Window)
4.1 什么是上下文窗口?
上下文窗口指的是 Transformer 在一次前向传播中能处理的最大 Token 数量。超出这个范围的文本,模型”看不见”。
1 | 上下文窗口 = 4096 tokens → 最多处理约 3000 个英文单词 或 2000 个汉字 |
4.2 为什么上下文窗口有限制?
回顾 Transformer 的复杂度:
1 | Self-Attention: O(n² · d) |
其中 n 是序列长度。如果把上下文窗口扩大 4 倍(n → 4n),计算量会增加 16 倍!这是二次方增长的恐怖之处。
此外,更长的上下文意味着更大的 KV Cache(后文会讲),对显存的要求也急剧增加。
4.3 上下文窗口的发展历程
| 年份 | 模型 | 上下文窗口 |
|---|---|---|
| 2020 | GPT-3 | 4,096 tokens |
| 2022 | GPT-4(初始版) | 8,192 tokens |
| 2023 | Claude 2 | 100K tokens |
| 2023 | GPT-4 Turbo | 128K tokens |
| 2024 | Claude 3.5 | 200K tokens |
| 2024 | Gemini 1.5 | 1M tokens |
从 4K 到 1M,增长了 250 倍,主要依靠以下技术突破:
- FlashAttention:注意力计算的 IO 优化,不改变数学等价性
- Ring Attention:分布式注意力,支持超长序列
- Sparse Attention:稀疏化注意力,跳过不重要的计算
- 位置编码外推:让模型能够处理训练时未见过的超长位置
五、位置编码与上下文扩展
5.1 预训练阶段的位置范围
训练一个大模型时,需要指定一个最大上下文窗口(例如 4096),在这个范围内收集数据、训练位置编码。一旦训练完成,模型处理超出训练长度的新位置时,可能会出现质量下降。
5.2 位置编码外推(Position Extrapolation)
有两种策略处理训练长度外的新位置:
策略一:扩展位置编码
- 原始 RoPE 在 4096 以内训练 → 直接扩展到 32768
- 位置索引超过 4096 时,通过插值或重新缩放映射回已训练范围
- 如 ALiBi(Attention with Linear Biases):用线性偏置替代绝对位置编码,更容易外推
策略二:上下文窗口滚动
- 保持模型参数不变,使用滑动窗口处理超长文本
- 类似于人类的阅读习惯——一次只能看完一页,但可以记住前文的核心内容
- 代表工作:Longformer、BigBird
5.3 经验法则
如果你发现模型在处理长文本时开始”遗忘”开头的内容,这是上下文窗口不足的典型症状。
对于需要处理长文档的场景,应该选择上下文窗口更大的模型,或者考虑使用RAG(检索增强生成)将长文本切分后分批处理。
六、实用技巧
6.1 估算 Token 数量
1 | # 粗略估算 |
6.2 节省 Token 的技巧
- 删除不必要的格式化:大模型的 Markdown 输出会消耗额外 token
- 压缩 prompt:将长 System Prompt 精简,只提供必要信息
- Few-shot 示例不要贪多:2~5 个高质量示例优于 20 个低质量示例
6.3 Token 计数工具
- OpenAI Tokenizer
- tiktoken(Python 库)
- anthropic/tokenizer
总结
理解 Tokenizers 和上下文窗口,是掌握大模型边界的重要一环:
- Token 数量直接影响成本和速度——用 GPT-4 处理 10 万字和 1000 字,成本差 100 倍
- 上下文窗口是大模型的”视野”——超过这个范围,模型需要借助外部记忆(如 RAG)
- 选择合适的模型和策略——长文本处理选择大上下文窗口模型或 RAG 方案
相关文章: