需要比布尔更有语义,又要比稠密向量更可解释(哪几个词项拉高了分)。根因是单向量维度不可审计。本方法用 SPLADE 一类稀疏语义。长尾同义仍弱于 ColBERT/稠密,适合术语密集库。
本文属于 RAG 工程框架中的「2 索引与召回」环节,聚焦「Sparse Vector Retrieval」方法。
定位
| 维度 | 内容 |
|---|---|
| 角色 | 可解释的稀疏语义检索 |
| 输入 → 输出 | query → 稀疏向量 → 倒排点积 Top-k |
| 默认组合 | SPLADE + Pyserini;或 ES learned sparse |
| 何时不用 | 需要 token 级对齐(ColBERT);或只要硬过滤(Boolean) |
核心机制
$$
\mathrm{score}(q,d)=\sum_{t} w_q(t),w_d(t)
$$
多数 $w(t)=0$。非零维就是「亮了的词项」(可含模型扩展的同义项)。
实现路径与心智:用 SPLADE 一类编码器把 query/doc 写成词表上的稀疏权重,建倒排,检索就是稀疏点积。底层心智:仍是「看哪些词项亮了」,比 BM25 多一层模型扩词,比 dense 可审计。调试时先看非零维,而不是看一个 768 维黑盒。
优缺点
- 优点:可解释;部署比 ColBERT 轻。
- 缺点:长尾改写弱于 dense/ColBERT。
契约与走通样例
输入
1 | {"query": "GAPDH knockdown 48 h"} |
中间量
$w_q$ 非零:GAPDH:1.8, knockdown:1.1, siRNA:0.9, 48h:0.7(模型扩出 siRNA)。与方法段点积 $4.2$,与无关 actin 段 $1.1$。
输出
1 | [{"doc_id": "P-GAPDH-01-C1", "score": 4.2, "top_terms": ["GAPDH", "siRNA", "48h"]}] |
社区实现
SPLADE + Pyserini。风险:词表与分析器不一致时扩展项对不上倒排。
工程落地
最小可运行示例
复制为 .py 后直接运行(仅标准库)。生产稀疏编码换成 SPLADE / Pyserini,倒排换成 ES learned sparse。
1 | """词表上的稀疏权重做点积;可打印点亮了哪些 term。""" |
参数
| 参数 | 起点 | 影响 |
|---|---|---|
| 查询非零维上限 | 数十 | 过大变慢且噪声词亮起 |
top_k |
20 | 交给融合或精排 |
失效—信号—螺丝
- 扩词漂移:点亮无关领域词。信号:top_terms 与问句无关。螺丝:提高稀疏阈值。
- 分析器不一致:文档侧切词与模型词表不同。螺丝:统一 tokenizer。
- 当 dense 用:丢掉可解释性还更慢。螺丝:保留 term 调试日志。
规模(100 篇生物学 PDF)
GPU 12–16 GB;稀疏索引 约 3–7 GB;编码+建库 0.8–2.5 GPU·h。