Spacy, al usar nlp.pipe en un gran conjunto de datos en Python, el multiprocesamiento lleva a que los procesos entren en estado

CorePress2024-01-25  150

Estoy trabajando en un problema de clasificación de PNL en una gran base de datos de correos electrónicos (~1 millón). Necesito usar spacy para analizar textos y estoy usando el método nlp.pipe() como nlp.pipe(emails,n_process=CPU_CORES, batch_size=20) para recorrer el conjunto de datos. El código funciona pero me enfrento a un comportamiento extraño (tal vez no tan): los procesos se están creando pero todos están en estado SLEEP menos uno, casualmente algunos de ellos entran en estado RUN durante unos segundos y luego vuelven a dormir. Entonces me encuentro con un solo proceso que usa un núcleo al 100% pero, por supuesto, el script no usa todos los núcleos de la CPU. Es como si los procesos no se "alimentaran" con el tiempo. ingrese datos desde la tubería.

¿Alguien sabe cómo utilizar correctamente la tubería Spacy NLP o cómo evitar esta situación? no hay forma de usar nlp.pipe con G¿PU?

¡Muchas gracias! Sandro

EDITAR: Todavía no tengo solución, pero he notado que si configuro el tamaño de lote = divmod (len (correos electrónicos), CPU_CORES), todos los procesos comienzan a ejecutarse al 100% de la CPU y después de unos segundos todos cambian a estado de sueño pero uno. Realmente parece que algún elemento en la tubería espacial se bloquea mientras espera que algo termine... ¿Alguna idea?

EDITAR 2: Configurar lote_size=divmod(len(emails),CPU_CORES) mientras se procesa un conjunto de datos grande conduce inevitablemente a un error de memoria vacía:

Error de memoria: no se puede asignar una matriz con forma (1232821, 288) y tipo de datos float32

* Algo que tal vez no sea tan extraño ya que mi máquina tiene 10 GB de RAM y (1232821 × 288 × 32) bits / 8 = 1,4 GB multiplicados por 6 (CPU_CORES), lo que da como resultado 8,5 GB de RAM necesarios. Por eso supongo que,Al tener ya otras cosas en la memoria, resulta plausible. *

No soy un experto en multiprocesamiento, pero ¿ha intentado aumentar el tamaño del lote a 500 o 1000 (quizás más teniendo en cuenta su gran número de muestras)? 20 parecen bastante pequeñas, significa que cada 20 muestras es necesario reprogramar los procesos. Alternativamente, puede desactivar algunas tuberías en su modelo espacioso (generalmente uso solo la etiqueta POS)

-ygorg

29/03/2021 a las 10:29

Hola @ygorg, sí, intenté establecer el tamaño del lote en muchos valores diferentes (<= 10,000) pero nada cambió, todos los procesos están en estado de suspensión menos uno. Lamentablemente, deshabilitar algunos componentes de la canalización no es una opción, ya que los necesito todos. A ver si alguien más tiene alguna sugerencia. ¡Gracias por su respuesta! :)

- El Viejo

29/03/2021 a las 15:16

En GPU probablemente sea más fácilOptimice el tamaño de lote para la longitud de su texto + memoria GPU y use un proceso. Dependiendo de la cantidad de procesos/RAM, el tamaño del lote de la CPU puede ser superior a 1000, es posible que el tamaño del lote de la GPU deba ser mucho más pequeño. Además, si está utilizando un modelo de transformador, es posible que tenga problemas relacionados con la antorcha y OpenMP (en CPU o GPU): github.com/pytorch/pytorch/issues/17199

-aab

30 de marzo de 2021 a las 7:54

@aab gracias por tu respuesta. No estoy seguro de cómo "forzar" ¿spacy nlp.pipe() para usar la GPU?

- El Viejo

30 de marzo de 2021 a las 9:58

¿Podría la causa ser que lo que hago dentro del documento for en nlp.pipe(...): el bucle es demasiado lento en términos de tiempo de ejecución y, por lo tanto, spacy pipe de alguna manera tiene que esperar a que se procesen todos los lotes? Es sólo una suposición, ya que no soy un experto en espacios ni en multiprocesamiento....

- El Viejo

30/03/2021 a las 10:02



------------------------------------

Descubrí que usar n_process=n funciona bien para algunos modelos, como en_core_web_lg, pero falla con otros, como en_core_web_trf.

Por alguna razón, en_core_web_trf parece usar todos los núcleos con solo un tamaño de lote especificado, mientras que en_core_web_lg usa solo uno a menos que se proporcione n_process=n. Del mismo modo, en_core_web_trf falla con un error de cierre si se especifica n_process=n.

1

Estoy usando en_core_web_lg, pero el problema principal para mí es que los procesos se van a suspender y (aparentemente) se activan aleatoriamente en lugar de estar ejecutándose todos juntos todo el tiempo. Gracias por tu contribución de todos modos :)

- El Viejo

12 de abril de 2021 a las 10:46



------------------------------------

Vale, creo que encontré una mejora pero, sinceramente, el comportamiento no me queda muy claro. Ahora los procesos de suspensión son mucho menores, la mayoría de ellos se ejecutan de manera estable y algunos duermen o cambian entre los dos estados. Lo que hice fue limpiar y acelerar todo el código dentro del bucle for y configurar los argumentos nlp.pipe de esta manera:

para e en nlp.pipe(correos electrónicos,n_process=CPU_CORES-1, tamaño_lote=200):

Si alguien tiene alguna explicación sobre esto o alguna sugerencia sobre cómo mejorar aún más, por supuesto es más que bienvenido :)

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare