面试知识库
进阶

Embedding原理与选型#

一句话答案#

Embedding 将文本映射为稠密向量,语义相似的文本向量距离近,是 RAG 检索的基础。

核心要点

为什么”语义相近的文本向量也相近”——训练机制

不是天生的,而是用对比学习训练出来的:模型被显式优化成”把语义相近的文本拉到一起、把不相近的推开”。

  • 双塔 / 孪生结构:用同一个(共享权重的)编码器分别编码两段文本得到两个向量,在向量空间里比较。
  • 正负样本对:正样本对是语义相近的两句(如”问题—答案”、释义对、同篇上下文);负样本对是不相近的。训练目标 = 拉近正样本、推远负样本,反复优化后语义相近 → 向量距离近就成了模型的”习得属性”。
  • In-batch negatives(批内负采样):高效造负样本的技巧——一个 batch 内,每条样本的正例之外,其他样本的配对句直接当作它的负例,一个 batch 复用出大量负样本,无需额外采负。
  • 损失函数 InfoNCE / 对比损失:本质是把”正样本对的相似度”在”正样本 + 所有负样本”中做 softmax,最大化正样本被选中的概率(带温度系数 τ 调节区分度)。

句向量怎么来(token 向量 → 一个句向量)

Transformer 输出的是每个 token 一个向量,需池化成单个句向量:

  • [CLS] 池化:取句首 [CLS] 位置的向量(需训练让它学会聚合全句语义)。
  • mean-pooling(均值池化):对所有 token 向量取平均,通常更稳健,是 BGE/E5 等常用做法。

为何要归一化:把向量缩放到单位长度后,内积 = 余弦相似度,既能用更快的内积/点积计算,又消除了向量长度的干扰,只比较方向(语义)。余弦适合”只看方向、不看大小”的语义匹配(最常用);欧氏距离会受向量模长影响,适合需要考虑”幅度/大小”的场景。归一化后余弦与欧氏在排序上等价。

现代 embedding 的训练范式(BGE / E5 等):通常是两阶段——先在海量弱监督文本对上对比预训练(学通用语义),再用高质量标注对 + 难负样本做对比微调(对齐检索任务),部分还引入指令前缀(query/passage 加不同提示)进一步提升检索效果。

选型考虑: 向量维度 / 语言支持 / 性能 / 成本

常用模型: text-embedding-3-small(OpenAI) / bge-large(开源) / m3e(中文)

相似度: 余弦相似度(最常用)/ 内积 / 欧氏距离

面试回答(2分钟版)

Embedding的核心思想是把文本映射为高维稠密向量,使得语义相似的文本在向量空间中距离相近。这是RAG检索的基础——用户的问题和知识库文档都转成向量,通过计算向量相似度来找到最相关的内容。相似度计算最常用余弦相似度,衡量两个向量方向的一致性,不受向量长度影响。选型方面需要考虑几个维度:向量维度越高语义表达越精细但存储和计算成本也越高;语言支持很关键,中文场景下bge-large和m3e系列效果比较好;如果追求方便,OpenAI的text-embedding-3-small开箱即用但有API成本,开源模型可以本地部署更可控。实际项目中还有一些工程细节需要注意:Embedding模型要和向量数据库的索引类型配合,比如用了归一化的向量就可以用内积代替余弦相似度来加速;不同领域的文本可能需要对Embedding模型做微调才能获得好的召回效果;另外Embedding的质量直接决定了RAG系统的上限,所以选型时一定要用业务数据做评测而不是只看公开基准。

追问与易错

追问方向:

  • Embedding 模型怎么选?维度越高越好吗? → 看 MTEB 排行榜选同语言/同领域模型。维度 768-1024 是甜区,更高维度边际收益小但成本增加明显
  • 中文 Embedding 和英文 Embedding 有什么区别?选型要注意什么? → 中文分词粒度影响大(字级/词级/子词),需选中文语料训练的模型(如 BGE/M3E),英文模型直接用在中文上效果差
  • Embedding 缓存怎么做?增量更新时怎么避免重复计算? → 文档 Hash→Embedding 映射做缓存。DocMind 用 SHA-256 content_hash 做增量判断,hash 不变直接复用 vector_id
  • 不同相似度度量(余弦/欧氏/点积)什么时候用哪个? → 余弦最常用(归一化后不受向量长度影响),点积适合已归一化的向量(更快),欧氏距离适合需要考虑向量”大小”的场景

易错点:

  • ❌ 忽略 Embedding 模型和业务领域的匹配 → 通用模型在专业领域(法律、医学)效果可能很差,需要领域微调或选用专用模型
  • ❌ 不考虑 Embedding 计算的延迟和成本 → 在线实时 Embedding 要关注 API 延迟,大批量文档要考虑 Embedding API 费用
  • ❌ 文档更新时全量重算 Embedding → 应该用内容 Hash 做增量判断,只对变化的 chunk 重新计算

项目实践(DocMind): 使用 1024 维 Embedding 模型。增量索引核心设计:每个 chunk 计算 SHA-256 content_hash,更新时按 (kb_id, content_hash) 做 diff——hash 相同复用 vector_id 跳过 Embedding,hash 不同才重新计算。实际效果:100 页文档改 1 个字 = 1 次 Embedding 而非 200-400 次,吞吐提升两个数量级。