paint-brush
使用 Courier 和 GPT2 生成每日励志名言经过@courier
559 讀數
559 讀數

使用 Courier 和 GPT2 生成每日励志名言

经过 Courier8m2023/02/13
Read on Terminal Reader

太長; 讀書

在彩信和电子邮件转发流行的那一天,励志名言风靡一时。我们不会硬编码励志名言列表,而是使用机器学习模型按需生成名言。我们将使用 Hugging Face 库来加载和提供将为我们生成报价的 ML 模型。
featured image - 使用 Courier 和 GPT2 生成每日励志名言
Courier HackerNoon profile picture
0-item


在彩信和电子邮件转发流行的那一天,励志名言风靡一时。我记得我的父母在每天早晨开始时将我转发。快进到今天,如果幸运的话,您将成为所选消息应用程序(Whatsapp、Telegram 等)上某个转发组的一员。


受同一想法的启发,今天我们将构建一项服务,向我们的朋友和家人发送人工智能生成的当天励志名言。我们不会硬编码励志名言列表,而是使用机器学习模型按需生成名言,这样我们就永远不会用完名言来分享!

指示

第 1 部分:使用 AI 生成励志名言

OpenGPT2 和语言模型

OpenAI GPT-2 模型由 Alec Radford、Jeffrey Wu、Rewon Child、David Luan、Dario Amodei 和 Ilya Sutskever 在 Language Models are Unsupervised Multitask Learners 中提出。它是一个使用语言建模在约 40 GB 文本数据的超大语料库上进行预训练的因果转换器。

为了简化这一点,OpenAI GPT2 在高层次上是一个大型语言模型,已经过大量数据的训练。该模型可用于预测给定序列中的下一个标记。

如果这听起来太复杂,请不要担心,您无需了解任何机器学习或 AI 即可完成此项目。图书馆如拥抱的脸使在我们的应用程序中使用此模型变得非常容易。

拥抱的脸

我们将使用拥抱的脸库来加载和服务将为我们生成报价的 ML 模型。 Hugging Face 使得在我们的项目中使用 transformer 模型(GPT2 是一种类型)变得非常容易,而无需任何 ML 或 AI 知识。如前所述,GPT2 是一种通用语言模型,这意味着它擅长在给定输入序列的情况下预测通用文本。在我们的例子中,我们需要一个更适合生成报价的模型。为此,我们有两种选择:

  1. 我们可以使用我们自己的文本来微调 GPT2 模型,为此我们需要一个好的引文数据集。
  2. 或者我们可以找到一个已经存在的模型,该模型已经用一些引号进行了微调。

幸运的是,在我们的案例中,有一个经过微调的模型已经在 500k 报价数据集上进行了训练 - https://huggingface.co/nandinib1999/quote-generator

有了 Hugging Face,使用这个模型就像创建分词器一样简单


from transformers import AutoTokenizer, AutoModelWithLMHead, pipeline tokenizer = AutoTokenizer.from_pretrained("nandinib1999/quote-generator")


然后从预训练模型构建模型


model = AutoModelWithLMHead.from_pretrained("nandinib1999/quote-generator")


最后,构建我们可以用来生成报价的生成器

generator = pipeline("text-generation", model=model, tokenizer=tokenizer) # use a starting prompt generator("Keep an open mind and") [{'generated_text': 'Keep an open mind and a deep love for others'}]

构建 API 来为模型提供服务

既然我们有办法为我们生成报价,我们就必须考虑如何在我们的应用程序中使用它。有多种方法可以构建它。

  1. 每次我们要运行脚本发送脚本时加载模型。
  2. 创建服务于此 GPT2 模型的 API 或服务,以按需为我们生成报价。

第二个选项的一个关键加点是一旦加载模型,API 可以快速响应我们,也可以在其他应用程序中使用。 FWIW,第一个选项也是完全有效的方法。

我们可以使用 __Fast API __来构建快速服务 API。这就是它的样子

# in file api.py from pydantic import BaseModel from fastapi import FastAPI, HTTPException from transformers import AutoTokenizer, AutoModelWithLMHead, pipeline ## create the pipeline tokenizer = AutoTokenizer.from_pretrained("nandinib1999/quote-generator") model = AutoModelWithLMHead.from_pretrained("nandinib1999/quote-generator") generator = pipeline("text-generation", model=model, tokenizer=tokenizer) app = FastAPI() class QuoteRequest(BaseModel): text: str class QuoteResponse(BaseModel): text: str ### Serves the Model API to generate quote @app.post("/generate", response_model=QuoteResponse) async def generate(request: QuoteRequest): resp = generator(request.text) if not resp[0] and not resp[0]["generated_text"]: raise HTTPException(status_code=500, detail='Error in generation') return QuoteResponse(text=resp[0]["generated_text"])


让我们测试一下


$ uvicorn api:app INFO: Started server process [40767] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)


现在我们可以开始向/generate端点发送请求,该端点将为我们生成报价。

第 2 部分:构建报价生成器

现在我们有了一种按需生成报价的方法,我们可以停在这里并开始通过以下方式发送报价导游.但是我们在开玩笑,没有人再读文字了!我们可以通过使用漂亮的图像并将我们的报价放在上面使其看起来像海报来使它变得有趣。

生成报价

鉴于我们的 API,我们现在可以执行以下操作来生成报价

from random import choice # feel free to add more starting prompts for more variety canned_seeds = ["Always remember to", "Start today with", "It is okay to"] seed = choice(canned_seeds) resp = requests.post('http://127.0.0.1:8000/generate', data=json.dumps({"text": seed})) return resp.json()["text"]

下载背景图像

第一个挑战是为我们的报价获取漂亮的背景图片。为此,我们将使用 Unsplash API,它提供了一个很好的端点来返回与查询匹配的随机图像。开幕式https://source.unsplash.com/random/800×800/?nature在我们的浏览器中返回一个漂亮的自然图像。

为了让事情变得有趣,我们可以使用不同的查询词,例如星星等。下载背景图片的代码如下所示 -

 from random import choice image_backgdrops = ['nature', 'stars', 'mountains', 'landscape'] backdrop = choice(image_backdrops) response = requests.get("https://source.unsplash.com/random/800×800/?"+ backdrop, stream=True) # write the output the img.png on our filesystem with open('img.png', 'wb') as out_file: shutil.copyfileobj(response.raw, out_file) del response

使用报价创建图像

好的,现在我们有了背景图片和报价,这意味着我们可以组装最终图片,发送给收件人。在高层次上,我们想在图像上放置一些文本,但即使是这个简单的任务也可能具有挑战性。对于初学者,有许多问题需要我们回答

  1. 如何将文本放置在图像上?
  2. 包装文本怎么样?
  3. 文本应该是什么颜色才能在背景图像上可见?
  4. 我们如何为具有不同宽度和高度的图像执行此操作?

其中一些问题的答案比其他问题更复杂。为简单起见,我们将文本放在中间,并做一些环绕以使其看起来不错。最后,我们现在将使用浅色文本。对于所有图像处理,我们将使用 Python 图像库 (PIL) 来简化操作。

 # use the image we downloaded in the above step img = Image.open("img.png") width, height = img.size image_editable = ImageDraw.Draw(img) # wrap text lines = textwrap.wrap(text, width=40) # get the line count and generate a starting offset on y-axis line_count = len(lines) y_offset = height/2 - (line_count/2 * title_font.getbbox(lines[0])[3]) # for each line of text, we generate a (x,y) to calculate the positioning for line in lines: (_, _, line_w, line_h) = title_font.getbbox(line) x = (width - line_w)/2 image_editable.text((x,y_offset), line, (237, 230, 211), font=title_font) y_offset += line_h img.save("result.jpg") print("generated " + filename) return filename


这会生成名为result.jpg的最终图像

上传图片

对于倒数第二步,我们需要上传图像,以便我们可以将其与 Courier 一起使用。在本例中,我使用的是 Firebase 存储,但您可以随意使用任何您喜欢的存储。


 import firebase_admin from firebase_admin import credentials from firebase_admin import storage cred = credentials.Certificate('serviceaccount.json') firebase_admin.initialize_app(cred, {...}) bucket = storage.bucket() blob = bucket.blob(filename) blob.upload_from_filename(filename) blob.make_public() return blob.public_url


第 3 步:与 Courier 集成

最后,我们拥有了开始向我们的朋友和家人发送精彩报价所需的一切。我们可以使用 Courier 创建一个好看的电子邮件模板。

从创建帐户开始。

在 Courier 中创建模板

发送信息

使用 Courier 发送消息非常简单。虽然 Courier 有自己的 SDK 可以简化集成,但我更喜欢使用它的 API 端点来简化事情。有了我的AUTH_TOKENTEMPLATE_ID ,我们可以使用下面的代码来发送我们的图像


import requests headers = { "Accept": "application/json", "Content-Type": "application/json", "Authorization": "Bearer {}".format(os.environ['COURIER_AUTH_TOKEN']) } message={ "to": { "email": os.environ["COURIER_RECIPIENT"] }, "data": { "date": datetime.today().strftime("%B %d, %Y"), "img": image_url ## this is image url we generated earlier }, "routing": { "method": "single", "channels": [ "email" ] }, "template": os.environ["COURIER_TEMPLATE"] } requests.post("https://api.courier.com/send", json={"message": message}, headers=headers)


API密钥可以在设置模板 ID 可以在模板设计的设置。就是这样!

结论

本教程展示了开始使用机器学习和 Courier 是多么容易。

如果你想继续改进这个项目,这里有一些有趣的想法可以尝试

  • 更好的背景图像:使用生成的报价中的术语来搜索图像?
  • 更好的文本背景颜色:为文本使用更好的颜色。一个很酷的想法是使用图像主色中的互补色。您可以使用 k 均值聚类来找出答案。
  • 添加更多渠道:将此扩展到消息传递客户端和短信上的消息!

关于作者

普拉卡是谷歌的一名高级软件工程师,致力于构建开发者工具。他是一位充满热情的开源开发人员,喜欢在空闲时间弹吉他。

快速链接

🔗快递文件

🔗拥抱的脸

🔗快速API

🔗不飞溅API