python - sklearn - ¿Por qué es importante proteger el bucle principal cuando se utiliza joblib.Parallel?
joblib dump (1)
Esto es necesario porque Windows no tiene fork()
. Debido a esta limitación, Windows necesita volver a importar su módulo __main__
en todos los procesos secundarios que genera, para poder volver a crear el estado del padre en el hijo. Esto significa que si tiene el código que genera el nuevo proceso a nivel de módulo, se ejecutará recursivamente en todos los procesos secundarios. La protección if __name__ == "__main__"
se utiliza para evitar que el código en el alcance del módulo se vuelva a ejecutar en los procesos secundarios.
Esto no es necesario en Linux porque tiene fork()
, lo que le permite bifurcar un proceso hijo que mantiene el mismo estado que el padre, sin volver a importar el módulo __main__
.
Los documentos de joblib contienen la siguiente advertencia:
Bajo Windows, es importante proteger el bucle principal del código para evitar la generación recursiva de subprocesos cuando se usa joblib.Paralelo. En otras palabras, debes escribir código como este:
import .... def function1(...): ... def function2(...): ... ... if __name__ == ''__main__'': # do stuff with imports and functions defined about ...
Ningún código debe ejecutarse fuera de los bloques "if __name__ == ''__main__''", solo importaciones y definiciones.
Inicialmente, asumí que esto era solo para prevenir el caso impar ocasional en el que una función pasaba a joblib.Parallel
llamaba el módulo de forma recursiva, lo que significaría que en general era una buena práctica pero a menudo era innecesaria. Sin embargo, no tiene sentido para mí por qué esto solo sería un riesgo en Windows. Además, esta respuesta parece indicar que el hecho de no proteger el bucle principal hizo que el código se ejecutara varias veces más lento de lo que hubiera sido en un problema no recursivo muy simple.
Por curiosidad, ejecuté el ejemplo súper simple de un bucle vergonzosamente paralelo de los documentos de Joblib sin proteger el bucle principal en un cuadro de Windows. Mi terminal recibió spam con el siguiente error hasta que lo cerré:
ImportError: [joblib] Attempting to do parallel computing without protecting your import on a system that does not suppo
rt forking. To use parallel-computing in a script, you must protect you main loop using "if __name__ == ''__main__''". Ple
ase see the joblib documentation on Parallel for more information
Mi pregunta es, ¿qué pasa con la implementación de Windows de joblib requiere que el bucle principal esté protegido en todos los casos?
Disculpas si esta es una pregunta super básica. Soy nuevo en el mundo de la paralelización, por lo que me pueden faltar algunos conceptos básicos, pero no pude encontrar este problema discutido explícitamente en ninguna parte.
Finalmente, quiero señalar que esto es puramente académico; Entiendo por qué generalmente es una buena práctica escribir el código de esta manera, y lo seguiré haciendo independientemente de joblib.