如何避免LLM的“幻觉”(Hallucination)

生成式大语言模型(LLM)可以针对各种用户的 prompt 生成高度流畅的回复。然而,大模型倾向于产生幻觉或做出非事实陈述,这可能会损害用户的信任。

大语言模型的长而详细的输出看起来很有说服力,但是这些输出很有可能是虚构的。这是否意味着我们不能信任聊天机器人,每次都必须手动检查输出的事实?有一些方法可以让聊天机器人在适当的保护措施下不太可能说假话。

一个最简单的方法就是调整temperature到一个很大的值,例如0.7,然后使用相同的提问多次对话。这样得到的输出应该只会改变句子的结构,输出之间的差异应该只是语义上的,而不是事实上的。

这个简单的想法允许引入一种新的基于样本的幻觉检测机制。如果LLM对同一提示的输出相互矛盾,它们很可能是幻觉。如果它们相互关联,就意味着信息是真实的。对于这种类型的求值,我们只需要llm的文本输出。这被称为黑盒评估。

余弦距离

余弦距离(Cosine Distance)是衡量两个向量之间相似度的一种度量方法,通常用于文本相似性、推荐系统和机器学习等领域。我们可以计算嵌入句子的对应对之间的两两余弦相似度。下面的函数将最初生成的句子output和一个包含3个示例输出的列表sampled_passages作为输入。

这里使用了all-MiniLM-L6-v2轻量模型。嵌入一个句子会把它变成它的向量表示。

 output = "Evelyn Hartwell is a Canadian dancer, actor, and choreographer." output_embeddings= model.encode(output)array([ 6.09108340e-03, -8.73148292e-02, -5.30637987e-02, -4.41815751e-03,1.45469820e-02, 4.20340300e-02, 1.99541822e-02, -7.29453489e-02,…-4.08893749e-02, -5.41420840e-02, 2.05906332e-02, 9.94611382e-02,-2.24501686e-03, 2.29083393e-02, 7.80007839e-02, -9.53456461e-02],dtype=float32)

将LLM的每个输出生成嵌入,然后使用sentence_transformers中的pairwise_cos_sim函数计算cos相似度。将原始响应与每个新样本响应进行比较,然后求平均值。

 from sentence_transformers.util import pairwise_cos_simfrom sentence_transformers import SentenceTransformerdef get_cos_sim(output,sampled_passages):model = SentenceTransformer('all-MiniLM-L6-v2')sentence_embeddings = model.encode(output).reshape(1, -1)sample1_embeddings = model.encode(sampled_passages[0]).reshape(1, -1)sample2_embeddings = model.encode(sampled_passages[1]).reshape(1, -1)sample3_embeddings = model.encode(sampled_passages[2]).reshape(1, -1)cos_sim_with_sample1 = pairwise_cos_sim(sentence_embeddings, sample1_embeddings)cos_sim_with_sample2  = pairwise_cos_sim(sentence_embeddings, sample2_embeddings)cos_sim_with_sample3  = pairwise_cos_sim(sentence_embeddings, sample3_embeddings)cos_sim_mean = (cos_sim_with_sample1 + cos_sim_with_sample2 + cos_sim_with_sample3) / 3cos_sim_mean = cos_sim_mean.item()return round(cos_sim_mean,2)

从上面的图像可以看到矢量之间的角度大约是30⁰,因此它们彼此接近。余弦大约是0.87。余弦函数越接近1,这两个向量就越接近。

 cos_sim_score = get_cos_sim(output, [sample1,sample2,sample3])

嵌入的cos_sim_score的平均值为0.52。

为了理解如何解释这个数字,让我们将其与一些有效输出的余弦相似度评分进行比较

这个输出的余弦相似度为0.93。所以说第一个输出很有可能是LLM的幻觉。

BERTScore

BERTScore建立在两两余弦相似度思想的基础上。

用于计算上下文嵌入的标记器是RobertaTokenizer。上下文嵌入不同于静态嵌入,因为它们会考虑单词周围的上下文。

 def get_bertscore(output, sampled_passages):# spacy sentence tokenizationsentences = [sent.text.strip() for sent in nlp(output).sents] selfcheck_bertscore = SelfCheckBERTScore(rescale_with_baseline=True)sent_scores_bertscore = selfcheck_bertscore.predict(sentences = sentences, # list of sentencessampled_passages = sampled_passages, # list of sampled passages)df = pd.DataFrame({'Sentence Number': range(1, len(sent_scores_bertscore) + 1),'Hallucination Score': sent_scores_bertscore})return df

selfcheck_bertscore没有将完整的原始输出作为参数传递,而是将其分成单独的句子。

 ['Evelyn Hartwell is an American author, speaker, and life coach.','She is best known for her book, The Miracle of You: How to Live an Extraordinary Life, which was published in 2007.','She is a motivational speaker and has been featured on TV, radio, and in many magazines.','She has authored several books, including How to Make an Impact and The Power of Choice.']

这一步很重要,因为selfcheck_bertscore.predict函数将每个句子的BERTScore计算为与样本中每个句子匹配的原始响应。它创建一个数组,其行数等于原始输出中的句子数,列数等于样本数。

 array([[0., 0., 0.],[0., 0., 0.],[0., 0., 0.],[0., 0., 0.]])

用于计算候选句子和参考句子之间BERTScore的模型是RoBERTa large,共17层。最初的输出有4个句子,分别是r1 r2 r3和r4。第一个样本有两个句子:c1和c2。计算原始输出中的每个句子与第一个样本中的每个句子匹配的F1 BERTScore。然后我们对基线张量b =([0.8315,0.8315,0.8312])进行缩放。基线b是使用来自Common Crawl单语数据集的100万个随机配对句子来计算的。他们计算了每一对的BERTScore,并取其平均值。这代表了一个下界,因为随机对几乎没有语义重叠。

保留原始回复中每个句子的BERTScore,并从每个抽取的样本中选择最相似的句子。其逻辑是,如果一条信息出现在由同一提示生成的多个样本中,那么该信息很有可能是真实的。如果一个语句只出现在一个示例中,而没有出现在来自同一提示的任何其他示例中,则更有可能是伪造的。

所以我们计算最大相似度:

 bertscore_arrayarray([[0.43343216, 0.        , 0.        ],[0.12838356, 0.        , 0.        ],[0.2571277 , 0.        , 0.        ],[0.21805632, 0.        , 0.        ]])

对另外两个样本重复这个过程:

 array([[0.43343216, 0.34562832, 0.65371764],[0.12838356, 0.28202596, 0.2576825 ],[0.2571277 , 0.48610589, 0.2253703 ],[0.21805632, 0.34698656, 0.28309497]])

然后我们计算每行的平均值,给出原始回复中每个句子与每个后续样本之间的相似度得分。

 array([0.47759271, 0.22269734, 0.32286796, 0.28271262])

每句话的幻觉得分是通过从上面的每个值中减去1得到的。

将结果与尼古拉斯·凯奇(Nicolas Cage)的答案进行比较。

有效输出的幻觉得分较低,而虚构输出的幻觉得分较高。但是计算BERTScore的过程非常耗时,这使得它不适合用于实时幻觉检测。

NLI

自然语言推理(NLI)涉及确定一个假设在逻辑上是遵循给定前提还是与给定前提相矛盾。这种关系可分为牵连、矛盾或中立。对于NLI,我们利用在MNLI数据集上进行微调的DeBERTa-v3-large模型来执行NLI。

下面是一些前提-假设对及其标签的例子。

 def get_self_check_nli(output, sampled_passages):# spacy sentence tokenizationsentences = [sent.text.strip() for sent in nlp(output).sents] selfcheck_nli = SelfCheckNLI(device=mps_device) # set device to 'cuda' if GPU is availablesent_scores_nli = selfcheck_nli.predict(sentences = sentences, # list of sentencessampled_passages = sampled_passages, # list of sampled passages)df = pd.DataFrame({'Sentence Number': range(1, len(sent_scores_nli) + 1),'Probability of Contradiction': sent_scores_nli})return df

在selfcheck_nli.predict函数,原始响应中的每个句子都与三个样本中的每个配对。

 logits = model(**inputs).logits # neutral is already removedprobs = torch.softmax(logits, dim=-1)prob_ = probs[0][1].item() # prob(contradiction)

现在我们对这四个句子中的每一个重复这个过程。

可以看到,模型输出的矛盾概率非常高。现在我们将其与实际输出进行比较。

这个模特做得很好!但是NLI检查时间有点太长了。

Prompt

较新的方法已经开始使用llm本身来评估生成的文本。而不是使用公式来计算分数,我们将输出与三个样本一起发送到gpt-3.5 turbo。该模型将决定原始输出相对于生成的其他三个样本的一致性。

 def llm_evaluate(sentences,sampled_passages):prompt = f"""You will be provided with a text passage \and your task is to rate the consistency of that text to \that of the provided context. Your answer must be only \a number between 0.0 and 1.0 rounded to the nearest two \decimal places where 0.0 represents no consistency and \1.0 represents perfect consistency and similarity. \n\n \Text passage: {sentences}. \n\n \Context: {sampled_passages[0]} \n\n \{sampled_passages[1]} \n\n \{sampled_passages[2]}."""completion = client.chat.completions.create(model="gpt-3.5-turbo",messages=[{"role": "system", "content": ""},{"role": "user", "content": prompt}])return completion.choices[0].message.content

Evelyn Hartwell的自相似性得分为0。Nicolas Cage相关的输出得分为0.95。获得分数所需的时间也很低。

这似乎是案例的目前最佳解决方案,Prompt的性能明显优于所有其他方法,NLI是性能第二好的方法。

评估数据集是通过使用WikiBio数据集和GPT-3生成合成维基百科文章来创建的。为了避免模糊的概念,238篇文章的主题是从最长文章的前20%中随机抽取的。GPT-3被提示以维基百科风格为每个概念生成第一段。

,这些生成的段落在句子层面上被手工标注为事实。每个句子被标记为主要不准确,次要不准确,或准确。总共有1908个句子被注释,大约40%的句子主要不准确,33%的句子次要不准确,27%的句子准确。

为了评估注释者的一致性,201个句子有双重注释。如果注释者同意,则使用该标签;否则选择最坏情况的标签。Cohen’s kappa测量的注释者间一致性在准确、次要不准确和主要不准确之间进行选择时为0.595,在次要/主要不准确合并到一个标签时为0.748。

评价指标AUC-PR是指准确率-召回率曲线下的面积,是用来评价分类模型的指标。

实时幻觉检测

我们可以构建一个实时幻觉检测的Streamlit应用。如前所述,最好的度量是LLM自相似性得分。我们将使用0.5的阈值来决定是显示生成的输出还是显示免责声明。

 import streamlit as stimport utilsimport pandas as pd# Streamlit app layoutst.title('Anti-Hallucination Chatbot')# Text inputuser_input = st.text_input("Enter your text:")if user_input:prompt = user_inputoutput, sampled_passages = utils.get_output_and_samples(prompt)# LLM scoreself_similarity_score = utils.llm_evaluate(output,sampled_passages)# Display the outputst.write("**LLM output:**")if float(self_similarity_score) > 0.5:st.write(output)else:st.write("I'm sorry, but I don't have the specific information required to answer your question accurately. ")

我们看看结果。

总结

聊天机器人的幻觉检测一直是人们讨论已久的质量问题。

我们只是概述的了目前的研究成果:通过生成对同一提示的多个响应并比较它们的一致性来完成。

还有更多的工作要做,但与其依赖于人工评估或手工制定的规则,让模型自己捕捉不一致似乎是一个很好的方向。

本文引用:

https://avoid.overfit.cn/post/f32f440c1b99458e86d3e48c70ddcf94

作者:Iulia Brezeanu

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

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

相关文章

外汇天眼:行情突发爆仓,他只用了一招喜获赔偿!

在外汇市场中,行情的剧烈波动往往伴随着风险和机遇,有些突发行情的性质可能导致滑点和爆仓等交易问题,投资者在这样的情况下往往感到手足无措,往大了说是遭遇黑平台、假冒平台诈骗,往小了说就是在持有正规海外牌照的主…

electron自定义菜单

创建menu.js const { app, Menu } require("electron"); const createMenu () > {const menu [{label: "菜单",submenu: [{label: "新增",click: () > {},}, ],},{label: "关于",submenu: [{label: "新增",click:…

了解Apache 配置与应用

本章内容 理解 Apache 连接保持 掌握 Apache 的访问控制 掌握 Apache 日志管理的方法 Apache HTTP Server 之所以受到众多企业的青睐,得益于其代码开源、跨平台、功能 模块化、可灵活定制等诸多优点,不仅性能稳定,在安全性方面的表现也十分…

阿里云2核2G3M服务器能放几个网站?有限制吗?

阿里云2核2g3m服务器可以放几个网站?12个网站,阿里云服务器网的2核2G服务器上安装了12个网站,甚至还可以更多,具体放几个网站取决于网站的访客数量,像阿里云服务器网aliyunfuwuqi.com小编的网站日访问量都很少&#xf…

使用MQTT.JS创建一个网页版的MQTT客户端

一、MQTT.JS介绍 MQTT.js 是一个开源的 MQTT 协议的客户端库,使用 JavaScript 编写,主要用于 Node.js 和 浏览器环境中。是JavaScript 环境下的 MQTT 客户端库。可以用于微信小程序、支付宝小程序等定制浏览器环境。 我们可以直接在HTML文件中进行调用…

k8s中实现pod自动扩缩容

一、k8s应用自动扩缩容概述 1)背景: 在实际的业务场景中,我们经常会遇到某个服务需要扩容的场景(例如:测试对服务压测、电商平台秒杀、大促活动、或由于资源紧张、工作负载降低等都需要对服务实例数进行扩缩容操作&…

LiveGBS流媒体平台GB/T28181功能-国标级联对接海康大华宇视华为等上级平台选择通道支持只看已选只看未选

LiveGBS功能国标级联对接海康大华宇视华为等上级平台选择通道支持只看已选只看未选 1、国标级联2、只看已选3、只看未选4、搭建GB28181视频直播平台 1、国标级联 LiveGBS可以作为下级平台,级联到第三方国标平台,详见: LiveGBS国标GB/T28181流…

SpringBoot整合Elasticsearch报错

本文来记录一下SpringBoot整合Elasticsearch报错 文章目录 报错如下报错原因es7.15.2版本下载 报错如下 报错如下 2024-01-02 15:09:10.349 ERROR 134936 --- [nio-8088-exec-6] o.a.c.c.C.[.[.[/]. [dispatcherServlet] : Servlet.service() for servlet [dispatcherServle…

小红书、抖音、视频号下载工具:随心管理个人作品集 | 开源日报 No.134

karanpratapsingh/system-design Stars: 20.6k License: NOASSERTION 这个项目是关于系统设计的。它提供了有关系统设计的课程内容,包括 IP、OSI 模型、TCP 和 UDP 等主题。该项目的核心优势和特点如下: 提供全面而高效的系统架构定义。从基础设施到数…

SM2——适用于前后端(java+vue)公用的SM2国密加解密传输

目录 一、SM2国密加解密算法1.1、pom文件引入依赖包1.2、SM2加解密工具类1.3、测试类 一、SM2国密加解密算法 1.1、pom文件引入依赖包 <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk18on</artifactId><version>…

element的select遇到的下拉名称过长的问题修复

问题描述&#xff1a;如果下拉框的数据名称过长怎么解决 解决办法&#xff1a;在select下加类名 :popper-append-to-body“false” popper-class“my-select” 不要忽略一点&#xff1a;如果改样式的话因为用的饿了么组件&#xff0c;有的样式避免找来找去&#xff0c;可以直接…

自动驾驶TPM技术杂谈 ———— ODDODC

文章目录 介绍研究现状主流相关定义国标定义SAE定义WP29定义 ODD主流构建框架NHTSA ODD构建框架SAE AVSC ODD构建框架PEGASUS 6层模型BSI ODD构建框架 设计运行条件的原则ODC 的设计原则ODC 元素的制定原则ODC 的使用原则 设计运行条件元素ODD 元素驾乘人员状态4车辆状态 ODC 描…