python multithreading scikit-learn grid-search

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 con source 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 a GridSearchCV .

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.