【NLP】第 5 章 :使用Hugging Face的任务

到目前为止,我们已经了解了如何在非常初级的层面上将 transformers 与 huggingface Transformers 库一起使用。我们现在将开始了解如何使用该库来完成与文本、音频和图像相关的不同任务。

但在我们继续之前,我们将向您介绍 Gradio,这是一个用于在 huggingface 之上构建 UI 的库。

Gradio:简介

Gradio 是一个专门为部署和推理机器学习模型而构建的Web 框架 。Gradio 使我们能够通过 Web 界面快速公开我们的 ML 模型,而无需学习太多编码。通过收购 Gradio,Hugging Face 向前迈进了一步,为 huggingface 社区提供了一个简单的界面,可以在 huggingface 模型上部署和提供 UI。

在本章中,我们将使用huggingface spaces ,它为我们提供了一个接口来快速部署和提供我们的应用程序(使用 huggingface API 构建),一个 Web 前端,最终用户可以使用它与我们的应用程序进行交互。

在Hugging Face上创造空间

要在huggingface infra 上创建一个空间,我们需要有一个 huggingface 的帐户。这可以通过导航到https://huggingface.co/并在那里创建一个帐户来完成。创建账户后,我们可以点击最右边 的彩色圆圈,如图5-1所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-1登录 后Hugging Face屏幕

点击新建空间,我们看到如图5-2所示的画面。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-2 创造一个新的空间

为您的空间命名并选择 Gradio 作为SDK 。现在保持默认公开以提高可见性,最后单击“Create Space”按钮。

您将看到如图5-3所示的以下菜单。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-3

huggingface 网页上显示的菜单

对于本章中的大多数应用程序,我们将使用文件和版本以及应用程序选项卡。

单击文件和版本选项卡,在右侧,我们看到添加文件。单击它我们可以添加我们的应用程序所需的文件。

对于我们的应用程序,我们只需要创建两个文件 :

  1. app.py:这是 Gradio 应用程序的主要代码文件。

  1. requirements.txt:此文件包含应用程序所需的 Python 依赖项。

Hugging Face任务

我们将从问答任务开始。

问答

模型的输入将是一个段落和该段落中的一个问题。模型推理的输出将是问题的答案。

我们使用的模型是在 SQuAD数据集 上训练的。

斯坦福问答数据集,也称为SQuAD ,是一个阅读理解数据集,由众包人员针对一组维基百科文章提出的问题组成。每个问题的答案都是来自相应阅读文章的一段文本,也称为span ,否则问题可能无法回答。

SQuAD 1.1 包含超过 100,000 个问答对,涵盖 500 多篇不同的文章。

首先,使用 RoBERTa基础 模型 ,使用SQuAD 2. 0数据集进行微调。它接受 了问答对的训练,包括无法回答的问题,用于问答任务。

模型使用的一些超参数是

  • batch_size:96

  • n_epochs:2

  • max_seq_len:386

  • max_query_length:64

首先使用huggingface UI 创建一个新空间,如上一节中的步骤所述。

单击 UI 上的文件和版本选项卡。使用以下内容创建文件 requirements.txt:

requirements.txt

gradio

transformers

torch

创建另一个文件 app.py 并复制 清单5-1中的内容。

from transformers import AutoModelForQuestionAnswering, AutoTokenizer, pipeline
import gradio as grad
import ast
mdl_name = "deepset/roberta-base-squad2"
my_pipeline = pipeline('question-answering', model=mdl_name, tokenizer=mdl_name)
def answer_question(question,context):
    text= "{"+"'question': '"+question+"','context': '"+context+"'}"
    di=ast.literal_eval(text)
    response = my_pipeline(di)
    return response
grad.Interface(answer_question, inputs=["text","text"], outputs="text").launch()

清单 5-1 app.py 的代码

单击 Commit changes 按钮提交更改,如图5-4所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-4 提交 app.py 文件

这将触发构建和部署 过程,并且可以单击图5-5中的“查看日志”按钮来查看活动。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-5 显示各种选项卡,包括“查看日志”按钮

初始阶段将是构建阶段,如图5-6所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-6 应用程序的部署状态

点击See logs我们可以看到如图5-7所示的活动 。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-7 显示应用程序的构建进度 。在这里,它正在加载用于创建容器的 Docker 映像

可以看到这里正在构建Docker 镜像 ,然后将部署它。如果一切 运行成功,我们将在 UI 上看到一个绿色的阶段,状态为 Running,如图5-8所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-8 应用程序的状态更改为正在运行

完成后,单击“文件和版本”选项卡左侧的“应用程序”选项 卡。这将为您呈现用于键入输入的 UI。提供输入后,请单击提交按钮,如图5-9所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-9 通过 Gradio 问答 UI。在标有上下文的输入框中为该段落提供您选择的输入,该段落中的问题应放入标有问题的输入框中

在清单5-2中,我们将在不同的模型上尝试相同的段落 和问题。我们将使用的模型是distilbert-base-cased-distilled-squad:

requirements.txt

gradio

transformers

torch

from transformers import AutoModelForQuestionAnswering, AutoTokenizer, pipeline
import gradio as grad
import ast
mdl_name = "distilbert-base-cased-distilled-squad"
my_pipeline = pipeline('question-answering', model=mdl_name, tokenizer=mdl_name)
def answer_question(question,context):
    text= "{"+"'question': '"+question+"','context': '"+context+"'}"
    di=ast.literal_eval(text)
    response = my_pipeline(di)
    return response
grad.Interface(answer_question, inputs=["text","text"], outputs="text").launch()

清单 5-2 app.py 的代码

提交更改并等待 部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-10所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-10 显示用于基于BERT 的问答 的基于 Gradio 的问答 UI

翻译

我们要处理 的下一个任务是语言翻译。这背后的想法是采用一种语言输入,然后根据通过 huggingface 库加载的预训练模型将其翻译成另一种语言。

我们在这里探索的第一个模型是Helsinki-NLP/opus-mt-en-de 模型 ,它接受英语输入并将其翻译成德语。

Code

app.py

from transformers import pipeline
import gradio as grad
mdl_name = "Helsinki-NLP/opus-mt-en-de"
opus_translator = pipeline("translation", model=mdl_name)
def translate(text):
    response = opus_translator(text)
    return response
grad.Interface(translate, inputs=["text",], outputs="text").launch()

清单 5-3 app.py 的代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

Output

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-11所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-11 用于翻译任务的 Gradio UI

我们现在将在清单5-4中看到我们是否可以在不使用管道抽象的情况下编写相同的代码。如果我们还记得我们之前使用 AutoTokenizer 和AutoModel 等Auto 类做过同样的事情 。让我们继续。

Code

app.py

from transformers import AutoModelForSeq2SeqLM,AutoTokenizer
import gradio as grad
mdl_name = "Helsinki-NLP/opus-mt-en-de"
mdl = AutoModelForSeq2SeqLM.from_pretrained(mdl_name)
my_tkn = AutoTokenizer.from_pretrained(mdl_name)
#opus_translator = pipeline("translation", model=mdl_name)
def translate(text):
    inputs = my_tkn(text, return_tensors="pt")
    trans_output = mdl.generate(**inputs)
    response = my_tkn.decode(trans_output[0], skip_special_tokens=True)
    #response = opus_translator(text)
    return response
grad.Interface(translate, inputs=["text",], outputs="text").launch()

清单 5-4 app.py 的代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-12所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-12 基于 Gradio 的翻译 UI

为了给你一种幸福 的感觉,当我们尝试通过谷歌翻译 同样的翻译时,我们得到了如下结果,如图5-13所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-13 显示 Google 翻译如何翻译我们用于翻译应用程序的相同文本

我们可以看到我们与谷歌的结果有多接近 。这就是抱脸模型的力量。

为了强化这个概念,我们将用不同的语言翻译重复这个练习。这次我们以英法翻译为例。

这次我们采用Helsinki-NLP/opus-mt-en-fr 模型 并尝试翻译我们在前面示例中采用的相同句子,但这次是法语。

首先,我们使用管道抽象编写代码。

Code

app.py

from transformers import pipeline
import gradio as grad
mdl_name = "Helsinki-NLP/opus-mt-en-fr"
opus_translator = pipeline("translation", model=mdl_name)
def translate(text):
    response = opus_translator(text)
    return response
txt=grad.Textbox(lines=1, label="English", placeholder="English Text here")
out=grad.Textbox(lines=1, label="French")
grad.Interface(translate, inputs=txt, outputs=out).launch()

清单 5-5 app.py 的代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-14所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-14 使用 Gradio 的翻译 UI

我们得到以下输出。

接下来,我们尝试在清单5-6中没有管道 API 的情况下进行相同的操作。

Code

app.py

from transformers import AutoModel,AutoTokenizer,AutoModelForSeq2SeqLM
import gradio as grad
mdl_name = "Helsinki-NLP/opus-mt-en-fr"
mdl = AutoModelForSeq2SeqLM.from_pretrained(mdl_name)
my_tkn = AutoTokenizer.from_pretrained(mdl_name)
#opus_translator = pipeline("translation", model=mdl_name)
def translate(text):
    inputs = my_tkn(text, return_tensors="pt")
    trans_output = mdl.generate(**inputs)
    response = my_tkn.decode(trans_output[0], skip_special_tokens=True)
    #response = opus_translator(text)
    return response
txt=grad.Textbox(lines=1, label="English", placeholder="English Text here")
out=grad.Textbox(lines=1, label="French")
grad.Interface(translate, inputs=txt, outputs=out).launch()

清单 5-6 app.py 的代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-15所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-15 用于翻译任务的 Gradio UI,无需直接使用管道 API

再次将结果与Google Translate 的结果进行比较,如图5-16所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-16 Google 翻译 我们用于 Gradio 应用程序的相同文本

正如我们所见,结果 完全匹配。有什么值得欢呼的。

概括

如果要阅读冗长的文档,我们的自然倾向是要么根本不阅读它们,要么只浏览最重要的要点。因此,对信息进行总结以节省时间和脑力处理能力将非常有帮助。

然而,在过去,自动总结文本是一项不可能完成的任务。更具体地说,做一个抽象的总结是一件非常困难的事情。抽象摘要比提取摘要更难,后者从文档中提取关键句子并将它们组合起来形成“摘要”。因为abstractive summarization涉及释义词,所以也比较费时;但是,它有可能产生更加优美和连贯的摘要。

我们将首先查看google/pegasus-xsum 模型 以生成一些文本的摘要。

这是代码。

app.py

from transformers import PegasusForConditionalGeneration, PegasusTokenizer
import gradio as grad
mdl_name = "google/pegasus-xsum"
pegasus_tkn = PegasusTokenizer.from_pretrained(mdl_name)
mdl = PegasusForConditionalGeneration.from_pretrained(mdl_name)
def summarize(text):
    tokens = pegasus_tkn(text, truncation=True, padding="longest", return_tensors="pt")
    txt_summary = mdl.generate(**tokens)
    response = pegasus_tkn.batch_decode(txt_summary, skip_special_tokens=True)
    return response
txt=grad.Textbox(lines=10, label="English", placeholder="English Text here")
out=grad.Textbox(lines=10, label="Summary")
grad.Interface(summarize, inputs=txt, outputs=out).launch()

清单 5-7 app.py 的代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-17所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-17 使用 Gradio 的摘要应用程序 。在标有英文的框中粘贴段落,提交后,标有摘要的框将显示段落文本的摘要

接下来,我们使用另一个文本,并使用一些参数对模型进行一些调整。

from transformers import PegasusForConditionalGeneration, PegasusTokenizer
import gradio as grad
mdl_name = "google/pegasus-xsum"
pegasus_tkn = PegasusTokenizer.from_pretrained(mdl_name)
mdl = PegasusForConditionalGeneration.from_pretrained(mdl_name)
def summarize(text):
    tokens = pegasus_tkn(text, truncation=True, padding="longest", return_tensors="pt")
    translated_txt = mdl.generate(**tokens,num_return_sequences=5,max_length=200,temperature=1.5,num_beams=10)
    response = pegasus_tkn.batch_decode(translated_txt, skip_special_tokens=True)
    return response
txt=grad.Textbox(lines=10, label="English", placeholder="English Text here")
out=grad.Textbox(lines=10, label="Summary")
grad.Interface(summarize, inputs=txt, outputs=out).launch()

清单 5-8 app.py 的代码

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-18所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-18 通过 Gradio 应用程序总结文本

【NLP】第 5 章 :使用Hugging Face的任务

图 5-19 用于总结文本的Google Pegasus 模型 Imagsource: https ://1.bp.blogspot.com/-TSor4o51jGI/Xt50lkj6blI/AAAAAAAAGDs/

我们可以看到我们在代码中提供了以下参数:

translated_txt = mdl.generate(**tokens,num_return_sequences=5,max_length=200,temperature=1.5,num_beams=10)

文本生成 是通过使用波束搜索来完成的,这就是 num beams 所指的。与只返回最有可能找到的下一个单词的贪婪搜索相反,此方法返回最有可能找到的 n 个单词。

Num_return_sequences 返回返回的输出数。在前面的示例中,我们给出了 5 作为序列数。

改变由神经网络计算的输出分布是使用温度函数 的一个理由。根据公式 5-1(温度函数),它被添加到 logits 向量中:

𝑞𝑖 =exp(𝑧𝑖/𝑇)/ ∑𝑗exp(𝑧𝑗/𝑇) (公式 5-1)

其中𝑇是温度参数。

您必须了解这将导致总体概率发生变化。您可以自由选择任何您喜欢的 T 值(T 越高,分布越“柔和” ;如果设置为 1,输出分布 将与您的正常 softmax 输出相同),但请保持请注意,分布越柔和,T 应该越高。当我说模型的预测将“更软”时,我的意思是模型对其进行预测的能力的信心会降低。随着参数 T 接近 0,分布的“难度”增加。

a)Sample “hard” softmax probs : [0.01,0.04,0.95]

b)Sample ‘soft’ softmax probs : [0.15,0.25,0.6]

前面的“a”是一个更难的分布 。您的模型对其预测表现出高度的把握。另一方面,您可能不希望您的模型在大多数情况下以这种方式运行。例如,如果您使用 RNN 生成文本,您实际上是从输出分布中获取样本并将该样本词用作您的输出标记(和下一个输入)。如果你的模特有很高的自信 , 它可能会生成非常重复且不是很有趣的文本。您希望它生成具有更多主题的文本,但它无法做到这一点,因为在进行抽样过程时,大部分概率质量将集中在几个标记中,并且作为结果,您的模型将一遍又一遍地选择同一小组单词。您可以插入温度变量以生成更多样化的文本,并让其他词也有机会被采样。这将完成同样的事情。

指数函数是造成更高温度导致更平坦分布 这一事实的罪魁祸首。这是因为函数的工作原理。与较小的 logits 相比,温度参数对较大的 logits 施加了更大的负权重。“递增函数”就是所谓的指数函数 。因此,如果一个术语已经非常重要,那么与该术语相对较小的情况相比,对其进行少量惩罚会使其小得多(以百分比表示)。

对于更敏锐的用户,这里是 Pegasus 模型的简介。

Pegasus

在Pegasus 系统 的预训练阶段,从源文档中删除了几个完整的句子。然后该模型的任务是检索这些句子。文档中缺失的句子作为这种预训练的输入,而文档本身作为输出。输入文档就是所谓的“输入文档 ”。这是一个自我监督的模型,不需要在训练数据集中进行任何注释。

零样本学习

零样本学习, 顾名思义 ,就是使用一个预训练模型 ,在某一组数据上训练,在训练时它没有见过的另一组数据上训练。这意味着,例如,从在特定数据集上训练的 huggingface 中获取一些模型,并将其用于推断它以前从未见过的示例。

零样本文本分类

文本分类 是自然语言处理中的一项任务,需要模型根据常识对文本文档所属的类别进行预测。在传统方法中,我们需要使用大量已标记的数据来训练模型。此外,他们无法使用未见过的数据进行预测。零样本学习与文本分类的结合使用在自然语言处理中达到了前所未有的复杂程度。

与零样本文本分类技术相关的任何模型的主要目标是在不使用任何标记数据或没有看到任何标记文本的情况下对文本文档进行分类。这可以通过在没有看到任何带标签的文本的情况下对文档进行分类来实现。变压器是我们最常发现零样本分类 实现的地方。在 huggingface 库中可以找到 60 多个基于零样本分类的变换器模型。

当我们讨论零样本文本分类 时,还会想到另外一件事。与零样本分类相同的是少样本分类,它与零样本分类非常相似。然而,与零样本分类相比,少样本分类在训练过程中使用非常少的标记样本。few-shot 分类方法 的实现可以在 OpenAI 中找到,其中 GPT3 分类器是 few-shot 分类器的一个著名示例。

为什么我们需要零样本

1.要么 根本没有数据,要么只有非常有限的数据可用于训练(检测用户的意图而不从用户那里接收任何数据)。

2.类和标签的数量非常多(成千上万)。

3.一种“开箱即用”的分类器,可降低基础设施和开发成本 。

我们将首先使用管道 API 来查看是否可以创建一个简单的零样本学习分类器 。

Code

app.py

from transformers import pipeline
import gradio as grad
zero_shot_classifier = pipeline("zero-shot-classification")
def classify(text,labels):
    classifer_labels = labels.split(",")
    #["software", "politics", "love", "movies", "emergency", "advertisment","sports"]
    response = zero_shot_classifier(text,classifer_labels)
    return response
txt=grad.Textbox(lines=1, label="English", placeholder="text to be classified")
labels=grad.Textbox(lines=1, label="Labels", placeholder="comma separated labels")
out=grad.Textbox(lines=1, label="Classification")
grad.Interface(classify, inputs=[txt,labels], outputs=out).launch()

清单 5-9

app.py 的代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-20所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-20 零样本分类

我们可以看到此文本被正确分类在体育类别下。

我们尝试另一个示例,如图5-21所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-21 零样本分类 的另一个例子。标有分类的框表示各个类别的分数/概率

下面显示了在没有管道 API 的情况下实现相同目的的另一种方法。

Code

app.py

from transformers import BartForSequenceClassification, BartTokenizer
import gradio as grad
bart_tkn = BartTokenizer.from_pretrained('facebook/bart-large-mnli')
mdl = BartForSequenceClassification.from_pretrained('facebook/bart-large-mnli')
def classify(text,label):
    tkn_ids = bart_tkn.encode(text, label, return_tensors='pt')
    tkn_lgts = mdl(tkn_ids)[0]
    entail_contra_tkn_lgts = tkn_lgts[:,[0,2]]
    probab = entail_contra_tkn_lgts.softmax(dim=1)
    response =  probab[:,1].item() * 100
    return response
txt=grad.Textbox(lines=1, label="English", placeholder="text to be classified")
labels=grad.Textbox(lines=1, label="Label", placeholder="Input a Label")
out=grad.Textbox(lines=1, label="Probablity of label being true is")
grad.Interface(classify, inputs=[txt,labels], outputs=out).launch()

清单 5-10 app.py 的代码

requirements.txt

gradio

transformers

torch

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向UI 提供输入并单击提交按钮以查看结果,如图5-22所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-22 用于零样本分类的 Gradio 应用程序

这再次正确分类了体育类别下的文本。

文本生成任务/模型

文本生成模型 的开发始于几十年前,比最近对深度学习 的兴趣激增早了很长时间。给定一段文本,这种模型应该能够对特定的单词或单词串做出准确的预测。给定一个文本作为输入,该模型会在搜索空间中导航,以从单词的联合分布中生成下一个可能单词的概率。

最早的文本生成模型是基于马尔可夫链 的。马尔可夫链就像一个状态机,其中仅使用前一个状态来预测下一个状态。这也类似于我们在双字母组中研究的内容。

在马尔可夫链之后,引入了能够保留更大文本上下文的循环神经网络 (RNN) 。 它们基于本质上循环的神经网络架构。RNN 能够保留所引入文本的更大上下文。然而,这类网络能够记住的信息量是有限的,而且训练它们也很困难,这意味着它们不能有效地生成冗长的文本。为了解决 RNN 的这个问题,发展了LSTM 架构 ,它可以捕获文本中的长期依赖性。最后,我们来到了变形金刚,其解码器架构在用于生成文本的生成模型中变得流行,例如。

在本节中,我们将专注于GPT2 模型 ,并了解如何使用 huggingface API 来使用 GPT2 模型执行生成任务。这将使我们能够使用预训练模型生成文本,并在需要时使用自定义文本数据集对其进行微调。

Code

app.py

from transformers import GPT2LMHeadModel,GPT2Tokenizer
import gradio as grad
mdl = GPT2LMHeadModel.from_pretrained('gpt2')
gpt2_tkn=GPT2Tokenizer.from_pretrained('gpt2')
def generate(starting_text):
    tkn_ids = gpt2_tkn.encode(starting_text, return_tensors = 'pt')
    gpt2_tensors = mdl.generate(tkn_ids)
    response = gpt2_tensors
    return response
txt=grad.Textbox(lines=1, label="English", placeholder="English Text here")
out=grad.Textbox(lines=1, label="Generated Tensors")
grad.Interface(generate, inputs=txt, outputs=out).launch()

清单 5-11 app.py 的代码

requirements.txt

gradio

transformers

torch

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-23所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-23 英文文本的张量

接下来,我们在生成函数中解码这些张量。

def generate(starting_text):
    tkn_ids = gpt2_tkn.encode(starting_text, return_tensors = 'pt')
    gpt2_tensors = mdl.generate(tkn_ids)
    response=""
    #response = gpt2_tensors
    for i, x in enumerate(gpt2_tensors):
       response=response+f"{i}: {gpt2_tkn.decode(x, skip_special_tokens=True)}"
    return response

清单 5-12 生成函数

我将提供另一个文本作为输入并检查。

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-24所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-24 通过 Gradio生成代码的应用程序

接下来,我们将更改模型中的一个简单参数。

我们再次稍微修改生成函数,如下所示。

def generate(starting_text):
    tkn_ids = gpt2_tkn.encode(starting_text, return_tensors = 'pt')
    gpt2_tensors = mdl.generate(tkn_ids,max_length=100)
    response=""
    #response = gpt2_tensors
    for i, x in enumerate(gpt2_tensors):
       response=response+f"{i}: {gpt2_tkn.decode(x, skip_special_tokens=True)}"
    return response

清单 5-13 修改app.py生成函数的代码

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-25所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-25 使用 Gradio生成文本

我们可以看到生成的输出中发生了很多重复 。为了缓解这种情况,我们向模型添加了另一个参数。

def generate(starting_text):
    tkn_ids = gpt2_tkn.encode(starting_text, return_tensors = 'pt')
    gpt2_tensors = mdl.generate(tkn_ids,max_length=100,no_repeat_ngram_size=True)
    response=""
    #response = gpt2_tensors
    for i, x in enumerate(gpt2_tensors):
       response=response+f"{i}: {gpt2_tkn.decode(x, skip_special_tokens=True)}"
    return response

清单 5-14 修改app.py的generate函数代码,避免重复

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向UI 提供输入并单击提交按钮以查看结果,如图5-26所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-26 生成器现在避免文本重复的文本生成

到目前为止,模型为找到下一个词所做的搜索是基于贪婪搜索的。

这是最直接的方法 ,需要从所有备选方案中选择正确概率最高的单词。只要没有指定特定参数,就会使用它。这个过程本质上是确定性的,这意味着如果我们使用相同的参数,结果文本与以前相同。

接下来,我们指定一个参数 num_beams 来执行波束搜索。

它返回具有最高概率的序列,然后,当需要选择时,它会选择具有最高概率的序列。num_beams的值用参数X来表示,我们再次修改generate函数来调整这个参数。

def generate(starting_text):
    tkn_ids = gpt2_tkn.encode(starting_text, return_tensors = 'pt')
    gpt2_tensors = mdl.generate(tkn_ids,max_length=100,no_repeat_ngram_size=True,num_beams=3)
    response=""
    #response = gpt2_tensors
    for i, x in enumerate(gpt2_tensors):
       response=response+f"{i}: {gpt2_tkn.decode(x, skip_special_tokens=True)}"
    return response

清单 5-15 修改app.py的generate函数代码,指定num_beams

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-27所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-27 UI 显示在生成函数中使用波束搜索后生成的文本

我们采取的下一个方法是抽样。

采样 是从概率分布中随机选择下一个单词的参数。

在这种情况下,我们在生成函数中设置参数 do_sample=true。

def generate(starting_text):
    tkn_ids = gpt2_tkn.encode(starting_text, return_tensors = 'pt')
    gpt2_tensors = mdl.generate(tkn_ids,max_length=100,no_repeat_ngram_size=True,num_beams=3,do_sample=True)
    response=""
    #response = gpt2_tensors
    for i, x in enumerate(gpt2_tensors):
       response=response+f"{i}: {gpt2_tkn.decode(x, skip_special_tokens=True)}"
    return response

清单 5-16

修改了app.py生成函数的代码,带采样

提交更改并等待部署状态变为绿色。发布单击菜单 中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-28所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-28 Gradio UI 具有在后台使用采样的生成功能

可以改变分布的“温度 ”,以提高从最有可能的候选词中成功 删除单词的可能性。

生成模型表现出的贪婪程度与温度成正比。

如果温度低,则具有最高对数概率的样本类别以外的样本类别的概率将很低。因此,该模型可能会输出最正确的文本,但它会相当单调并且仅包含少量变化。

如果温度高,则模型输出不同单词的机会大于概率最高的单词。生成的文本将包含更多主题,但生成无意义 文本和包含语法错误的可能性也会增加。

我们再次修改生成函数。

def generate(starting_text):
    tkn_ids = gpt2_tkn.encode(starting_text, return_tensors = 'pt')
    gpt2_tensors = mdl.generate(tkn_ids,max_length=100,no_repeat_ngram_size=True,num_beams=3,do_sample=True,temperatue=1.5)
    response=""
    #response = gpt2_tensors
    for i, x in enumerate(gpt2_tensors):
       response=response+f"{i}: {gpt2_tkn.decode(x, skip_special_tokens=True)}"
    return response

清单 5-17 修改温度设置为1.5的app.py生成函数代码

提交更改并等待部署 状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-29所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-29 Gradio UI 中显示的文本生成使用温度设置为 1.5 的生成函数

当我们以较低的温度 运行相同的代码时,输出变差较小。

from transformers import GPT2LMHeadModel,GPT2Tokenizer
import gradio as grad
mdl = GPT2LMHeadModel.from_pretrained('gpt2')
gpt2_tkn=GPT2Tokenizer.from_pretrained('gpt2')
def generate(starting_text):
    tkn_ids = gpt2_tkn.encode(starting_text, return_tensors = 'pt')
    gpt2_tensors = mdl.generate(tkn_ids,max_length=100,no_repeat_ngram_size=True,num_beams=3,do_sample=True,temperatue=0.1)
    response=""
    #response = gpt2_tensors
    for i, x in enumerate(gpt2_tensors):
       response=response+f"{i}: {gpt2_tkn.decode(x, skip_special_tokens=True)}"
    return response
txt=grad.Textbox(lines=1, label="English", placeholder="English Text here")
out=grad.Textbox(lines=1, label="Generated Text")
grad.Interface(generate, inputs=txt, outputs=out).launch()

清单 5-18

修改app.py生成函数代码,温度设置为0.1

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-30所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-30 Gradio UI 中显示的文本生成使用温度设置为 0.1 的生成函数

为了让文本生成的概念更加深入,我们将考虑另一种称为“ distilgpt2 ”的模型。

Code

app.py

from transformers import pipeline, set_seed
import gradio as grad
gpt2_pipe = pipeline('text-generation', model='distilgpt2')
set_seed(42)
def generate(starting_text):
    response= gpt2_pipe(starting_text, max_length=20, num_return_sequences=5)
    return response
txt=grad.Textbox(lines=1, label="English", placeholder="English Text here")
out=grad.Textbox(lines=1, label="Generated Text")
grad.Interface(generate, inputs=txt, outputs=out).launch()

清单 5-19 使用 GPT2 模型生成文本的 app.py 代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动 应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-31所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-31 在幕后使用GPT2 模型 生成文本

文本到文本生成

在本节中,我们将介绍使用 T5模型 的文本到文本生成。

采用文本到文本方法的基于转换器的架构 称为 T5,它代表文本到文本传输转换器。

在文本到文本的方法中,我们将问答、分类、摘要、代码生成等任务转化为问题,为模型提供某种形式的输入,然后教它生成某种形式的目标文本。这使得将相同的模型、损失函数、超参数和其他设置应用于我们所有不同的职责集成为可能。

由Google Research 开发并公开的 T5 模型为之前进行的研究做出了以下贡献:

1.它生成了庞大的 Common Crawl 数据集的更简洁版本,称为Colossal Cleaned Common Crawl (C4) 。这个数据集比维基百科的范围大约大 100,000 倍。

2.它为 Common Crawl 上的 T5 准备身体。

3.它建议重新考虑每一个 NLP 任务,将其作为输入文本到输出文本的公式。

4.它表明,通过使用预训练的 T5 和文本到文本的公式,可以通过对各种任务(例如摘要、问答和阅读理解)进行微调来获得最先进的结果。

5.此外,T5团队进行了深入研究,以学习最有效的预训练和微调方法。在他们的论文中,他们详细说明了哪些参数对于实现理想结果最重要。

Code

app.py

from transformers import AutoModelWithLMHead, AutoTokenizer
import gradio as grad
text2text_tkn = AutoTokenizer.from_pretrained("mrm8488/t5-base-finetuned-question-generation-ap")
mdl = AutoModelWithLMHead.from_pretrained("mrm8488/t5-base-finetuned-question-generation-ap")
def text2text(context,answer):
    input_text = "answer: %s  context: %s </s>" % (answer, context)
    features = text2text_tkn ([input_text], return_tensors='pt')
    output = mdl.generate(input_ids=features['input_ids'],
               attention_mask=features['attention_mask'],
               max_length=64)
    response=text2text_tkn.decode(output[0])
    return response
context=grad.Textbox(lines=10, label="English", placeholder="Context")
ans=grad.Textbox(lines=1, label="Answer")
out=grad.Textbox(lines=1, label="Genereated Question")
grad.Interface(text2text, inputs=[context,ans], outputs=out).launch()

清单 5-20 app.py代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-32所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-32 从段落中产生问题

【NLP】第 5 章 :使用Hugging Face的任务

图 5-33 从文本生成问题的另一个例子

在同一个例子中,让我们稍微改变一下答案。

现在我们来看一下 T5 的另一个用例,就是对一段文字进行总结。

这是代码。

app.py

from transformers import AutoTokenizer, AutoModelWithLMHead
import gradio as grad
text2text_tkn = AutoTokenizer.from_pretrained("deep-learning-analytics/wikihow-t5-small")
mdl = AutoModelWithLMHead.from_pretrained("deep-learning-analytics/wikihow-t5-small")
def text2text_summary(para):
    initial_txt = para.strip().replace("\n","")
    tkn_text = text2text_tkn.encode(initial_txt, return_tensors="pt")
    tkn_ids = mdl.generate(
            tkn_text,
            max_length=250,
            num_beams=5,
            repetition_penalty=2.5,
            early_stopping=True
        )
    response = text2text_tkn.decode(tkn_ids[0], skip_special_tokens=True)
    return response
para=grad.Textbox(lines=10, label="Paragraph", placeholder="Copy paragraph")
out=grad.Textbox(lines=1, label="Summary")
grad.Interface(text2text_summary, inputs=para, outputs=out).launch()

清单 5-21 app.py代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-34所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-34 使用 T5 模型总结文本

我们现在将执行更多可以使用 T5 模型执行的任务。下面列出了其中一些:

1.翻译

2.情感分类

3.释义

4.从句子中演绎陈述是否正确的分类

5.还有一些

我们将在下文中介绍上述一些任务。

使用 T5 的英语到德语

正如以下代码段中突出显示 的那样,我们需要在文本前加上translate English to German以生成相应的德语翻译。

Code

app.py

from transformers import T5ForConditionalGeneration, T5Tokenizer
import gradio as grad
text2text_tkn= T5Tokenizer.from_pretrained("t5-small")
mdl = T5ForConditionalGeneration.from_pretrained("t5-small")
def text2text_translation(text):
     inp = "translate English to German:: "+text
     enc = text2text_tkn(inp, return_tensors="pt")
     tokens = mdl.generate(**enc)
     response=text2text_tkn.batch_decode(tokens)
     return response
para=grad.Textbox(lines=1, label="English Text", placeholder="Text in English")
out=grad.Textbox(lines=1, label="German Translation")
grad.Interface(text2text_translation, inputs=para, outputs=out).launch()

清单 5-22 app.py代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-35所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-35 使用 T5 模型进行翻译

如果我们将这个翻译后的文本 放入谷歌翻译 ,我们会得到如图5-36所示的结果。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-36 使用谷歌翻译翻译

这正是我们提供的输入。

现在我们更改前缀以在 app.py 中将英语翻译成法语。

from transformers import T5ForConditionalGeneration, T5Tokenizer
import gradio as grad
text2text_tkn= T5Tokenizer.from_pretrained("t5-small")
mdl = T5ForConditionalGeneration.from_pretrained("t5-small")
def text2text_translation(text):
     inp = "translate English to French:: "+text
     enc = text2text_tkn(inp, return_tensors="pt")
     tokens = mdl.generate(**enc)
     response=text2text_tkn.batch_decode(tokens)
     return response
para=grad.Textbox(lines=1, label="English Text", placeholder="Text in English")
out=grad.Textbox(lines=1, label="French Translation")
grad.Interface(text2text_translation, inputs=para, outputs=out).launch()

清单 5-23 app.py代码

提交更改并等待 部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-37所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-37 基于 T5 模型的翻译 的另一个例子

【NLP】第 5 章 :使用Hugging Face的任务

图 5-38 使用谷歌翻译翻译

我们对谷歌进行检查。

我们可以看到结果与谷歌翻译中的结果完全 一样。

情感分析任务

接下来,我们尝试使用 T5 模型进行情感分类 。

我们使用 sst2 句子前缀进行情感分析。

Code

app.py

from transformers import T5ForConditionalGeneration, T5Tokenizer
import gradio as grad
text2text_tkn= T5Tokenizer.from_pretrained("t5-small")
mdl = T5ForConditionalGeneration.from_pretrained("t5-small")
def text2text_sentiment(text):
     inp = "sst2 sentence: "+text
     enc = text2text_tkn(inp, return_tensors="pt")
     tokens = mdl.generate(**enc)
     response=text2text_tkn.batch_decode(tokens)
     return response
para=grad.Textbox(lines=1, label="English Text", placeholder="Text in English")
out=grad.Textbox(lines=1, label="Sentiment")
grad.Interface(text2text_sentiment, inputs=para, outputs=out).launch()

清单 5-24 app.py代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-39所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-39 使用 T5 的情感分析任务 – 正面

【NLP】第 5 章 :使用Hugging Face的任务

图 5-40 使用 T5 的情感分析任务 – 负面

让我们在不同的文本上再次运行代码 。

我们得到以下输出。

同样,您可以通过在各种任务中使用这些预训练模型来观察 生活变得多么轻松。

接下来我们使用 T5 模型通过使用可乐句前缀来检查文本的语法接受度,如下所示。

Code

app.py

from transformers import T5ForConditionalGeneration, T5Tokenizer
import gradio as grad
text2text_tkn= T5Tokenizer.from_pretrained("t5-small")
mdl = T5ForConditionalGeneration.from_pretrained("t5-small")
def text2text_acceptable_sentence(text):
     inp = "cola sentence: "+text
     enc = text2text_tkn(inp, return_tensors="pt")
     tokens = mdl.generate(**enc)
     response=text2text_tkn.batch_decode(tokens)
     return response
para=grad.Textbox(lines=1, label="English Text", placeholder="Text in English")
out=grad.Textbox(lines=1, label="Whether the sentence is acceptable or not")
grad.Interface(text2text_acceptable_sentence, inputs=para, outputs=out).launch()

清单 5-25 app.py代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-41所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-41 句子可接受性

句子释义任务

现在我们使用 mrpc sentence1 sentence2 前缀检查两个句子 是否是彼此的释义。

Code

app.py

from transformers import T5ForConditionalGeneration, T5Tokenizer
import gradio as grad
text2text_tkn= T5Tokenizer.from_pretrained("t5-small")
mdl = T5ForConditionalGeneration.from_pretrained("t5-small")
def text2text_paraphrase(sentence1,sentence2):
     inp1 = "mrpc sentence1: "+sentence1
     inp2 = "sentence2: "+sentence2
     combined_inp=inp1+" "+inp2
     enc = text2text_tkn(combined_inp, return_tensors="pt")
     tokens = mdl.generate(**enc)
     response=text2text_tkn.batch_decode(tokens)
     return response
sent1=grad.Textbox(lines=1, label="Sentence1", placeholder="Text in English")
sent2=grad.Textbox(lines=1, label="Sentence2", placeholder="Text in English")
out=grad.Textbox(lines=1, label="Whether the sentence is acceptable or not")
grad.Interface(text2text_paraphrase, inputs=[sent1,sent2], outputs=out).launch()

清单 5-26 app.py代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-42所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-42 显示句子是否等价

【NLP】第 5 章 :使用Hugging Face的任务

图 5-43 再次显示句子是否等价

让我们在下面的两个完全不同的句子上运行相同的代码 。

我们得到以下输出。

接下来,我们研究检查 从文本中推导出的语句是否正确的任务。我们再次通过 T5 模型执行此操作。

为此,我们需要使用 rte sentence1 sentence 2prefix,如下面的代码所示。

Code

app.py

from transformers import T5ForConditionalGeneration, T5Tokenizer
import gradio as grad
text2text_tkn= T5Tokenizer.from_pretrained("t5-small")
mdl = T5ForConditionalGeneration.from_pretrained("t5-small")
def text2text_deductible(sentence1,sentence2):
     inp1 = "rte sentence1: "+sentence1
     inp2 = "sentence2: "+sentence2
     combined_inp=inp1+" "+inp2
     enc = text2text_tkn(combined_inp, return_tensors="pt")
     tokens = mdl.generate(**enc)
     response=text2text_tkn.batch_decode(tokens)
     return response
sent1=grad.Textbox(lines=1, label="Sentence1", placeholder="Text in English")
sent2=grad.Textbox(lines=1, label="Sentence2", placeholder="Text in English")
out=grad.Textbox(lines=1, label="Whether sentence2 is deductible from sentence1")
grad.Interface(text2text_ deductible, inputs=[sent1,sent2], outputs=out).launch()

清单 5-27 app.py代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-44所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-44 用于检查一个句子是否可以从另一个句子中扣除的 Gradio 应用程序 – 蕴涵

【NLP】第 5 章 :使用Hugging Face的任务

图 5-45 用于检查一个句子是否可以从另一个句子中扣除的 Gradio 应用程序 – not_entailment

在这里,蕴含意味着 句子 2 可以从句子 1 中推导出来。

让我们为同一个任务提供不同的句子,看看我们得到什么作为输出。

这给出了以下输出。

这里,输出中的 not_entailment 表示 sentence2 不能从 sentence1 中扣除。

从 T5转到 聊天机器人的世界,我们将展示使用 huggingface API 开发聊天机器人是多么容易。

聊天机器人/对话机器人

作为本章的最后一个例子,我们举了一个例子来说明如何使用 Transformers 库构建一个简单的对话系统 。

机器学习研究面临着构建开放域聊天机器人形式的巨大障碍。虽然之前的研究表明,缩放神经模型可以改善结果,但这并不是开发一个好的聊天机器人时应该考虑的唯一因素。良好的对话需要很多技巧,聊天机器人需要具备这些技巧才能进入无缝对话。

这些技能将需要理解正在交谈的内容以及对话中前几句话中所讨论的内容。该机器人应该能够处理有人试图将其诱骗为断章取义的问题的场景。

下面我们展示了一个名为 Alicia 的简单机器人,它基于Microsoft DialoGPT 模型 。

Code

app.py

from transformers import AutoModelForCausalLM, AutoTokenizer,BlenderbotForConditionalGeneration
import torch
chat_tkn = AutoTokenizer.from_pretrained("microsoft/DialoGPT-medium")
mdl = AutoModelForCausalLM.from_pretrained("microsoft/DialoGPT-medium")
#chat_tkn = AutoTokenizer.from_pretrained("facebook/blenderbot-400M-distill")
#mdl = BlenderbotForConditionalGeneration.from_pretrained("facebook/blenderbot-400M-distill")
def converse(user_input, chat_history=[]):
    user_input_ids = chat_tkn(user_input + chat_tkn.eos_token, return_tensors='pt').input_ids
    # keep history in the tensor
    bot_input_ids = torch.cat([torch.LongTensor(chat_history), user_input_ids], dim=-1)
    # get response
    chat_history = mdl.generate(bot_input_ids, max_length=1000, pad_token_id=chat_tkn.eos_token_id).tolist()
    print (chat_history)
    response = chat_tkn.decode(chat_history[0]).split("<|endoftext|>")
    print("starting to print response")
    print(response)
    # html for display
    html = "<div class='mybot'>"
    for x, mesg in enumerate(response):
        if x%2!=0 :
           mesg="Alicia:"+mesg
           clazz="alicia"
        else :
           clazz="user"
        print("value of x")
        print(x)
        print("message")
        print (mesg)
        html += "<div class='mesg {}'> {}</div>".format(clazz, mesg)
    html += "</div>"
    print(html)
    return html, chat_history
import gradio as grad
css = """
.mychat {display:flex;flex-direction:column}
.mesg {padding:5px;margin-bottom:5px;border-radius:5px;width:75%}
.mesg.user {background-color:lightblue;color:white}
.mesg.alicia {background-color:orange;color:white,align-self:self-end}
.footer {display:none !important}
"""
text=grad.inputs.Textbox(placeholder="Lets chat")
grad.Interface(fn=converse,
             theme="default",
             inputs=[text, "state"],
             outputs=["html", "state"],
             css=css).launch()

清单 5-28 app.py代码

requirements.txt

gradio

transformers

torch

transformers[sentencepiece]

提交更改并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击“提交”按钮以查看对话,如图5-46所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-46 使用Microsoft DialoGPT 模型 的聊天机器人

代码和代码注释生成

代码生成正迅速 成为自然语言处理 (NLP) 领域的热门话题,与普遍看法相反,这不仅仅是炒作。OpenAI Codex 模型 刚刚可用。如果您查看其中一个 Codex 演示,您将能够观察到这些模型将如何影响未来软件编程的开发。由于预训练模型不向公众开放,如果要求不仅仅是使用 API 对其进行试验,那么从研究人员的角度来看,使用 Codex 模型是不可能的。从技术上讲,可以使用已发表的论文重新创建 Codex;但是,为了这样做,你需要一个大的GPU 集群 ,这是很少有人能够获得或负担得起的东西。我相信这种限制会使研究变得更加困难。想象一下,如果作者选择不公开预训练的权重;我们可用的 BERT 下游应用程序的数量将直线下降。我们只能希望 Codex 不是目前可用的唯一代码生成范例。

在本章中,我们将介绍 CodeGen ,这是一种编码器-解码器代码生成模型,具有公开可用的预训练检查点,您可以立即对其进行测试。

代码生成器

CodeGen 是一种语言模型,可以将基本的英文提示转换为可以执行的代码。您无需自己编写代码,而是使用自然语言描述代码应该做什么,然后机器会根据您所描述的内容为您编写代码。

在由 Erik Nijkamp、Bo Pang、Hiroaki Hayashi、Lifu Tu、Huan Wang、Yingbo Zhou、Silvio Savarese 和 Caiming Xiong 撰写的论文“A Conversational Paradigm for Program Synthesis”中,有一系列用于程序合成的自回归语言模型称为代码生成器。这些模型首先可以从该存储库下载,具有三种不同的预训练数据变体(NL、Multi 和 Mono),以及四种不同的模型大小变体(350M、2B、6B、16B)。

在本章 中,我们将研究一些示例,我们可以在其中使用 CodeGen 模型生成代码。

我们将使用具有 3.5 亿个参数的小型CodeGen 模型 。

Code

app.py

from transformers import AutoTokenizer, AutoModelForCausalLM
import gradio as grad
codegen_tkn = AutoTokenizer.from_pretrained("Salesforce/codegen-350M-mono")
mdl = AutoModelForCausalLM.from_pretrained("Salesforce/codegen-350M-mono")
def codegen(intent):
# give input as text which reflects intent of the program.
     #text = " write a function which takes 2 numbers as input and returns the larger of the two"
     input_ids = codegen_tkn(intent, return_tensors="pt").input_ids
     gen_ids = mdl.generate(input_ids, max_length=128)
     response = codegen_tkn.decode(gen_ids[0], skip_special_tokens=True)
     return response
output=grad.Textbox(lines=1, label="Generated Python Code", placeholder="")
inp=grad.Textbox(lines=1, label="Place your intent here")
grad.Interface(codegen, inputs=inp, outputs=output).launch()

清单 5-29 app.py代码

requirements.txt

gradio

git+ https://github.com/huggingface/transformers.git

torch

transformers[sentencepiece]

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-47所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-47 用于查找两个数字中较大者的示例代码生成器

正如我们所看到的,代码 并不完全准确,但抓住了意图。

接下来,我们尝试生成如图5-48所示的冒泡排序代码。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-48 冒泡排序文本到代码示例

通过修改 app.py 文件(将 max_length 参数更改为 256),可以对合并排序执行相同的操作 。

from transformers import AutoTokenizer, AutoModelForCausalLM
import gradio as grad
codegen_tkn = AutoTokenizer.from_pretrained("Salesforce/codegen-350M-mono")
mdl = AutoModelForCausalLM.from_pretrained("Salesforce/codegen-350M-mono")
def codegen(intent):
# give input as text which reflects intent of the program.
     #text = " write a function which takes 2 numbers as input and returns the larger of the two"
     input_ids = codegen_tkn(intent, return_tensors="pt").input_ids
     gen_ids = mdl.generate(input_ids, max_length=256)
     response = codegen_tkn.decode(gen_ids[0], skip_special_tokens=True)
     return response
output=grad.Textbox(lines=1, label="Generated Python Code", placeholder="")
inp=grad.Textbox(lines=1, label="Place your intent here")
grad.Interface(codegen, inputs=inp, outputs=output).launch()
text = """def merge_sort(unsorted:list):
"""
input_ids = codegen_tkn(text, return_tensors="pt").input_ids
gen_ids = mdl.generate(input_ids, max_length=256)
print(codegen_tkn.decode(gen_ids[0], skip_special_tokens=True))

清单 5-30 app.py代码

提交更改 并等待部署状态变为绿色。发布单击菜单中的 App 选项卡以启动应用程序。

向 UI 提供输入并单击提交按钮以查看结果,如图5-49所示。

【NLP】第 5 章 :使用Hugging Face的任务

图 5-49 生成归并排序代码

代码注释生成器

本节的目标是将一些代码作为输入并让模型为该代码生成注释 。 在这种情况下,我们将使用 Salesforce CodeT5 模型,该模型在Java 代码 上进行了微调。

顾名思义,T5 编码器-解码器范例 是构建 CodeT5 [1] 的基础。它没有像对待任何其他自然语言 (NL) 文本一样对待源代码,而是应用了一种新的标识符感知预训练目标,该目标利用了代码语义。这与以前依赖于传统预训练方法的代码生成模型形成对比。

作者分发了两个预训练模型 :一个具有 2.2 亿个数据点的基本模型和一个只有 6000 万个数据点的较小模型。除此之外,他们还通过公共 GCP 存储桶分发了所有微调检查点。此外,著名的 huggingface 库使这两种预训练模型都可供使用。

CodeT5 是一个统一的预训练编码器-解码器转换器模型 。CodeT5 方法使用了一个统一的框架,它不仅有利于多任务学习,而且还支持轻松的代码解释和生成活动。

CodeT5 的预训练是使用两个单独的目标以顺序方式 完成的。该模型在前 100 个时期内使用标识符感知的去噪目标进行了优化。这训练模型区分标识符(例如变量名、函数名等)和特定编程语言 (PL) 关键字(例如,if、while 等)。然后,使用双峰双生成目标对总共 50 次迭代执行优化。作为最终目标,我们希望确保代码和 NL 描述彼此更加一致。

由于此示例需要从非 huggingface 存储库 下载模型(截至撰写本书时,模型尚未在 huggingface 上更新),因此我们将在 Google Colab 而不是 huggingface 中执行此示例。

在 Colab 中创建一个新笔记本。

在开始评论生成代码之前,我们需要安装依赖项:

!pip install -q git+https://github.com/huggingface/transformers.git

创建评论模型目录 :

!mkdir comment_model
%cd comment_model
!wget -O config.json https://storage.googleapis.com/sfr-codet5-data-research/pretrained_models/codet5_base/config.json
!wget -O pytorch_model.bin https://storage.googleapis.com/sfr-codet5-data-research/finetuned_models/summarize_java_codet5_base.bin
from transformers import RobertaTokenizer, T5ForConditionalGeneration
model_name_or_path = './comment_model'  #  Path to the folder created earlier.
codeT5_tkn = RobertaTokenizer.from_pretrained('Salesforce/codet5-base')
mdl = T5ForConditionalGeneration.from_pretrained(model_name_or_path)
# provide code snippet as input
text = """ public static void main(String[] args) {
    int num = 29;
    boolean flag = false;
    for (int i = 2; i <= num / 2; ++i) {
      // condition for nonprime number
      if (num % i == 0) {
        flag = true;
        break;
      }
    }
    if (!flag)
      System.out.println(num + " is a prime number.");
    else
      System.out.println(num + " is not a prime number.");
  } """
input_ids = codeT5_tkn(text, return_tensors="pt").input_ids
gen_ids = mdl.generate(input_ids, max_length=20)
print(codeT5_tkn.decode(gen_ids[0], skip_special_tokens=True))

清单 5-31 从源代码文件 生成注释的代码

我们得到以下输出:

A test program to check if the number is a prime number .

我们输入另一个文本并检查:

text = """ LocalDate localDate = new LocalDate(2020, 1, 31);
int numberOfDays = Days.daysBetween(localDate, localDate.plusYears(1)).getDays();
boolean isLeapYear = (numberOfDays > 365) ? true : false;"""
input_ids = codeT5_tkn(text, return_tensors="pt").input_ids
gen_ids = mdl.generate(input_ids, max_length=150)
print(codeT5_tkn.decode(gen_ids[0], skip_special_tokens=True))

输出:

Returns true if the year is a leap year

接下来,我们尝试使用访问Google 搜索 API 的代码。

text = """
String google = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";
    String search = "stackoverflow";
    String charset = "UTF-8";
    URL url = new URL(google + URLEncoder.encode(search, charset));
    Reader reader = new InputStreamReader(url.openStream(), charset);
    GoogleResults results = new Gson().fromJson(reader, GoogleResults.class);
    // Show title and URL of 1st result.
    System.out.println(results.getResponseData().getResults().get(0).getTitle());
    System.out.println(results.getResponseData().getResults().get(0).getUrl());
"""
input_ids = codeT5_tkn(text, return_tensors="pt").input_ids
gen_ids = mdl.generate(input_ids, max_length=50, temperature=0.2,num_beams=200,no_repeat_ngram_size=2,num_return_sequences=5)
print(codeT5_tkn.decode(gen_ids[0], skip_special_tokens=True))

清单 5-32 尝试为 Google 搜索代码生成注释的代码

这输出

https://www. googleapis. com / ajax. services. search. web?v = 1. 0 &q = 123 Show title and URL of 1st result.

最后的结果可能看起来不太好,但这可以通过调整具体参数来改善,我留给你去试验。

最后,这些预训练模型 还可以针对特定的编程语言(如 C、C++ 等)进行微调。

概括

在本章中,我们研究了转换器如何用于处理文本并将其应用于分类、翻译、摘要等各种任务的各种用例和实现。我们还研究了如何使用 huggingface 轻松构建聊天机器人蜜蜂。

在下一章中,我们将了解如何将变换器应用于图像处理领域。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年2月26日 上午9:04
下一篇 2023年2月26日 上午9:05

相关推荐