文本嵌入(用于句子和整篇文档):简洁篇

前文回顾

  • 给单个词元(Token) 办身份证
  • “文本嵌入” (Text Embeddings)
    • 就是给整个句子、段落甚至整篇文档拍一张“全息快照”。

这一节非常关键,因为它是目前大火的 RAG(检索增强生成)向量数据库 的技术基石。

我们可以从以下三个维度来直观理解:

目录

1. 核心概念:从 TokenSequence 的“语义压缩”

但在实际业务中,我们要处理的是:“The user cannot login to the system”(用户无法登录系统)

  • 以前的笨办法(词袋模型):
    • 统计单词出现的次数
    • 缺点是丢失了语序和深层含义
  • 中间的办法(词元嵌入取平均):
    • 把这句话里所有 Token 的向量加起来取平均值。虽然简单,但效果一般,因为“狗咬人”和“人咬狗”的平均值可能是一样的。
  • 现在的办法(文本嵌入模型):
    • 使用专门训练过的模型(通常是 BERT 类模型),将变长的输入文本(String),“压缩”成一个固定长度的浮点数数组(Vector)

工程师视角的类比: 你可以把“文本嵌入”看作是一种“语义哈希(Semantic Hash)”。

  • 传统的 Hash (MD5/SHA):
    • 输入变一点点,输出千差万别。
  • 语义 Hash (Embedding):
    • 输入变一点点(比如换个同义词),输出的向量只变一点点;
    • 意思越相近,向量在空间距离上就越近。

2. 代码实战:sentence-transformers

书中推荐使用 sentence-transformers 这个库,它是目前 Python 生态中做文本嵌入的事实标准(Standard)。

代码逻辑非常简单:

from sentence_transformers import SentenceTransformer

# 1. 加载模型 (这就好比加载一个专门生成 Hash 算法的库)
# 'all-mpnet-base-v2' 是一个很流行、效果很好的通用嵌入模型
model = SentenceTransformer("sentence-transformers/all-mpnet-base-v2")

# 2. 输入文本 (变长字符串)
text = "Best movie ever!"

# 3. 生成向量 (固定长度数组)
vector = model.encode(text)

# 4. 查看结果形状
print(vector.shape)
# 输出: (768,)

关键点解析:

  • 输入: 无论是 “Hi” 还是 “一段 500 字的影评”,输出的维度永远是固定的(比如 768 维)。
  • 这个 768 维向量:
    • 就是这句话在计算机眼里的“含义”。计算机现在不看字面了,只看这个数组。

3. 应用场景:为什么我们需要这个?

理解了“文本嵌入”,你就理解了现代 AI 应用的一半江山。书中简要提到了它的用途,这为本书第二部分埋下了伏笔:

  1. 语义搜索 (Semantic Search):
    • 传统搜索:
      • 用户搜 “登录失败”,你只能匹配包含“登录”或“失败”关键字的文档。
    • 嵌入搜索
      • 用户搜 “进不去系统了”,模型生成的向量和 “登录失败” 的向量非常接近(距离短),直接就能搜出来,虽然字面上没有一个字重合
  2. 聚类 (Clustering):
    • 你有 10 万条乱七八糟的客户评论。
    • 把它们都转成向量,扔到坐标系里。
      • 你会发现“物流慢”的评论自动聚在一起
      • “产品坏了”的评论聚在另一堆。
  3. RAG (检索增强生成):
    • 先把公司的知识库文档全部转成向量存进向量数据库
    • 当用户提问时,把问题也转成向量,去数据库里“捞”出最相似的文档片段,发给 ChatGPT 让它总结回答。

总结:给工程师的“太长不看版”

  • 文本嵌入模型 (Text Embedding Model) = 一个特征提取器。
  • 输入:
    • 任意长度的文本字符串
  • 输出:
    • 一个固定长度的 Float 数组(Feature Vector)。
    • 多维数组
  • 作用:
    • 让计算机能够通过计算向量距离(如余弦相似度),来判断两段话的意思是不是一样,而不是仅仅比较字符是否相同。