Appearance
密集检索
密集检索是现代RAG系统的核心技术之一,它通过将文本转换为高维向量,捕捉语义关系,实现更准确的检索。相比稀疏检索,密集检索能够理解同义词、上下位词等语义关系,大大提高了检索的准确性。
1. 基本原理
核心概念
- 向量嵌入:将文本转换为高维向量表示
- 语义相似度:通过向量空间中的距离衡量文本间的语义相似性
- 向量数据库:专门存储和检索向量的数据库系统
工作流程
- 文本嵌入:使用预训练模型将文本转换为向量
- 向量存储:将向量存储到向量数据库中
- 查询处理:将用户查询转换为向量
- 相似度搜索:在向量空间中查找最相似的向量
- 结果返回:返回对应的文本内容
2. 嵌入模型
主流模型
- Sentence-BERT:基于BERT的句子嵌入模型,适合通用场景
- OpenAI Embeddings:OpenAI提供的嵌入API,性能优异
- Hugging Face模型:丰富的预训练模型,支持多语言
- GPT-3.5/GPT-4 Embeddings:与GPT模型配套的嵌入服务
模型选择
| 模型 | 维度 | 适用场景 | 特点 |
|---|---|---|---|
| all-MiniLM-L6-v2 | 384 | 轻量级应用 | 速度快,效果好 |
| all-mpnet-base-v2 | 768 | 平衡性能 | 效果更好,速度适中 |
| text-embedding-ada-002 | 1536 | 高质量应用 | 效果最佳,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)