高级RAG(五):TruLens 评估-扩大和加速LLM应用程序评估

之前我们介绍了,RAGAs评估,今天我们再来介绍另外一款RAG的评估工具:TruLens , trulens是TruEra公司的一款开源软件工具,它可帮助您使用反馈功函数客观地评估基于 LLM 的应用程序的质量和有效性。反馈函数有助于以编程方式评估输入、输出和中间结果的质量,以便我们可以加快和扩大实验评估,并将其用于各种应用场景,包括问答、检索增强生成和基于代理的应用程序。

一、核心概念

1.1 反馈函数

反馈函数,类似于标记函数,提供了一种在应用程序运行时生成评估的编程方法。TruLens的反馈函数的实现包装了一个受支持的提供者模型,比如一个相关性模型或一个情感分类器,它被重新用于提供评估。通常,为了获得最大的灵活性,这个模型也可以是另一个LLM。

在两个维度上考虑评估范围是非常有用的:可扩展性(Scalable)和有意义(Meaningful)。

领域专家评估(Ground Truth Evals)

在早期开发阶段,我们建议从领域专家评估开始。这些评估通常是由开发人员自己完成的,代表了你的应用程序期望完成的核心用例。这让你能够更深入地了解应用的性能,但却缺乏规模性。

用户反馈(人工)评估(Human Evals)

在你完成了早期评估并对你的应用获得更多信心后,收集人们的反馈通常是有用的。这通常以用户提供的二元(上/下)反馈的形式出现。这比基本事实(Ground Truth)的可扩展性稍强,但与方差作斗争,并且收集起来仍然很昂贵。

传统 NLP 评估(Traditional NLP Evals)

传统的 NLP 指标进行评估是一种常见的做法,例如 BLEU 和 ROUGE。虽然这些评估具有极高的可扩展性,但它们通常过于语法化,并且无法提供有关应用程序性能的有意义的信息。

中等语言模型评估(MLM Evals)

中等语言模型(如BERT)是LLM应用评估的最佳选择。这种规模的模型运行起来相对便宜(可扩展),还可以为你的应用提供细微的、有意义的反馈。在某些情况下,这些模型需要进行微调,以便为你的领域提供正确的反馈。

TruLens提供了许多开箱即用的反馈功能,这些功能依赖于这种模型风格,如基础NLI、情感、语言匹配、适度等。

大型语言模型评估(LLM Evals)

大型语言模型也可以为LLM应用程序的性能提供有意义和灵活的反馈。通常通过简单的提示,基于LLM的评估可以提供与人类非常一致的有意义的评估。此外,它们可以很容易地用LLM提供的推理来扩展,以证明对调试有用的高或低评估分数。

根据LLM的规模和性质,这些评估在规模上可能相当昂贵。

1.2 RAG三元组

为了避免LLM产生幻觉,RAG已经成为为LLM提供上下文(Context)的标准架构。然而,即使是RAG也会产生幻觉,因为当检索器无法检索到足够的上下文,甚至检索到不相关的上下文,然后将其传送给LLM后,LLM也可能产生幻觉。

TruEra创新的使用了RAG三元组来评估RAG架构的每条边的幻觉,如下所示:

 RAG 三元组由 3 个评估组件组成:上下文相关性(Context Relevance)、基础性(Groundedness)和答案相关性(Answer Relevance)。 

上下文相关性(Context Relevance)

任何 RAG 应用程序的第一步都是检索;为了验证检索的质量,我们希望确保每个检索到的上下文文档块(Context)都与输入查询(question)相关。这一点至关重要,因为LLM将使用此Context来形成答案(answer),因此Context中任何不相关的信息都可能会被编织成幻觉。TruLens 使您能够使用序列化记录的结构来评估上下文相关性。

基础性(Groundedness)

在检索上下文之后,然后由LLM将其形成答案。LLM往往倾向于偏离所提供的事实,夸大或扩展到一个听起来正确的答案。为了验证我们的应用程序的基础性(groundedness),我们可以将LLM产生的答案(answer)分成单独的主张(claims),并在检索的上下文(Context)中独立地搜索支持每个主张的证据。

答案相关性(Answer Relevance)

最后,我们的答案(answer)仍然需要有助于回答最初的问题。我们可以通过评估最终答案与用户输入(question)的相关性来验证这一点。

将它们组合在一起

如果我们对这个三元组进行评估后获得了满意的结果, 我们可以明确的说我们的应用程序经验证在其知识库的限制范围内不会出现幻觉。 换句话说,如果向量数据库包含的信息时准确的,那么RAG提供的答案也是准确的。

二、基本的RAG管道

2.1 基本的RAG管道介绍

在进行TruLens评估之前,我们首先回顾一下基本的RAG架构:

在基本RAG架构中包含了文档数据的处理,文档内容检索、LLM应答等环节,其中文档数据处理包含了文档的分割,向量化处理,向量数据库存储等步骤,而文档内容检索又包含了对向量数据库内容的相似度搜索,获取top_k个相关文档等步骤,然后将相关文档(context)和用户问题传送给LLM并产生最终的答案(answer), 如果对这些过程和步骤还不熟悉的朋友可以看一下我之前写的使用langchain与你自己的数据对话系列博客。接下来我们要使用llamaIndex开发一个基本RAG应用程序,并使用TruLens的RAG三元组对其进行评估。

2.2 环境配置

我们首先需要安装如下python包:

pip install llama_hub 
pip install llama_index
pip install trulens-eval

接下来我们需要做一些初始化的工作,比如导入openai,gemini等大模型的api_key:

import os
from dotenv import load_dotenv, find_dotenv#导入.env配置文件
_ = load_dotenv(find_dotenv()) 

2.3 加载文档数据

今天我们同样使用上一篇博客:RAGAs评估 中的相同数据即从百度百科的网页中抓取关于恐龙的文章:

这里我们使用的是LlamaIndex 的数据爬虫工具:TrafilaturaWebReader

from llama_index.readers.web import TrafilaturaWebReaderurl="https://baike.baidu.com/item/恐龙/139019"
docs = TrafilaturaWebReader().load_data([url])docs

2.4 切割文档

接下来我们要对该文档进行切割,我们首先需要创建一个文档切割器:

from llama_index.node_parser import SimpleNodeParser
from llama_index.schema import IndexNode#创建文档切割器
node_parser = SimpleNodeParser.from_defaults(chunk_size=1024)node_parser

 这里我们创建了一个简单的文档切割器,并且将chunk_sez设置为1024,这样我们被切割出来的文档块长度将会在1024左右。

#切割文档
base_nodes = node_parser.get_nodes_from_documents(docs)
len(base_nodes)

这里我们看到,原来的文档被切割成了30个文档块,下面我们看一下文档块中的内容:

base_nodes[5]

2.5 设置Embedding 和 LLM

接下来我们要设置一些基础组件,其中包括:embedding模型,llm,service_context,这里我们的embedding模型选择的是开源的bge-small-zh-v1.5模型,llm选择的是openai的gpt-3.5-turbo模型,当然你也可以选择gemini模型:

from llama_index.embeddings import resolve_embed_model
from llama_index import VectorStoreIndex, ServiceContext
from llama_index.llms import OpenAI
#from llama_index.llms import Gemini#创建BAAI的embedding
embed_model = resolve_embed_model("local:BAAI/bge-small-zh-v1.5")#创建OpenAI的llm
llm = OpenAI(model="gpt-3.5-turbo")#创建谷歌gemini的llm
# llm = Gemini()service_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model
)

2.6 创建 Index, retriever, query engine

#创建index
base_index = VectorStoreIndex(base_nodes, service_context=service_context)
#创建检索器
base_retriever = base_index.as_retriever(similarity_top_k=2)#检索相关文档
retrievals = base_retriever.retrieve("恐龙是冷血动物吗?"
)

接下来我们可以查看和问题:"恐龙是冷血动物吗?"相关的文档:

from llama_index.response.notebook_utils import display_source_nodefor n in retrievals:display_source_node(n, source_length=1500)

这里我们看到由于我们在创建检索器的时候设置了similarity_top_k=2,即让检索器每次都返回2个与用户问题相似度最高的文档,在上面的返回结果中我们同时还看到检索器除了返回相关node的内容(Text)以外,还返回了Node Id,相似度值Similarity。接下来我们要请出大模型ChatGPT根据检索器返回的相关文档来回答用户的问题,下面我们看看ChatGPT的回答:

#openai的回答
response = query_engine_base.query("恐龙是冷血动物吗?"
)
print(str(response))

 这里我们看到chatgpt模型在这两个相关文档的基础上归纳出了一个比较完整的且对用户友好的答案。

 三、TruLens 评估

3.1 什么是反馈函数

反馈函数的作用是在审查 LLM 应用程序的输入,输出和中间结果后给出一个分数。下面我们要定义一个评估器对象,和一个provider,其中评估器对象会初始化一个数据库,该数据库用来存储prompt、reponse、中间结果等信息。provider则用来执行反馈功能。

from trulens_eval import Tru
from trulens_eval import OpenAI as fOpenAI
import nest_asyncio#设置线程的并发执行
nest_asyncio.apply()#创建评估器对象
tru = Tru()
#初始化数据库,它用来存储prompt、reponse、中间结果等信息。
tru.reset_database()#定义一个provider用来执行反馈
provider = fOpenAI()

 接下来我们需要定义Answer Relevance、Context Relevance、Groundedness等3个反馈函数。

3.2 答案相关性(Answer Relevance)

Answer Relevance评估的是最终的答案(answer)与用户的问题(question)相关程度。它的主要结构如下图所示:

 下面我们来定义一个Answer Relevance反馈函数

from trulens_eval import Feedbackf_qa_relevance = Feedback(provider.relevance_with_cot_reasons,name="Answer Relevance"
).on_input_output()

3.3 上下文相关性(Context Relevance)

Context Relevance评估的是检索出来的上下文(Context )与用户的问题(question)相关程度。由于我们会设置检索器返回的检索结果的数量(如similarity_top_k), 所以在计算Context Relevance指标时会对返回的多个上下文取平均值。

下面我们来定义一个Context Relevance反馈函数 

import numpy as np
from trulens_eval import TruLlamacontext_selection = TruLlama.select_source_nodes().node.textf_qs_relevance = (Feedback(provider.qs_relevance,name="Context Relevance").on_input().on(context_selection).aggregate(np.mean)
)

3.4 基础性(Groundedness)

Groundedness用来评估LLM提供的答案(answer)和上下文(context)相关程度,或者说,当Groundedness的分数很低时,说明LLM产生了幻觉,理想情况下因为我们希望answer完全由context总结(推导)出来,当Groundedness的分数较高时可以排除LLM产生幻觉的可能性。下面我们来定义一个Groundedness反馈函数:

from trulens_eval.feedback import Groundednessgrounded = Groundedness(groundedness_provider=provider)f_groundedness = (Feedback(grounded.groundedness_measure_with_cot_reasons,name="Groundedness").on(context_selection).on_output().aggregate(grounded.grounded_statements_aggregator)
)

3.5 评估RAG三元组

前面我们定义了三个反馈函数:f_qa_relevance、f_qs_relevance、f_groundedness,接下来我们要定义一组问题,然后通过基本RAG管道来检索答案,最后我们通过这些问题和答案来实现对基本RAG管道的评估:

from trulens_eval import TruLlama
from trulens_eval import FeedbackMode#
tru_recorder = TruLlama(query_engine_base,app_id="App_1",feedbacks=[f_qa_relevance,f_qs_relevance,f_groundedness]
)#定义问题
eval_questions = ["恐龙是怎么被命名的?", "恐龙怎么分类的?","体型最大的是哪种恐龙?","体型最长的是哪种恐龙?它在哪里被发现?","恐龙采样什么样的方式繁殖?","恐龙是冷血动物吗?","陨石撞击是导致恐龙灭绝的原因吗?","恐龙是在什么时候灭绝的?","鳄鱼是恐龙的近亲吗?","恐龙在英语中叫什么?"]
#执行评估,LLM回答所有的问题
for question in eval_questions:with tru_recorder as recording:query_engine_base.query(question)#展示评估结果
records, feedback = tru.get_records_and_feedback(app_ids=[])
records[['input', 'output']] = records[['input', 'output']].applymap(lambda x: x.encode('latin1').decode('unicode_escape'))
records[["input", "output"]+feedback]

 这里我们看到除了Context Relevance的分数有较大的波动之外,Groundedness和Answer Relevance的分数都是比较高,其中所有问题的Answer Relevance分数都是1,说明Answer和question有非常高的相关性,并且Groundedness除了两个问题之外剩余的8个问题得分都是1,这说明answer基本上都是从上下文(Context)中推导(或是总结)出来的,因此可以肯定的说answer不是由于LLM的幻觉产生的。另外Context Relevance分数较低这是和我们在拆分文档时设置的块大小(chunk_size)有关,当chunk_size设置的太大时文档块中可能会包含更多的信息,这就会导致检索到的文档块内容(context)和question的相关性降低。但是由于我们使用的是openai的gpt-3.5模型,它有着非常强大的推理能力,尽管我们的Context Relevance分数较低,但gpt-3.5模型仍然能够从中推导出正确的答案。下面我们看一下这10个问题的总体成绩:

tru.get_leaderboard(app_ids=[])

这里我们看到了总体的评估结果除了Context Relevance,Groundedness和Answer Relevance之外还包括了评估的耗时(latency),以及评估的总成本(total_cost),其中耗时耗时(latency)花费了10.25秒,而评估的成本花费了$0.003322美刀,而总成本是通过计算question,context,answer统计出来的。

四、总结

今天我们学习了TruLens评估的基本原理,其中包括RAG三元组Context Relevance,Groundedness和Answer Relevance的定义和作用,然后我们又使用llamaIndex开发了基本RAG应用,最后我们使用了TruLens的反馈函数对基本RAG的检索结果进行了评估。希望今天的内容对大家学习RAG有所帮助.

五、参考资料

LlamaIndex 🦙 0.9.26 

Feedback Functions - TruLens

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/606086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3 内置组件

文章目录 前言一、过渡效果相关的组件1、Transition2、TransitionGroup 二、状态缓存组件(KeepAlive)三、传送组件(Teleport )四、异步依赖处理组件(Suspense) 前言 在vue3中 其提供了5个内置组件 Transiti…

antv/x6_2.0学习使用(四、边)

一、添加边 节点和边都有共同的基类 Cell,除了从 Cell 继承属性外,还支持以下选项。 属性名类型默认值描述sourceTerminalData-源节点或起始点targetTerminalData-目标节点或目标点verticesPoint.PointLike[]-路径点routerRouterData-路由connectorCon…

猫咪吃哪种猫粮好?主食冻干猫粮哪种性价比高

由于猫咪是肉食动物,对蛋白质的需求很高,如果摄入的蛋白质不足,就会影响猫咪的成长。而冻干猫粮本身因为制作工艺的原因,能保留原有的营养成分和营养元素,所以冻干猫粮蛋白含量比较高,营养又高,…

第二十七周:文献阅读笔记

第二十七周:文献阅读笔记 摘要AbstractDenseNet 网络1. 文献摘要2. 引言3. ResNets4. Dense Block5. Pooling layers6. Implementation Details7. Experiments8. Feature Reuse9. 代码实现 总结 摘要 DenseNet(密集连接网络)是一种深度学习神…

工智能基础知识总结--词嵌入之FastText

什么是FastText FastText是Facebook于2016年开源的一个词向量计算和文本分类工具,它提出了子词嵌入的方法,试图在词嵌入向量中引入构词信息。一般情况下,使用fastText进行文本分类的同时也会产生词的embedding,即embedding是fastText分类的产物。 FastText流程 FastText的架…

计算机组成原理简答题

目录 1、指令和数据在计算机内部以几进制存储,又是如何区分的呢? 2、计算机内部为什么要使用二进制? 3、简单描述计算机系统的层次结构 4、DRAM为什么要进行刷新,如何刷新的? 5、简述不同操作码的指令格式&#xf…

FileStream文件管理

文件管理 FileStream:是一个用于读写文件的一个类。它提供了基于流的方式操作文件,可以进行读取、写入、查找和关闭等操作。 第一个参数:path(路径) 相对路径:相对于当前项目的bin目录下的Debug和Realse来…

[嵌入式AI从0开始到入土]10_yolov5在昇腾上应用

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注:等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间,后期会考虑出视频教程,务必催更,以防我变身鸽王。 第一章 昇腾Altas 200 DK上手 第二章 下载昇腾案例并运行 第三章…

【AI视野·今日NLP 自然语言处理论文速览 第七十一期】Fri, 5 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Fri, 5 Jan 2024 Totally 28 papers 👉上期速览✈更多精彩请移步主页 Daily Computation and Language Papers LLaMA Pro: Progressive LLaMA with Block Expansion Authors Chengyue Wu, Yukang Gan, Yixiao Ge, Zeyu Lu, …

java导出word套打

这篇文档手把手教你完成导出word套打&#xff0c;有这个demo&#xff0c;其他word套打导出都通用。 1、主要依赖 <!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.0</ve…

IPv6路由协议---IPv6动态路由(RIPng)

IPv6动态路由协议 动态路由协议有自己的路由算法,能够自动适应网络拓扑的变化,适用于具有一定数量三层设备的网络。缺点是配置对用户要求比较高,对系统的要求高于静态路由,并将占用一定的网络资源和系统资源。 路由表和FIB表 路由器转发数据包的关键是路由表和FIB表,每…

CreateDIBSection失败的问题记录

错误记录 [ERROR] (:0, ): QPixmap::fromWinHICON(), failed to GetIconInfo() (操作成功完成。) [ERROR] (:0, ): QPixmap::fromWinHICON(), failed to GetIconInfo() (参数错误。) [ERROR] (:0, ): QPixmap::fromWinHICON(), failed to GetIconInfo() (参数错误。) [ERROR] …

升级 Vite 5 出现警告 The CJS build of Vite‘s Node API is deprecated.

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

数仓建设学习路线(一)

前言 数仓建设实践路线是语兴发布在B站的系列课程&#xff0c;搜索语兴呀即可学习完整的数仓建设理论。 大数据相关岗位 大数据常见的岗位主要包括实时开发、数据治理、数据安全、数据资产等。 其中&#xff1a; 实时开发组的主要任务是实时可视化制作(大屏/彩蛋/战报&…

前端结合MQTT实现连接 订阅发送信息等操作 VUE3

MQTT客户端下载 使用测试 在我之前文章中 MQTT下载基础使用 下面记录一下前端使用的话的操作 1.安装 npm i mqtt引入 import * as mqtt from "mqtt/dist/mqtt.min"; //VUE3 import mqtt from mqtt //VUE2 一、MQTT协议中的方法 Connect。等待与服务器建立连接…

[VUE]2-vue的基本使用

目录 vue基本使用方式 1、vue 组件 2、文本插值 3、属性绑定 4、事件绑定 5、双向绑定 6、条件渲染 7、axios 8、⭐跨域问题 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅…

气膜建筑:舒适、智能、可持续

气膜建筑之所以能够拥有广阔的发展空间&#xff0c;源于其融合了诸多优势特点&#xff0c;使其成为未来建筑领域的前沿趋势。 气膜建筑注重环境可持续性和能源效率。在材料和设计上&#xff0c;它采用可回收材料、提高热保温效果&#xff0c;并积极利用太阳能等可再生能源&…

【洛谷学习自留】p9226 糖果

解题思路&#xff1a; 简单的计算题&#xff0c;用n对k取余&#xff0c;如果余数为0&#xff0c;则输出k的值&#xff0c;否则输出&#xff08;k-余数&#xff09;的值。 代码实现&#xff1a; import java.util.Scanner;public class p9226 {public static void main(Strin…

【2023 CCF 大数据与计算智能大赛】基于TPU平台实现超分辨率重建模型部署 基于QuickRNet的TPU超分模型部署

2023 CCF 大数据与计算智能大赛 《赛题名称》 基于QuickRNet的TPU超分模型部署 巴黎欧莱雅 林松 智能应用业务部算法工程师 中信科移动 中国-北京 gpu163.com 团队简介 巴黎欧莱雅团队包含一个队长和零个队员。 队长林松&#xff0c;研究生学历&#xff0c;2019-202…

【一份老网工珍藏多年的网络配置笔记,很重要!】

01、交换机、路由器的几种配置模式及模式转换 1. 用户模式 登录到交换机&#xff08;路由器&#xff09;时会自动进入用户模式&#xff0c;提示符为 switchname>。在该模式下只能够查看相关信息&#xff0c; 对 IOS的运行不产生任何影响。 2. 特权模式 用户模式下&#xff…