第3章:Token —— 大模型的基本单位
本章解决的核心问题:大模型读的不是「字」,而是 token。Token 是什么?为什么需要分词器?为什么 API 按 token 收费而不是按字收费?上下文窗口又是什么?读完这一章,你能看懂 API 账单上的每一个数字。
3.1 为什么不是「字」:Token 存在的理由
在展开技术细节之前,我们先来直面一个直觉上很奇怪的事实:大模型看不见「字」——它只看见数字。
计算机的世界里一切最终都是数字。图片是数字、声音是数字、文字也是数字。要把人类的语言喂给数学模型,必须先对语言做数字化编码。
最天真的做法可能是:给每个汉字或英文单词一个编号。
但这样做有几个致命问题:
问题一:词汇表无限膨胀
英语有超过 17 万个单词(牛津英语词典),中文常用字就有 6000 多个,词的数量更是数以万计。而且新词不断出现——网络用语、品牌名、科技词汇……给每个词分配一个固定编号意味着模型需要极大的词汇表,大量编号使用频率极低,浪费参数和算力。
问题二:如何应对「没见过」的词
如果「cat」和「dog」在训练数据里都有,模型认识。但「cat-dog-like-creature」这个组合在训练数据里从未出现过。你不能说「这个词在我的词汇表里没有,所以我处理不了」——你需要一种方式让模型能组合已知部件来理解新词。
问题三:不同语言编码混乱
「苹果」在中文里是一个词,在英文里是「apple」。用一个全局词汇表意味着跨语言的能力要靠在训练数据中每个语言的每个词都出现才能形成——效率极低。
答案:Token(分词)
Token 的核心思想是:不按单词切,而是按「有意义的子单元」切。 就像拼音把语音拆成声母和韵母,分词把文字拆成「最常见的片段」。
| 语言 | 原文 | 切成 token |
|---|---|---|
| 英文 | "unbelievable" | ["un", "believ", "able"] |
| 英文 | "playing" | ["play", "ing"] |
| 中文 | "人工智能" | ["人工", "智能"] 或 ["人", "工", "智", "能"] |
| 中文 | "ChatGPT 很好用" | ["Chat", "G", "PT", "很", "好用"] |
| 代码 | print("hello") |
["print", "(", """, "hello", """, ")"] |
关键洞察:Token 不是字也不是词——它是在统计意义上最常见的字符组合。一个 token 可能是一个完整的词、一个词的一部分、一个标点符号,或者一个空格。
3.2 分词器:怎么把文字切成 Token
3.2.1 BPE(Byte Pair Encoding):大模型最常用的分词算法
今天绝大多数大模型使用的分词算法都直接或间接源于 BPE(Byte Pair Encoding)。它的思想非常优美:
把「切成最小 → 合并最频」的过程自动化。
具体步骤:
- 初始状态:把训练数据里的所有文本拆成单个字符(或字节)。每个字符就是一个初始 token。
- 统计频率:扫描所有文本,找出出现次数最多的相邻 token 对。
- 合并:把这对 token 合并成一个新的 token,加入到词汇表。
- 重复 2-3:不断合并,直到词汇表达到预设的大小(比如 GPT 用的 50000 或 100000 个 token)。
用一个极简的例子说明:
训练文本:"low lower lowest"
初始:l, o, w, 空格, l, o, w, e, r, 空格, l, o, w, e, s, t
第1轮:发现 "l"+"o" 出现最多(3次),合并为 "lo"
第2轮:发现 "lo"+"w" 出现最多(3次),合并为 "low"
第3轮:发现 "e"+"r" 出现最多(2次),合并为 "er"
第4轮:发现 "low"+"er" 出现最多(2次),合并为 "lower"
...
最终词汇表:low, lower, lowest, lo, w, er, est, ...
BPE 的聪明之处在于:高频的常见词会保持完整(如 "the"、"a"、"is" 通常是一个 token),而罕见词或新词会被自动拆成更小的子单元——这些子单元和模型见过的其他词里的组成部件是相同的,所以模型能「推测」它的含义。
3.2.2 各模型的分词器对比
不同的模型使用不同的分词器——甚至同一家公司不同版本的模型也可能不同。这里是一些代表性案例:
| 模型 | 分词器 | 词汇表大小 | 中文特点 |
|---|---|---|---|
| GPT-3 / GPT-4 | cl100k_base | ~100,000 | 英文友好,中文一个字通常 1-2 tokens |
| Claude | 自研(未公开) | 未公开 | 多语言优化较好 |
| DeepSeek | 自研 | 未公开 | 中文优化明显——相比 GPT,中文 token 效率高 1.5-2 倍 |
| LLaMA 2 | SentencePiece (BPE) | 32,000 | 中文效率一般 |
| Qwen(通义千问) | 自研 | ~150,000 | 中文优化好 |
3.2.3 中文分词的「不平等待遇」
这是一个非常务实的话题。因为大多数大模型最初为英文设计,中文在分词上存在效率差异:
- 英文:一个常见单词(如 "intelligence")通常是一个 token。
- 中文:在 GPT 的分词器下,一个汉字通常是 1-3 个 token。"人工智能" 可能需要 4-8 个 token。
这意味着处理同样的信息量,中文比英文消耗更多的 token。也因此,同样的 API 调用,中文 prompt 可能更贵,或者在同样长度的上下文窗口里能容纳的有效信息更少。
好消息:中文 AI 公司(DeepSeek、Qwen、智谱等)的分词器对中文做了大幅优化。以 DeepSeek 为例,它的中文 token 效率比 GPT-4 高约 1.5 到 2 倍——意味着同样的中文内容,在 DeepSeek 上消耗的 token 数大约只有 GPT 的一半到三分之二。
3.3 Token → 向量:模型怎么「理解」Token
分词只是第一步。分出来的 token 编号(比如 token #4587)本身只是一个索引——没有语义信息。下一步是把这个编号变成一个有意义的向量。
3.3.1 Embedding(嵌入)
Embedding 是深度学习中的一个基础概念。简单说:
把一个离散的 token 映射到一个高维空间中的点(向量)。含义相近的 token,在这个空间中距离也近。
token "猫" → [0.23, -0.45, 0.67, 0.12, ..., -0.33] (比如 768 或 4096 维)
token "狗" → [0.21, -0.42, 0.64, 0.15, ..., -0.31] (和「猫」的距离很近)
token "汽车" → [0.78, 0.12, -0.23, -0.56, ..., 0.44] (和「猫」距离较远)
Embedding 空间的有趣特性:
flowchart LR
subgraph 语义空间
direction TB
K[🐱 猫] --- D[🐶 狗]
Q[👑 国王] --- QU[👸 王后]
M[👨 男人] --- W[👩 女人]
end一个经典的例子来自 Word2Vec(2013 年):
国王 - 男人 + 女人 ≈ 王后
在向量空间中,「国王」的向量减去「男人」的向量(去掉男性属性),加上「女人」的向量(加上女性属性),得到的结果向量最接近「王后」的向量。
这不是人工编码的规则——是模型从大量文本的统计规律中学到的。
3.3.2 上下文相关的 Embedding
在早期的模型中(如 Word2Vec、GloVe),一个词无论出现在什么上下文里,embedding 都一样——「苹果」在「吃苹果」和「苹果公司」里是同一个向量。
Transformer 改变了这一点。通过自注意力机制(第2章讲到),每个 token 的表示会被上下文中的其他 token 所影响。在「我吃了一个苹果」和「苹果发布了新款 iPhone」中,「苹果」的最终向量是不同的——它吸收了上下文信息。
这种 上下文感知的表示是 Transformer 强大能力的重要来源。
3.4 上下文窗口:模型的「记忆上限」
3.4.1 什么是上下文窗口
上下文窗口(Context Window)是模型在一次推理中能「看到」的 token 总数上限。它决定了模型能处理多长的文本。
flowchart LR
subgraph context[上下文窗口]
T1[token₁] --- T2[token₂] --- T3[...] --- T4[tokenₙ]
end| 模型 | 上下文窗口 | 发布时 |
|---|---|---|
| GPT-2 | 1,024 tokens | 2019 |
| GPT-3 初始版 | 2,049 tokens | 2020 |
| GPT-3.5-Turbo | 4,096 tokens | 2022 |
| GPT-4 初始版 | 8,192 tokens | 2023 |
| GPT-4-Turbo | 128,000 tokens | 2023 |
| Claude 3 | 200,000 tokens | 2024 |
| Gemini 1.5 Pro | 最多 100 万 tokens | 2024 |
| DeepSeek-V3 | 128,000 tokens | 2024 |
上下文窗口的物理体验:
- 2000 tokens:大约一页 A4 纸的文字
- 8000 tokens:大约一篇中篇博客文章
- 128000 tokens:一本中篇小说
- 100 万 tokens:十多本书的容量
3.4.2 为什么上下文窗口很重要
上下文窗口决定了模型在一次对话中能「记住」多少之前的对话内容和输入信息。
如果你的上下文窗口是 8000 tokens,当对话历史 + 你新发送的消息超过 8000 tokens 时,最早的对话内容会被「遗忘」——模型就看不见它们了。
这也是为什么当你和一个 AI 聊了很久之后,它会「忘记」你一开始说过的话。不是因为它不聪明——而是因为上下文窗口满了,旧内容已经被裁剪掉了。
flowchart LR
subgraph before[超长对话]
O1[开头] --> O2[中间很长] --> O3[最新消息]
end
subgraph after[模型实际看到]
direction LR
N1[
中间被截断] --> N2[最新消息]
end3.4.3 上下文窗口的技术挑战:注意力机制的平方复杂度
为什么要扩展上下文窗口这么难?因为自注意力的计算复杂度是 O(n²)——序列长度翻倍,计算量翻四倍。
假设处理 1000 个 token 需要 100 个单位的时间,那处理 128000 个 token 就需要:
这就是为什么超长上下文窗口直到最近一两年才成为现实——需要有算法上的创新(如 FlashAttention、Ring Attention 等)来降低计算和内存开销。
3.5 Token = 钱:API 的计费逻辑
3.5.1 为什么按 Token 收费
当你调用 ChatGPT API 或 Claude API 时,账单上显示的不是「你问了几个问题」,而是「你消耗了多少 token」。原因很直接:
Token 消耗 ≈ GPU 计算量 ≈ 服务器成本
每一个 token 在模型内部都要经过数十亿参数的矩阵运算。输出 token 比输入 token 更贵,因为输出需要一步一步地自回归生成——每生成一个 token 都要做一次完整的推理。
3.5.2 主流 API 的价格(2024-2025 参考)
| 模型 | 输入价格(每百万 token) | 输出价格(每百万 token) | 备注 |
|---|---|---|---|
| GPT-4o | ~$5.00 | ~$15.00 | OpenAI 旗舰 |
| GPT-4o-mini | ~$0.15 | ~$0.60 | 性价比之选 |
| Claude 3.5 Sonnet | ~$3.00 | ~$15.00 | Anthropic 中档 |
| Claude 3.5 Haiku | ~$0.80 | ~$4.00 | Anthropic 轻量 |
| DeepSeek-V3 | ~$0.27 | ~$1.10 | 超高性价比 |
| DeepSeek-R1 | ~$0.55 | ~$2.19 | 推理模型 |
⚠️ 价格变动频繁,以上为大致参考。具体价格请查阅各平台的官方定价页。
3.5.3 Token 成本的实际感受
假设你用 GPT-4o-mini 做一个典型的问答:
| 场景 | 输入 tokens | 输出 tokens | 大约费用 |
|---|---|---|---|
| 简单问答(一句话) | ~50 | ~150 | ~$0.0001 |
| 中等长度对话 | ~800 | ~500 | ~$0.0005 |
| 分析一篇文章 | ~3000 | ~1000 | ~$0.001 |
| 处理整本书 | ~150000 | ~10000 | ~$0.03 |
| 高强度的 Agent 工作流 | ~50000/轮 × 多轮 | ~30000/轮 | 一天可能几美元到几十美元 |
一个形象的对比:用 GPT-4o-mini 生成一本《小王子》长度的书(约 25000 词,约 30000 tokens),输出成本大约 1-2 美分。
3.5.4 输入和输出为什么价格不同
输入 token(prompt):只做一次前向传播 → 便宜
输出 token(completion):每个 token 都要做一次完整推理 → 贵
输出价格通常是输入价格的 2-5 倍
3.6 Token 的实用知识
3.6.1 怎么估算 Token 数
粗略的换算(以 GPT 分词器为基准):
| 语言 | 大致换算 |
|---|---|
| 英文 | 1 token ≈ 0.75 个单词 ≈ 4 个字符 |
| 中文 | 1 token ≈ 0.5-0.7 个汉字(取决于分词器) |
| 代码 | 高度可变——关键字通常 1 token,变量名可能被拆 |
精确工具:OpenAI 提供了官方的 Tokenizer 工具,可以粘贴文本看实际 token 数。
3.6.2 节省 Token 的实用技巧
- 用英文写 system prompt:在中文 API 场景中如果不需要中文,英文 prompt 通常 token 效率更高。
- 去除不必要的空格和换行:它们也消耗 token。
- 精简示例(few-shot examples):每个示例都消耗 token,选最具代表性的 1-2 个就好。
- 用短的变量名:在代码生成场景中,「
x」比「user_input_variable」省 token。
本章小结
| 要点 | 一句话 |
|---|---|
| 什么是 Token | 文本的「最常见子片段」——不是字也不是词,是统计意义上的最小高效编码单元 |
| BPE 分词 | 从单字符开始,反复合并最频繁的相邻对,直到词汇表达到预设大小 |
| Embedding | 把 token 映射为高维向量——语义相近的 token 在空间中距离也近 |
| 上下文窗口 | 模型一次能「看到」的 token 数上限——超出部分会被裁剪遗忘 |
| Token 计费 | Token 消耗 ≈ GPU 计算成本;输出比输入贵 2-5 倍 |
| 中文的效率 | GPT 分词器对中文不友好(一个汉字多个 token),国产模型做了大幅优化 |
下一章预告
本章我们反复提到一个问题:处理 token 需要算力。但「算力」到底是什么?GPU 凭什么比 CPU 更适合 AI?训练一个大模型到底要烧多少钱?为什么 NVIDIA 成了 AI 时代最大的赢家?
→ 第4章:算力
| ← 上一章 | 回到目录 | 下一章 → |
|---|---|---|
| 第2章:大模型是什么 | 第4章:算力 |