基于大型语言模型的业务应用的增长带来了对这些应用提供的解决方案质量的衡量需求。这就是ROUGE等度量标准变得重要的地方。

到目前为止,我们一直使用传统模型的度量标准,如准确度、F1得分或召回率,这些度量标准无法帮助我们评估生成模型的结果。
对于这些模型,我们开始使用BLEU、ROUGE或METEOR等度量标准。这些度量标准与模型的目标相适应。
在本文中,我将解释如何使用ROUGE度量标准来衡量最新的大型语言模型生成的摘要的质量。
ROUGE是什么?
ROUGE由一组度量标准组成,用于比较生成的文本与参考文本的质量。
只要有参考文本可用,就可以使用它。其中一些最常见的应用包括翻译、文本摘要或实体提取等。
需要注意的是,ROUGE的可靠性取决于参考文本的质量。如果参考文本质量较差,ROUGE提供的结果可能无法正确反映生成文本的质量。
ROUGE的另一个用途是测量两个不同模型产生的输出有多大差异。也许我们想看看两个模型生成的文本之间是否存在显著差异。
此外,我们可以使用ROUGE来估计像修剪或量化(模型权重减少)这样的过程是否显著改变了我们的模型针对特定任务产生的结果。
提供的度量标准有:
- ROUGE-1:使用1-gram或个别单词指示生成文本与参考文本的匹配程度。
- ROUGE-2:与ROUGE-1相同,但考虑2-gram的集合。
- ROUGE-L:此度量标准评估两个文本之间最长公共子序列的单词匹配。单词不需要以完全相同的顺序出现。
有关ROUGE度量标准的更多信息,请访问:https://pypi.org/project/rouge-score/
我们将在笔记本中测量什么?
我们将使用一个基础的T5模型与一个用于生成摘要的经过微调的T5模型进行比较。
首先,我们将分析两个模型之间的差异,以确定微调过程是否产生了具有不同行为的模型。
然后,我们将使用CNN-DailyMail数据集中提供的参考文本来评估这两个模型,以查看哪个模型生成更好的摘要。
本文的源代码以及关于大型语言模型的整个课程可以在我的GitHub存储库中找到,其中还包括相应的英文文章。本文所使用的笔记本可以在以下链接中访问:https://github.com/peremartra/Large-Language-Model-Notebooks-Course/blob/main/rouge-evaluation-untrained-vs-trained-llm.ipynb
GitHub – peremartra/Large-Language-Model-Notebooks-Course
通过在GitHub上创建账号为peremartra/Large-Language-Model-Notebooks-Course做贡献。
github.com
使用的模型可以在Hugging Face上找到。
- 经过微调的:t5-Base:https://huggingface.co/flax-community/t5-base-cnn-dm
- 基础的:t5-Base:https://huggingface.co/t5-base
加载数据。
在文章的第一部分中,我们将使用Kaggle上可用的包含MIT新闻的数据集,该数据集没有生成的摘要。这个数据集将用于验证两个加载的模型生成的摘要是否足够不同。
数据集链接:https://www.kaggle.com/datasets/deepanshudalal09/mit-ai-news-published-till-2023
让我们从导入典型的Python库开始:
#导入通用库import numpy as np import pandas as pdimport torch
这些都是Python世界中众所周知的库。导入torch是必要的,因为ROUGE需要它。
让我们加载数据集。
news = pd.read_csv('/kaggle/input/mit-ai-news-published-till-2023/articles.csv')DOCUMENT="Article Body"#因为这只是一个课程,我们选择了一小部分新闻.MAX_NEWS = 3subset_news = news.head(MAX_NEWS)subset_news.head()

完整的文章内容包含在列Article Body中。这是我们需要的数据集中的唯一字段。
我们只选择了三篇文章以加快笔记本的执行速度。
articles = subset_news[DOCUMENT].tolist()
我们将三篇加载的文章的完整文本存储在名为articles的变量中。如果我们想要使用更多或更少的新闻文章进行工作,只需更改变量MAX_NEWS的值即可。
加载模型并生成摘要。
使用的两个模型都来自T5系列。其中一个是基础的T5-Base模型,另一个是从T5-Base派生并经过CNN-DailyMail数据集微调的模型。
由于这两个模型都在Hugging Face上可用,我们将使用transformers库。
import transformersfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM#模型名称存储在变量model_name_small和model_name_reference中。model_name_small = "t5-base"model_name_reference = "flax-community/t5-base-cnn-dm"
为了获得标记器和模型,我创建了以下函数:
#此函数返回标记器和模型。 def get_model(model_id): tokenizer = AutoTokenizer.from_pretrained(model_id) model = AutoModelForSeq2SeqLM.from_pretrained(model_id) return tokenizer, model
此函数接收model_id作为输入,并返回加载的模型和标记器。
标记器用于将文本转换为可以由模型处理的令牌序列。
使用get_model函数,我们可以获得两个标记器和模型:
tokenizer_small, model_small = get_model(model_name_small)tokenizer_reference, model_reference = get_model(model_name_reference)
为了生成摘要,我们将创建一个函数,该函数接受四个参数:
- 要进行摘要的文本列表。
- 标记器。
- 模型。
- 所得摘要的最大长度。
该函数应该对要摘要的文章的文本进行一些格式化。这涉及在每篇文章之前加入一个前缀。这个前缀将由模型的指令组成。在我们的情况下,我们希望模型对文章进行摘要,所以要添加的前缀将是:“Summarize this news:”。
使用标记器,每篇文章将被转换为编码,然后发送给模型。模型将返回一个摘要,需要将其解码并从编码转换为文本。
def create_summaries(texts_list, tokenizer, model, max_l=125): #我们将为要摘要的每篇文章添加一个前缀,以便模型知道它应该做什么。 prefix = "Summarize this news: " summaries_list = [] #将包含所有摘要的列表 texts_list = [prefix + text for text in texts_list] for text in texts_list: summary="" #计算编码 input_encodings = tokenizer(text, max_length=1024, return_tensors='pt', padding=True, truncation=True) #生成摘要 with torch.no_grad(): output = model.generate( input_ids=input_encodings.input_ids, attention_mask=input_encodings.attention_mask, max_length=max_l, #设置生成的摘要的最大长度 num_beams=2, #设置用于搜索的beam数量 early_stopping=True ) #解码以获得文本 summary = tokenizer.batch_decode(output, skip_special_tokens=True) #将摘要添加到摘要列表 summaries_list += summary return summaries_list
让我们来看一下函数代码的一个具体部分:用于生成摘要的模型调用:
# 生成摘要 with torch.no_grad(): output = model.generate( input_ids=input_encodings.input_ids, attention_mask=input_encodings.attention_mask, max_length=max_l, # 设置生成摘要的最大长度 num_beams=2, # 设置波束搜索的数量 early_stopping=True )
正如你所看到的,我们用这行代码开始了代码块:with torch.no_grad(),这表示我们不希望在代码块内计算梯度。这提高了代码的速度。
然后我们调用model.generate,并传入以下参数:
- input_ids:表示标记化输入文本的编码。
- attention_mask:由标记器提供的注意力掩码。
- max_length:模型回复的最大长度。
- beams:波束数量越大,模型生成的回复多样性越大。我们将其设置为2以引入一些变化。
- early_stopping:此参数允许模型在回复达到最大长度之前停止生成文本。将其值设置为True是一个好习惯。
让我们看看如何调用create_summaries函数来获取摘要:
# 为两个模型创建摘要。summaries_small = create_summaries(articles, tokenizer_small, model_small)summaries_reference = create_summaries(articles, tokenizer_reference, model_reference)
正如你所看到的,非常简单。你只需要传入要摘要的文本、标记器和模型。
让我们来看看这两个模型生成的摘要:
summaries_small: [‘MIT和MIT-Watson AI实验室开发了一个统一的框架,该系统可以同时预测分子性质和生成新的分子。它使用这个语法来构造可行的分子并预测它们的性质。’, ‘“BioAutoMATED”是一个自动化的机器学习系统,可以为给定的数据集选择和构建一个适当的模型。它甚至可以处理繁琐的数据预处理任务,将几个月的过程缩短为几个小时。“我们希望为那些想要使用机器学习或生物学的人降低这些障碍,”首席合著者Jacqueline Valeri说。’, ‘MIT和IBM的研究科学家通过训练计算机视觉模型以像人类和其他灵长类动物依赖于对象识别的大脑部分一样工作来增强了其鲁棒性。“我们要求人工神经网络使其内部模拟的“神经”层的功能尽可能与相应的生物神经层相似,”MIT教授说。’]
summaries_reference: [‘研究人员创建了一个机器学习系统,该系统仅使用小型的领域特定数据集自动学习分子的“语言”。该系统学会构造可行的分子并预测它们的性质。计算设计和制造组将在国际机器学习会议上展示。’, ‘自动化的机器学习系统可以选择和构建一个适当的模型,适用于给定的数据集。“BioAutoMATED”是一个自动化的机器学习系统。该工具包括二元分类模型、多类分类模型和更复杂的神经网络。’, ‘MIT和IBM的研究人员发现人工神经网络类似于处理人类和其他灵长类动物中的视觉信息的多层脑电路。“我们要求它同时做这两件事,以及标准的计算机视觉方法,”一位专家说。该网络通过训练使其工作方式类似于人类依赖于对象识别的大脑部分,发现其更具鲁棒性。’]
乍一看,你就可以观察到生成的摘要是不同的。然而,仅仅通过摘要来确定哪一个对我们的需求更好是困难的。
为了确定摘要是否显著不同,我们将使用ROUGE。当比较两个生成的摘要时,其中没有一个作为参考摘要,我们并没有了解生成摘要质量本身。相反,我们获得了结果之间有多大不同的指示。这样可以让我们确定微调过程是否对摘要的结果产生了一些影响。
计算 ROUGE
让我们安装和加载必要的库,以便我们可以运行 ROUGE 指标。
虽然有几个库可以实现 ROUGE 计算,但我决定使用 evaluate 库。有时,选择是基于熟悉度,这是我习惯使用的库。
!pip install evaluate import evaluatefrom nltk.tokenize import sent_tokenize#使用 evaluate 库的 load 函数 #我们创建一个 rouge_score 对象rouge_score = evaluate.load("rouge")
一旦导入了这些库,计算 ROUGE 指标就只需要对刚刚创建的 rouge_score 对象调用一次 compute 函数。
将文本传递给此函数,以及第三个参数,指示您是要使用单词词干(词元)还是整个单词进行比较。通常只比较词干,这样像“jump”和“jumped”这样的单词被视为相等。
以下是一些词元示例:
- Jumping → Jump。
- Running → Run。
- Cats → Cat。
当对 steamer 参数使用 True 时,具有相同词干的单词被视为相等,而使用 False 则将它们视为不同的单词。
但是,重要的是要对文本进行一些准备工作,例如在每行开头添加换行符并删除空字符。为此,让我们创建 compute_rouge_score 函数:
def compute_rouge_score(generated, reference): #我们需要在每行之前添加 '\n' 才能将其发送到 ROUGE generated_with_newlines = ["\n".join(sent_tokenize(s.strip())) for s in generated] reference_with_newlines = ["\n".join(sent_tokenize(s.strip())) for s in reference] return rouge_score.compute( predictions=generated_with_newlines, references=reference_with_newlines, use_stemmer=True, )
如您所见,此函数通过为每个句子添加换行符修改接收的参数文本。然后,它只需一次调用 rouge_score.compute 函数。
compute_rouge_score(summaries_small, summaries_reference)
在此调用中,我们传递了使用 T5 Base 模型和经过微调的 T5 模型生成的文本。它返回的结果是:
{‘rouge1’: 0.47018752391886715, ‘rouge2’: 0.3209013209013209, ‘rougeL’: 0.34330271718331423, ‘rougeLsum’: 0.44692881745120555}
我们可以看到 ROUGE-1 的相似度为 47%,而 ROUGE-2 的相似度为 32%。这明确表明两个模型生成的摘要是不同的,有些相似但存在显著差异,表明微调过程影响了模型生成摘要的方式。
然而,我们还不能确定哪个模型更好,因为我们还没有与任何参考文本进行比较。
与参考文本比较。
现在我们将使用第二个数据集:CNN_Dailymail,这是一个著名的数据集,是 Datasets 库的一部分。
除了文章,该数据集还包含人工生成的摘要,我们将使用它们作为参考文本。
我们将把两个模型生成的摘要与数据集中的参考摘要进行比较。这将帮助我们确定哪个模型生成的摘要与提供的参考文本更相似。
from datasets import load_datasetcnn_dataset = load_dataset( "cnn_dailymail", version="3.0.0")#仅获取一些新闻进行测试sample_cnn = cnn_dataset["test"].select(range(MAX_NEWS))sample_cnn
与文章的第一部分一样,我们只加载了有限数量的新闻。这有助于控制执行时间。
我们获取数据集中所选摘要的最大长度,以指示我们希望模型生成的响应具有的最大长度。
max_length = max(len(item['highlights']) for item in sample_cnn)max_length = max_length + 10
我们现在已经具备了生成摘要所需的所有条件。
summaries_t5_base = create_summaries(sample_cnn["article"], tokenizer_small, model_small, max_l=max_length)summaries_t5_finetuned = create_summaries(sample_cnn["article"], tokenizer_reference, model_reference, max_l=max_length)#从cnn_dataset获取真实摘要real_summaries = sample_cnn['highlights']
有了这三个摘要各自的变量后,我们来看一下内容。
summaries = pd.DataFrame.from_dict( { "base": summaries_t5_base, "finetuned": summaries_t5_finetuned, "reference": real_summaries, } )summaries.head()

事实上,一眼之间很难知道哪个模型创建的摘要更好。
让我们计算两个模型的ROUGE指标。
compute_rouge_score(summaries_t5_base, real_summaries)
summaries_t5_base: {‘rouge1’: 0.3050834824090638, ‘rouge2’: 0.07211128178870115, ‘rougeL’: 0.2095520274299344, ‘rougeLsum’: 0.2662418008348241}
compute_rouge_score(summaries_t5_finetuned, real_summaries)
summaries_t5_finetuned: {‘rouge1’: 0.31659149328289443, ‘rouge2’: 0.11065084340946411, ‘rougeL’: 0.22002036956205442, ‘rougeLsum’: 0.24877540132887144}
根据这些结果,我认为微调模型比T5-Base模型生成的摘要更好。这是基于微调模型在所有指标上都获得了更高的分数,只是在LSUM上的差异很小。
还需要注意的是,ROUGE指标非常易于解释,并不提供绝对真理。换句话说,一个模型的ROUGE分数较高,并不意味着它一定比其他模型更好。这些分数只表明它生成的文本与参考文本的相似度更高。
这两个模型的结果非常相似,但微调模型在所有指标上都获得了更高的分数,特别是在ROUGE-2和ROUGE-L上,只是在ROUGE-LSUM上稍有差异。这意味着基础模型可能生成更相似的文本,而微调模型则使用与参考文本更相似的词汇。
无论如何,我们不能得出明确的结论,因为我们只分析了少数摘要。要确定哪个模型最好,我们需要采用不同的策略。一个好的方法是:按主题对新闻进行分组,并检查结果是否存在显著差异。
结论。
单纯的指标是不够的,即使是ROUGE也不足以满足我们的需求,因为它在很大程度上取决于我们作为参考的文本的质量。
人的因素仍然非常重要,以检查回答的适用性。这就是为什么那些经过人工介入训练的模型取得成功的原因。
至少我们有一个好消息:获取ROUGE等指标相当容易,这可以帮助我们在决策过程中进行判断,有助于我们做出更好的模型评估。
关于大型语言模型的完整课程 可在Github上找到。要保持更新,请考虑关注或点赞该存储库。 这样,您将在添加新内容时收到通知。
GitHub – peremartra/Large-Language-Model-Notebooks-Course
通过在GitHub上创建一个帐户来为peremartra/Large-Language-Model-Notebooks-Course做出贡献。
github.com
我经常写关于深度学习和人工智能的文章。考虑关注我在VoAGI上以获取新文章的更新。当然,你也可以通过LinkedIn与我联系。