在HPC上使用scikit学习函数的并行选项的简单方法



在scikit的许多函数中,学习实现了用户友好的并行化。例如sklearn.cross_validation.cross_val_score您只需在n_jobs参数中传递所需数量的计算作业。对于具有多核处理器的PC来说,它的工作效果会非常好。但如果我想在高性能集群中使用这样的选项(安装了OpenMPI包并使用SLURM进行资源管理)?正如我所知,sklearn使用joblib进行并行化,后者使用multiprocessing。而且,正如我所知(例如,从这里可以看出,mpi中的Python多处理)用multiprocessing并行的Python程序很容易用mpirun实用程序扩展整个mpi体系结构。仅使用mpirunn_jobs自变量,我就可以在几个计算节点上扩展sklearn函数的计算吗?

SKLearn使用Joblib管理其并行性。Joblib可以将多处理后端换成其他分布式系统,如dask.distributed或IPython Parallel。有关详细信息,请参阅sklearn github页面上的此问题。

将Joblib与Dask.distributed一起使用的示例

代码取自上面链接的问题页面。

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)

这需要在集群上设置dask.distributed调度程序和工作程序。此处提供了一般说明:http://dask.readthedocs.io/en/latest/setup.html

将Joblib与ipyparallel一起使用的示例

代码取自同一期。

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)

注意:在上述两个示例中,n_jobs参数似乎不再重要。

使用SLURM设置dask.distributed

对于SLURM来说,最简单的方法可能是使用dask作业队列项目

>>> from dask_jobqueue import SLURMCluster
>>> cluster = SLURMCluster(project='...', queue='...', ...)
>>> cluster.scale(20)

您也可以使用dask-mpi或dask的设置文档中提到的其他几种方法中的任何一种

直接使用dask.distributed

或者,您可以设置一个dask.distributed或IPyParallel集群,然后直接使用这些接口来并行化您的SKLearn代码。以下是SKLearn和Joblib开发人员Olivier Grisel在PyData Berlin做这件事的示例视频:https://youtu.be/Ll6qWDbRTD0?t=1561

尝试Dask ML

您也可以尝试Dask-ML包,它有一个RandomizedSearchCV对象,该对象与scikit-learn兼容API,但在Dask-之上通过计算实现

https://github.com/dask/dask-ml

pip install dask-ml

最新更新