¿Cuál es la causa de este extraño comportamiento de bloqueo relacionado con Python, Anaconda, Matplotlib, MKL y Jupyter?

¿Cuál es la causa de este extraño comportamiento de bloqueo relacionado con Python, Anaconda, Matplotlib, MKL y Jupyter?

Estamos bastante perplejos con este problema de falla, ya que no recibimos ningún rastreo ni otros mensajes sobre lo que realmente está mal, por lo que ha sido difícil depurarlo. De todos modos, aquí va.

Contamos con una estación de trabajo para ejecutar nuestro trabajo de análisis en Python. La esencia del problema es que cuando trabajamos en portátiles (o ejecutamos el script de prueba que se muestra a continuación), el sistema falla. El bloqueo consiste en una congelación del sistema operativo y luego un reinicio. No hay nada que nos diga qué pasó, solo que la máquina se congela y se reinicia.

Los bloqueos ocurren con mayor frecuencia cuando ejecutamos una computadora portátil y le pedimos que trace demasiado. Es imposible para nosotros definir exactamente "demasiado trazado", pero el siguiente ejemplo es un caso extremo para forzar el problema. El script a veces provoca un bloqueo rápido y otras veces lleva un poco de tiempo. Pero inevitablemente provocará un colapso.

Estas son algunas de las cosas que estamos ejecutando y que, según nuestra investigación hasta ahora, parecen ser parte del problema:

  • ubuntu 18.04
  • Anaconda 5.2.0 con MKL
  • Numerosos 1.16.2
  • Matplotlib 3.0.3
  • Jupyter 1.0.0

El resumen de los hallazgos es:

  1. La instalación básica de Anaconda usa Numpy con MKL y tiene Matplotlib vinculado a sus dependencias dentro de la distribución de Anaconda. La ejecución del siguiente script de prueba con Python provoca un bloqueo cada vez. ETA: Probamos diferentes backends para Matplotlib pero no hizo la diferencia.
  2. Si ejecutamos el script de prueba desde una distribución de Anaconda donde Conda instaló Numpy peronocon MKL y Matplotlib se instaló mediante pip ynoa través de Conda, entonces el script funciona bien. Si usamos MKLoConda en lugar de pip para instalar Matplotlib, obtenemos el fallo. También podemos ejecutar el script correctamente con una distribución que no sea Anaconda con todo instalado mediante pip (y sin ningún otro enlace MKL).
  3. Si creamos una versión del script en el cuaderno Jupyter (un gráfico por celda) y ejecutamos todas las celdas, el cuaderno provocará el bloqueo. Entonces, todas nuestras ganancias en el punto 2 se eliminan simplemente usando Jupyter.
  4. Normalmente ejecutamos Jupyter en un contenedor Docker y detrás de un proxy inverso Nginx. Descartamos esto como causa porque las imágenes de Docker también son Ubuntu 18.04 y ejecutamos las pruebas directamente en la máquina host para descartar cualquier problema de Docker.
  5. Cuando realizamos un seguimiento del uso de recursos, encontramos naturalmente que con MKL, el uso de la CPU llega al rango del 300-400%. Tenemos una CPU de 12 núcleos y habitualmente alcanzamos valores de porcentaje más altos. Apenas usamos un giga de memoria cuando ejecutamos el script de prueba mientras tenemos una capacidad de 128 GB y rutinariamente ejecutamos análisis de datos que nos llevan mucho más allá de ese 1 GB.

Eso cubre lo que hemos podido descubrir. Dado que los fallos estaban tan relacionados con el trazado, parecía bastante obvio que los ajustes en Matplotlib crearon al menos una solución parcial. El problema de MKL añadió un desconcertante factor de confusión, pero pensamos que teníamos una solución alternativa. Pero luego, cuando volvimos a probarlo en Jupyter, resulta que, aunque teníamos el script en ejecución, el punto 4 todavía muestra que no hemos solucionado todo por completo.

Y eso nos lleva a esta publicación. Nada de lo que he visto en línea se acerca ni remotamente a lo que estamos observando y nunca he visto nada parecido. Me he quedado completamente sin ideas y no he recurrido a preguntarme si en realidad se trata de un problema de hardware.

Cualquier ayuda para resolver esta nuez sería muy apreciada. Estoy pensando en probar esto en nuestra estación de trabajo con una distribución de Linux distinta de Ubuntu.

# Test Script
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# None of the dataframe stuff seems to matter nor the figure size, just 
# that we're trying to plot a bunch
n = 100000
figsize = (8, 6)

df = pd.DataFrame(
    {
        'A': np.cumsum(np.random.rand(n)) / np.arange(1, n+1, 1),
        'B': np.cumsum(np.random.rand(n)) / np.arange(1, n+1, 1),
        'C': np.cumsum(np.random.rand(n)) / np.arange(1, n+1, 1)
    },
    index=pd.date_range('2001-01-01 12:00:00', freq='S', periods=n)
)
df.plot(figsize=figsize)
# closing the figures just in case, but doesn't make a difference
plt.close(plt.gcf())

...
# Repeat the dataframe and plotting snippet a lot, like ~100x
...

AÑADIDO: Mi colega encontró esta publicación esta mañana. Presentar argumentos más sólidos a favor del problema del hardware.https://forum.manjaro.org/t/python-matplotlib-script-crashes-system/44052/10

ACTUALIZACIÓN REVISADA: Desactivar el hyperthreading en el BIOS no funcionó. Pero siguiendo las sugerencias de arranque de esa publicación en manjaro.orghizoayuda, siempre y cuando no se hayan realizado junto con la desactivación del hyperthreading en el BIOS.

Respuesta1

Asolución alternaes utilizar la configuración de arranque apci=offcomo se menciona en esta publicación del foro: https://forum.manjaro.org/t/python-matplotlib-script-crashes-system/44052/10

Esto es aceptable para nosotros, pero si alguien tiene una solución o explicación real o algo que agregar a esto, soy todo oídos.

Respuesta2

Tuve exactamente los mismos problemas con un nuevo sistema Ubuntu 18.04.2 LTS y la última instalación nueva de Anaconda. Curiosamente, tuve exactamente el mismo comportamiento (congelación + falla del sistema) en Windows 10 Pro (completamente actualizado).

AFAIK, Windows no permite el arranque sin ACPI. Sin embargo, Ubuntu sí lo hace, y cambiar la configuración de arranque de grub agregando acpi=offresolvió el problema.

Sin embargo, esto no resolvió el problema de la partición de Windows, ya que ACPI es algo que Windows espera. Mi colega argentino (que es realmente fantástico) sugirió probar una versión anterior de matplotlib. Entonces, utilicé el comando conda install matplotlib=2.2.3para bajar a la versión 2.2.3.

¡La degradación resolvió inmediatamente el problema en Ubuntu y Windows! Por lo tanto, sugiero bajar la versión por ahora hasta que los desarrolladores de matplotlib resuelvan este problema. También significa que no tiene que desactivar ACPI ni ninguna otra opción que (según la estimación de este principiante) probablemente esté haciendo cosas buenas en segundo plano y, por lo tanto, es mejor continuar.

De hecho, esto funcionó para el primer ejemplo en la galería de matplotlib. Pero después de probar más ejemplos mediante scripts y en jupyter notebook, todavía falla con 2.2.3. Entonces, volví a actualizar a la última versión de matplotlib y agregué nuevamente acpi=off, pero esto aún resultó en congelación + falla al trazar un histograma en jupyter notebook. Entonces, agregué intel_pstate=disabley mantuve la última versión de matplotlib, esto pudo ejecutarse a través de un cuaderno jupyter.

ACTUALIZACIÓN: Un inconveniente de esto es que el sistema no se apaga correctamente :/ Ubuntu se bloqueará hacia el final de su apagado con esta configuración y tengo que apagar la máquina manualmente. No estoy seguro si es técnicamente bueno para el hardware.

información relacionada