Pipelines para inferencias performativas con Hugging Face 🤗

Domina la PNL con Cara Abrazadora

Tenga mucho cuidado con el uso de la memoria

Alex Litvinov
cultura friki
2 juguetes transformadores
Foto de Jeffery Ho en Unsplash

¡A todos nos encantan los transformadores! En los últimos años, revolucionaron por completo el procesamiento del lenguaje natural al permitir una comprensión y generación de lenguaje más precisa y eficiente en comparación con los métodos utilizados anteriormente y comenzaron a hacer lo mismo con el procesamiento de imágenes y audio. Y Hugging Face, a su vez, ha hecho que los modelos basados ​​en transformadores sean más accesibles y fáciles de usar para investigadores y desarrolladores. Es tan fácil como ir a la página de la tarjeta del modelo y copiar el código repetitivo que se proporciona allí. O es eso…?

Muchos modelos tienen algún código de muestra para inferencia en su página. Copiar y pegar está bien cuando solo quieres probarlo en un par de muestras. Pero si desea hacer inferencias sobre una cantidad decente de datos, lo más probable es que este enfoque no funcione y seguramente no será el más eficiente. En realidad, según el modelo, una cantidad decente podría ser igual a tan solo 100 muestras para hacer que la inferencia sea imposible.

Si desea usar un modelo de transformador Hugging Face para inferir en más de unos pocos ejemplos, debe usar pipeline. Y a continuación veremos cómo aplicar esta sugerencia en la práctica.

El plan para hoy es el siguiente:

  1. Tome un modelo de Hugging Face y use el código de inferencia provisto en la tarjeta del modelo.
  2. Ejecutarlo en un cuaderno de Colab, perfilar el uso de la memoria y el tiempo que toma la inferencia
  3. Repita usando una muestra más grande (¡Alerta de spoiler!) y Falle.
  4. Actualice el código original para usar pipeline y ser testigo de una mejora significativa.

Usaremos el modelo de verificación de hechos climáticos para nuestros experimentos. Estoy usando este ejemplo en relación con el tema de un proyecto de PNL en el que participé recientemente, pero lo más importante es que el principio es aplicable a cualquier modelo de Hugging Face.
El modelo toma como entrada dos oraciones relacionadas con el clima, una de las cuales es una afirmación y la otra es evidencia potencial. El modelo es un clasificador que predice la presencia de vinculación/contradicción. En otras palabras, etiqueta un par de entrada como SUPPORTS, REFUTESo NOT ENOUGH INFORMATION.
Este modelo es un buen ejemplo porque proporciona un caso un poco más avanzado y potencialmente más útil, ya que la entrada del modelo es un par de oraciones en lugar de una sola.

En Colab o Github

Nota: A continuación, veremos la ejecución en la CPU. Pero el portátil también está listo para ejecutarse en GPU si hay uno disponible

Para poder ejecutar un modelo Hugging Face en Colab, necesitaremos instalar transformers biblioteca primero. Además, instalaremos datasets para obtener los datos para hacer inferencias, y memory_profiler para monitorear las mejoras.

Primero, echemos un vistazo al código de la tarjeta modelo. Lo modificaré un poco de inmediato, extrayendo la parte de inferencia como una función para que sea más fácil cambiar las entradas.

Para poder perfilar el tiempo de ejecución y el uso de la memoria, es necesario utilizar time y memit magia como esta

Con la creación de perfiles, ejecutamos la inferencia en la muestra proporcionada

%%time %memit predict_using_sample_code(sample_claim, sample_evidence) memoria máxima: 1400,44 MiB, incremento: 11,71 MiB Tiempos de CPU: usuario 1,24 s, sys: 140 ms, total: 1,38 s Tiempo de pared: 1,7 s
Perfil de memoria y tiempo de ejecución en una muestra usando el código original

Y el resultado parece algo aceptable.

Ahora, carguemos más muestras e intentemos ejecutar la inferencia nuevamente.
el conjunto de datos test split contiene 1535 pares, que no es un número particularmente grande.

Carga el conjunto de datos en el que se probó el modelo

La vez que lo ejecuté, encontré un entorno con una cantidad exorbitante de RAM, debe haber sido una falla de Colab, y estos son los números impactantes que obtuve. ¡52 GB de RAM no es broma!

%%time %memit etiquetas = predict_using_sample_code(input_claims, input_evidences) memoria máxima: 70648,12 MiB, incremento: 52950,69 MiB Tiempos de CPU: usuario 12 min 46 s, sistema: 6 min 37 s, total: 19 min 23 s Tiempo de pared: 3 min 48 s
Memoria y perfil de tiempo de ejecución en un montón de muestras usando el código original. Fuente: Imagen del autor.

Pero normalmente simplemente mataría la computadora portátil con una falta de memoria.

Su sesión se bloqueó.  Reinicio automático
Fuente: Imagen del autor.

Eso ciertamente no es aceptable y tenemos que arreglarlo.

Para crear un pipeline necesitamos especificar la tarea en cuestión, que en nuestro caso es «clasificación de texto». Hay un par de docenas de otras tareas disponibles, puede consultar la lista aquí. Además, estamos pasando el modelo y el tokenizador junto con sus parámetros adicionales. Y, por último, estamos especificando el dispositivo en el que se ejecutará la canalización.

Para ejecutar la canalización, necesitamos pasar los datos que pueden venir en dos tipos, ya sea un Dataset o un generador. En este caso, podríamos haber usado un conjunto de datos ya que lo tenemos disponible, pero decidí usar un generador para mostrar cómo manejar los datos que no representan un Dataset . Por ejemplo, si los datos provienen de solicitudes HTTP o de una base de datos.

batch_size se establece en 1 en aras de la comparación y, lo que es más importante, porque en este ejemplo estamos usando CPU. Al ejecutar sus inferencias en GPUasegúrate de jugar con el batch_size parámetro para ver qué configuración funciona mejor en el hardware que está utilizando, puede marcar una gran diferencia.

Ahora estamos listos para ejecutar la inferencia con un pipeline

pred_labels, pred_probs = predict_using _pipelines(input_claims, input_evidences) memoria máxima: 1434,24 MiB, incremento: 9,80 MiB Tiempos de CPU: usuario 4 min, sistema: 557 ms, total: 4 min Tiempo de pared: 4 min 7 s
Perfil de memoria y tiempo de ejecución mediante una canalización. Fuente: Imagen del autor.

Podemos notar una mejora significativa de inmediato:

  • En primer lugar, la inferencia finaliza con éxito.
  • Resulta que es posible ejecutar una inferencia usando aproximadamente la misma cantidad de RAM que para una de una muestra con el código original.

Apuesto a que puedes mejorarlo aún más cambiando a GPU y usando una adecuada batch_size para su configuración. Consulte la siguiente documentación para obtener más información.

Vimos cómo utilizar pipeline para inferencia utilizando modelos de transformadores de Hugging Face. Este enfoque no solo hace posible dicha inferencia, sino que también mejora significativamente la eficiencia de la memoria.

Definitivamente le recomiendo que lea el «Tutorial de canalizaciones para la inferencia en Hugging Face» para una inmersión más profunda y una mayor adopción para sus necesidades.

Eso es todo por hoy. ¡Feliz inferencia!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio