- Introducción
- Pre requisitos
- Instrucciones para desplegar la Aplicación
- Uso del chatbot con IA generativa
- Cómo funciona el despliegue
- Costo Estimado
- Conclusiones y siguientes pasos
En el blog anterior, aprendiste cómo construir un agente conversacional utilizando modelos de IA generativa de forma local. En este blog continuaremos con el proyecto para llevarlo al siguiente nivel, desplegar la aplicación como un sitio web con autenticación.
Aprenderemos cómo empaquetar nuestra aplicación en un contenedor Docker y desplegarlo en AWS utilizando servicios como en Elastic Container Service (ECS). Esto permitirá acceder de forma segura al asistente desde cualquier lugar o dispositivos.
También integraremos autenticación de usuarios utilizando Amazon Cognito permitir el acceso sólo a usuarios autenticados.
Al final de este blog, tendrás un asistente conversacional con IA generativa listo que pueda ser accedido por múltiples usuarios simultáneamente desde cualquier dispositivo a través de una interfaz web.
A construir!
Antes de comenzar, asegúrate de tener instalado lo siguiente:
-
CDK (AWS Cloud Development Kit) nos permitirá definir y desplegar la infraestructura de nuestra aplicación de forma declarativa mediante código. Sigue estas instrucciones para instalarlo.
-
Cuenta AWS y usuario con permisos: Necesitarás una cuenta AWS y un usuario con los permisos necesarios para crear recursos en servicios como CloudFormation, Secrets Manager, IAM, S3, ECR, etc. Puedes crear un usuario con acceso de administrador temporalmente.
-
opcional cdk boostrap: Si este es tu primer proyecto cdk en tu cuenta/region de aws. Deberás ejecutar el comando antes de desplegar el proyecto 👇
cdk bootstrap aws://{your_aws_account}/{region}
Clona este repositorio (si es que no lo has hecho)
git clone https://github.com/ensamblador/generative-ai-chat-application.git
y accede a la carpeta:
cd generative-ai-chat-application/02-personal-assistant-ecs
python3 -m venv .venv
source .venv/bin/activate
Instala las dependencias del proyecto:
pip install -r requirements.txt
Ejecuta cdk deploy
para crear automáticamente los siguientes recursos:
- Un pool de usuarios de Amazon Cognito.
- Repositorio en Amazon Elastic Container Registry (ECR) para almacenar la imagen del contenedor.
- Proyecto enAWS Code Build para construir y guardar la imagen del contenedor en ECR
- Un pipeline en AWS Code Pipeline que toma un zip en S3, y una acción build que dispara el proyecto de Code Build.
- Un cluster de Amazon Elastic Container Service (ECS) donde se desplegarán los servicio. Además de una nueva VPC.
- Un Servicio ECS y un balanceador de carga.
- Roles y Permisos necesarios para cada etapa.
luego de unos 6 minutos verás la salida del despliegue terminado:
✅ PERSONAL-ASSISTANT-ECS
✨ Deployment time: 386.75s
Outputs:
PERSONAL-ASSISTANT-ECS.LappLoadBalancer = PERSON-XXXX.us-east-1.elb.amazonaws.com
PERSONAL-ASSISTANT-ECS.LappServiceURL = http://PERSON-XXXX.us-east-1.elb.amazonaws.com
PERSONAL-ASSISTANT-ECS.UsersAPPCLIENTID = XXXXX
PERSONAL-ASSISTANT-ECS.UsersAPPCLIENTSECRET = XXXXX
PERSONAL-ASSISTANT-ECS.UsersPOOLID = region_XXXX
PERSONAL-ASSISTANT-ECS.Userscognitoconsole = https://region.console.aws.amazon.com/cognito/v2/idp/user-pools/POOLID/users?region=region
Ingresa a link de los outputs Userscognitoconsole
, que te lleva a la consola de amazon cognito y crea un usuario nuevo (correo/password). Asegura de hacer check en marcar este correo electronico como verificado
El link de tu aplicación también está en los outputs LappServiceURL
(http://PERSON-XXXX.us-east-1.elb.amazonaws.com) solo navega ahi y cambia la contraseña:
Nota: Si no sabes donde están estos outputs (url del servicio). Puedes obtenerlos del stack de cloudformation -> Outputs.
En este caso no veremos en detalle en cómo funciona el chatbot en términos de IA Generativa, si quieres profundizar te dejo esta explicación acá. Ahora nos interesa entender como funciona el despliegue usando servicios de AWS.
Partamos de lo más básico, el contenedor.
Este Dockerfile tiene las instrucciones para armar el contenedor de la aplicación (utilizando docker). Aquí está una explicación de los comandos:
FROM public.ecr.aws/docker/library/python:3.9-slim
Establece la imagen base como la imagen oficial de Python 3.9 en Amazon ECR Public Gallery
WORKDIR /app
Establece el directorio de trabajo dentro del contenedor en /app.
ADD . /app
Copia los archivos y directorios del directorio actual en la máquina host al directorio /app dentro del contenedor.
RUN pip3 install -r requirements.txt
Instala las dependencias
EXPOSE 8501
El puerto de escucha es el 8501
ENTRYPOINT ["streamlit", "run", "chatbot_app.py", "--server.port=8501"]
Esto se ejecuta cuando el contenedor se lanza.
Es posible contruir la imagen en nuestro laptop. Necesitamos docker instalado y muchos recursos. Para no depender de los recursos locales vamos a usar un pipeline de construcción y publicación de la imagen.
flowchart LR
subgraph Source Stage
a1("S3 \nsource")
end
subgraph Build Stage
a1-- new asset -->b2("docker build")
end
subgraph Elastic Container Registry
b2-- push -->ECR("container image")
end
Detalle:
- Source S3 es una acción que se gatilla cuando aparece una nueva versión del archivo en una ubicación de s3 (ejemplo s3://path/to/file/asset.zip)
- Build Stage es un proyecto de AWS Code Build, que se inicia activado por Source Stage. Las instrucciones de ese proyecto Code Build están definidas en buildspec.yml. Principalmente
docker build
ydocker push
. La imagen de contenedor se almacena en Amazon ECR.
Una vez está la imagen publicada en ECR, se despliega en Amazon Elastic Container Service (ECS) con tecnología Fargate, de esta forma no tenemos que ocuparnos de desplegar y administrar servidores.
Adicional el servicio ECS, desplegaste un balanceador de carga que enruta las peticiones de los usuarios a las tareas del servicio que corren en el cluster ECS.
flowchart LR
subgraph ECS Cluster
subgraph ECS Service
RCI("Running container")
end
end
subgraph Elastic Container Registry
RCI("running container") <--pull-->CI("container image")
end
flowchart TB
Usuario("Usuarios \n👩🏻💻👨🏻💻") --http-->LoadBalancer
LoadBalancer("Balanceador de Carga ") -->RCI
subgraph Amazon ECS Cluster
subgraph ECS Service
RCI("Running container")
end
end
subgraph Amzon Cognito
UserPool("User Pool") -.auth.-RCI
end
Como sabemos, usamos Amazon Cognito como proveedor de identidades (usuario y contraseña). Pero como sabe la aplicación chatbot_app.py eso? Hicimos un pequeño cambio respecto al proyecto pasado:
#importamos esta nueva librería
from streamlit_cognito_auth import CognitoAuthenticator
#Variables de entorno tienen los datos
pool_id = os.environ.get("POOL_ID")
app_client_id = os.environ.get("APP_CLIENT_ID")
app_client_secret = os.environ.get("APP_CLIENT_SECRET")
#Esta clase nos permite interactuar con cognito,
# presenta la UI y hace las llamadas de API
authenticator = CognitoAuthenticator(
pool_id=pool_id,
app_client_secret=app_client_secret,
app_client_id=app_client_id,
)
is_logged_in = authenticator.login()
En el proyecto cdk, le pasamos al contenedor estas variables de entorno (POOL_ID
,APP_CLIENT_ID
, APP_CLIENT_SECRET
) luego de crear los recursos de cognito:
personal_assistant_ecs_stack.py
def create_user_pool(self):
self.users = UserPool(self, "Users")
self.task_environment = {
"POOL_ID": self.users.pool_id,
"APP_CLIENT_ID": self.users.app_client_id,
"APP_CLIENT_SECRET": self.users.app_client_secret
}
De esta forma el contenedor puede acceder a ellas en tiempo de ejecución.
Adicional a los costos de LLM indicados en el proyecto anterior debemos agregar los servicios e infraestructura de nube:
-
Balanceador de Carga (pricing):
0,0225 + 0,008 USD x hora. Aproximadamente 22 USD x Mes
Nota Si aún estás en el free tier de 12 meses: 0 USD x Mes
(esta cantidad soporta hasta 3000 conexiones activas por minuto)
-
Servicio Fargate (ARM):
0,50 CPU virtuales x 720 horas x 0,03238 USD por hora = 11,66 USD por las horas de vCPU 1,00 GB x 720 horas x 0,00356 USD por GB por hora = 2,56 USD por las horas de GB Aproximadamente 15 USD x Mes
Para saber cuantas tareas necesitamos ejecutar en paralelo para soportar la demanda de usuarios, te sugiero probar un test de carga. Este valor viene dado más por los recursos de la app (CPU, RAM) necesarios para cada usuario.
- Amazon Cognito: Free Tier, siempre que estés bajo los 50.000 Usuarios activos mensuales.
- Otros costos pequeños: ECR, Code build, Code Pipeline.
En este caso si deseas destruir los recursos para no incurrir en gastos puedes ejecutar
cdk destroy
(o ir a la consola de cloudformation y eliminar el stack)
En esta oportunidad aprendiste a empaquetar una aplicación Python en un contenedor Docker para facilitar su despliegue. Entre otras cosas:
- Utilizamos servicios de AWS como CodeBuild y CodePipeline para automatizar la construcción y publicación de la imagen de contenedor en ECR.
- Desplegamos el contenedor en ECS Fargate para ejecutarlo de forma escalable y serverless.
- Integramos autenticación de usuarios con Amazon Cognito para permitir el acceso solo a usuarios registrados.
Algunas ideas como siguientes pasos:
- Agregar el CI / CD. Permitir la integración y despliegue continuo de nuevas versiones.
- Permitir que los usuarios subir sus propios datos para personalizar las respuestas.
- Agregar https listener al balanceador usando un certificado.
Stay tuned!