1. \textbf{1. } 1. 从词袋到 ColBERT \textbf{ColBERT} ColBERT: 文本相似性计算方法概览
1.1. \textbf{1.1. } 1.1. 如何计算两个文本的相似性 ? \textbf{?} ?
1️⃣特征方法:从文本中提取人工设计的特征 → \text{→} →通过特征来计算文本相似度,也可叫稀疏方法 / / /词频方法
方式 描述 基于词频 认为[查询 ↔ \xleftrightarrow{} 段落]共同词多 + \text{+} +共同词的词频( TF \text{TF} TF)分布类似,表明相似度高 基于 TF-IDF \text{TF-IDF} TF-IDF 在词频的基础上,引入 IDF \text{IDF} IDF以惩罚常见词 / / /奖励关键词 BM25 \text{BM25} BM25 TF-IDF \text{TF-IDF} TF-IDF的改进版,平滑化词频 + \text{+} +考虑文档长度,最为经典的特征方法没有之一 2️⃣神经方法:将文本转化为稠密的嵌入 → \text{→} →通过嵌入来计算文本相似度
方法 示意图 描述 查询质量 查询延迟 段落级
(大颗粒度)①查询 / / /段落各自生成单嵌入
②相似度 ← \text{←} ←两向量的内积低 小 词元级
(细颗粒度)①拼接将查询和段落
②输入 BERT \text{BERT} BERT得到相似度高 大 \quad 🤔是否有方法,能在保留 Token \text{Token} Token级的细颗粒度交互同时,降低计算量 ? ? ?
\quad 💡查询前(离线)就算好所有段落的词级嵌入 → \text{→} →查询时(在线)即时得到查询的词级嵌入 → \text{→} →交互得相似度
1.2. ColBERT \textbf{1.2. ColBERT} 1.2. ColBERT概述
1️⃣组成结构上
![]()
- 编码模块:
- 对段落:原始段落 → CPU WordPiece \xrightarrow[\text{CPU}]{\text{WordPiece}} WordPieceCPU段落 Token → GPU BERT ( 段落编码器 f P ) \text{Token}\xrightarrow[\text{GPU}]{\text{BERT}(段落编码器f_P)} TokenBERT(段落编码器fP)GPU每个 Token \text{Token} Token都生成一个嵌入向量
- 对查询:原始查询 → CPU WordPiece \xrightarrow[\text{CPU}]{\text{WordPiece}} WordPieceCPU查询 Token → GPU BERT ( 查询编码器 f Q ) \text{Token}\xrightarrow[\text{GPU}]{\text{BERT}(查询编码器f_Q)} TokenBERT(查询编码器fQ)GPU每个 Token \text{Token} Token都生成一个嵌入向量
- 交互模块:后期交互 S q , d := ∑ i ∈ [ ∣ E q ∣ ] max j ∈ [ ∣ E d ∣ ] E q i ⋅ E d j T \displaystyle{}S_{q, d}\text{:=}\sum_{i \in\left[\left|E_q\right|\right]} \max _{j \in\left[\left|E_d\right|\right]} E_{q_i} \cdot E_{d_j}^T Sq,d:=i∈[∣Eq∣]∑j∈[∣Ed∣]maxEqi⋅EdjT
- 第一步:计算每个 v ∈ E q v \text{∈} E_q v∈Eq与 E d E_d Ed中向量的最大相似度( MaxSim \text{MaxSim} MaxSim)
- 第二步:将所有 MaxSim \text{MaxSim} MaxSim相加,即为最终的相似度
2️⃣使用流程上
- 离线阶段:对数据库中所有段落进行操作,生成全部其嵌入
- 在线阶段:即时地生成查询的嵌入 → \text{→} →与段落嵌入后期交互得到相似度 → \text{→} →结合 IVF \text{IVF} IVF返回 Top- k / \text{Top-}k/ Top-k/重排
3️⃣性能上:在于原始 BERT \text{BERT} BERT性能差不多的情况下大大降低了延迟
![]()
2. \textbf{2. } 2. 从 ColBERT \textbf{ColBERT} ColBERT到 PLAID \textbf{PLAID} PLAID: 对原始模型的改进
2.1. ColBERTv2 \textbf{2.1. ColBERTv2} 2.1. ColBERTv2: 针对训练 & \textbf{\&} &存储的优化
1️⃣改进动机
- 基础:全盘采纳 ColBERT \text{ColBERT} ColBERT的结构,不作任何改变
- 动机:训练策略高度优化的单向量模型反而优于 ColBERT \text{ColBERT} ColBERT,对原始嵌入整个存储开销太大
2️⃣改进思路:
模型训练:借鉴很多单向量模型的高度监督调优,即蒸馏优化 + \text{+} +降噪训练
- 蒸馏优化:将原有大型 BERT \text{BERT} BERT的参数蒸馏到小型 MiniLM \text{MiniLM} MiniLM中,用来给段落评分以获取负样本
- 降噪训练:借助上一步,在训练过程中引入更多的负样本
存储优化:对离线阶段所得的嵌入进行残差压缩,以减小离线存储需求 & \& &在线查询时的总线带宽
模型 离线嵌入阶段 在线查询阶段 v1 \text{v1} v1 计算段落嵌入 → \text{→} →存储完整嵌入 直接计算 v2 \text{v2} v2 计算段落嵌入 + \text{+} +质心 / / /残差压缩 → \text{→} →存储压缩嵌入 先要解压查询附近的段落嵌入 2.2. PLAID \textbf{2.2. PLAID} 2.2. PLAID: 针对后期交互机制的优化
1️⃣改进动机
- 基础:全盘采纳 ColBERT \text{ColBERT} ColBERT的结构,对 ColBERTv2 \text{ColBERTv2} ColBERTv2的降噪监督 + \text{+} +残差压缩也予以保留
- 动机:基于对 ColBERTv2 \text{ColBERTv2} ColBERTv2进一步分析所得的两个结论
- [查询嵌入 ↔ 距离 \xleftrightarrow{距离} 距离 段落所属的质心向量] ≈ \text{≈} ≈[查询 ↔ 距离 \xleftrightarrow{距离} 距离 段落嵌入] → \text{→} →以该近似距离进行初排可避免解压
- 对一个查询只有少部分质心起作用 → \text{→} →可进行大刀阔斧的质心剪枝
2️⃣改进思路
- 段落初排:使用质心代替的阉割版
- 候选生成:计算与查询邻近的质心集
- 质心剪枝:计算[查询 ↔ \xleftrightarrow{} 质心]的近似距离,筛掉评分低的质心
- 质心交互:和后期交互一致,只不过参与交互的段落嵌入集,变成了段落嵌入所属质心的集合
- 段落重排:使用嵌入解压的完整版
3. \textbf{3. } 3. 后 PLAID \textbf{PLAID} PLAID: 对多向量检索优化的探索
3.1. EMVB: \textbf{3.1. EMVB: } 3.1. EMVB: 沿原有思路对 PLAID \textbf{PLAID} PLAID的进一步改进
1️⃣模型方法上
- 质心交互:抛弃原有的残差压缩改为 PQ \text{PQ} PQ压缩
- 质心剪枝:对已生成的候选集进一步"预过滤",减少参与排序的质心数目
2️⃣工程实现上:按位运算快速判断质心相似度,垂直堆叠压缩存储, SIMD \text{SIMD} SIMD加速向量计算…
3.2. BGE-M3: \textbf{3.2. BGE-M3: } 3.2. BGE-M3: 从嵌入方式上下手
1️⃣三种检索任务:密集 / \mathcal{/} /多向量 / \mathcal{/} /稀疏(词汇)
模型 嵌入方式 相似度计算(得分) 模型实例 密集检索 编码段落为单个段落级稠密向量 s dense ← s_{\text {dense}} \leftarrow sdense←两个向量间的点积计算 BERT \text{BERT} BERT 多向量检索 编码段落为多个词汇级稠密向量 s mul ← s_{\text {mul}} \leftarrow smul←两组向量间的复杂交互 ColBERT \text{ColBERT} ColBERT 稀疏检索 计算段落中词的词项权重 s lex ← s_{\text {lex}} \leftarrow slex←词匹配得分 BM25 \text{BM25} BM25 2️⃣ BGE-M3 \text{BGE-M3} BGE-M3:实现对三种嵌入方式的通用性
训练:三种检索任务的优化方向可能存在冲突 → \text{→} →通过自蒸馏 + \text{+} +集成学习整合进统一损失函数
部署:针对不同任务使用不同的检索 / / /重排策略
单独的:
检索方式 描述 Dense \text{Dense} Dense 生成语料库的稠密嵌入,建立 Faiss \text{Faiss} Faiss索引以进行 Top-1000 \text{Top-1000} Top-1000检索 Sparse \text{Sparse} Sparse 生成语料库的稀疏表示,建立 Lucene \text{Lucene} Lucene索引以进行 Top-1000 \text{Top-1000} Top-1000检索 整合的:
检索方式 检索内容 重排依据 Dense+Sparse \text{Dense+Sparse} Dense+Sparse 并合各自 Top-1000 \text{Top-1000} Top-1000 w 1 s dense + w 2 s lex w_1s_{\text {dense}}\text{+}w_2s_{\text {lex}} w1sdense+w2slex MultiVec \text{MultiVec} MultiVec Dense \text{Dense} Dense的 Top-200 \text{Top-200} Top-200 s mul s_{\text {mul}} smul All \text{All} All Dense \text{Dense} Dense的 Top-200 \text{Top-200} Top-200 w 1 s dense + w 2 s lex + w 3 s mul w_1s_{\text {dense}}\text{+}w_2 s_{\text {lex}}\text{+}w_3s_{\text {mul}} w1sdense+w2slex+w3smul 3.3. MuVERA: \textbf{3.3. MuVERA: } 3.3. MuVERA: 将多向量压缩为固定维度的单向量
1️⃣核心思想
- 维度压缩:设计特殊的映射函数 { F q u e : 2 R d → R d F D E F doc : 2 R d → R d F D E → \begin{cases}\mathbf{F}_{\mathrm{que}}: 2^{\mathbb{R}^{d}} \rightarrow \mathbb{R}^{d_{\mathrm{FDE}}}\\\\\mathbf{F}_{\text{doc}}: 2^{\mathbb{R}^{d}} \rightarrow \mathbb{R}^{d_{\mathrm{FDE}}}\end{cases}\text{→} ⎩ ⎨ ⎧Fque:2Rd→RdFDEFdoc:2Rd→RdFDE→将多向量压缩为固定 d FDE d_{\text{FDE}} dFDE维的单向量
- 相似度计算:直接用内积 ⟨ F q u e ( Q ) , F doc ( P ) ⟩ \left\langle\mathbf{F}_{\mathrm{que}}(Q), \mathbf{F}_{\text{doc}}(P)\right\rangle ⟨Fque(Q),Fdoc(P)⟩作为原有 ∑ q ∈ Q max p ∈ P ⟨ q , p ⟩ \displaystyle{}\sum_{q \in Q} \max _{p \in P}\langle q, p\rangle q∈Q∑p∈Pmax⟨q,p⟩(即 MaxSim \text{MaxSim} MaxSim)的替代
2️⃣工作流程:
- 预处理:对所有文档进行 F doc \mathbf{F}_{\text{doc}} Fdoc映射得到 F doc ( P i ) \mathbf{F}_{\text{doc}}(P_i) Fdoc(Pi)
- 查询时:对给定查询 Q Q Q进行 F que \mathbf{F}_{\text{que}} Fque映射得到 F que ( Q ) \mathbf{F}_{\text{que}}(Q) Fque(Q),计算 ⟨ F q u e ( Q ) , F doc ( P i ) ⟩ \left\langle\mathbf{F}_{\mathrm{que}}(Q), \mathbf{F}_{\text{doc}}(P_i)\right\rangle ⟨Fque(Q),Fdoc(Pi)⟩得到 Top- k \text{Top-}k Top-k文档
- 最后再用完整的 ∑ q ∈ Q max p ∈ P ⟨ q , p ⟩ \displaystyle{}\sum_{q \in Q} \max _{p \in P}\langle q, p\rangle q∈Q∑p∈Pmax⟨q,p⟩相似度,对 Top- k \text{Top-}k Top-k个文档进行重排