改进多节点集群上的 h2o DRF 运行时

Posted

技术标签:

【中文标题】改进多节点集群上的 h2o DRF 运行时【英文标题】:Improve h2o DRF runtime on a multi-node cluster 【发布时间】:2018-01-11 03:29:36 【问题描述】:

我目前正在运行h2o 的 DRF 算法和一个 3 节点 EC2 集群(h2o 服务器跨越所有 3 个节点)。 我的数据集有 100 万行和 41 列(40 个预测变量和 1 个响应)。

我使用R绑定控制集群,RF调用如下

model=h2o.randomForest(x=x,
                       y=y,
                       ignore_const_cols=TRUE,
                       training_frame=train_data,
                       seed=1234,
                       mtries=7,
                       ntrees=2000,
                       max_depth=15,
                       min_rows=50,
                       stopping_rounds=3,
                       stopping_metric="MSE",
                       stopping_tolerance=2e-5)

对于 3 节点集群(c4.8xlarge,启用增强网络),这大约需要 240 秒; CPU 利用率在 10-20% 之间; RAM 利用率在 20-30% 之间;网络传输在 10-50MByte/sec(输入和输出)之间。建造 300 棵树,直到提前停止。

单节点 集群上,我可以在大约 80 秒内获得相同的结果。因此,对于 3 节点集群,我得到的速度不是预期的 3 倍,而是 3 倍。

我做了一些研究,发现一些资源报告了同样的问题(虽然不像我的那么极端)。例如,参见: https://groups.google.com/forum/#!topic/h2ostream/bnyhPyxftX8

具体来说,http://datascience.la/benchmarking-random-forest-implementations/ 的作者指出

虽然不是本研究的重点,但有迹象表明运行 多个分布式随机森林实现(例如 H2O) 节点不能提供人们希望的速度优势(因为 在每次拆分时运送直方图的高成本 网络)。

https://www.slideshare.net/0xdata/rf-brighttalk 还指出了 2 种不同的 DRF 实现,其中一种具有更大的网络开销。

我认为我遇到了与上面链接中描述的相同的问题。 如何提高h2o 在多节点集群上的 DRF 性能? 是否有任何设置可以改善运行时间? 任何帮助都非常感谢!

【问题讨论】:

【参考方案1】:

如果您的随机森林在多节点 H2O 集群上速度较慢,这仅意味着您的数据集不够大,无法利用分布式计算。集群节点之间的通信存在开销,因此如果您可以在单个节点上成功训练模型,那么使用单个节点总是会更快。

多节点设计用于当您的数据太大而无法在单个节点上进行训练时。只有这样,使用多个节点才值得。否则,您只是无缘无故地增加了通信开销,并且会看到您观察到的减速类型。

如果您的数据适合单台机器的内存(并且您可以成功训练模型而不会耗尽内存),加快训练速度的方法是切换到具有更多内核的机器。您还可以尝试一些影响训练速度的参数值,看看是否可以加快速度,但这通常会以模型性能为代价。

【讨论】:

感谢您的帮助。我假设其他机器学习技术(例如 GBM,其中模型大小通常较小)不会遇到这个问题。遗憾的是 DRF 无法加速,因为根据问题大小和 DRF 超参数,单节点模型训练在我的情况下可能需要长达 45 分钟。这使得顺序超参数优化变得棘手......无论如何,我将尝试在 x1.32xlarge 机器上运行我的代码,看看它是如何执行的。据我所知,内存带宽似乎是 DRF 的瓶颈,这些实例提供了高内存带宽(据说)。 GBM 将需要相似数量的内存——通常你在 RF 中训练的树比 GBM 少,但树在 RF 中更深。 GBM 通常比 RF 获得更好的性能,因此您可能需要同时尝试两者,看看哪种方法最适合您的数据。 艾琳,还有一个问题:难道不能独立地种植森林中的单棵树吗?鉴于关闭了提前停止,那么应该没有中间通信开销。非常类似于我在问题中链接的 Michal Malohlava 的 rf-brighttalk 幻灯片中提出的射频训练算法 #1。我的猜测是,出于“大数据”的原因,h2o 采用了另一种实现方式(这取决于直方图的中间交换)。 h2o 是否有计划在 #2 之外还实施算法 #1(见幻灯片)? 是的,这是可能的,但它需要每个独立的进程将整个训练集保存在内存中,所以这是一个很大的缺点。我们曾经在 H2O-2 中拥有两个版本(“DRF”和“SpeeDRF”),但后者无法扩展到大数据。有可能我们可以放回快速/小数据版本,但目前不在路线图上。 感谢您的确认。顺便说一句:现在有了大内存云实例(AWS x1.32xlarge 为 2TB)以及贝叶斯超参数优化变得越来越流行,我猜用户对“小数据”版本的需求将会回升。【参考方案2】:

正如 Erin 所说,通常添加更多节点只是增加了更大数据集的能力,而不是更快的学习。随机森林可能是最糟糕的;我通过深度学习获得了相当好的结果(例如,4 个节点快 3 倍,8 个节点快 5-6 倍)。

在您对 Erin 的回答的评论中,您提到真正的问题是您想加速超参数优化吗?令人沮丧的是,h2o.grid() 不支持在每个节点上并行构建模型,而此时数据将适合每个节点上的内存。但是你可以自己做,用一点脚本:在每个节点上设置一个 h2o 集群,在每个节点上使用超参数子集进行网格搜索,让他们将结果和模型保存到 S3,然后将结果并在最后组合它们。 (如果进行随机网格搜索,您可以在每个集群上运行完全相同的网格,但最好在每个集群上显式使用不同的种子。)

【讨论】:

达伦,非常感谢您的意见。您所描述的(在每个节点上都有一个单独的 h2o 集群)非常适合随机搜索和网格搜索。实际上,我已经将这种解决方案用于网格/随机搜索。但是,如果想要进行贝叶斯超参数优化(基本上是按顺序工作),最好让多个节点在一个参数配置上工作。顺便说一句:我有你的书;) 您的多节点网格/随机搜索是否适用于一组 H2O 集群?我很想看到一篇博客文章或其他内容,展示您使用的脚本。 (感谢您购买这本书!) 我在 R 中做所有事情(在一个不做任何 h2o 计算的主节点上)。我对***.com/questions/43515062/increase-h2o-init-timeout 的回答中描述了集群设置。但我现在使用clusterCall 而不是foreach 进行集群设置。任务分配通过foreach 完成。我也通过 CV 折叠(不仅通过超级参数 conf)拆分任务。结果通过data.table::rbindList 收集(如果您有更大的数据集,这很重要)。 嗨 Darren,如果您仍然对在集群​​上运行 R ML 任务感兴趣,我强烈推荐新的 future R 包。我现在可以使用自己的负载平衡方法,动态创建/删除任务并按顺序分析传入的结果。它不能解决并行化贝叶斯优化的问题(如我最初的问题中所述) - 但它比使用 foreachclusterCall 灵活得多。

以上是关于改进多节点集群上的 h2o DRF 运行时的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止一个节点上的死锁使整个集群崩溃?

从 R 中启动多个 h2o 集群

在 hadoop 多节点集群上运行 mahout kmeans

单节点hadoop集群上的实验练习

使用 rsparkling 在 Databricks 上启动 H2O 上下文

如何跨 Slurm 集群上的多个节点运行 MPI Python 脚本?错误:警告:无法在 2 个节点上运行 1 个进程,将 nnodes 设置为 1