paint-brush
Uso de Courier y GPT2 para generar una cita motivacional del díapor@courier
559 lecturas
559 lecturas

Uso de Courier y GPT2 para generar una cita motivacional del día

por Courier8m2023/02/13
Read on Terminal Reader

Demasiado Largo; Para Leer

Las citas motivacionales estaban de moda en los días en que MMS y el reenvío de correo electrónico eran populares. En lugar de codificar una lista de citas motivacionales, vamos a utilizar un modelo de aprendizaje automático para generar una cita a pedido. Usaremos la biblioteca Hugging Face para cargar y servir el modelo ML que generará las cotizaciones para nosotros.
featured image - Uso de Courier y GPT2 para generar una cita motivacional del día
Courier HackerNoon profile picture
0-item


Las citas motivacionales estaban de moda en los días en que MMS y el reenvío de correo electrónico eran populares. Recuerdo que mis padres me reenviaban al comienzo de cada mañana. Avance rápido hasta hoy, si tiene suerte, es parte de algún grupo de reenvío en la aplicación de mensajería de su elección (Whatsapp, Telegram, etc.).


Inspirándonos en la misma idea, hoy vamos a crear un servicio que envía a nuestros amigos y familiares una cita motivacional del día generada por IA. En lugar de codificar una lista de citas motivacionales, vamos a utilizar un modelo de aprendizaje automático para generar una cita a pedido para que nunca nos quedemos sin citas para compartir.

Instrucciones

Parte 1: Uso de IA para generar citas motivacionales

OpenGPT2 y modelos de lenguaje

El modelo OpenAI GPT-2 fue propuesto en Language Models are Unsupervised Multitask Learners por Alec Radford, Jeffrey Wu, Rewon Child, David Luan, Dario Amodei e Ilya Sutskever. Es un transformador causal entrenado previamente usando modelado de lenguaje en un corpus muy grande de ~40 GB de datos de texto.

Para simplificar esto, en un nivel alto OpenAI GPT2 es un modelo de lenguaje grande que ha sido entrenado en cantidades masivas de datos. Este modelo se puede utilizar para predecir el siguiente token en una secuencia determinada.

Si eso suena demasiado complicado, no se preocupe, no necesita saber nada de aprendizaje automático o inteligencia artificial para seguir este proyecto. bibliotecas como cara de abrazo hacer que usar este modelo en nuestra aplicación sea muy fácil.

cara de abrazo

Usaremos el cara de abrazo biblioteca para cargar y servir el modelo ML que generará las cotizaciones para nosotros. Hugging Face hace que sea muy fácil usar modelos de transformadores (de los cuales GPT2 es un tipo) en nuestros proyectos sin ningún conocimiento de ML o AI. Como se mencionó anteriormente, GPT2 es un modelo de lenguaje de propósito general, lo que significa que es bueno para predecir texto genérico dada una secuencia de entrada. En nuestro caso, necesitamos un modelo más adecuado para generar cotizaciones. Para ello, tenemos dos opciones:

  1. Podemos ajustar el modelo GPT2 usando nuestro propio texto para el cual necesitaremos un buen conjunto de datos de citas.
  2. O podemos encontrar un modelo ya existente que ha sido ajustado con algunas cotizaciones.

Afortunadamente, en nuestro caso hay un modelo ajustado que ha sido entrenado en el conjunto de datos de cotizaciones de 500k: https://huggingface.co/nandinib1999/quote-generator

Con Hugging Face, usar este modelo es tan fácil como crear un tokenizador


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


luego construir un modelo a partir del modelo pre-entrenado


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


y finalmente, construir el generador que podemos usar para generar la cotización

 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'}]

Construyendo una API para servir el modelo

Ahora que tenemos una forma de generar cotizaciones para nosotros, tenemos que pensar en cómo podemos usar esto en nuestra aplicación. Hay varias formas de construir esto.

  1. Cargar el modelo cada vez que queramos ejecutar el script para enviar el script.
  2. Cree una API o servicio que sirva este modelo GPT2 para generarnos cotizaciones bajo demanda.

Una ventaja clave de la segunda opción es que una vez que se carga el modelo, la API puede respondernos rápidamente y también se puede usar en otras aplicaciones. FWIW, la primera opción también es un enfoque totalmente válido.

Podemos usar __ Fast API __ para crear una API de servicio rápido. Esto es lo que parece

 # 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"])


Vamos a probarlo


 $ 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)


Ahora podemos comenzar a enviar solicitudes al punto final /generate que generará una cotización para nosotros.

Parte 2: Construyendo el Generador de Cotizaciones

Ahora que tenemos una forma de generar cotizaciones a pedido, podemos detenernos aquí y comenzar a trabajar en enviar esto a través de mensajero . Pero a quién engañamos, ¡ya nadie lee el texto! Podemos hacer que esto sea interesante usando una buena imagen y colocando nuestra cita en ella para que parezca un póster.

Generar cotización

Dada nuestra API, ahora podemos hacer lo siguiente para generar una cotización

 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"]

Descargando la imagen de fondo

El primer desafío es obtener una hermosa imagen de fondo para nuestra cotización. Para eso, usaremos la API de Unsplash que proporciona un buen punto final para devolver una imagen aleatoria que coincida con una consulta. Apertura https://source.unsplash.com/random/800×800/?naturaleza en nuestro navegador devuelve una bonita imagen de la naturaleza.

Para mantener las cosas interesantes, podemos usar diferentes términos de consulta, como estrellas, etc. Así es como se ve el código para descargar nuestra imagen de fondo:

 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

Creando la imagen con la cita

Bien, ahora tenemos nuestra imagen de fondo y un presupuesto, lo que significa que podemos trabajar en el ensamblaje de la imagen final que se enviará a los destinatarios. En un nivel alto, queremos colocar texto en una imagen, pero incluso esta tarea simple puede ser un desafío. Para empezar, hay una serie de preguntas que debemos responder.

  1. ¿Cómo se colocará el texto en la imagen?
  2. ¿Qué hay de envolver el texto?
  3. ¿De qué color debe ser el texto para que sea visible en la imagen de fondo?
  4. ¿Cómo hacemos esto para imágenes con diferentes anchos y altos?

Las respuestas a algunas de estas preguntas son más complicadas que otras. Para mantenerlo simple, colocaremos el texto en el centro y lo envolveremos para que se vea bien. Finalmente, usaremos un texto de color claro por ahora. Para toda la manipulación de imágenes, usaremos la Biblioteca de imágenes de Python (PIL) para que nos resulte más fácil.

 # 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


Esto genera la imagen final llamada result.jpg

Subiendo la imagen

Para el penúltimo paso, necesitamos cargar la imagen para poder usarla con Courier. En este caso, estoy usando Firebase Storage, pero puedes usar lo que quieras.


 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


Paso 3: Integración con Courier

Finalmente, tenemos todo lo que necesitamos para comenzar a enviar nuestras increíbles frases a nuestros amigos y familiares. Podemos usar Courier para crear una plantilla de correo electrónico atractiva.

Comience por crear una cuenta.

Crear la plantilla en Courier

enviando el mensaje

Enviar un mensaje con Courier es tan fácil como parece. Si bien Courier tiene sus propios SDK que pueden facilitar la integración, prefiero usar su extremo de API para simplificar las cosas. Con mi AUTH_TOKEN y TEMPLATE_ID en la mano, podemos usar el siguiente código para enviar nuestra imagen


 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)


La clave API se puede encontrar en Ajustes y el ID de la plantilla se puede encontrar en el diseño de plantilla ajustes. ¡Y eso es!

Conclusiones

Este tutorial demostró lo fácil que es comenzar con el aprendizaje automático y Courier.

Si quieres seguir adelante y mejorar este proyecto, aquí hay algunas ideas interesantes para probar

  • Mejor imagen de fondo: ¿Usar un término de la cita generada para buscar una imagen?
  • Mejor color de fondo para el texto: Use mejores colores para el texto. Una buena idea es usar el color complementario del color principal de la imagen. Puede usar el agrupamiento k-means para averiguarlo.
  • Agregar más canales: ¡Extiende esto a mensajes en clientes de mensajería y sms!

Sobre el Autor

prakhar es ingeniero de software sénior en Google, donde trabaja en la creación de herramientas para desarrolladores. Es un apasionado desarrollador de código abierto y le encanta tocar la guitarra en su tiempo libre.

enlaces rápidos

🔗 Documentos de mensajería

🔗 cara de abrazo

🔗 API rápida

🔗 API de visualización