一句话总结
Token = LLM处理文本的最小单位。一段文字先被切分成Token序列,再映射成整数ID,最后转为向量送入模型。分词算法决定了怎么切,上下文窗口决定了能吃多少。
1. 为什么需要Token?
LLM的输入是数值张量,不能直接吃字符串。中间需要两步转换:
"你好世界" → ["你", "好", "世", "界"] → [1234, 5678, 9012, 3456]
文本 Token序列 Token ID序列
Token是文本和数值之间的桥梁。分词算法决定"怎么切",词表决定"每个Token对应什么数字"。
2. 三大分词算法
2.1 BPE (Byte Pair Encoding)
核心思想:从字符级别开始,不断合并最高频的字符对,直到达到目标词表大小。
步骤:
- 初始化:每个字符是一个Token
- 统计所有相邻字符对的频率
- 合并频率最高的字符对为新Token
- 重复2-3,直到词表大小达到预设值
示例:
初始词表: l, o, w, e, r, n, s, t, i, d
语料: low lower lowest new newest
第1轮: 合并 l+o → lo (出现2次)
第2轮: 合并 lo+w → low (出现2次)
第3轮: 合并 e+r → er (出现2次)
...
谁在用:GPT-2、GPT-3、GPT-4(用tiktoken库)、Claude
2.2 WordPiece
核心思想 :类似BPE,但选择合并对的标准不是频率,而是似然增益(合并后对语言模型概率的提升)。
"语言模型概率增加最多"到底是什么意思?
假设当前词表把 "play" 和 "##ing"(##表示非词首片段)分成两个Token,合并后变成 "playing" 一个Token。合并前后,语言模型对同一份语料的预测概率会变化:
合并前:P(语料) = P(play) × P(##ing) × ... (两个Token各自独立出现)
合并后:P(语料) = P(playing) × ... (一个Token整体出现)
似然增益 = log P(playing) - [log P(play) + log P(##ing)]
如果 "playing" 作为一个整体出现频率很高,合并后语言模型就能用更少的Token表示同样的文本,概率值更高。WordPiece选的就是让这个增益最大的那个pair。
直观对比:
- BPE:看统计频次 → "哪对出现最多就合并谁"(只看数量)
- WordPiece:看概率提升 → "合并哪对能让模型更好地预测文本"(看对模型有没有用)
💡 举个例子:假设语料中
"th"出现100次,"in"也出现100次,但"qu"只出现50次。BPE会优先合并"th"或"in"。但如果合并"qu"后模型对文本的预测概率提升更大(因为q后面几乎总是u,合并消除了不确定性),WordPiece反而会选"qu"。
谁在用:
-
BERT(Bidirectional Encoder Representations from Transformers):Google 2018年发布的预训练语言模型,双向编码器架构,是NLP领域的里程碑。它通过"完形填空"式预训练(随机遮盖15%的Token让模型预测),学会了深度理解上下文语义。BERT开创了"预训练+微调"范式,之后几乎所有NLP模型都走这条路。
-
DistilBERT:BERT的蒸馏版(Distillation = 知识蒸馏)。把大模型的知识"压缩"进小模型------保留97%的BERT性能,参数量减半、速度快60%。简单说就是BERT的轻量平替,适合资源有限或对延迟敏感的场景。
2.3 Unigram
核心思想 :从大词表开始,逐步删除对整体损失影响最小的Token,直到达到目标词表大小。
与BPE相反的方向:
- BPE:从小到大(不断合并)
- Unigram:从大到小(不断裁剪)
"最小损失影响"到底是什么意思?
Unigram给每个Token算一个"重要性分数"------如果删掉这个Token,语言模型对语料的预测概率会下降多少。下降越多说明这个Token越重要,应该保留。
假设当前词表有 V 个Token,语料的对数似然为 L
删除 Token X 后,重新计算语料的对数似然 L'
损失增量 Δ = L - L'
Δ 越小 → Token X 越不重要 → 优先删除
Δ 越大 → Token X 越不可替代 → 保留
直观举例 :假设词表里有 "the" 和 "zxq"。删掉 "the" 后,大量英文句子无法正确编码,损失暴增;删掉 "zxq" 后几乎没影响。Unigram就会删 "zxq"。
Unigram的独特优势:一个文本多种切法
BPE和WordPiece对同一段文本只有一种切法,Unigram不同------它保留每个Token的概率分布,一段文本可以有多种分词方式,按概率加权选择:
"undoing" 可能的切法:
un + do + ing (概率 0.6)
un + do + i + ng (概率 0.3)
u + n + doing (概率 0.1)
这种多候选特性让Unigram在处理歧义文本时更灵活。
谁在用:
- T5(Text-to-Text Transfer Transformer):Google 2019年提出的统一框架,把所有NLP任务都转成"文本→文本"格式(翻译是en→de,分类是text→label,摘要是长文→短文)。这种统一让一个模型一个训练流程搞定所有任务。
- ALBERT:BERT的轻量版,通过参数共享(所有层共用同一套参数)和词表分解(把大词表拆成小矩阵映射)大幅缩减参数量,ALBERT-xxlarge参数只有BERT-large的1/18,但性能更优。
- SentencePiece:Google开源的分词工具库,Unigram是它的默认模式,也支持BPE。不依赖预分词,直接从原始文本训练词表,对中文/日文等无空格语言特别友好。
2.4 三种算法对比
| 特性 | BPE | WordPiece | Unigram |
|---|---|---|---|
| 方向 | 自底向上合并 | 自底向上合并 | 自顶向下裁剪 |
| 选择标准 | 最高频率 | 最大似然增益 | 最小损失影响 |
| 多候选 | 否 | 否 | 是(保留概率分布) |
| 典型模型 | GPT系列 | BERT系列 | T5系列 |
| 实现库 | tiktoken | tokenizer | SentencePiece |
3. Token ID与词表
每个Token对应词表中的一个整数索引(Token ID):
python
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4")
tokens = enc.encode("Hello, world!")
print(tokens) # [9906, 11, 1917, 0]
# 解码回来
text = enc.decode(tokens)
print(text) # "Hello, world!"
词表大小:
| 模型 | 词表大小 | 分词算法 |
|---|---|---|
| GPT-2 | 50,257 | BPE |
| GPT-4 | 100,256 | BPE (cl100k_base) |
| BERT | 30,000 | WordPiece |
| LLaMA 2 | 32,000 | SentencePiece (BPE) |
| LLaMA 3 | 128,256 | BPE |
词表越大,每个Token承载的信息越多,同样文本需要的Token数越少。这也是LLaMA 3把词表从32K扩到128K的原因------提升多语言编码效率。
4. 特殊Token
模型除了正常文本Token,还定义了一些特殊Token:
| Token | 作用 | 使用模型 |
|---|---|---|
[CLS] |
分类任务的特殊标记 | BERT |
[SEP] |
分隔句子 | BERT |
[MASK] |
掩码语言模型预训练 | BERT |
[PAD] |
填充短序列 | 通用 |
| `< | endoftext | >` |
| `< | im_start | >` |
| `< | im_end | >` |
<s> / </s> |
序列起止 | LLaMA |
这些Token在词表中有固定ID,不对应任何真实文本。
5. 上下文窗口
上下文窗口 = 模型一次能处理的最大Token数。2026年的趋势是1M上下文成为旗舰标配:
| 模型 | 上下文窗口 | 发布时间 |
|---|---|---|
| GPT-4 | 8K / 32K | 2023 |
| Claude 3 | 200K | 2024 |
| GPT-5.5 | 1M | 2026 |
| Claude Opus 4.7 | 1M | 2026 |
| DeepSeek V4 Pro | 1M | 2026 |
| GLM-5.1 | 202K | 2026 |
| Kimi K2.6 | 256K | 2026 |
| MiniMax M2.7 | 196K | 2026 |
为什么不能无限长? Self-Attention的计算复杂度是O(n²),序列长度翻倍,计算量翻四倍。但2026年的新模型通过稀疏注意力、KV Cache压缩等技术,已经把1M上下文做到了生产可用------DeepSeek V4的KV Cache仅为V3.2的10%。
实际影响:
- 1K Token ≈ 750个英文单词 ≈ 500个中文字
- 一篇CSDN文章约2K-5K Token
- 一本小说约100K-300K Token
- 1M上下文 = 可以一次性塞入整本《三体》+ 提问
6. 中英文Token效率差异
中文的Token效率比英文低,因为中文词表覆盖不足:
python
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4")
# 英文
en_tokens = enc.encode("Hello, how are you today?")
print(f"英文: {len(en_tokens)} tokens") # 6 tokens
# 中文
zh_tokens = enc.encode("你好,你今天怎么样?")
print(f"中文: {len(zh_tokens)} tokens") # 10-15 tokens
原因:GPT的BPE词表以英文语料训练,中文常被切成单字甚至UTF-8字节,导致同样信息量下中文消耗更多Token。
直接影响:中文API调用比英文贵1.5-2倍(按Token计费)。
7. Token计费
2026年主流模型全部按Token计费,输入+输出分开定价,价格差异可达107倍。以下是2026年5月最新定价:
| 模型 | 输入价格 | 输出价格 | 缓存价格 | 上下文 |
|---|---|---|---|---|
| GPT-5.5 | $5.00 | $30.00 | $0.50 | 1M |
| Claude Opus 4.7 | $5.00 | $25.00 | $0.50 | 1M |
| GLM-5.1 | $1.40 | $4.40 | $0.26 | 202K |
| Kimi K2.6 | $0.95 | $4.00 | $0.16 | 256K |
| DeepSeek V4-Pro | 1.74 (0.435折扣) | 3.48 (0.87折扣) | --- | 1M |
| DeepSeek V4-Flash | $0.14 | $0.28 | --- | 1M |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | 196K |
价格分层很明显:旗舰推理模型(GPT-5.5 / Claude Opus 4.7)贵一个数量级,但长上下文和复杂推理能一次做对;轻量模型(DeepSeek V4-Flash / MiniMax M2.7)便宜到离谱,适合高并发和简单任务。DeepSeek V4-Pro折扣期(截至2026-05-31)性价比碾压全场。
省钱技巧:
- 用tiktoken预估Token消耗再调API,别盲调
- 简单任务用DeepSeek V4-Flash或MiniMax M2.7,复杂推理才上GPT-5.5
- 长上下文+重复前缀的场景,启用Prompt Caching可省80-90%
- 国内业务优先用DeepSeek或GLM,成本仅为OpenAI的1/10
python
# 预估Token消耗(2026年5月定价)
import tiktoken
PRICING = {
"gpt-5.5": {"input": 5.00, "output": 30.00, "cache": 0.50},
"claude-opus-4.7":{"input": 5.00, "output": 25.00, "cache": 0.50},
"glm-5.1": {"input": 1.40, "output": 4.40, "cache": 0.26},
"kimi-k2.6": {"input": 0.95, "output": 4.00, "cache": 0.16},
"ds-v4-pro": {"input": 1.74, "output": 3.48, "cache": None},
"ds-v4-flash": {"input": 0.14, "output": 0.28, "cache": None},
"minimax-m2.7": {"input": 0.30, "output": 1.20, "cache": 0.06},
}
def estimate_cost(text, model="ds-v4-pro", output_ratio=2.0, use_cache=False):
"""估算API调用成本
text: 输入文本
model: 模型名
output_ratio: 输出长度相对输入的倍数
use_cache: 是否启用prompt caching
"""
enc = tiktoken.encoding_for_model("gpt-4") # 大部分模型沿用cl100k_base
n_input = len(enc.encode(text))
n_output = int(n_input * output_ratio)
p = PRICING[model]
input_price = p["cache"] if use_cache and p["cache"] else p["input"]
cost = (n_input * input_price + n_output * p["output"]) / 1_000_000
return cost, n_input, n_output
# 示例:估算一篇5000字中文博客的摘要成本
text = "一篇约5000字的中文技术博客内容..."
for model in ["ds-v4-flash", "kimi-k2.6", "gpt-5.5"]:
cost, n_in, n_out = estimate_cost(text, model, output_ratio=0.3)
print(f"{model:15s}: ${cost:.4f} (输入{n_in} / 输出{n_out} tokens)")
# 输出示例:
# ds-v4-flash : $0.0005 (输入3750 / 输出1125 tokens)
# kimi-k2.6 : $0.0081 (输入3750 / 输出1125 tokens)
# gpt-5.5 : $0.0525 (输入3750 / 输出1125 tokens)
8. 面试高频问题
Q1:BPE和WordPiece的核心区别?
BPE选最高频pair合并,WordPiece选最大似然增益的pair合并。WordPiece更"聪明"------它不只看频率,还看合并后对模型概率的贡献。
Q2:为什么中文比英文费Token?
GPT的BPE词表以英文语料训练,中文高频字/词在词表中的覆盖率低,经常被切成单字甚至字节。LLaMA 3把词表扩到128K后中文效率大幅提升。
Q3:上下文窗口能训练后扩展吗?
可以,但有上限。RoPE位置编码支持通过插值扩展(如CodeLlama从16K→100K)。但训练数据中长文本比例低时,长上下文效果会退化。
Q4:Token和Character的区别?
Character是字符("hello"=5个字符),Token是分词后的单位("hello"=1个Token)。英文约4个字符=1个Token,中文约1-2个字符=1个Token。
总结
| 概念 | 关键点 |
|---|---|
| 分词算法 | BPE(合并) / WordPiece(似然) / Unigram(裁剪) |
| Token ID | 词表中的整数索引,模型实际输入 |
| 特殊Token | [CLS]/[SEP]/[MASK]等,任务标记 |
| 上下文窗口 | 模型一次能处理的最大Token数 |
| 中英差异 | 中文费1.5-2x Token,直接影响成本 |
| 计费 | 按Token计费,先预估再调用 |
搞懂Token,你就理解了LLM的输入边界------什么能进、进多少、花多少钱。
路易乔布斯 © 2026 | AI Agent & RAG学习计划 · 模块03-LLM基础 · 第二篇
以下是近期发布的《系统学AI》相关文章,推荐阅读:
【系统学AI】0 一文搞定AI Agent与RAG:从入门到工程实战的完整学习路线
1.【系统学AI】01 Transformer原理全解:从Self-Attention到GPT的架构进化
2. 【系统学AI】02 token机制全解:LLM如何'读懂'人类语言
3. 【系统学AI】03 LLM训练全流程:预训练→SFT→对齐五条路线
未完待续
想要系统学习的朋友,快收藏起来慢慢看吧,更多更新请关注账号~
