模型简介
模型特点
模型能力
使用案例
🚀 BGE-M3
BGE-M3是一个具备多功能性、多语言性和多粒度性的文本嵌入模型。它能同时执行密集检索、多向量检索和稀疏检索三种常见的检索功能,支持超100种工作语言,还能处理从短句到长达8192个标记的长文档等不同粒度的输入。
更多详情请参考我们的GitHub仓库:FlagEmbedding
🚀 快速开始
安装
git clone https://github.com/FlagOpen/FlagEmbedding.git
cd FlagEmbedding
pip install -e .
或者:
pip install -U FlagEmbedding
生成文本嵌入
密集嵌入
from FlagEmbedding import BGEM3FlagModel
model = BGEM3FlagModel('BAAI/bge-m3',
use_fp16=True) # 设置use_fp16为True可在轻微降低性能的情况下加快计算速度
sentences_1 = ["What is BGE M3?", "Defination of BM25"]
sentences_2 = ["BGE M3 is an embedding model supporting dense retrieval, lexical matching and multi-vector interaction.",
"BM25 is a bag-of-words retrieval function that ranks a set of documents based on the query terms appearing in each document"]
embeddings_1 = model.encode(sentences_1,
batch_size=12,
max_length=8192, # 如果不需要这么长的长度,可以设置较小的值以加快编码过程
)['dense_vecs']
embeddings_2 = model.encode(sentences_2)['dense_vecs']
similarity = embeddings_1 @ embeddings_2.T
print(similarity)
# [[0.6265, 0.3477], [0.3499, 0.678 ]]
你也可以使用sentence-transformers
和huggingface transformers
来生成密集嵌入。详情请参考baai_general_embedding。
稀疏嵌入(词法权重)
from FlagEmbedding import BGEM3FlagModel
model = BGEM3FlagModel('BAAI/bge-m3', use_fp16=True) # 设置use_fp16为True可在轻微降低性能的情况下加快计算速度
sentences_1 = ["What is BGE M3?", "Defination of BM25"]
sentences_2 = ["BGE M3 is an embedding model supporting dense retrieval, lexical matching and multi-vector interaction.",
"BM25 is a bag-of-words retrieval function that ranks a set of documents based on the query terms appearing in each document"]
output_1 = model.encode(sentences_1, return_dense=True, return_sparse=True, return_colbert_vecs=False)
output_2 = model.encode(sentences_2, return_dense=True, return_sparse=True, return_colbert_vecs=False)
# 你可以查看每个标记的权重:
print(model.convert_id_to_token(output_1['lexical_weights']))
# [{'What': 0.08356, 'is': 0.0814, 'B': 0.1296, 'GE': 0.252, 'M': 0.1702, '3': 0.2695, '?': 0.04092},
# {'De': 0.05005, 'fin': 0.1368, 'ation': 0.04498, 'of': 0.0633, 'BM': 0.2515, '25': 0.3335}]
# 通过词法匹配计算分数
lexical_scores = model.compute_lexical_matching_score(output_1['lexical_weights'][0], output_2['lexical_weights'][0])
print(lexical_scores)
# 0.19554901123046875
print(model.compute_lexical_matching_score(output_1['lexical_weights'][0], output_1['lexical_weights'][1]))
# 0.0
多向量(ColBERT)
from FlagEmbedding import BGEM3FlagModel
model = BGEM3FlagModel('BAAI/bge-m3', use_fp16=True)
sentences_1 = ["What is BGE M3?", "Defination of BM25"]
sentences_2 = ["BGE M3 is an embedding model supporting dense retrieval, lexical matching and multi-vector interaction.",
"BM25 is a bag-of-words retrieval function that ranks a set of documents based on the query terms appearing in each document"]
output_1 = model.encode(sentences_1, return_dense=True, return_sparse=True, return_colbert_vecs=True)
output_2 = model.encode(sentences_2, return_dense=True, return_sparse=True, return_colbert_vecs=True)
print(model.colbert_score(output_1['colbert_vecs'][0], output_2['colbert_vecs'][0]))
print(model.colbert_score(output_1['colbert_vecs'][0], output_2['colbert_vecs'][1]))
# 0.7797
# 0.4620
计算文本对的分数
输入一个文本对列表,你可以得到通过不同方法计算的分数。
from FlagEmbedding import BGEM3FlagModel
model = BGEM3FlagModel('BAAI/bge-m3', use_fp16=True)
sentences_1 = ["What is BGE M3?", "Defination of BM25"]
sentences_2 = ["BGE M3 is an embedding model supporting dense retrieval, lexical matching and multi-vector interaction.",
"BM25 is a bag-of-words retrieval function that ranks a set of documents based on the query terms appearing in each document"]
sentence_pairs = [[i,j] for i in sentences_1 for j in sentences_2]
print(model.compute_score(sentence_pairs,
max_passage_length=128, # 较小的最大长度会导致较低的延迟
weights_for_different_modes=[0.4, 0.2, 0.4])) # weights_for_different_modes(w)用于进行加权求和:w[0]*dense_score + w[1]*sparse_score + w[2]*colbert_score
# {
# 'colbert': [0.7796499729156494, 0.4621465802192688, 0.4523794651031494, 0.7898575067520142],
# 'sparse': [0.195556640625, 0.00879669189453125, 0.0, 0.1802978515625],
# 'dense': [0.6259765625, 0.347412109375, 0.349853515625, 0.67822265625],
# 'sparse+dense': [0.482503205537796, 0.23454029858112335, 0.2332356721162796, 0.5122477412223816],
# 'colbert+sparse+dense': [0.6013619303703308, 0.3255828022956848, 0.32089319825172424, 0.6232916116714478]
# }
✨ 主要特性
- 多功能性:能够同时执行嵌入模型的三种常见检索功能,即密集检索、多向量检索和稀疏检索。
- 多语言性:支持超过100种工作语言。
- 多粒度性:能够处理不同粒度的输入,从短句到长达8192个标记的长文档。
📦 安装指南
git clone https://github.com/FlagOpen/FlagEmbedding.git
cd FlagEmbedding
pip install -e .
或者:
pip install -U FlagEmbedding
📚 详细文档
RAG检索管道的建议
我们建议使用以下管道:混合检索 + 重排。
- 混合检索:利用各种方法的优势,提供更高的准确性和更强的泛化能力。一个经典的例子是同时使用嵌入检索和BM25算法。现在,你可以尝试使用BGE-M3,它支持嵌入和稀疏检索。这允许你在生成密集嵌入时无需任何额外成本即可获得标记权重(类似于BM25)。要使用混合检索,你可以参考Vespa和Milvus。
- 重排:作为交叉编码器模型,重排器比双编码器嵌入模型具有更高的准确性。在检索后使用重排模型(例如,bge-reranker,bge-reranker-v2)可以进一步筛选所选文本。
新闻
- 2024/7/1:我们更新了BGE-M3的MIRACL评估结果。要复现新结果,你可以参考:bge-m3_miracl_2cr。我们还在arXiv上更新了我们的论文。
详情
之前的测试结果较低是因为我们错误地从搜索结果中删除了与查询具有相同ID的段落。纠正这个错误后,BGE-M3在MIRACL上的整体性能高于之前的结果,但实验结论保持不变。其他结果不受此错误影响。要复现之前较低的结果,你需要在使用pyserini.search.faiss
或pyserini.search.lucene
搜索段落时添加--remove-query
参数。
规格
模型
模型名称 | 维度 | 序列长度 | 介绍 |
---|---|---|---|
BAAI/bge-m3 | 1024 | 8192 | 多语言;从bge-m3-unsupervised进行统一微调(密集、稀疏和colbert) |
BAAI/bge-m3-unsupervised | 1024 | 8192 | 多语言;从bge-m3-retromae进行对比学习 |
BAAI/bge-m3-retromae | -- | 8192 | 多语言;将xlm-roberta的最大长度扩展到8192,并通过retromae进一步预训练 |
BAAI/bge-large-en-v1.5 | 1024 | 512 | 英语模型 |
BAAI/bge-base-en-v1.5 | 768 | 512 | 英语模型 |
BAAI/bge-small-en-v1.5 | 384 | 512 | 英语模型 |
数据
数据集 | 介绍 |
---|---|
MLDR | 文档检索数据集,涵盖13种语言 |
bge-m3-data | bge-m3使用的微调数据 |
FAQ
1. 不同检索方法的介绍
- 密集检索:将文本映射到单个嵌入,例如DPR、BGE-v1.5。
- 稀疏检索(词法匹配):一个大小等于词汇表的向量,大多数位置设置为零,仅为文本中存在的标记计算权重。例如BM25、unicoil和splade。
- 多向量检索:使用多个向量表示一个文本,例如ColBERT。
2. 如何在其他项目中使用BGE-M3?
对于嵌入检索,你可以使用与BGE相同的方法来使用BGE-M3模型。唯一的区别是BGE-M3模型不再需要在查询中添加指令。
3. 如何微调bge-M3模型?
你可以按照这个示例中的常见方法来微调密集嵌入。
如果你想微调m3的所有嵌入函数(密集、稀疏和colbert),你可以参考统一微调示例。
🔧 技术细节
评估
开源社区的基准测试
BGE-M3模型在这个基准测试中表现出色(OAI是OpenAI的缩写)。更多详情,请参考文章和GitHub仓库。
我们的结果
-
多语言(Miracl数据集)
-
跨语言(MKQA数据集)
-
长文档检索
- MLDR:
请注意,MLDR是我们通过大语言模型构建的一个文档检索数据集,涵盖13种语言,包括测试集、验证集和训练集。我们利用MLDR的训练集来增强模型的长文档检索能力。因此,将基线与
Dense w.o.long
(不使用长文档数据集进行微调)进行比较更为公平。此外,这个长文档检索数据集将开源,以解决当前开源多语言长文本检索数据集的缺乏问题。我们相信这些数据将有助于开源社区训练文档检索模型。 - NarritiveQA:
- MLDR:
-
与BM25的比较 我们使用Pyserini实现了BM25,测试结果可以通过这个脚本复现。我们使用两种不同的分词器测试了BM25:一种使用Lucene Analyzer,另一种使用与M3相同的分词器(即xlm-roberta的分词器)。结果表明,BM25仍然是一个有竞争力的基线,特别是在长文档检索方面。
训练
- 自我知识蒸馏:将不同检索模式的多个输出组合作为奖励信号,以提高单模式的性能(特别是稀疏检索和多向量(colbert)检索)。
- 高效批处理:提高在长文本上微调时的效率。小批量策略简单但有效,也可用于微调大型嵌入模型。
- MCLS:一种在不进行微调的情况下提高长文本性能的简单方法。如果你没有足够的资源对长文本进行模型微调,这种方法很有用。
更多详情请参考我们的报告。
📄 许可证
本项目采用MIT许可证。
致谢
感谢Miracl、MKQA、NarritiveQA等开源数据集的作者。感谢Tevatron、Pyserini等开源库。
引用
如果你觉得这个仓库有用,请考虑给它加星 :star: 并引用:
@misc{bge-m3,
title={BGE M3-Embedding: Multi-Lingual, Multi-Functionality, Multi-Granularity Text Embeddings Through Self-Knowledge Distillation},
author={Jianlv Chen and Shitao Xiao and Peitian Zhang and Kun Luo and Defu Lian and Zheng Liu},
year={2024},
eprint={2402.03216},
archivePrefix={arXiv},
primaryClass={cs.CL}
}







