Token 是大语言模型(LLM)的"基本计量单位"和"基本运算单位"。它既不是字符、也不完全等于单词。这篇文档用图文把四件事讲清楚:Token 是什么 → 怎么计算 → 输入和输出分别怎么算 → 模型底层怎么处理每个 Token,并附带常见模型的长度限制和"上下文窗口"的关系。
一句话:模型"读"和"写"的最小单位,介于"字符"和"单词"之间。
人类用文字交流,但模型并不能直接理解字符串。它先把文本切成一段段小片段,每个片段叫做一个 Token,再给每个 Token 编一个整数编号(Token ID),模型真正处理的是这些 编号 和它们背后的 向量。
"apple" 是 5 个字符,但很可能只是 1 个 Token。逐字符处理会让序列极长、效率低。
"playing" 可能被拆成 "play" + "ing" 两个 Token。按空格切词会把生僻词逼到词表外。
最常用的方案是"子词(subword)":高频整词保留,低频词拆成更小的可复用片段。
英文句子 Let's build AI. 在 GPT 类分词器里大致被切成:
→ 共 5 个 Token(注意 's 和空格常被并进前一个 token)。
中文 我喜欢机器学习 大致被切成(不同分词器略有差异):
→ 常见经验:中文约 1 个汉字 ≈ 1~2 个 Token;英文约 1 个 Token ≈ 4 个字符 ≈ 0.75 个单词。
核心:用模型自带的"分词器(Tokenizer)"把文本映射到 Token ID 序列;Token 数 = 映射后 ID 的个数。
Byte-Pair Encoding。从字符出发,反复把"出现最频繁的符号对"合并成新单元。GPT-2/3/4、Llama 都用它。
BERT 系列采用。类似 BPE,但合并时按"语言模型似然增益"而非纯频次择优。
多语言友好(直接吃原始字节/字符,不依赖空格)。T5、Llama 2 的部分变体、很多开源模型使用。
tiktoken 库;开源模型多用 HuggingFace 的 AutoTokenizer。一次对话的总消耗 = 输入 Token + 输出 Token。两者分开计数、分开计费,但共用同一个"上下文窗口"。
指模型"喂进去"的全部文本,通常包括:
输入 Token 在你按下"发送"那一刻就一次性算好——分词器对整段 prompt 编码,得到多少个 ID 就是多少。
指模型"生成出来"的回复。关键区别:
从编号到向量,再到注意力——模型的每一层都在"围绕每个 Token 的向量"做运算。
模型内部有一张巨大的嵌入查找表(形状约为 词表大小 × 隐藏维度,例如 128000 × 4096)。给定 Token ID,直接取出对应那一行,得到一个高维向量。
这一步把"离散编号"变成"连续向量",语义相近的 Token 在向量空间里也离得近。
Transformer 本身不天然知道顺序。必须注入位置信号。现代主流模型(Llama、GPT-NeoX 系、Qwen、DeepSeek 等)用 RoPE(旋转位置编码):把位置信息"旋转"进 Query / Key 向量里,使两个 Token 的内积天然包含它们的相对距离。
其中 m、n 是位置下标,R 是旋转矩阵。这样注意力分数就与"相对位置 (m−n)"有关。
每个 Token 进入一层后,会计算自己的 Q(查询)、K(键)、V(值) 三个向量,然后和序列里所有其他 Token 做交互:
含义:每个 Token 用它的 Q 去"问"别的 Token 的 K"你和我相关吗",拿到相关度权重后,再按权重把别人的 V"汇总"成自己的新表示。一个 Token 的向量,在这一步融合了上下文里其他 Token 的信息。
自回归生成时,如果每生成一个新 Token 都把整段历史重新算一遍,会非常浪费。实际做法是把前面所有 Token 算出的 Key、Value 缓存下来(KV Cache),新 Token 只需算自己的 Q,再和缓存的 K、V 做注意力。
"长度限制"其实有两道独立的闸:①上下文窗口(输入+输出总上限)②单次输出上限(一次最多生成多少)。
| 模型 / 系列 | 上下文窗口(总 Token 上限) | 单次输出上限 | 说明 |
|---|---|---|---|
| GPT-3.5 Turbo | 16K | 4K | 早期 4K,后扩展 |
| GPT-4o / GPT-4 Turbo | 128K | 16K(可调) | 输出上限可配置,默认常较低 |
| Claude 3 / 3.5 / 3.7 | 200K | 4K–8K(部分可扩至数十 K) | Anthropic 长上下文代表 |
| Gemini 1.5 / 2.5 Pro | 128K 标准,最高 1M–2M | 8K–64K | 超长窗口标杆,可吃整本书/代码库 |
| Llama 3.1 / 3.3 | 128K | 4K | Meta 开源,支持长上下文 |
| DeepSeek-V3 / R1 | 64K(可扩至 128K,YaRN) | 8K | 推理/对话常用 64K |
| Qwen2.5 系列 | 128K | 8K | 通义千问,长文本友好 |
| 文心 ERNIE 4.0 | 128K | 4K | 百度,中文场景 |
两个容易混淆的点:
一句话:上下文窗口就是用 Token 来度量的;它规定了"输入+输出"的总额。
所以:
自注意力的计算量和显存随序列长度平方增长。窗口翻倍,注意力成本大约变 4 倍。
缓存所有历史 Token 的 K、V,长度越长显存占用线性上涨,直接限制能并行服务的请求数。
序列过长时,模型对中间内容的注意力可能被"两端"稀释("lost in the middle" 现象)。
支持更长窗口通常需要特殊位置编码与训练策略(如 RoPE 外推、YaRN),成本高。
Q1:中文和英文,谁的 Token 更"费"?
A:通常中文更费。英文约 4 字符 1 Token;中文约 1~2 字 1 Token,且代码/公式符号密集也偏贵。
Q2:为什么同样一句话,不同模型 Token 数不同?
A:词表大小和分词算法不同,切分粒度就不一样。务必用目标模型的分词器统计。
Q3:上下文窗口 200K,是不是就能一次输出 200K?
A:不是。200K 是"输入+输出"总额;单次输出上限通常小得多(几 K 到几十 K)。
Q4:超过窗口会怎样?
A:超过部分被截断(一般丢最前面),模型"看不见"被截掉的内容。