BGE-M3实战入门:与Elasticsearch 8.x结合使用,dense+sparse混合打分

📅 发布时间:2026/7/8 14:56:17 👁️ 浏览次数:
BGE-M3实战入门:与Elasticsearch 8.x结合使用,dense+sparse混合打分
BGE-M3实战入门与Elasticsearch 8.x结合使用densesparse混合打分BGE-M3句子相似度模型 二次开发构建by113小贝1. 什么是BGE-M3嵌入模型BGE-M3是一个专门为检索场景设计的文本嵌入模型可以理解为三合一的多功能嵌入工具。它最大的特点是同时支持三种检索模式密集检索Dense理解语义相似性适合找意思相近的内容稀疏检索Sparse匹配关键词适合精确查找多向量检索ColBERT细粒度匹配特别适合长文档简单来说BGE-M3不是生成文本的模型而是专门用来找相似内容的工具。它能把任何文本转换成数学向量然后通过计算向量之间的距离来找到最相关的内容。技术特点向量维度1024维最大处理长度8192个token支持100多种语言使用FP16精度加速推理2. 环境准备与快速部署2.1 系统要求在开始之前请确保你的环境满足以下要求Python 3.8或更高版本至少16GB内存推荐32GBGPU可选有GPU会更快Elasticsearch 8.x已安装并运行2.2 一键部署BGE-M3服务最简单的启动方式是使用提供的脚本# 进入项目目录 cd /root/bge-m3 # 使用启动脚本推荐 bash start_server.sh如果脚本不可用也可以手动启动# 设置环境变量重要 export TRANSFORMERS_NO_TF1 # 启动服务 cd /root/bge-m3 python3 app.py如果需要后台运行nohup bash /root/bge-m3/start_server.sh /tmp/bge-m3.log 21 2.3 验证服务状态服务启动后检查是否正常运行# 检查端口 netstat -tuln | grep 7860 # 查看日志 tail -f /tmp/bge-m3.log在浏览器中访问http://你的服务器IP:7860如果看到Gradio界面说明服务已成功启动。3. Elasticsearch 8.x集成实战3.1 安装必要的Python库首先安装所需的依赖pip install elasticsearch8 sentence-transformers flag-embedding3.2 创建Elasticsearch索引我们需要创建一个特殊的索引来存储向量from elasticsearch import Elasticsearch # 连接到Elasticsearch es Elasticsearch([http://localhost:9200]) # 创建索引配置 index_config { settings: { number_of_shards: 1, number_of_replicas: 0 }, mappings: { properties: { content: {type: text}, dense_vector: { type: dense_vector, dims: 1024, index: True, similarity: cosine }, sparse_vector: { properties: { tokens: {type: keyword}, weights: {type: float} } } } } } # 创建索引 es.indices.create(indexbge-m3-documents, bodyindex_config)3.3 文本嵌入与索引写入现在我们来演示如何将文本内容存入Elasticsearchfrom FlagEmbedding import BGEM3FlagModel # 初始化模型 model BGEM3FlagModel(/root/.cache/huggingface/BAAI/bge-m3, use_fp16True) # 要索引的文档 documents [ 人工智能是计算机科学的一个分支, 机器学习是人工智能的核心技术, 深度学习是机器学习的一个子领域, 自然语言处理让计算机理解人类语言 ] for i, doc in enumerate(documents): # 生成嵌入向量 embeddings model.encode(doc, return_denseTrue, return_sparseTrue) # 准备索引数据 doc_data { content: doc, dense_vector: embeddings[dense_vecs].tolist()[0], sparse_vector: { tokens: list(embeddings[lexical_weights].keys()), weights: list(embeddings[lexical_weights].values()) } } # 写入Elasticsearch es.index(indexbge-m3-documents, idi, bodydoc_data) print(文档索引完成)4. 混合检索实战densesparse打分4.1 密集检索示例首先看纯语义搜索def dense_search(query, top_k3): # 生成查询向量 query_embedding model.encode(query, return_denseTrue)[dense_vecs][0] # Elasticsearch查询 script_query { script_score: { query: {match_all: {}}, script: { source: cosineSimilarity(params.query_vector, dense_vector) 1.0, params: {query_vector: query_embedding.tolist()} } } } response es.search( indexbge-m3-documents, body{query: script_query, size: top_k} ) return response[hits][hits] # 执行语义搜索 results dense_search(计算机智能技术) for hit in results: print(f得分: {hit[_score]:.3f} - 内容: {hit[_source][content]})4.2 稀疏检索示例关键词匹配搜索def sparse_search(query, top_k3): # 生成稀疏向量 sparse_embedding model.encode(query, return_sparseTrue)[lexical_weights] # 构建查询 terms [] for token, weight in sparse_embedding.items(): terms.append({ term: { sparse_vector.tokens: { value: token, boost: float(weight) } } }) response es.search( indexbge-m3-documents, body{query: {bool: {should: terms}}, size: top_k} ) return response[hits][hits] # 执行关键词搜索 results sparse_search(机器学习深度) for hit in results: print(f得分: {hit[_score]:.3f} - 内容: {hit[_source][content]})4.3 混合检索实战现在展示如何结合两种检索方式def hybrid_search(query, dense_weight0.7, sparse_weight0.3, top_k5): # 生成两种向量 embeddings model.encode(query, return_denseTrue, return_sparseTrue) dense_vector embeddings[dense_vecs][0].tolist() sparse_weights embeddings[lexical_weights] # 构建混合查询 dense_query { script_score: { query: {match_all: {}}, script: { source: cosineSimilarity(params.query_vector, dense_vector) 1.0, params: {query_vector: dense_vector} } } } sparse_terms [] for token, weight in sparse_weights.items(): sparse_terms.append({ term: { sparse_vector.tokens: { value: token, boost: float(weight) * sparse_weight } } }) sparse_query {bool: {should: sparse_terms}} if sparse_terms else {match_none: {}} # 组合查询 hybrid_query { bool: { should: [ {function_score: {query: dense_query, weight: dense_weight}}, sparse_query ] } } response es.search( indexbge-m3-documents, body{query: hybrid_query, size: top_k} ) return response[hits][hits] # 执行混合搜索 results hybrid_search(人工智能学习技术) print(混合搜索结果) for i, hit in enumerate(results, 1): print(f{i}. 得分: {hit[_score]:.3f}) print(f 内容: {hit[_source][content]}) print()5. 实际应用场景与建议5.1 不同场景的模式选择根据你的具体需求可以选择最适合的检索模式使用场景推荐模式效果说明语义搜索Dense找意思相近的内容比如汽车也能找到车辆关键词匹配Sparse精确匹配关键词适合技术文档搜索长文档搜索ColBERT处理长文章时效果更好高准确度需求混合模式结合两种方式的优点准确度最高5.2 性能优化建议在实际使用中可以考虑以下优化措施# 批量处理文档提高效率 def batch_index_documents(docs, batch_size32): for i in range(0, len(docs), batch_size): batch docs[i:ibatch_size] # 批量生成嵌入 embeddings model.encode(batch, return_denseTrue, return_sparseTrue) # 批量写入Elasticsearch bulk_actions [] for j, doc in enumerate(batch): action { index: { _index: bge-m3-documents, _id: i j } } doc_data { content: doc, dense_vector: embeddings[dense_vecs][j].tolist(), sparse_vector: { tokens: list(embeddings[lexical_weights][j].keys()), weights: list(embeddings[lexical_weights][j].values()) } } bulk_actions.append(action) bulk_actions.append(doc_data) es.bulk(bodybulk_actions) # 使用GPU加速如果有的话 model BGEM3FlagModel(/root/.cache/huggingface/BAAI/bge-m3, use_fp16True, devicecuda) # 使用GPU5.3 常见问题解决问题1服务启动失败检查7860端口是否被占用可以更改app.py中的端口号问题2内存不足减少batch_size或者使用更小的模型版本问题3检索速度慢确保使用FP16模式考虑添加GPU加速6. 总结通过本文的实战教程你应该已经掌握了BGE-M3服务部署学会了如何快速启动和验证嵌入服务Elasticsearch集成了解了如何创建适合向量检索的索引结构混合检索实现掌握了dense和sparse两种检索方式的单独使用和组合使用实战技巧获得了性能优化和问题解决的实用建议BGE-M3的强大之处在于它的灵活性你可以根据具体需求调整dense和sparse的权重比例。一般来说如果搜索语义相关的内容提高dense权重0.7-0.8如果搜索关键词匹配的内容提高sparse权重0.6-0.7对于一般搜索各取0.5的平衡权重往往效果不错现在你可以尝试在自己的数据集上应用这些技术构建强大的智能搜索系统了获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。