Evaluate 文档
使用评估器
并获得增强的文档体验
开始使用
使用评估器
Evaluator
类允许对模型、数据集和指标三元组进行评估。这些模型被封装在一个管道中,负责处理所有预处理和后处理。开箱即用的 Evaluator
支持已支持任务的 transformers 管道,但也可以传递自定义管道,如 使用 evaluator
与自定义管道 部分所示。
目前支持的任务有:
"text-classification"
: 将使用 TextClassificationEvaluator。"token-classification"
: 将使用 TokenClassificationEvaluator。"question-answering"
: 将使用 QuestionAnsweringEvaluator。"image-classification"
: 将使用 ImageClassificationEvaluator。"text-generation"
: 将使用 TextGenerationEvaluator。"text2text-generation"
: 将使用 Text2TextGenerationEvaluator。"summarization"
: 将使用 SummarizationEvaluator。"translation"
: 将使用 TranslationEvaluator。"automatic-speech-recognition"
: 将使用 AutomaticSpeechRecognitionEvaluator。"audio-classification"
: 将使用 AudioClassificationEvaluator。
要在单次调用中运行一个包含多个任务的 Evaluator
,请使用 EvaluationSuite,它对一组 SubTask
进行评估。
每个任务对数据集格式和管道输出都有自己的要求,请确保为您的自定义用例检查这些要求。让我们看一些例子,了解如何使用评估器同时评估单个或多个模型、数据集和指标。
文本分类
文本分类评估器可用于评估文本模型在分类数据集(如 IMDb)上的表现。除了模型、数据和指标输入外,它还接受以下可选输入:
input_column="text"
:此参数用于指定包含管道数据的列。label_column="label"
:此参数用于指定包含用于评估的标签的列。label_mapping=None
:标签映射将管道输出中的标签与评估所需的标签对齐。例如,label_column
中的标签可能是整数(0
/1
),而管道可能产生标签名称,如"positive"
/"negative"
。通过这个字典,管道输出被映射到标签。
默认情况下,计算 "accuracy"
指标。
评估 Hub 上的模型
有多种方法可以将模型传递给评估器:您可以传递 Hub 上模型的名称,可以加载一个 transformers
模型并将其传递给评估器,或者可以传递一个已初始化的 transformers.Pipeline
。此外,您还可以传递任何行为类似于该任务的 pipeline
调用的可调用函数,无论使用何种框架。
因此,以下任何一种方式都可行:
from datasets import load_dataset
from evaluate import evaluator
from transformers import AutoModelForSequenceClassification, pipeline
data = load_dataset("imdb", split="test").shuffle(seed=42).select(range(1000))
task_evaluator = evaluator("text-classification")
# 1. Pass a model name or path
eval_results = task_evaluator.compute(
model_or_pipeline="lvwerra/distilbert-imdb",
data=data,
label_mapping={"NEGATIVE": 0, "POSITIVE": 1}
)
# 2. Pass an instantiated model
model = AutoModelForSequenceClassification.from_pretrained("lvwerra/distilbert-imdb")
eval_results = task_evaluator.compute(
model_or_pipeline=model,
data=data,
label_mapping={"NEGATIVE": 0, "POSITIVE": 1}
)
# 3. Pass an instantiated pipeline
pipe = pipeline("text-classification", model="lvwerra/distilbert-imdb")
eval_results = task_evaluator.compute(
model_or_pipeline=pipe,
data=data,
label_mapping={"NEGATIVE": 0, "POSITIVE": 1}
)
print(eval_results)
如果不指定设备,模型推理的默认设备将是机器上的第一个 GPU(如果有),否则为 CPU。如果您想使用特定设备,可以向 compute
传递 device
,其中 -1 将使用 GPU,而正整数(从 0 开始)将使用相应的 CUDA 设备。
结果将如下所示:
{
'accuracy': 0.918,
'latency_in_seconds': 0.013,
'samples_per_second': 78.887,
'total_time_in_seconds': 12.676
}
请注意,评估结果不仅包括所请求的指标,还包括通过管道获得预测所需的时间信息。
时间性能可以为模型推理速度提供有用的指示,但应谨慎对待:它们包括管道中进行的所有处理。这可能包括分词、后处理等,这些过程可能因模型而异。此外,它很大程度上取决于您运行评估的硬件,您或许可以通过优化批量大小等来提高性能。
评估多个指标
通过 combine() 函数,可以将多个指标捆绑到一个行为类似于单个指标的对象中。我们可以利用这一点同时使用评估器评估多个指标。
import evaluate
eval_results = task_evaluator.compute(
model_or_pipeline="lvwerra/distilbert-imdb",
data=data,
metric=evaluate.combine(["accuracy", "recall", "precision", "f1"]),
label_mapping={"NEGATIVE": 0, "POSITIVE": 1}
)
print(eval_results)
结果将如下所示:
{
'accuracy': 0.918,
'f1': 0.916,
'precision': 0.9147,
'recall': 0.9187,
'latency_in_seconds': 0.013,
'samples_per_second': 78.887,
'total_time_in_seconds': 12.676
}
接下来,让我们看看分词分类。
分词分类
使用分词分类评估器,可以评估用于 NER 或 POS 标注等任务的模型。它具有以下特定参数:
input_column="text"
:此参数用于指定包含管道数据的列。label_column="label"
:此参数用于指定包含用于评估的标签的列。label_mapping=None
:标签映射将管道输出中的标签与评估所需的标签对齐。例如,label_column
中的标签可能是整数(0
/1
),而管道可能产生标签名称,如"positive"
/"negative"
。通过这个字典,管道输出被映射到标签。join_by=" "
:虽然大多数数据集已经分词,但管道期望输入为字符串。因此,在传递给管道之前需要将分词连接起来。默认情况下,它们用空格连接。
让我们看看如何使用评估器对多个模型进行基准测试。
对多个模型进行基准测试
这是一个示例,展示了如何借助 evaluator
在几行代码内比较多个模型,它抽象了预处理、推理、后处理和指标计算等过程。
import pandas as pd
from datasets import load_dataset
from evaluate import evaluator
from transformers import pipeline
models = [
"xlm-roberta-large-finetuned-conll03-english",
"dbmdz/bert-large-cased-finetuned-conll03-english",
"elastic/distilbert-base-uncased-finetuned-conll03-english",
"dbmdz/electra-large-discriminator-finetuned-conll03-english",
"gunghio/distilbert-base-multilingual-cased-finetuned-conll2003-ner",
"philschmid/distilroberta-base-ner-conll2003",
"Jorgeutd/albert-base-v2-finetuned-ner",
]
data = load_dataset("conll2003", split="validation").shuffle().select(range(1000))
task_evaluator = evaluator("token-classification")
results = []
for model in models:
results.append(
task_evaluator.compute(
model_or_pipeline=model, data=data, metric="seqeval"
)
)
df = pd.DataFrame(results, index=models)
df[["overall_f1", "overall_accuracy", "total_time_in_seconds", "samples_per_second", "latency_in_seconds"]]
结果是一个如下所示的表格:
模型 | overall_f1 | overall_accuracy | total_time_in_seconds | samples_per_second | latency_in_seconds |
---|---|---|---|---|---|
Jorgeutd/albert-base-v2-finetuned-ner | 0.941 | 0.989 | 4.515 | 221.468 | 0.005 |
dbmdz/bert-large-cased-finetuned-conll03-english | 0.962 | 0.881 | 11.648 | 85.850 | 0.012 |
dbmdz/electra-large-discriminator-finetuned-conll03-english | 0.965 | 0.881 | 11.456 | 87.292 | 0.011 |
elastic/distilbert-base-uncased-finetuned-conll03-english | 0.940 | 0.989 | 2.318 | 431.378 | 0.002 |
gunghio/distilbert-base-multilingual-cased-finetuned-conll2003-ner | 0.947 | 0.991 | 2.376 | 420.873 | 0.002 |
philschmid/distilroberta-base-ner-conll2003 | 0.961 | 0.994 | 2.436 | 410.579 | 0.002 |
xlm-roberta-large-finetuned-conll03-english | 0.969 | 0.882 | 11.996 | 83.359 | 0.012 |
可视化结果
您可以将上述 results
列表输入到 plot_radar()
函数中,以可视化其性能的不同方面,并根据与您的用例相关的指标选择最适合的模型。
import evaluate
from evaluate.visualization import radar_plot
>>> plot = radar_plot(data=results, model_names=models, invert_range=["latency_in_seconds"])
>>> plot.show()

对于值越小越好的指标(例如秒级延迟),请不要忘记指定 invert_range
。
如果您想将图表保存在本地,可以使用 plot.savefig()
函数,并带有 bbox_inches='tight'
选项,以确保图像的任何部分都不会被裁剪掉。
问答
使用问答评估器,可以评估 QA 模型,而无需担心这些模型所需的复杂预处理和后处理。它具有以下特定参数:
question_column="question"
:数据集中包含问题的列的名称。context_column="context"
:包含上下文的列的名称。id_column="id"
:包含问答对标识字段的列的名称。label_column="answers"
:包含答案的列的名称。squad_v2_format=None
:数据集是否遵循 squad_v2 数据集格式,其中问题可能在上下文中没有答案。如果未提供此参数,将自动推断格式。
让我们看看如何评估 QA 模型并同时计算置信区间。
置信区间
每个评估器都提供了使用自助法计算置信区间的选项。只需传递 strategy="bootstrap"
并使用 n_resamples
设置重采样次数即可。
from datasets import load_dataset
from evaluate import evaluator
task_evaluator = evaluator("question-answering")
data = load_dataset("squad", split="validation[:1000]")
eval_results = task_evaluator.compute(
model_or_pipeline="distilbert-base-uncased-distilled-squad",
data=data,
metric="squad",
strategy="bootstrap",
n_resamples=30
)
结果包括置信区间和误差估计,如下所示:
{
'exact_match':
{
'confidence_interval': (79.67, 84.54),
'score': 82.30,
'standard_error': 1.28
},
'f1':
{
'confidence_interval': (85.30, 88.88),
'score': 87.23,
'standard_error': 0.97
},
'latency_in_seconds': 0.0085,
'samples_per_second': 117.31,
'total_time_in_seconds': 8.52
}
图像分类
通过图像分类评估器,我们可以评估任何图像分类器。它使用与文本分类器相同的关键字参数:
input_column="image"
:包含 PIL ImageFile 格式图像的列的名称。label_column="label"
:包含标签的列的名称。label_mapping=None
:我们希望将管道中模型定义的类标签映射为与label_column
中定义的值一致的值。
让我们看看如何在大型数据集上评估图像分类模型。
处理大型数据集
评估器可以在大型数据集上使用!下面是一个示例,展示了如何在 ImageNet-1k 数据集上进行图像分类。请注意,此示例需要下载约 150 GB 的数据。
data = load_dataset("imagenet-1k", split="validation", token=True)
pipe = pipeline(
task="image-classification",
model="facebook/deit-small-distilled-patch16-224"
)
task_evaluator = evaluator("image-classification")
eval_results = task_evaluator.compute(
model_or_pipeline=pipe,
data=data,
metric="accuracy",
label_mapping=pipe.model.config.label2id
)
由于我们使用 datasets
来存储数据,我们利用了一种称为内存映射的技术。这意味着数据集永远不会完全加载到内存中,从而节省了大量 RAM。运行上述代码仅使用约 1.5 GB 的 RAM,而验证集的大小超过 30 GB。