【AI】Embedding -- 词嵌入
现在我们有了一串数字 [8, 121, 33, …] ,但这串数字本身没有任何意义。数字 8 和数字 121 之间没有任何关联。我们需要将每个数字 ID 转换成一个 高维向量(Vector) ,这个向量能够捕捉到 Token 的 语义信息。至此,词嵌入完成。我们把一串无意义的数字 ID,转换成了一个包含初步语义信息的向量矩阵。
现在我们有了一串数字 [8, 121, 33, …] ,但这串数字本身没有任何意义。数字 8 和数字 121 之间没有任何关联。我们需要将每个数字 ID 转换成一个 高维向量(Vector) ,这个向量能够捕捉到 Token 的 语义信息 。
-
嵌入矩阵 (Embedding Matrix) :
- 这是 LLM 内部一个至关重要的、 可训练的 巨大参数矩阵。您可以把它想象成一个超级“查询台”。
- 这个矩阵的 行数 等于字典的大小(比如 50,000 行)。
- 这个矩阵的 列数 是一个超参数,称为 嵌入维度 (Embedding Dimension) ,也常被称为 d_model 。这个维度决定了模型的“宽度”。一个典型的 d_model 值可能是 768 (对于 BERT-base 模型) 或 12288 (对于 GPT-3)。我们以 768 为例。
- 所以,这个嵌入矩阵的尺寸就是 [50000, 768] 。
-
查询过程 :
- 对于我们得到的第一个 ID 8 (代表“请”),我们就在这个 [50000, 768] 的嵌入矩阵中, 取出第 8 行 。这一整行,就是一个包含 768 个浮点数的向量,它就是“请”这个 Token 的初始语义表示。
- 同理,我们取出第 121 行作为“帮”的向量,第 33 行作为“我”的向量,以此类推。
-
维度变化 :
- 输入 :一个长度为 6 的整数序列 [8, 121, 33, 556, 982, 105] 。
- 输出 :一个 [6, 768] 的矩阵。这个矩阵有 6 行,每行是一个 768 维的向量,分别代表了“请”、“帮”、“我”、“生成”、“一首”、“诗”这 6 个 Tokens 的语义。
至此,词嵌入完成。我们把一串无意义的数字 ID,转换成了一个包含初步语义信息的向量矩阵。
从整数 ID 到语义向量:深入 Embedding 层
- 输入:一个简单的整数张量 (Integer Tensor)
首先,这串整数 ID 在计算机程序中,通常被表示为一个 一维张量(Tensor) 。您可以暂时把它理解为一个数组或列表。
- 数据结构 : input_ids = tensor([8, 121, 33, 556, 982, 105])
- 形状 (Shape) :这个张量的形状是 [sequence_length] ,在我们的例子中就是 [6] 。它只有一个维度,长度是 6。
这个 input_ids 张量,就是我们准备传给 Embedding 层的全部输入。
- 核心部件:可训练的嵌入矩阵 (Embedding Matrix)
现在,我们来看 Embedding 层本身。它本质上就是一个 巨大、可训练的查询表 (Lookup Table) 。
- 它是一个矩阵 :这个矩阵的权重是模型需要学习的最重要的参数之一。
- 矩阵的维度 :
- 行数 (Rows) :等于词汇表的大小 ( vocab_size )。例如, 50,000 。
- 列数 (Columns) :等于模型的隐藏状态维度 ( embedding_dimension 或 d_model )。例如, 768 。
- 所以,这个嵌入矩阵的形状是 [50,000, 768] 。
您可以想象一个巨大的 Excel 表格,它有 50,000 行,768 列。每一行都代表了词汇表中的一个 Token。这一整行的 768 个浮点数,就是那个 Token 的“语义DNA”。
关键点 :这个 [50000, 768] 矩阵里的所有数字,在模型训练之初是随机初始化的。在数万亿次的“预测下一个词”的训练过程中,模型通过反向传播算法,不断微调这几千万个(50000 * 768)参数,最终让它们学会了:
- 意思相近的 Token(比如“国王”和“皇帝”)的向量在空间中也彼此靠近。
- 向量之间可以进行有意义的运算(比如 vector(“国王”) - vector(“男”) + vector(“女”) 在数学上会非常接近 vector(“女王”) )。
- 操作过程:高效的“查表”
当 input_ids = tensor([8, 121, 33, …]) 被传给 Embedding 层时,发生的操作极其简单高效:
它就是一个直接的索引查询 (Indexing / Lookup)。
- 模型看到输入张量的第一个数字是 8 。
- 它就直接去那个 [50000, 768] 的嵌入矩阵中, 取出索引为 8 的那一行向量 。这个向量的形状是 [768] 。
- 接着,模型看到第二个数字是 121 。
- 它就去矩阵中, 取出索引为 121 的那一行向量 。
- …这个过程对输入序列中的每一个 ID 都执行一次。
这个操作在底层硬件(GPU/TPU)上是高度优化的,速度极快。
- 输出:一个蕴含语义的二维矩阵
当对输入序列中的所有 6 个 ID 都执行完查表操作后,Embedding 层会把这 6 个取出来的 768 维向量堆叠在一起,形成一个新的 二维张量 。
- 输入形状 : [sequence_length] (即 [6] )
- 输出形状 : [sequence_length, embedding_dimension] (即 [6, 768] )
这个输出的 [6, 768] 矩阵看起来是这样的:
[
[0.02, -0.15, ..., 0.98], // 第 0 行: "请" 的 768 维向量 (从嵌入矩阵的第 8 行复制而来)
[-0.33, 0.87, ..., -0.01], // 第 1 行: "帮" 的 768 维向量 (从嵌入矩阵的第 121 行复制而来)
[0.56, 0.11, ..., 0.45], // 第 2 行: "我" 的 768 维向量 (从嵌入矩阵的第 33 行复制而来)
[0.91, -0.22, ..., -0.67], // 第 3 行: "生成" 的 768 维向量 (从嵌入矩阵的第 556 行复制而来)
[-0.08, 0.49, ..., 0.13], // 第 4 行: "一首" 的 768 维向量 (从嵌入矩阵的第 982 行复制而来)
[0.72, 0.03, ..., 0.88] // 第 5 行: "诗" 的 768 维向量 (从嵌入矩阵的第 105 行复制而来)
]
至此,我们已经成功地将一串无意义的整数 ID,转换成了一个包含丰富语义信息的、机器可以进行数学运算的浮点数矩阵。
这个 [6, 768] 的矩阵,就是我们送往下一站—— 位置编码(Positional Encoding) ——的“半成品”。
embedding算法
现在的大型语言模型(LLM) 不再使用一个独立的、预先训练好的嵌入算法 。取而代之的是, 嵌入层(Embedding Layer)本身就是整个巨大模型的一部分,它的参数(也就是那个巨大的嵌入矩阵)是与模型所有其他部分(如Attention层、Feed-Forward层)在同一个训练任务中,通过端到端(End-to-End)的方式共同学习和优化的。
这个“训练任务”本身,就是我们用来学习嵌入的“算法”。对于现代LLM,这个核心任务通常是 语言建模(Language Modeling) 。
核心思想:通过“上下文”来学习词义
无论是早期的Word2Vec,还是现在的LLM,学习词嵌入的基本哲学思想是一致的,源于语言学家J.R. Firth的名言: “You shall know a word by the company it keeps.”(观其伴,知其义。)
一个词的意义,是由它周围频繁出现的其他词来定义的。LLM将这个思想发挥到了极致。
LLM使用的“算法”:语言建模任务
LLM的训练目标非常纯粹: 给定一段上下文,预测下一个最可能的词(Token)是什么。 这个过程就是所谓的语言建模。
我们来看一个具体的例子,看看嵌入矩阵是如何在这个过程中被“教会”的。
假设的训练句子 : “The cat sat on the mat.” (猫坐在垫子上。)
训练步骤:
-
准备输入和目标 :
- 输入 (Context) : “The cat sat on the”
- 目标 (Target) : “mat”
-
初始状态 :
- 在训练开始时,模型内部那个巨大的嵌入矩阵 [50000, 768] 里的所有值都是 随机初始化 的。这意味着,此时取出的 “The”, “cat”, “sat” 等词的向量,都是无意义的随机数字串。
-
前向传播 (Forward Pass) :
- a. 嵌入 :模型取出输入序列 “The cat sat on the” 中每个词对应的随机向量。
- b. Transformer处理 :这些随机向量经过位置编码后,被送入多层的Transformer模块(Attention、Feed-Forward等)。
- c. 预测 :经过所有层的复杂计算后,模型在最顶层输出一个最终的向量。这个向量经过一个线性层和Softmax函数,转换成一个包含50,000个概率值的列表,代表了词汇表中每个词作为下一个词的可能性。
- 因为所有权重(包括嵌入矩阵)都是随机的,所以模型的第一次预测结果基本是胡猜。比如,它可能预测“floor”的概率是0.1%,“sky”是0.05%,而正确答案“mat”的概率只有0.002%。
-
计算损失 (Calculate Loss) :
- 模型将它的预测结果(一个概率分布)与真实的目标(“mat”)进行比较。
- 它发现,正确答案“mat”的预测概率(0.002%)非常低。
- 通过一个叫做**交叉熵损失(Cross-Entropy Loss)**的函数,模型计算出一个“损失值”或“错误程度”。这个值现在会非常高,表示“我这次错得离谱”。
-
反向传播 (Backpropagation) —— 学习的关键!
- 这是最神奇的一步。模型会利用这个巨大的“损失值”,从输出层开始, 反向地 计算出模型中 每一个参数 对于造成这个错误“应该承担多少责任”。
- 这个“责任”就是 梯度(Gradient) ,它指明了每个参数应该朝着哪个方向微调,才能让下一次的预测结果更接近正确答案。
- 这个梯度会一路回传,穿过所有Transformer层,最终抵达最底层的 嵌入矩阵 。
-
更新权重 (Update Weights) :
- 优化器(如Adam)根据计算出的梯度,对所有参数进行一次微小的更新。
- 关键在这里 :嵌入矩阵中,对应于我们输入词 “The” , “cat” , “sat” , “on” 的那几 行向量 ,都会被进行微调。
- 调整的方向是:“如果你们这些向量的值稍微变成这样,那么经过整个模型的计算后,最终预测出‘mat’的概率就会更高一点。”
这个过程会重复数万亿次,使用来自互联网、书籍等的海量文本。
-
当模型读到 “The cat drinks ___” 时,它会学习到应该预测 “milk” ,并微调 “The” , “cat” , “drinks” 的向量。
-
当模型读到 “My pet cat is ___” 时,它会学习到应该预测 “cute” ,并再次微调 “cat” 的向量。
经过亿万次来自不同上下文的“微调”后: -
“cat” 的向量因为它频繁地与 “pet” , “milk” , “meow” , “purr” 等词的上下文一起被优化,它的向量表示就逐渐编码了“猫”这个概念的丰富语义。
-
同理, “dog” 的向量会因为它与 “bark” , “loyal” , “walk” 等词的共现而被优化。
-
最终, “cat” 和 “dog” 的向量在768维空间中的位置会变得很近(因为它们都与"pet"共现),但又各有区别。
LLM 不再使用 Word2Vec做embedding
LLM 不再使用 Word2Vec,就像现代的智能手机不再使用物理键盘一样。Word2Vec 是一个革命性的、开创性的技术,它为后续所有工作奠定了基础,但它的设计理念和能力,已经无法满足现代 LLM 的需求。
具体来说,Word2Vec 有三个核心的“时代局限性”,而 LLM 的集成式 Embedding 完美地解决了这些问题:
1. 致命缺陷:静态与“一词一义” (Static & “One-Meaning-Per-Word”)
这是最根本的区别。
-
Word2Vec 的世界 :
- Word2Vec 训练完成后,会生成一个 静态的 查询文件。在这个文件中,一个词(比如 “bank”) 永远只对应一个固定的向量 。
- 这意味着,无论在什么语境下,“bank” 的向量表示都是一模一样的。
- 问题 :考虑以下两个句子:
- “I need to go to the bank to deposit money.” (我需要去 银行 存钱。)
- “The river bank is beautiful.” (这条 河岸 很美。)
- 对于 Word2Vec 来说,这两个 “bank” 的向量是 完全相同 的。它无法区分“银行”和“河岸”这两个截然不同的含义,所有的语义都被模糊地混合在了一个向量里。这是一个巨大的信息损失。
-
LLM 的世界 :
- LLM 的 Embedding 层虽然也提供一个初始的、固定的向量(就像我们之前讨论的),但这仅仅是 第一步 。
- 这个初始向量会和句子中其他词的向量一起,被送入多层 Transformer 模块。在 Attention(注意力)机制 的作用下,模型会根据上下文来动态地调整和重构每个词的表示。
- 在处理第一句话时,Attention 机制会发现 “bank” 和 “deposit”、“money” 关系密切,于是它最终输出的 “bank” 的向量表示会偏向“金融机构”的含义。
- 在处理第二句话时,Attention 机制会发现 “bank” 和 “river” 关系密切,于是它最终输出的 “bank” 的向量表示会偏向“河岸”的含义。
- 因此,LLM 产生的是 动态的、上下文相关的 (Contextualized) 词表示。
结论一:Word2Vec 是静态的,无法解决多义词问题;而 LLM 的嵌入是动态的,能根据上下文生成不同的表示。
2. 模型深度:浅层与深层 (Shallow vs. Deep)
-
Word2Vec 的世界 :
- Word2Vec 本质上是一个非常 浅的 神经网络,它只有一个隐藏层。
- 它能学习到的仅仅是基于一个很小的“滑动窗口”(比如目标词前后各5个词)内的局部共现关系。它能知道 “cat” 经常和 “meow” 一起出现,但很难捕捉到更复杂、更长距离的语法和语义结构。
-
LLM 的世界 :
- LLM 是一个非常 深的 神经网络,拥有几十甚至上百个 Transformer 层。
- 这种深度允许模型学习到 层次化的特征表示 。底层的网络可能学习到词性、句法等基础信息,而更高层的网络则能在此基础上,学习到逻辑、推理、情感、比喻等抽象得多的概念。
- Embedding 层作为这个深层结构的第一层,它所学习到的表示,是为整个深层网络的复杂计算“量身定制”的。
结论二:Word2-Vec 模型太浅,只能学到局部、简单的关系;而 LLM 的深度结构能学习到更丰富、更抽象的语言特征。
3. 训练范式:解耦与端到端 (Decoupled vs. End-to-End)
-
Word2Vec 的世界 :
- 训练和使用是 解耦的(Decoupled) 。你先用一个通用语料库(比如维基百科)训练好一个词向量文件。然后,在你的具体任务(比如情感分析)中,你 加载 这个已经训练好的、通用的词向量,并可能在任务训练中不再更新它(或只做微小的更新)。
- 问题 :这个“通用”的词向量,不一定最适合你那个“特定”的任务。
-
LLM 的世界 :
- 训练是 端到端的(End-to-End) 。Embedding 层作为整个模型的一部分,它的参数(嵌入矩阵)是和所有其他参数一起,为了同一个最终目标(预测下一个词)而被共同优化的。
- 这意味着,Embedding 层学习到的表示,是 高度适配 于 LLM 自身架构和任务的。它不是一个通用的“零件”,而是与整个“引擎”完美匹配的定制化组件。
结论三:Word2Vec 是一个通用的、预先训练好的“外挂”,而 LLM 的 Embedding 是与模型自身“血肉相连”的、共同进化的有机组成部分。
一个比喻
- Word2Vec :就像一个性能不错的**“通用引擎”**。你可以把它装在轿车、卡车、甚至船上。它都能工作,但表现不是最优的。
- LLM 的 Embedding 层 :就像一辆 F1 赛车的定制引擎 。它和赛车的底盘、空气动力学套件、电子系统是作为一个整体被设计和调校的。你不能把这个引擎拆下来装到一辆卡车上,但在它所属的那辆 F1 赛车里,它能爆发出无与伦比的性能。
参考资料:
https://zhuanlan.zhihu.com/p/1889016539598021229
https://zhuanlan.zhihu.com/p/1897009944559088101
https://blog.csdn.net/u011808788/article/details/154982463?spm=1001.2014.3001.5501
更多推荐

所有评论(0)