跳到主要内容

稠密嵌入与向量索引

嵌入(Embedding)是什么?​

  • 定义: 把每个词或句子转化成一串数字(向量,如 [0.2, -0.5, 0.8, ...]),并让语义相近的内容转化出的数字串也相近;
  • 向量空间: 这些向量所在的数学空间,可想象成一张高维地图,语义越接近的内容彼此越靠近;
  • 经典例子: “国王” - “男性” + “女性” ≈ “女王”,说明向量运算能捕捉语义关系;
  • “稠密”的含义: 相对于稀疏嵌入而言——稠密向量的每个维度都有数值,稀疏向量大部分维度为零;
  • 作用: 用深度学习把文本映射到向量空间,语义相近则向量距离也近;

为什么用余弦相似度而不是距离?​

  • 公式: cos(θ) = (A·B) / (|A| × |B|),A·B 是点积(对应维度相乘再求和),|A| 是模(各维度平方和的平方根);
  • 直觉: 关心两个向量的方向是否一致(语义是否相近),而不是它们的长度(文本的长度或频率);
  • 理由: 两篇内容相同但长度不同的文档,向量长度不同但方向一致,余弦相似度能正确判断语义相同;
  • 手算示例: “如何养猫” A=(0.9, 0.5, 0.1) 与“猫咪饲养指南” B=(0.8, 0.6, 0.1) 的 cos(θ) ≈ 0.99;与“股票投资策略” C=(0.1, 0.1, 0.9) 的 cos(θ) ≈ 0.25;
  • 量级: 实际嵌入模型使用 768 维甚至更高维度,但判断“是否相似”的原理完全相同;

稠密嵌入如何从 Word2Vec 演进到上下文感知?​

  • Word2Vec: 通过分析海量文本中的词汇共现关系,为每个词生成一个固定向量,能捕捉 king - man + woman ≈ queen 这类线性语义关系;
  • 静态向量的局限: 无法处理一词多义——“bank”在“river bank”(河岸)与“investment bank”(投资银行)中得到完全相同的向量;
  • 上下文感知模型(BERT、BGE-M3): 生成一个词的向量时充分考虑其所在句子甚至段落,同一词在不同语境下得到不同向量;
  • 机制: 自注意力(Self-Attention)让模型计算每个词向量时同时参考句子中所有其他词的信息;
  • 例子: “苹果”在“苹果公司发布新产品”与“买了两斤苹果”中得到不同的向量表示,实现从“词汇级”到“语境级”语义的飞跃;
  • 长文本: BERT 这类较早的上下文模型输入长度上限仅 512 个 token,不适合长文本;BGE-M3 等新一代模型进一步支持多语言与长文本;
  • 注意: BGE-M3 实际同时输出稠密、稀疏、多向量三种表示,此处仅以其稠密输出为例;

什么是 ANN,为什么需要它?​

  • 场景: 知识库有上百万条文档时,逐一计算相似度太慢;
  • ANN(Approximate Nearest Neighbor,近似最近邻): 通过巧妙的索引结构,在海量向量中实现近似但极快的最近邻查找;
  • 收益: 用少量精度损失换取数量级的查询速度;
  • 实现选择: dense-embedding 项目提供 ANNOY 与 HNSW 两种可切换后端,直接观察两类主流 ANN 算法的区别;

ANNOY 与 HNSW 如何取舍?​

特性ANNOY(基于树)HNSW(基于图)
构建速度快较慢
内存占用低较高
增量更新不支持(需完全重建)支持(长期增量插入后建议定期重建以保持查询精度)
查询精度较高极高
适用场景数据不常变的静态数据集需要实时索引新信息的动态场景
  • 结论: 选择合适的索引策略与选择嵌入模型同等重要,它直接决定系统的性能、成本和可维护性;