想想象一座巨大的“万国档案馆”,里面存放着人类所有的知识:有贴着世界名画标签的图片、有整柜整柜的语言书籍、还有一排排老式录像带。这些资料原本说着完全不同的“语言”——图片用色彩和线条讲故事,书籍用文字记录思想,录像带靠连续的画面传递动态信息。如果一位访客用中文问:“我想找一段小狗在沙滩上奔跑的视频”,传统的检索员只能靠人工给录像带贴的文字标签去猜,标签没写“小狗”,这段珍贵视频就永远沉在档案柜底。 这座档案馆的解法,是建一个“世界语翻译中心”。所有资料,不管原来是图片、文字还是录像带,都会被翻译成同一种“世界语数字编码”——也就是一个高维向量。从此,无论你用文字、图片还是视频片段提问,翻译员都能把你的问题也译成世界语编码,再在全馆资料库中找出编码最接近的档案。这个“翻译中心”,就是多模态Embedding(图文/视频)要做的事。

岗位关联

掌握多模态Embedding,意味着你能让AI在图片、文本、视频之间自由“对表”,这是现代搜索、推荐、内容理解系统里连接不同数据形态的关键能力,也是向量检索从业者的核心技术栈之一。

目录
  1. 可视化演示
  2. 多模态初相识——档案馆里的“语言混乱”
  3. 统一向量空间——订立“世界语规范”
  4. 图文双塔匹配——翻译官是如何练成的
  5. 视频嵌入方法——如何翻译一卷录像带
  6. 相似度检索——用一把尺子丈量世界语
  7. 索引加速算法——档案馆的索引柜
  8. 工程实践落地——从档案馆到分馆
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

模拟CLIP双编码器将图文映射到共享向量空间,展示对比学习训练与HNSW近似最近邻检索过程。

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

模式1:CLIP双编码器架构 图像编码器(ViT)提取视觉特征向量 文本编码器(Transformer)提取语义向量 sim(I,T) = cos(I_e, T_e) 双编码器将图文映射到共享Embedding空间。

多模态初相识——档案馆里的“语言混乱”

万国档案馆的库房总是很热闹:左手边,收藏家送来一幅《沙滩上的金毛犬》油画;右手边,作家交来一部描写夏日海边的小说;楼上,导演还在剪辑一段小狗追浪的纪录片。可检索员叫苦不迭——油画不会说话,小说只有文字,录像带更是没法“翻页”。它们虽然讲着同一个主题,用的却是三种完全不同“语言”。所谓多模态(Multimodal),指的就是图像、文本、视频这些截然不同的数据形态。它们各自的原生表示差异极大:图片是一堆像素矩阵,文本是一串离散的词元(Token),视频则是连续画面的序列,计算机天然无法把它们摆在一起比较。

传统做法像是给每份档案手写标签,用文字描述图片内容、给视频打关键词,可这既费人力,又会丢失大量细腻的视觉信息。Embedding方法的思路完全不同——它训练一个神经网络编码器,把任何模态的原始数据直接压缩成一个稠密向量(Dense Vector)。这个向量里没有“像素”,也没有“单词”,只有一组表示语义特征的实数。一个训练良好的向量应该让“金毛犬”的图片编码和“金毛犬”的文字编码在数字层面长得差不多,这就是多模态Embedding的核心野心。

万国档案馆的“翻译中心”正是这样运作的:不管收进来的是油画、小说还是录像带,都先送进各自的编码器压成一条定长的世界语编码。至于如何让这些编码之间真的“能对话”,则是下一节要解决的对齐问题。

z=fθ(x),z∈Rdz = f_\theta(x), \quad z \in \mathbb{R}^d
这个公式是说:找一个带参数的神经网络函数 \(f_\theta\),把任意模态的原始输入 \(x\) 变成一个 \(d\) 维向量 \(z\)。从此,图片、文字、视频都拥有了同一种“身份证格式”。
  1. 输入 \(x\)代表任意模态的原始数据——图片的像素矩阵、文本的词元序列、视频的单帧画面。它是一切编码的起点。
    xx
  2. 编码器 \(f_\theta\)一个可训练的神经网络,参数为 \(\theta\),负责从原始数据中提炼语义特征,类似一位“翻译官”。
    fθ(⋅)f_\theta(\cdot)
  3. 输出 \(z\)模型产出的稠密向量,每个维度都是一个小数,整体代表该样本的语义浓缩。
    z=fθ(x)z = f_\theta(x)
  4. 空间 \(\mathbb{R}^d\)向量 \(z\) 生活在一个 \(d\) 维实数空间中,\(d\) 常取 512、768 或 1024。
    Rd\mathbb{R}^d
  5. 整体视角不同模态的输入只要能送进各自的 \(f_\theta\),就被统一成了同维度、同空间中的向量。
    z∈Rdz \in \mathbb{R}^d

统一向量空间——订立“世界语规范”

档案馆要真正让三种语言互通,光有“翻译中心”还不够,还得订立一本统一的世界语规范。假如图像翻译官独自发明了一套编码,文本翻译官又发明了另一套,两套编码的写法完全不同,检索员拿着访客的文字问题去比对图片编码时依然一头雾水。因此,所有模态的编码最终必须落到同一个坐标系里才能互相比较。这个共享的坐标系,就是统一向量空间(Unified Vector Space)。

实现统一的第一步,是让每种模态先经过各自的基础编码器提取特征,再通过一个可学习的投影层(Projection Layer)把特征映射到共享空间。以图文为例:图片先经过卷积网络或视觉Transformer得到视觉特征,文本先经过BERT等语言模型得到语义特征,然后两者分别乘上一个投影矩阵,将各自的原始空间“旋转”到一个公共空间。

投影层就像一本“世界语对照表”:图像翻译官把自己对画面的理解写成一串数字,文本翻译官把对文字的理解也写成一串数字,两串数字的长度和书写规则完全一致。此时,检索员再也不用关心这份档案来自哪种语言,只需要拿着同一把尺子去衡量它们在世界语空间中的远近即可。

zimage=Wimage⋅Eimage(ximage),ztext=Wtext⋅Etext(xtext)z_{\text{image}} = W_{\text{image}} \cdot E_{\text{image}}(x_{\text{image}}), \quad z_{\text{text}} = W_{\text{text}} \cdot E_{\text{text}}(x_{\text{text}})
这个公式展示了“各走各的路,最后汇合”的思想:图像和文本各自用基础编码器 \(E\) 处理原始输入,再用投影矩阵 \(W\) 对齐到统一空间中,得到可互相比较的向量。
  1. 图像原始输入 \(x_{\text{image}}\)输入的一张图片,例如“金毛犬在沙滩上”的照片。
    ximagex_{\text{image}}
  2. 图像基础编码器 \(E_{\text{image}}\)一个在大量图像上预训练好的骨干网络,负责抽取视觉特征。
    Eimage(ximage)E_{\text{image}}(x_{\text{image}})
  3. 图像投影矩阵 \(W_{\text{image}}\)可学习的线性变换矩阵,将视觉特征“扳”进统一空间的方向。
    Wimage⋅Eimage(ximage)W_{\text{image}} \cdot E_{\text{image}}(x_{\text{image}})
  4. 文本侧同理文本用 \(E_{\text{text}}\) 编码,再用 \(W_{\text{text}}\) 投影,得到 \(z_{\text{text}}\)。
    ztext=Wtext⋅Etext(xtext)z_{\text{text}} = W_{\text{text}} \cdot E_{\text{text}}(x_{\text{text}})
  5. 两式并列图像和文本两条路径的输出 \(z_{\text{image}}\)、\(z_{\text{text}}\) 处于同一向量空间中,意味着可以直接计算相似度。
    zimage, ztext∈Rdz_{\text{image}}, \, z_{\text{text}} \in \mathbb{R}^d

图文双塔匹配——翻译官是如何练成的

光有对照表还不够,还得让全体翻译官一起合练。万国档案馆的做法是:请一位图像翻译官和一位文本翻译官并肩坐在同一张桌前,天天看同一批“图文对”——例如一张金毛犬玩飞盘的照片,配上一句“金毛犬在草地上接飞盘”。训练时,如果图像翻译官输出的编码和文本翻译官输出的编码越接近,就奖励他们;如果驴唇不对马嘴,就惩罚他们。这套方法在技术上的名字叫“对比学习”,而这两位翻译官合在一起,就是著名的“双塔模型”。

双塔结构(Two-Tower)由两个独立的编码塔组成:图像塔(Image Tower)负责把图片编码成向量 \(z_{\text{image}}\),文本塔(Text Tower)负责把文本编码成向量 \(z_{\text{text}}\)。在训练时,把一批图文配对样本同时送进两座塔,对每个图像,它的正确文字描述就是正样本,其他文字都是负样本;对每段文字,同理。模型的优化目标是让正样本对在统一空间里距离更近,负样本对距离更远。

经过这种合练,两位翻译官的默契度大幅提升。以后不管来的是从来没见过的画作,还是措辞新奇的诗句,他们都能把彼此输出的世界语编码对齐到相近的位置。这份“看图说话”和“听声辨物”的双向能力,正是以图搜文、以文搜图的基础。

LInfoNCE=−log⁡exp⁡(sim(zi+,zi)/τ)∑j=1Nexp⁡(sim(zj,zi)/τ)\mathcal{L}_{\text{InfoNCE}} = -\log \frac{\exp\left(\text{sim}(z_i^+, z_i)/\tau\right)}{\sum_{j=1}^{N} \exp\left(\text{sim}(z_j, z_i)/\tau\right)}
InfoNCE 损失的通俗理解:把“正确地认出配对样本”当作一场考试。模型不仅要认出唯一的正确答案,还要在 \(N\) 个干扰项中把它挑出来。温度系数 \(\tau\) 控制考试的严格程度。
  1. 正样本相似度 \(\text{sim}(z_i^+, z_i)\)查询向量 \(z_i\)(如图片向量)与它的正确配对向量 \(z_i^+\)(如对应文本向量)之间的相似度,一般用余弦相似度。
    sim(zi+,zi)\text{sim}(z_i^+, z_i)
  2. 相似度指数化与温度 \(\tau\)把相似度除以温度系数 \(\tau\) 后取指数,\(\tau\) 越小,分布越尖锐,模型对困难负样本更敏感。
    exp⁡(sim(zi+,zi)/τ)\exp\left(\text{sim}(z_i^+, z_i)/\tau\right)
  3. 分母的求和 \(\sum_{j=1}^{N}\)把查询向量与所有 \(N\) 个候选向量(包括一个正样本和 \(N-1\) 个负样本)的相似度指数求总和。
    ∑j=1Nexp⁡(sim(zj,zi)/τ)\sum_{j=1}^{N} \exp\left(\text{sim}(z_j, z_i)/\tau\right)
  4. 取负对数 \(-\log\)将“正样本概率”取负对数作为损失,概率越接近 1,损失越小;训练就是不断压低这个损失。
    −log⁡(⋅)-\log(\cdot)
  5. 整体含义模型被迫在众多干扰项中认出正样本,从而学会让图文语义在统一空间中“同义靠近”。
    exp⁡(sim(zi+,zi)/τ)∑j=1Nexp⁡(sim(zj,zi)/τ)\frac{\exp(\text{sim}(z_i^+, z_i)/\tau)}{\sum_{j=1}^{N} \exp(\text{sim}(z_j, z_i)/\tau)}

视频嵌入方法——如何翻译一卷录像带

到了录像带档案室,翻译工作又升级了。一卷录像带不是一张静态图片,而是一连串不断变化的画面。如果翻译官只挑其中一帧来看,看到的是小狗静止在沙滩上,完全感受不到它奔跑的姿态;可如果把每一帧都当成图片仔细翻译,一卷十分钟的视频有上万帧,计算成本高得吓人。万国档案馆聪明的做法是:先抽样,再连起来看。

视频嵌入(Video Embedding)的关键差异就在于多了时间维度。工程上一般分两步:第一步是帧采样,常用的有均匀采样(每隔固定帧数取一帧)和关键帧采样(先抽帧再用算法挑出画面变化最剧烈的帧);第二步是时序建模,把采样出来的帧序列送入一个能捕捉时间关系的模型,如 3D 卷积、视频 Transformer,或者简单的时序池化。最朴素的基线方法就是平均池化——把每一帧经过图像塔得到的向量加起来取平均,作为整个视频的向量。

平均池化像一个只顾“均值”的偷懒翻译官:把整卷录像带的每帧世界语都念一遍后取个平均值,虽然大体不差,但小狗起跳的精彩瞬间却被冲淡了。更高级的作法是用注意力机制给每一帧加权,让模型自己决定哪一帧更值得多看一眼,从而保留叙事中的高光时刻。

zvideo=1T∑t=1Tztz_{\text{video}} = \frac{1}{T} \sum_{t=1}^{T} z_t
这个公式像在说:把一卷录像带翻译成 \(T\) 句“帧语言”,再把 \(T\) 句编码逐字加起来取平均,得到整卷录像带的概要。平均池化是基线,但有时会稀释掉关键瞬间的信息。
  1. 视频总帧数 \(T\)经过采样后,从原始视频中选出的帧数量,一般取 8、16 或 32 帧。
    TT
  2. 第 \(t\) 帧的向量 \(z_t\)每一帧图像单独经过图像编码器得到的向量,代表该瞬间的画面内容。
    ztz_t
  3. 累加求和 \(\sum_{t=1}^{T} z_t\)把所有帧向量按维度逐项相加,得到视频的“总能量”。
    ∑t=1Tzt\sum_{t=1}^{T} z_t
  4. 取平均 \(\frac{1}{T}\)将总和除以帧数,得到一个与帧数无关的稳定向量。
    1T∑t=1Tzt\frac{1}{T} \sum_{t=1}^{T} z_t
  5. 输出 \(z_{\text{video}}\)最终生成的视频级向量,可以和其他模态向量直接比较相似度。
    zvideo∈Rdz_{\text{video}} \in \mathbb{R}^d

相似度检索——用一把尺子丈量世界语

档案资料全部翻译成世界语编码之后,真正的考验来了:访客用中文问“小狗沙滩奔跑”,翻译员把这句话也译成了一串世界语编码。可档案库里躺着上百万条编码,怎么判断哪一条更像访客想要的?万国档案馆给每位检索员发了一把“尺子”——不是量长度的尺,而是量方向的尺。只要两条编码指向的方向越接近,就认为它们的语义越相似。

这把尺子的学名叫余弦相似度(Cosine Similarity)。它衡量两个向量的夹角余弦值,只关心方向是否一致,不关心向量的长短。这非常符合语义比较的场景:同一句话用不同的语气、不同的长度表达时,编码向量的模长可以不同,但语义方向应该一致。

有了这把尺子,检索员的工作变得轻松:把访客的查询向量与档案库中每条向量的余弦相似度算一遍,从大到小排序,再把前 \(K\) 条返给访客。这就是跨模态搜索最朴素的流程——查询模态也好,档案模态也好,都被世界语编码统一,用同一把尺子丈量。

sim(u,v)=u⋅v∥u∥⋅∥v∥=cos⁡(θ)\text{sim}(u, v) = \frac{u \cdot v}{\|u\| \cdot \|v\|} = \cos(\theta)
通俗地说:把两个向量画成从原点出发的两条箭头,夹的角越小,余弦值越接近 1,说明语义越像;夹成直角时余弦为 0,说明没什么关联;反方向时余弦为负,说明语义相反。
  1. 向量点积 \(u \cdot v\)\(u\) 和 \(v\) 逐维度相乘后累加,衡量两个向量在对应维度上的协同程度。
    u⋅v=∑k=1dukvku \cdot v = \sum_{k=1}^{d} u_k v_k
  2. 向量的模 \(\|u\|\)向量 \(u\) 的长度,计算方式是各维度平方和再开根号。
    ∥u∥=∑k=1duk2\lVert u \rVert = \sqrt{\sum_{k=1}^{d} u_k^2}
  3. 归一化比值点积除以两个模长,本质是把两个向量都缩放到单位长度后再点积,消除长度影响。
    u⋅v∥u∥⋅∥v∥\frac{u \cdot v}{\|u\| \cdot \|v\|}
  4. 余弦等价 \(\cos(\theta)\)比值等于两向量夹角 \(\theta\) 的余弦值,结果范围在 \([-1, 1]\)。
    cos⁡(θ)∈[−1,1]\cos(\theta) \in [-1, 1]

索引加速算法——档案馆的索引柜

百万份档案,刚才的“逐份比对”还能勉强接受;可万国档案馆的库房很快扩展到了上亿份,检索员就算拔腿狂奔,也没法在眨眼间跑完全馆。聪明的档案馆长决定加装一套“索引柜”——把相似的世界语编码分门别类摆进相邻的抽屉,检索员只需先找到访客查询可能对应的那几格抽屉,再在里面仔细翻找,而不是扫遍全馆。

这套思维对应着向量检索中的 ANN(近似最近邻)算法。其中最常用的两个家族是 IVF 和 HNSW。IVF(倒排文件索引)的思路是先对所有档案向量做聚类,比如聚成 1000 个桶,查询时只挑最近的几个桶去搜索;HNSW(分层小世界图)则构建一张多层图,顶层节点少、连接稀疏,可以快速跳到目标区域,底层节点多、连接紧密,再做精细搜索。两者都追求“少跑冤枉路”。

索引柜让检索员从“全馆搜捕”变成“定点排查”,速度提升成百上千倍,代价是可能漏掉极少数藏在错误抽屉里的相关档案——这正是“近似”二字的由来。在召回率和查询速度之间寻求平衡,是向量索引工程中永恒的功课。

ncandidates=∑k=1nprobe∣Ck∣n_{\text{candidates}} = \sum_{k=1}^{n_{\text{probe}}} |\mathcal{C}_k|
这个公式描述 IVF 的候选集规模:查询时探测 \(n_{\text{probe}}\) 个聚类桶,把每个桶里的档案数相加,得到真正需要精确比对的候选数量。\(n_{\text{probe}}\) 越大,候选越多,召回越高但耗时越长。
  1. 聚类桶 \(\mathcal{C}_k\)档案馆中的一个“抽屉”,里面放着尽可能语义接近的一批档案向量。
    Ck\mathcal{C}_k
  2. 桶内数量 \(|\mathcal{C}_k|\)第 \(k\) 个桶中的档案条数。
    ∣Ck∣|\mathcal{C}_k|
  3. 探测桶数 \(n_{\text{probe}}\)查询时决定翻几个抽屉,是 IVF 最重要的调参旋钮之一。
    nproben_{\text{probe}}
  4. 累加求和 \(\sum_{k=1}^{n_{\text{probe}}}\)把所有被探测抽屉中的档案数加起来,得到候选总量。
    ∑k=1nprobe∣Ck∣\sum_{k=1}^{n_{\text{probe}}} |\mathcal{C}_k|
  5. 候选集 \(n_{\text{candidates}}\)接下来要逐一精确比对相似度的档案数量,直接决定查询延迟。
    ncandidates=∑k=1nprobe∣Ck∣n_{\text{candidates}} = \sum_{k=1}^{n_{\text{probe}}} |\mathcal{C}_k|

工程实践落地——从档案馆到分馆

万国档案馆的技术成熟后,开始向城市各地开分馆。电商分馆里,顾客随手拍一张穿搭照,就能在数百万商品中找出同款;短视频分馆中,用户每点开一个视频,系统就能根据这个视频的“世界语编码”推荐下一段内容;影视分馆内,编剧用一句“小狗在海边奔跑”就能从素材库里调出所有相关镜头。这些分馆的背后,都运行着同一条流水线:离线把图像、文本、视频统一编码入库,在线把查询编码后送入向量索引,召回候选再做精排。

要保证分馆的服务质量,光有检索系统还不够,还得建立评估闭环。线上查询时,系统并不知道哪些档案是“真正相关”的,因此离线阶段需要人工标注或规则构造出标注集,再用量化指标衡量检索效果。Recall@K 是最常用的指标之一:它看的是,前 \(K\) 条检索结果里,真正相关的档案占全部相关档案的比例。

从翻译中心的建立,到世界语规范的订立,再到翻译官合练、录像带翻译、尺规度量、索引柜提速,一整套多模态检索体系最终在分馆中落地开花。这座万国档案馆的故事告诉我们:只要有统一向量空间和一套可靠的检索链路,图文视频们就能真正“用同一种语言对话”。

Recall@K=∣Rrelevant∩Rretrieved(K)∣∣Rrelevant∣\text{Recall}@K = \frac{|\mathcal{R}_{\text{relevant}} \cap \mathcal{R}_{\text{retrieved}}^{(K)}|}{|\mathcal{R}_{\text{relevant}}|}
这个公式衡量“漏没漏”:如果相关档案一共 100 条,前 20 条结果里命中了 80 条,那么 Recall@20 就是 80%。\(K\) 越小还越高,说明检索系统越精准。
  1. 相关档案集合 \(\mathcal{R}_{\text{relevant}}\)在测试集中,与查询语义真正相关的所有档案组成的集合。
    Rrelevant\mathcal{R}_{\text{relevant}}
  2. 前 \(K\) 条检索结果 \(\mathcal{R}_{\text{retrieved}}^{(K)}\)系统返回的相似度最高的前 \(K\) 条档案集合。
    Rretrieved(K)\mathcal{R}_{\text{retrieved}}^{(K)}
  3. 取交集 \(\cap\)求两个集合重合的部分,即“被召回了的相关档案”。
    Rrelevant∩Rretrieved(K)\mathcal{R}_{\text{relevant}} \cap \mathcal{R}_{\text{retrieved}}^{(K)}
  4. 计算基数 \(|\cdot|\)对集合取元素个数。
    ∣Rrelevant∩Rretrieved(K)∣|\mathcal{R}_{\text{relevant}} \cap \mathcal{R}_{\text{retrieved}}^{(K)}|
  5. 求比值交集数量除以全部相关档案数量,得到召回率。
    ∣Rrelevant∩Rretrieved(K)∣∣Rrelevant∣\frac{|\mathcal{R}_{\text{relevant}} \cap \mathcal{R}_{\text{retrieved}}^{(K)}|}{|\mathcal{R}_{\text{relevant}}|}

AI 应用场景

电商“拍图搜同款”

阶段:特征表示 / 跨模态检索

解决的问题:传统电商搜索只能匹配文字标题和类目,用户想找“上周看到的那个模特穿的白裙子”时,用文字难以描述版型和垂坠感。多模态Embedding让用户直接上传图片,系统把商品主图和用户上传图都编码到统一空间,相似度最高的商品立刻被召回。

具体案例:某电商平台把 5000 万商品的主图和标题分别用双塔模型编码,构建向量索引。用户在逛街时拍下一件衣服,上传后拿到检索 TopK 结果,再用文本“价格低于三百”做过滤重排,从拍图到出结果不到 200 毫秒。

短视频平台的智能推荐

阶段:内容理解 / 召回排序

解决的问题:短视频推荐不能只看单一封面图,用户感兴趣的是视频里的动态内容、配乐、文案等综合信息。视频Embedding把连续帧和音频信息压缩成一个整体向量,让推荐系统能在一个统一空间中比较“用户近期喜欢的视频”和“候选视频”。

具体案例:某短视频平台将每条视频均匀采样 8 帧,经过视频编码器生成视频向量;用户历史上完播、点赞过的视频向量取平均作为“兴趣向量”;最后用余弦相似度在百万级视频库中召回候选,再由精排模型输出推荐列表。

影视素材库的语义搜索

阶段:多模态索引 / 语义匹配

解决的问题:影视制作公司有海量视频素材,剪辑师想找“黄昏时城市街道的长镜头”,但素材文件名往往是“A037_C014_0815”,无法用文字定位。将镜头切分后的视频通过多模态Embedding编码入库,让自然语言直接检索视频片段。

具体案例:一家视频素材库把 10 万条镜头片段编码为向量,剪辑师输入自然语言“深夜霓虹灯下的雨夜街道”,系统在索引库中返回相似片段,命中率比原来的关键词标签方式提高了 60% 以上。

Python 演示

python39 行
import numpy as np  class VecArchive:    """模拟多模态向量档案馆:用伪编码演示图文视频统一检索。"""     def __init__(self, dim=16):        self.dim = dim        self.docs = {}   # doc_id -> vector     def _pseudo_embed(self, raw: str) -> np.ndarray:        # 用内容种子生成确定性向量,模拟多模态Encoder的输出        seed = sum(bytearray(raw.encode("utf-8"))) % 10000        rng = np.random.default_rng(seed)        v = rng.normal(size=self.dim)        return v / (np.linalg.norm(v) + 1e-8)     def add(self, doc_id: str, raw: str):        self.docs[doc_id] = self._pseudo_embed(raw)     def search(self, query: str, k: int = 3):        q = self._pseudo_embed(query)        scored = sorted(            ((doc_id, float(q @ v)) for doc_id, v in self.docs.items()),            key=lambda t: t[1],            reverse=True,        )        return scored[:k]  if __name__ == "__main__":    archive = VecArchive(dim=16)    archive.add("img:sunset_beach.jpg", "金色夕阳 海边 沙滩")    archive.add("video:dog_running.mp4", "小狗 奔跑 海浪 沙滩")    archive.add("txt:商品描述A", "纯棉T恤 白色 休闲")    archive.add("video:city_street.mp4", "城市 街道 夜色 霓虹")     for hit_id, score in archive.search("一只狗在沙滩上跑"):        print(hit_id, round(score, 4))
目的:用几十行代码演示“多模态统一向量空间”的核心流程——把不同模态的样本伪编码为同一空间中的向量,再用余弦相似度做跨模态检索,帮助理解索引检索的最小闭环。
  1. rng = np.random.default_rng(seed)用内容字符串生成固定随机种子,让同一描述每次得到相同向量,模拟训练好的多模态Encoder的确定性输出。
  2. v / (np.linalg.norm(v) + 1e-8)L2 归一化,把所有向量长度压到单位长度,这样点积就是余弦相似度。
  3. q @ v归一化向量的点积等价于余弦相似度,体现“用一把尺子丈量所有模态”。
  4. sorted(..., key=lambda t: t[1], reverse=True)按相似度降序排序,模拟检索系统的排序环节。

常见误区

误区把图片特征和文本特征各自过一遍模型,然后拼成一个长向量,以为这就是多模态Embedding。这样得到的向量虽然包含了两种模态信息,但检索时并不好用。

正解拼接前如果两个向量不在同一个对齐语义空间中,拼出来的长向量只是把两种“互不相通”的数字放进了同一个容器,检索时无法正确反映跨模态语义关系。真正有效的多模态Embedding必须经过对比学习或类似策略对齐,让图像塔输出的“金毛犬”向量与文本塔输出的“金毛犬”向量在统一空间中彼此靠近。

为何常见:因为单模态特征提取看起来很成功,容易让人忽略跨模态对齐才是多模态Embedding的灵魂。

误区把视频抽帧后逐帧送入图像编码器,再把所有帧的向量平均,以为这样就是完整的视频Embedding。

正解平均池化只是最简单的时序融合基线,它假设所有帧同样重要,但实际视频中存在着强烈的时序依赖——例如“小狗跳起来接飞盘”这个动作,单独看某一帧无法理解,必须通过时序建模捕捉运动变化。工业系统一般会用视频 Transformer 或 3D 卷积建模帧间关系,或用注意力机制给关键帧更高权重。

为何常见:视频本质上是一串图像,初学者很容易把它拆解成“图像集合”,从而忽略了时间维度带来的额外信息量。

误区认为 Embedding 向量维度越高,保存的语义信息越多,检索就越准。

正解高维向量在高维空间中会出现“维数灾难”——所有点之间的距离趋于均匀,向量之间的区分度反而下降;同时存储开销和索引计算量都显著上升。实际工程中,128 到 768 维通常已经足够承载语义信息,很多系统还会对向量做降维或量化来进一步压缩。

为何常见:直觉上“信息越多越好”容易让人忽略高维空间几何特性的反直觉现象。

误区看到两个向量余弦相似度为负数,就认为两段内容完全不相关,直接把它们从检索结果中丢弃。

正解余弦相似度为 0 表示两向量正交,只能说明方向没有重叠;在训练后的语义空间里,向量分布往往集中在一个窄锥形区域内,很多实际相关文档的余弦值也可能在 0 附近波动。检索排序关注的是相似度的相对大小,而不是绝对阈值,负值不应该被单独当作“无关”的证据。

为何常见:数学课上学过余弦值的定义域是 [-1, 1],于是不少人把两端的直观含义机械地套用到语义检索中。

面试题

Q1. 多模态Embedding的核心目标是什么?

单选题 · easy

  • A.让不同模态数据在统一向量空间中可比← 正确答案
  • B.压缩图像文件本身的存储体积
  • C.让每种模态各自建立独立向量空间
  • D.用更大的神经网络提高模型参数量

答案:A。多模态Embedding的目标是让图像、文本、视频等不同模态的数据在同一个向量空间中表达,从而可以互相计算相似度,实现跨模态检索。独立空间无法比较彼此的距离,压缩存储和扩参量都不是核心目标。

Q2. CLIP 双塔结构中的“双塔”指的是什么?

单选题 · easy

  • A.图像编码器与文本编码器← 正确答案
  • B.两个不同的图像编码器并联
  • C.召回塔与排序塔两个阶段
  • D.编码器与解码器两个网络

答案:A。双塔模型的两座塔分别是图像编码塔和文本编码塔,各自处理一种模态,输出向量后在同一空间对齐。它不是两个图像塔,也不是检索和排序两个阶段,更不是生成任务里的编码解码结构。

Q3. InfoNCE 损失中的“负样本对”主要起什么作用?

单选题 · mid

  • A.拉远不配对样本在向量空间中的距离← 正确答案
  • B.提高模型可训练参数量
  • C.替代数据增强策略
  • D.让文本塔输出维度变高

答案:A。InfoNCE 损失的本质是让正样本对靠近、负样本对远离。如果没有负样本,模型只需把所有输出压到同一个点就能“骗过”损失函数;引入负样本后,模型必须学会区分不同语义,才能在统一空间中形成有区分度的分布。

Q4. 视频Embedding与图像Embedding最本质的差异是什么?

单选题 · mid

  • A.多了一维时间建模← 正确答案
  • B.视频的分辨率通常更高
  • C.图像模型完全不能用于视频
  • D.视频向量必须比图像向量更大

答案:A。视频是带时间维度的帧序列,捕捉运动信息和时序关系是视频Embedding的关键。分辨率只是工程特征,图像模型也可以逐帧处理视频,向量维度也不必然更大,这些都是表面差异而非本质差异。

Q5. 余弦相似度为 0 表示两个向量之间的关系是?

单选题 · mid

  • A.相互正交← 正确答案
  • B.完全相同
  • C.完全相反
  • D.距离最近

答案:A。余弦相似度等于 0 时,两个向量夹角为 90 度,即正交。完全相同时余弦为 1,完全相反时为 -1。距离最近对应方向一致,也是余弦接近 1 的情况,因此正确答案只有正交。

Q6. IVF 索引中参数 n_probe 表示什么?

单选题 · hard

  • A.查询时要探测的聚类桶数量← 正确答案
  • B.全库聚类的总桶数
  • C.每个桶内向量的维度
  • D.最终返回的结果条数

答案:A。n_probe 决定查询时会翻找几个最近的聚类桶。n_probe 越大,候选集越大,召回越高但延迟也越高;聚类总桶数是 nlist,向量维度是 d,返回条数是 topK,不要混淆这几个参数。

Q7. 以下哪个做法最符合多模态Embedding的对齐思路?

单选题 · mid

  • A.用对比学习拉近图文配对样本的距离← 正确答案
  • B.把图像向量和文本向量直接拼接
  • C.只训练图像塔,文本塔保持随机
  • D.用欧氏距离替代所有向量比较

答案:A。对比学习是当前图文多模态对齐的主流方法,通过拉近正样本对、推远负样本对,让两个塔的向量空间实现语义对齐。直接拼接没有对齐训练,只训练单塔无法让两模态可比,欧氏距离只是度量方式变化,同样依赖对齐质量。

Q8. HNSW 检索时为什么先从高层图开始搜索?

单选题 · hard

  • A.高层节点少、跨步大,能快速定位目标区域← 正确答案
  • B.高层节点保存了更完整的语义信息
  • C.高层图可以直接替代底层计算相似度
  • D.底层图无法进行距离计算

答案:A。HNSW 把图分成多层,越高的层节点越稀疏、连接跨度越大,像“先看省份地图再进街道地图”:高层用大步子跳到查询点附近区域,底层再沿密集连接精搜最近邻。高层并不保存额外语义,也不能替代底层。

Q9. 在多模态检索系统中,查询(Query)可以来自哪些形式?

多选题 · mid

  • A.一段自然语言文本描述← 正确答案
  • B.一张示例图片← 正确答案
  • C.一小段视频片段← 正确答案
  • D.数据库中的表结构定义

答案:ABC。多模态检索允许查询和文档来自不同模态:文本搜图、图搜图、视频搜视频都可以。只要查询能通过对应的编码器变成统一空间中的向量,就能参与检索。数据库表结构定义与语义检索无关,不属于查询形式。

Q10. 影响多模态向量检索效果的因素有哪些?

多选题 · hard

  • A.图文编码器的对齐训练质量← 正确答案
  • B.索引算法中如 n_probe 等参数的选择← 正确答案
  • C.训练数据的分布与覆盖度← 正确答案
  • D.向量归一化策略的一致性← 正确答案

答案:ABCD。编码器对齐质量决定向量本身是否语义可比;索引参数决定召回与延迟的平衡;训练数据分布决定模型泛化能力;归一化策略则影响相似度计算的一致性,例如训练时用 L2 归一化,推理时也必须保持一致,否则向量距离会失真。四者共同影响最终检索效果。