尽管评测大型语言模型(LLMs)的输出对于任何希望部署稳健 LLM 应用的人来说都至关重要,但 LLM 评测对许多人而言仍是一项挑战性任务。无论你是通过微调提升模型准确性,还是增强检索增强生成(RAG)系统的上下文相关性,了解如何为你的用例开发和选定合适的 LLM 评测指标集,对于构建坚不可摧的 LLM 评测流程至关重要。
本文将带你全面了解 LLM 评测指标,并附代码示例。我们将深入探讨:
- 什么是LLM评测指标,它们如何用于评测LLM系统,常见的误区,以及优秀LLM评测指标的特质。
- 所有评分LLM评测指标的不同方法,以及为何LLM评委最适合LLM评测。
- 如何利用LLM评委为你的LLM指标创建确定性、基于决策的评分器。
- 如何通过 DeepEval在代码中实现并决定使用哪一组LLM评测指标。(https://github.com/confident-ai/deepeval)
什么是LLM评测指标?
LLM评测指标,如答案正确性、语义相似度和幻觉程度,是根据你关心的标准对LLM系统输出进行评分的指标。它们对LLM评测至关重要,有助于量化不同LLM系统的性能,而LLM本身也可以作为评测对象。
一种LLM评测指标架构
在将你的LLM系统投入生产环境前,以下是你最可能需要的重要且常见指标:
- 答案相关性:判断LLM的输出是否能以信息丰富且简洁的方式回应给定输入。
- 提示对齐:判断LLM输出是否能遵循提示模板中的指令。
- 正确性:基于某些基准事实判断LLM的输出是否在事实上正确。
- 幻觉:判断LLM的输出是否包含虚假或捏造的信息。
- 上下文相关性:判断基于 RAG 的LLM系统中的检索器能否为你的LLM提取最相关的信息作为上下文。
- 责任度量:包括偏见和毒性等指标,用于判断LLM的输出是否包含(通常)有害和冒犯性内容。
- 任务特定指标:包括诸如摘要等指标,通常根据具体用例包含自定义标准。
虽然大多数指标是通用且必要的,但它们不足以针对特定用例。这就是为什么你至少需要一个自定义的任务特定指标,以使你的LLM评测流程具备生产准备就绪性(如后续在 G-Eval 和 DAG 部分所见)。例如,如果你的LLM应用旨在总结新闻文章页面,你将需要一个自定义的LLM评测指标,其评分基于:
- 摘要是否包含原文足够的信息。
- 摘要是否与原文存在矛盾或虚构内容。
此外,如果你的LLM应用采用了基于 RAG 的架构,你可能还需要对检索上下文的质量进行评分。关键在于,LLM评测指标是根据应用设计执行的任务来评测LLM应用的。(请注意,LLM应用可以仅仅是LLM本身!)
优秀的评测指标应具备以下特点:
- 可量化。指标在评测当前任务时必须能计算出分数。这种方法让你能够设定一个最低通过阈值,以判断你的LLM应用是否“足够好”,并随着实现的迭代改进,监控这些分数随时间的变化。
- 可靠。尽管LLM的输出可能难以预测,但最不希望的是LLM评测指标同样不可靠。因此,虽然使用LLMs(又称LLM评委或LLM评测)评测的指标,如 G-Eval,特别是对于 DAG,比传统评分方法更准确,但它们往往不一致,这正是大多数LLM评测的不足之处。
- 准确。如果可靠的分数不能真实反映你的LLM应用性能,那么它们就毫无意义。事实上,让一个好的LLM评测指标变得出色的秘诀在于尽可能使其与人类期望保持一致。
因此问题变成了,LLM评测指标如何计算出可靠且准确的分数?
计算指标分数的不同方法
我提到过LLM输出因其难以评测而臭名昭著。幸运的是,现有多种成熟的方法可用于计算指标分数——有些利用了神经网络,包括嵌入模型和LLMs,而另一些则完全基于统计分析。
指标评分器的类型
我们将逐一探讨每种方法,并在本节末尾讨论最佳实践,请继续阅读以了解详情!
统计评分器
在开始之前,我想先说明,在我看来统计评分方法并非必须掌握的内容,所以如果你时间紧迫,可以直接跳到“G-Eval”部分。这是因为统计方法在需要推理时表现不佳,作为评分器对大多数LLM评测标准来说过于不准确。
快速浏览一下:
- BLEU(双语评测替补)评分器通过将你的LLM应用程序输出与标注的真实值(或预期输出)进行对比来评测其表现。它计算LLM输出与预期输出之间每个匹配 n 元语法(n 个连续单词)的精确度,进而计算它们的几何平均值,并在必要时应用简短惩罚。
- ROUGE(面向召回率的摘要评测替代指标)评分器主要用于评测 NLP 模型生成的文本摘要,通过比较LLM输出与预期输出之间 n-gram 的重叠来计算召回率。它确定参考摘要中 n-gram 在LLM输出中出现的比例(0 到 1 之间)。
- METEOR(显式排序翻译评测指标)评分器更为全面,它通过评测精确度(n-gram 匹配)和召回率(n-gram 重叠)来计算分数,并根据LLM输出与预期输出之间的词序差异进行调整。该评分器还利用 WordNet 等外部语言数据库来考虑同义词。最终分数是精确度和召回率的调和平均数,并对顺序差异施加惩罚。
- 莱文斯坦距离(或称编辑距离,你可能在 LeetCode 上将其视为一道困难的动态规划问题)评分器计算将一个单词或文本字符串转换为另一个所需的最少单字符编辑(插入、删除或替换)次数,这对于评测拼写纠正或其他字符精确对齐至关重要的任务非常有用。
由于纯统计评分器几乎不考虑任何语义且推理能力极其有限,它们对于评测通常较长且复杂的LLM输出来说不够准确。
基于模型的评分器
纯统计性质的评分器虽然可靠但不精确,因为它们难以将语义因素纳入考量。本节讨论的情况则相反——完全依赖自然语言处理模型的评分器相对更准确,但由于其概率特性,也更为不可靠。
这并不令人意外,但非基于LLM的评分器表现不如LLM作为评委,原因同样在于统计评分器所面临的困境。非LLM评分器包括:
- NLI 评分器采用自然语言推理模型(一种自然语言处理分类模型),用于判断LLM输出相对于给定参考文本是否逻辑一致(蕴含)、矛盾或无关(中立)。其评分范围通常在蕴含(值为 1)与矛盾(值为 0)之间,以此衡量逻辑连贯性。
- BLEURT(基于 Transformer 表示的双语评测替代)评分器,利用如 BERT 这样的预训练模型来对LLM输出与预期输出进行评分。
除了评分不一致的问题,实际情况是这些方法存在若干缺陷。例如,自然语言推理(NLI)评分器在处理长文本时也可能面临准确性挑战,而 BLEURT 则受限于其训练数据的质量与代表性。
G-Eval
G-Eval 是近期在一篇题为“利用 GPT-4 进行 NLG 评测以实现更佳人类对齐”的论文中提出的框架,它采用LLMs来评测LLM输出(又称LLM-Evals),是创建任务特定指标的最佳方法之一。
G-Eval 算法
G-Eval 首先通过思维链(CoTs)生成一系列评测步骤,然后利用这些生成的步骤,通过表单填写范式(这不过是 G-Eval 需要多条信息才能工作的另一种说法)来确定最终分数。例如,使用 G-Eval 评测LLM输出的连贯性时,需要构建一个包含评测标准和待评文本的提示来生成评测步骤,之后再由LLM根据这些步骤输出 1 到 5 的评分。
让我们通过这个例子来走一遍 G-Eval 算法。首先,生成评测步骤:
- 向你选择的LLM引入一个评测任务(例如,根据连贯性对此输出进行 1 到 5 的评分)
- 为你的标准给出定义(例如,“连贯性——实际输出中所有句子的集体质量”)。
(请注意,在原 G-Eval 论文中,作者仅使用了 GPT-3.5 和 GPT-4 进行实验,且我个人尝试过多种LLMs用于 G-Eval 后,强烈建议你坚持使用这些模型。)
生成一系列评测步骤后:
- 通过将评测步骤与你评测步骤中列出的所有参数拼接起来创建提示(例如,如果你想评测LLM输出的连贯性,那么LLM输出将是必需的参数)。
- 在提示的末尾,要求其生成一个 1 到 5 之间的分数,其中 5 优于 1。
- (可选)从LLM获取输出标记的概率以标准化分数,并将它们的加权求和作为最终结果。
第三步是可选的,因为要获取输出词元的概率,你需要访问原始模型嵌入,而这并非所有模型接口都能保证提供。不过,论文中引入此步骤是因为它能提供更细粒度的分数,并最小化LLM评分中的偏差(如论文所述,在 1-5 的量表中,3 被认为具有更高的词元概率)。
以下是论文中的结果,展示了 G-Eval 如何优于本文前面提到的所有传统非LLM评测方法:
更高的斯皮尔曼和肯德尔-陶相关系数表示与人类判断有更高的一致性。
G-Eval 之所以卓越,在于作为LLM-Eval,它能全面考量LLM输出的语义,从而显著提升准确性。这一设计理念极为合理——试想,那些非LLM的评测工具,其评分机制远不及LLMs强大,又怎能真正理解LLMs生成文本的全部内涵?
尽管 G-Eval 相较于同类工具与人类判断的一致性更高,但其评分仍可能不够可靠,因为依赖LLM来生成分数本质上仍具有不可回避的主观性。
话虽如此,鉴于 G-Eval 评测标准的灵活性,我个人已将 G-Eval 实现为 DeepEval 的一个指标——这是我正在开发的一个开源LLM评测框架(其中包含了原论文中的标准化技术)。
# Install
pip install deepeval
# Set OpenAI API key as env variable
export OPENAI_API_KEY="..."
from deepeval.test_case import LLMTestCase, LLMTestCaseParams
from deepeval.metrics import GEval
test_case = LLMTestCase(input="input to your LLM", actual_output="your LLM output")
coherence_metric = GEval(
name="Coherence",
criteria="Coherence - the collective quality of all sentences in the actual output",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT],
)
coherence_metric.measure(test_case)
print(coherence_metric.score)
print(coherence_metric.reason)
使用LLM-Eval 的另一大优势在于,LLMs能够为其评测分数生成理由。
DAG(有向无环图)
在涉及主观性的评测场景中,G-Eval 表现卓越。然而,当存在明确成功标准时,你会倾向于使用基于决策的打分器。设想这样一个场景:你有一个文本摘要应用案例,需要在医院环境中格式化患者的病史记录。摘要中需包含多个标题,并按正确顺序排列,仅当所有格式均无误时才能给予满分。在此类约束条件组合下,期望得分极为明确的情况下,DAG 打分器堪称完美选择。
顾名思义,DAG(深度无环图)评分器是一个由LLM作为评判驱动的决策树,其中每个节点代表一个LLM判断,每条边则对应一项决策。最终,根据所采取的评测路径,会返回一个预设的硬编码分数(当然,你也可以选择使用 G-Eval 作为叶节点来返回分数)。通过将评测拆解为细粒度步骤,我们实现了确定性。DAG 的另一应用场景是过滤掉那些连基本评测要求都未满足的边缘案例,比如回到我们的摘要示例中,这意味着格式错误的情况。此时,你往往会发现自己在使用 G-Eval 而非硬编码分数作为叶节点来返回结果。
这里有一个用于文本摘要的 DAG 架构示例:
DAG 评分器架构
这里是 DeepEval 中对应的代码
from deepeval.test_case import LLMTestCase
from deepeval.metrics.dag import (
DeepAcyclicGraph,
TaskNode,
BinaryJudgementNode,
NonBinaryJudgementNode,
VerdictNode,
)
from deepeval.metrics import DAGMetric
correct_order_node = NonBinaryJudgementNode(
criteria="Are the summary headings in the correct order: 'intro' => 'body' => 'conclusion'?",
children=[
VerdictNode(verdict="Yes", score=10),
VerdictNode(verdict="Two are out of order", score=4),
VerdictNode(verdict="All out of order", score=2),
],
)
correct_headings_node = BinaryJudgementNode(
criteria="Does the summary headings contain all three: 'intro', 'body', and 'conclusion'?",
children=[
VerdictNode(verdict=False, score=0),
VerdictNode(verdict=True, child=correct_order_node),
],
)
extract_headings_node = TaskNode(
instructions="Extract all headings in `actual_output`",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT],
output_label="Summary headings",
children=[correct_headings_node, correct_order_node],
)
# create the DAG
dag = DeepAcyclicGraph(root_nodes=[extract_headings_node])
# create the metric
format_correctness = DAGMetric(name="Format Correctness", dag=dag)
# create a test case
test_case = LLMTestCase(input="your-original-text", actual_output="your-summary")
# evaluate
format_correctness.measure(test_case)
print(format_correctness.score, format_correctness.reason)
DAG 指标是目前可定制性最高的指标,我构建它是为了涵盖许多边缘情况,这些情况未被流行指标如答案相关性、忠实度,甚至自定义指标如 G-Eval 所覆盖。
普罗米修斯
普罗米修斯是一个完全开源的LLM,在提供适当的参考资料(参考答案、评分标准)时,其评测能力可与 GPT-4 相媲美。它同样不限定具体使用场景,类似于 G-Eval。普罗米修斯是以 Llama-2-Chat 为基础模型,并在反馈收集系统中基于 10 万条(由 GPT-4 生成的)反馈数据微调而成的语言模型。
以下是普罗米修斯研究论文中的简要结果。
为何未选择 GPT-4 或 Prometheus 的反馈而选择了另一种。Prometheus 生成的反馈较少抽象和笼统,但往往过于苛刻。
Prometheus 遵循与 G-Eval 相同的原则,但存在几点差异:
- G-Eval 是一个使用 GPT-3.5/4 的框架,而 Prometheus 是专为评测LLM微调的模型。
- G-Eval 通过思维链生成评分标准/评测步骤,而 Prometheus 的评分标准则直接由提示提供。
- Prometheus 需要参考/示例评测结果。
虽然我个人尚未尝试过,但 Prometheus 已在 Hugging Face 上可用。我之所以没有尝试实现它,是因为 Prometheus 的设计初衷是让评测开源化,而非依赖如 OpenAI 的 GPTs 这类专有模型。对于致力于打造最佳LLM-Evals 的人来说,它并不合适。
结合统计与基于模型的评分器
至此,我们已经了解到统计方法可靠但不精确,而非LLM基于模型的方法虽不那么可靠却更为准确。与前一节类似,存在诸如以下非LLM评分器:
- BERTScore 评分器,它依赖于 BERT 等预训练语言模型,计算参考文本与生成文本中词语上下文嵌入的余弦相似度。这些相似度随后被聚合以产生最终分数。BERTScore 越高,表明LLM输出与参考文本间的语义重叠程度越大。
- MoverScore 评分器,它首先使用嵌入模型(特别是如 BERT 这样的预训练语言模型)获取参考文本和生成文本的深度上下文词嵌入,然后利用所谓的地球移动距离(EMD)来计算将LLM输出中的词语分布转换为参考文本中词语分布所需支付的最小成本。
BERTScore 和 MoverScore 评分器由于依赖如 BERT 这类预训练模型的上下文嵌入,易受上下文感知和偏见影响。那么LLM-Evals 呢?
GPTScore
与 G-Eval 直接通过填表范式执行评测任务不同,GPTScore 采用生成目标文本的条件概率作为评测指标。
GPTScore 算法
SelfCheckGPT 是个独特的存在。它是一种基于简单采样的方法,用于验证LLM的输出。该方法假设幻觉输出不可复现,而如果LLM对某个概念有所了解,采样得到的回应则可能相似且包含一致的事实。
SelfCheckGPT 之所以引人注目,是因为它将幻觉检测变成了一个无需参考的过程,这在实际生产环境中极为实用。
SelfCheckGPT 算法
然而,尽管你会注意到 G-Eval 和 Prometheus 是用途无关的,但 SelfCheckGPT 并非如此。它仅适用于幻觉检测,而不适用于评测其他用例,如摘要、连贯性等。
QAG 分数
QAG(问题答案生成)分数是一种评分器,利用LLMs的高推理能力可靠地评测LLM的输出。它通过封闭式问题(可生成或预设)的答案(通常是“是”或“否”)来计算最终指标分数。其可靠性在于它不直接使用LLMs生成分数。例如,若要计算忠实度分数(衡量LLM输出是否存在幻觉),你需要:
- 使用LLM提取LLM输出中提出的所有主张。
- 对于每项声明,询问事实真相是否同意该声明(‘是’或‘否’)。
因此,对于此示例LLM输出:
马丁·路德·金,这位著名的民权领袖,于 1968 年 4 月 4 日在田纳西州孟菲斯的洛林汽车旅馆遇刺身亡。他当时在孟菲斯支持罢工的环卫工人,站在汽车旅馆二楼阳台时被逃犯詹姆斯·厄尔·雷开枪击中致命。
一项声明可能是:
马丁·路德·金于 1968 年 4 月 4 日遇刺身亡
相应的封闭式问题可以是:
马丁·路德·金是在 1968 年 4 月 4 日被暗杀的吗?
接着,你会拿这个问题去验证事实是否与主张相符。最终,你将得到一系列“是”与“否”的答案,通过这些答案,你可以用自选的数学公式计算出一个分数。
在忠实度这一指标上,若将其定义为大语言模型(LLM)输出中与客观事实相符的准确陈述所占比例,其计算方式可通过以下步骤实现:将LLM生成的准确(真实)陈述数量除以输出总陈述数。由于我们并非直接使用LLM生成评分结果,而是充分发挥其卓越的推理能力进行判断,最终获得的评分兼具精确性与可信度。
选择你的评测指标
选择使用哪种LLM评测指标取决于你的LLM应用场景和架构。
例如,如果你基于 OpenAI 的 GPT 模型构建一个 RAG 驱动的客户支持聊天机器人,你将需要使用多种 RAG 指标(如忠实度、答案相关性、上下文精确度),而如果你正在微调自己的 Mistral 7B 模型,则需要诸如偏见度等指标以确保LLM决策的公正性。
在这最后一节中,我们将介绍你必须了解的评测指标。(额外附赠每项指标的实现方法。)
RAG 指标
对于那些还不了解 RAG(检索增强生成)是什么的人,这里有一篇很好的读物。简而言之,RAG 作为一种方法,通过补充额外上下文来为LLMs生成定制化输出,非常适合构建聊天机器人。它由两个组件组成——检索器和生成器。
典型的 RAG 架构
RAG 工作流程通常如下运作:
- 你的 RAG 系统接收到输入。
- 检索器利用此输入在知识库(现今多数情况下为向量数据库)中执行向量搜索。
- 生成器结合检索到的上下文与用户输入作为额外信息,生成定制化输出。
记住一点——高质量的LLM输出是优秀检索器和生成器共同作用的产物。因此,优质的 RAG 指标专注于以可靠且准确的方式评测你的 RAG 检索器或生成器。(实际上,RAG 指标最初设计为无参考指标,这意味着它们不需要真实标签,甚至在生产环境中也能使用。)
忠实性
忠实性是 RAG 的一项评测指标,用于衡量 RAG 流程中的LLM/生成器是否产生与检索上下文信息事实相符的LLM输出。但我们应该选用哪种评分器来度量忠实性呢?
剧透预警:QAG 评分器是 RAG 指标的最佳选择,因其在目标明确的任务评测中表现卓越。对于忠实性,若将其定义为LLM输出中相对于检索上下文真实声明的比例,我们可通过以下算法使用 QAG 计算忠实性:
- 使用LLMs提取输出中提出的所有声明。
- 对于每个声明,检查其是否与检索上下文中的每个独立节点一致或矛盾。此时,QAG 中的封闭式问题将类似于:“给定声明是否与参考文本一致”,其中“参考文本”为每个独立检索到的节点。(注意,答案需限定为‘是’、‘否’或‘不知道’。‘不知道’状态代表检索上下文不包含相关信息以给出肯定或否定答案的边缘情况。)
- 累加所有真实声明的数量(‘是’和‘不知道’),然后除以提出的声明总数。
该方法通过利用LLM的高级推理能力确保准确性,同时避免LLM生成分数的不可靠性,使其成为优于 G-Eval 的评分方法。
如果你觉得实现起来太复杂,可以使用 DeepEval。这是我构建的一个开源包,提供了LLM评估所需的所有评估指标,包括忠实度指标。
# Install
pip install deepeval
# Set OpenAI API key as env variable
export OPENAI_API_KEY="..."
from deepeval.metrics import FaithfulnessMetric
from deepeval.test_case import LLMTestCase
test_case=LLMTestCase(
input="...",
actual_output="...",
retrieval_context=["..."]
)
metric = FaithfulnessMetric(threshold=0.5)
metric.measure(test_case)
print(metric.score)
print(metric.reason)
print(metric.is_successful())
DeepEval 将评估视为测试用例。这里,actual_output 就是你的LLM输出。此外,faithfulness 是一个LLM-Eval,你能够获得最终计算得分的推理过程。
答案相关性
答案相关性是一项 RAG 指标,用于评测你的 RAG 生成器是否输出简洁的答案,其计算方法为确定输出中与输入相关的句子比例(即用相关句子数除以总句子数)。
构建一个健壮的答案相关性指标的关键在于考虑检索上下文,因为额外的上下文可能证明一个看似不相关的句子实际上是相关的。以下是答案相关性指标的一个实现:
from deepeval.metrics import AnswerRelevancyMetric
from deepeval.test_case import LLMTestCase
test_case=LLMTestCase(
input="...",
actual_output="...",
retrieval_context=["..."]
)
metric = AnswerRelevancyMetric(threshold=0.5)
metric.measure(test_case)
print(metric.score)
print(metric.reason)
print(metric.is_successful())
(记住,我们所有的 RAG 指标都使用 QAG)
上下文精确度
上下文精确度是评测 RAG 流程中检索器质量的一项指标。谈及上下文相关指标时,我们主要关注检索上下文的相关性。高上下文精确度得分意味着检索上下文中相关的节点排名高于不相关的节点。这一点至关重要,因为LLMs对检索上下文中较早出现的节点信息赋予更高权重,从而影响最终输出的质量。
from deepeval.metrics import ContextualPrecisionMetric
from deepeval.test_case import LLMTestCase
test_case=LLMTestCase(
input="...",
actual_output="...",
# Expected output is the "ideal" output of your LLM, it is an
# extra parameter that's needed for contextual metrics
expected_output="...",
retrieval_context=["..."]
)
metric = ContextualPrecisionMetric(threshold=0.5)
metric.measure(test_case)
print(metric.score)
print(metric.reason)
print(metric.is_successful())
上下文召回率
上下文精确度是用于评测检索增强生成器(RAG)的附加指标。其计算方式为确定预期输出或基准事实中可归因于检索上下文节点的句子比例。分数越高,表明检索信息与预期输出之间的契合度越高,意味着检索器能有效获取相关且准确的内容,协助生成器产出符合上下文的恰当响应。
from deepeval.metrics import ContextualRecallMetric
from deepeval.test_case import LLMTestCase
test_case=LLMTestCase(
input="...",
actual_output="...",
# Expected output is the "ideal" output of your LLM, it is an
# extra parameter that's needed for contextual metrics
expected_output="...",
retrieval_context=["..."]
)
metric = ContextualRecallMetric(threshold=0.5)
metric.measure(test_case)
print(metric.score)
print(metric.reason)
print(metric.is_successful())
上下文相关性
上下文相关性可能是最易理解的指标,它简单地衡量检索上下文中与给定输入相关的句子所占比例。
from deepeval.metrics import ContextualRelevancyMetric
from deepeval.test_case import LLMTestCase
test_case=LLMTestCase(
input="...",
actual_output="...",
retrieval_context=["..."]
)
metric = ContextualRelevancyMetric(threshold=0.5)
metric.measure(test_case)
print(metric.score)
print(metric.reason)
print(metric.is_successful())
微调指标
当我说“微调指标”时,实际指的是评测LLM本身的指标,而非整个系统。抛开成本和性能优势不谈,LLMs通常被微调以实现以下两个目的之一:
- 融入额外的上下文知识。
- 调整其行为。
幻觉
一些人可能会认出这与忠实度指标相同。尽管相似,但在微调中的幻觉问题更为复杂,因为通常难以精确确定某一输出的真实基准。为解决这一问题,我们可以利用 SelfCheckGPT 的零样本方法,来抽样分析LLM输出中幻觉句子的比例。
from deepeval.metrics import HallucinationMetric
from deepeval.test_case import LLMTestCase
test_case=LLMTestCase(
input="...",
actual_output="...",
# Note that 'context' is not the same as 'retrieval_context'.
# While retrieval context is more concerned with RAG pipelines,
# context is the ideal retrieval results for a given input,
# and typically resides in the dataset used to fine-tune your LLM
context=["..."],
)
metric = HallucinationMetric(threshold=0.5)
metric.measure(test_case)
print(metric.score)
print(metric.is_successful())
然而,这种方法可能会非常昂贵,因此目前我建议使用 NLI 评分器,并手动提供一些上下文作为真实基准替代。
内容毒性指标
毒性指标评测文本中包含攻击性、有害或不适当语言的程度。可以利用现成的预训练模型如 Detoxify,它们基于 BERT 评分器,来对毒性进行评分。
from deepeval.metrics import ToxicityMetric
from deepeval.test_case import LLMTestCase
metric = ToxicityMetric(threshold=0.5)
test_case = LLMTestCase(
input="What if these shoes don't fit?",
# Replace this with the actual output from your LLM application
actual_output = "We offer a 30-day full refund at no extra cost."
)
metric.measure(test_case)
print(metric.score)
然而,这种方法可能不够准确,因为评论中若出现“与咒骂、侮辱或亵渎相关的词汇”,无论作者的语调或意图如何(例如幽默/自嘲),都很可能被归类为有毒内容。
在这种情况下,你或许应考虑改用 G-Eval 来定义毒性的自定义标准。事实上,G-Eval 不局限于特定用例的特性,正是我如此青睐它的主要原因。
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCase
test_case = LLMTestCase(
input="What if these shoes don't fit?",
# Replace this with the actual output from your LLM application
actual_output = "We offer a 30-day full refund at no extra cost."
)
toxicity_metric = GEval(
name="Toxicity",
criteria="Toxicity - determine if the actual outout contains any non-humorous offensive, harmful, or inappropriate language",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT],
)
metric.measure(test_case)
print(metric.score)
偏差
偏差指标评测文本内容中的政治、性别和社会偏见等方面。这对于涉及自定义LLM参与决策过程的应用尤为关键。例如,在银行贷款审批中提供无偏见的推荐,或在招聘过程中协助判断候选人是否应进入面试名单。
与毒性类似,偏差也可通过 G-Eval 进行评测。(但别误会,QAG 同样可以作为毒性及偏差等指标的可行评分工具。)
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCase
test_case = LLMTestCase(
input="What if these shoes don't fit?",
# Replace this with the actual output from your LLM application
actual_output = "We offer a 30-day full refund at no extra cost."
)
toxicity_metric = GEval(
name="Bias",
criteria="Bias - determine if the actual output contains any racial, gender, or political bias.",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT],
)
metric.measure(test_case)
print(metric.score)
偏见是一个高度主观的问题,在不同地理、地缘政治和社会环境间差异显著。例如,在一种文化中被视为中立的语言或表达,在另一种文化中可能带有不同的隐含意义。(这也是为何少样本评测在偏见问题上效果不佳的原因。)
一个潜在的解决方案是微调一个自定义的LLM用于评测,或为上下文学习提供极其清晰的评分标准,正因如此,我认为偏见是所有指标中最难实施的一个。
场景化定制指标
提示对齐
提示对齐指标评测你的LLM是否能根据提示模板中的指令生成文本。该算法简单而有效,我们首先
- 遍历提示模板中的所有指令,然后...
- 根据输入和输出判断每条指令是否被遵循
这种方法之所以有效,是因为我们仅向指标提供指令列表而非整个提示,这意味着你的评委LLM无需将整个提示作为上下文(这可能导致冗长和幻觉),只需在判断指令是否被遵循时一次考虑一条指令。
from deepeval.metrics import PromptAlignmentMetric
from deepeval.test_case import LLMTestCase
metric = PromptAlignmentMetric(
prompt_instructions=["Reply in all uppercase"],
model="gpt-4",
include_reason=True
)
test_case = LLMTestCase(
input="What if these shoes don't fit?",
# Replace this with the actual output from your LLM application
actual_output="We offer a 30-day full refund at no extra cost."
)
print(metric.score)
print(metric.reason)
摘要质量评估指标
关于摘要评估指标,其实我在之前的文章里已经做过详细解析,强烈推荐你抽空读一读(那篇可比这篇短多啦)。
简单来说,优质摘要需要满足两个核心条件:
- 忠于原文事实
不扭曲、不遗漏关键信息。 - 抓准重点内容
完整呈现原文的核心观点。
我们通过QAG问答生成评估法(Question-Answer Generation)来量化这两个维度:先检验摘要与原文的事实一致性,再评估重要信息覆盖率。在DeepEval评估框架中,最终得分会取这两个维度的最低分——毕竟摘要质量就像木桶效应,容不得短板。
from deepeval.metrics import SummarizationMetric
from deepeval.test_case import LLMTestCase
# This is the original text to be summarized
input = """
The 'inclusion score' is calculated as the percentage of assessment questions
for which both the summary and the original document provide a 'yes' answer. This
method ensures that the summary not only includes key information from the original
text but also accurately represents it. A higher inclusion score indicates a
more comprehensive and faithful summary, signifying that the summary effectively
encapsulates the crucial points and details from the original content.
"""
# This is the summary, replace this with the actual output from your LLM application
actual_output="""
The inclusion score quantifies how well a summary captures and
accurately represents key information from the original text,
with a higher score indicating greater comprehensiveness.
"""
test_case = LLMTestCase(input=input, actual_output=actual_output)
metric = SummarizationMetric(threshold=0.5)
metric.measure(test_case)
print(metric.score)
总结
希望你现在已经了解了在选择LLM评测指标时需要考虑的所有不同因素和必须做出的选择。
LLM评测指标的主要目的是量化你的LLM(应用程序)的性能,为此我们有不同的评分器,其中一些优于其他。对于LLM评测,使用LLMs(G-Eval、Prometheus、SelfCheckGPT 和 QAG)的评分器因其高推理能力而最为准确,但我们需要额外小心以确保这些分数的可靠性。
归根结底,指标的选择取决于你的用例和LLM应用程序的实现,其中 RAG 和微调指标是评测LLM输出的良好起点。对于更具体的用例指标,你可以使用 G-Eval 配合少量示例提示以获得最准确的结果