MTEB评估基准使用指北

介绍

  文本嵌入通常是在单一任务的少量数据集上进行评估,这些数据集未涵盖其可能应用于其他任务的情况,不清楚在语义文本相似性(semantic textual similarity, STS)等任务上的最先进嵌入是否同样适用于聚类或重排序等其他任务。这使得该领域的进展难以跟踪,因为不断有各种模型被提出,而没有进行适当的评估。
  为了解决这个问题,Hugging Face团队推出了大规模文本嵌入基准(Massive Text Embedding Benchmark, MTEB)。MTEB涵盖了8个嵌入任务,共58个数据集和112种语言,是目前迄今为止最全面的文本嵌入基准。
  MTEB源码:https://github.com/embeddings-benchmark/mteb
  MTEB论文:https://arxiv.org/abs/2210.07316
  MTEB排行榜:https://huggingface.co/spaces/mteb/leaderboard
  C-MTEB是当前最全面的中文语义向量评测基准,涵盖6大类评测任务(检索、排序、句子相似度、推理、分类、聚类),涉及35(31)个相关数据集。
  C-MTEB评估代码:https://github.com/FlagOpen/FlagEmbedding/tree/master/C_MTEB
  C-MTEB论文:https://arxiv.org/abs/2309.07597

评估数据

  由于众所周知的原因,Hugging Face官网访问无法直接,所以这篇文章提供了一个比较友好的代理方案来下载数据集。

  由于mteb1.12.4的版本中使用了ISO编码,导致task_langs参数不太好使了,这里暂时使用1.1.1版本。
  pip install mteb==1.1.1
  pip install C_MTEB

# -*- coding: utf-8 -*-
# Author  : liyanpeng
# Email   : yanpeng.li@cumt.edu.cn
# Datetime: 2024/5/28 18:23
# Filename: download_data.py
from mteb import MTEB

import os
import subprocess

os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
data_path = '/root/data3/liyanpeng/hf_data'

def show_dataset():
    evaluation = MTEB(task_langs=["zh", "zh-CN"])
    dataset_list = []
    for task in evaluation.tasks:
        if task.description.get('name') not in dataset_list:
            dataset_list.append(task.description.get('name'))
            desc = 'name: {}\t\thf_name: {}\t\ttype: {}\t\tcategory: {}'.format(
                task.description.get('name'), task.description.get('hf_hub_name'),
                task.description.get('type'), task.description.get('category'),
            )
            print(desc)
    print(len(dataset_list))

def download_dataset():
    evaluation = MTEB(task_langs=["zh", "zh-CN"])
    err_list = []
    for task in evaluation.tasks:
        # task.load_data()
        # https://huggingface.co/datasets/
        task_name = task.description.get('hf_hub_name')
        print(task_name)
        cmd = ['huggingface-cli', 'download', '--repo-type', 'dataset', '--resume-download',
               '--local-dir-use-symlinks', 'False', task_name, '--local-dir', os.path.join(data_path, task_name)]
        try:
            result = subprocess.run(cmd, check=True)
        except subprocess.CalledProcessError as e:
            err_list.append(task_name)
            print("{} is error".format(task_name))

    if err_list:
        print('download failed: \n', '\n'.join(err_list))
    else:
        print('download success.')

if __name__ == '__main__':
	download_dataset()
	show_dataset()

  一共是31个数据集:

在这里插入图片描述
在这里插入图片描述

评估模型

  使用C-MTEB来评估模型:

# -*- coding: utf-8 -*-
# Author  : liyanpeng
# Email   : yanpeng.li@cumt.edu.cn
# Datetime: 2024/7/14 13:04
# Filename: cmteb.py
from mteb import MTEB
from C_MTEB import ChineseTaskList, load_retrieval_data
from sentence_transformers import SentenceTransformer
from datasets import load_dataset
import os
from prettytable import PrettyTable


def print_table(task_names, scores):
    tb = PrettyTable()
    tb.field_names = task_names
    tb.add_row(scores)
    print(tb)


# os.environ['HF_DATASETS_CACHE'] = data_path
# os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'


if __name__ == '__main__': 
    data_path = '/root/data3/liyanpeng/hf_data'
    model_name = "/root/data3/emb_models/sensenova/piccolo-base-zh"
    
    model = SentenceTransformer(model_name)
    evaluation = MTEB(tasks=ChineseTaskList)
    for task in evaluation.tasks:
        if task.description.get('type') == 'Retrieval':
            task.corpus, task.queries, task.relevant_docs = load_retrieval_data(os.path.join(data_path, task.description["hf_hub_name"]),
                                                                                task.description['eval_splits'])
        else:
            dataset = load_dataset(
                path=os.path.join(data_path, task.description["hf_hub_name"]),
                revision=task.description.get("revision", None),
                # task_eval_splits=task.description.get("eval_splits", [])
            )
            task.dataset = dataset
        task.data_loaded = True
    results = evaluation.run(model, output_folder=f"zh_results/piccolo-base-zh")
    print(results)
<think>嗯,用户在使用Ollama部署了deepseek-R1模型,并且用AnythingLLM添加了本地知识库,但遇到了检索不精准的问题。首先,我需要分析可能的原因。本地知识库的检索问题通常涉及多个方面,比如文档处理、嵌入模型、分块策略、检索参数或者模型本身的限制。 用户可能已经正确加载了模型,但知识库的处理可能有问题。首先应该检查文档预处理。比如,文档是否被正确分割?分块的大小和重叠是否合适?如果分块太大,可能导致信息冗余;太小则可能丢失上下文。另外,是否清除了噪音数据,比如特殊字符或无关内容?这些都会影响检索效果。 接下来是嵌入模型的选择。AnythingLLM默认可能用了某个嵌入模型,但不同的模型在不同类型数据上表现不同。用户是否需要更换更适合自己数据类型的模型?比如,sentence-transformers里的模型可能更适用于特定语言或领域。另外,嵌入模型的维度是否匹配,如果维度不匹配,检索效果也会差。 然后是检索策略。AnythingLLM可能使用了余弦相似度或欧氏距离,用户是否调整过相似度阈值?提高阈值可以过滤掉不相关的结果,但可能漏掉部分相关。检索返回的结果数量是否足够?太少的话可能错过正确答案,太多则引入噪音。 模型本身的限制也可能导致问题。deepseek-R1作为基座模型,可能在处理长上下文或复杂查询时有局限。用户是否在查询时提供了足够的上下文?或者需要调整提示词,让模型更明确地依赖知识库内容。 另外,知识库内容的覆盖范围是否全面?如果知识库中的数据不够或与查询不相关,检索自然不准确。测试时是否尝试过简单查询验证基础功能?比如直接引用知识库中的内容,看是否能正确检索到。 还有版本和配置问题。Ollama和AnythingLLM的版本是否最新?有时候软件更新会修复已知问题。配置文件中是否有参数需要调整,比如top_k或温度参数? 用户可能没有详细说明具体症状,比如是完全检索不到还是部分不准,或者返回无关结果。可能需要建议用户检查日志,看看检索过程中是否有错误,或者观察分块后的内容是否符合预期。 最后,如果所有步骤都正确,可能需要进一步优化,比如微调嵌入模型或调整模型推理参数。或者考虑其他工具如LangChain进行更灵活的流程控制。</think>在使用本地知识库结合大模型(如deepseek-R1)时遇到检索精度问题,可能涉及多个环节的配置或数据质量问题。以下是逐步排查和优化的方向: --- ### **1. 检查知识库预处理环节** - **文档分块策略** - 分块大小(chunk_size):建议根据内容类型调整(如技术文档适合512-1024字符,对话记录适合200-400字符)。 - 分块重叠(overlap):保留10-15%的重叠内容避免上下文断裂(例如分块大小1024时,重叠约150字符)。 - 尝试使用智能分块工具(如`langchain.text_splitter.RecursiveCharacterTextSplitter`)替代基础分块。 - **元数据标注** - 为每个分块添加标题、关键词、文档来源等元数据,可显著提升后续检索匹配度。 - **数据清洗** - 移除HTML标签、乱码、页眉页脚等噪音数据。 - 对PDF文档需检查OCR识别错误(尤其是扫描版PDF)。 --- ### **2. 优化嵌入模型(Embedding Model)** - **模型选择** - 默认的`all-MiniLM-L6-v2`适合英文,中文建议换用: - `paraphrase-multilingual-mpnet-base-v2`(多语言高精度) - `text2vec-base-chinese`(专为中文优化) - 通过[HuggingFace MTEB排行榜](https://huggingface.co/spaces/mteb/leaderboard)选择适合任务的模型。 - **本地部署嵌入模型** ```python # 示例:在AnythingLLM中替换嵌入模型 from sentence_transformers import SentenceTransformer embedder = SentenceTransformer('paraphrase-multilingual-mpnet-base-v2') ``` --- ### **3. 调整检索策略** - **相似度算法** - 测试余弦相似度(cosine) vs 欧氏距离(L2),通常余弦更适合文本。 - **混合检索(Hybrid Search)** - 结合关键词检索(如BM25)与向量检索,缓解语义模糊问题: ```python # 伪代码示例 keyword_results = bm25_search(query) vector_results = vector_db.search(query_embedding) fused_results = fuse_results(keyword_results, vector_results) ``` - **重排序(Reranking)** 使用交叉编码器(如`bge-reranker-base`)对Top100结果重新排序: ```python from FlagEmbedding import FlagReranker reranker = FlagReranker('BAAI/bge-reranker-base', use_fp16=True) scores = reranker.compute_score([[query, chunk] for chunk in candidates]) ``` --- ### **4. 验证知识库与查询的匹配性** - **测试基础案例** 构造一个完全匹配知识库内容的查询(如直接复制某段文字的前半句),观察是否能返回正确分块。 - **分析Bad Cases** 记录失败案例,检查: - 问题是否在知识库中有明确答案 - 分块是否丢失关键信息(如表格被拆散) - 相似分块是否过多导致干扰 --- ### **5. 调整模型交互提示词** - **强制引用知识库** 在prompt中明确要求模型优先基于知识库回答: ```markdown 你是一个专业助手,请严格根据提供的知识库内容回答问题。 如果知识库中没有相关信息,请回答“根据现有资料无法确定”。 知识库内容: {context} 问题:{question} ``` - **增加拒绝机制** 当检索置信度低于阈值时,让模型主动拒绝回答而非猜测。 --- ### **6. 技术栈替代方案** 如果问题持续存在,可尝试: - 用**LlamaIndex**替换知识库组件,其提供更灵活的数据连接器和检索逻辑。 - 使用**ChromaDB**或**Qdrant**替代默认向量数据库,支持元数据过滤等高级查询。 - 对关键业务场景微调嵌入模型(需准备正负样本对)。 --- ### **关键日志检查点** 1. 观察知识库加载日志,确认文档解析无误。 2. 检查检索阶段返回的相似度分数分布(是否普遍低于0.6)。 3. 在Ollama启动命令中添加`--verbose`参数查看推理过程细节。 通过逐步验证每个环节的数据流转,通常可以定位到具体瓶颈。建议从一个小型精准知识库(如10个文档)开始测试,逐步扩展到全量数据。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏小悠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值