评估文档
使用 `evaluator`
并获得增强的文档体验
开始使用
使用 evaluator
Evaluator
类允许评估模型、数据集和指标的三元组。模型被封装在 pipeline 中,负责处理所有预处理和后处理并开箱即用。Evaluator
支持受支持任务的 transformers pipelines,但可以传递自定义 pipelines,如 将 evaluator
与自定义 pipelines 一起使用 部分所示。
当前支持的任务有
"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。
要在单个调用中运行具有多个任务的 Evaluator
,请使用 EvaluationSuite,它在 SubTask
s 的集合上运行评估。
每个任务对数据集格式和 pipeline 输出都有自己的一组要求,请务必查看它们以了解您的自定义用例。让我们看看其中的一些,看看如何使用 evaluator 同时评估单个或多个模型、数据集和指标。
文本分类
文本分类 evaluator 可用于评估文本模型在分类数据集上的性能,例如 IMDb。除了模型、数据和指标输入外,它还接受以下可选输入
input_column="text"
:使用此参数可以指定包含 pipeline 数据的列。label_column="label"
:使用此参数可以指定包含评估标签的列。label_mapping=None
:标签映射将 pipeline 输出中的标签与评估所需的标签对齐。例如,label_column
中的标签可以是整数 (0
/1
),而 pipeline 可以生成标签名称,例如"positive"
/"negative"
。通过该字典,pipeline 输出被映射到标签。
默认情况下,计算 "accuracy"
指标。
在 Hub 上评估模型
有几种方法可以将模型传递给 evaluator:您可以传递 Hub 上模型的名称,您可以加载 transformers
模型并将其传递给 evaluator,或者您可以传递初始化的 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。如果您想使用特定设备,可以将 device
传递给 compute
,其中 -1 将使用 GPU,正整数(从 0 开始)将使用关联的 CUDA 设备。
结果将如下所示
{
'accuracy': 0.918,
'latency_in_seconds': 0.013,
'samples_per_second': 78.887,
'total_time_in_seconds': 12.676
}
请注意,评估结果包括请求的指标以及通过 pipeline 获取预测所花费的时间信息。
时间性能可以给出模型推理速度的有用指示,但应谨慎对待:它们包括 pipeline 中发生的所有处理。这可能包括分词、后处理,这可能因模型而异。此外,这在很大程度上取决于您运行评估的硬件,您可以通过优化批量大小等事项来提高性能。
评估多个指标
通过 combine() 函数,可以将多个指标捆绑到一个对象中,该对象的行为类似于单个指标。我们可以使用它通过 evaluator 一次评估多个指标
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
}
接下来,让我们看看 token 分类。
Token 分类
使用 token 分类 evaluator 可以评估 NER 或 POS 标记等任务的模型。它具有以下特定参数
input_column="text"
:使用此参数可以指定包含 pipeline 数据的列。label_column="label"
:使用此参数可以指定包含评估标签的列。label_mapping=None
:标签映射将 pipeline 输出中的标签与评估所需的标签对齐。例如,label_column
中的标签可以是整数 (0
/1
),而 pipeline 可以生成标签名称,例如"positive"
/"negative"
。通过该字典,pipeline 输出被映射到标签。join_by=" "
:虽然大多数数据集已经分词,但 pipeline 期望的是字符串。因此,token 需要在传递到 pipeline 之前连接起来。默认情况下,它们用空格连接。
让我们看看如何使用 evaluator 来基准测试多个模型。
基准测试多个模型
这是一个示例,借助 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(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'
,以确保图像的任何部分都不会被裁剪掉。
问答
使用问答 evaluator 可以评估 QA 模型,而无需担心这些模型所需的复杂预处理和后处理。它具有以下特定参数
question_column="question"
:数据集中包含问题的列的名称context_column="context"
:包含上下文的列的名称id_column="id"
:包含问题和答案对的标识字段的列的名称label_column="answers"
:包含答案的列的名称squad_v2_format=None
:数据集是否遵循 squad_v2 数据集的格式,其中问题可能在上下文中没有答案。如果未提供此参数,将自动推断格式。
让我们看看如何评估 QA 模型并同时计算置信区间。
置信区间
每个 evaluator 都带有使用 bootstrapping 计算置信区间的选项。只需传递 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
}
图像分类
使用图像分类 evaluator,我们可以评估任何图像分类器。它使用与文本分类器相同的关键字参数
input_column="image"
:包含作为 PIL ImageFile 的图像的列的名称label_column="label"
:包含标签的列的名称label_mapping=None
:我们希望将 pipeline 中模型定义的类标签映射到与label_column
中定义的值一致的值
让我们看看如何在大型数据集上评估图像分类模型。
处理大型数据集
evaluator 可以用于大型数据集!下面,一个示例展示了如何在 ImageNet-1k 上用于图像分类。请注意,此示例将需要下载约 150 GB。
data = load_dataset("imagenet-1k", split="validation", use_auth_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 大。