通俗版
先来回答一个最基础的问题:模型吃的是数字,但文字不是数字,怎么办?
最直接的想法是用 ASCII 码——"好"的 UTF-8 编码是 0xE5A5BD,给模型一个整数不就行了?问题是这样没有任何语义信息。"好"和"棒"在语义上非常接近,但它们的 UTF-8 编码对应的数字,和"好"与"坏"的数字距离差不多——模型根本无从判断这两个字在意思上有什么关系。
你用一个数字表示一个词,你能表达的信息只有"排序"——数字 1 比数字 2 小。但语义关系远不止"大小",还有相似程度、属于哪个类别、是名词还是动词、带正面情绪还是负面情绪……一个数字表达不了这些。
所以我们用多个数字——一个词变成一个向量,比如 512 个浮点数。你可以把这 512 个数字理解成一个词在 512 个不同"维度"上的坐标,每个维度隐约对应着某种语义属性(这些维度不是人为设计的,是模型自己学出来的,所以不能直白地说"第 3 个维度是情绪",但它确实在做类似的事)。
用地图类比:一个地点在地图上需要两个坐标(经度和纬度)才能定位,因为地理空间是二维的。语义空间是高维的,你需要更多坐标才能"定位"一个词的含义。
为什么语义相近的词,向量会自动靠近?
这不是人工设计的,是训练出来的。想想模型是怎么训练的:预测下一个词。"今天天气真好"和"今天天气真棒"都是正确的句子——在"今天天气真"这个上下文后面,"好"和"棒"都是合理的预测。因为这两个词在大量相似上下文里都出现过,模型为了能同时预测对这两个词,就会把它们的向量放到相似的位置。相似的上下文喂出相似的向量,这个规律从数据里自动长出来。
"国王 - 男人 + 女人 ≈ 女王"这个经典案例说明了一件更惊人的事:向量的方向是有含义的。从"国王"到"女王"的方向向量,和从"男人"到"女人"的方向向量,几乎是平行的——这意味着"性别"这个概念被编码成了一个一致的方向。这套几何结构是模型从数百亿句话里自己长出来的,没人手把手教过。
进阶版
Embedding 层在模型里的位置
Embedding 是模型的第一层,负责把 token ID(一个整数)变成向量(一组浮点数)。整个 Embedding 层本质上是一个查找表:一个 [vocab_size, embedding_dim] 的矩阵,比如 [32000, 4096]——32000 个词,每个词对应一行 4096 个浮点数。每次输入一个 token ID,就返回矩阵里对应的那一行。
这个矩阵的参数也是通过训练学出来的,不是固定的。意味着 Embedding 不是一个静态词典,而是整个模型训练过程中的一部分——模型在学"怎么预测下一个词"的同时,也在不断调整每个词的向量表示,让整个系统的预测越来越准。查找表的每一行都在被梯度更新。
Word2Vec vs LLM Embedding 的本质区别
Word2Vec(2013 年)是早期的词向量方法:每个词有且只有一个固定向量。"苹果"这个词,不管是"苹果公司"还是"苹果好吃",它的向量永远一样。
现代 LLM 里已经不存在"静态词向量"了。你在 Embedding 层查到的向量,只是这个 token 的初始表示,它会被后续的每一层 Transformer 不断修改,最终输出的向量已经完全不是 Embedding 层的那个了。同一个词"苹果",在"苹果公司发布了新品"这句话里,经过 32 层 Transformer 之后,它的最终向量和在"妈妈买了一个苹果"这句话里是不同的——上下文已经把它塑造成了不同的表示。这是 Contextual Embedding,是 Transformer 架构的核心能力。
和 CGPoint/CGVector 的类比
表面上很像:CGPoint 是二维坐标,Embedding 向量是高维坐标,都是用数字描述"位置"。但有一个根本差异:CGPoint 的坐标系是人定义的(x 是水平方向,y 是垂直方向,单位是像素),每个维度含义明确。
Embedding 向量的每个维度是模型自己学出来的,没有人可以告诉你"第 137 个维度是什么意思"。更准确的类比是:想象一个 512 维的空间,里面的坐标轴是模型根据"预测效果最优化"这个目标自动确定的,没有固定方向,只有相对关系。你能做的操作不是"测量 x 方向的距离",而是"计算两个向量有多相似"(点积或余弦相似度)。
这一点很重要:向量的维度不可解释,但向量之间的距离和方向可以用来推断语义关系。你不能问"这个词的第 3 维是什么意思",但你可以问"这两个词在语义空间里距离多近"——这是 Embedding 唯一允许的操作,也是它和普通坐标系最根本的区别。