模型简介
模型特点
模型能力
使用案例
🚀 BCEmbedding:用于RAG的双语和跨语种嵌入模型
BCEmbedding是由网易有道开发的双语和跨语种语义表征算法模型库,包含EmbeddingModel
和RerankerModel
两类基础模型。EmbeddingModel
可生成语义向量,在语义搜索和问答中起关键作用;RerankerModel
则擅长优化搜索结果和排序。该模型库以其出色的双语和跨语种能力著称,能消除中英语言差异,实现强大的语义表征和RAG评测表现。
🚀 快速开始
最新、最详细的bce-embedding-base_v1相关信息,请移步:GitHub
安装
首先,创建并激活一个conda环境:
conda create --name bce python=3.10 -y
conda activate bce
然后,进行BCEmbedding
的最小化安装:
pip install BCEmbedding==0.1.1
或者从源码安装:
git clone git@github.com:netease-youdao/BCEmbedding.git
cd BCEmbedding
pip install -v -e .
快速上手示例
1. 基于BCEmbedding
使用EmbeddingModel
,默认使用cls
pooler:
from BCEmbedding import EmbeddingModel
# 句子列表
sentences = ['sentence_0', 'sentence_1', ...]
# 初始化嵌入模型
model = EmbeddingModel(model_name_or_path="maidalun1020/bce-embedding-base_v1")
# 提取嵌入向量
embeddings = model.encode(sentences)
使用RerankerModel
计算相关分数并重新排序:
from BCEmbedding import RerankerModel
# 你的查询和相应的段落
query = 'input_query'
passages = ['passage_0', 'passage_1', ...]
# 构建句子对
sentence_pairs = [[query, passage] for passage in passages]
# 初始化重排模型
model = RerankerModel(model_name_or_path="maidalun1020/bce-reranker-base_v1")
# 方法0:计算句子对的分数
scores = model.compute_score(sentence_pairs)
# 方法1:对段落进行重排
rerank_results = model.rerank(query, passages)
注意:
- 在
RerankerModel.rerank
方法中,当“passages”非常长时,我们提供了一种在生产中使用的高级预处理方法来生成sentence_pairs
。
2. 基于transformers
对于EmbeddingModel
:
from transformers import AutoModel, AutoTokenizer
# 句子列表
sentences = ['sentence_0', 'sentence_1', ...]
# 初始化模型和分词器
tokenizer = AutoTokenizer.from_pretrained('maidalun1020/bce-embedding-base_v1')
model = AutoModel.from_pretrained('maidalun1020/bce-embedding-base_v1')
device = 'cuda' # 如果没有GPU,设置为"cpu"
model.to(device)
# 获取输入
inputs = tokenizer(sentences, padding=True, truncation=True, max_length=512, return_tensors="pt")
inputs_on_device = {k: v.to(device) for k, v in inputs.items()}
# 获取嵌入向量
outputs = model(**inputs_on_device, return_dict=True)
embeddings = outputs.last_hidden_state[:, 0] # cls pooler
embeddings = embeddings / embeddings.norm(dim=1, keepdim=True) # 归一化
对于RerankerModel
:
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
# 初始化模型和分词器
tokenizer = AutoTokenizer.from_pretrained('maidalun1020/bce-reranker-base_v1')
model = AutoModelForSequenceClassification.from_pretrained('maidalun1020/bce-reranker-base_v1')
device = 'cuda' # 如果没有GPU,设置为"cpu"
model.to(device)
# 获取输入
inputs = tokenizer(sentence_pairs, padding=True, truncation=True, max_length=512, return_tensors="pt")
inputs_on_device = {k: v.to(device) for k, v in inputs.items()}
# 计算分数
scores = model(**inputs_on_device, return_dict=True).logits.view(-1,).float()
scores = torch.sigmoid(scores)
3. 基于sentence_transformers
对于EmbeddingModel
:
from sentence_transformers import SentenceTransformer
# 句子列表
sentences = ['sentence_0', 'sentence_1', ...]
# 初始化嵌入模型
## 注意:sentence-transformers有新更新,所以先清理 "`SENTENCE_TRANSFORMERS_HOME`/maidalun1020_bce-embedding-base_v1" 或 "~/.cache/torch/sentence_transformers/maidalun1020_bce-embedding-base_v1" 以下载新版本。
model = SentenceTransformer("maidalun1020/bce-embedding-base_v1")
# 提取嵌入向量
embeddings = model.encode(sentences, normalize_embeddings=True)
对于RerankerModel
:
from sentence_transformers import CrossEncoder
# 初始化重排模型
model = CrossEncoder('maidalun1020/bce-reranker-base_v1', max_length=512)
# 计算句子对的分数
scores = model.predict(sentence_pairs)
RAG框架集成示例
1. 在langchain
中使用
from langchain.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.vectorstores.utils import DistanceStrategy
query = 'apples'
passages = [
'I like apples',
'I like oranges',
'Apples and oranges are fruits'
]
# 初始化嵌入模型
model_name = 'maidalun1020/bce-embedding-base_v1'
model_kwargs = {'device': 'cuda'}
encode_kwargs = {'batch_size': 64, 'normalize_embeddings': True, 'show_progress_bar': False}
embed_model = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
# 示例 #1. 提取嵌入向量
query_embedding = embed_model.embed_query(query)
passages_embeddings = embed_model.embed_documents(passages)
# 示例 #2. langchain检索器示例
faiss_vectorstore = FAISS.from_texts(passages, embed_model, distance_strategy=DistanceStrategy.MAX_INNER_PRODUCT)
retriever = faiss_vectorstore.as_retriever(search_type="similarity", search_kwargs={"score_threshold": 0.5, "k": 3})
related_passages = retriever.get_relevant_documents(query)
2. 在llama_index
中使用
from llama_index.embeddings import HuggingFaceEmbedding
from llama_index import VectorStoreIndex, ServiceContext, SimpleDirectoryReader
from llama_index.node_parser import SimpleNodeParser
from llama_index.llms import OpenAI
query = 'apples'
passages = [
'I like apples',
'I like oranges',
'Apples and oranges are fruits'
]
# 初始化嵌入模型
model_args = {'model_name': 'maidalun1020/bce-embedding-base_v1', 'max_length': 512, 'embed_batch_size': 64, 'device': 'cuda'}
embed_model = HuggingFaceEmbedding(**model_args)
# 示例 #1. 提取嵌入向量
query_embedding = embed_model.get_query_embedding(query)
passages_embeddings = embed_model.get_text_embedding_batch(passages)
# 示例 #2. RAG示例
llm = OpenAI(model='gpt-3.5-turbo-0613', api_key=os.environ.get('OPENAI_API_KEY'), api_base=os.environ.get('OPENAI_BASE_URL'))
service_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)
documents = SimpleDirectoryReader(input_files=["BCEmbedding/tools/eval_rag/eval_pdfs/Comp_en_llama2.pdf"]).load_data()
node_parser = SimpleNodeParser.from_defaults(chunk_size=512)
nodes = node_parser.get_nodes_from_documents(documents[0:36])
index = VectorStoreIndex(nodes, service_context=service_context)
query_engine = index.as_query_engine()
response = query_engine.query("What is llama?")
✨ 主要特性
- 双语和跨语种能力:基于有道翻译引擎的强大能力,
BCEmbedding
具备强大的中英双语和跨语种语义表征能力,后续还将支持更多语言。 - RAG适配:针对RAG任务进行了优化,适用于翻译、摘要、问答等多种任务,能准确理解查询意图。详见 基于LlamaIndex的RAG评测指标。
- 高效且精确的语义检索:
EmbeddingModel
采用双编码器,可在第一阶段实现高效检索;RerankerModel
采用交叉编码器,在第二阶段实现更高精度的重排和深度语义分析。 - 广泛的领域适应性:在多样化的数据集上进行训练,能在教育、法律、金融、医疗、文学、FAQ、教科书、维基百科等多个领域表现出色。
- 用户友好设计:无需为每个任务指定查询指令,使用更加便捷。
- 有意义的重排序分数:
RerankerModel
提供相关分数,可提高结果质量,优化大语言模型性能。 - 经过生产验证:已在有道的产品中成功实现并验证。
📦 安装指南
环境准备
首先,创建并激活一个conda环境:
conda create --name bce python=3.10 -y
conda activate bce
安装方式
最小化安装
pip install BCEmbedding==0.1.1
从源码安装
git clone git@github.com:netease-youdao/BCEmbedding.git
cd BCEmbedding
pip install -v -e .
💻 使用示例
基础用法
以下是使用EmbeddingModel
和RerankerModel
的基础示例:
# EmbeddingModel示例
from BCEmbedding import EmbeddingModel
sentences = ['sentence_0', 'sentence_1', ...]
model = EmbeddingModel(model_name_or_path="maidalun1020/bce-embedding-base_v1")
embeddings = model.encode(sentences)
# RerankerModel示例
from BCEmbedding import RerankerModel
query = 'input_query'
passages = ['passage_0', 'passage_1', ...]
sentence_pairs = [[query, passage] for passage in passages]
model = RerankerModel(model_name_or_path="maidalun1020/bce-reranker-base_v1")
scores = model.compute_score(sentence_pairs)
rerank_results = model.rerank(query, passages)
高级用法
以下是在langchain
和llama_index
中使用的高级示例:
# langchain示例
from langchain.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.vectorstores.utils import DistanceStrategy
query = 'apples'
passages = [
'I like apples',
'I like oranges',
'Apples and oranges are fruits'
]
model_name = 'maidalun1020/bce-embedding-base_v1'
model_kwargs = {'device': 'cuda'}
encode_kwargs = {'batch_size': 64, 'normalize_embeddings': True, 'show_progress_bar': False}
embed_model = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
query_embedding = embed_model.embed_query(query)
passages_embeddings = embed_model.embed_documents(passages)
faiss_vectorstore = FAISS.from_texts(passages, embed_model, distance_strategy=DistanceStrategy.MAX_INNER_PRODUCT)
retriever = faiss_vectorstore.as_retriever(search_type="similarity", search_kwargs={"score_threshold": 0.5, "k": 3})
related_passages = retriever.get_relevant_documents(query)
# llama_index示例
from llama_index.embeddings import HuggingFaceEmbedding
from llama_index import VectorStoreIndex, ServiceContext, SimpleDirectoryReader
from llama_index.node_parser import SimpleNodeParser
from llama_index.llms import OpenAI
query = 'apples'
passages = [
'I like apples',
'I like oranges',
'Apples and oranges are fruits'
]
model_args = {'model_name': 'maidalun1020/bce-embedding-base_v1', 'max_length': 512, 'embed_batch_size': 64, 'device': 'cuda'}
embed_model = HuggingFaceEmbedding(**model_args)
query_embedding = embed_model.get_query_embedding(query)
passages_embeddings = embed_model.get_text_embedding_batch(passages)
llm = OpenAI(model='gpt-3.5-turbo-0613', api_key=os.environ.get('OPENAI_API_KEY'), api_base=os.environ.get('OPENAI_BASE_URL'))
service_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)
documents = SimpleDirectoryReader(input_files=["BCEmbedding/tools/eval_rag/eval_pdfs/Comp_en_llama2.pdf"]).load_data()
node_parser = SimpleNodeParser.from_defaults(chunk_size=512)
nodes = node_parser.get_nodes_from_documents(documents[0:36])
index = VectorStoreIndex(nodes, service_context=service_context)
query_engine = index.as_query_engine()
response = query_engine.query("What is llama?")
📚 详细文档
模型列表
模型名称 | 模型类型 | 支持语言 | 参数数量 | 权重下载 |
---|---|---|---|---|
bce-embedding-base_v1 | EmbeddingModel |
中文、英文 | 279M | 下载 |
bce-reranker-base_v1 | RerankerModel |
中文、英文、日文、韩文 | 279M | 下载 |
评测
基于MTEB评估语义表征
我们基于MTEB和C_MTEB,提供embedding
和reranker
模型的语义表征评测工具。
- Embedding模型评测:运行以下命令在双语和跨语种设置下评测
your_embedding_model
(如maidalun1020/bce-embedding-base_v1
):
python BCEmbedding/tools/eval_mteb/eval_embedding_mteb.py --model_name_or_path maidalun1020/bce-embedding-base_v1 --pooler cls
评测包含“Retrieval”、 “STS”、 “PairClassification”、 “Classification”、 “Reranking”和“Clustering”六大类任务的114个数据集。
- Reranker模型评测:运行以下命令在双语和跨语种设置下评测
your_reranker_model
(如maidalun1020/bce-reranker-base_v1
):
python BCEmbedding/tools/eval_mteb/eval_reranker_mteb.py --model_name_or_path maidalun1020/bce-reranker-base_v1
评测包含“Reranking”任务的12个数据集。
- 指标可视化工具:我们提供了一键脚本,将
embedding
和reranker
模型的评估结果汇总为Embedding模型指标汇总和Reranker模型指标汇总。
python BCEmbedding/evaluation/mteb/summarize_eval_results.py --results_dir {your_embedding_results_dir | your_reranker_results_dir}
基于LlamaIndex评估RAG
LlamaIndex是一个著名的大模型应用的开源工具,在RAG中很受欢迎。我们按照其评测流程验证BCEmbedding
在RAG中的效果。
- 安装LlamaIndex:
pip install llama-index==0.9.22
- 指标定义:
- 命中率(Hit Rate):计算在检索的前k个文档中找到正确答案的查询所占的比例,该指标越大越好。
- 平均倒数排名(Mean Reciprocal Rank,MRR):通过查看最高排名的相关文档的排名来评估系统的准确性,是所有查询中这些排名的倒数的平均值,该指标越大越好。
- 复现LlamaIndex博客结果:
# 至少需要两个可用的GPU
CUDA_VISIBLE_DEVICES=0,1 python BCEmbedding/tools/eval_rag/eval_llamaindex_reproduce.py
然后,汇总评估结果:
python BCEmbedding/tools/eval_rag/summarize_eval_results.py --results_dir results/rag_reproduce_results
结果详见LlamaIndex RAG评测结果复现,从结果中可以看出:
- 在
WithoutReranker
设置下,bce-embedding-base_v1
比其他embedding模型效果更好。 - 在固定embedding模型设置下,
bce-reranker-base_v1
比其他reranker模型效果更好。 bce-embedding-base_v1
和bce-reranker-base_v1
组合表现SOTA。- 多领域适应性评估:为了评估
BCEmbedding
的领域泛化性、双语和跨语种能力,我们构建了多领域评估数据集CrosslingualMultiDomainsDataset。
# 至少需要两个可用的GPU
CUDA_VISIBLE_DEVICES=0,1 python BCEmbedding/tools/eval_rag/eval_llamaindex_multiple_domains.py
然后,汇总评估结果:
python BCEmbedding/tools/eval_rag/summarize_eval_results.py --results_dir results/rag_results
多领域评估总结详见多领域场景评估。
排行榜
MTEB中的语义表征评估
Embedding模型
模型 | 维度 | Pooler | 指令要求 | 检索(47) | STS(19) | 成对分类(5) | 分类(21) | 重排(12) | 聚类(15) | 平均(119) |
---|---|---|---|---|---|---|---|---|---|---|
bge-base-en-v1.5 | 768 | cls |
需要 | 37.14 | 55.06 | 75.45 | 59.73 | 43.00 | 37.74 | 47.19 |
bge-base-zh-v1.5 | 768 | cls |
需要 | 47.63 | 63.72 | 77.40 | 63.38 | 54.95 | 32.56 | 53.62 |
bge-large-en-v1.5 | 1024 | cls |
需要 | 37.18 | 54.09 | 75.00 | 59.24 | 42.47 | 37.32 | 46.80 |
bge-large-zh-v1.5 | 1024 | cls |
需要 | 47.58 | 64.73 | 79.14 | 64.19 | 55.98 | 33.26 | 54.23 |
e5-large-v2 | 1024 | mean |
需要 | 35.98 | 55.23 | 75.28 | 59.53 | 42.12 | 36.51 | 46.52 |
gte-large | 1024 | mean |
无需 | 36.68 | 55.22 | 74.29 | 57.73 | 42.44 | 38.51 | 46.67 |
gte-large-zh | 1024 | cls |
无需 | 41.15 | 64.62 | 77.58 | 62.04 | 55.62 | 33.03 | 51.51 |
jina-embeddings-v2-base-en | 768 | mean |
无需 | 31.58 | 54.28 | 74.84 | 58.42 | 41.16 | 34.67 | 44.29 |
m3e-base | 768 | mean |
无需 | 46.29 | 63.93 | 71.84 | 64.08 | 52.38 | 37.84 | 53.54 |
m3e-large | 1024 | mean |
无需 | 34.85 | 59.74 | 67.69 | 60.07 | 48.99 | 31.62 | 46.78 |
multilingual-e5-base | 768 | mean |
需要 | 54.73 | 65.49 | 76.97 | 69.72 | 55.01 | 38.44 | 58.34 |
multilingual-e5-large | 1024 | mean |
需要 | 56.76 | 66.79 | 78.80 | 71.61 | 56.49 | 43.09 | 60.50 |
bce-embedding-base_v1 | 768 | cls |
无需 | 57.60 | 65.73 | 74.96 | 69.00 | 57.29 | 38.95 | 59.43 |
注意:
bce-embedding-base_v1
在相同规模的开源嵌入模型中表现出色。- 评测包含“Retrieval”、 “STS”、 “PairClassification”、 “Classification”、 “Reranking”和“Clustering”六大类任务的114个数据集。
- 我们发布的跨语种语义表征评测数据属于
Retrieval
任务。 - 更详细的评测结果详见Embedding模型指标汇总。
Reranker模型
模型 | 重排(12) | 平均(12) |
---|---|---|
bge-reranker-base | 59.04 | 59.04 |
bge-reranker-large | 60.86 | 60.86 |
bce-reranker-base_v1 | 61.29 | 61.29 |
注意:
bce-reranker-base_v1
优于其他开源重排模型。- 评测包含“Reranking”任务的12个数据集。
- 更详细的评测结果详见Reranker模型指标汇总。
LlamaIndex中的RAG评估
多领域场景
注意:
- 在
["en", "zh", "en-zh", "zh-en"]
设置下进行评估。 - 在
WithoutReranker
设置下,bce-embedding-base_v1
优于其他嵌入模型。 - 在固定嵌入模型设置下,
bce-reranker-base_v1
表现最佳。 bce-embedding-base_v1
和bce-reranker-base_v1
组合表现SOTA。
有道BCEmbedding API
对于更喜欢直接调用API的用户,有道提供了方便的BCEmbedding
调用API。这种方式可以简化和高效地将BCEmbedding
集成到项目中,避免手动设置和系统维护的复杂性。更详细的API调用接口说明详见有道BCEmbedding API。
🔧 技术细节
双语和跨语种优势
现有的单个语义表征模型在双语和跨语种场景中常常表现不佳,特别是在中文、英文及其跨语种任务中。BCEmbedding
充分利用有道翻译引擎的优势,实现只需一个模型就可以在单语、双语和跨语种场景中表现出卓越的性能。
EmbeddingModel
支持中文和英文(之后会支持更多语种)。RerankerModel
支持中文、英文、日文和韩文。
最新更新
- 2024-01-03:模型发布 - bce-embedding-base_v1和bce-reranker-base_v1已发布。
- 2024-01-03:RAG评测数据 [CrosslingualMultiDomainsDataset] - 基于LlamaIndex的RAG评测数据已发布。
- 2024-01-03:跨语种语义表征评测数据 [详情] - 基于MTEB的跨语种评测数据已发布。
📄 许可证
BCEmbedding
采用Apache 2.0许可证。
🔗 相关链接
🧲 微信交流群
欢迎大家扫码加入官方微信交流群。
✏️ 引用
如果在您的研究或项目中使用BCEmbedding
,请按照以下方式引用并给项目点个星:
@misc{youdao_bcembedding_2023,
title={BCEmbedding: Bilingual and Crosslingual Embedding for RAG},
author={NetEase Youdao, Inc.},
year={2023},
howpublished={\url{https://github.com/netease-youdao/BCEmbedding}}
}







