软件著作代码在线生成_利用 50 行 Python 代码构建一个在线文本生成器

本文指导读者使用OpenAI的GPT-2模型和Panel框架创建一个在线文本生成Web应用。首先介绍如何加载模型和构建预测函数,然后讲解如何利用Panel构建交互式的web界面,让用户输入文本并自动生成续篇。
摘要由CSDN通过智能技术生成

本指南将引导你学习构建一个自动完成任意输入文本的Web应用程序。

b24beaa82aa4e194e5037af0b162554d.png

作者 | Dev Sharma

译者 | 苏本如,责编 | 郭芮

出品 | CSDN(ID:CSDNnews)

以下为译文:

在本文中,我们将使用OpenAI的新一代表语言模型GPT-2来建立模型,使用Panel框架来构建web页面的仪表板。本指南分为两部分。在第一部分中,我们将加载我们的模型并编写一个预测函数。在第二部分中,我们将构建一个web应用程序。

自动生成文本的应用程序示例。我们将构建这个web应用程序的一个更简单的变体。

816bcc3bf8bb6e864874d4d7d1ea84bf.png a5b133a29cc7ca8a07f40711f29c4bc9.png

准备工作

本教程假设你已经安装了Python 3.7+,并且对语言模型有一定的了解。尽管本教程所涉及的所有步骤都可以在Jupyter之外完成,但是强烈建议你使用jupyter notebook。

我们将使用PyTorch作为我们选择的深度学习库。在PyTorch中,我们将使用transformers库导入预先训练好的OpenGPT-2模型。可以通过在bash命令行中分别输入以下命令来安装这些库:

pip install torch
pip install transformers

对于我们的web应用程序,我们将利用Panel这个窗口容器/框架,这是一个很好的工具,可以被用来从jupyter notebooks或者常规的Python脚本中轻松地创建可维护的仪表板。可以使用以下命令安装Panel:

pip install panel
91cc5ce6a2cf03f48ec01268eae2e176.png

第一部分:建立模型

OpenAI的GPT是一种基于transformer的语言模型,它在生成类似人类语言的文本方面受到了很多关注。如果你以前没有尝试过,你很可能会在阅读结束时得出同样的观点。

加载模型

首先,我们需要导入所需的包。详情如下:

import numpy as np
import torch
import torch.nn.functional as F
from transformers import GPT2Tokenizer, GPT2LMHeadModel
from random import choice

接下来,我们将加载OpenGPT2的Tokenizer和语言模型:(如果是第一次运行,可能需要几分钟下载预先训练的模型)

tok = GPT2Tokenizer.from_pretrained("gpt2")
model = GPT2LMHeadModel.from_pretrained("gpt2")

预测函数

在这个阶段,大部分工作已经完成了。因为我们的模型是预先训练过的,所以我们不需要再次训练它或做任何修改。我们只需要编写一个函数,它可以向模型输入文本并生成预测的文本。

def get_pred(text, model, tok, p=0.7):
input_ids = torch.tensor(tok.encode(text)).unsqueeze(0)
logits = model(input_ids)[0][:, -1]
probs = F.softmax(logits, dim=-1).squeeze
idxs = torch.argsort(probs, descending=True)
res, cumsum = , 0.
for idx in idxs:
res.append(idx)
cumsum += probs[idx]
if cumsum > p:
pred_idx = idxs.new_tensor([choice(res)])
break
pred = tok.convert_ids_to_tokens(int(pred_idx))
return tok.convert_tokens_to_string(pred)

这个函数中发生了很多事情。因此,让我们把它分解来看看。首先,我们对input_ids中的输入文本进行标记(tokenize)和编码(encode)。接着,我们要求我们的模型为下一个单词/标记(token)生成一个logits向量。在应用softmax函数并按降序对这些可能的概率结果进行排序之后,我们得到了一个向量idxs,它按各自的概率顺序列出了每个token的索引。

在这个阶段,我们可以选择概率最高的token。但是,我们希望能够混合结果,以便相同的输入文本可以生成各种文本。为此,我们将添加一个随机元素,从最可能的下一个token列表中选择一个随机token。这样的话,我们就不会每次都选择相同的预测token。为了做到这一点,我们采用了Nucleus (Top-p) Sampling 方式。

我们通过循环遍历每个概率来执行此操作,直到循环遍历的所有概率之和大于p(这里的p是一个介于0到1之间的任意数字)。当p被超过前,所有遍历到的token都将被存储在列表res中。一旦p被超过,我们就从这个列表中随机选择一个token。请记住,我们正在遍历的概率列表包含了其按概率排序的索引。注意,p值越高,我们的列表中将包含更多的token。反之亦然。因此,如果每次都希望得到相同的结果,可以将p值设置为0。

现在,让我们测试一下我们的预测函数:

6993c949fbf10946f080e1594bb4b4ee.gif

每次都会有不同的结果,这正是我们所期望的。现在,我们的预测功能准备好了。让我们开始构建我们的Web应用程序吧!

5b4da18942c8358f77c217c36cd308ad.png

第二部分:构建web应用程序

Panel框架简介

0cd6cc189a838ba75461f492d625e15e.png

如果你还不熟悉Panel框架,那请记住,Panel框架可以帮助我们创建一个web仪表板和web应用程序。简而言之,你需要知道的是它有三个主要组件:

  • Panel:可以包含一个或多个窗格(pane)对象的容器,面板(pane)对象是指文本、图像、图形、小部件等(也可以包含其他panel);

  • Pane:任何单个对象,例如文本、图像、数据帧等;

  • Widget(小部件):用户可以自行调整的项目,包括文本输入框、滑块、按钮、复选框,等等可以改变窗格的行为的小部件。

下一个也是最后一个你需要知道的事情是:我们有多种方法来定义不同的窗格和小部件之间的交互方式,我们称之为“callback(回调)”。例如,如果按下某个按钮,其他窗格应该如何更新呢?稍后我们将定义一个回调函数来演示它将如何准确地做到这一点。

Web应用程序简介

我们的文本生成器应用程序将有一个输入窗口,以便用户输入他们想要输入的文本。接下来,用户应该能够通过按下按钮生成新的token。在这之后,它将使用我们在第一部分中定义的预测函数来预测新的token来生成新文本。最后,用户应该能够在已经预测的token基础之上继续生成新的文本。

实施

让我们首先导入Panel并创建文本输入小部件:

import panel as pn
pn.extension # loading panel's extension for jupyter compatibility text_input = pn.widgets.TextInput

现在,如果在jupyter中执行文本输入,我们将得到以下结果:

c808cc290e36d21bfab0cce61df6ea53.gif

接下来,我们需要一个窗格,它会在越来越多的token生成时存储整个文本:

generated_text = pn.pane.Markdown(object=text_input.value)

注意,这里我们将文本对象设置为text_input的值。我们希望generated_text的值与text_input的值相同,因为我们将要在generated_text之上预测新文本。随着越来越多的token被添加到我们的序列中,我们将继续基于generated_text进行预测,直到用户改变了text_input。一旦用户改变了text_input,这个进程将重新启动。

然而,到这里事情还没有完全结束。尽管generated_text将在开始时接受text_input的值,但如果text_input值发生更改,generated_text值将不会自我更新。为此,我们需要像下面这样将这两个对象链接在一起:

text_input.link(generated_text, value='object')

这里,我们在text_input和generated_text之间形成了单向链接。因此,每当text_input的值发生更改时,generated_text值也将更改为新值。如下所示:

257aff4f2e2cbf91d6986f81ab386ccc.gif

观察面板中文的text_input和generated_text之间的链接行为。注意:作为组件的pn.Row也是一个面板,即它是一个窗格和小部件的容器。

现在我们有了两个文本对象,让我们来创建按钮小部件:

button = pn.widgets.Button(name="Generate
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值