项目实战:用bge-small-zh-v1.5构建一个智能文档检索系统,只需100行代码!
项目构想:我们要做什么?
在这个项目中,我们将利用开源模型bge-small-zh-v1.5构建一个智能文档检索系统。该系统能够根据用户输入的查询语句,快速从文档库中检索出最相关的文档片段。以下是具体的功能描述:
- 输入:用户输入一个查询语句(例如:“如何优化Python代码性能?”)。
- 输出:系统返回与查询语句最相关的文档片段列表,按相关性排序。
这个应用非常适合用于个人知识库管理、企业内部文档检索或在线问答系统。
技术选型:为什么是bge-small-zh-v1.5?
bge-small-zh-v1.5是一个轻量级的中文文本嵌入模型,具有以下核心亮点:
- 高效的检索能力:模型经过优化,能够快速生成高质量的文本嵌入向量,适合实时检索任务。
- 合理的相似度分布:v1.5版本改进了相似度分布,使得检索结果更加准确。
- 轻量级设计:模型体积小,适合在资源有限的环境中部署。
- 支持中文:专门针对中文文本优化,能够更好地理解中文语义。
基于这些特性,bge-small-zh-v1.5非常适合构建高效的文档检索系统。
核心实现逻辑
项目的核心逻辑分为以下几步:
- 加载模型:使用
transformers库加载bge-small-zh-v1.5模型。 - 文档嵌入:将文档库中的文本转换为嵌入向量并存储。
- 查询处理:将用户查询转换为嵌入向量。
- 相似度计算:计算查询向量与文档向量的相似度,返回最相关的文档片段。
关键代码逻辑
from transformers import AutoTokenizer, AutoModel
import torch
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# 加载模型和分词器
model_name = "BAAI/bge-small-zh-v1.5"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)
def get_embedding(text):
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)
with torch.no_grad():
outputs = model(**inputs)
return outputs.last_hidden_state.mean(dim=1).numpy()
# 示例文档库
documents = ["Python性能优化的常见方法包括使用更高效的数据结构。",
"多线程编程可以提升程序的运行效率。",
"使用JIT编译器可以显著加快Python代码的执行速度。"]
# 生成文档嵌入
doc_embeddings = [get_embedding(doc) for doc in documents]
# 用户查询
query = "如何优化Python代码性能?"
query_embedding = get_embedding(query)
# 计算相似度
similarities = [cosine_similarity(query_embedding, doc_embedding)[0][0] for doc_embedding in doc_embeddings]
# 按相似度排序
sorted_docs = sorted(zip(documents, similarities), key=lambda x: x[1], reverse=True)
# 输出结果
for doc, sim in sorted_docs:
print(f"相似度: {sim:.4f} | 文档: {doc}")
代码全览与讲解
以下是完整的项目代码,包含详细的中文注释:
# 导入必要的库
from transformers import AutoTokenizer, AutoModel
import torch
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# 加载模型和分词器
model_name = "BAAI/bge-small-zh-v1.5"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)
# 定义函数:生成文本嵌入
def get_embedding(text):
# 对文本进行分词和编码
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)
# 生成嵌入向量
with torch.no_grad():
outputs = model(**inputs)
# 取最后一层隐藏状态的平均值作为文本嵌入
return outputs.last_hidden_state.mean(dim=1).numpy()
# 示例文档库
documents = [
"Python性能优化的常见方法包括使用更高效的数据结构。",
"多线程编程可以提升程序的运行效率。",
"使用JIT编译器可以显著加快Python代码的执行速度。"
]
# 为文档库生成嵌入向量
doc_embeddings = [get_embedding(doc) for doc in documents]
# 用户输入查询
query = "如何优化Python代码性能?"
query_embedding = get_embedding(query)
# 计算查询与每个文档的相似度
similarities = [cosine_similarity(query_embedding, doc_embedding)[0][0] for doc_embedding in doc_embeddings]
# 按相似度排序文档
sorted_docs = sorted(zip(documents, similarities), key=lambda x: x[1], reverse=True)
# 打印结果
print("查询:", query)
print("检索结果:")
for idx, (doc, sim) in enumerate(sorted_docs, 1):
print(f"{idx}. 相似度: {sim:.4f} | 文档: {doc}")
代码讲解
- 模型加载:使用
transformers库加载预训练的bge-small-zh-v1.5模型和分词器。 - 嵌入生成:
get_embedding函数将输入文本转换为嵌入向量。 - 文档库处理:为文档库中的每个文档生成嵌入向量。
- 查询处理:将用户查询转换为嵌入向量,并计算其与文档库中每个文档的相似度。
- 结果排序:按相似度从高到低排序文档,并输出结果。
效果展示与功能扩展
效果展示
运行上述代码后,输出结果如下:
查询: 如何优化Python代码性能?
检索结果:
1. 相似度: 0.8921 | 文档: Python性能优化的常见方法包括使用更高效的数据结构。
2. 相似度: 0.7564 | 文档: 使用JIT编译器可以显著加快Python代码的执行速度。
3. 相似度: 0.4321 | 文档: 多线程编程可以提升程序的运行效率。
功能扩展
- 支持大规模文档库:可以将文档嵌入向量存储到向量数据库(如FAISS)中,以支持高效检索。
- 多语言支持:结合其他语言的嵌入模型,扩展为多语言检索系统。
- 用户界面:使用Flask或FastAPI构建一个简单的Web界面,方便用户交互。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



