ONNX 模型库
返回模型

说明文档

这是 Sudhanshu Sharma 创建的 bge-reranker-v2-m3 模型量化版本的 ONNX 格式

license: apache-2.0 language:

  • 多语言 pipeline_tag: 文本分类 tags:
  • transformers
  • sentence-transformers
  • text-embeddings-inference

重排序器

更多详情请参阅我们的 Github: FlagEmbedding

与嵌入模型不同,重排序器以问题和文档作为输入,直接输出相似度而非嵌入向量。 您可以通过向重排序器输入查询和段落来获取相关性分数。 该分数可以通过 sigmoid 函数映射到 [0,1] 范围内的浮点值。

模型列表

模型 基础模型 语言 逐层 特性
BAAI/bge-reranker-base xlm-roberta-base 中文和英文 - 轻量级重排序模型,易于部署,推理速度快。
BAAI/bge-reranker-large xlm-roberta-large 中文和英文 - 轻量级重排序模型,易于部署,推理速度快。
BAAI/bge-reranker-v2-m3 bge-m3 多语言 - 轻量级重排序模型,具有强大的多语言能力,易于部署,推理速度快。
BAAI/bge-reranker-v2-gemma gemma-2b 多语言 - 适用于多语言场景,在英文能力和多语言能力方面均表现良好。
BAAI/bge-reranker-v2-minicpm-layerwise MiniCPM-2B-dpo-bf16 多语言 8-40 适用于多语言场景,在英文和中文能力方面均表现良好,允许自由选择输出层,便于加速推理。

您可以根据您的场景和资源选择模型。

使用方法

使用 FlagEmbedding

pip install -U FlagEmbedding

对于普通重排序器 (bge-reranker-base / bge-reranker-large / bge-reranker-v2-m3 )

获取相关性分数(分数越高表示相关性越强):

from FlagEmbedding import FlagReranker
reranker = FlagReranker('BAAI/bge-reranker-v2-m3', use_fp16=True) # 将 use_fp16 设置为 True 可以加速计算,但会有轻微的性能下降

score = reranker.compute_score(['query', 'passage'])
print(score) # -5.65234375

# 您可以通过设置 \"normalize=True\" 将分数映射到 0-1 范围,这将对接应用 sigmoid 函数
score = reranker.compute_score(['query', 'passage'], normalize=True)
print(score) # 0.003497010252573502

scores = reranker.compute_score([['what is panda?', 'hi'], ['what is panda?', 'The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.']])
print(scores) # [-8.1875, 5.26171875]

# 您可以通过设置 \"normalize=True\" 将分数映射到 0-1 范围,这将对接应用 sigmoid 函数
scores = reranker.compute_score([['what is panda?', 'hi'], ['what is panda?', 'The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.']], normalize=True)
print(scores) # [0.00027803096387751553, 0.9948403768236574]

对于基于 LLM 的重排序器

from FlagEmbedding import FlagLLMReranker
reranker = FlagLLMReranker('BAAI/bge-reranker-v2-gemma', use_fp16=True) # 将 use_fp16 设置为 True 可以加速计算,但会有轻微的性能下降
# reranker = FlagLLMReranker('BAAI/bge-reranker-v2-gemma', use_bf16=True) # 您也可以设置 use_bf16=True 来加速计算,但会有轻微的性能下降

score = reranker.compute_score(['query', 'passage'])
print(score)

scores = reranker.compute_score([['what is panda?', 'hi'], ['what is panda?', 'The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.']])
print(scores)

对于基于 LLM 的逐层重排序器

from FlagEmbedding import LayerWiseFlagLLMReranker
reranker = LayerWiseFlagLLMReranker('BAAI/bge-reranker-v2-minicpm-layerwise', use_fp16=True) # 将 use_fp16 设置为 True 可以加速计算,但会有轻微的性能下降
# reranker = LayerWiseFlagLLMReranker('BAAI/bge-reranker-v2-minicpm-layerwise', use_bf16=True) # 您也可以设置 use_bf16=True 来加速计算,但会有轻微的性能下降

score = reranker.compute_score(['query', 'passage'], cutoff_layers=[28]) # 调整 'cutoff_layers' 来选择用于计算分数的层。
print(score)

scores = reranker.compute_score([['what is panda?', 'hi'], ['what is panda?', 'The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.']], cutoff_layers=[28])
print(scores)

使用 Huggingface transformers

对于普通重排序器 (bge-reranker-base / bge-reranker-large / bge-reranker-v2-m3 )

获取相关性分数(分数越高表示相关性越强):

import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained('BAAI/bge-reranker-v2-m3')
model = AutoModelForSequenceClassification.from_pretrained('BAAI/bge-reranker-v2-m3')
model.eval()

pairs = [['what is panda?', 'hi'], ['what is panda?', 'The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.']]
with torch.no_grad():
    inputs = tokenizer(pairs, padding=True, truncation=True, return_tensors='pt', max_length=512)
    scores = model(**inputs, return_dict=True).logits.view(-1, ).float()
    print(scores)

对于基于 LLM 的重排序器

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

def get_inputs(pairs, tokenizer, prompt=None, max_length=1024):
    if prompt is None:
        prompt = "Given a query A and a passage B, determine whether the passage contains an answer to the query by providing a prediction of either 'Yes' or 'No'."
    sep = "\n"
    prompt_inputs = tokenizer(prompt,
                              return_tensors=None,
                              add_special_tokens=False)['input_ids']
    sep_inputs = tokenizer(sep,
                           return_tensors=None,
                           add_special_tokens=False)['input_ids']
    inputs = []
    for query, passage in pairs:
        query_inputs = tokenizer(f'A: {query}',
                                 return_tensors=None,
                                 add_special_tokens=False,
                                 max_length=max_length * 3 // 4,
                                 truncation=True)
        passage_inputs = tokenizer(f'B: {passage}',
                                   return_tensors=None,
                                   add_special_tokens=False,
                                   max_length=max_length,
                                   truncation=True)
        item = tokenizer.prepare_for_model(
            [tokenizer.bos_token_id] + query_inputs['input_ids'],
            sep_inputs + passage_inputs['input_ids'],
            truncation='only_second',
            max_length=max_length,
            padding=False,
            return_attention_mask=False,
            return_token_type_ids=False,
            add_special_tokens=False
        )
        item['input_ids'] = item['input_ids'] + sep_inputs + prompt_inputs
        item['attention_mask'] = [1] * len(item['input_ids'])
        inputs.append(item)
    return tokenizer.pad(
            inputs,
            padding=True,
            max_length=max_length + len(sep_inputs) + len(prompt_inputs),
            pad_to_multiple_of=8,
            return_tensors='pt',
    )

tokenizer = AutoTokenizer.from_pretrained('BAAI/bge-reranker-v2-gemma')
model = AutoModelForCausalLM.from_pretrained('BAAI/bge-reranker-v2-gemma')
yes_loc = tokenizer('Yes', add_special_tokens=False)['input_ids'][0]
model.eval()

pairs = [['what is panda?', 'hi'], ['what is panda?', 'The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.']]
with torch.no_grad():
    inputs = get_inputs(pairs, tokenizer)
    scores = model(**inputs, return_dict=True).logits[:, -1, yes_loc].view(-1, ).float()
    print(scores)

对于基于 LLM 的逐层重排序器

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

def get_inputs(pairs, tokenizer, prompt=None, max_length=1024):
    if prompt is None:
        prompt = "Given a query A and a passage B, determine whether the passage contains an answer to the query by providing a prediction of either 'Yes' or 'No'."
    sep = "\n"
    prompt_inputs = tokenizer(prompt,
                              return_tensors=None,
                              add_special_tokens=False)['input_ids']
    sep_inputs = tokenizer(sep,
                           return_tensors=None,
                           add_special_tokens=False)['input_ids']
    inputs = []
    for query, passage in pairs:
        query_inputs = tokenizer(f'A: {query}',
                                 return_tensors=None,
                                 add_special_tokens=False,
                                 max_length=max_length * 3 // 4,
                                 truncation=True)
        passage_inputs = tokenizer(f'B: {passage}',
                                   return_tensors=None,
                                   add_special_tokens=False,
                                   max_length=max_length,
                                   truncation=True)
        item = tokenizer.prepare_for_model(
            [tokenizer.bos_token_id] + query_inputs['input_ids'],
            sep_inputs + passage_inputs['input_ids'],
            truncation='only_second',
            max_length=max_length,
            padding=False,
            return_attention_mask=False,
            return_token_type_ids=False,
            add_special_tokens=False
        )
        item['input_ids'] = item['input_ids'] + sep_inputs + prompt_inputs
        item['attention_mask'] = [1] * len(item['input_ids'])
        inputs.append(item)
    return tokenizer.pad(
            inputs,
            padding=True,
            max_length=max_length + len(sep_inputs) + len(prompt_inputs),
            pad_to_multiple_of=8,
            return_tensors='pt',
    )

tokenizer = AutoTokenizer.from_pretrained('BAAI/bge-reranker-v2-minicpm-layerwise', trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained('BAAI/bge-reranker-v2-minicpm-layerwise', trust_remote_code=True, torch_dtype=torch.bfloat16)
model = model.to('cuda')
model.eval()

pairs = [['what is panda?', 'hi'], ['what is panda?', 'The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.']]
with torch.no_grad():
    inputs = get_inputs(pairs, tokenizer).to(model.device)
    all_scores = model(**inputs, return_dict=True, cutoff_layers=[28])
    all_scores = [scores[:, -1].view(-1, ).float() for scores in all_scores[0]]
    print(all_scores)

微调

数据格式

训练数据应该是一个 json 文件,每行是一个类似这样的字典:

{"query": str, "pos": List[str], "neg":List[str], "prompt": str}

query 是查询,pos 是正向文本列表,neg 是负向文本列表,prompt 指示查询和文本之间的关系。如果您没有某个查询的负向文本,您可以从整个语料库中随机采样一些作为负样本。

有关示例数据文件,请参见 toy_finetune_data.jsonl

训练

您可以使用以下代码微调重排序器:

对于基于 llm 的重排序器

torchrun --nproc_per_node {number of gpus} \
-m FlagEmbedding.llm_reranker.finetune_for_instruction.run \
--output_dir {path to save model} \
--model_name_or_path google/gemma-2b \
--train_data ./toy_finetune_data.jsonl \
--learning_rate 2e-4 \
--num_train_epochs 1 \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 16 \
--dataloader_drop_last True \
--query_max_len 512 \
--passage_max_len 512 \
--train_group_size 16 \
--logging_steps 1 \
--save_steps 2000 \
--save_total_limit 50 \
--ddp_find_unused_parameters False \
--gradient_checkpointing \
--deepspeed stage1.json \
--warmup_ratio 0.1 \
--bf16 \
--use_lora True \
--lora_rank 32 \
--lora_alpha 64 \
--use_flash_attn True \
--target_modules q_proj k_proj v_proj o_proj

对于基于 llm 的逐层重排序器

torchrun --nproc_per_node {number of gpus} \
-m FlagEmbedding.llm_reranker.finetune_for_layerwise.run \
--output_dir {path to save model} \
--model_name_or_path openbmb/MiniCPM-2B-dpo-bf16 \
--train_data ./toy_finetune_data.jsonl \
--learning_rate 2e-4 \
--num_train_epochs 1 \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 16 \
--dataloader_drop_last True \
--query_max_len 512 \
--passage_max_len 512 \
--train_group_size 16 \
--logging_steps 1 \
--save_steps 2000 \
--save_total_limit 50 \
--ddp_find_unused_parameters False \
--gradient_checkpointing \
--deepspeed stage1.json \
--warmup_ratio 0.1 \
--bf16 \
--use_lora True \
--lora_rank 32 \
--lora_alpha 64 \
--use_flash_attn True \
--target_modules q_proj k_proj v_proj o_proj \
--start_layer 8 \
--head_multi True \
--head_type simple \
--lora_extra_parameters linear_head

我们的重排序器是从 google/gemma-2b(用于基于 llm 的重排序器)和 openbmb/MiniCPM-2B-dpo-bf16(用于基于 llm 的逐层重排序器)初始化的,我们在混合多语言数据集上对其进行训练:

评估

  • llama-index.

image-20240317193909373

  • BEIR.
    对 bge-en-v1.5 large 的前 100 个结果进行重排序。

image-20240317174633333

对 e5 mistral 7b instruct 的前 100 个结果进行重排序。

image-20240317172949713

  • CMTEB-retrieval.
    对 bge-zh-v1.5 large 的前 100 个结果进行重排序。

image-20240317173026235

  • miracl (多语言).
    对 bge-m3 的前 100 个结果进行重排序。

image-20240317173117639

引用

如果您觉得这个仓库有用,请考虑点个 star 并引用

@misc{li2023making,
      title={Making Large Language Models A Better Foundation For Dense Retrieval}, 
      author={Chaofan Li and Zheng Liu and Shitao Xiao and Yingxia Shao},
      year={2023},
      eprint={2312.15503},
      archivePrefix={arXiv},
      primaryClass={cs.CL}
}
@misc{chen2024bge,
      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}
}

sudhanshu746/bge-reranker-v2-m3-quant-onnx

作者 sudhanshu746

↓ 7 ♥ 2

创建时间: 2024-08-20 12:46:46+00:00

更新时间: 2024-08-20 13:11:53+00:00

在 Hugging Face 上查看

文件 (10)

.gitattributes
README.md
config.json
model.onnx ONNX
model.onnx.data
ort_config.json
sentencepiece.bpe.model
special_tokens_map.json
tokenizer.json
tokenizer_config.json