Skip to content

About

SearchForge · 世界级神经/混合检索与学习重排系统(BM25+FAISS/LSI 双路召回 → RRF → LightGBM LambdaMART 重排,旗舰 RankFuse nDCG@10 相对最强基线 +11.73%)。作者:晨星

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

SearchForge · 世界级神经/混合检索与学习重排系统

CI Release License: MIT Python Quality

作者:晨星 (CJX0712) · v0.1.0


一句话

用顶级开源搭一套现代搜索引擎 / RAG 检索栈的两段式架构: BM25 + FAISS(LSI) 双路召回 → RRF 融合 → LightGBM LambdaMART 学习重排(旗舰 RankFuse), 在 3 seeds 上 nDCG@10 相对最强基线 +11.73%(0.9086 vs 0.8132,统计显著)。

本系统不从零自研 SOTA。BM25、ANN、LambdaMART 全部直接复用久经工业验证的开源实现, 工程重心放在正确组合、可复现评测、可降级交付上。见 docs/architecture.md §1。


快速开始(一键复现)

git clone https://github.com/CJX0712/searchforge.git
cd searchforge
python -m venv .venv && .venv/Scripts/python -m pip install -r requirements.lock.txt   # Linux: .venv/bin/python

python examples/run_demo.py        # 端到端:基准 + 确定性 + 消融 + 失败案例(约 37s,CPU)
python -m searchforge.cli bench --seeds 42,43,44 --out benchmark.json
python -m searchforge.cli run --seed 42
python -m searchforge.cli tune --trials 16      # Optuna 调参(独立验证种子)

所有依赖均有 win_amd64 / manylinux 预编译 wheel,无需源码编译、无需下载任何模型权重。


性能基线(3 seeds:42/43/44,nDCG 为主指标)

方法 nDCG@10 nDCG@5 MAP@10 Recall@100
random(对照) 0.0246 ± 0.0021 0.0245 ± 0.0043 0.0025 ± 0.0002 0.0839 ± 0.0009
lexical(BM25, rank_bm25) 0.8121 ± 0.0159 0.8187 ± 0.0183 0.1384 ± 0.0061 0.7267 ± 0.0199
dense(FAISS + LSI) 0.6347 ± 0.0168 0.6206 ± 0.0167 0.1493 ± 0.0067 0.9418 ± 0.0200
hybrid(RRF 融合) 0.8042 ± 0.0164 0.7998 ± 0.0121 0.1493 ± 0.0061 0.9118 ± 0.0220
rankfuse(旗舰) 0.9086 ± 0.0175 0.9080 ± 0.0205 0.1493 ± 0.0061 0.9118 ± 0.0220

门禁:旗舰 0.9086 vs 最强基线 0.8132 → Δ = +0.0954(+11.73%),门槛 +5%, 显著性判据(均值差 > ½(σ₁+σ₂) = 0.019)通过 → PASS。

数字全部来自真实运行输出(benchmark.json),无手填。

两个必须说清的指标现象(不粉饰)

  1. MAP@10 无区分度:dense/hybrid/rankfuse 三者的 MAP@10 完全相同(0.1493)。 原因是三者都把约 10 篇相关文档放进 top-10,AP@10 触及 10/|rel| 天花板后 对排序顺序不敏感。因此以分级的 nDCG@10 作为主指标,MAP 仅作参考。
  2. 旗舰 Recall@100 = hybrid(0.9118),低于 dense(0.9418): 重排只重排 top-N 候选窗口、不扩大召回;而 LSI 稠密通路召回面更广。 这是本架构的已知限制(也是下一步方向,见"已知限制")。

消融(单 seed,nDCG@10 / MAP@10)

配置 nDCG@10 MAP@10 结论
all(全部特征) 0.9021 0.1455 基准
no_dense(去掉稠密特征) 0.8912 0.1421 −0.0109,稠密信号有正贡献
no_bm25(去掉词法特征) 0.8950 0.1448 −0.0071,词法信号有正贡献
no_rrf(去掉融合特征) 0.8901 0.1449 −0.0120,融合特征贡献最大
no_rerank(不做重排,纯 RRF) 0.7935 0.1442 −0.1086,重排阶段是主要增益来源

每个组件贡献为正且被如实保留;不存在"只报正增益"的筛选。

失败案例(从结果派生,非预设)

qid achieved 初排 天花板 窗口内相关 首篇相关位次 归因
0 0.0000 0.0000 0.8074 10/64 16 召回失败:相关文档在窗口内但初排即被跨主题干扰词压到第 11 位之后
201 0.0000 0.0000 0.4331 3/61 28 同上
266 0.0000 0.0245 0.6183 6/57 6 重排劣于初排:该查询上学习到的组合信号失效(负面结果如实保留)

架构

                  ┌─────────────── 离线建索引 ───────────────┐
语料 ──┬──→ 词法通路:BM25 (rank_bm25)                        │
       └──→ 稠密通路:TF-IDF → TruncatedSVD(LSI) → 归一化 ──→ FAISS IndexFlatIP
                                                     │
query ──→ 双路召回 top-K ──→ RRF 融合初排 ──→ top-N 候选 ──→ LambdaMART 重排 ──→ 最终排序
searchforge/
  core/        types · errors(E100~E500) · config(ENV 覆盖) · interfaces(Protocol) · seed
  data/        合成语料/查询 + 分级相关性标注(确定性 DGP)
  retrieval/   lexical(BM25/TF-IDF 兜底) · dense(FAISS-LSI/numpy 兜底) · hybrid(RRF)
  rerank/      features(LTR 特征) · lambdamart(LightGBM/sklearn 兜底)
  hpo/         Optuna(独立验证种子,防调参泄漏)
  eval/        nDCG@K / MAP@K / MRR@K / Recall@K
  pipeline/    SearchPipeline.run() + benchmark()
  cli.py       run / bench / tune

调用方向单向无环:cli → pipeline → {data, retrieval, rerank, hpo, eval} → core。

复用的顶级开源

环节 项目 权威依据
词法召回 rank_bm25 Robertson & Zaragoza (2009),BM25 至今不可绕过的强基线
稠密召回 faiss-cpu Johnson/Douze/Jégou (arXiv 1702.08734),Meta ANN 事实标准
稠密表示 TruncatedSVD(LSI) Deerwester et al. (1990)
多路融合 Reciprocal Rank Fusion Cormack, Clarke & Büttcher, SIGIR 2009
学习重排 lightgbm LambdaMART Burges (MSR-TR-2010-82),工业级 LTR 主力
超参优化 optuna Akiba et al., KDD 2019

离线降级(SOTA 后端不可用时自动降级,不伪造数字)

缺失依赖 降级路径
rank_bm25 词法改用 TF-IDF 余弦
faiss 稠密改用 numpy 精确余弦(同一 LSI 嵌入,结果逐位一致,有单测保证)
lightgbm 重排改用 sklearn.LogisticRegression
全部缺失 仍端到端跑通(有单测覆盖)

工程收口

项 状态
单测 51 passed
依赖锁定 requirements.lock.txt(校验无本机绝对路径)
确定性 同 seed 两次运行核心指标差 = 0.00e+00
性能预算 demo 37.4s(≤60s)、峰值 187MB(≤2GB)
lint / format ruff check + ruff format --check 全绿
CI GitHub Actions,矩阵 Python 3.12 / 3.13
密钥自查 git grep -nE "(sk-|api[_-]?key|token|secret|password)" 无命中
许可证 MIT,与全部依赖许可证兼容

已知限制

  1. 重排不扩大召回:旗舰 Recall@100 受初排窗口约束(0.9118 < dense 0.9418)。 下一步可引入更大候选窗或召回导向的第二阶段。
  2. 评测基于合成语料:相关性与干扰模式由 DGP 显式控制(便于可复现与难度体检), 未使用 TREC/BEIR 等真实数据集——因为环境不允许下载外部权重/数据。 结论可迁移性应在此前提下理解。
  3. 稠密表示是 LSI 而非预训练神经编码器:同样受"不下载外部权重"约束。 真实场景中替换为稠密编码器后,双路信号的互补性只会更强。
  4. 极难查询上重排可能劣于初排(见失败案例 q=266),即学习到的组合信号在部分查询上失效。

文档

许可

MIT © 晨星 (CJX0712)

About

SearchForge · 世界级神经/混合检索与学习重排系统(BM25+FAISS/LSI 双路召回 → RRF → LightGBM LambdaMART 重排,旗舰 RankFuse nDCG@10 相对最强基线 +11.73%)。作者:晨星

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages