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模型微调的数据集包含以下三组:
queries
:node_id
映射和LLM生成的问题的集合。corpus
:node_id
映射和相应节点中的文本的集合。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_transformers
的InformationRetrievalEvaluator
进行评估,因为它提供了一套更全面的指标。
微调Embedding模型似乎涉及到很多问题。幸运的是,LlamaIndex(我个人感觉LlamaIndex目前的发展可能会在RAG方面打败LangChain)在最近的0.8.21版本中引入以下关键类/函数,使得微调Embedding模型变得超级简单:
SentenceTransformersFinetuneEngine
generate_qa_embedding_pairs
EmbeddingQAFinetuneDataset
这些类和函数为我们抽象了底层的详细集成逻辑,使开发人员能够非常直观地调用它。
微调方法
为了可视化微调BAAI/big-small-en
所涉及的主要任务,让我们看看下图:
微调embedding整体思路
如图中的数值所示,主要任务包括:
- 通过调用
EmbeddingQAFinetuneDataset
函数generate_qa_embedding_pairs
,自动生成评估和训练数据集的数据。 - 通过传入基本模型和训练数据集来构造
SentenceTransformersFinetuneEngine
,然后调用其finetune
函数来训练基本模型。 - 创建经过微调的模型。
- 调用向量存储索引检索器检索相关节点并评估基本模型的命中率。
- 调用
InformationRetrievalEvaluator
来评估基本模型。 - 调用向量存储索引检索器检索相关节点并评估微调模型的命中率。
- 调用
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.pdfdef 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 nodesSEC_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
函数返回的节点,它为每个节点生成问题(默认为每个节点两个问题,可以自定义),然后用所有三组数据构建数据集:queries
,corpus
和relevant_docs
(queries
与corpus
之间的映射对应的node_id
)。
下面是样本训练数据集的样子。注意queries
和corpus
在截图中是折叠的,因为每个都有超过100个数据对:
样本训练数据集
Step 2: 微调Embedding模型
SentenceTransformersFinetuneEngine
就是为这个任务设计的。在底层,它执行多个子任务:
- 通过构建
SentenceTransformer
加载预训练模型,传入BAAI/big-small-en
模型id。 - 定义数据加载器。它加载我们的训练数据集,将其解析为
查询
,语料库
和relevant_docs
。然后循环查询,将relevant_docs
中的node_id
与corpus
中的文本节点进行映射,构造InputExample
,其列表依次传递到创建DataLoader
中. - 定义loss(损失函数)。它使用
sentence_transformers
multiplenegativerankingloss
来训练检索设置的Embeddings。 - 定义评估器。它设置了一个带有eval数据集的评估器来监控Embedding模型在训练期间的表现。
- 运行训练。它插入上面定义的数据加载器、损失函数和评估器来运行训练。
LlamaIndex将微调Embedding模型的所有详细子任务封装在一个SentenceTransformersFinetuneEngine
中,我们所需要做的就是调用它的finetune
函数。下面,您可以看到展示LlamaIndex的代码片段:
Step 3: 评估微调后的模型
如上所述,我们使用两种不同的评估方法:
- 命中率:对每个
query
/relevant_doc
对进行简单的top-k检索。如果搜索结果包含relevant_doc
,那么它就是一个“命中”。这可以用于专有的Embeddings,例如OpenAI的Embedding模型和开源Embedding模型。请参阅下面代码片段中的evaluate
函数。 InformationRetrievalEvaluator
:一个更全面的用于评估开源Embeddings的度量套件。请参阅下面代码片段中的evaluate_st
函数。
- 评测OpenAI
现在,让我们评估一下OpenAI的Embedding模型text-embedding-ada-002
。代码如下:
结果:
结果
- 评测
BAAI/bge-small-en
结果:
结果
- 评估微调后的model
查看结果:
结果比较
- 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管道中重新嵌入文档。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。