周末清晨,小区门口新开了一家“万物超市”。经理在门口站了一整天,发现顾客的问题几乎都是跨品类的:“有没有低糖又好喝的?”“能配牛奶吃的零食在哪?”甚至有人举着手机里的照片,问“有没有长这样的东西”。可超市里的商品是按饮料、零食、日用品分区的,每类都有自己的账本。经理要回答这些问题,面前有两条路:把所有商品混编进一本“中央目录”,一次翻完;或者每个区保留独立小目录,分区翻完再把结果汇总比较。这两条路,正是多模态检索世界里“统一索引”与“分离索引”的抉择。多模态检索要解决的是:用户输入文本、图片或语音,系统却要到所有模态的数据里找答案。而怎么组织这些异质数据的向量索引,决定了系统能有多快、吃多少内存、找得准不准。本文将从零认识这两种索引结构的原理、代价与工程落地,并给你一套在真实项目中做选型的思考框架。

岗位关联

对搜索推荐算法工程师来说,透彻理解统一/分离索引的取舍,是搭建亿级多模态检索系统的第一道分水岭——它直接决定线上延迟、存储成本与召回质量。

目录
  1. 可视化演示
  2. 多模态检索概述
  3. 统一索引设计
  4. 分离索引设计
  5. 特征对齐融合
  6. 结果合并排序
  7. 性能权衡取舍
  8. 工程实现调优
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

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

统一索引:跨模态共享Embedding空间 CLIP编码器 统一ANN索引 (共享向量空间) 跨模态查询:以图搜文 / 以文搜图 多模态索引结构可视化:对比统一索引与分离索引的架构差异、性能特征及工程实践。

多模态检索概述

新超市开业第一周,经理发现一个规律:顾客的问题几乎都“跨品类”。有人问“有没有既解渴又助眠的”,有人举着手机里的照片问“有没有长这样的零食”。经理起初只有按品类分区的商品账本,面对这种提问总要跑好几个区才能凑出答案。他意识到,得先想明白“怎么组织这些账本”,才能真正回答顾客的问题。多模态检索面临的正是同样的窘境:用户输入一段文字,系统却要在海量的图片、视频、音频里找答案。

要让计算机“跨品类”检索,第一步是把所有东西翻译成同一种“数字语言”。就像超市给每件商品贴一张规格卡(甜度、容量、单价等数字),开发者给每段文本、每张图片、每段音频都算出一个固定长度的向量——它浓缩了内容的语义。于是,检索就变成了“拿用户查询的向量,去库里找最相似的向量”。

多模态检索的完整链路通常分为四步:查询向量化(用编码器把输入变成向量)、候选向量入库(把库中所有模态的向量组织成可检索的结构)、相似度打分(计算查询向量与候选向量的距离)、排序返回(按分数取前 K 个)。打分最常用的是余弦相似度:

这相当于给规格卡定了一套“统一度量衡”。只有把甜度、容量都换算成同一套单位,饮料和零食才能放在一起比高低;同理,只有让文本向量和图像向量落在同一套坐标系里,跨模态比较才有意义。而“坐标系怎么建立、账本怎么组织”,正是接下来每一节要解决的问题。

sim(q,x)=q⋅x∥q∥ ∥x∥=cos⁡(θ)\displaystyle \text{sim}(\mathbf{q}, \mathbf{x}) = \frac{\mathbf{q} \cdot \mathbf{x}}{\|\mathbf{q}\| \, \|\mathbf{x}\|} = \cos(\theta)
这个公式把“有多像”变成 0 到 1 之间的一个数:两个向量方向越一致,值越大。
  1. 查询向量 q用户输入(文本、图片或语音)经编码器转换成的定长向量,是检索的起点。
    q\mathbf{q}
  2. 候选向量 x库中任意一条数据经过同一套编码流程得到的向量。
    x\mathbf{x}
  3. 点积与模长分子衡量两向量同向程度,分母用两个模长的乘积消除向量长度的影响。
    q⋅x,∥q∥ ∥x∥\mathbf{q} \cdot \mathbf{x}, \quad \|\mathbf{q}\| \, \|\mathbf{x}\|
  4. 余弦相似度结果落在 [-1, 1],越接近 1 表示语义越接近。
    cos⁡(θ)\cos(\theta)

统一索引设计

经理决定先试“中央大目录”:把所有商品——不管饮料、零食还是日用品——按统一格式编进一本厚厚的总目录,每条记录后面贴一个小标签注明品类。查“低糖”时只翻一本目录,翻到任何品类都算命中。这就是统一索引的核心思路:所有模态的向量混排进同一个向量索引。

放在技术里,开发者准备一个向量库(比如 FAISS 或 HNSW 索引),把文本、图像、音频三种模态的 embedding 全部 add 进去,每条向量附带一个 modality 标签。查询时,无论用户输入哪种模态,都只对这个大索引发起一次检索,一次返回的 TopK 结果里天然混着各种模态的候选。

由于所有向量在一个池子里,TopK 检索是一次全量打分过程:

中央目录的好处和代价都写在“厚”字上。好处是一本目录全覆盖,天然支持跨模态召回,运维时只需维护一套结构;代价是每次查询都要翻这本越来越厚的目录,而且如果某个品类商品暴增,整本目录都要跟着膨胀。这正是统一索引“简单但重”的宿命。

Runi=topK({sim(q,v)∣v∈U})\displaystyle \mathcal{R}_{\text{uni}} = \text{top}_K\left(\{\text{sim}(\mathbf{q}, \mathbf{v}) \mid \mathbf{v} \in \mathcal{U}\}\right)
统一索引把所有模态的候选放在同一个集合 \(\mathcal{U}\) 里,只做一轮排序。
  1. 统一索引集合 U全部模态的向量混排后构成的大集合,每条记录带模态标签。
    U={v1,v2,…,vN}\mathcal{U} = \{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_N\}
  2. 逐一打分查询向量与 U 中每个向量计算相似度。
    sim(q,v)\text{sim}(\mathbf{q}, \mathbf{v})
  3. 取前 K 个按分数降序取前 K 条返回,结果天然覆盖多个模态。
    topK(⋅)\text{top}_K(\cdot)

分离索引设计

试用一周后,经理发现饮料区总是最先被翻烂,零食区却门可罗雀。他决定给每个区配一本独立小目录:饮料目录、零食目录、日用品目录各管各的。顾客跨品类提问时,就让三个区的导购同时翻各自目录,把结果汇总。这就是分离索引:每个模态一个独立索引,各自检索,最后合并。

工程上,分别为文本、图像、音频构建三套向量索引。查询向量被广播到所有索引并行执行 TopK 检索,每套索引返回各自的候选集,再进入统一的合并排序模块。这种方式允许每个模态独立选择最合适的索引类型与参数。

分离检索的数学表达是一个“并集 + 合并”的过程:

独立目录的好处是:哪个区商品暴增就改造哪个区,不影响其他区;每个区还能保留自己的翻页习惯(检索参数)。代价是:跨品类提问时必须跑遍所有区,还要把分数换算成同一种“币值”才能合并——这引出了后面“结果合并”的难题。

Rsep=merge(⋃m∈{t,i,a}topKm(q))\displaystyle \mathcal{R}_{\text{sep}} = \text{merge}\left(\bigcup_{m \in \{t, i, a\}} \text{top}_{K_m}(\mathbf{q})\right)
各模态先各自选出候选,再汇入同一个合并函数。
  1. 模态子库文本、图像、音频各自独立的向量集合。
    Ut,Ui,Ua\mathcal{U}_t, \mathcal{U}_i, \mathcal{U}_a
  2. 并行 TopK查询向量在各模态子库同时检索,各取若干候选。
    topKm(q)\text{top}_{K_m}(\mathbf{q})
  3. 候选并集把各子库的返回结果合并成一个大候选池。
    ⋃m∈{t,i,a}\bigcup_{m \in \{t, i, a\}}
  4. 合并排序经归一化与统一排序后输出最终 TopK。
    merge(⋅)\text{merge}(\cdot)

特征对齐融合

要真正实现“统一目录”或“分区合并”,有一个隐藏前提:各品类的规格卡要用同一套维度来填写。如果饮料卡写“甜度 8”,零食卡写“酥脆度 9”,这两张卡永远没法比较。超市的解法是制定统一的“商品描述规范”,让所有品类都按同一组维度填卡。对应到多模态检索,这就是特征对齐。

特征对齐的目标是让不同模态的编码器把各自的输入映射到同一个“共享语义空间”——一个所有模态向量可以互相比较的坐标系。于是,文本“一只柯基犬”与图片里那只柯基的向量,在这个空间中应当靠得很近,这是跨模态检索能成立的地基。

实践中常用对比学习(contrastive learning)来训练这个空间。以图文为例,把语义配对好的(文本,图像)当作正样本对,用 InfoNCE 损失拉近正样本、推远负样本:

对比学习就像超市的“规格卡校准小组”:不断抽查同一商品在不同品类的描述是否一致,把“甜度 8”和“糖分高”校准成同一个数值。无论统一还是分离索引,少了特征对齐,索引再快也只是在错误的坐标系里空转。

LinfoNCE=−1N∑n=1Nlog⁡exp⁡(sim(hnt,hni)/τ)∑j=1Nexp⁡(sim(hnt,hji)/τ)\displaystyle \mathcal{L}_{\text{infoNCE}} = -\frac{1}{N} \sum_{n=1}^{N} \log \frac{\exp(\text{sim}(\mathbf{h}_n^t, \mathbf{h}_n^i)/\tau)}{\sum_{j=1}^{N} \exp(\text{sim}(\mathbf{h}_n^t, \mathbf{h}_j^i)/\tau)}
这个损失像“抽查考核”:让每一对正确的图文组合得分最高。
  1. 模态编码器输出文本与图像分别经各自的编码器映射到共享空间。
    ht,hi\mathbf{h}^t, \mathbf{h}^i
  2. 正样本对语义配对的图文样本应当获得更高的相似度。
    sim(hnt,hni)\text{sim}(\mathbf{h}_n^t, \mathbf{h}_n^i)
  3. 温度系数 τ控制相似度分布的尖锐程度,τ 越小对难分负样本的惩罚越强。
    τ\tau
  4. 归一化与负对数把相似度转成概率后取负对数,最小化损失即最大化正样本概率。
    −log⁡exp⁡(⋅/τ)∑jexp⁡(⋅/τ)-\log \frac{\exp(\cdot / \tau)}{\sum_j \exp(\cdot / \tau)}

结果合并排序

分区目录上线后,新的麻烦出现了:饮料区按“甜度分”排序,零食区按“酥脆分”排序,两边的分数根本不是同一套币值。顾客问“哪个最接近我要的?”总不能把 8 分甜度和 9 分酥脆直接相加。经理只好先制定换算规则:把所有分数都压到 0 到 1 之间再比较。这就是多模态结果合并里的分数归一化。

在分离索引中,各模态返回的相似度分数分布差异很大:图像索引的分数可能普遍在 0.8 以上,文本索引的分数可能集中在 0.3 附近。直接拼接排序会天然偏向分数整体偏高的模态,导致文本结果几乎无法进入 TopK。

常用做法是先做 min-max 归一化:

归一化之后再按业务权重加权求和,或用更重的重排(rerank)模型对候选统一打分。这就像超市最终张贴的那张“总性价比榜”——先换算币值,再按顾客口味加权。合并策略直接决定分离索引的最终效果,也是“分区目录”能否战胜“中央目录”的关键一环。

s^m=sm−min⁡(Sm)max⁡(Sm)−min⁡(Sm)\displaystyle \hat{s}_m = \frac{s_m - \min(S_m)}{\max(S_m) - \min(S_m)}
把每个模态自己的分数区间压到 [0, 1],先统一“币值”再比大小。
  1. 原始分数某模态下候选的原始相似度,尺度因模态而异。
    sms_m
  2. 分数区间端点本次查询中该模态全部候选分数的最小值与最大值。
    min⁡(Sm),max⁡(Sm)\min(S_m), \max(S_m)
  3. 线性映射将分数压到 [0, 1],消除模态间尺度差异。
    s^m∈[0,1]\hat{s}_m \in [0, 1]

性能权衡取舍

三个月后,经理手里有两份账单:中央目录只有一本、省书架,但每个人都要翻大厚本;分区目录每本很薄、翻得快,但要跑好几个区再把结果兑成同一种币值。他需要算清每一笔账,才能决定哪种组织方式继续用。多模态索引同样要在存储、延迟、召回、扩展性之间权衡。

统一索引只维护一份向量库,存储最省;但每次查询都对全量数据扫描,延迟随总量线性增长。分离索引把库拆开,各库可并行检索,总延迟近似取决于最大的那个模态库;但多个库带来存储冗余与合并开销,且各模态参数独立,增加了运维复杂度。

用大 O 表示复杂度:假设总量为 N,文本、图像、音频分别为 N_t、N_i、N_a:

经理最终得出的经验是:如果各品类规模接近且跨品类提问是常态,中央目录更省心;如果某个品类膨胀极快或各品类冷热差异大,分区目录更灵活。没有绝对正确的索引,只有当前业务规模下的最优取舍。

Tuni=O(N),Tsep=O ⁣(max⁡mNm)+O(K⋅∣M∣)\displaystyle T_{\text{uni}} = O(N), \qquad T_{\text{sep}} = O\!\left(\max_{m} N_m\right) + O(K \cdot |M|)
统一索引慢在“全量”,分离索引慢在“最大的那个分区 + 合并”。
  1. 总量关系统一索引的全量候选数是各模态之和。
    N=Nt+Ni+NaN = N_t + N_i + N_a
  2. 统一扫描成本一次全量计算相似度的复杂度。
    O(N)O(N)
  3. 分离并行成本各模态库并行扫描,耗时近似等于最大的库,再加上合并 K 条候选的开销。
    O(max⁡mNm)+O(K⋅∣M∣)O(\max_m N_m) + O(K \cdot |M|)

工程实现调优

选型定下来只是开始。经理每天还在做三件事:给热门商品加“快速查找卡”(缓存)、调整目录排版让翻找更快(索引参数)、统计顾客找货成功率(效果监控)。工程落地多模态索引用的是同一套思路。

以 FAISS 为代表的工程库提供了 IVF-PQ、HNSW 等近似最近邻结构,核心是在构建时间、查询延迟与召回率之间取平衡。向量量化(PQ)的比特数决定内存与精度,聚类中心数 nlist 决定倒排分桶粒度,查询时扫描的桶数 nprobe 决定速度与召回。

评估近似索引效果最常用的指标是召回率:

经理用同样的方法不断迭代:给热门商品加快速卡是缓存优化,调整字号是调 nprobe,统计找货成功率就是算 Recall@K。索引不是一次建好就万事大吉,而是一个持续测量、持续调参的运营过程——这正是多模态检索系统从“能用”走向“好用”的最后一公里。

Recall@K=∣GTK∩PredK∣K\displaystyle \text{Recall@}K = \frac{\left| \text{GT}_K \cap \text{Pred}_K \right|}{K}
看看近似检索返回的前 K 个里,有多少是暴力精确检索也会返回的“真答案”。
  1. 真实 TopK由暴力精确检索得到的标准答案集合。
    GTK\text{GT}_K
  2. 预测 TopK近似索引实际返回的候选集合。
    PredK\text{Pred}_K
  3. 交集与比例计算真实答案中被命中的比例,衡量近似索引的召回完整度。
    ∣GTK∩PredK∣K\frac{|\text{GT}_K \cap \text{Pred}_K|}{K}

AI 应用场景

电商“以图搜同款”

阶段:召回(多模态检索)

解决的问题:用户街拍一张衣服照片想找同款,传统依赖人工打标,图像到文本的语义鸿沟导致召回率低。AI 将商品主图与标题文本用对比学习对齐到共享空间,再统一写进一个向量索引,图像查询天然命中带文本标注的同款商品。

具体案例:某服饰电商约 5000 万商品,把商品图与标题向量统一建成 FAISS 索引(IVF-PQ 压缩),以图搜同款 P95 延迟约 85ms,跨模态召回率提升 37%。

短视频平台“文案搜视频”

阶段:召回 + 融合排序

解决的问题:用户输入一句文案要找对应视频,视频同时包含视觉帧与 ASR 语音两路信息。若用统一索引,海量视觉向量会压过文本命中;于是采用分离索引,视觉库与文本库并行检索,归一化融合后再排序。

具体案例:某短视频平台日均十亿级检索,视觉/文本双索引并行,融合后整体时延控制在 120ms 内,长尾文案召回率提升 25%。

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

阶段:检索增强生成

解决的问题:知识库包含 PDF 文本、流程图、录音三种模态,各自语义密度差异大。系统按 query 类型路由到对应模态库(统一/分离混合架构),合并候选后交给大模型生成答案,避免单一索引的模态偏差。

具体案例:某金融企业合规知识库约 200 万文档,路由 + 分离检索使答案引用准确率提升 28%,检索时延下降 40%。

Python 演示

python90 行
# -*- coding: utf-8 -*-"""统一索引与分离索引的多模态检索对比演示"""import numpy as npimport time  class MultimodalIndex:    """同时维护统一与分离两种索引结构"""     def __init__(self, dim=64):        self.dim = dim        self.unified_items = []        self.unified_mods = []        self.separate_map = {}        self.gc_count = 0     def add(self, modality, vector):        vec = np.asarray(vector, dtype=np.float32)        self.unified_items.append(vec)        self.unified_mods.append(modality)        self.separate_map.setdefault(modality, []).append(vec)     def _l2_distance(self, query, items):        q = np.asarray(query, dtype=np.float32)        arr = np.vstack(items)        return np.linalg.norm(arr - q, axis=1)     def unified_search(self, query, top_k=5):        """统一索引: 一次全量扫描取 top-k"""        dists = self._l2_distance(query, self.unified_items)        idx = np.argsort(dists)[:top_k]        return [(self.unified_mods[i], float(dists[i])) for i in idx]     def separate_search(self, query, top_k=5):        """分离索引: 各模态并行检索后归一化合并"""        all_hits = []        for mod, items in self.separate_map.items():            dists = self._l2_distance(query, items)            idx = np.argsort(dists)[:top_k]            for i in idx:                all_hits.append((mod, float(dists[i])))            self.gc_count += 1        if not all_hits:            return []        max_d = max(h[1] for h in all_hits)        norm_hits = [(m, 1.0 - d / max_d) for m, d in all_hits]        norm_hits.sort(key=lambda x: x[1], reverse=True)        return norm_hits[:top_k]  def make_demo(seed=42):    """构造 3 个模态各 50 条向量的演示数据"""    np.random.seed(seed)    index = MultimodalIndex(dim=64)    for mod in ("text", "image", "audio"):        for _ in range(50):            index.add(mod, np.random.randn(64))    return index  def profile_search(index, query, repeat=20):    """统计两种结构的平均检索耗时"""    t0 = time.perf_counter()    for _ in range(repeat):        index.unified_search(query)    t_uni = (time.perf_counter() - t0) / repeat    t0 = time.perf_counter()    for _ in range(repeat):        index.separate_search(query)    t_sep = (time.perf_counter() - t0) / repeat    return t_uni, t_sep  def show_hits(hits, tag):    print(tag)    for mod, score in hits:        print("  %-6s 相似度 %.4f" % (mod, score))  def main():    index = make_demo()    query = np.random.randn(64)    show_hits(index.unified_search(query), "[统一索引]")    show_hits(index.separate_search(query), "[分离索引]")    t_uni, t_sep = profile_search(index, query)    print("平均耗时: 统一=%.5fs 分离=%.5fs" % (t_uni, t_sep))  if __name__ == "__main__":    main()
目的:用 NumPy 模拟多模态向量库,对比统一索引与分离索引两种结构的命中结果与检索耗时。
  1. self.separate_map.setdefault(modality, []).append(vec)分离索引建库的核心:每个模态一个列表,新向量只进自己的分区。
  2. dists = self._l2_distance(query, self.unified_items)统一索引全量扫描:查询向量与库中每个向量算距离。
  3. idx = np.argsort(dists)[:top_k]距离升序排列后取前 K 个,即最近邻候选。
  4. for mod, items in self.separate_map.items():分离索引遍历各模态,把查询广播到每个分区。
  5. norm_hits = [(m, 1.0 - d / max_d) for m, d in all_hits]用最大距离做归一化,把距离转成 0~1 相似度币值。
  6. norm_hits.sort(key=lambda x: x[1], reverse=True)归一化后统一排序,完成跨模态合并。

常见误区

误区我一开始以为,统一索引就是把文本、图片、音频的向量直接塞进同一个向量库,标个类型标签就行了,不用管别的。

正解向量放进同一个库不代表能互相比较。就像把“甜度 8”和“酥脆度 9”写在同一张卡上,单位不一致时数字没有意义。必须先做特征对齐,让各模态映射到共享语义空间,统一索引才能真正工作。

为何常见:因为“同一个库”听起来天然能一起算距离,但距离是否语义化取决于空间是否对齐。

误区分离索引要查好几个库,查询次数更多,肯定比统一索引慢。

正解分离索引的各库可以并行检索,总延迟近似等于最大的那个库,而不是几个库的耗时之和;统一索引虽然只查一次,但每次都是全量扫描,库变大后延迟增长更快。规模与并行度共同决定胜负。

为何常见:把“查询次数多”直接等同于“慢”,忽略了并行计算的存在。

误区各模态检索完,把相似度分数直接加起来排个序不就行了?

正解不同模态的分数分布差异很大:图像相似度普遍偏高,文本普遍偏低,直接相加会让图像结果永远压过文本。必须先归一化(如 min-max)统一尺度,再按业务权重融合。

为何常见:直觉上分数都是“相似度”,却忽略了不同索引产出的分数根本没有可比性。

误区我以为上了近似索引,召回率就一定会比原来高。

正解暴力精确检索的召回率是上限,近似索引(IVF-PQ、HNSW)是用召回换速度。nprobe 太小、PQ 量化太狠都会让召回下降。召回率反而是调参时需要持续监控的指标。

为何常见:把“性能优化”误当成“效果提升”,混淆了延迟、内存与召回率的三角关系。

误区统一索引只维护一份,模态数量越多它优势越大,应该无脑选统一。

正解模态增多意味着索引体积膨胀、全量扫描更慢,且任何单模态的分布变化都可能触发全库重建,各模态也无法独立调参。模态多且差异大时,分离索引的独立扩展性反而更优。

为何常见:只看到“统一 = 少维护”的一面,忽略了耦合与重建成本。

面试题

Q1. 关于统一索引结构,下列说法正确的是?

单选题 · easy

  • A.不同模态向量共用一个索引← 正确答案
  • B.每个模态各建独立索引
  • C.只允许存储文本模态
  • D.检索前需要人工标注

答案:A。统一索引就像超市的一本中央目录,所有品类的规格卡混排在一起,共用一套检索结构。B 是分离索引的做法;C 把多模态退化成了单模态;D 是特征对齐要解决的问题,与索引组织方式无关。

Q2. 分离索引检索完成后,合并前最关键的一步是?

单选题 · mid

  • A.删除图像类的结果
  • B.把向量再编码一次
  • C.分数归一化统一尺度← 正确答案
  • D.扩充所有候选数据

答案:C。各分区目录的记分币值不同,必须先归一化再比较,否则图像分一高就永远压过文本分。A 删除结果会丢失信息;B 重复编码浪费算力;D 扩充候选会增加延迟,都不是合并前的必要步骤。

Q3. 统一索引结构的优势包括?

多选题 · mid

  • A.天然支持跨模态召回← 正确答案
  • B.只需维护一套索引结构← 正确答案
  • C.各模态可独立扩容
  • D.无需做特征对齐

答案:AB。一本中央目录覆盖所有品类,天然跨模态且运维成本低。C 是分离索引的优势;D 是错误概念——统一不代表可以跳过错对齐,向量不在同一空间,放在一个库里也没法比较。

Q4. 对比学习中温度系数 τ 减小,相似度分布会?

单选题 · extreme

  • A.变得更尖锐← 正确答案
  • B.变得更平缓
  • C.变成离散数值
  • D.自动升高维度

答案:A。τ 相当于给规格卡打分时的“灵敏度旋钮”。τ 变小,exp(sim/τ) 的差异被放大,分布更尖锐,模型对难分负样本的惩罚更强。B 是 τ 增大的效果;C、D 与温度系数无关。

Q5. 下列哪种情况更适合分离索引?

单选题 · mid

  • A.各模态数据规模相当
  • B.各模态数据规模悬殊← 正确答案
  • C.必须强制跨模态召回
  • D.完全禁止并行计算

答案:B。数据规模悬殊时,分离索引让大模态独立扩容、小模态不被拖累,正如给膨胀的饮料区单独换大目录。A 规模均衡时统一索引更省;C 是统一索引的强项;D 分离索引依赖并行,禁止并行时优势尽失。

Q6. 影响近似索引召回率(Recall@K)的因素有?

多选题 · mid

  • A.聚类中心数量设定← 正确答案
  • B.查询时扫描的桶数← 正确答案
  • C.商品描述的标点符号
  • D.向量量化压缩位数← 正确答案

答案:ABD。nlist 聚类中心数决定倒排分桶粒度,nprobe 决定扫描桶数,PQ 量化位数决定向量压缩精度,三者都直接影响召回。C 标点符号属于文本原始形态,与近似索引的检索过程无关。

Q7. 共享语义空间主要解决什么问题?

单选题 · easy

  • A.服务器机房的散热问题
  • B.数据库表连接的性能
  • C.用户登录的鉴权安全
  • D.不同模态向量的可比性← 正确答案

答案:D。共享语义空间就像统一的规格卡规范,把文本、图像、音频映射到同一坐标系,使跨模态相似度可计算。A、B、C 与向量空间无关。

Q8. 近似检索中调大 nprobe 最直接的影响是?

单选题 · hard

  • A.召回率提高且延迟上升← 正确答案
  • B.召回率下降且延迟降低
  • C.索引构建时间必然减少
  • D.存储占用自动减半

答案:A。nprobe 是查询时扫描的桶数,相当于顾客在目录里多翻几个分区,找得更全但更慢。B 方向相反;C 与查询阶段无关;D 存储由 nlist 与 PQ 位数决定,与 nprobe 没有直接关系。

Q9. 分离索引结果合并的常用手段包括?

多选题 · hard

  • A.最小最大分数归一化← 正确答案
  • B.直接丢弃低分模态
  • C.加权求和综合排序← 正确答案
  • D.重排模型二次打分← 正确答案

答案:ACD。归一化统一币值、加权融合体现业务偏好、重排模型做精细化打分,是三层常用手段。B 直接丢弃会损失跨模态信息,是错误做法。

Q10. 多模态检索相比单模态检索的核心区别是?

单选题 · easy

  • A.必须使用关系型数据库
  • B.查询可跨模态召回结果← 正确答案
  • C.不需要特征向量表示
  • D.结果一定是文本内容

答案:B。多模态检索允许“文本问、图像答”这类跨种类匹配,就像顾客举着照片在超市找同款零食。A、C、D 均不符合多模态检索的常识。