09aba-将离散的 token ID 映射为连续的稠密向量

09aba-将离散的 token ID 映射为连续的稠密向量

本文档深入讲解 Token Embedding 的核心原理,涵盖从离散符号到稠密向量的映射机制、Embedding 层与查找表的等价关系、PyTorch 从零实现完整代码及逐行解析、为什么要用稠密向量而非 One-Hot,以及一个完整可运行的示例。帮助读者彻底理解 Embedding 层的运行机制 💡

章节阅读路线图 🗺️

  1. 核心概念 → 理解 Token、Embedding 和向量化的本质区别
  2. 为什么需要 Embedding → 从 One-Hot 到稠密向量的演进逻辑
  3. Embedding 层的本质 → 查找表 vs 矩阵乘法的等价关系
  4. 总结 → 回顾核心要点

1. 核心概念 💡

本章理解 Token、Embedding 和向量化的本质区别

在深入代码之前,先明确几个关键概念:

1.1 什么是 Token?

Token 是模型处理文本的最小单位。它可以是:

  • 单词:如 "hello"、"world"
  • 子词:如 "un-"、"believ-"、"-able"(BPE 分词的结果)
  • 字符:如 "h"、"e"、"l"、"l"、"o"
  • 特殊符号 :如 <PAD><UNK><CLS>

经过 Tokenizer 处理后,每个 Token 都会被映射为一个唯一的整数 ID:

arduino 复制代码
"我" → 1024
"喜欢" → 2048
"深度" → 3072
"学习" → 4096

什么是 Tokenizer(分词器)?

Tokenizer 是 NLP 模型的前置组件,负责将原始文本切分为 Token 序列,并转换为整数 ID。它的作用类似于"翻译官"------把人类语言翻译为机器可理解的数字。

例如:

python 复制代码
文本: "我喜欢深度学习"
      ↓ (Tokenizer)
Token: ["我", "喜欢", "深度", "学习"]
      ↓ (查词汇表)
ID:    [1024, 2048, 3072, 4096]

参考资料:

1.2 什么是 Embedding?

Embedding(嵌入)是将离散的 Token ID 映射为连续的稠密向量的技术。

例如,假设向量维度为 4:

less 复制代码
Token ID: 1024 ("我")  →  [0.2, -0.5, 0.8, 0.1]
Token ID: 2048 ("喜欢") → [0.6, 0.3, -0.2, 0.9]
Token ID: 3072 ("深度") → [0.1, -0.8, 0.5, 0.4]
Token ID: 4096 ("学习") → [0.7, 0.2, 0.3, -0.6]

什么是"稠密向量"?

稠密向量(Dense Vector)是指向量中大多数元素都是非零值,且每个维度都携带语义信息。这与稀疏向量(如 One-Hot 编码)形成鲜明对比。

例如:

  • 稠密向量[0.2, -0.5, 0.8, 0.1](所有维度都有值)
  • 稀疏向量(One-Hot)[0, 0, 1, 0, 0, ...](只有一个 1,其余全是 0)

稠密向量的优势在于:

  • 语义相似性:语义相近的词,向量在空间中的距离也近
  • 信息密度高:每个维度都编码了某种语义特征
  • 维度低:通常 128~768 维,远低于 One-Hot 的几万到几十万维

1.3 Embedding vs 向量化

很多文章没有区分这两个概念,但它们有本质区别:

维度 Embedding(嵌入) 向量化(Vectorization)
目的 学习低维稠密语义表示 将数据转换为数值向量(可能稀疏)
是否需要学习 需要(通过神经网络训练) 不需要(基于规则或统计)
语义表示 保留深层语义关系和相似性 可能不保留语义,仅是机械化表示
典型方法 Word2Vec、BERT、GloVe One-Hot、TF-IDF、词袋模型
结果维度 低维且稠密(如 512 维) 高维且稀疏(如 50000 维)

直观理解

  • 向量化像是"机械翻译"------直接把文字转成数字,不理解含义
  • Embedding像是"智能翻译"------不仅转成数字,还理解了语义关系

例如,对于"新年快乐"四个字:

  • 向量化:生成 4 个独立的向量,彼此没有关系
  • Embedding:生成的向量蕴含语义结构("新"和"年"可能更接近,"快"和"乐"可能更接近)

参考资料:


2. 为什么需要 Embedding 🎯

本章理解从离散符号到稠密向量的演进逻辑

计算机无法直接处理文字,必须转换为数值。但为什么要选择稠密向量?让我们看看发展历程:

2.1 第一阶段:直接用数字(索引化)

最简单的做法是给每个词分配一个唯一编号:

python 复制代码
词汇表 = {"新": 1, "年": 2, "快": 3, "乐": 4}
"新年快乐" → [1, 2, 3, 4]

问题:单一数字信息量不足

  • 无法描述语义关系
  • "abeyance"(中止)、"abide"(遵守)、"ability"(能力)在字典中索引临近,但语义相差甚远
  • 而 "a" 和 "an" 这两个同质的词却隔得很远

本质问题:单一标量无法表达词的复杂语义。


2.2 第二阶段:One-Hot 编码

为了解决单一数字信息量不足 的问题,我们想到用多个数字(向量)来表示一个词。最直观的方法是 One-Hot 编码:

python 复制代码
词汇表大小 = 4
"新" → [1, 0, 0, 0]
"年" → [0, 1, 0, 0]
"快" → [0, 0, 1, 0]
"乐" → [0, 0, 0, 1]

One-Hot 编码的规则

  • 向量长度 = 词汇表大小
  • 每个词对应一个位置为 1,其余全为 0
  • 第 i 个词的向量,第 i 位是 1

问题:维度灾难 + 语义孤立

  1. 维度灾难

    • 如果词汇表有 50000 个词,每个向量就是 50000 维
    • 存储一个句子需要巨大的内存(50000 × 句子长度)
    • 计算效率极低(大量乘以 0 的无效运算)
  2. 语义孤立

    • 任意两个 One-Hot 向量的点积都是 0(正交)
    • 无法表达"相似性"(如"猫"和"狗"应该相似,但向量完全不相关)
    • 每个词都是独立的"孤岛",没有任何关联
  3. 稀疏性

    • 99.99% 的元素都是 0,信息密度极低
    • 浪费了绝大部分存储空间

2.3 第三阶段:稠密向量(Embedding)

为了解决 One-Hot 的问题,我们引入稠密向量

python 复制代码
词汇表大小 = 50000
向量维度 = 512  # 远低于 50000

"新" → [0.2, -0.5, 0.8, ..., 0.3]  # 512 维稠密向量
"年" → [0.1, -0.4, 0.7, ..., 0.2]
"快" → [0.6, 0.3, -0.2, ..., 0.9]
"乐" → [0.7, 0.2, 0.3, ..., 0.8]

为什么稠密向量更好?

  1. 语义相似性

    • 语义相近的词,向量在空间中的距离也近
    • 例如:cos("猫", "狗") = 0.85(相似度高)
    • 例如:cos("猫", "汽车") = 0.12(相似度低)
  2. 信息密度高

    • 每个维度都编码了某种语义特征
    • 例如:维度 1 可能表示"动物 vs 非动物"
    • 例如:维度 2 可能表示"大小"
    • 例如:维度 3 可能表示"情感极性"
  3. 维度大幅降低

    • 512 维 vs 50000 维,存储和计算效率提升 100 倍
    • 避免了维度灾难
  4. 可学习性

    • Embedding 向量在训练过程中不断优化
    • 模型自动学习哪些语义特征对任务最重要

直观类比

想象你要描述一个人的特征:

  • One-Hot:用一个超长的清单,只有"身高"那栏打勾,其他全是空白
  • 稠密向量:用一个紧凑的档案,包含身高、体重、年龄、性格等多个维度的具体数值

显然,稠密向量能传递更多信息,且更高效。


参考资料:


3. Embedding 层的本质 🔍

本章理解查找表与矩阵乘法的等价关系

3.1 Embedding 层的本质是查找表

Embedding 层内部维护了一个嵌入矩阵(Embedding Matrix) ,形状为 [vocab_size, embedding_dim]

python 复制代码
词汇表大小 = 5
向量维度 = 4

嵌入矩阵 = [
    [0.1,  0.2, -0.3,  0.4],  # Token 0 的向量
    [0.5, -0.1,  0.6,  0.2],  # Token 1 的向量
    [0.3,  0.8, -0.2,  0.1],  # Token 2 的向量
    [0.9,  0.4,  0.5, -0.3],  # Token 3 的向量
    [0.2, -0.6,  0.7,  0.8]   # Token 4 的向量
]

当输入 Token ID 为 [2, 0, 3] 时,Embedding 层直接查表取出对应行:

python 复制代码
输入 ID: [2, 0, 3]
查表结果:
    Token 2 → [0.3,  0.8, -0.2,  0.1]
    Token 0 → [0.1,  0.2, -0.3,  0.4]
    Token 3 → [0.9,  0.4,  0.5, -0.3]

输出形状: [3, 4]  # 3个token,每个4维

为什么叫"查找表(Lookup Table)"?

因为 Embedding 操作等价于用 Token ID 作为索引,从矩阵中直接取出对应行,就像查字典一样快速。


3.2 查找表 vs 矩阵乘法的等价性

Embedding 操作在数学上等价于 One-Hot 向量 × 嵌入矩阵

python 复制代码
# 方法 1: 查找表(高效)
Token ID: 2
嵌入矩阵[2] → [0.3, 0.8, -0.2, 0.1]

# 方法 2: 矩阵乘法(理论等价,但低效)
One-Hot(2) = [0, 0, 1, 0, 0]  # 第 2 位为 1
One-Hot(2) × 嵌入矩阵:
[0, 0, 1, 0, 0] × [
    [0.1,  0.2, -0.3,  0.4],
    [0.5, -0.1,  0.6,  0.2],
    [0.3,  0.8, -0.2,  0.1],  ← 只有这一行被选中
    [0.9,  0.4,  0.5, -0.3],
    [0.2, -0.6,  0.7,  0.8]
]
= [0.3, 0.8, -0.2, 0.1]  # 结果完全相同!

为什么等价?

One-Hot 向量中只有一个 1,矩阵乘法的结果就是嵌入矩阵中对应行的加权和。由于其他位置都是 0,实际只取出了第 i 行。

但查找表快 3~5 倍

  • 矩阵乘法需要做 vocab_size × embedding_dim 次乘法和加法
  • 查找表直接取出对应行,时间复杂度 O(1)
  • 避免了大量乘以 0 的无效计算

反向传播的差异

  • 矩阵乘法:梯度会传播到整个嵌入矩阵(大部分是 0,无意义)
  • 查找表:梯度只更新被查询的那些行(高效且精准)

参考资料:


4. 总结 📝

本节我们完成了 Token Embedding 的核心原理和代码实现,核心要点回顾:

概念 说明 关键点
Token 文本处理的最小单位 可以是单词、子词、字符
Embedding 将离散 ID 映射为稠密向量 保留语义关系,维度低
查找表 Embedding 层的本质 用 ID 索引直接取行,比矩阵乘法快 3~5 倍
One-Hot 早期向量化方法 维度灾难、语义孤立、已被淘汰
稠密向量 现代表示方法 语义相似性、信息密度高、可学习

🔴 关键理解

  1. Embedding 是查找表,不是矩阵乘法(虽然数学等价,但实现差异大)
  2. 稠密向量比 One-Hot 更高效(维度降低 100 倍,语义关系可学习)
  3. padding_idx 用于标记填充位置(保持为 0,不参与训练)
  4. Embedding 向量在训练中不断优化(模型自动学习语义特征)

最后更新时间:2026-06-01

相关推荐
YOLO数据集集合1 小时前
低空林业巡检数据集|生态监测树木识别|深度学习树种分类数据集
人工智能·深度学习·yolo·目标检测·分类·无人机
weixin_468466851 小时前
机器学习之决策树新手实战指南
人工智能·python·算法·决策树·机器学习·ai
cesske1 小时前
机器学习模型评估指标|准确率、召回率、F1详解
人工智能·深度学习·机器学习·模型评估·召回率·准确率
古月开发1 小时前
AI 自动写周报工具:接入企业微信推送实战
人工智能·企业微信
J2虾虾1 小时前
Spring AI Alibaba - 智能体作为工具(Agent Tool)
java·人工智能·spring
武雄(小星Ai)1 小时前
Gemini CLI 免费用户6月18日停服,Google Antigravity 2.0 深度解读
运维·人工智能·agent
小北的AI科技分享1 小时前
iPaaS平台核心能力解读:五款产品功能与数据实录
人工智能·ipaas平台
KaMeidebaby1 小时前
卡梅德生物技术快报|生信实操:ChIP 染色质免疫共沉淀技术流程、短板与替代方案详解
前端·人工智能·物联网·百度·新浪微博
新加坡内哥谈技术1 小时前
大规模可靠 LLM 推理服务的实践经验构建可靠 LLM 推理基础设施的经验总结
人工智能