在 HPC 上使用 scikit-learn 函数的并行选项的简单方法
Posted
技术标签:
【中文标题】在 HPC 上使用 scikit-learn 函数的并行选项的简单方法【英文标题】:Easy way to use parallel options of scikit-learn functions on HPC 【发布时间】:2016-11-30 18:14:00 【问题描述】:在 scikit-learn 的许多函数中实现了用户友好的并行化。例如在
sklearn.cross_validation.cross_val_score
您只需在 n_jobs
参数中传递所需数量的计算作业。对于具有多核处理器的 PC,它会非常好用。但是如果我想在高性能集群中使用这样的选项(安装了 OpenMPI 包并使用 SLURM 进行资源管理)?据我所知sklearn
使用joblib
进行并行化,它使用multiprocessing
。而且,据我所知(据此,例如Python multiprocessing within mpi)Python 程序与multiprocessing
并行化很容易使用mpirun
实用程序扩展整个MPI 架构。我可以仅使用 mpirun
和 n_jobs
参数在多个计算节点上传播 sklearn
函数的计算吗?
【问题讨论】:
你可能想用分布式调度器检查 dask-sklearn,它可以在集群中运行:jcrist.github.io/dask-sklearn-part-1.html @dukebody 你能发布一个使用分布式调度程序的例子吗?我见过的分布式 dask 示例涉及在每台机器上手动创建工作人员并将它们分配给调度程序。我不确定我是否看到这与 dask-sklearn 函数有什么关系。我是否可以像这里一样创建调度程序和工作人员:dask.pydata.org/en/doc-test-build/distributed.html 然后像在您的链接中那样设置默认调度程序(其中 10.0.0.3:8786 是我在第一个链接中创建的调度程序的地址)? 是的。设置过程与您描述的完全一样。见distributed.readthedocs.io/en/latest/setup.html @MRocklin 这似乎对我不起作用。尽管已成功创建工人,但似乎没有对工人执行任何操作。您能否阅读下面的答案和我的 cmets,看看您有什么想法吗? 【参考方案1】:SKLearn 使用Joblib 管理其并行性。 Joblib 可以将多处理后端换成其他分布式系统,例如 dask.distributed 或 IPython Parallel。详情请参阅sklearn
github 页面上的this issue。
将 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-jobqueue 项目
>>> from dask_jobqueue import SLURMCluster
>>> cluster = SLURMCluster(project='...', queue='...', ...)
>>> cluster.scale(20)
您也可以使用dask-mpi 或Dask's setup documentation 中提到的其他几种方法中的任何一种
直接使用dask.distributed
或者,您可以设置一个 dask.distributed 或 IPyParallel 集群,然后直接使用这些接口来并行化您的 SKLearn 代码。以下是 SKLearn 和 Joblib 开发人员 Olivier Grisel 的示例视频,他们在 PyData Berlin 正是这样做的:https://youtu.be/Ll6qWDbRTD0?t=1561
试试 Dask-ML
你也可以试试 Dask-ML 包,它有一个 RandomizedSearchCV
对象,它的 API 与 scikit-learn 兼容,但在 Dask 之上实现了计算
https://github.com/dask/dask-ml
pip install dask-ml
【讨论】:
我正在尝试让第一个示例正常工作,这里也描述了这个示例:distributed.readthedocs.io/en/latest/joblib.html。我使用dask-ssh
来设置我的调度程序和工作人员。这很好用,如果我打印调度程序对象,我会得到正确数量的内核 (240
)。接下来,我在with
语句中包装了对随机搜索的fit
的调用。如果我查看执行dask-ssh
的控制台窗口,我会看到来自运行python 脚本的节点的连接。但是,没有进行分布式工作。它无法扩展,甚至看不到工作人员拥有的 GPU。
我还尝试修改 RandomizedSearchCV 的 n_jobs
参数,设置为 -1
、1
、100
、240
。 20
以上的每个值都会导致大致相同的性能,这让我认为分布式工作程序上实际上没有运行任何东西,但是在我运行 python 脚本的节点上(gensim 还会打印一条消息,即没有 GPU。那里是工作节点上的 GPU,但在我运行脚本的节点上没有 GPU)。
在这一点上,你已经超出了我的专业范围。您可以向 joblib 维护者提出问题。我给一个人发了电子邮件并提醒他这个问题,但他们很忙。我还附加了指向实验性 dask-learn 包的答案
好的,谢谢。我尝试了 dklearn,但不幸的是它只是卡住了我,似乎永远不会完成。会坚持下去的。
更新:也试过ipyparallel
,我用dask
描述的一样。工作人员(ipyparallel 中的引擎)已成功创建,客户端可以看到它们,但我的网格搜索没有在它们上运行。以上是关于在 HPC 上使用 scikit-learn 函数的并行选项的简单方法的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用 UDF .xll 在 HPC 网格上并行化 Excel
R在HPC MPIcluster上运行foreach dopar循环