Ascend-SACT/bge-reranker-v2-m3_mistei
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

bge-reranker-v2-m3 模型服务化部署与精度评测实践

1. 背景

本文档介绍 bge-reranker-v2-m3 模型的服务化部署与精度评测实践。该模型是 BGE 系列的重排序模型,官方 CMTEB 检索评测中将其与 bge-large-zh-v1.5(Embedding 模型)搭配使用:先由 bge-large-zh-v1.5 生成向量进行初筛检索,再由 bge-reranker-v2-m3 对 Top-K 结果进行精排。

本实践基于 FlagEmbedding 框架,通过 API 调用方式完成两阶段评测,验证服务化部署后的精度是否与官方结果一致。

评测目标:

  1. 验证服务化部署后的 Embedding + Reranker 两阶段检索精度
  2. 对比 Reranker 对检索结果的优化效果
  3. 与官方 CMTEB 评测结果进行对比验证

2. 服务化部署

说明:Embedding 模型(bge-large-zh-v1.5)与 Reranker 模型(bge-reranker-v2-m3)均基于昇腾(Ascend)NPU 与 TEI(Text Embeddings Inference)框架进行服务化部署,步骤完全相同,仅权重文件不同。以下以 bge-reranker-v2-m3 为例说明,bge-large-zh-v1.5 只需替换对应的模型名称和端口即可。

2.1 拉取镜像

docker pull swr.cn-south-1.myhuaweicloud.com/ascendhub/mis-tei:26.0.0-800I-A2-aarch64

2.2 下载权重

TORCH_DEVICE_BACKEND_AUTOLOAD=0 modelscope download --model BAAI/bge-reranker-v2-m3

2.3 创建在线推理容器

模型权重已下载到 /opt/data/models 目录,通过 -v 挂载到容器内。

export IMAGE=swr.cn-south-1.myhuaweicloud.com/ascendhub/mis-tei:26.0.0-800I-A2-aarch64
export NAME=bge-reranker-v2-m3

docker run -u root -e ENABLE_BOOST=True -itd --privileged \
  --name $NAME \
  --net=host \
  --shm-size=40g \
  --device /dev/davinci_manager \
  --device /dev/devmm_svm \
  --device /dev/hisi_hdc \
  -w /workspace \
  -v /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro \
  -v /usr/local/sbin:/usr/local/sbin:ro \
  -v /opt/data/models:/home/HwHiAiUser/model/ \
  $IMAGE BAAI/bge-reranker-v2-m3 0.0.0.0 8007

2.4 测试服务

curl 127.0.0.1:8007/v1/rerank \
  -X POST \
  -d '{
    "query": "What is Deep Learning?",
    "documents": ["Deep Learning is not...", "Deep learning is..."]
  }' \
  -H 'Content-Type: application/json'

3. 精度评测

3.1 数据集介绍

3.1.1 T2Retrieval 数据集结构

属性说明
全称T2Retrieval (CMTEB 检索任务之一)
语料规模118,605 篇中文文档
Query 数22,812 个查询
Qrels 数118,932 条相关性标注
评测指标NDCG@k, Recall@k, MAP@k, MRR@k, Precision@k
数据格式MTEB 2.x BEIR 格式(corpus/queries/qrels 分离)

3.1.2 数据来源

# HuggingFace Hub
"mteb/T2Retrieval"

# 三个子配置
corpus  → 118,605 篇文档(title + text)
queries → 22,812 个查询
default → 118,932 条 qrels(query-id + corpus-id + score)

3.1.3 评测指标说明

指标说明
NDCG@k归一化折损累计增益,衡量排序质量
Recall@ktop-k 中召回的相关文档比例
MAP@k平均精度均值
MRR@k第一个相关文档排名的倒数均值
Precision@ktop-k 中相关文档的精确率

3.2 环境准备

3.2.1 依赖安装

# 基础依赖
pip install faiss-cpu datasets pytrec_eval

# 克隆 FlagEmbedding 仓库
git clone https://github.com/FlagOpen/FlagEmbedding.git
cd FlagEmbedding

# 切换到 patch 对应的 commit
git checkout 7ed43d6

# FlagEmbedding(本地安装)
pip install -e .

3.3 代码适配

3.3.1 获取 Patch

从当前仓库中获取Patch 文件,其中包含所有代码修改和新增文件:

# 将 patch 复制到仓库根目录后应用
git apply cmteb_api_eval.patch

3.3.2 确认应用成功

git status

应看到以下变更:

文件状态说明
api_embedder.py新增Embedding API 封装,ThreadPoolExecutor 并发调用
api_reranker.py新增Reranker API 封装,按 query 分组调用
run_cmteb_api.py新增CMTEB 评测主入口
quick_verify_cmteb.py新增快速验证脚本,加载真实 T2Retrieval 子集进行端到端验证

3.3.3 整体架构

FlagEmbedding 默认流程:

本地加载 HuggingFace 模型 → Corpus Encoding → FAISS Index → Query Encoding → Search → Evaluate

适配后流程:

调用远程 Embedding API → Corpus Encoding → FAISS Index → Query Encoding → Search → Reranker API → Evaluate

各阶段详细说明:

阶段说明输入/输出
Corpus API Encoding通过 Embedding API 对 11.8 万篇文档进行向量编码,生成 doc.npy(约 464MB)输入:118,605 篇文档;输出:(118605, 1024) 维 float32 数组
FAISS Index基于内积相似度构建平面内积索引(IndexFlatIP),支持 top-k 最近邻检索输入:Corpus embeddings;输出:可查询的 FAISS 索引对象
Query API Encoding对 22,812 个查询进行向量编码(带 query instruction)输入:Query 文本;输出:(22812, 1024) 维向量
Search在 FAISS 索引中检索与 query 最相似的 top-k 文档输入:Query embeddings + FAISS 索引;输出:(22812, 100) 文档 ID 及相似度分数
Reranker API对 top-100 文档调用 Reranker API 重新排序每 query 4 次 API 调用(100 docs ÷ batch_size 32)
Evaluate基于 qrels 计算 NDCG/Recall/MAP/MRR/Precision输入:Search 结果 + 标准答案;输出:各 k 值指标

3.3.4 API Embedder 实现(api_embedder.py)

核心逻辑:继承 AbsEmbedder,将 encode_single_device 重载为 HTTP API 调用。

class APIEmbedder(AbsEmbedder):
    def __init__(self, ..., max_workers=8, **kwargs):
        kwargs["devices"] = ["cpu"]
        super().__init__(...)
        self.max_workers = max_workers

    def encode_single_device(self, sentences, batch_size=256, ...):
        # 使用 ThreadPoolExecutor 并发调用 API
        with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
            # 提交所有 batch 任务
            future_to_idx = {
                executor.submit(self._call_api, batch): batch_idx
                ...
            }
            # 收集结果
            for future in tqdm(as_completed(future_to_idx), ...):
                ...

3.3.5 API 重排序器实现(api_reranker.py)

核心逻辑:继承 AbsReranker,按查询分组调用重排序器 API。

class APIReranker(AbsReranker):
    def compute_score_single_gpu(self, sentence_pairs, ...):
        # Group by query to batch call API per query
        query_to_docs = {}
        for idx, (query, doc) in enumerate(sentence_pairs):
            ...
        
        scores = [0.0] * len(sentence_pairs)
        for query in tqdm(query_to_docs, desc="API reranking"):
            docs = query_to_docs[query]
            # TEI API may have max batch size limit; chunk if needed
            for start in range(0, len(docs), self.batch_size):
                chunk_scores = self._call_api(query, doc_chunk)
                ...
        return np.array(scores, dtype=np.float32)

关键设计点:

  • 按 query 分组,避免不同 query 的 docs 混在一起
  • 每 query 的 docs 按 batch_size=32 切分 chunk
  • 每个 chunk 一次 API 调用(每 query 约 4 次调用)

3.3.6 主入口脚本(run_cmteb_api.py)

适配后的评测入口,支持命令行参数:

def parse_args():
    parser.add_argument("--dataset_names", nargs="+", default=None)  # 评测任务名称
    parser.add_argument("--embedder_api_url", default="http://127.0.0.1:8009/v1/embeddings")
    parser.add_argument("--embedder_api_model", default="bge-large-zh-v1.5")
    parser.add_argument("--embedder_api_batch_size", type=int, default=32)
    parser.add_argument("--search_top_k", type=int, default=100)
    parser.add_argument("--rerank_top_k", type=int, default=100)
    parser.add_argument("--corpus_embd_save_dir", default=None)  # Corpus 缓存目录
    parser.add_argument("--overwrite", action="store_true")      # 覆盖已有结果
    ...

3.3.7 快速验证脚本(quick_verify_cmteb.py)

用于端到端 pipeline 验证,使用小规模真实数据(默认 50 文档 + 5 查询),所有参数均通过命令行传入,与 run_cmteb_api.py 保持一致。

HF_ENDPOINT=https://hf-mirror.com python quick_verify_cmteb.py \
    --embedder_api_url "http://127.0.0.1:8009/v1/embeddings" \
    --embedder_api_model "bge-large-zh-v1.5" \
    --reranker_api_url "http://127.0.0.1:8007/rerank" \
    --reranker_api_model "bge-reranker-v2-m3" \
    --max_corpus 50 \
    --max_queries 5

3.4 测试命令

3.4.1 快速验证

HF_ENDPOINT=https://hf-mirror.com python quick_verify_cmteb.py \
    --embedder_api_url "http://127.0.0.1:8009/v1/embeddings" \
    --embedder_api_model "bge-large-zh-v1.5" \
    --reranker_api_url "http://127.0.0.1:8007/rerank" \
    --reranker_api_model "bge-reranker-v2-m3" \
    --max_corpus 50 \
    --max_queries 5 \
    --search_top_k 10 \
    --rerank_top_k 10

3.4.2 T2Retrieval 正式评测

mkdir -p /tmp/hf_cache/cmteb

cd /workspace/FlagEmbedding

HF_ENDPOINT=https://hf-mirror.com nohup python run_cmteb_api.py \
    --dataset_names T2Retrieval \
    --cache_path /tmp/hf_cache/cmteb \
    --embedder_api_url "http://127.0.0.1:8009/v1/embeddings" \
    --embedder_api_model "bge-large-zh-v1.5" \
    --embedder_api_batch_size 32 \
    --embedder_max_workers 8 \
    --reranker_api_url "http://127.0.0.1:8007/rerank" \
    --reranker_api_model "bge-reranker-v2-m3" \
    --reranker_api_batch_size 32 \
    --search_top_k 100 \
    --rerank_top_k 100 \
    --output_dir ./cmteb_search_results_api \
    --corpus_embd_save_dir ./cmteb_corpus_embd_api \
    --eval_output_path ./cmteb_eval_results_api.md \
    --log_level INFO \
    > run_t2retrieval.log 2>&1 &

3.4.3 可配置参数说明

run_cmteb_api.py(正式评测)与 quick_verify_cmteb.py(快速验证)均通过命令行参数配置,参数风格保持一致。

通用参数(两个脚本均支持):

参数默认值说明
--embedder_api_urlhttp://127.0.0.1:8009/v1/embeddings嵌入模型 API 端点
--embedder_api_modelbge-large-zh-v1.5嵌入模型名称
--embedder_api_batch_size32 / 8嵌入模型 API 每批文本数量(正式 / 验证)
--embedder_max_workers8 / 2嵌入模型 API 并发线程数(正式 / 验证)
--query_instruction为这个句子生成表示以用于检索相关文章:查询指令前缀
--reranker_api_urlhttp://127.0.0.1:8007/rerank重排模型 API 端点
--reranker_api_modelbge-reranker-v2-m3重排模型名称
--reranker_api_batch_size32 / 8重排模型 API 每批文档数(正式 / 验证)
--search_top_k100 / 10检索返回前 k 条结果(正式 / 验证)
--rerank_top_k100 / 10重排返回前 k 条结果(正式 / 验证)
--k_values[1,3,5,10,100,1000] / [1,3,5,10]评测指标截断点(正式 / 验证)
--cache_pathNoneHuggingFace 数据集缓存目录

正式评测参数(仅 run_cmteb_api.py):

参数默认值说明
--dataset_namesNone(全部任务)评测数据集名称列表,如 T2Retrieval
--dataset_dirNone本地数据集目录
--splits["dev"]数据集划分列表
--output_dir./cmteb_search_results_api检索结果保存目录
--corpus_embd_save_dirNone语料嵌入缓存目录
--eval_output_path./cmteb_eval_results_api.md评估报告输出路径
--overwriteFalse是否覆盖已有结果
--log_levelINFO日志级别

快速验证参数(仅 quick_verify_cmteb.py):

参数默认值说明
--max_corpus50验证用文档数
--max_queries5验证用查询数

3.5 测试与优化过程

3.5.1 各阶段耗时分析

首次运行(无缓存)真实耗时(基于 run_t2retrieval.log 时间戳):

阶段耗时说明
数据加载~15秒从 HuggingFace Hub 下载并加载语料库(Corpus)+ 相关性判断(Qrels)+ 查询集(Queries)
语料库 API 编码~6分钟118,605 篇文档通过 Embedding API 进行编码(批处理大小=32,8个工作进程)
FAISS 索引构建~1分钟构建 118,605 个向量的内积索引
查询 API 编码~2分钟22,812 个查询通过 Embedding API 进行编码
FAISS 检索~8分钟在 CPU 上对 22,812 × 118,605 进行 top-100 检索(使用 faiss-cpu)
保存检索结果~1分钟保存 93MB 大小的检索结果 JSON 文件
检索评估~1分钟无重排序器(Reranker)阶段的指标计算
重排序器 API~5小时40分钟22,812 个查询 × 每个查询4次调用,单线程串行调用
最终评估~1分钟重排序器(Reranker)阶段的指标计算
总计~6小时

3.6 结果说明

3.6.1 评测结果(完整指标)

检索阶段(无重排序器):

{
    "T2Retrieval-dev": {
        "ndcg_at_1": 0.89383,
        "ndcg_at_3": 0.85389,
        "ndcg_at_5": 0.83960,
        "ndcg_at_10": 0.83975,
        "ndcg_at_100": 0.87592,
        "ndcg_at_1000": 0.87592,
        "map_at_1": 0.27132,
        "map_at_3": 0.53632,
        "map_at_5": 0.65916,
        "map_at_10": 0.76314,
        "map_at_100": 0.79939,
        "map_at_1000": 0.79939,
        "recall_at_1": 0.27132,
        "recall_at_3": 0.55350,
        "recall_at_5": 0.69370,
        "recall_at_10": 0.82932,
        "recall_at_100": 0.94673,
        "recall_at_1000": 0.94673,
        "precision_at_1": 0.89383,
        "precision_at_3": 0.74744,
        "precision_at_5": 0.62641,
        "precision_at_10": 0.41775,
        "precision_at_100": 0.04990,
        "precision_at_1000": 0.00499,
        "mrr_at_1": 0.89383,
        "mrr_at_3": 0.91594,
        "mrr_at_5": 0.91883,
        "mrr_at_10": 0.92034,
        "mrr_at_100": 0.92123,
        "mrr_at_1000": 0.92123
    }
}

Reranker 重排阶段:

{
    "T2Retrieval-dev": {
        "ndcg_at_1": 0.90430,
        "ndcg_at_3": 0.86471,
        "ndcg_at_5": 0.84912,
        "ndcg_at_10": 0.84676,
        "ndcg_at_100": 0.88214,
        "ndcg_at_1000": 0.88214,
        "map_at_1": 0.27684,
        "map_at_3": 0.54535,
        "map_at_5": 0.66852,
        "map_at_10": 0.77114,
        "map_at_100": 0.80765,
        "map_at_1000": 0.80765,
        "recall_at_1": 0.27684,
        "recall_at_3": 0.56159,
        "recall_at_5": 0.70095,
        "recall_at_10": 0.83255,
        "recall_at_100": 0.94673,
        "recall_at_1000": 0.94673,
        "precision_at_1": 0.90430,
        "precision_at_3": 0.75554,
        "precision_at_5": 0.63160,
        "precision_at_10": 0.41910,
        "precision_at_100": 0.04990,
        "precision_at_1000": 0.00499,
        "mrr_at_1": 0.90430,
        "mrr_at_3": 0.92438,
        "mrr_at_5": 0.92679,
        "mrr_at_10": 0.92810,
        "mrr_at_100": 0.92889,
        "mrr_at_1000": 0.92889
    }
}

3.6.2 结果对比

本次评测 vs 官方 CMTEB 结果:

指标本次(无 Reranker)本次(Reranker)官方(无 Reranker)官方(Reranker)
NDCG@1083.9884.6883.9984.57

官方数据来源:ModelScope - bge-reranker-v2-m3 CMTEB 检索评测表

完整指标对比:

指标本次(无 Reranker)本次(Reranker)提升
NDCG@189.3890.43+1.05
NDCG@385.3986.47+1.08
NDCG@583.9684.91+0.95
NDCG@1083.9884.68+0.70
NDCG@10087.5988.21+0.62
Recall@10094.6794.67—
MRR@1092.0392.81+0.78
MAP@10079.9480.77+0.83

3.6.3 结果分析

  1. 与官方结果高度一致:

    • 无 Reranker 阶段:本次 83.98 vs 官方 83.99,差异仅 -0.01
    • Reranker 阶段:本次 84.68 vs 官方 84.57,差异 +0.11
    • 服务化部署通过 API 调用获得的精度与官方结果趋势一致,验证了部署精度无损
  2. Reranker 对排序质量有正向优化:NDCG@10 从 83.98 提升到 84.68,提升约 0.7 个百分点

  3. 低 k 值提升更明显:NDCG@1/3/5 提升 0.95-1.08,说明 Reranker 能有效将更相关文档排到前列

  4. Recall 不变:Recall@100 均为 94.67,符合预期(Reranker 只在已有 top-100 内重排,不引入新文档)


4. 结论与建议

  1. API 化适配可行:通过 APIEmbedder + APIReranker 将 FlagEmbedding 框架适配为远程 API 调用,完整保留了评测流程的准确性。

  2. Reranker 有正向优化效果:NDCG@10 从 83.98 提升到 84.68,低 k 值(NDCG@1/3/5)提升更明显,说明 bge-reranker-v2-m3 能有效优化排序质量。

  3. 与官方结果高度一致:

    • 无 Reranker 阶段 NDCG@10:本次 83.98 vs 官方 83.99,差异仅 -0.01
    • Reranker 阶段 NDCG@10:本次 84.68 vs 官方 84.57,差异 +0.11
    • 服务化部署通过 API 调用获得的评测结果与官方 CMTEB 结果高度吻合,验证了服务化部署的精度无损