Transcripción de lenguaje de signos (a nivel de palabra) mediante Deep Learning |
Hecho con fastapi como alternativa a un backend hecho con JavaScript usando onnx.js Esto se debe a que onnx.js no es tan fiable y su ecosistema no estan rico como el de Python.
El cliente enviará un video y el servidor lo procesará y devolverá el signo clasificado de vuelta.
Alojado en Google Cloud (contenedor Docker) con integración continua y disponible en api.sign2text.com
- Creamos un entonro virtual de Python con
virtualenv venv
opython -m venv ./venv
- Instalamos los requisitos con
pip install -r requirements,txt
Entramos en la carpeta src: cd src
Para desarrollo
uvicorn main:app --reload --port 8000
or python dev.py
Para producción
uvicorn main:app --port 8000
- Construye la imagen con
docker build -t sign2text .
- Ejecútalo:
docker run -p 8000:8000 sign2text
- Accede desde el navegador en
http://localhost:8000
Si quieres usar o descargar una imagen ya construida, puedes desde esta url: https://hub.docker.com/r/gazquez/sign2text
Tambiñen puedes descargarla usando el CLI con docker pull gazquez/sign2text
- Inicie sesión:
docker login sign2textapi.azurecr.io
(Ver claves en Sign2TextAPI > Azure Container Registry > Claves de Acceso) - Añadir la etiqueta al registro:
docker tag sign2text:latest sign2textapi.azurecr.io/latest
- Empuje la imagen al registro:
docker push sign2textapi.azurecr.io/latest
.
docker pull sign2textapi.azurecr.io/sign2text
- Instalamos el CLI de AWS:
pip install awscli
- Configuramos el CLI:
aws configure
- Nos logueamos en el ECR (elastic container registry):
aws ecr get-login --region eu-west-3
- Ejecutamos login con Docker según la salida del comando anterior:
docker login -u AWS -p <PASSWORD> https://<ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com
- Creamos un repositorio:
aws ecr create-repository --repository-name sign2text
- Añadimos la etiquta al repositorio:
docker tag sign2text:latest <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/sign2text
- Verificamos que el tag existe:
docker images
- Hacemos push de la imagen al registro:
docker push <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/sign2text
- (Opcional) Si queremos eliminar la imagen del registro:
aws ecr batch-delete-image --repository-name sign2text --image-ids imageTag=latest
- (Opcional) Si queremos eliminar el repositorio:
aws ecr delete-repository --repository-name sign2text
- Crear un servicio EC2 en la plataforma.
- Conéctate a él con ssh usando el par de claves dadas con:
ssh -i "credenciales.pem" ec2-usuario@<INSTANCIA>.<REGIÓN>.compute.amazonaws.com
. - Cuando esté conectado, ejecute los siguientes comandos:
- Actualice la lista de paquetes:
sudo yum update -y
- Instalar Docker:
sudo amazon-linux-extras install docker
. - Inicie el docker con
sudo service docker start
. - Añade el usuario ec2 al grupo docker para poder ejecutar los #comandos Docker sin usar sudo.
sudo usermod -a -G docker ec2-user
- Actualice la lista de paquetes:
- Reinicaimos la instancia de EC2 desde la plataforma y nos conectamos de nuevo.
- Al igual que en el punto anterior, subimos la imagen al ECR (Elastic Container Registry) (tag + push)
- Una vez tenemos el registro y el EC2, nos conectamos a este último de nuevo para ejecutar la imagen.
- Una vez conectados iniciamos aws:
aws configure
- Inicia el daemon de docker (ver 3.3) y añade tus credenciales (Punto anterior 3 y 4).
- Copia la URI de la imagen de docker subida al ECR y ejecuta en la instancia:
docker pull <URI>
- Una vez hehco esto, ejecutamos el docker como lo haríamos de forma local:
docker run -dp 80:8000 <NAME_OF_IMAGE>
- Podemos ver las imagenes con
docker images
- Importante usar
80:8000
para mapear los puertos de la instancia a los puertos de la imagen. - Comprobar que la imagen está corriendo con
docker ps
- Podemos ver las imagenes con
- Añadimos regla de entrada para aceptar tráfico.
- En la instancia > Seguridad > Grupos de Seguridad > Editar reglas de entrada
- Agregamos una regla con tipo "Todo el tráfico" y 0.0.0.0/0 o arreglamos regla de Https y Http Para 0.0.0.0 y ::0.
- La aplicación ya es accesible públicamente.
-
Crea una aplicación de EB desde el dashboard de AWS.
-
Elige la opción de Docker + subir código.
-
Sube un archivo Docker.aws.json
- Por ejemplo:
{ "AWSEBDockerrunVersion": "1", "Image": { "Name": "<IMAGE_URI>", "Update": "true" }, "Ports": [ { "ContainerPort": "8000" } ] }
-
La imagen puede ser de ECR, Dockerhub o cualqueir otro lado.
-
Espera que la aplicación se despligue y accede al link proporcionado.
- Vamos a "asignar dirección ip estática"
- Seguimos las instrucciones de Amazon hasta que nos otorgue una IP que no cambia cada vez que levantamos la instancia.
- Con esta IP elástica podemos ahora añadir un registro A desde nuestro subdominio a la dirección elástica o usar Route 53.
- Vamos a Route 53 en Amazon y conectamos con un registro A la dirección IP con el dominio que queremos.
- En nuestro gestor de DNS añadimos los nameservers de Amazon.
- Ya esta listo nuestro dominio con htttp. El único problema es que no es seguro (no es https).
- Creamos un load balancer con un listener en el puerto 80 y un listener en el puerto 443.
- El puerto 80 es el que se usa para el acceso a la aplicación.
- El puerto 443 se leasignarña un certificado SSL.
- Importante añadir la política de seguridad de grupo de la instancia en el load balancer.
- Cuando se consgiga hacer el health check, nuestra app estará disponible en la dns del load balancer.
- (Opcional) Ahora podemos eliminar la ip elástica de la instancia si así lo queremos.
- (Opcional) Con la dns pública con HTTPS, podemos generar un registro A o CNAME para nuestro subdominio y así obtene runa url más simple.
- Para esto usamos Route 53, añadimos un registro A de alias y le damos el nombre de nuestro subdominio.
- Importante hacer primero los pasos del apartado anterior.
- Finalmente para redirigir el load balancer de http a https debemos añadir un listener con un redirect 301 al litener con https.
- Este listener de 443 (https) será el que nos redirecciona al grupo que tiene la instancia con el puerto 80.
- Para que esto funcione AWS hará un health check (un ping) al puerto de la instancia.
- Una vez tengamos los listener creados podemos acceder al dominio del load balancer con http y nos redirigirá a https.
- Add a tag to your local image like this:
docker tag <IMAGE_NAME> <HOSTNAME>/<PROJECT_ID>/<IMAGE_NAME>
- Hostname can be one of the following:
gcr.io
us.gcr.io
eu.gcr.io
asia.gcr.io
- En mi caso hago:
docker tag gazquez/sign2text gcr.io/sign2text-354412/sign2text
- Hostname can be one of the following:
- Hacemos un push de la imagen a Google Cloud.
docker push gcr.io/sign2text/sign2text
- Esto generará una imagen en Google Cloud con el tag que le hemos añadido.
- Info: Si nos dice que no tenemos acceso al registry: seguimos esta guía paa obtener acceso.
- En mi caso uso Google Cloud CLI con el siguiente comando:
gcloud auth login
- Tras esto configuramos docker con
gcloud auth configure-docker
- En mi caso uso Google Cloud CLI con el siguiente comando:
- Una vez hecho eso ya tenemos al imagen subida al registro y podemos crear un Cloud Run para ejecutar la imagen.
net localgroup docker-users "%username%" /add
- Elegimos la imagen creada en el punto anterior.
- Elegimos el puerto del contenedor. En mi caso es 8000.
- Esperamos a que se despliegue.
- Una vez hecho esto se nos dará una url con el contenedor desplegado.
- Esta url tendrá el certificado SSL de forma directa, salvándonos muchísimo tiempo.
- En mi caso la URL es: https://sign2text-lk67e2zqjq-no.a.run.app/
- (Opcional): Si queremos tener un dominio personalizado podemos consultar la siguiente guia.
- Pero básicamente consiste en verificar nuestro dominio o subdomnio con DNS (registro TXT y CNAME) y listos.
- Tras esto podemos elegir el subdomnio que queremos.
- Tardará un rato en reflejar los cambios de DNS pero ya estará disponible.
- Google nos asigna el certificado automáticamene.
- Ya podemos acceder a nuestra api sin que la aplicación del cliente tenga que hacer ninguna configuración.
- En el anexo de costes haremos un estudio de costes de nuestra aplicación.
- Habilitamos la API de Cloud Build.
- Elegimos el repositorio en que el se configurará la escucha para hacer rebuild de la imagen de docker.
- ¡Ya está!. Ahora Google hará rebuild de la imagen en el registro y redeploy de cloud run para actualizar los cambios.
- (Opcional): Si queremos tener más control sobre cuantá sveces se crea la imagen (ya que consume mucho tiempo y recursos), podemos cambiar de deploy según commit a deploy manual en el dashboard de la API de Cloud Build.
- En mi caso tengo esta opción marcada. De esta manera solo se hace redeploy del servidor (código, modelos y dependencias) de forma manual.
Esta imagen de FastAPI está alojada en Google Cloud con mapeo de dominios mediante docker y está disponible en el siguiente enlace: https://api.sign2text.com/docs
Debido a que es una aplicación de prueba, los recursos del servidor asignados son pocos (4GB de RAM con 2CPUs), por lo que peticiones simultáneas hacen que el contenedor caiga, y tengamos que volver a arrancarlo constantemente. Esto se soluciona con un autoscaling, aunque aumenta el coste sustancialmente.