大型语言模型中的Token详解:数据、处理与意义
Token 是大型语言模型 (Large Language Models, LLMs) 处理文本的基本单位。它不是传统意义上的“词”,而是模型将人类可读的文字序列(如句子、段落)切分、编码并最终用于学习和生成文本的离散符号表示。理解 Token 的概念对于深入了解 LLMs 的工作原理、能力边界以及成本核算至关重要。
核心思想:LLMs 不直接处理原始文本,而是将其分解为一系列经过特殊编码的 Token。这些 Token 构成了模型输入和输出的最小单元,并直接影响模型的性能、效率和成本。
一、什么是 Token?
在自然语言处理 (NLP) 领域,尤其是在 LLMs 中,Token 是指模型进行训练和推理时所使用的文本片段。它可能是:
- 一个完整的词 (Word):例如 “cat”, “run”。
- 一个词的一部分 (Subword):例如 “un”, “believe”, “able” 组合成 “unbelievable”。
- 一个标点符号 (Punctuation):例如 “.”, “,”, “!”。
- 一个特殊符号或控制字符 (Special Token):例如
[CLS],[SEP],<bos>,<eos>,用于标记文本的开始、结束或不同部分。
为什么是 Token 而不是简单的“词”?
- 处理未知词 (Out-of-Vocabulary, OOV) 问题:如果只用词作为基本单位,模型会遇到训练集中未出现过的新词。子词分词可以将新词分解成已知的子词单元,从而有效处理 OOV 问题。
- 控制词汇表大小 (Vocabulary Size):词汇表过大不仅占用大量内存,还会增加模型训练的复杂性。子词分词能够用相对较小的词汇表覆盖绝大多数词语,例如,通过组合有限的子词来表示无限的词汇。
- 保留形态学信息 (Morphological Information):通过分解成子词,模型能够更好地理解词语的构成和词根、前缀、后缀等带来的语义变化。例如,“running”分解成“run”和“ing”,模型就能学到“run”的含义以及“ing”表示进行时的语法功能。
- 跨语言一致性 (Cross-lingual Consistency):对于一些没有明确词语边界的语言(如汉语、日语),子词分词提供了更统一和有效的分词策略。
二、Tokenization (分词) 过程
Tokenization 是将原始文本分解成 Token 序列的过程。这个过程是 LLMs 工作流的第一步,也是至关重要的一步。
2.1 常见 Tokenization 算法
目前,主流的 LLMs 大多采用基于子词 (Subword) 的分词算法,其中最常见的有:
- Byte Pair Encoding (BPE):
- 原理:BPE 算法通过迭代地合并文本中最常出现的字节对(或字符对)来构建词汇表。它从字符级别开始,逐渐合并成子词,直到达到预设的词汇表大小或合并次数。
- 特点:倾向于保留常见的完整词,同时将不常见的词分解为有意义的子词。
- WordPiece:
- 原理:由 Google 开发,是 BERT 等模型使用的主要分词器。与 BPE 类似,但它不是合并出现频率最高的对,而是合并使语言模型概率增幅最大的对。
- 特点:更侧重于优化语言模型的性能,生成更“有用”的子词。
- SentencePiece:
- 原理:一种语言无关的子词分词器,可以将所有文本视为字节序列。它支持 BPE 和 WordPiece 算法,并且能够处理预分词空白符(pre-tokenization whitespace),这意味着它不会预先将文本按空格切分。
- 特点:特别适用于处理多种语言,包括那些没有明确词语边界的语言。
2.2 Tokenization 流程示意
graph TD
A["原始文本: 'Large language models are powerful.'"] --> B{Tokenization}
B --> C["Token 序列: ['Large', 'language', 'models', 'are', 'powerful', '.']"]
C --> D["Token ID 序列: [341, 1025, 654, 301, 789, 21]"]
D --> E["Token Embeddings (向量表示)"]
2.3 特殊 Token
为了帮助模型理解文本结构和执行特定任务,LLMs 会使用一些特殊的 Token:
<bos>(Beginning Of Sentence/Stream):标记输入序列的开始。<eos>(End Of Sentence/Stream):标记输入序列的结束。<pad>(Padding):用于将不同长度的序列填充到相同的长度,以进行批量处理。<unk>(Unknown):表示词汇表中不存在的 Token。[CLS](Classification):在 BERT 等模型中,作为输入序列的第一个 Token,其对应的输出通常用于分类任务。[SEP](Separator):在 BERT 等模型中,用于分隔不同的句子或文本段。
三、Token ID 与 Token Embeddings
经过 Tokenization 后,每个 Token 会被进一步转化为模型可以处理的数值形式:
3.1 Token ID (整数编码)
分词器会维护一个词汇表 (Vocabulary),其中包含了所有已知的 Token,并为每个 Token 分配一个唯一的整数 ID。
例如:
- “hello” ->
100 - “world” ->
200 - “!” ->
10
3.2 Token Embeddings (向量表示)
Token ID 本身不包含语义信息。为了让模型理解 Token 的含义,每个 Token ID 会被映射到一个高维浮点数向量,这就是词嵌入 (Word Embedding) 或 Token Embedding。
- 高维空间:这些向量通常是几百到几千维的(例如,GPT-3 的 Token Embedding 维度为 12288)。
- 语义信息:语义相似的 Token 在这个高维向量空间中距离较近,而语义不相关的 Token 则相距较远。
- 上下文感知:在现代 LLMs 中,Token 的最终嵌入向量会结合其上下文信息,使得同一个 Token 在不同语境下具有不同的向量表示。
数学表示:
如果词汇表大小为 $V$ 且嵌入维度为 $d$,则存在一个嵌入矩阵 $E \in \mathbb{R}^{V \times d}$。对于一个 Token ID $i$,其嵌入向量为 $E_i \in \mathbb{R}^d$。
3.3 位置编码 (Positional Encoding)
Transformer 架构的注意力机制本身不包含序列的顺序信息。为了让模型理解 Token 的位置关系和顺序信息,会在 Token Embedding 中加入位置编码 (Positional Encoding)。
- 原理:位置编码通常是一系列固定计算的(如正弦/余弦函数)或可学习的向量,它们被加到 Token Embedding 上。
- 作用:让模型能够区分相同 Token 在不同位置时的含义,例如“我爱你”和“你爱我”虽然词相同但顺序不同,通过位置编码模型能理解其差异。
四、Token 在 LLMs 中的重要意义
Token 是连接原始文本与 LLM 内部计算的桥梁,其重要性体现在多个方面:
4.1 输入和输出的单位
- 输入:LLMs 接受 Token 序列作为输入。
- 输出:LLMs 逐个生成 Token 来构建响应。
4.2 上下文窗口 (Context Window)
- 定义:LLMs 的“记忆”能力被限制在一个上下文窗口内,即模型在一次推理中能够同时处理的 Token 数量上限。
- 影响:上下文窗口的大小直接决定了模型能够理解和生成的文本长度。如果输入的 Token 数量超过了上下文窗口,文本就会被截断,导致信息丢失。
4.3 成本核算 (Pricing)
- 绝大多数 LLM API(如 OpenAI 的 GPT 系列)的收费是基于Token 数量。无论是输入还是输出,每个 Token 都会产生费用。这意味着更长的提示 (prompt) 和更长的响应会导致更高的成本。
4.4 模型性能与效率
- Tokenization 策略:不同的分词策略会影响模型的最终性能。一个好的分词器可以生成更语义化、更紧凑的 Token 序列,从而提高模型的效率和理解能力。
- 计算资源:处理的 Token 数量越多,所需的计算资源(内存、计算时间)就越大。
五、Go 语言中简化 Tokenization 的概念性示例
一个真实的 LLM 分词器(如基于 BPE 或 WordPiece)的实现非常复杂,涉及大规模语料库的统计分析和词汇表构建。然而,我们可以通过一个简化的 Go 语言示例来理解 Tokenization 的概念,特别是如何将文本分解成子词单元。
下面的示例模拟了一个极简的分词器,它尝试将某些常见的词根和后缀识别为独立的 Token。
1 | package main |
解释:上述 Go 代码展示了一个高度简化的概念性分词器。它首先对文本进行基本清洗和分割,然后通过硬编码的规则尝试将词语分解成前缀、词根和后缀。真实的 LLM 分词器会通过统计学习和迭代合并(如 BPE)来动态构建子词词汇表,远比这个示例复杂和智能。这个示例的目的在于说明 Token 不仅仅是词,它们可以是更小的、有语义意义的单元。
六、挑战与考量
- 分词策略的影响:不同的分词器和词汇表可能导致相同的文本被分解成不同的 Token 序列,这会影响模型的学习效率和泛化能力。
- 多语言处理:对于像中文、日文这样没有明显词语边界的语言,Tokenization 更加复杂,通常需要依赖专门的分词器。
- 计算效率:Tokenization 过程必须高效,尤其是在处理大规模文本和实时应用时。
- Token 的粒度:Token 过大可能导致 OOV 问题和词汇表膨胀;Token 过小(如字符级)会丢失语义信息,且序列长度过长增加计算负担。子词分词是这两者之间的一种平衡。
- 隐私和偏见:Tokenization 过程中,如果处理不当,可能会在 Token 层面引入偏见或泄露敏感信息。
七、总结
Token 是 LLMs 与人类语言交互的基石。它们作为模型输入和输出的基本单位,不仅承载了文本的语义信息,也直接决定了模型的上下文理解能力、计算效率以及运行成本。通过精巧的分词算法(如 BPE、WordPiece),LLMs 能够以一种高效且灵活的方式处理复杂多变的自然语言,从而展现出惊人的生成和理解能力。深入理解 Token 的概念,是掌握大型语言模型核心工作原理的关键一步。
