您当前的位置:首页 > 电脑百科 > 人工智能

手工微调embedding模型,让RAG应用检索能力更强

时间:2023-09-27 14:59:50  来源:微信公众号  作者:土猛的员外

在RAG应用中,有一个我们可以去提升的环节就是——Embedding模型,我在之前的文章《大模型主流应用RAG的介绍——从架构到技术细节》也说过可以去微调embedding模型以便增强我们整体的检索能力。

最早我们用的是AI target=_blank class=infotextkey>OpenAI的Embedding模型text-embedding-ada-002,但这个模型后面不一定可以在正式环境中使用,而且我们也没办法去微调,因此让我们在本文中探索对开源Embedding模型进行微调。

BAAI/bge-small-en

目前HuggingFace的MTEB(海量文本Embedding基准)排行榜上排名第一的Embedding模型是big-large-en,它由北京人工智能研究院(BAAI,智源)开发。它是一种预训练的transformer模型,可用于各种自然语言处理任务,如文本分类、问答、文本生成等。该模型在海量文本和代码数据集上进行训练,并在海量文本Embedding基准(MTEB)上进行了微调。

在本文中,我们将使用 big-large-en的缩小版big-small-en,这是一个384维的小规模模型(OpenAI是1500+维),具有竞争力的性能,非常适合在google Colab中运行。大家也可以选择中文版的bge-base-zh-v1.5,只有0.1G。当然你的硬件环境允许,也可以使用1.3G的bge-large-zh-v1.5等embedding模型。

微调Embedding模型与微调LLM

与LLM(大语言模型)微调相比,big-small-en微调的实现有一些不一样,下面简单说一下异同点:

相似点

  • 两种类型的微调都遵循相同的方法,即生成用于训练和评估的数据集,微调模型,最后评估基本模型和微调模型之间的性能。
  • 使用LLM自动生成训练和评估数据集。

不同点

  • 数据集内容在LLM微调和Embedding模型微调之间有所不同。用于LLM微调的数据集包含LLM生成的问题。在微调过程中,包括问题、答案、系统prompt等在内的一系列数据将以JSON行( jsonl)文件的形式传递给要进行微调的模型。

不同的是,用于Embedding模型微调的数据集包含以下三组:

  1. queriesnode_id映射和LLM生成的问题的集合。
  2. corpusnode_id映射和相应节点中的文本的集合。
  3. relevant_docs:查询的node_id和语料库 node_id之间的交叉引用映射的集合。给定一个查询,它告诉Embedding模型要查找哪个文本节点/语料库。
  • 由于我们使用开源Embedding模型bge-small-en ,微调的前提就是要先把它下载到您的本地环境。以Google Colab为例,经过微调的模型将被下载到笔记本的根目录中。
  • 评估方法在微调Embedding模型和微调LLM之间有所不同,我们可以使用Ragas框架来衡量精准度和答案相关性。然而,当使用Embedding模型微调时,我们无法测量答案的正确性,因为我们只能为我们的问题检索相关节点。相反,我们使用一个称为“命中率”的简单度量,这意味着对于每个(query, relevant_doc)对,我们用查询检索top-k文档,如果结果包含relevant_doc,则它被认为是“命中”的。该指标可用于专有Embeddings,如OpenAI的Embedding模型和开源Embedding模型。对于开源Embedding模型,我们还可以使用来自sentence_transformersInformationRetrievalEvaluator进行评估,因为它提供了一套更全面的指标。

微调Embedding模型似乎涉及到很多问题。幸运的是,LlamaIndex(我个人感觉LlamaIndex目前的发展可能会在RAG方面打败LangChain)在最近的0.8.21版本中引入以下关键类/函数,使得微调Embedding模型变得超级简单:

  • SentenceTransformersF.NETuneEngine
  • generate_qa_embedding_pairs
  • EmbeddingQAFinetuneDataset

这些类和函数为我们抽象了底层的详细集成逻辑,使开发人员能够非常直观地调用它。

微调方法

为了可视化微调BAAI/big-small-en所涉及的主要任务,让我们看看下图:

微调embedding整体思路

如图中的数值所示,主要任务包括:

  1. 通过调用 EmbeddingQAFinetuneDataset函数generate_qa_embedding_pairs,自动生成评估和训练数据集的数据。
  2. 通过传入基本模型和训练数据集来构造SentenceTransformersFinetuneEngine,然后调用其finetune函数来训练基本模型。
  3. 创建经过微调的模型。
  4. 调用向量存储索引检索器检索相关节点并评估基本模型的命中率。
  5. 调用InformationRetrievalEvaluator来评估基本模型。
  6. 调用向量存储索引检索器检索相关节点并评估微调模型的命中率。
  7. 调用InformationRetrievalEvaluator来评估经过微调的模型。

基于LlamaIndex的微调Embeddings指南(文末有链接),我们将在我们的用例中微调bge-small-en模型。

实现细节

Step 1: 生成数据集

让我们使用LLM来自动生成训练和评估的数据集。

  • Load corpus

在我们的用例中NVIDIA的SEC 10-K文件(代码中和文末都有链接)是一个169页的PDF文档(你可以用你自己的中文PDF),所以我们需要在生成数据集时将文档分成两部分——一部分用于训练数据集,另一部分用于evalals数据集。

使用单独的数据集进行训练和评估被认为是一种很好的ML实践。可以调用load_corpus函数来收集训练数据集(前90页)或eval数据集(其余页面)的节点。下面是load_corpus的代码片段:

!curl https://d18rn0p25nwr6d.cloudfront.net/CIK-0001045810/4e9abe7b-fdc7-4cd2-8487-dc3a99f30e98.pdf --output nvidia-sec-10k-2022.pdf

def load_corpus(docs, for_training=False, verbose=False):
    parser = SimpleNodeParser.from_defaults()
    if for_training:
        nodes = parser.get_nodes_from_documents(docs[:90], show_progress=verbose)
    else:
        nodes = parser.get_nodes_from_documents(docs[91:], show_progress=verbose)

    if verbose:
        print(f'Parsed {len(nodes)} nodes')

    return nodes

SEC_FILE = ['nvidia-sec-10k-2022.pdf']

print(f"Loading files {SEC_FILE}")

reader = SimpleDirectoryReader(input_files=SEC_FILE)
docs = reader.load_data()
print(f'Loaded {len(docs)} docs')

train_nodes = load_corpus(docs, for_training=True, verbose=True)
val_nodes = load_corpus(docs, for_training=False, verbose=True)

请记住,在LlamaIndex中,节点和页面并不完全匹配。对于一个169页的文档,结果显示它为训练数据集解析了97个节点,为evals数据集解析了91个节点。这两个数据集的节点数量足够接近。让我们继续。

 
  • 生成合成查询和数据集

现在,让我们生成训练和评估的数据集。请注意,我们这里没有传递LLM (gpt-3.5-turbo-0613),只有OpenAI API密钥。这是因为LlamaIndex的默认LLM是gpt-3.5-turbo-0613;如果没有定义LLM,只要提供OpenAI API密钥,则默认为它。

generate_qa_embedding_pairs是一个生成数据集的方便函数。基于上面load_corpus函数返回的节点,它为每个节点生成问题(默认为每个节点两个问题,可以自定义),然后用所有三组数据构建数据集:queriescorpusrelevant_docs(queriescorpus之间的映射对应的node_id)。

from llama_index.finetuning import (
    generate_qa_embedding_pairs,
    EmbeddingQAFinetuneDataset,
)
from llama_index.llms import OpenAI

os.environ["OPENAI_API_KEY"] = "sk-############"
openai.api_key = os.environ["OPENAI_API_KEY"]

train_dataset = generate_qa_embedding_pairs(train_nodes)
val_dataset = generate_qa_embedding_pairs(val_nodes)

train_dataset.save_json("train_dataset.json")
val_dataset.save_json("val_dataset.json")

train_dataset = EmbeddingQAFinetuneDataset.from_json("train_dataset.json")
val_dataset = EmbeddingQAFinetuneDataset.from_json("val_dataset.json")

下面是样本训练数据集的样子。注意queriescorpus在截图中是折叠的,因为每个都有超过100个数据对:

样本训练数据集

Step 2: 微调Embedding模型

SentenceTransformersFinetuneEngine就是为这个任务设计的。在底层,它执行多个子任务:

  • 通过构建SentenceTransformer加载预训练模型,传入BAAI/big-small-en模型id。
  • 定义数据加载器。它加载我们的训练数据集,将其解析为查询语料库relevant_docs。然后循环查询,将relevant_docs中的node_idcorpus中的文本节点进行映射,构造InputExample,其列表依次传递到创建DataLoader中.
  • 定义loss(损失函数)。它使用sentence_transformers multiplenegativerankingloss来训练检索设置的Embeddings。
  • 定义评估器。它设置了一个带有eval数据集的评估器来监控Embedding模型在训练期间的表现。
  • 运行训练。它插入上面定义的数据加载器、损失函数和评估器来运行训练。

LlamaIndex将微调Embedding模型的所有详细子任务封装在一个SentenceTransformersFinetuneEngine中,我们所需要做的就是调用它的finetune函数。下面,您可以看到展示LlamaIndex的代码片段:

from llama_index.finetuning import SentenceTransformersFinetuneEngine

finetune_engine = SentenceTransformersFinetuneEngine(
    train_dataset,
    model_id="BAAI/bge-small-en",
    model_output_path="test_model",
    val_dataset=val_dataset,
)

finetune_engine.finetune()

embed_model = finetune_engine.get_finetuned_model()

Step 3: 评估微调后的模型

如上所述,我们使用两种不同的评估方法:

  • 命中率:对每个query / relevant_doc对进行简单的top-k检索。如果搜索结果包含relevant_doc,那么它就是一个“命中”。这可以用于专有的Embeddings,例如OpenAI的Embedding模型和开源Embedding模型。请参阅下面代码片段中的evaluate函数。

  • InformationRetrievalEvaluator:一个更全面的用于评估开源Embeddings的度量套件。请参阅下面代码片段中的evaluate_st函数。

from llama_index.embeddings import OpenAIEmbedding
from llama_index import ServiceContext, VectorStoreIndex
from llama_index.schema import TextNode
from tqdm.notebook import tqdm
import pandas as pd

# function for hit rate evals
def evaluate(
    dataset,
    embed_model,
    top_k=5,
    verbose=False,
):
    corpus = dataset.corpus
    queries = dataset.queries
    relevant_docs = dataset.relevant_docs

    service_context = ServiceContext.from_defaults(embed_model=embed_model)
    nodes = [TextNode(id_=id_, text=text) for id_, text in corpus.items()]
    index = VectorStoreIndex(nodes, service_context=service_context, show_progress=True)
    retriever = index.as_retriever(similarity_top_k=top_k)

    eval_results = []
    for query_id, query in tqdm(queries.items()):
        retrieved_nodes = retriever.retrieve(query)
        retrieved_ids = [node.node.node_id for node in retrieved_nodes]
        expected_id = relevant_docs[query_id][0]
        is_hit = expected_id in retrieved_ids  # assume 1 relevant doc

        eval_result = {
            "is_hit": is_hit,
            "retrieved": retrieved_ids,
            "expected": expected_id,
            "query": query_id,
        }
        eval_results.Append(eval_result)
    return eval_results


from sentence_transformers.evaluation import InformationRetrievalEvaluator
from sentence_transformers import SentenceTransformer

def evaluate_st(
    dataset,
    model_id,
    name,
):
    corpus = dataset.corpus
    queries = dataset.queries
    relevant_docs = dataset.relevant_docs

    evaluator = InformationRetrievalEvaluator(queries, corpus, relevant_docs, name=name)
    model = SentenceTransformer(model_id)
    return evaluator(model, output_path="results/")
  • 评测OpenAI

现在,让我们评估一下OpenAI的Embedding模型text-embedding-ada-002。代码如下:

ada = OpenAIEmbedding()
ada_val_results = evaluate(val_dataset, ada)

df_ada = pd.DataFrame(ada_val_results)

hit_rate_ada = df_ada['is_hit'].mean()

结果:

结果
 
  • 评测BAAI/bge-small-en
bge = "local:BAAI/bge-small-en"
bge_val_results = evaluate(val_dataset, bge)

df_bge = pd.DataFrame(bge_val_results)

hit_rate_bge = df_bge['is_hit'].mean()

evaluate_st(val_dataset, "BAAI/bge-small-en", name='bge')

结果:

结果
  • 评估微调后的model
finetuned = "local:test_model"
val_results_finetuned = evaluate(val_dataset, finetuned)

df_finetuned = pd.DataFrame(val_results_finetuned)

hit_rate_finetuned = df_finetuned['is_hit'].mean()

evaluate_st(val_dataset, "test_model", name='finetuned')

查看结果:

结果比较
  • Summary of results

把评测结果放在一起,让我们仔细看看。

命中率:我们的微调模型比其基本模型bge-small-en的性能提高了1.29%。与OpenAI的Embedding模型相比,我们的微调模型的性能仅低了4.85%。

与另外两个模型的比较
 

InformationRetrievalEvaluator结果:经过微调的模型比其基本模型的性能提高了5.81%。与基本模型相比,微调模型对这30多个指标列中的每一个都有更好的数字。

微调之后各指标的结果
 

总结

在本文中,我们探讨了微调RAG管道的Embedding模型所涉及的步骤。我们使用开源的sentence_transformers模型BAAI/big-small-en作为我们的基本Embedding模型,介绍了如何生成用于训练和评估的数据集,如何对其进行微调,以及如何评估基本模型和微调模型之间的性能差异。

评估结果表明,微调Embedding模型的性能比基本模型提高了1-6%,与OpenAI的Embedding模型相比,微调模型的性能损失仅为4.85%。这种性能提升可能因数据集的质量和数量而异。

我们还简要探讨了LlamaIndex的最新版本,该版本对任何Embedding模型的线性适配器进行了微调,从而提高了性能并避免了在RAG管道中重新嵌入文档。



Tags:模型   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
AI程序员上岗 垂类大模型应用迎来井喷期
能自动写代码的“AI员工”、逐渐告别不够好用的智能客服,无需费时费力开发的工业AI控制器……随着人工智能大模型能力开始深入多个行业,IT、工业生产、金融、服务...【详细内容】
2024-04-07  Search: 模型  点击:(3)  评论:(0)  加入收藏
AI干掉声优?音频大模型追逐“图灵时刻”
七十年前,“人工智能之父”图灵提出,如果人无法判断屏幕的另一侧究竟是人还是机器,就证明机器具备了人一样的智能。这一经典的图灵测试如同北斗星一般,指引着AI行业的工作者们不...【详细内容】
2024-04-03  Search: 模型  点击:(5)  评论:(0)  加入收藏
大模型Kimi火了,长文本“卷”出新高度
近日,AI智能助手Kimi宣布支持200万字无损上下文,在长上下文窗口技术上再次取得突破,引燃人工智能领域新一轮投资热情。  摄影/宁颖OpenAI官方去年11月发布的GPT-4 Turbo,支持1...【详细内容】
2024-03-29  Search: 模型  点击:(13)  评论:(0)  加入收藏
大模型应用的 10 种架构模式
作者 | 曹洪伟在塑造新领域的过程中,我们往往依赖于一些经过实践验证的策略、方法和模式。这种观念对于软件工程领域的专业人士来说,已经司空见惯,设计模式已成为程序员们的重...【详细内容】
2024-03-27  Search: 模型  点击:(13)  评论:(0)  加入收藏
Sora超逼真视频引恐慌!Nature刊文警示AI视频模型,或在2024年颠覆科学和社会
新智元报道编辑:LRS【新智元导读】王炸Sora发布后,想要分辨AI视频和真实视频变得更难了,各行各业都面临新的挑战与危机。‍技术的发展总是伴随着被滥用的风险,从ChatGPT到最...【详细内容】
2024-03-27  Search: 模型  点击:(19)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  Search: 模型  点击:(8)  评论:(0)  加入收藏
超长文本是AI大模型的能力突破口吗?
◎记者 刘怡鹤近日,能“一口气读完20万字小说”的AI大模型应用Kimi再次为国内AI产业添了一把火。业内认为,国产大模型能力提升或成今年国内AI领域最核心的主线。超长上下文是...【详细内容】
2024-03-26  Search: 模型  点击:(8)  评论:(0)  加入收藏
百度AI“咬”了一口苹果 大模型商用有戏了?
百度3月25日突传利好。据知情人士透露,百度将为苹果今年发布的iPhone16、Mac系统和ios18提供AI功能。消息人士称,苹果曾与阿里以及另外一家国产大模型公司进行过洽谈,最后确定...【详细内容】
2024-03-26  Search: 模型  点击:(18)  评论:(0)  加入收藏
Kimi引燃大模型“长文本竞赛”,阿里360百度急出手
从ChapGPT到Sora,从数千亿参数到千万长文本,大模型浪潮下,永远不缺热点。近日,“Kimi概念股暴涨”“Kimi为宕机道歉”等词条先后冲上微博热搜,让月之暗面这家刚成立一年的人工智...【详细内容】
2024-03-25  Search: 模型  点击:(15)  评论:(0)  加入收藏
Kimi爆了 国产大模型应用元年还远吗?
国产大模型应用Kimi近日可谓横空出世。根据Similarweb数据,Kimi智能助手的周度访问量由23年12月初的15万提升至近期(3.10-3.16)的超过200万,APP端下载量也快速提升,从2月初的效率...【详细内容】
2024-03-22  Search: 模型  点击:(14)  评论:(0)  加入收藏
▌简易百科推荐
藏在AI背后的“吃电狂魔”
人工智能时代的能耗黑洞据估算,到2027年,人工智能行业每年将消耗85~134太瓦时的电力,相当于瑞典或荷兰一年的总用电量。马斯克判断,电力缺口最早可能会在2025年发生,“明年你会看...【详细内容】
2024-04-09    雪豹财经社  Tags:AI   点击:(1)  评论:(0)  加入收藏
OpenAI和谷歌再起纷争:AI的尽头是内容
日前,纽约时报的一篇报道称,人工智能公司 OpenAI为收集高质量训练数据而开发了一个语音转录模型Whisper。该模型主要用于转录 OpenAI 获取的超过 100 万小时的 YouTube 视频,也...【详细内容】
2024-04-09  小编也疯狂  新浪网  Tags:AI   点击:(1)  评论:(0)  加入收藏
AI产业的灰色暗面:OpenAI、谷歌、META如何搞训练语料
财联社4月7日讯(编辑 史正丞)种种迹象显示,目前站在全世界AI领域潮头浪尖的这些公司,早在几年前就已经陷入对训练语料的“绝望”追逐中——为此他们不惜修改政策条款...【详细内容】
2024-04-09    财联社  Tags:AI产业   点击:(1)  评论:(0)  加入收藏
和“数字人”交朋友,当心隐私被出卖......
在虚拟社交中如何在保护用户隐私和数据安全的同时提供高质量的社交体验?如何避免过度依赖虚拟社交找到虚拟与真实之间的平衡点?《中国消费者报》记者就此展开了调查APP里有个...【详细内容】
2024-04-09    中国消费者报  Tags:数字人   点击:(2)  评论:(0)  加入收藏
AI“复活”成产业链:成本可降至数百元
大模型应用落地,带火数字人(11.560, 0.29, 2.57%)赛道。文|《中国企业家》记者李艳艳 实习生 孙欣编辑|姚赟头图来源|《流浪地球2》电影画面截图清明节前,预估会有需求的庞立...【详细内容】
2024-04-09    中国企业家  Tags:AI“复活”   点击:(2)  评论:(0)  加入收藏
多方热议人工智能产业新机遇
编者按  从前沿科技展会到高层对话平台,从上海、重庆到博鳌,从线上到线下……一场场高规格、大规模的盛会中,人工智能正在成为各界热议的高频词。赋能千...【详细内容】
2024-04-08    中国家电网  Tags:人工智能   点击:(4)  评论:(0)  加入收藏
​人形机器人时代来了吗
日前,由中国人形机器人(11.080, -0.05, -0.45%)百人会主办的人形机器人大赛在北京经济技术开发区开赛。工作人员向参观者展示一款人形机器人。参观者与一款陪护型人形机器人...【详细内容】
2024-04-08    中国青年报  Tags:​人形机器人   点击:(5)  评论:(0)  加入收藏
AI重塑社交:腾讯与字节跳动的新赛场
文|新火种 一号编辑|美美最近,腾讯和字节跳动这两大互联网巨头几乎同步推出了各自的AI社交产品,尽管腾讯和字节跳动在前段时间刚刚“破冰”,但这一举措不仅意味着这两大巨头之...【详细内容】
2024-04-07    蓝鲸财经  Tags:AI   点击:(8)  评论:(0)  加入收藏
第一批用 Kimi 做内容的网红已经杀疯了
作者:王东东 文章来自:斗战圣佛小组技术信仰派 VS 市场信仰派 朱啸虎和月之暗面老板杨植麟在前几天有一场不算 battle 的 battle。battle 的争论点是:大模型有没有戏。技术派...【详细内容】
2024-04-04    斗战圣佛小组  Tags:Kimi   点击:(4)  评论:(0)  加入收藏
昆仑万维发布面向人工智能时代的六条人才宣言
过去的一年多,是人工智能取得非凡进步的一年。在这充满突破性技术飞跃和备受争议的一年里,我们见证了人工智能的快速发展和广泛的影响,人工智能已经迅速地融入了我们的生活,深刻...【详细内容】
2024-04-03    砍柴网  Tags:昆仑万维   点击:(7)  评论:(0)  加入收藏
站内最新
站内热门
站内头条