Skip to content

密集检索

密集检索是现代RAG系统的核心技术之一,它通过将文本转换为高维向量,捕捉语义关系,实现更准确的检索。相比稀疏检索,密集检索能够理解同义词、上下位词等语义关系,大大提高了检索的准确性。

1. 基本原理

核心概念

  • 向量嵌入:将文本转换为高维向量表示
  • 语义相似度:通过向量空间中的距离衡量文本间的语义相似性
  • 向量数据库:专门存储和检索向量的数据库系统

工作流程

  1. 文本嵌入:使用预训练模型将文本转换为向量
  2. 向量存储:将向量存储到向量数据库中
  3. 查询处理:将用户查询转换为向量
  4. 相似度搜索:在向量空间中查找最相似的向量
  5. 结果返回:返回对应的文本内容

2. 嵌入模型

主流模型

  • Sentence-BERT:基于BERT的句子嵌入模型,适合通用场景
  • OpenAI Embeddings:OpenAI提供的嵌入API,性能优异
  • Hugging Face模型:丰富的预训练模型,支持多语言
  • GPT-3.5/GPT-4 Embeddings:与GPT模型配套的嵌入服务

模型选择

模型维度适用场景特点
all-MiniLM-L6-v2384轻量级应用速度快,效果好
all-mpnet-base-v2768平衡性能效果更好,速度适中
text-embedding-ada-0021536高质量应用效果最佳,API调用

嵌入模型示例

python
from langchain.embeddings import HuggingFaceEmbeddings, OpenAIEmbeddings

# 使用Hugging Face模型
embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/all-MiniLM-L6-v2"
)

# 或使用OpenAI Embeddings(需要API密钥)
# embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

# 生成文本嵌入
text = "RAG是一种结合检索和生成的技术"
vector = embeddings.embed_query(text)
print(f"向量维度: {len(vector)}")

3. 向量相似度计算

余弦相似度

最常用的相似度度量方法:

python
import numpy as np

def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# 示例
vec1 = embeddings.embed_query("机器学习")
vec2 = embeddings.embed_query("深度学习")
vec3 = embeddings.embed_query("自然语言处理")

print(f"机器学习 vs 深度学习: {cosine_similarity(vec1, vec2)}")
print(f"机器学习 vs NLP: {cosine_similarity(vec1, vec3)}")

欧氏距离

python
def euclidean_distance(a, b):
    return np.linalg.norm(np.array(a) - np.array(b))

4. 向量数据库

常用向量数据库

  • Chroma:轻量级,适合入门和小型项目
  • FAISS:Facebook开源,高性能
  • Pinecone:托管服务,企业级
  • Weaviate:开源,功能丰富
  • Milvus:开源,分布式架构

Chroma示例

python
from langchain.vectorstores import Chroma
from langchain.embeddings import HuggingFaceEmbeddings

# 初始化嵌入模型
embeddings = HuggingFaceEmbeddings()

# 准备文档
documents = [
    "RAG是一种结合检索和生成的技术",
    "向量数据库用于存储和检索嵌入向量",
    "大语言模型可以生成自然语言文本"
]

# 创建向量存储
vectorstore = Chroma.from_texts(
    texts=documents,
    embedding=embeddings,
    persist_directory="./chroma_db"
)

# 相似度搜索
results = vectorstore.similarity_search("什么是RAG?", k=2)
for doc in results:
    print(doc.page_content)

5. 检索优化

近似最近邻(ANN)

对于大规模数据,使用近似最近邻算法提高检索速度:

python
import faiss

# 创建FAISS索引
dimension = 768  # 嵌入维度
index = faiss.IndexFlatL2(dimension)

# 添加向量
vectors = np.array([embeddings.embed_query(doc) for doc in documents])
index.add(vectors)

# 搜索
query_vector = np.array([embeddings.embed_query("RAG技术")])
distances, indices = index.search(query_vector, k=3)

HNSW索引

python
# 创建HNSW索引(更快但占用更多内存)
index = faiss.IndexHNSWFlat(dimension, 32)
index.hnsw.efConstruction = 40
index.add(vectors)

6. 优缺点分析

优点

  • 语义理解:能够理解同义词和语义关系
  • 上下文感知:捕捉文本的上下文含义
  • 多语言支持:支持跨语言检索
  • 灵活性高:可以微调适应特定领域

缺点

  • 计算成本高:需要计算和存储高维向量
  • 需要预训练模型:依赖预训练嵌入模型
  • 可解释性弱:难以解释为什么两个文本相似
  • 存储开销大:向量存储占用较多空间

7. 最佳实践

嵌入模型选择

  • 通用场景:all-MiniLM-L6-v2(轻量)或 all-mpnet-base-v2(平衡)
  • 高质量需求:text-embedding-ada-002
  • 中文场景:选择支持中文的多语言模型

向量维度

  • 384维:轻量级应用,资源受限场景
  • 768维:平衡性能和精度
  • 1536维:高质量需求,资源充足

索引选择

  • 小规模数据(<10k):暴力搜索
  • 中等规模(10k-1M):HNSW
  • 大规模(>1M):量化索引(IVF、PQ)