python - Por qué GridSearchCV en scikit-learn engendra tantos hilos
multithreading grid-search (1)
De sklearn.GridSearchCV
doc:
n_jobs: int, default = 1 Número de trabajos para ejecutar en paralelo.
pre_dispatch: int, o string, opcional Controla el número de trabajos que se envían durante la ejecución en paralelo. Reducir este número puede ser útil para evitar una explosión de consumo de memoria cuando se envían más trabajos de los que las CPU pueden procesar. Este parámetro puede ser: ninguno, en cuyo caso todos los trabajos se crean y generan inmediatamente. Úselo para trabajos livianos y de ejecución rápida, para evitar demoras debido a la generación de trabajos a pedido. Int, dando el número exacto de trabajos totales que se generan. Una cadena, dando una expresión en función de n_jobs, como en '' 2 * n_jobs ''
Si entiendo la documentación correctamente, el GridSearchCV
genera un montón de hilos como número de puntos de grilla, y solo ejecuta n_jobs
simultáneamente. Número 31 Creo que es algún tipo de límite de límite de sus 40 posibles valores. Intenta jugar con el valor del parámetro pre_dispatch
.
Otros 11 hilos creo que no tienen nada que ver con el GridSearchCV
sí, ya que se muestra en el mismo nivel. Creo que son restos de otros comandos.
Por cierto, no observo ese comportamiento en Mac (solo veo 5 procesos engendrados por GridSearchCV
como uno esperaría) así que puede provenir de bibliotecas incompatibles. Intente actualizar sklearn
y numpy
manualmente.
Aquí está mi salida pstree
(parte de la ruta eliminada para privacidad):
└─┬= 00396 *** -fish
└─┬= 21743 *** python /Users/***/scratch_5.py
├─── 21775 *** python /Users/***/scratch_5.py
├─── 21776 *** python /Users/***/scratch_5.py
├─── 21777 *** python /Users/***/scratch_5.py
├─── 21778 *** python /Users/***/scratch_5.py
└─── 21779 *** python /Users/***/scratch_5.py
respuesta al segundo comentario:
Ese es tu código en realidad. Acaba de generar un problema separable de clase 1d dos:
N = 50000
Xs = np.concatenate( (np.random.random(N) , 3+np.random.random(N)) ).reshape(-1, 1)
ys = np.concatenate( (np.zeros(N), np.ones(N)) )
100k muestras fueron suficientes para tener la CPU ocupada durante aproximadamente un minuto.
Aquí está la salida pstree
de mi actual GridSearch en ejecución, tengo curiosidad por ver qué procesos están sucediendo, y hay algo que aún no puedo explicar.
├─bash─┬─perl───20*[bash───python─┬─5*[python───31*[{python}]]]
│ │ └─11*[{python}]]
│ └─tee
└─bash───pstree
Eliminé cosas que no están relacionadas. Las llaves cortas significan hilos.
- La aparición de perl se debe a que utilicé
parallel -j 20
para iniciar mis trabajos de python. Como puede ver,20*
hecho muestra que hay 20 procesos. - Un proceso de
bash
antes de cada uno de los procesos de python se debe a la activación del entorno virtual de Anaconda consource activate venv
. - Dentro de cada proceso de Python, hay otros 5 procesos de python (
5*
) generados. Esto se debe a que especifiquén_jobs=5
aGridSearchCV
.
Mi comprensión termina aquí.
Pregunta : ¿alguien puede explicar por qué hay otros 11 subprocesos python ( 11*[{python}]
) junto con la búsqueda de cuadrícula, y 31 subprocesos python ( 31*[{python}]
) generados dentro de cada uno de los 5 trabajos de búsqueda de grillas?
Actualización : agregó el código para llamar a GridSearchCV
Cs = 10 ** np.arange(-2, 2, 0.1)
skf = StratifiedKFold(n_splits=10, shuffle=True, random_state=0)
clf = LogisticRegression()
gs = GridSearchCV(
clf,
param_grid={''C'': Cs, ''penalty'': [''l1''],
''tol'': [1e-10], ''solver'': [''liblinear'']},
cv=skf,
scoring=''neg_log_loss'',
n_jobs=5,
verbose=1,
refit=True)
gs.fit(Xs, ys)
Actualización (2017-09-27) :
Envolví un código de prueba en esencia para que puedas reproducir fácilmente si está interesado.
Probé el mismo código en una Mac Pro y múltiples máquinas Linux, y reproduje el resultado de @igrinis, pero solo en Mac Pro. En las máquinas Linux, obtengo números diferentes a los anteriores, pero de forma consistente. Por lo tanto, la cantidad de subprocesos generados puede depender de la información de datos particular de GridSearchCV.
python─┬─5*[python───31*[{python}]]
└─3*[{python}]
Tenga en cuenta que las pstree instaladas por homebrew / linuxbrew en Mac Pro y linux son diferentes. Aquí publico las versiones exactas que utilicé:
Mac:
pstree $Revision: 2.39 $ by Fred Hucht (C) 1993-2015
EMail: fred AT thp.uni-due.de
Linux:
pstree (PSmisc) 22.20
Copyright (C) 1993-2009 Werner Almesberger and Craig Small
La versión de Mac no parece tener una opción para mostrar los hilos, lo que pensé que podría ser por qué no se ven en el resultado. Todavía no he encontrado una manera de inspeccionar los hilos en Mac Pro. Si por casualidad sabes una forma, por favor comenta.
Actualización (2017-10-12)
En otro conjunto de experimentos, confirmé que establecer la variable de entorno OMP_NUM_THREADS
hace la diferencia.
Antes de export OMP_NUM_THREADS=1
, hay muchos (63 en este caso) subprocesos sin un uso incierto generado como se describe anteriormente:
bash───python─┬─23*[python───63*[{python}]]
└─3*[{python}]
No hay uso de Linux parallel
aquí. n_jobs=23
.
Después de export OMP_NUM_THREADS=1
, no se generaron subprocesos, pero los 3 procesos de Python todavía están allí, cuyo uso todavía desconozco.
bash───python─┬─23*[python]
└─3*[{python}]
Inicialmente me encontré con OMP_NUM_THREADS
porque causa un error en algunos de mis trabajos de GridSearchCV, los mensajes de error son algo así como
OMP: Error #34: System unable to allocate necessary resources for OMP thread:
OMP: System error #11: Resource temporarily unavailable
OMP: Hint: Try decreasing the value of OMP_NUM_THREADS.