词云嵌入(精简版)

#2025/12/28 #ai

可以把 “词元嵌入” (Token Embeddings) 看作是将非结构化数据(文本)转换为结构化数据(向量)的关键类型转换过程。

分词器(Tokenizer)把文本转成了 List<Int>Token IDs)。但是,神经网络的内部计算(矩阵乘法)不能直接处理整数 ID,它需要浮点数向量

下面讲两个核心概念:

  • 静态查表动态上下文处理
    • 我们可以用“数据库查找”和“运行时上下文注入”来类比。

目录

1. 静态嵌入:巨大的 Key-Value 查找表 (The Lookup Table)

语言模型如何存储词元?

  • 数据结构视角:
    • 想象模型内部维护了一个巨大的只读哈希表(HashMap)或者查找表(Lookup Table)
      • Key (索引):
        • Token ID (例如 50257 代表 "The")。
      • Value (数据):
        • 一个固定长度的浮点数数组(Vector),
          • 比如 [0.12, -0.98, 0.55, ...]
  • 流程:
    • 当你把 Token ID 列表
      • `` 传给模型时,模型的第一层不做任何计算,仅仅是查表。它根据 ID 找到对应的向量。
        • 输入:[Integer]
        • 输出:[Vector<Float>]
  • 初始化与训练:
    • 这张表(嵌入矩阵)在模型刚开始训练时,里面的浮点数是随机初始化的(全是噪声)。
      • 为什么要这样呢?这个问题很有意思
    • 通过海量数据的训练,反向传播算法会修改这些数值,让语义相近的词(如 “cat” 和 “dog”)在数学空间上的向量距离更近。

2. 动态嵌入:运行时上下文注入 (Contextualized Embeddings)

这是 LLM 与老一代技术(如 word2vec)最大的区别

  • 问题:
    • 在静态查表中,“Apple” 这个词对应的向量是固定的
    • 但是
      • 在“I ate an Apple”(水果)和“I bought Apple stock”(科技公司)这两句话里,“Apple”的意思完全不同。
      • 如果只用查表,模型不仅无法区分多义词,也无法理解语境。
  • 解决方案(上下文相关):
    • 模型的第一层查表得到的只是“初始状态”。随后,这些向量会流经模型的一层层神经网络(Transformer 层)。
      • 处理逻辑:
        • 模型会查看“Apple”周围的词(Context)。
          • 如果周围有“eat”,模型就会修改“Apple”的向量,使其更像“水果”;
          • 如果周围有“stock”,就修改它使其更像“公司”。
      • 结果: 最终输出的向量是与上下文相关的(Contextualized)。它是动态计算出来的,而不是静态查出来的。

3. 代码实战:数据的形状 (Shape)

书中通过一段 DeBERTa 模型的代码展示了数据在内存中的样子。作为程序员,理解数据的 Shape(维度) 至关重要。

# 1. 输入文本
tokens = tokenizer('Hello world', return_tensors='pt')
# 此时 tokens['input_ids'] 是一个整数张量: [] (假设值)

# 2. 模型处理
output = model(tokens)

# 3. 查看输出维度
print(output.shape)
# 输出: torch.Size()

如何理解这个 ``?,

  • 1 (Batch Size):
    • 你一次处理了 1 个句子。
  • 4 (Sequence Length):
    • 这个句子被分成了 4 个 Token(比如 [CLS], Hello, world, [SEP])。
  • 384 (Hidden Size / Vector Dimension):
    • 这就是嵌入的核心。 每一个 Token 不再是一个整数,而被“展开”成了一个包含 384 个浮点数的向量。

总结:程序员视角的“词元嵌入”

  1. 接口层: 它是 IntegerFloat[] 的适配器。
  2. 存储层: 模型权重里包含一个巨大的 Matrix[Vocab_Size, Vector_Dim],专门用来做 ID 到向量的映射。
  3. 逻辑层:
    • LLM 的本质就是把这些静态的向量,经过复杂的计算(混合上下文信息),转换成含有丰富语义的动态向量,供下游任务(如分类、生成图片、命名实体识别)使用。

简单来说,嵌入(Embedding)就是把 符号(Symbol)变成了可计算的数学对象(Vector)