Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

habemus progressus #1

Open
indirivacua opened this issue Apr 1, 2022 · 12 comments
Open

habemus progressus #1

indirivacua opened this issue Apr 1, 2022 · 12 comments

Comments

@indirivacua
Copy link
Member

Buenas! 👋 Acá vengo a dibujar una "weekly scrum meeting" (?

¿Qué hiciste en la semana?

Estuve repasando JavaScript y React, además de aprender TensorFlow.js, acá muestro en lo que estuve trabajando al respecto.

Aclaraciones:

  • Utilizo React para captar la referencia de la cámara y la actualización casi-constante del DOM.
  • El modelo usado para probar es MoveNet de los modelos ready-to-use de TensorFlow (tiene solo 17 keypoints para el cuerpo), fue probado en una PC sin GPU y con GPU, ambas dieron un buen rendimiento.

¿Que harás en la próxima semana?

Voy a tratar de tener algo hecho con AlphaPose y/u OpenPose.

¿Hay impedimentos en tu camino?

No tengo ni idea de como instalar y convertir el modelo o pesos de tales librerías a tf.js, pero ya me las rebuscaré.

@indirivacua
Copy link
Member Author

Buenas x2! 👋 Dejo un update de lo que laburé en la semana a modo de bitácora por si es relevante.

  • Combiné todos los proyectos por separado (mockup de la web y modelo de reconocimiento) para que sean uno solo.
  • Agregué el modelo pre-entrenado de TensorFlow.js para el reconocimiento de keypoints en la cara.
  • Hice la cuenta regresiva para cuando empieza.
  • Agregué la grabación periódica de 5 segundos + simulación de envío y respuesta con una Fake REST API.

Acá dejo un videito mostrando todo eso:

En la reunión del viernes que viene les cuento lo que haga falta, un saludo!

PD: @pedroodb tenías razón sobre lo que hablamos el martes de la cámara, se me había quedado recontra blucleada en un EventListener 🤦‍♂️

@facundoq
Copy link
Member

facundoq commented Apr 29, 2022 via email

@indirivacua
Copy link
Member Author

Viendo los resultados después de probar, ahora estoy confundido con mis dichos, ambos parecen ser... sin GPU? Parece depender siempre del procesador, a pesar de que utilizo WebGL como backend de gráficos (integrado ya con tf.js).

AMD Ryzen 5 5600G (iGPU)

alt text

AMD Ryzen 5 1600 + NVIDIA GeForce GTX 1060 6GB (dGPU)

alt text

Algo que si dudo que sea posible, es que la GPU esté a 0% siempre, ya que hasta mover un ícono la hacer subir a 25% (lo descubrí hace un rato al tener el taskmgr abierto 👀).

alt text

@indirivacua
Copy link
Member Author

No iba a poder dormir si no lo probaba: hice una app react (porque se me hizo imposible conectar paquetes npm con JavaScript vanilla, e importar este modelo de TensorFlow.js -BlazePose- con cdn daba error por alguna razón que busqué y nadie tenía la solución) y me puse a probar el runtime-backend de MediaPipe que usa WASM y está preparado para aceleración por GPU (en lugar de TensorFlow.js con WebGL).

Este si está usando posta GPU, queda en evidencia por el uso de la misma en comparación con la otra prueba, además lo noto que va bastante más fluido (no conté los FPS, pero diría que va entre 50 y 60).

alt text

@indirivacua
Copy link
Member Author

indirivacua commented May 2, 2022

El sábado me di maña para que se pueda utilizar el runtime de mediapipe con JS vanilla e importé todos los modelos directamente en la app, los FPS ahora van de 20-30 y está usando la GPU para el procesamiento de los 3 modelos (solo si el navegador permite aceleración por hardware, tengo que probar qué onda en la PC sin GPU dedicada, cuando lo haga edito este comentario).

Si tienen ganas de probar la "rapidez" que maneja este método, les dejo la prueba del viernes hecha en react hosteada acá (solo tiene incorporado el modelo de poses).

@pedroodb
Copy link
Collaborator

pedroodb commented May 2, 2022 via email

@facundoq
Copy link
Member

facundoq commented May 2, 2022 via email

@pedroodb
Copy link
Collaborator

pedroodb commented May 3, 2022 via email

@indirivacua
Copy link
Member Author

Buenas! Voy contestando todo:

@pedroodb

Buenas! Che, bárbaro todo, genial que ya estuviste chequeando lo de la aceleración por hardware y ya garantizando que usa la gpu. De cualquier manera vos hablas de los fps a los que se muestra la visualización después de dibujarle los puntos, no? Si no me equivoco no vamos a tener mucho problema con eso, si vos podés captar todos los frames y bufferearlos para ir dandoselos completos al modelo ya genial, aunque después usemos 15 fps nomás.

Sep, hablo de los FPS post-dibujado, algo que probé recién para mejorar la performance es ver si influía mucho el "dibujado" del frame/imágen que capta la cámara sobre el canvas, o era mejor hacerle unhide al video tag y con CSS superponer un canvas encima para el dibujado (ahorra el hacer algo manual que ya hace el navegador de por sí -no lo hice antes porque el CSS y mi cabeza no nos llevamos muy bien en general cuando se trata de los position: relative / absolute;-). Conclusión: el video se muestra siempre fluido para el usuario, los FPS corresponden ahora únicamente al captado de frames y dibujado en el canvas.

Con respecto al guardado de los frames, estos ahora mismo están siendo captados y buffereados en un array, esto se hace cada 5 segundos (obviamente como se hace cada ese tiempo, depende estríctamente de los FPS la cantidad de frames que se guardan en el mismo).

@facundoq

La visualización seguro siempre se puede mostrar a 30fps, el tema es que cuantos podemos procesar que es otra cosa; habría que chusmear el código a ver si el modelo se está corriendo en paralelo al main thread o si está bloqueando la captura/dibujo.

El procesamiento de un frame específico se hace en paralelo mediante la ejecución de las promesas de manera asíncrona, pero no está fuera del refresco de pantalla del main thread de JavaScript, o sea, no solo la cadena se rompe por el eslabón más debil (la inferencia más larga condiciona la demora de las demás -es la de las manos la más compleja-) sino que si tarda en estimar, tarda en mostrar, ende tarda en captar el siguiente frame.

Algo que pensé luego de buscar es utilizar los Web Workers de JavaScript, que serían como un estilo de pasaje de mensajes asincrónicos ya que utilizan memoria distribuida "por archivo .js".

@pedroodb @facundoq

Pd, vos con lo que estuviste probando de tensorflow ja podrías levantar cualquier modelo de tensorflow desde el navegador en teoría, no? Para saber si el próximo paso sería nomás convertir el modelo de pytorch a TF

No es tan simple porque algunos operadores no están disponibles en tf.js. Ponele, si querés usar una Strided Convolution quizás no esté..

Como dijo Facu, hay una complicación, primero de PyTorch hay que pasarlo a TensorFlow (o Keras), luego de ahí hay que pasarlo a TensorFlow.js, que no permite todas las capas que PyTorch tiene (las que permite están listadas acá).

@pedroodb

Buenas! Aprovecho para comentar, ahora que mencionabas del modelo Facu, yo ya implemente una primera versión del modelo que funciona con los keypoints y ahora lo estoy entrenando, y la idea era el viernes después de nuestra reunión con Óscar quedarnos entre Franco, Facu y un par de chicos más que están también en el grupo de investigación compartirles un poco como quedó el modelo y aprovechar para compartir ideas y después almorzamos por ahí. Si tenés ganas de sumarte Oscar estás más que invitado y también aprovechamos a pensar qué tan complejo va a ser mover el modelo a TF.

Excelente eso! Y me encataría sumarme, en un momento tengo que irme ya que tengo CADP (11:30 a 13:15), me avisan si eso implica una dificultad, 0 drama ;).

Un abrazo!

@facundoq
Copy link
Member

facundoq commented May 4, 2022 via email

@indirivacua
Copy link
Member Author

Guarda uno solo, si llega la captura antes que el procesamiento tiras el frame viejo y listo.

Para lograr eso hay que sí o sí separar la captura de la estimación, de manera que sean threads totalmente independientes, y que su comunicación no sea bloqueante (me parece a mi, lo estuve pensando y no se me ocurrió otra forma). Estuve probando cosas con los Web Workers, logré hacer unas pruebas (no dentro de la app) pero hay un par de temas a cosiderar que complican la situación, los comento mañana en la reunión.

Claro a eso me refería. Yo creo que el problema que resolviste con css se resuelve solo si usas algo en paralelo - no solamente un callback. Ojo quizás le estoy pifiando y el callback si se ejecuta en otro hilo/core ¿Que dice el monitor del sistema?

Sep, tenés razón, seguramente todo el tema de performance y demora se resuelva con algo en paralelo "real" (otra podría ser hacer algo server-side con Node.JS y que este se encargue del procesamiento de los frames, eso si sería paralelo pero con overhead en la comunicación, igual no descarto la posibilidad de probar esa opción).

El monitor de performance muestra esto:

O sea, usa solo el main thread para todo y por el asincronismo se van separando las tareas, no hay paralelismo real entre distintos cores.

Y es a las 11 pero si te queda de pasada de cadp venite un poco antes si querés!

Joya, me paso por ahí!

@facundoq
Copy link
Member

facundoq commented Oct 11, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants