源文件:chapter3/sparse-embedding/README.md 教学型稀疏向量检索引擎 一个基于倒排索引和 BM25 算法的稀疏向量检索引擎教学实现。本项目通过详尽的日志与可视化特性,展示信息检索的基础概念。 特性 完整的 BM25 实现:完整实现 BM25 排序算法 高级分词:全面处理数字、代码、技术术语和混合大小写的分词器 倒排索引:用于词项查找的高效倒排索引数据结构 HTTP API:基于 FastAPI 构建的 RESTful API 交互式 Web UI:浏览器端的索引与检索界面 详尽日志:贯穿索引与检索全过程的详细教学日志 索引可视化:检查索引内部结构的 API 内存存储:为教学目的采用的简单内存存储 分词能力 TextProcessor
源文件:chapter3/sparse-embedding/README.md
一个基于倒排索引和 BM25 算法的稀疏向量检索引擎教学实现。本项目通过详尽的日志与可视化特性,展示信息检索的基础概念。
TextProcessor 现在为真实文本提供全面的分词:
404、3.14、2.0.1XK9-2B4-7Q1、API_KEY_123C++、.NET、Node.jsJavaScript、PyTorch、iPhoneuser@example.com#FF5733、0x1234API、HTTP、NASAPython3、ES6、HTML5BM25(Best Matching 25)是一种概率排序函数,根据查询词项为文档打分。该算法使用:
关键参数:
k1(默认 1.5):控制词频饱和b(默认 0.75):控制长度归一化pip install -r requirements.txt
cli.py(下节的命令行工具)只依赖 Python 标准库,无需安装任何第三方包即可离线运行;server.py / demo.py 才需要上面的 FastAPI 等依赖。
cli.py 提供一个完全离线的命令行入口:在一个内置的 10 篇小型语料上运行 BM25 稀疏检索、复现书中“逐词 IDF/TF/BM25 贡献”的日志,并在带标注的评测集上计算 recall/precision/MRR。所有参数都有中文 --help。
python cli.py --help # 查看全部参数(中文) python cli.py # 默认演示:查询 "model distillation" python cli.py -q "model distillation" --explain # 逐词展示 TF/IDF/BM25 贡献(对应书中日志) python cli.py --eval # 在标注集上计算 recall@k / precision@k / MRR python cli.py -q "cat" # 观察 BM25 读不懂同义词的短板(kitten/feline 漏召回) python cli.py --corpus my.json -q "查询" -o out.json # 自定义语料 + 结果落盘 python cli.py --k1 2.0 -b 0.5 -q "..." # 调 BM25 参数 k1 / b python cli.py --method splade -q "..." # 学习型稀疏检索 SPLADE(需预先下载模型)
主要参数:
| 参数 | 说明 |
|---|---|
-q, --query |
查询字符串(默认 model distillation) |
-c, --corpus |
语料文件(.json 文档数组或 .jsonl 每行一篇);缺省用内置示例语料 |
-m, --method |
bm25(默认,离线)或 splade(学习型稀疏,需下载模型) |
-k, --top-k |
返回前 k 条(默认 5) |
-o, --output |
把结果 / 评测指标写入 JSON 文件 |
--eval |
在标注集上评测 recall@k / precision@k / MRR |
--labels |
自定义评测标注 {query: [相关doc_id,...]} |
--explain |
对命中文档逐词展示 TF / IDF / BM25 贡献 |
--k1 / -b |
BM25 词频饱和参数 k1、文档长度归一化参数 b |
-v, --verbose |
打开引擎 DEBUG 日志(分词、倒排索引构建、打分全过程) |
内置标注集覆盖精确关键词、错误码、专有名称与“只有同义表达”的查询。python cli.py --eval 的真实输出(k=5):
查询 'model distillation' recall@5=1.00 precision@5=1.00 RR=1.00 查询 'HTTP 404 error' recall@5=1.00 precision@5=0.50 RR=1.00 查询 'XK9-2B4-7Q1' recall@5=1.00 precision@5=1.00 RR=1.00 查询 'BM25 ranking function' recall@5=1.00 precision@5=1.00 RR=1.00 查询 'cat' recall@5=0.00 precision@5=0.00 RR=0.00 <- 漏召回(同义词短板) 宏平均 recall@5=0.800 precision@5=0.700 MRR=0.800 漏召回率(1-recall@5)=0.200
结果直观印证了书中的结论:BM25 在精确关键词、错误码、专有名称上表现极佳(recall=1.0),但读不懂同义词——查询 cat 无法命中只写了 kitten / feline 的文档(recall=0)。这一长一短正是引入混合检索(见实验 3-6 retrieval-pipeline)的动机。
--method splade 对应书中提到的学习型稀疏检索(SPLADE):用掩码语言模型为每个词项打权重,并能为原文未出现但语义相关的词项补权重(术语扩展)。它需要下载预训练模型 naver/splade-cocondenser-ensembledistil(依赖 torch、transformers)。离线环境下无法下载权重时,命令会快速给出清晰提示(并说明 BM25 路径无需任何模型即可离线运行),不会卡在网络下载上。联网环境可先执行 huggingface-cli download naver/splade-cocondenser-ensembledistil 缓存模型后再运行。
python server.py
服务会在 http://localhost:4241 启动。
打开浏览器访问 http://localhost:4241 即可使用交互式 Web UI。
POST /index { "text": "Your document text here", "metadata": {"title": "Document Title", "category": "Category"} }
POST /search { "query": "your search query", "top_k": 10 }
GET /stats
GET /index/structure
GET /document/{doc_id}
DELETE /index
python demo.py
演示脚本会:
系统在每一步都提供详细日志:
/index/structure 端点返回:
每条检索结果都包含调试信息:
2024-01-15 10:30:45 - Indexing document with ID 0 2024-01-15 10:30:45 - Document text: Python is a high-level programming... 2024-01-15 10:30:45 - Tokenizing text of length 142 2024-01-15 10:30:45 - Found 23 raw tokens 2024-01-15 10:30:45 - After removing stop words: 15 tokens 2024-01-15 10:30:45 - Document 0: 15 tokens, 12 unique terms 2024-01-15 10:30:45 - Document 0 indexed successfully
2024-01-15 10:31:20 - Searching for: 'machine learning algorithms' 2024-01-15 10:31:20 - Query terms after processing: ['machine', 'learning', 'algorithms'] 2024-01-15 10:31:20 - Term 'machine' appears in 2 documents 2024-01-15 10:31:20 - Term 'learning' appears in 3 documents 2024-01-15 10:31:20 - Term 'algorithms' appears in 1 document 2024-01-15 10:31:20 - Found 4 candidate documents 2024-01-15 10:31:20 - IDF for 'machine': N=10, df=2, idf=1.7918 2024-01-15 10:31:20 - Term 'machine' in doc 1: tf=2, dl=35, score=3.2451 2024-01-15 10:31:20 - Document 1 total score: 7.8923 2024-01-15 10:31:20 - Returning top 3 results
服务运行时,可在 http://localhost:4241/docs 访问交互式 API 文档。
sparse-embedding/ ├── bm25_engine.py # 核心检索引擎实现 ├── cli.py # 离线 argparse CLI:BM25/SPLADE 检索 + recall/precision 评测 ├── server.py # FastAPI HTTP 服务 ├── demo.py # 演示脚本 ├── requirements.txt # Python 依赖 └── README.md # 本文件
本实现演示了:
这是一个教学实现,存在一些局限:
潜在的学习向增强: