Embedding 与向量化:语义检索的地基
一句话定位:Embedding 把文字变成「语义坐标系里的点」,让机器用距离衡量意思的远近——检索、推荐、Agent 记忆、RAG(检索增强生成)全踩在这块地基上。无硬前置,可与提示词工程并行阅读。
换了个说法,就搜不到了
在文档系统里搜「退款」,所有含「退款」两个字的段落都能找到——关键词匹配干这个很在行。
但用户问「钱退回来了吗」,含「退款」的段落一条也搜不到:字面没有重叠,机器就束手无策。人类的理解力知道这是同一件事,关键词匹配不知道。
机器怎么才能知道「退款」和「钱退回来」意思相近?
答案是别拿文字比,先把文字变成坐标——意思相近的句子,在坐标系里就是相邻的点。比距离,就是在比意思。
图:Embedding 管线——文字进模型出坐标;语义相近的点在空间里天然聚拢,检索就是找最近邻
渐进拆解:给每本书算一组主题坐标
类比:按主题坐标排书的图书馆
想象一个图书馆,每本书不再按书名排序,而是按三个维度打分:「历史含量 0.8、科技含量 0.7、文学含量 0.6」——这组分数就是这本书的坐标,一本科技史的小说化读本就有了画像。找「讲故事的科技史」,不用匹配书名关键词,直接算坐标距离,最近的几本就是答案。
Embedding 模型干的就是这件事,只是维度不是 3 个而是几百到几千个,打的分也不是「主题含量」这么直白——每个维度是模型从海量文本里学到的某种语义特征。
从词向量到文本向量的演进也在这条线上:早期技术(word2vec 时代)一个词一个向量,「苹果」在任何句子里都是同一个坐标;现代模型整句整段进、整段出,同一个词在不同上下文里的坐标不同——「苹果发布了新手机」和「苹果很甜」里的苹果,已经被分到了两个位置。
例子:余弦相似度怎么算
两个向量各代表一句话,余弦相似度量的就是它们的夹角:夹角越小(方向越一致)分数越接近 1,完全垂直(无关)是 0,方向相反是负数。数值为示意(不同模型给分差异不小),直观感受一下三个数字:
- 「申请退款」 vs 「钱退回来了吗」:约 0.8 —— 意思几乎相同
- 「申请退款」 vs 「退货政策是什么」:约 0.6 —— 相关但不同事
- 「申请退款」 vs 「今日天气晴」:约 0.1 —— 基本无关
为什么用夹角而不用直线距离
两者在高维空间里通常排序一致,但余弦只看方向、不管长短——两段文字一个长一个短不影响相似度判断,正合适。工程上向量常做归一化(缩成单位长度),之后点积和余弦相等,算得更快。
大白话
Embedding 就是给每段文字发一张「语义身份证」,身份证上的号码是模型学出来的。找相似内容不用记文字,比对身份证号的接近程度——号码越接近,意思越近,就这么简单。
技术定义
Embedding 是把文本映射为高维稠密向量的函数,训练目标是让语义相近的文本在向量空间中距离更近。向量检索即以某查询向量为心,按余弦相似度(或内积)在库中找最近邻;大规模时用近似最近邻(ANN)索引换一点精度换大量速度,索引原理在朴素 RAG展开,混合检索在RAG 进阶展开。
选型四看:维度、语言、领域、榜单
一看维度
维度越高表达力越强,存储和计算成本也线性上涨。选型时留意一个新特性——嵌套维度(MRL):训练时让高维向量的前缀也是合法向量,于是同一个模型能按需取 4096 维或砍到 256 维用。主流开源模型规模参考:小模型约 1024 维(0.6B 参数级,单卡可跑),大模型可达 4096 维(8B 参数级,效果最好但成本数倍)。不过维度和参数量都不与效果严格挂钩,实测为准。
二看语言
模型的多语言能力完全由训练语料决定:只喂英文的模型,中文进去就是「乱码坐标」——不同语言的文本被扔进互不相关的小区域,跨语言检索、中文相似度全部失真。这就是「英文嵌入处理中文失效」的根因。选型第一步永远是确认模型的支持语言列表与中文评测成绩。
三看领域
通用模型对代码、医疗、法律等领域的表达天然弱一档;领域强需求时有两条路——换领域训练过的模型(如代码检索专用模型),或用自有数据微调(成本高于换模型,低于训练新模型)。
四看榜单,但别只看榜单
MTEB(大规模文本嵌入基准)是权威参考,覆盖检索、重排、聚类、分类、语义相似度等八类任务,榜首常年在开源与商用 API 之间轮换——以多语言榜为例,2025 年中大参数开源模型已登顶第一,平均分高于主要商用接口。看榜三原则:
- 只看自己任务对应的子榜——做检索就看检索子榜。
- 警惕榜单过拟合:在 benchmark 上刷分高,不等于你的数据上好。
- 永远用自己的真实数据跑一组对照——拿 50 条真实查询测命中率,一小时的事,比任何榜单都可信。
动手:算一次相似度,估一次迁移账
import numpy as np
def cosine(a, b): # 余弦相似度:夹角的余弦
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
v_refund = embed("申请退款") # 模型产出:如 1024 维向量
v_back = embed("钱退回来了吗")
v_weather = embed("今日天气晴")
print(cosine(v_refund, v_back)) # ≈ 0.8:意思近,分数高
print(cosine(v_refund, v_weather)) # ≈ 0.1:无关,分数低
# 换模型的迁移账:向量空间不通用,必须全量重算
# 两个模型的坐标系各自训练、互不相通——维度不同没法比,维度相同也不可比
cost = docs_count * (latency_per_doc or price_per_doc)
# 例:100 万段 × 2ms/段 ≈ 33 分钟(本地);或按 API 定价线性付费
迁移成本的量级感:embedding 本身不贵,贵在重算期间的服务与一致性——重算耗时分钟级到小时级,取决于文档量、批大小与硬件;千万级要考虑分批切换与新旧双跑。
边界与取舍
语义与字面,各有各的地盘——一张图看清分工:
图:地盘分工——左右互换位置都会翻车;向量被「长得像的编号」骗,关键词被「换个说法」骗
语义相似不等于答案正确。 Embedding 只保证「意思相近的点靠得近」,不保证最近的点就是你要的答案——「退款的坑」和「怎么退款」意思很近,但一个是吐槽一个是教程。这就是纯向量检索的天然盲区,需要重排序与查询改写来补,见RAG 进阶。
关键词没有死。 型号名、代码标识符、人名这类必须字面精确的内容,关键词匹配(BM25)反而比向量可靠——「错误码 E-4021」被 embed 之后,和「错误码 E-4022」可能近得危险。生产系统几乎都是向量 + 关键词双路,混合检索的取舍同样在 RAG 进阶展开。
向量库选型一句话版
选型的第一分岔不是「哪个库」,而是「要不要独立部署一个库」——十万级以下数据,SQLite 加个向量插件甚至够用。
| 场景 | 选型 | 理由 |
|---|---|---|
| 实验和小项目;个人知识库(几千条笔记) | Chroma | 嵌入式,几行代码起服务,直接嵌进应用进程 |
| 单机性能与算法丰富度;纯离线批处理(每晚重建一次索引) | FAISS | Meta 的向量计算库,不是完整数据库;批处理算完就收工 |
| 分布式、多租户、要生产级运维;团队级检索(百万级、并发查询) | Milvus(或各类云托管方案) | 独立部署 |
自测
合上文章先自己答,再展开对照:
「字面相似」和「语义相似」为什么是两件事?英文嵌入处理中文为什么失效?
字面相似是字符序列的重叠(关键词匹配的领域),语义相似是意思的接近(向量空间的领域)——「退款」与「钱退回来了」字面零重叠但语义几乎相同,「错误码 E-4021」与「E-4022」字面几乎相同但语义无关。两套相似度各管一段,互相不可替代。英文嵌入处理中文失效的根因在训练语料:模型的语义空间完全由训练数据塑造,语料里几乎没有中文,中文文本就没有被安放到有意义的坐标上——不同语言的文本散落在互不相关的区域,中文查询自然找不到该找到的内容。选模型先确认支持语言与中文评测成绩。
换 Embedding 模型为什么要重建整个向量库?迁移成本怎么估?
每个模型的语义空间是独立训练出来的:同一个「退款」,A 模型给出的 1024 维坐标与 B 模型的 2560 维坐标分属两个互不相通的坐标系——维度不同无法直接比,维度相同也不可比(各维度的语义含义完全不同)。所以换模型 = 库里每条向量都要用新模型重算一遍。成本估算:核心是「文档量 × 单条处理成本」——本地部署算时间(分钟级到小时级,看文档量与硬件)、API 部署算钱(单价 × 总量),再叠加重算期间的服务连续性成本(通常新旧双跑或分批切换)。另外别忘查询端:查询文本也要同步换模型,且历史日志无法复用。
参考与延伸
- Qwen3-Embedding 系列仓库(2025-06):0.6B/4B/8B 三档规格与多语言榜单成绩,当前开源多语言模型的代表 — github.com/QwenLM/Qwen3-Embedding
- MTEB 排行榜(Hugging Face):大规模文本嵌入基准,八类任务分榜查询,选型第一站 — huggingface.co/spaces/mteb/leaderboard
下一站:RAG 检索增强生成——Embedding 是引擎,RAG 是装上引擎的第一台整车。