探索 GPT 等大型语言模型(LLM)中分词与嵌入的关键区别。了解分词如何将文本分解为可管理的单元,而嵌入如何为这些标记提供丰富的向量表示。理解这些过程对于释放 LLM 在自然语言处理任务中的潜力至关重要。
引言
分词和嵌入是 GPT 等大型语言模型(LLM)的基础组件,对于理解和生成文本至关重要。分词涉及将原始文本分解为称为标记的可管理单元,而嵌入则提供这些标记的丰富向量表示。理解分词和嵌入之间的区别,对于掌握 LLM 如何处理语言数据的复杂性至关重要。
什么是分词
标记在 AI 研究中频繁被提及,例如在 Llama 2 论文中,作者提到在 2 万亿个标记的数据上进行训练。标记作为基本单元,类似于 LLM 的“原子”。分词涉及将字符串(即文本)转换为标记序列,反之亦然。
在机器学习领域,标记通常不等同于单个单词。相反,它可能代表一个更小的单元,例如一个字符或单词的一部分,或者一个更大的单元,例如整个短语。标记的大小取决于所使用的分词方法。
分词通常由一个称为“分词器”的组件处理。该模块独立于大型语言模型运行,并拥有自己的文本训练数据集,该数据集可能与 LLM 训练数据完全不同。
为什么分词很重要?
分词往往是大型语言模型(LLM)中观察到的许多奇特现象的根本原因。虽然某些问题最初可能看起来源于神经网络架构或 LLM 本身,但实际上可以归因于分词。以下是可以追溯到分词的问题的非详尽列表:
- 拼写错误
- 难以处理简单的字符串操作任务,例如反转字符串
- 在非英语语言(如日语)中表现较差
- 在基本算术运算中表现不佳
- GPT-2 在处理 Python 等编码任务时遇到挑战
- 尾随空格等问题
- 早期版本的 GPT 在提示“SolidGoldMagikarp”时出现异常行为
- 在处理结构化数据时偏好 YAML 而非 JSON
我们将在本文中深入探讨分词如何导致这些问题。
分词细节
以下是分词涉及的步骤概述。虽然其中一些步骤可能不会立即清晰,但我们将在本文中逐步详细探讨它们。
预训练:建立词汇表
- 收集训练数据:收集大量文本数据语料库,模型将从中学习。
- 初始分词:使用初始分词方法将文本划分为基本单元,例如单词、子词或字符。
- 创建词汇表:选择一种分词算法,如字节对编码(BPE)、WordPiece 或 SentencePiece,以生成一组可管理且高效的标记。
- 应用算法:对初始标记实施所选算法,以生成一组子词标记或字符,从而捕捉训练数据中存在的语言细微差别。
- 分配 ID:为生成的词汇表中的每个标记分配一个唯一的整数 ID。
实时分词过程
- 根据已建立的词汇表将输入文本转换为标记,确保覆盖所有文本。
- 将每个标记与预定义词汇表中对应的整数 ID 关联起来。
- 将任何必要的特殊标记插入序列中,以满足模型处理要求。
理解分词挑战
随意键入句子,观察标记是如何生成的(并注意标记数量和每个提示价格的相应增加)。
选中“显示空格”复选框后,将鼠标悬停在右侧文本上,您将观察到高亮显示的标记。这些标记通常由“块”组成,这些块通常包含开头的空格字符。

另一个例子:

观察标记块及其数字表示如何根据以下因素而变化:
- 单词前是否有空格
- 是否存在标点符号
- 字母大小写
大型语言模型(LLM)必须从原始数据中学习,尽管这些标记存在差异,但单词代表相同的概念或至少非常相似。这种可变性可能会降低性能。
其他人类语言
比较英语和其他语言的块大小,您通常会注意到非英语语言使用的标记数量明显更多。这种差异源于其他语言的块更碎片化,导致文档中的序列长度膨胀。
在机器学习 Transformer 的注意力机制中,非英语语言更可能用尽上下文。即使在传达相同信息时,也会消耗更多标记,因为块更小。这种差异受到分词器使用的训练集和分词器本身的影响。
最终,非英语语言的上下文窗口利用效率低下,导致大型语言模型(LLM)在处理非英语查询时性能较差。
分词与代码 — Python
对于 Python,OpenAI 的 GPT-2 编码器经常在 Python 代码段缩进中使用的单个空白字符上花费大量标记。这种行为类似于非英语语言面临的挑战,导致 LLM 上下文窗口严重膨胀,并因此导致性能下降。
配置:YAML 与 JSON
研究发现,YAML 比 JSON 更密集,完成相同任务所需的标记更少。
这是一个简单的说明:


JSON:46 个标记
JSON 的膨胀增加导致:
- LLM 更难理解(密度更低,更容易超出上下文窗口)。
- 用户花费更高(因为他们实际上在 API 调用 OpenAI 时按标记付费)。
分词问题
分词是大型语言模型(LLM)中观察到的许多异常的核心。一些最初可能看起来与神经网络架构或 LLM 本身相关的问题,实际上可以追溯到分词。例如:
- LLM 难以拼写单词或执行基本字符串处理任务(如字符串反转)。
- 非英语语言的性能往往会下降。
- LLM 在处理简单算术时表现不佳。
- GPT-2 在编写 Python 代码时遇到重大挑战。
- 尾随空格可能会引发奇怪的警告。
- 短语“Solid Gold Magikarp”经常导致 LLM 偏离正题,进入无关的领域。
- 在使用 LLM 时,YAML 比 JSON 更受青睐。
大型语言模型中的分词
在训练大型语言模型(LLM)时,该过程涉及获取字符串并将其转换为来自预定义词汇表的整数。然后,这些整数用于从嵌入表中检索向量,这些向量随后输入到 Transformer 模型中。这个过程变得复杂,因为它不仅需要支持基本的英文字母,还需要支持各种语言和特殊字符(如表情符号)。
Python 中的字符串和 Unicode 码点
在 Python 中,字符串是由 Unicode 码点组成的不可变序列。这些码点由 Unicode 联盟在 Unicode 标准中定义,该标准目前包含约 150,000 个字符,涵盖 161 种文字。Unicode 标准仍在积极维护,最新版本 15.1 于 2023 年 9 月发布。
要获取 Python 中单个字符的 Unicode 码点,我们可以使用 ord() 函数。例如:

然而,直接使用这些原始码点整数进行分词是不可行的,因为这将导致词汇量过大(150,000+),而且由于 Unicode 标准不断演变,词汇表也不稳定。
Unicode 字节编码
为了寻求更有效的分词解决方案,我们转向 Unicode 字节编码,如 ASCII、UTF-8、UTF-16 和 UTF-32。这些编码规定了将抽象 Unicode 码点转换为适合存储和传输的实际字节的方法。
Unicode 字节编码:ASCII、UTF-8、UTF-16、UTF-32
Unicode 联盟定义了三种编码类型:UTF-8、UTF-16 和 UTF-32。这些编码是将 Unicode 文本转换为二进制数据或字节流的手段。
在这些编码中,UTF-8 是最常见的。它将每个 Unicode 码点转换为 1 到 4 个字节的字节流,具体取决于码点。前 128 个码点(ASCII)只需要一个字节。接下来的 1,920 个码点需要两个字节进行编码,涵盖大多数拉丁字母。基本多语言平面(BMP)中剩余的 61,440 个码点需要三个字节。四个字节涵盖其他 Unicode 平面,包括不常见的 CJK 字符、各种历史文字和数学符号。

直接使用原始 UTF-8 字节对语言模型来说效率极低,会导致序列过长,且词汇表大小仅限制为 256 个可能的字节值。这种约束阻碍了模型关注足够长上下文的能力。
解决方案是使用字节对编码(BPE)算法对这些字节序列进行可变压缩。这种方法能够以更大但可调整的词汇表大小高效地表示文本。
分词和嵌入有什么区别?
分词和嵌入是大型语言模型(LLM)(如 GPT)中独立但又相互关联的过程,它们共同影响模型理解和生成文本的方式。以下是它们的简要概述及其区别:
LLM 分词
目标:分词旨在将原始文本转换为标记序列,根据所选的分词方法,标记可以包括单词、子词或字符。
过程:它涉及将文本分解为模型可以理解的片段。这可能包括根据空格和标点符号初始分割文本,如果单词不在模型的预定义词汇表中,则进一步分割为子词或字符。
结果:结果是代表原始文本的标记序列,格式适合模型处理。每个标记根据模型的词汇表被分配一个唯一的整数 ID。
嵌入
目标:嵌入是紧凑、低维、连续的标记向量表示。它们编码语义和句法含义,帮助模型理解语言的细微差别。
过程:在分词之后,每个标记(由其整数 ID 表示)与一个嵌入向量相关联。这些向量通过模型的训练阶段获得,并存储在嵌入矩阵或表中。
结果:嵌入作为 LLM 神经网络层的输入,使模型能够对标记进行计算,并识别数据集中的关系和模式。
在我们的博客中查找有关 LLM 嵌入的更多详细信息:什么是 LLM 嵌入:你需要知道的一切

区别特征
处理阶段:分词是初始预处理步骤,将文本转换为模型可理解的格式(标记),而嵌入发生在分词之后,将标记转换为详细的向量表示。
功能:分词主要涉及对文本进行结构性分解和表示,而嵌入侧重于捕捉和利用标记中嵌入的语义和句法含义。
表示:分词产生离散的、基于整数的文本组件表示,而嵌入将这些整数转换为编码语言信息的连续向量。
结论
总之,分词和嵌入在大型语言模型的功能中扮演着关键角色。分词将文本结构化为标记,而嵌入通过向量表示为这些标记提供语义和句法含义。通过理解这些过程,我们能够洞察 LLM 如何解释和生成文本,从而推动自然语言处理的进步。
novita.ai 是一个一站式平台,为无限创意提供 100 多个 API。从图像生成、语言处理到音频增强和视频处理,采用低廉的按需付费模式,让你在构建自己产品的同时摆脱 GPU 维护的烦恼。免费试用。
推荐阅读
