HF模型选择与应用指南
最近,我在日常工作中尝试使用 Hugging Face 目录中的模型,从中获得了很多乐趣,我认为这可能是一个很好的时机来分享我所学到的知识,并为读者提供一些如何以最小的压力应用这些模型的技巧。
我最近的具体任务是查看大量非结构化文本数据(例如备忘录、电子邮件、自由文本评论字段等),并根据与业务用例相关的类别对其进行分类。有很多方法可以做到这一点,我一直在尽可能多地探索,包括模式匹配和词典搜索等简单的东西,也扩展到使用预构建的神经网络模型来实现许多不同的功能,我对结果感到相当满意。
我认为最好的策略是结合多种技术,以某种形式的集成,以获得最佳选择。我并不相信这些模型能够经常(而且肯定不够一致)地正确处理问题,因此不能单独使用它们,但当与更基本的技术结合使用时,它们可以增加信号。
1、选择用例
对我来说,正如我所提到的,任务只是获取通常由人类编写的、没有一致格式或模式的文本块,并尝试找出适用于该文本的类别。除了前面提到的分析方法之外,我还采取了几种不同的方法来做到这一点,这些方法从非常省力到我在这方面需要做更多的工作。这些是我迄今为止测试过的三种策略:
- 要求模型选择类别(零样本分类 - 我将在本文中后面使用它作为示例)
- 使用命名实体识别模型查找文本中引用的关键对象,并在此基础上进行分类
- 要求模型总结文本,然后应用其他技术根据总结进行分类
2、寻找模型
这是最有趣的部分 - 浏览 Hugging Face 目录寻找模型!在Hugging Face模型目录页面 ,你可以看到大量可用的模型,这些模型已被用户添加到目录中。我有一些关于如何明智选择的提示和建议。
- 查看下载和点赞数量,不要选择未经大量其他用户尝试和测试过的东西。你还可以查看每个模型页面上的“社区”选项卡,查看用户是否在讨论挑战或报告错误。
- 如果可能,调查谁上传了模型,并确定你是否认为他们值得信赖。训练或调整模型的人可能知道也可能不知道他们在做什么,你的结果质量将取决于他们!
- 仔细阅读文档,跳过文档很少或没有文档的模型。无论如何,你都很难有效地使用它们。
- 使用页面侧面的过滤器缩小到适合你任务的模型。选择的数量可能令人不知所措,但它们分类合理,可以帮助你找到所需的内容。
- 大多数模型卡都提供了快速测试,你可以运行它来查看模型的行为,但请记住,这只是一个例子,它可能是被选中的,因为模型在这方面很擅长,并且发现这种情况很容易。
3、将模型融入你的代码
找到想要尝试的模型后,很容易开始 - 单击模型卡页面右上角的“使用此模型”按钮,你将看到如何实现的选项。 如果选择 Transformers 选项,你将获得一些如下所示的说明:
如果 Transformers 库不支持你选择的模型,可能会列出其他技术,如 TF-Keras、scikit-learn 等,但当你单击该按钮时,所有技术都应显示说明和示例代码,以便于使用。
在我的实验中,所有模型都受 Transformers 支持,因此我只需按照以下步骤操作即可轻松运行它们。如果你发现有疑问,还可以查看更深层次的文档,并查看 Transformers 库及其提供的不同类的完整 API 详细信息。在优化时,我确实花了一些时间查看特定类的这些文档,但要正常运行模型,通常你不需要这样做。
4、准备推理数据
好的,所以你已经选择了想要尝试的模型。你已经有数据了吗?如果没有,我一直在使用几个公开可用的数据集进行此实验,主要来自 Kaggle,你也可以在那里找到许多有用的数据集。此外,Hugging Face 还有一个数据集目录供你查看,但根据我的经验,在那里搜索或理解数据内容并不那么容易(只是文档没有那么多)。
一旦你选择了非结构化文本数据集,将其加载到这些模型中并不那么困难。加载你的模型和你的分词器(来自如上所述的 Hugging Face 上提供的文档)并通过所有这些操作都交给 transformers 库中的管道函数。你将循环遍历列表或 pandas 系列中的文本块,并将它们传递给模型函数。无论你执行哪种任务,这基本上都是一样的,尽管对于零样本分类,你还需要提供候选标签或标签列表,如下所示。
5、代码示例
那么,让我们仔细看看零样本分类。正如我上面提到的,这涉及使用预训练模型根据尚未经过专门训练的类别对文本进行分类,希望它可以使用其学习到的语义嵌入来衡量文本和标签术语之间的相似性。
from transformers import AutoModelForSequenceClassification
from transformers import AutoTokenizer
from transformers import pipeline
nli_model = AutoModelForSequenceClassification.from_pretrained("facebook/bart-large-mnli", model_max_length=512)
tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-mnli")
classifier = pipeline("zero-shot-classification", device="cpu", model=nli_model, tokenizer=tokenizer)
label_list = ['News', 'Science', 'Art']
all_results = []
for text in list_of_texts:
prob = self.classifier(text, label_list, multi_label=True, use_fast=True)
results_dict = {x: y for x, y in zip(prob["labels"], prob["scores"])}
all_results.append(results_dict)
这将返回一个字典列表,每个字典都包含可能标签的键,值是每个标签的概率。您不必像我在这里所做的那样使用管道,但它使多标签零样本比手动编写代码容易得多,并且它返回的结果易于解释和使用。
如果你不想使用管道,可以改为执行类似这样的操作,但你必须为每个标签运行一次。请注意,需要指定模型运行产生的逻辑处理,以便获得人类可解释的输出。此外,你仍然需要如上所述加载分词器和模型。
def run_zero_shot_classifier(text, label):
hypothesis = f"This example is related to {label}."
x = tokenizer.encode(
text,
hypothesis,
return_tensors="pt",
truncation_strategy="only_first"
)
logits = nli_model(x.to("cpu"))[0]
entail_contradiction_logits = logits[:, [0, 2]]
probs = entail_contradiction_logits.softmax(dim=1)
prob_label_is_true = probs[:, 1]
return prob_label_is_true.item()
label_list = ['News', 'Science', 'Art']
all_results = []
for text in list_of_texts:
for label in label_list:
result = run_zero_shot_classifier(text, label)
all_results.append(result)
6、是否微调模型?
你可能已经注意到,我还没有谈到自己为这个项目微调模型——这是真的。我将来可能会这样做,但目前我只有极少的带标签的训练数据可供使用,因此我的能力受到限制。我可以使用半监督技术或引导带标签的训练集,但整个实验都是为了看看我能用现成的模型走多远。我确实有一些小的带标签的数据样本,用于测试模型的性能,但这远远达不到我调整模型所需的数据量。
如果你确实有良好的训练数据并希望调整基础模型,Hugging Face 有一些文档可以提供帮助。
7、计算和速度
性能一直是一个有趣的问题,因为到目前为止,我已经在本地笔记本电脑上运行了所有实验。当然,使用 Hugging Face 的这些模型将比正则表达式和词典搜索等基本策略更耗费计算资源,速度也更慢,但它提供了无法通过其他方式实现的信号,因此寻找优化方法是值得的。所有这些模型都支持 GPU,并且很容易将它们推到 GPU 上运行。
如果你想快速在 GPU 上尝试,请查看我上面显示的代码,如果你的编程环境中有可用的 GPU,请将你看到的“cpu”替换为“cuda”。
请记住,使用云提供商的 GPU 并不便宜,因此请相应地确定优先级并决定更快的速度是否值得付出代价。
大多数情况下,使用 GPU 对于训练更为重要(如果您选择微调,请记住这一点),但对于推理则不那么重要。我不会在这里深入探讨有关优化的更多细节,但如果这对您很重要,您也需要考虑并行性——数据并行性和实际训练/计算并行性。
8、测试和理解输出
我们已经运行了模型!结果在这里。我有一些关于如何审查输出并将其实际应用于业务问题的结束提示。
- 不要盲目地相信模型输出,而是要进行严格的测试并评估性能。仅仅因为一个转换器模型在某个文本块上表现良好,或者能够定期将文本与某个标签正确匹配,并不意味着这是可推广的结果。使用大量不同的示例和不同类型的文本来证明性能足够。
- 如果你对模型有信心并希望在生产环境中使用它,请跟踪和记录模型的行为。对于任何生产中的模型来说,这都是很好的做法,但你应该将其产生的结果与你给它的输入一起保存,这样就可以不断检查它并确保性能不会下降。这对于这些类型的深度学习模型来说更为重要,因为我们对模型得出推论的原因和方式没有太多的可解释性。对模型的内部工作原理做太多假设是危险的。
正如我之前提到的,我喜欢将这些类型的模型输出用作更大技术池的一部分,将它们结合在集成策略中——这样我不仅依赖一种方法,而且我确实得到了这些推论可以提供的信号。
我希望这个概述对那些刚开始使用预训练模型进行文本(或其他模式)分析的人有用——祝你好运!
原文链接:Choosing and Implementing Hugging Face Models
汇智网翻译整理,转载请标明出处