midusi / lsapp

Argentinian Sign Language translation and learning application
https://midusi.github.io/lsapp/sign-language-app-src/templates/translate.html?debug=true
GNU Affero General Public License v3.0
2 stars 0 forks source link

habemus progressus #1

Open indirivacua opened 2 years ago

indirivacua commented 2 years ago

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.

IMAGE ALT TEXT HERE

Aclaraciones:

¿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 commented 2 years ago

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

Acá dejo un videito mostrando todo eso:

IMAGE ALT TEXT HERE

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 commented 2 years ago

Genial! Pregunta esos fps son con o sin gpu? Cuando probas sin gpu, verificas que el uso sea 0% desde el monitor del sistema? Mira que al ser del browser no tiene nada que ver con cuda por ejemplo

El vie., 29 abr. 2022 08:16, Oscar Stanchi @.***> escribió:

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 https://jsonplaceholder.typicode.com/ .

Acá dejo un videito mostrando todo eso: [image: IMAGE ALT TEXT HERE] https://www.youtube.com/watch?v=tVo2_CtCJs0

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

PD: @pedroodb https://github.com/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 🤦‍♂️

— Reply to this email directly, view it on GitHub https://github.com/midusi/sign-language-app/issues/1#issuecomment-1113186962, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMA6BZQY4FVBSTAXY5RI63VHPAJZANCNFSM5SIZCFJA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

indirivacua commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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

IMAGE ALT TEXT HERE

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 commented 2 years ago

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.

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

Saludos!

El lun., 2 de mayo de 2022 08:57, Oscar Stanchi @.***> escribió:

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 https://i.imgur.com/r6LKvuH.png, tengo que probar qué onda en la PC sin GPU dedica, cuando lo haga edito este comentario). [image: IMAGE ALT TEXT HERE] https://www.youtube.com/watch?v=p5_bnpnUmkk

Si tienen ganas de probar la "rapidez" que maneja este método, le dejo la prueba del viernes hecha en react hosteada acá https://indirivacua.github.io/pose-mediapipe/ (solo tiene incorporado el modelo de poses).

— Reply to this email directly, view it on GitHub https://github.com/midusi/sign-language-app/issues/1#issuecomment-1114765261, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAYTS7GLBJCYUGGNJMNIPDVH67KJANCNFSM5SIZCFJA . You are receiving this because you were mentioned.Message ID: @.***>

facundoq commented 2 years ago

On Mon, May 2, 2022 at 6:52 PM Pedro Dal Bianco @.***> wrote:

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.

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.

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é..

Saludos!

El lun., 2 de mayo de 2022 08:57, Oscar Stanchi @.***> escribió:

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 https://i.imgur.com/r6LKvuH.png, tengo que probar qué onda en la PC sin GPU dedica, cuando lo haga edito este comentario). [image: IMAGE ALT TEXT HERE] < https://www.youtube.com/watch?v=p5_bnpnUmkk>

Si tienen ganas de probar la "rapidez" que maneja este método, le dejo la prueba del viernes hecha en react hosteada acá https://indirivacua.github.io/pose-mediapipe/ (solo tiene incorporado el modelo de poses).

— Reply to this email directly, view it on GitHub < https://github.com/midusi/sign-language-app/issues/1#issuecomment-1114765261 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/AHAYTS7GLBJCYUGGNJMNIPDVH67KJANCNFSM5SIZCFJA

. You are receiving this because you were mentioned.Message ID: @.***>

— Reply to this email directly, view it on GitHub https://github.com/midusi/sign-language-app/issues/1#issuecomment-1115407473, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMA6B57OWYGBROZ44FQ4Q3VIBFDLANCNFSM5SIZCFJA . You are receiving this because you commented.Message ID: @.***>

pedroodb commented 2 years ago

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.

Abrazo!

El lun., 2 de mayo de 2022 19:02, Facundo Quiroga @.***> escribió:

On Mon, May 2, 2022 at 6:52 PM Pedro Dal Bianco @.***> wrote:

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.

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.

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é..

Saludos!

El lun., 2 de mayo de 2022 08:57, Oscar Stanchi @.***> escribió:

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 https://i.imgur.com/r6LKvuH.png, tengo que probar qué onda en la PC sin GPU dedica, cuando lo haga edito este comentario). [image: IMAGE ALT TEXT HERE] < https://www.youtube.com/watch?v=p5_bnpnUmkk>

Si tienen ganas de probar la "rapidez" que maneja este método, le dejo la prueba del viernes hecha en react hosteada acá https://indirivacua.github.io/pose-mediapipe/ (solo tiene incorporado el modelo de poses).

— Reply to this email directly, view it on GitHub <

https://github.com/midusi/sign-language-app/issues/1#issuecomment-1114765261

, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/AHAYTS7GLBJCYUGGNJMNIPDVH67KJANCNFSM5SIZCFJA

. You are receiving this because you were mentioned.Message ID: @.***>

— Reply to this email directly, view it on GitHub < https://github.com/midusi/sign-language-app/issues/1#issuecomment-1115407473 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/AAMA6B57OWYGBROZ44FQ4Q3VIBFDLANCNFSM5SIZCFJA

. You are receiving this because you commented.Message ID: @.***>

— Reply to this email directly, view it on GitHub https://github.com/midusi/sign-language-app/issues/1#issuecomment-1115413816, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAYTSZSFDS47LC7Q4KLIBDVIBGGZANCNFSM5SIZCFJA . You are receiving this because you were mentioned.Message ID: @.***>

indirivacua commented 2 years ago

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 commented 2 years ago

El mar., 3 may. 2022 16:50, Oscar Stanchi @.***> escribió:

Buenas! Voy contestando todo:

@pedroodb https://github.com/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.

Genial!

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

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

@facundoq https://github.com/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".

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?

@pedroodb https://github.com/pedroodb @facundoq https://github.com/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á https://js.tensorflow.org/api/latest/#Layers).

@pedroodb https://github.com/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 ;).

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

Un abrazo!

— Reply to this email directly, view it on GitHub https://github.com/midusi/sign-language-app/issues/1#issuecomment-1116500815, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMA6B4IJETB5ELME2TEKQDVIF7P5ANCNFSM5SIZCFJA . You are receiving this because you were mentioned.Message ID: @.***>

indirivacua commented 2 years ago

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 commented 2 years ago

Dale, igual si hacemos captura primero y luego reconocimiento no hay drama con esto.

Dejo para un futuro cuando hagamos tiempo real: un webworker no puede usar el canvas, asi que no podría usar la gpu para tensorflow.js, con lo cual es como un tradeoff medio extraño poder tener paralelismo pero no la gpu. Habría que medir que es mejor, quizás por ahora no complicarse entonces con webworkers y tratar de mejorar la ejecución con un solo core.

El jue., 5 may. 2022 22:50, Oscar Stanchi @.***> escribió:

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:

https://camo.githubusercontent.com/91fbe81c7ea29ed3fe91a4efaa8285b510a24825ad1494555870272b045fe061/68747470733a2f2f692e696d6775722e636f6d2f6a4d38363268302e6a7067

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í!

— Reply to this email directly, view it on GitHub https://github.com/midusi/sign-language-app/issues/1#issuecomment-1119191261, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMA6B6JS4ILRIDQLQ7EMOLVIR3HLANCNFSM5SIZCFJA . You are receiving this because you were mentioned.Message ID: @.***>