|文末点击阅读原文查看网页版| 更多专栏文章点击查看:
LLM 架构专栏
大模型架构专栏文章阅读指南
Agent系列
强化学习系列
欢迎加入大模型交流群:加群链接 https://docs.qq.com/doc/DS3VGS0NFVHNRR0Ru#
公众号【柏企阅文
知乎【柏企】

在自然语言处理领域,评估自然语言系统生成文本的质量一直是一个重要课题。传统的评估指标,如BLEU和ROUGE,在许多情况下,尤其是在创意性或多样化的任务中,与人类的判断结果存在较大偏差。而且,这些指标依赖的“标准答案”获取成本非常高。

为了解决这些问题,一种名为G-Eval的全新框架应运而生。该框架引入了一种创新的方法,结合思维链(Chain-of-Thought, CoT)推理和结构化填空范式,有效提升了评估性能。在文本摘要和对话生成任务的测试中,由GPT-4驱动的G-Eval框架在文本摘要评估中,与人类评估的斯皮尔曼相关性达到了0.514,显著超越了以往的评估方法。

在深入探讨之前,我们先通过三个主要步骤来了解一下这个框架:

  1. 第一步:将任务介绍和评估标准输入到大型语言模型(LLM)中,指示它生成包含详细评估步骤的思维链。
  2. 第二步:结合当前的提示和生成的评估步骤,让LLM对自然语言生成(NLG)的输出进行评估。
  3. 第三步:利用输出评级标记的概率来计算最终的评估指标。

G-Eval主要在两个自然语言生成任务中进行了实验:

  1. 文本摘要
  2. 对话生成

方法论

G-Eval框架主要可以分为两个部分:

  1. 评估提示
  2. 评分函数

评估提示

G-Eval使用的提示主要包含3个部分:

  1. 任务介绍
  2. 评估标准
  3. 由LLM生成的思维链评估步骤

我们以“连贯性(coherence)”这个用于衡量生成摘要质量的指标为例,看看评估提示是怎样的。连贯性主要检查源文档中的关键点是否在摘要中有所涵盖。其评估提示内容如下:

  • 你将收到一篇新闻文章的摘要。
  • 你的任务是根据一个指标对该摘要进行评分。
  • 请仔细阅读并理解这些说明。在评估时请保持此文档打开,并根据需要进行参考。

评估标准

连贯性(1 - 5分):衡量所有句子的整体质量。我们将这个维度与DUC质量问题中的结构和连贯性保持一致,即“摘要应结构良好、组织有序。摘要不应只是一堆相关信息的堆砌,而应从一个句子到另一个句子,构建成一个关于某个主题的连贯信息体”。

评估步骤

  1. 仔细阅读新闻文章,确定主要主题和关键点。
  2. 阅读摘要,并将其与新闻文章进行比较。检查摘要是否涵盖了新闻文章的主要主题和关键点,以及是否以清晰、逻辑的顺序呈现它们。
  3. 根据评估标准,在1 - 5分的范围内为连贯性打分,1分为最低分,5分为最高分。

示例

  • 源文本:{{Document}}
  • 摘要:{{Summary}}
  • 评估表(仅分数):连贯性:

类似地,在G-Eval的论文中,你可以找到评估对话生成的提示。

评分函数

在G-Eval论文中,他们直接采用填空范式来执行评估任务。例如,在评估连贯性时,他们将提示(任务介绍和评估标准)、思维链(评估步骤)与新闻文章和摘要连接起来,然后调用LLM,根据定义的标准为每个评估方面输出一个1到5分的分数。

他们发现直接评分函数主要存在两个问题:

  1. 对于某些评估任务,某个数字往往会主导其他数字。例如在连贯性评估中,1 - 5分的评分里,3分出现的频率较高。这导致分数的方差较低,与人类判断的相关性也较低。
  2. 即使明确要求LLM输出小数值,它通常也只会输出整数值。这也导致评估分数之间出现很多相同的情况,难以得出结论。

为了解决这些问题,他们通过使用输出标记的概率对分数进行归一化处理,然后取加权总和作为最终结果。分数的计算公式如下(文中未明确给出具体公式,此处仅按描述示意):
[最终分数 = \frac{\sum_{i} (分数_{i} \times 概率_{i})}{\sum_{i}概率_{i}}]

具体实现

我们来看一下如何使用Python实现这个过程:

def get_score(response):
    """
    根据标记的概率计算最终分数
    Args:
        response: openai响应
    Returns:
        weighted_summed_score: 归一化后的分数
    """
    response = json.loads(response.json())
    generated_logprobs = response['choices'][0]['logprobs']['content']
    raw_score = response['choices'][0]['message']['content']
    predicted_token_logprobs = None
    for token_logprobs in generated_logprobs:
        if token_logprobs["token"] == str(raw_score):
            predicted_token_logprobs = token_logprobs
            break
    linear_probability: Dict[int, float] = {}
    min_logprob = math.log(0.01)
    sum_linear_probability = 0
    for token_info in predicted_token_logprobs['top_logprobs']:
        logprob = token_info['logprob']
        score_token = token_info["token"]
        if logprob < min_logprob:
            continue
        if not score_token.isdecimal():
            continue
        linear_prob = math.exp(logprob)
        score_token = str(int(score_token))
        if score_token in linear_probability.keys():
            linear_probability[score_token] += linear_prob
        if score_token not in linear_probability.keys():
            linear_probability[score_token] = linear_prob
        sum_linear_probability += linear_prob
    print(f"Total of {len(linear_probability.keys())} tokens for probability calculation detected: {linear_probability}")
    sum_of_weighted_scores = 0
    for score, prob in linear_probability.items():
        sum_of_weighted_scores += int(score) * float(prob)
    weighted_summed_score = (
        sum_of_weighted_scores / sum_linear_probability
    )
    return weighted_summed_score

在调用OpenAI时,我们启用了对数概率(log probability)功能。启用后,API会返回每个标记的对数概率,以及该位置最可能出现的有限数量的标记。这里的对数概率指的是在给定前文语境的情况下,每个标记在序列中特定位置出现的可能性。

首先,我们要找到预测分数标记的对数概率,示例如下:

{
    "token": "3",
    "bytes": [51],
    "logprob": -0.005407473,
    "top_logprobs": [
        {"token": "3", "bytes": [51], "logprob": -0.005407473},
        {"token": "Based", "bytes": [66, 97, 115, 101, 100], "logprob": -6.0054073},
        {"token": "Correct", "bytes": [67, 111, 114, 114, 101, 99, 116], "logprob": -6.2554073},
        {"token": "The", "bytes": [84, 104, 101], "logprob": -7.2554073}
    ]
}

接下来,我们过滤掉所有非数字的标记,然后提取分数标记及其相应概率的对(线性概率可以通过对数概率的指数运算得到)。将每个分数标记与其概率相乘并求和,最后将其除以线性概率的总和,得到最终分数。

实验设置

他们分别使用了GPT3.5和GPT4进行实验。由于GPT4不提供标记概率,他们使用了“n = 20, temperature = 1, top p = 1”的设置,进行20次采样来估计标记概率。

他们使用了以下3个基准来比较G-Eval和人类判断:

  1. SummaryEval:用于比较不同文本摘要评估方法(流畅性、连贯性、一致性和相关性)的基准。
  2. Topical-chat(对话生成任务):用于评估自然度、连贯性、吸引力和 groundedness。
  3. QAGS:用于衡量摘要中的幻觉现象。它旨在测量两个不同摘要数据集上摘要的一致性维度。

他们还将G-Eval指标与其他基线方法,如BERTScore、MoverScore、BARTScore、Unieval等进行了比较。

评估结果

  1. 文本摘要评估:他们使用斯皮尔曼(Spearman)和肯德尔tau(Kendall-Tau)相关性来评估摘要级别的指标。第一级指标(ROUGE-1、ROUGE-2、ROUGE-L)基于摘要和参考文本之间的语义相似性。第二级指标主要基于神经网络。从表格中可以看出,G-Eval的表现优于第一级指标。而且,基于GPT的摘要评估表现更好。我们还可以看到,G-Eval的概率指标比基于标记条件概率的GPTScore表现更优。
  2. 对话生成评估:他们对对话的每一轮使用皮尔逊(Pearson)和斯皮尔曼相关性进行评估。

  1. 幻觉评估:对于这部分,他们使用了皮尔逊、斯皮尔曼和肯德尔tau相关性进行评估。

分析

  1. 对基于LLM输出的偏差:在评估时,G-Eval大多情况下与人类的偏好一致。但它可能仍然更偏向于基于LLM(如gpt3.5)生成的摘要,而非人类生成的摘要。这是因为模型在生成和评估过程中可能会共享相同的评估标准概念。
  2. 思维链的影响:他们分别进行了有无思维链的评估实验,发现有思维链的情况下能得到更好的结果。
  3. 概率归一化的影响:不使用概率的直接评分可能会导致很多相同分数的情况,从而产生一致性或不一致性的配对。这可能会导致较高的肯德尔tau相关性,但并不能反映模型评估生成文本的真实能力。另一方面,概率归一化可以获得更细粒度、连续的分数,能够更好地捕捉生成文本之间的细微差异。
  4. 模型大小的影响:从实验中他们发现,gpt4在评估中的表现优于gpt3.5。因此,更大的模型规模也会对性能产生影响。

参考资料

  1. 论文链接
  2. 代码实现链接