Dans de nombreuses fonctions de scikit-learn, une parallélisation conviviale a été mise en œuvre. Par exemple, dans sklearn.cross_validation.cross_val_score
, Vous passez simplement le nombre souhaité de travaux de calcul dans l'argument n_jobs
. Et pour PC avec processeur multi-cœurs, cela fonctionnera très bien. Mais si je veux utiliser une telle option dans un cluster haute performance (avec le package OpenMPI installé et en utilisant SLURM pour la gestion des ressources)? Comme je sais, sklearn
utilise joblib
pour la parallélisation, qui utilise multiprocessing
. Et, comme je le sais (à partir de cela, par exemple, multiprocessing Python dans mpi ) Python programmes parallélisés avec multiprocessing
facile à mettre à l'échelle sur toute l'architecture MPI avec mpirun
utilitaire. Puis-je étendre le calcul des fonctions sklearn
sur plusieurs nœuds de calcul en utilisant simplement l'argument mpirun
et n_jobs
?
SKLearn gère son parallélisme avec Joblib . Joblib peut échanger le backend multiprocesseur pour d'autres systèmes distribués comme dask.distributed ou IPython Parallel . Voir ce problème sur la page sklearn
github pour plus de détails.
Code tiré de la page de problème liée ci-dessus.
from sklearn.externals.joblib import parallel_backend
search = RandomizedSearchCV(model, param_space, cv=10, n_iter=1000, verbose=1)
with parallel_backend('dask', scheduler_Host='your_scheduler_Host:your_port'):
search.fit(digits.data, digits.target)
Cela nécessite que vous configuriez un planificateur dask.distributed
Et des travailleurs sur votre cluster. Des instructions générales sont disponibles ici: http://distributed.readthedocs.io/en/latest/setup.html
ipyparallel
Code extrait de la même page de problème.
from sklearn.externals.joblib import Parallel, parallel_backend, register_parallel_backend
from ipyparallel import Client
from ipyparallel.joblib import IPythonParallelBackend
digits = load_digits()
c = Client(profile='myprofile')
print(c.ids)
bview = c.load_balanced_view()
# this is taken from the ipyparallel source code
register_parallel_backend('ipyparallel', lambda : IPythonParallelBackend(view=bview))
...
with parallel_backend('ipyparallel'):
search.fit(digits.data, digits.target)
Remarque: dans les deux exemples ci-dessus, le paramètre n_jobs
Ne semble plus avoir d'importance.
Pour SLURM, la façon la plus simple de le faire est probablement d'utiliser le projet dask-jobqueue
>>> from dask_jobqueue import SLURMCluster
>>> cluster = SLURMCluster(project='...', queue='...', ...)
>>> cluster.scale(20)
Vous pouvez également utiliser dask-mpi ou l'une des autres méthodes mentionnées dans documentation de configuration de Dask
Vous pouvez également configurer un cluster dask.distributed ou IPyParallel, puis utiliser ces interfaces directement pour paralléliser votre code SKLearn. Voici un exemple de vidéo du développeur SKLearn et Joblib Olivier Grisel, faisant exactement cela à PyData Berlin: https://youtu.be/Ll6qWDbRTD0?t=1561
Vous pouvez également essayer le package Dask-ML, qui a un objet RandomizedSearchCV
qui est compatible API avec scikit-learn mais implémenté par calcul au-dessus de Dask
https://github.com/dask/dask-ml
pip install dask-ml