2.文本处理为词向量
计算机无法直接理解文字,只能处理数字。因此在使用Transformer处理文本之前,必须先将文字转换为数字表示。这这个转换的过程需要经过如下流程:

# 2.1 为什么需要词向量
人类看到"苹果"这个词,脑海中会浮现水果的形象、味道、颜色等信息。但对计算机来说,"苹果"只是两个字符,毫无意义。
词向量就是用一组数字来表示一个词的含义。比如:
- "苹果" → [0.2, 0.8, 0.1, 0.5, ...]
- "香蕉" → [0.3, 0.7, 0.2, 0.4, ...]
好的词向量能让语义相近的词在数值上也相近,比如"苹果"和"香蕉"的向量距离会比"苹果"和"汽车"更近。
# 2.2 词元化(Tokenization)
在Transformer中,通常会将文本分解成更小的单元——"词元"。这些词元可以是单词、子词甚至是字符。
# 2.2.1 字符词元化
字符词元化:按每个字符单独馈送到模型。
"苹果" → ["苹", "果"]
"apple" → ["a", "p", "p", "l", "e"]
2
缺点:字符级别的词元化忽略了文本中的任何结构。虽然可能有助于处理拼写错误和生僻词,但是语言结构(如单词)需要从数据中学习,需要大量的计算、内存和数据。因此,字符词元化在实践中很少使用。
# 2.2.2 单词词元化
单词词元化:将文本细分为单词。
"我喜欢吃苹果" → ["我", "喜欢", "吃", "苹果"]
"I love apples" → ["I", "love", "apples"]
2
优点:使模型跳过从字符学习单词的步骤,从而降低训练过程的复杂性。
缺点:鉴于单词可以包括变形、派生或拼写错误,词表的大小很容易增长到数百万!词表太大导致神经网络需要大量的参数,计算量过大。
举例:假设词表中有100万个唯一词项,并按照大多数NLP架构中的标准步骤将100万维输入向量压缩到第一层神经网络中的1000维向量。这样第一层的权重矩阵将包含 100万 × 1千 = 10亿个权重。现在的Transformer最少6层,大模型基本都100多层,显然这样算力吃不消。
# 2.2.3 子词词元化
子词词元化:将生僻单词拆分成更小的单元,以使模型能够处理复杂单词和拼写错误;将常见单词作为唯一实体保留下来,以便将输入长度保持在可管理的范围内。
"unhappiness" → ["un", "happi", "ness"]
"苹果手机" → ["苹果", "手机"]
2
优点:大约可以将词表控制在几万到二十几万左右,平衡了词表大小和语义完整性。
常见算法:
- BPE(Byte Pair Encoding):GPT系列使用
- WordPiece:BERT使用
- SentencePiece:支持多语言,LLaMA使用
# 2.3 词元编码
完成词元化后,我们需要将文本中每个词元映射成一个唯一的整数索引,完成这个操作的前提是需要一个词表来记录唯一整数与词元的关系。
# 2.3.1 词表(Vocabulary)
词表是在预训练阶段将预训练文本词元化生成的,最终目的是将文本中的每个词元(如单词、子词或字符)映射到一个唯一的整数索引。
词表示例:
{"苹果": 1234, "香蕉": 5678, "我": 156, "爱": 892, ...}
2
# 2.4 向量化
# 2.4.1 独热向量(One-Hot Encoding)
独热编码是一种将离散类别变量转化为向量表示的方式。核心思想是:对于每个类别(或词元),将其表示为一个只有一个非零元素(1)的向量,其他所有元素都是零。
假设词表:["苹果", "香蕉", "橙子"]
"苹果" → [1, 0, 0]
"香蕉" → [0, 1, 0]
"橙子" → [0, 0, 1]
2
3
4
5
独热向量的问题:
- 数据过于稀疏:如果词汇表有10,000个词,每个词就会被表示成一个10,000维的稀疏向量,只有一个位置是1,其他都是0(浪费大量内存和计算资源)
- 没有语义信息:独热编码将每个类别表示为一个独立的向量,词与词之间的相似性、类别之间的关系或顺序完全丧失
- 没有数学或逻辑关系:比如不能满足诸如
国王 - 男人 + 女人 = 女王这样的数学逻辑关系
# 2.4.2 词向量(Word Embeddings)
词向量的核心思想是将词语嵌入到一个高维的连续向量空间(潜空间),使得在这个空间中,语义相似的词语在向量空间中的位置也相近。
这意味着词与词之间的距离(例如余弦相似度或欧几里得距离)能够反映词语之间的语义关系。
"国王" → [0.2, 0.8, 0.1, ...]
"女王" → [0.3, 0.7, 0.2, ...] ← 与"国王"相近
"苹果" → [0.9, 0.1, 0.8, ...] ← 与"国王"较远
2
3
# 2.5 嵌入矩阵(Embedding Matrix)
在Transformer中,词向量通过嵌入矩阵实现,这是一个可学习的参数矩阵。
# 2.5.1 嵌入矩阵的结构
假设词表大小为 V,嵌入维度为 d:
嵌入矩阵 E:V × d
例如:词表50000个词,嵌入维度768
E: 50000 × 768
2
3
4
每个词元对应矩阵中的一行,就是该词元的向量表示。
# 2.5.2 查表过程
1. "苹果" 在词表中的索引是 1234
2. 取嵌入矩阵的第 1234 行
3. 得到 768 维的向量 [0.12, -0.45, 0.78, ...]
2
3
数学本质:嵌入查表等价于独热向量与嵌入矩阵的矩阵乘法。
索引 1234 → 独热向量 x = [0, 0, ..., 1, ..., 0] (第1234位为1)
↓
嵌入向量 = x · E = E[1234] (取嵌入矩阵第1234行)
2
3
由于独热向量只有一个位置为1,矩阵乘法的结果就是选取嵌入矩阵中对应的那一行。实际实现中,框架会直接用索引取行,避免稀疏矩阵运算的开销。
# 2.5.3 嵌入向量的学习机制
Transformer的嵌入矩阵是模型的可训练参数,其学习过程如下:
- 初始化:嵌入矩阵中的参数采用随机初始化(如正态分布或均匀分布)
- 训练优化:在预训练过程中,嵌入矩阵与模型其他参数一起,通过反向传播算法不断优化
- 训练完成:收敛后,嵌入矩阵被固定,矩阵中的每一行就是对应词元的静态向量
训练完成后,语义相近的词元在向量空间中自然聚集。例如"猫"和"狗"的向量会比较接近,而与"汽车"的向量距离较远。
静态嵌入 vs 上下文表示:
嵌入层输出的是静态向量——同一词元无论出现在何种语境,查表得到的初始向量相同。
"苹果很好吃" 中的 "苹果" → [0.12, -0.45, ...]
"苹果发布会" 中的 "苹果" → [0.12, -0.45, ...] ← 初始向量相同
2
然而,经过Transformer的自注意力层处理后,模型会根据上下文动态调整每个词元的表示,使其携带丰富的语境信息。这种上下文相关表示正是Transformer相较于传统词向量方法的核心优势。