如何利用 BGE-M3 优化长文本 RAG 的召回率与切片策略
text-embedding-3-small 提升了约 30%。BGE-M3 强大的地方在于它支持 Dense(稠密)、Sparse(稀疏/BM25)和 Multi-vector(多向量)三种检索模式。对于长文本,千万不要只用 Dense 检索,因为稠密向量在处理长段落时会产生“信息稀释”,导致检索出来的片段虽然语义相关,但缺乏具体答案。
实战配置策略:
1. 放弃固定切片,改用“重叠窗口 + 语义分段”
不要直接 split(512)。建议用 RecursiveCharacterTextSplitter 设置 800 token 窗口,并保留 150 token 的 overlap。更进阶的做法是在切片前用 LLM 提取每个段落的摘要,将“摘要+正文”一起喂给 BGE-M3,这样在检索时,摘要能提供全局语义,正文提供细节。
2. 开启混合检索(Hybrid Search)
在 Milvus 或 Qdrant 中部署 BGE-M3 时,必须同时存储 Dense 向量和 Sparse 向量。
# 伪代码:利用 BGE-M3 生成两种向量
from FlagEmbedding import BGEM3FlagModel
model = BGEM3FlagModel('BAAI/bge-m3', use_fp16=True)
sentences = ["这里是你的长文本切片内容..."]
# 同时获取稠密向量和稀疏向量
dense_embeddings = model.encode(sentences, return_dense=True)['dense_vecs']
sparse_embeddings = model.encode(sentences, return_sparse=True)['lexical_weights']检索时,采用 score = alpha * dense_score + (1 - alpha) * sparse_score 的加权方式。经验值 $\alpha$ 设在 0.7 左右,这样既能保证语义覆盖,又能通过关键词精准命中技术术语。3. 避坑指南:ColBERT 模式的存储成本
BGE-M3 的 Multi-vector 模式(ColBERT)召回率最高,但它会为每个 token 生成一个向量。如果你有 10k 个切片,每个切片 512 token,存储压力会瞬间爆炸。除非你的精度要求极高且预算充足,否则建议只在 Rerank 阶段使用 BGE-Reranker,而不要在初筛阶段强开 Multi-vector 存储。
效率提升技巧:
如果觉得推理慢,可以用 int8 量化。在量化后,我实测在 4090 上处理 1000 条切片的编码速度提升了近 2 倍,而召回率几乎没掉。
推荐的检索 pipeline:
BGE-M3 (Dense + Sparse) 粗筛 → 取 Top 20 → BGE-Reranker 精排 → 取 Top 5 → 喂给 Claude 3.5 Sonnet。 这样能有效解决长文本 RAG 中常见的“中间丢失”问题。
全部回复 (0)
还没有回复,来发第一条吧!
