Press "Enter" to skip to content

拆解Hugging Face Transformers库

使用开源LLMs的快速入门指南

这是一系列关于实际使用大型语言模型(LLMs)的第三篇文章。在这里,我将给出一个适合初学者的指南,介绍Hugging Face Transformers库,该库提供了一种简单且免费的方式来使用各种开源语言模型。我将首先回顾关键概念,然后深入到示例Python代码中。

Photo by Jéan Béller on Unsplash

在本系列的上一篇文章中,我们探讨了OpenAI Python API,并使用它制作了一个自定义聊天机器人。然而,这个API的一个缺点是API调用是需要花费金钱的,这对于某些使用情况可能不可扩展。

在这些情况下,使用开源解决方案可能是有优势的。使用Hugging Face的Transformers库是一种流行的方法。

Hugging Face是什么?

Hugging Face是一个已经成为开源机器学习(ML)的重要中心的AI公司。他们的平台有三个主要元素,允许用户访问和共享机器学习资源。

首先是他们快速增长的预训练开源ML模型的存储库,用于自然语言处理(NLP)、计算机视觉等。其次是他们的用于训练几乎任何任务的ML模型的数据集库。第三个元素是Spaces,它是由Hugging Face托管的一组开源ML应用程序。

这些资源的威力在于它们是由社区生成的,充分利用了开源的所有优势(即免费、工具多样性、高质量资源和快速创新速度)。虽然这使得构建强大的ML项目比以前更容易,但Hugging Face生态系统的另一个关键元素是Transformers库。

🤗Transformers

Transformers是一个使下载和训练最先进的ML模型变得容易的Python库。尽管最初是为开发语言模型而设计的,但其功能已扩展到包括计算机视觉、音频处理等模型。

该库的两个重要优势是,一是它很容易与Hugging Face(前面提到的)的模型、数据集和Spaces存储库集成,二是该库支持其他流行的ML框架,如PyTorch和TensorFlow。

这使得该库成为一个简单而灵活的全能平台,用于下载、训练和部署机器学习模型和应用。

Pipeline()

使用该库的最简单方法是通过pipeline()函数,将NLP(和其他)任务抽象成一行代码。例如,如果我们想进行情感分析,我们需要选择一个模型,对输入文本进行分词,将其通过模型,然后解码数值输出以确定情感标签(积极或消极)。

虽然这似乎是很多步骤,但我们可以通过pipeline()函数在一行代码中完成所有这些操作,如下面的代码片段所示。

pipeline(task="sentiment-analysis")("Love this!")# 输出 -> [{'label': 'POSITIVE', 'score': 0.9998745918273926}]

当然,情感分析不是我们在这里可以做的唯一事情。几乎任何NLP任务都可以以这种方式完成,例如摘要、翻译、问答、特征提取(即文本嵌入)、文本生成、零样本分类等等。有关内置任务的完整列表,请查看pipeline()文档。

在上面的示例代码中,由于我们没有指定模型,所以使用了情感分析的默认模型(即distilbert-base-uncased-finetuned-sst-2-english)。然而,如果我们想更明确,我们可以使用下面的代码。

pipeline(task="sentiment-analysis", model='distilbert-base-uncased-finetuned-sst-2-english')("喜欢这个!")# 输出 -> [{'label': 'POSITIVE', 'score': 0.9998745918273926}]

Transformers库的最大好处之一是,我们可以通过改变传递给pipeline()函数的模型名称来轻松地使用Hugging Face Models仓库中的28000多个文本分类模型。

模型

Hugging Face上有一个庞大的预训练模型仓库(在撰写本文时为277,528个)。几乎所有这些模型都可以通过Transformers轻松使用,使用的语法与上面的代码块中看到的相同。

然而,Hugging Face上的模型并不仅适用于Transformers库。还有其他流行的机器学习框架(如PyTorch、Tensorflow、Jax)的模型。这使得Hugging Face的Models仓库在Transformers库之外对机器学习从业者也非常有用。

为了看看如何浏览仓库,让我们考虑一个例子。假设我们想要一个能够进行文本生成的模型,但我们希望它可以通过Transformers库的一行代码来使用(就像上面的例子一样)。我们可以使用“Tasks”和“Libraries”过滤器轻松查看符合这些条件的所有模型。

符合这些条件的一个模型是新发布的Llama 2。具体来说,Llama-2-7b-chat-hf是Llama 2系列中的一个模型,拥有约70亿个参数,针对聊天进行了优化,并且以Hugging Face Transformers格式提供。我们可以通过模型的模型卡片获取更多信息,如下图所示。

浏览 Llama-2-7b-chat-hf 模型卡片。图片由作者提供。

安装 🤗Transformers(使用Conda)

现在,我们已经对Hugging Face提供的资源和Transformers库有了基本的了解,让我们看看如何使用它们。我们首先安装库和其他依赖项。

Hugging Face在其网站上提供了安装指南。因此,我不会在这里(糟糕地)复制该指南。但是,我将提供一个快速的2步指南,介绍如何为下面的示例代码设置conda环境。

第一步:首先,下载GitHub存储库上可用的hf-env.yml文件。您可以直接下载该文件,也可以克隆整个存储库。

第二步:然后,在您的终端(或Anaconda命令提示符)中,使用以下命令基于hf-env.yml创建一个新的conda环境。

>>> cd <包含hf-env.yml的目录>>>> conda env create --file hf-env.yml

这可能需要几分钟来安装,但一旦安装完成,您就准备好了!

示例代码:使用 🤗Transformers进行自然语言处理

安装必要的库后,让我们进入一些示例代码。在这里,我们将使用pipeline()函数对3个自然语言处理应用案例进行调查,分别是情感分析、摘要生成和对话文本生成

最后,我们将使用Gradio快速生成一个用户界面(UI),用于这些应用案例中的任何一个,并将其部署为Hugging Face Spaces上的应用程序。所有示例代码都可在GitHub存储库中找到。

情感分析

我们从情感分析开始。回想一下之前我们使用pipeline函数执行类似下面代码块的操作,我们创建了一个分类器,可以将输入的文本标记为积极或消极。

from transformers import pipeline

classifier = pipeline(task="sentiment-analysis", \                      
                      model="distilbert-base-uncased-finetuned-sst-2-english")
classifier("讨厌这个。")# 输出 -> [{'label': 'NEGATIVE', 'score': 0.9997110962867737}]

为了更进一步,我们可以将文本作为一个批次传递给分类器,而不是逐个处理。

text_list = ["这很棒",
             "谢谢你一无所获",
             "你得改进你的脸蛋",
             "你很漂亮,永远不要改变!"]
classifier(text_list)# 输出 -> [{'label': 'POSITIVE', 'score': 0.9998785257339478},
                      {'label': 'POSITIVE', 'score': 0.9680058360099792},
                      {'label': 'NEGATIVE', 'score': 0.8776106238365173},
                      {'label': 'POSITIVE', 'score': 0.9998120665550232}]

然而,Hugging Face 上的文本分类模型不仅仅局限于正面-负面情感。例如,SamLowe 的“roberta-base-go_emotions”模型生成了一套类别标签。我们可以像下面的代码片段所示,同样轻松地将该模型应用于文本。

classifier = pipeline(task="text-classification", \                      
                      model="SamLowe/roberta-base-go_emotions", top_k=None)
classifier(text_list[0])# 输出 -> [[{'label': 'admiration', 'score': 0.9526104927062988},
                    {'label': 'approval', 'score': 0.03047208860516548},
                    {'label': 'neutral', 'score': 0.015236231498420238},
                    {'label': 'excitement', 'score': 0.006063772831112146},
                    {'label': 'gratitude', 'score': 0.005296189337968826},
                    {'label': 'joy', 'score': 0.004475208930671215},
                    ... 还有更多

摘要

我们可以使用 pipeline() 函数进行文本摘要。虽然这是一项与情感分析完全不同的任务,但语法几乎相同。 首先加载一个摘要模型,然后传入一些文本和一些输入参数。 summarizer = pipeline("summarization", model="facebook/bart-large-cnn") text = """Hugging Face是一家AI公司,已成为开源机器学习的主要枢纽。他们的平台有三个主要元素,允许用户访问和分享机器学习资源。首先,是他们快速增长的预训练开源机器学习模型仓库,用于自然语言处理(NLP)、计算机视觉等。其次,是他们的数据集库,用于训练几乎任何任务的机器学习模型。第三,最后,是Spaces,一个开源ML应用的集合。这些资源的强大之处在于它们是由社区生成的,充分利用了开源的所有好处,即零成本、工具的广泛多样性、高质量资源和快速创新的步伐。尽管这使得构建强大的ML项目比以前更加容易,但Hugging Face 生态系统的另一个关键要素是他们的 Transformers 库。""" summarized_text = summarizer(text, min_length=5, max_length=140)[0]['summary_text'] print(summarized_text)# 输出 -> 'Hugging Face是一家AI公司,已成为开源机器学习的主要枢纽。他们有三个主要元素,允许用户访问和分享机器学习资源。' 对于更复杂的用例,可能需要连续使用多个模型。例如,我们可以将情感分析应用于摘要文本以加快运行时间。 classifier(summarized_text)# 输出 -> [[{'label': 'neutral', 'score': 0.9101783633232117}, {'label': 'approval', 'score': 0.08781372010707855}, {'label': 'realization', 'score': 0.023256294429302216}, {'label': 'annoyance', 'score': 0.006623792927712202}, {'label': 'admiration', 'score': 0.004981081001460552}, {'label': 'disapproval', 'score': 0.004730119835585356}, {'label': 'optimism', 'score': 0.0033590723760426044}, ... 还有更多

对话式

最后,我们可以使用专门开发的模型来生成对话文本。由于对话需要将过去的提示和回复传递给后续的模型响应,因此这里的语法有些不同。但是,我们首先通过使用pipeline()函数来实例化我们的模型。

chatbot = pipeline(model="facebook/blenderbot-400M-distill")

接下来,我们可以使用Conversation()类来处理来回的对话。我们用用户提示进行初始化,然后将其传递给之前代码块中的chatbot模型。

from transformers import Conversationconversation = Conversation("你好,我是Shaw,你好吗?")conversation = chatbot(conversation)print(conversation)# 输出 -> Conversation id: 9248ee7d-2a58-4355-9fba-525189fae206 # 用户 >> 你好,我是Shaw,你好吗? # 机器人 >> 我很好。你今晚过得怎么样?我刚下班回家。

为了让对话继续进行,我们可以使用add_user_input()方法向对话中添加另一个提示。然后将对话对象再次传递给chatbot。

conversation.add_user_input("你在哪里工作?")conversation = chatbot(conversation)print(conversation)# 输出 -> Conversation id: 9248ee7d-2a58-4355-9fba-525189fae206 # 用户 >> 你好,我是Shaw,你好吗? # 机器人 >> 我很好。你今晚过得怎么样?我刚下班回家。# 用户 >> 你在哪里工作? # 机器人 >> 我在一家杂货店工作。你呢?你从事什么工作?

使用Gradio的聊天机器人界面

虽然我们可以通过Transformer库获得基本的聊天机器人功能,但这种方式与聊天机器人的交互并不方便。为了使交互更加直观,我们可以使用Gradio在几行Python代码中创建一个前端界面。

下面的代码实现了这个功能。在顶部,我们初始化了两个列表,分别用于存储用户消息和模型响应。然后我们定义了一个函数,该函数将接受用户提示并生成聊天机器人的输出。接下来,我们使用Gradio的ChatInterface()类创建了聊天界面。最后,我们启动了应用。

message_list = []response_list = []def vanilla_chatbot(message, history):    conversation = Conversation(text=message, past_user_inputs=message_list, generated_responses=response_list)    conversation = chatbot(conversation)    return conversation.generated_responses[-1]demo_chatbot = gr.ChatInterface(vanilla_chatbot, title="Vanilla Chatbot", description="输入文本开始聊天。")demo_chatbot.launch()

这将通过本地URL启动界面。如果窗口没有自动打开,您可以将URL直接复制粘贴到浏览器中。

Gradio界面。GIF由作者提供。

Hugging Face Spaces

为了更进一步,我们可以通过Hugging Face Spaces快速部署这个界面。这些是Hugging Face托管的Git存储库,并且通过计算资源进行增强。根据使用情况,可以选择免费或付费选项。在这里,我们将使用免费选项。

要创建一个新的Space,我们首先转到Spaces页面,然后点击“创建新的space”。然后,通过为其命名,例如“my-first-space”,并选择Gradio作为SDK来配置Space。然后点击“创建Space”。

Hugging Face Space配置。图片由作者提供。

接下来,我们需要将app.py和requirements.txt文件上传到Space。app.py文件包含了我们用来生成Gradio UI的代码,而requirements.txt文件指定了应用程序的依赖关系。这个示例的文件可以在GitHub仓库和Hugging Face Space上获取。

最后,我们像在GitHub上一样将代码推送到Space。最终的结果是一个托管在Hugging Face Spaces上的公共应用程序。

应用链接:https://huggingface.co/spaces/shawhin/my-first-space

结论

Hugging Face已成为开源语言模型和机器学习的代名词。他们的生态系统最大的优势在于为小型开发者、研究人员和爱好者提供了强大的机器学习资源。

虽然我们在本文中涵盖了很多内容,但我们只是触及了Hugging Face生态系统的冰山一角。在本系列的未来文章中,我们将探索更高级的用例,并介绍如何使用🤗Transformers对模型进行微调。

👉 更多关于LLMs的内容:Introduction | OpenAI API

资源

联系方式:我的网站 | 预约通话 | 向我提问

社交媒体:YouTube 🎥 | LinkedIn | Twitter

支持:成为会员 ⭐️ | 请我喝杯咖啡 ☕️

数据创业家

一个面向数据领域创业家的社区。👉 加入Discord!

VoAGI.com

[1] Hugging Face — https://huggingface.co/

[2] Hugging Face Course — https://huggingface.co/learn/nlp-course/chapter1/1

Leave a Reply

Your email address will not be published. Required fields are marked *