如何无需数日人工标注即可构建自定义文本分类器
大型语言模型(LLM)在提供少量示例时,作为文本分类器表现相当不错。然而,它们在规模化运行时成本高昂,对于某些实际场景不可行,并且在专业领域其性能会下降。另一方面,专用分类器具有低延迟性,并可能在 CPU 上运行,但它们需要标注的训练数据。
在这篇文章中,我们将展示如何利用 LLM 的反馈来训练一个分类器,以部署一个小型模型,而无需数日的人工标注。
适用人群
- 需要高效标注领域数据的数据科学家。
- 资源受限但需要有效模型的机器学习工程师。
- 希望熟悉应用机器学习的新手。
高质量的训练数据对于开发可靠的模型至关重要。虽然 LLM 有助于减少训练机器学习模型所需的人工输入量,但添加人工反馈可以显著提高模型质量。简化此过程的工具之一是 `distilabel` 库,它利用 LLM 增强标注工作流程。对于文本分类,`ArgillaLabeller` 任务使用 LLM 对 Argilla 上托管的数据集进行标注,Argilla 是一款现代、开源、以数据为中心的人工智能数据集改进工具。这种集成结合了两者的优点:LLM 的自动标注能力和人类专家的高质量注释。
本文将解释如何结合大型语言模型(LLM)和人工反馈来构建文本分类模型,从而大大缩短在特定用例中部署监督模型所需的时间。
本文详细介绍了以下步骤
- 通过定义其字段、标签和标注指南来自动标注数据集。
- 人工审查和改进 LLM 建议的标签。
- 训练一个专门的 SetFit 模型,并将其与 LLM 少量样本分类器进行比较。
定义您的数据集
第一步是配置您的 Argilla 数据集。这意味着您需要定义将包含待标注数据、标签和指南的字段。您可以根据您的用例完全灵活地自定义这些元素,使其与您的项目目标保持一致。
在此示例中,我们正在定义一个用于情感分类的数据集。
settings = rg.Settings(
fields=[
rg.TextField(
name="text",
title="Text",
description="Provide a concise response to the prompt",
)
],
questions=[
rg.LabelQuestion(
name="label",
title="Emotion",
description="Provide a single label for the sentiment of the text",
labels=["positive", "neutral", "negative"],
)
],
guidelines = "We are dealing with input data about detailed customer reviews of 3 corresponding labels: positive, negative, and neutral."
)
接下来,您可以使用已定义的设置创建数据集并添加要标注的数据。在本例中,我们将使用来自 Hub 的 argilla/pc-components-reviews 数据集。
dataset = rg.Dataset.from_hub(
repo_id="argilla/pc-components-reviews",
name="pc-components",
split="train",
with_records=True,
settings=settings,
)
在下一步中,distilabel 将使用此数据集及其配置,通过 LLM 对其进行自动标注。这意味着,在底层,distilabel 将检索 Argilla 的数据并将其格式化为提示模板,以指导 LLM 理解标注任务。您可以查阅附录中的提示模板以供参考。
自动标注
下一步是运行 distilabel 以开始自动标注,如下方视频所示
要使用 LLM 标注记录,您需要使用情感分类数据集设置 `ArgillaLabeller`。您可以选择添加一些示例记录以进行少量样本设置。
labeller = ArgillaLabeller(
llm=InferenceEndpointsLLM(
model_id="meta-llama/Llama-3.1-8B-Instruct",
tokenizer_id="meta-llama/Llama-3.1-8B-Instruct"
),
example_records=example_records,
)
labeller.load()
一旦您使用数据集运行 `ArgillaLabeller`,它将自动标注数据集。建议的标签将在 Argilla 用户界面中供人工审查。
suggestion = next(
labeller.process(
[
{
"record": record,
"fields": dataset.fields,
"question": dataset.questions[0],
"guidelines": dataset.guidelines,
}
]
)
)
record.suggestions.add(rg.Suggestion(**suggestion["suggestion"]))
dataset.records.log(record)
这种方法简化了标注过程,允许您实时自动标注数据,同时通过人工反馈进行完善。这种方法强大而通用,开箱即用就能提供良好的性能,特别是对于简单的流程。通过自动化大部分过程,您可以节省时间和精力,避免数天甚至数周的手动标注。同时,它确保了人工仍参与其中,使其成为为您的项目构建高质量数据集的有效方式。
从大型语言模型到小型模型
最后一步是使用标注数据训练我们的专用模型。这些数据已由 LLM 自动标注,然后通过 Argilla UI 借助人工反馈得到改进。目标是训练一个小型专用模型,使其针对您的用例进行优化,而无需依赖 LLM 进行推理。在本示例中,我们将使用 SetFit,一个强大的文本分类库。
如果您不熟悉该库,请查看其 GitHub 存储库。SetFit 即使在标记数据量很小的情况下也能达到高精度——例如,在客户评论情感数据集上,每类仅使用 8 个标记示例,SetFit 的性能就可与在包含 3k 个示例的完整训练集上对 RoBERTa Large 进行微调相媲美 🤯!
SetFit 首先对一个句子转换器模型进行微调,以生成更符合我们特定分类任务的新嵌入,采用对比学习方法。接下来,分类器使用微调后的嵌入模型进行训练,以输入数据并将其映射到相应的类别。
只需几行代码和来自 Argilla 的标注数据,您就可以轻松训练您的分类器。通过这种方法,您将有效地使用领域特定的高质量数据成功训练一个有效的分类器。
model = SetFitModel.from_pretrained("TaylorAI/bge-micro-v2")
trainer = Trainer(
model=model,
train_dataset=train_annotated_dataset,
eval_dataset=eval_dataset,
)
trainer.train()
纯大型语言模型标注与 SetFit 标注
在前面的章节中,我们演示了如何使用 LLM 标注数据集并获取足够的标注样本来馈送和训练小型模型。然而,关于每个模型的性能和准确性可能仍存在疑问。为了评估这一点,我们进行了一项实验,比较了两种方法。具体来说,我们使用了 argilla/pc-components-reviews 数据集,并使用不同数量的样本比较了两种模型的性能。
首先,我们使用 LLM (LlaMA 3.1 8b
) 将产品评论分类为正面、负面或中性情感。LLM 获得了标注指南中的任务描述,并以递增的每类示例(从 0 到 6 个)进行学习。然后,我们使用 bge-micro-v2
模型,通过 SetFit 库训练了一个分类器。这种方法不兼容提示,但我们使用了递增的每类示例(再次从 0 到 6 个)来训练分类器。在这两种情况下,我们都测量了 pc-component-review 数据集中剩余 122 个样本的准确性。
总而言之,在 LLM 建议的帮助下,我们在不到 10 分钟内审查了 18 个训练集样本。在实际应用中,我们将扩大评估集以提高鲁棒性。
如下所示,我们的实验结果表明,SetFit 模型优于零样本 LLama-3.1-8B,尤其是在少量样本分类方面。这突出了 LLM 在初始数据标注方面的价值,它们可以生成高质量的合成标签。一旦初始数据集被标注,SetFit 等小型模型可以进一步完善和学习这些数据,从而提供更高的性能。这种方法加快了模型开发,并允许在资源受限的环境中更有效地部署分类器。
结论
在这篇博客文章中,我们探讨了如何整合 Argilla 和 distilabel,以利用人工智能和人工反馈来训练一个小型分类器。我们展示了如何将这种方法应用于自动标注数据集,从而简化工作流程,节省时间和资源,同时仍能交付高性能模型。我们发现了几个关键优势:
- 通过使用大型语言模型提高标注效率
- 由于定义明确的标注指南,标注保持一致性
- 将人工智能反馈与人工校对相结合,兼具人工智能模型的规模优势和人工标注者的精确度。
接下来
如果您想在自己的用例中尝试自动标注,以下是接下来的步骤
- 开始使用 Hugging Face Spaces 上的 Argilla。
- 如果您没有任何数据,可以使用 distilabel 创建合成数据集,如 pc-components-review。
- 使用 Argilla Labeler 自动标注数据集的少量样本。
附录
提示模板
Please provide an answer to the question based on the input fields{% if examples %} and examples{% endif %}.
{% if guidelines %}
# Guidelines
{{ guidelines }}
{% endif %}
# Input Fields
{{ fields }}
# Question
{{ question }}
{% if examples %}
# Examples
{{ examples }}
{% endif %}