MMS と電子メール転送が普及していた当時、動機付けの引用は大流行でした。毎朝、両親が私を送り出してくれたのを覚えています。今日に早送りします。運が良ければ、選択したメッセージング アプリ (Whatsapp、Telegram など) のフォワード グループの一員です。
同じアイデアに触発されて、今日は友人や家族に、AI が生成したその日の動機付けの引用を送るサービスを構築します。動機付けの引用のリストをハードコーディングするのではなく、機械学習モデルを使用してオンデマンドで引用を生成し、共有する引用が不足することはありません!
OpenAI GPT-2 モデルは、Language Models are Unsupervised Multitask Learners で Alec Radford、Jeffrey Wu、Rewon Child、David Luan、Dario Amodei、Ilya Sutskever によって提案されました。これは、最大 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'}]
見積もりを生成する方法ができたので、アプリでこれをどのように使用できるかを考える必要があります。これを構築するには複数の方法があります。
2 番目のオプションの重要な利点は、モデルが読み込まれると、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
OK、これで背景画像と見積もりができました。つまり、受信者に送信される最終画像の組み立てに取り掛かることができます。大まかに言うと、画像にテキストを配置したいと考えていますが、この単純なタスクでさえ難しい場合があります。まず、私たちが答えなければならないいくつかの質問があります
これらの質問のいくつかに対する答えは、他の質問よりも複雑です。シンプルにするために、テキストを中央に配置し、見栄えを良くするために折り返しを行います。最後に、今のところ明るい色のテキストを使用します。すべての画像操作には、Python Image Library (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
という最終画像が生成されます。
最後から 2 番目のステップでは、Courier で使用できるように画像をアップロードする必要があります。今回は Firebase Storage を使用していますが、お好きなものを自由に使用してください。
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 を簡単に開始できることを示しました。
先に進み、このプロジェクトを改善したい場合は、いくつかの興味深いアイデアを試してみてください