Embeddings:让"词"变成"坐标"
上一节我们把文字切成了 token,每个 token 拿到一个整数 ID。 但模型看到 ID = 5 和 ID = 6,它并不知道 5 是「猫」、6 是「螺丝刀」,更不知道这两个东西毫不相关。 这一节我们解决"怎么让神经网络真正理解一个 token 的含义"。
① 直觉:把每个词放到一张「语义地图」上
想象一张二维地图,上面摆着很多词。我们这样摆:
- 语义相近的词放得近 ——「猫」和「狗」紧挨着
- 语义不相关的词放得远 ——「猫」和「计算机」分别在地图两头
- 变化方向也有意义 —— 从「king」到「queen」要往下走一格,从「man」到「woman」也是同样的方向
如果真的能这样摆,那机器只要"看坐标"就能知道两个词关系如何 —— 坐标就是一组数字。在 2 维地图上一个点是 (x, y) 这种两个数; 在 3 维空间是 (x, y, z) 三个数;维度更高就更多个数。
一个词的 embedding(嵌入向量),就是这样一组数 —— 用来描述它在"语义空间"里的位置。给你看一个最小例子,假设我们用 4 个数来描述每个词(每个数代表语义的某个抽象维度,比如「动物程度」「动作程度」「水生程度」「软萌程度」):
狗 → [ 0.8, 0.2, 0.0, 0.7 ] ← 和猫几乎一样 = 语义相近
鱼 → [ 0.7, -0.1, 0.9, 0.2 ] ← 也是动物,但水生程度高
跑 → [-0.2, 0.9, 0.0, 0.1 ] ← 不是动物,是动作
看「猫」和「狗」的 4 个数字几乎一一对应 —— 这就是机器"理解"它俩相近的方式:对应位置上的数字差很小。 和「跑」一比,第 1 个数(动物程度)从正变负 —— 机器一眼看出"种类完全不同"。
所以 "embedding" 这个词本质上就两层含义:
- "嵌入":把抽象的"猫"这个字嵌进一个具体的数值空间
- "向量":嵌进去之后的形式是一串数,数学上叫"向量"
现实里这串数不是 4 个,而是 、、 个。 但原理完全一样 —— 用一串数字描述一个词,让"语义相近 = 数字相近"。
② 互动:在 2D 语义地图上做"向量算术"
下面这张图是人工摆放的 2D 简化版(真实模型的 embedding 几百到几千维,画不出来)。 看一个神奇的现象:「king - man + woman」在地图上的位置非常接近「queen」。 这是 Mikolov 等人 2013 年发现的"词向量算术"现象,是 embedding 思想成立的最直观证据:
留意:这是人工摆放的 2D 演示,目的是直观感受"语义距离"。 真实 word2vec / Transformer 的 embedding 是几百到几千维,并不是预先指定坐标, 而是模型在大语料上自己"学"出来的 — 学完之后语义近的词自然就靠在一起。
切换不同类比题目,看看蓝色十字(计算出的目标位置)和最近的词。 这种现象之所以发生,是因为「性别」「年龄」「职位」「物种」这些语义维度, 在足够好的 embedding 里会大致正交,所以加加减减就能"沿着某个方向移动一格"。
③ 形式化:embedding 就是一张可学习的查找表
embedding 的数学非常朴素。给定词表大小 V 和维度 d,整个 embedding 就是一个矩阵:
关键点:
- 它是可学习的参数 —— 训练开始时 E 是随机的,毫无语义。 通过反向传播,模型为了让自己预测得更准,会一点点调整 E, 使得"语义靠近的词"在向量空间里靠拢。
- "查表"就是矩阵乘法的特例 —— 严格说,把 token ID i 写成 one-hot 向量, 就等于 。所以 embedding 层就是个特殊的全连接层,参数量 = V × d。
- 它是模型里参数量最大的部分之一 —— GPT-3 词表 50257、维度 12288,光 embedding 矩阵就有 6 亿多参数。
④ 代码:自己建一个 mini embedding 表
下面这段代码手工构造了一个 5 个词、4 维 的 embedding 表,然后查出一句话的向量:
np. 看自动提示,⌘/Ctrl + Enter运行。⑤ 怎么衡量两个 embedding 的"近"?余弦相似度
有了向量,怎么判断两个词像不像?最常用的不是欧氏距离,而是余弦相似度:
余弦相似度只看方向不看长度。两个向量同方向 → 1,垂直 → 0,反向 → -1。 对 embedding 来说这正合适:「猫」和「老虎」未必长度相同,但方向应该相近。
跑一下下面这段,看每个词和"猫"的相似度:
np. 看自动提示,⌘/Ctrl + Enter运行。⑥ 一个常见困惑:embedding 是怎么"知道"语义的?
embedding 是用大量文本训练出来的。基本想法叫"分布假设"(distributional hypothesis):
"一个词的含义,等于它出现的上下文。"
— J. R. Firth (1957)
翻译成可计算的话:如果两个词总是出现在相似的上下文里(「猫」「狗」都常出现在「我家有只 ___」「___ 在沙发上睡觉」这种位置), 那么训练目标会逼着模型把它俩的 embedding 学得相似 —— 因为只有相似的输入才能产生相似的预测。
在 LLM 里,embedding 是和整个模型端到端联合训练的。 模型预测错了,损失从输出层一路传回 embedding 层, embedding 矩阵的每一行(每个 token 的向量)都会被微调一点点。 几百亿个 token 的训练之后,这张"地图"就自然有了语义结构。
⑦ Position Embedding:还要让模型知道"谁在前谁在后"
Transformer 有个特点:它同时看一整个序列,并不知道 token 的顺序。 所以光有 token embedding 还不够,还要再加一个位置 embedding(position embedding)告诉模型「这个 token 出现在第几位」。
两个 embedding逐元素相加。这听起来很粗糙(为什么相加?),但实践证明它工作得很好 —— 因为高维向量空间足够大,token 和 position 的信息可以"叠"在一起而不互相干扰。
后来 LLaMA、PaLM 等改用了 RoPE(旋转位置编码)替代加性位置 embedding,效果更好、外推更强。 但理解阶段,知道"必须以某种方式注入位置信息"就够了。
⑧ 小测验
⑨ 延伸阅读
- Jay Alammar — The Illustrated Word2Vec:图解 word2vec 怎么训练出 embedding,可视化讲得最好的一篇。
- Mikolov et al. 2013 — Efficient Estimation of Word Representations:word2vec 原始论文,"king - man + woman = queen"现象的来源。
- TensorFlow Embedding Projector:把 word2vec 的几百维 embedding 用 t-SNE/PCA 降到 3 维让你旋转着看,非常震撼。