想象你走进一座巨大的国际图书馆。书架上的“书”形态千奇百怪:有的是印着文字的资料、有的是照片画册、有的是录音磁带;它们的“语言”也各不相同。若按传统方式找书,你得为每种语言、每种载体各制定一套检索规则,还要一位位翻译官手动处理。馆长的破局办法是一句朴素的话——无论什么形态、什么语言,我给每份资料都编一个统一的索书号。从此,一张猫的照片、一段写着“cat“的文本、一段”喵喵”叫声的音频,会被不同翻译官编成十分接近的索书号,放在索引大厅的同一片区。任何人只要拿着任意形态的纸条来到大厅,管理员就能顺着号码把其他形态的相关资料一起翻出来。这座图书馆就是多模态向量空间,翻译官是 CLIP 这类编码模型,索书号就是 Embedding(向量),大厅里的查找规则就是向量检索。下面,我们把这座图书馆从地基到前台服务完整搭建一遍。

岗位关联

学会多模态 Embedding 的统一存储与查询,你就能亲手设计以图搜图、图文互搜这类跨模态搜索系统,这是多模态 AI 应用、向量数据库和 AI 搜索引擎岗位的核心技能。

目录
  1. 可视化演示
  2. 多模态编码原理
  3. 统一向量空间
  4. 跨模态检索架构
  5. 多模态索引机制
  6. 存储选型策略
  7. 多模态应用实战
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示多模态Embedding存储的核心机制,通过入门/进阶/实战/优化四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

多模态Embedding存储:多模态E 多模态Embedding与CL 跨模态统一向量空间与对齐机制 核心机制可视化 多模态Embedding存储整体架构与关键组件

多模态编码原理

图书馆开业前,馆长先招聘了三类翻译官。文本翻译官擅长把句子拆成词义脉络,浓缩成一份“文字指纹”;视觉翻译官把像素里的轮廓、颜色、纹理变成“画面指纹”;音频翻译官把声波起伏转成“声音指纹”。他们风格完全不同,但馆方有个硬性要求:交上来的索书号长度必须一致,否则大厅没法统一归档。

在 AI 世界里,这三类翻译官就是三种模态的编码器。文本编码器常用 BERT 这类 Transformer 语言模型,把一句话变成一串数字;图像编码器用 ViT 视觉 Transformer 或 ResNet 这类卷积网络,把一张图变成同样长度的数字串;音频编码器则先将声波转成声谱图,再交给卷积网络提炼特征。训练时它们还要经过一个投影对齐层,把各自的特征统一映射到同一个向量维度。

从数学上看,每个编码器都是一个映射函数,把“原始数据”压成一个固定长度的向量:

三位翻译官各有所长,但最终交到大厅的答卷规格一致。语言、视觉、声音的巨大差异,被压缩进了一串数字里——图书馆的统一收编,从这一步就开始了。

fmodal:Xmodal→Rd\displaystyle f_{\text{modal}}: X_{\text{modal}} \to \mathbb{R}^d
通俗地说:三位翻译官交作业的答卷都必须是固定题数的答题卡,题数一样(d 道),大厅才好统一排架比较。
  1. 模态输入空间某一种模态的原始数据集合,例如一句话、一张 RGB 三通道图片、一段 16kHz 采样的音频波形。
    Xmodal∈{Xtext,Ximage,Xaudio}\displaystyle X_{\text{modal}} \in \{X_{\text{text}}, X_{\text{image}}, X_{\text{audio}}\}
  2. 编码映射函数由神经网络实现的编码器,把任意长度的原始输入压成固定长度 d 的实数向量。
    fmodal(x)=Encodermodal(x)\displaystyle f_{\text{modal}}(x) = \text{Encoder}_{\text{modal}}(x)
  3. 统一输出空间所有模态的向量都落在同一个 d 维实数空间里,文本、图像、音频的向量才能在后续两两比较。
    Rd∋ftext(xt),  fimage(xi),  faudio(xa)\displaystyle \mathbb{R}^{d} \ni f_{\text{text}}(x_t),\; f_{\text{image}}(x_i),\; f_{\text{audio}}(x_a)

统一向量空间

索书号有了,但馆里还必须立一条规矩:索书号越接近,内容越相关。否则光有编号,查了也白查。馆方在编号时约定:语义相同的资料必须排在一起,语义无关的必须隔得远远的。

这条规矩在 AI 里叫对比学习,而带领团队执行的总教练就是 CLIP 模型。训练 CLIP 时,把一张图和它对应的文字描述视为“正样本对”,把不匹配的图文视为“负样本对”。模型反复练习,直到正样本对的向量互相靠近、负样本对的向量相互远离。最终,文字和图片在同一个空间里达成了“语义对齐”——猫的照片和"cat"这个词,在向量空间里站到了几乎同一个方向。

如何判断两个向量有多接近?最常用的是余弦相似度:

CLIP 的训练目标,还可以写成对比学习的经典损失函数 InfoNCE:

经过这轮训练,同一只猫的照片、文字、音频,被练成了几乎相同方向的索书号,安静地躺在大厅同一片区;而“猫”和“狗”的索书号则相去甚远。图书馆的核心秩序,就此立下。

sim(u,v)=cos⁡θ=u⋅v∥u∥∥v∥=∑i=1duivi∑i=1dui2⋅∑i=1dvi2\displaystyle \text{sim}(u, v) = \cos\theta = \frac{u \cdot v}{\|u\| \|v\|} = \frac{\sum_{i=1}^{d} u_i v_i}{\sqrt{\sum_{i=1}^{d} u_i^2} \cdot \sqrt{\sum_{i=1}^{d} v_i^2}}
这张“评分单”要求正样本分数在全体候选分数中占绝对大头,好比新书入馆,管理员要确保它一定被放到语义最接近的书架。
  1. 正样本分数查询向量与匹配样本的相似度,模型希望它越大越好。
    sim(q,p+)\displaystyle \text{sim}(q, p^+)
  2. 温度系数控制分数分布的“尖锐程度”,值越小,模型对难负样本越敏感。
    τ>0\displaystyle \tau > 0
  3. 分母加和把正样本与全部负样本的指数分数加总,作为归一化基准。
    ∑j=1Nexp⁡(sim(q,pj)/τ)\displaystyle \sum_{j=1}^{N} \exp(\text{sim}(q, p_j) / \tau)
  4. 负对数把概率转成损失,概率越接近 1,损失越接近 0。
    −log⁡(⋅)\displaystyle -\log(\cdot)

跨模态检索架构

图书馆的读者服务中心,永远分两步服务:先在大厅快速圈出候选片区(粗召回),再由资深馆员精读候选书目给出最终推荐(精排)。这样既不会让读者等太久,也不会错过好书。

这套流程在工程上对应双塔模型。Query 塔负责实时编码用户的查询——无论是输入的文字、上传的图片还是喊出的一句语音;Item 塔则提前把全量资料离线编码好,存进向量库,避免在线重复计算。检索时,先用近似最近邻索引拉回 Top-K 个候选,再用更精细的模型对候选做二次打分。当一条资料同时包含文本、图像、音频三种描述时,可以按权重融合分数:

粗召回像在索引大厅按索书号快速扫片区,精排像馆员拿到候选书后逐一翻看内容。一台快、一台准,配合起来才既快又稳。

score(q,p)=w1⋅simtext(q,p)+w2⋅simimage(q,p)+w3⋅simaudio(q,p)\displaystyle \text{score}(q, p) = w_1 \cdot \text{sim}_{\text{text}}(q, p) + w_2 \cdot \text{sim}_{\text{image}}(q, p) + w_3 \cdot \text{sim}_{\text{audio}}(q, p)
三种线索各投一票,馆长根据业务场景决定哪一票更值钱:电商搜同款也许视觉票最重要,内容审核也许文本票最可靠。
  1. 各模态相似度查询与候选分别在文本、图像、音频三种语义下的余弦相似度。
    s1=simtext(q,p),  s2=simimage(q,p),  s3=simaudio(q,p)\displaystyle s_1 = \text{sim}_{\text{text}}(q, p),\; s_2 = \text{sim}_{\text{image}}(q, p),\; s_3 = \text{sim}_{\text{audio}}(q, p)
  2. 权重融合三个权重非负且和为 1,代表业务对每种模态的倚重程度。
    w1+w2+w3=1,wi≥0\displaystyle w_1 + w_2 + w_3 = 1, \quad w_i \geq 0

多模态索引机制

图书过亿后,哪怕有索书号,把整个大厅翻一遍也太慢。馆方于是配置了三套编目法宝。暴力搜索是一本一本地翻,准确但慢;IVF 倒排索引先把书架按大类分区,查询时只翻最可能的几个区;HNSW 图索引则靠“熟人网络”层层引荐——从几个书库管理员开始,顺着他们认识的近邻一路找到目标。PQ 量化则像把索书号写成缩写,在大致片区里先粗筛一遍,减少逐个比对的开销。

PQ 乘积量化的核心思想,是把一个高维向量拆成若干段,每段单独聚类,用“聚类中心编号”代替原始数值存储。查询距离因此变成一段段近似距离的求和:

三套法宝让查询从“翻遍全馆”变成“顺熟人引荐几步直达”,代价是偶尔会漏掉一两本远房冷门书——这就是近似检索的召回损失。工程上常说“没有免费的午餐”,速度、内存、召回率只能取舍。

d(x,y)≈∑m=1Md(cm(x(m)),cm(y(m)))\displaystyle d(x, y) \approx \sum_{m=1}^{M} d\big(c_m(x^{(m)}), c_m(y^{(m)})\big)
索书号的每一段都查一张“缩写对照表”,把大数字换成小编号,内存大幅下降,代价是距离变近似了。
  1. 向量切块把 d 维向量切成 M 段子向量,每段单独处理。
    x=[x(1);x(2);⋯ ;x(M)]\displaystyle x = [x^{(1)}; x^{(2)}; \cdots; x^{(M)}]
  2. 子空间聚类编码每一段在自己的子空间里找最近的聚类中心,用中心编号代替原始数值。
    cm(x(m))=arg⁡min⁡c∈Cm∥x(m)−c∥2\displaystyle c_m(x^{(m)}) = \arg\min_{c \in \mathcal{C}_m} \|x^{(m)} - c\|^2
  3. 距离近似求和把 M 段子空间的中心距离相加,得到原向量距离的近似值。
    ∑m=1M∥cm(x(m))−cm(y(m))∥2\displaystyle \sum_{m=1}^{M} \big\|c_m(x^{(m)}) - c_m(y^{(m)})\big\|^2

存储选型策略

图书馆落地时,馆方对空间做了精心规划:中心大厅只放索书号总索引,对应向量数据库;各楼层分馆放图书卡片和原始介质,对应关系型数据库与对象存储;热门书架放最近借阅最多的书,对应缓存层。

选存储时最常被问到:“向量库用哪个?” Milvus 擅长海量向量与 GPU 索引,适合亿级规模;pgvector 依托 PostgreSQL,让 SQL 和向量检索共存,适合中小规模与复杂过滤;Qdrant 用 Rust 实现、轻量易部署。实践中更常见的策略是元数据与向量分离:向量放向量库用于 ANN 召回,商品的标题、价格、类目等结构化字段放关系库,先向量召回再按元数据过滤。为了保证两套存储不闹矛盾,写入时通常采用双写加消息队列补偿,并配合主从同步保证一致性。

数据热度不同,存放位置也不同。热数据(如爆款商品、高频查询)放进内存索引或紧凑的量化向量;冷数据(如历史归档)落到磁盘或对象存储,需要时才加载。这种冷热分层让内存花在刀刃上,也控制了成本。

结构清晰的分馆让索书号索引、图书卡片、原始介质各自归位。以后要扩容,只需给索引大厅加新书架,分馆照常营业,互不拖累。

多模态应用实战

图书馆终于开门营业,最受欢迎的招牌服务有三项。以图搜图:读者拍一张衣服照片,大厅立刻按索书号找到同款、相似搭配甚至同色系的其他单品。图文互搜:输入“夕阳下奔跑的金毛犬”,系统同时返回文字段落、照片和视频片段。多模态 RAG:把 PDF 条款、合同截图、会议录音统一切片入库,大模型回答问题时可以引用跨越文本、图表、语音的证据。

落地上有三件事绕不开。第一,离线索引先行:所有资料在写入时就完成向量化,在线只做查询。第二,阈值与精排:ANN 返回的索书号再经过业务规则过滤——价格区间、库存状态、合规审核,避免“最相似但不该出现”的结果。第三,监控三件套:召回率、延迟、单次查询成本,任何一个指标恶化都要及时告警。

无论哪个应用,都在复用同一个大厅和同一套索书号体系。未来若新增一种模态,只需再雇一位“翻译官”,图书管理员不必推倒重来——这就是统一向量空间最大的红利。

AI 应用场景

电商以图搜图(拍立淘)

阶段:离线向量化 + 在线近邻检索

解决的问题:传统电商靠文字标签检索,买家拍照搜索时没有关键词,衣服的版型、花色、面料细节无法用文字准确描述;AI 用 CLIP 图像塔把商品图转成向量,用户随手一拍就能在千万商品里秒级找同款。

具体案例:某电商平台把 3000 万商品主图离线编码成向量存入 Milvus,用户上传一张街拍裙装照片后,系统先经 CLIP 图像塔得到查询向量,再用 HNSW 索引召回 Top 200,最后按店铺评分、价格区间、库存精排,把最像的 20 件呈现给用户,整体响应约 150ms。

多模态内容风控

阶段:离线违规样本索引 + 在线跨模态比对

解决的问题:涉黄涉暴内容常通过变体文字、改头换面的图片绕过关键词规则;AI 把视频关键帧、字幕文本、音频轨分别编码成向量,与违规样本库做近邻比对,语义相近就能命中,不再依赖字面匹配。

具体案例:某视频平台建立违规样本向量库,新上传的视频每秒抽取关键帧并转写字幕,三种模态的向量与库中样本计算相似度,任一模态得分超过阈值即进入人工复审队列,把漏放率降低了 60%。

多模态知识库问答(多模态 RAG)

阶段:离线切片向量化 + 在线检索增强生成

解决的问题:企业内部资料库包含 PDF 条款、产品截图、录音纪要,纯文本 RAG 无法检索图片和语音;AI 将各模态切片统一向量化,问答时跨模态召回,答案可以从图表和录音中找证据。

具体案例:一家律所的合同知识库接入多模态 RAG 后,律师提问“第 7.3 条的违约责任怎么约定”,系统同时检索到文字条款、盖章扫描件和会议讨论录音片段,并标注出处片段供核验。

Python 演示

python49 行
import math  class UnifiedSemanticLibrary:    """极简多模态语义库:用字符 bigram 特征模拟 CLIP 学到的统一向量空间。"""     def __init__(self, dim=64):        self.dim = dim        self.items = []        self.vectors = []     def _hash_vec(self, key):        v = [0.0] * self.dim        padded = " " + key.lower() + " "        for i in range(len(padded) - 1):            h = hash(padded[i:i + 2]) % self.dim            v[h] += 1.0        norm = math.sqrt(sum(x * x for x in v))        return [x / norm for x in v]     def add(self, text, modality):        self.items.append((text, modality))        self.vectors.append(self._hash_vec(text))        return self.vectors[-1]     def search(self, query_vec, topk=3):        scored = []        for i, v in enumerate(self.vectors):            s = sum(a * b for a, b in zip(query_vec, v))            scored.append((i, s))        scored.sort(key=lambda t: t[1], reverse=True)        return [(self.items[i][0], self.items[i][1], s) for i, s in scored[:topk]]  def main():    lib = UnifiedSemanticLibrary(dim=64)    lib.add("a cute cat in the sun", "text")    lib.add("cat photo on grass", "image")    lib.add("sound of meow cat", "audio")    lib.add("a dog running fast", "text")    lib.add("dog photo in the park", "image")     print("query: cat")    for text, modal, score in lib.search(lib._hash_vec("cat"), topk=3):        print("  %-4s | %-22s | %.3f" % (modal, text, score))  if __name__ == "__main__":    main()
目的:用 64 维“字符特征向量”模拟多模态编码效果,演示文本、图片、音频三类资料被统一存入一个语义空间,并支持跨模态近邻检索。
  1. self.vectors.append(self._hash_vec(text))每一条资料无论来自哪种模态,都转成同一个维度的向量,对应“统一索书号”。
  2. padded[i:i + 2]用字符二元组(bigram)作为特征,让拼写相近的文本在向量空间中自然靠近,模拟 CLIP 学到的语义一致性。
  3. s = sum(a * b for a, b in zip(query_vec, v))手工计算余弦相似度的分子部分,因为两个向量都是单位向量,点积就是余弦相似度。
  4. scored.sort(key=lambda t: t[1], reverse=True)按相似度从高到低排序,返回最匹配的 Top-K,对应大厅里“索书号最近的几本书”。
  5. lib._hash_vec("cat")把用户输入的查询词“cat“也编码成同一空间的向量,实现”拿着任意形态的纸条来找书”。

常见误区

误区我看到 CLIP 给我返回了相似图片,但它内部到底怎么判断的完全不知道,也没法控制和调试,只能全盘接受结果。

正解Embedding 向量本身承载了语义结构。模型把“猫”和“狗”编码到不同方向,把“猫”的照片和文字编码到相近方向,这些方向可以被可视化和统计。通过对比正负样本对、查看最近邻分布,工程师能定位模型是抓到了颜色、形状还是文字线索。向量还可以做算术:皇冠向量减去男人向量加上女人向量,会落在王后附近,说明空间里确实存在可解释的语义轴。

为何常见:平时开发只拿到一个相似度分数,看不到中间过程,自然觉得像黑盒;实际上向量距离、聚类结构、注意力权重都是可观测的窗口。

误区维度越大信息越丰富,检索效果肯定越好,所以一上来就选最大维度,模型能输出 1024 维就绝不用 512 维。

正解高维度带来“维度灾难”:在数据量不够时,高维空间里的点会变得稀疏,任意两点之间的距离趋于相同,反而难以区分近邻。同时内存和计算成本随维度线性增长,百万级向量、1024 维光原始存储就要几 GB。业界常用做法是先用高维训练,再通过降维或量化压缩到 256~512 维,换取近似的召回和更低的成本。

为何常见:人们习惯认为“大的就是好的”,且小规模实验里高维确实表现不差,等数据量上去才发现问题。

误区都是“找最近邻”,索引只是加速,返回的结果应该和全量扫描一模一样,不然就是索引有 bug。

正解HNSW、IVF 都属于近似最近邻(ANN)索引,本质是用召回率换速度。HNSW 层层贪心搜索可能错过局部最优路径;IVF 只查邻近几个桶,目标向量若落在桶边界就可能被漏掉。工程上通过增大 ef 参数、增加探测桶数(nprobe)来逼近暴力搜索的精度,但永远存在一个可调的近似误差。

为何常见:演示数据集只有几千条,索引和暴力搜索看起来结果一致,让人误以为两者等价;规模上百万后差距才会明显。

误区CLIP 能对齐文本和图片,那么多模态检索、分类、问答统统用 CLIP Embedding 就好,不用再想别的模型。

正解CLIP 擅长粗粒度的图文语义对齐,但对细粒度属性(“袖口有蓝色条纹”)、光学字符识别、罕见物体、分布偏移场景表现并不稳定。训练数据里少见的埋点、图标、专业图表,它的向量区分度会明显下降。实际系统常需要针对业务数据做微调,或把 CLIP 与 OCR、专用分类器组合使用。

为何常见:CLIP 的 Demo 效果震撼,很容易让人误以为“通用”等于“万能”,忽略了它本质上是训练数据分布下的对齐模型。

面试题

Q1. CLIP 模型通过什么方式让文本与图片共享同一个向量空间?

单选题 · easy

  • A.有监督分类
  • B.对比学习法← 正确答案
  • C.生成式预训练
  • D.深度强化学习

答案:B。CLIP 用对比学习拉近匹配图文对、推远不匹配图文对,从而让两种模态在同一个空间里语义对齐。分类任务需要固定标签体系,生成式预训练和强化学习都不是 CLIP 的核心机制。

Q2. 两个向量夹角越小,余弦相似度的值越接近多少?

单选题 · easy

  • A.0
  • B.0.5
  • C.1← 正确答案
  • D.-1

答案:C。余弦相似度衡量两个向量的夹角,夹角越小方向越一致,余弦值越接近 1。0 表示正交、-1 表示方向完全相反,0.5 只是中间值。就像两个人同向走时夹角为 0,方向一致性最高。

Q3. 双塔模型中 Query 塔和 Item 塔的主要区别是什么?

单选题 · mid

  • A.结构完全不同
  • B.编码对象不同← 正确答案
  • C.训练方式不同
  • D.输出维度不同

答案:B。双塔通常可以采用相同或相似的结构,训练也共用同一套对比损失,输出维度也必须一致才能算相似度。真正不同的是各自负责编码的对象:Query 塔编码的是实时查询,Item 塔编码的是库内全部候选资料。

Q4. 关于 InfoNCE 损失函数,下列说法正确的是?

多选题 · mid

  • A.温度系数控制预测分布的尖锐度← 正确答案
  • B.正样本是语义不匹配的样本对
  • C.分母包含正样本与全部负样本← 正确答案
  • D.优化目标只放大正样本的分数

答案:AC。InfoNCE 的温度系数 τ 越大分布越平滑、越小越尖锐;分母是正样本加全部负样本的指数分数总和,而非只算负样本;正样本是语义匹配的样本对;优化目标不是单纯放大正样本,而是让正样本在全体样本中的相对占比变大。因此选 A、C。

Q5. HNSW 索引的核心思想是什么?

单选题 · mid

  • A.聚类后分桶扫描
  • B.多层链表式近邻图← 正确答案
  • C.哈希表冲突链
  • D.B+ 树范围查询

答案:B。HNSW 维护一张多层近邻图,上层稀疏、下层稠密,查询时从上层快速定位到大致区域,再逐层进入下层精找。聚类分桶是 IVF 的做法,哈希表和 B+ 树分别是传统键值存储和关系库索引,与 HNSW 的图结构无关。

Q6. 使用 IVF 倒排索引查询时,候选集来自哪里?

单选题 · mid

  • A.全部数据集合
  • B.单个最近邻桶
  • C.最近的若干聚类桶← 正确答案
  • D.随机采样小桶

答案:C。IVF 先对全量向量做粗聚类,查询时把查询向量归入最近的若干聚类桶,只在这些桶内计算精确距离。若只查单个桶可能漏掉跨桶的近邻,查全部集合则失去了倒排索引的加速意义,随机采样更是无稽之谈。

Q7. PQ 乘积量化能节省存储空间的原因有哪些?

多选题 · hard

  • A.各子空间分别做聚类← 正确答案
  • B.用聚类编号代替原向量← 正确答案
  • C.根本上是减少了维度
  • D.用原型浮点表做映射← 正确答案

答案:ABD。PQ 将向量切分成多个子空间,每个子空间独立聚类,每个向量用一组聚类中心编号存储,编号远小于原始浮点数值;解码和距离计算通过查找浮点原型表完成。向量维度并没有减少,只是压缩了表达方式,因此 C 错误。

Q8. 向量与元数据分离存储的主要目的是什么?

单选题 · mid

  • A.让向量体积更小
  • B.降低索引更新成本
  • C.向量检索与属性过滤← 正确答案
  • D.防止单点故障丢失

答案:C。向量库专注 ANN 近邻召回,关系库保存结构化属性,二者结合才能完成“先按向量找相似、再按价格库存过滤”的业务流程。分离本身不压缩向量、不直接降低索引更新成本,也不是为容灾设计的,故选 C。

Q9. 以图搜图中,候选集从 100 万缩到 1 万后,精排环节主要负责什么?

单选题 · hard

  • A.直接删除全部候选
  • B.对候选重新算粗特征
  • C.在更准模型上精算相似度← 正确答案
  • D.转成文本后再搜索

答案:C。粗召回用轻量索引快速圈出 1 万个候选,精排则用更复杂但更准的模型(如更大规模微调模型、融合多模态分数)对这 1 万个逐一精算、重新排序。粗特征在召回时已算过,删除全部候选和转文本搜索都不符合精排的定位。

Q10. 工程上多模态检索系统采用冷热分层存储,通常会把什么放在热层?

多选题 · hard

  • A.高频访问的头部向量← 正确答案
  • B.全量历史长期归档数据
  • C.内存占用小的量化向量← 正确答案
  • D.延迟要求高的在线召回← 正确答案

答案:ACD。热层存放访问频次高、在线召回延迟敏感的数据,为了在有限内存里多放热数据,通常使用 PQ 等量化后的紧凑向量。全量历史归档数据属于冷层,应放在磁盘或对象存储中,故 B 错误,选 A、C、D。