在彩信和电子邮件转发流行的那一天,励志名言风靡一时。我记得我的父母在每天早晨开始时将我转发。快进到今天,如果幸运的话,您将成为所选消息应用程序(Whatsapp、Telegram 等)上某个转发组的一员。
受同一想法的启发,今天我们将构建一项服务,向我们的朋友和家人发送人工智能生成的当天励志名言。我们不会硬编码励志名言列表,而是使用机器学习模型按需生成名言,这样我们就永远不会用完名言来分享!
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 即可完成此项目。图书馆如
我们将使用
幸运的是,在我们的案例中,有一个经过微调的模型已经在 500k 报价数据集上进行了训练 -
有了 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 可以快速响应我们,也可以在其他应用程序中使用。 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
端点发送请求,该端点将为我们生成报价。
现在我们有了一种按需生成报价的方法,我们可以停在这里并开始通过以下方式发送报价
鉴于我们的 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,它提供了一个很好的端点来返回与查询匹配的随机图像。开幕式
为了让事情变得有趣,我们可以使用不同的查询词,例如星星等。下载背景图片的代码如下所示 -
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
好的,现在我们有了背景图片和报价,这意味着我们可以组装最终图片,发送给收件人。在高层次上,我们想在图像上放置一些文本,但即使是这个简单的任务也可能具有挑战性。对于初学者,有许多问题需要我们回答
其中一些问题的答案比其他问题更复杂。为简单起见,我们将文本放在中间,并做一些环绕以使其看起来不错。最后,我们现在将使用浅色文本。对于所有图像处理,我们将使用 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
最后,我们拥有了开始向我们的朋友和家人发送精彩报价所需的一切。我们可以使用 Courier 创建一个好看的电子邮件模板。
使用 Courier 发送消息非常简单。虽然 Courier 有自己的 SDK 可以简化集成,但我更喜欢使用它的 API 端点来简化事情。有了我的AUTH_TOKEN
和TEMPLATE_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密钥可以在
本教程展示了开始使用机器学习和 Courier 是多么容易。
如果你想继续改进这个项目,这里有一些有趣的想法可以尝试
🔗
🔗