首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R与H2O并行处理

R与H2O并行处理
EN

Stack Overflow用户
提问于 2017-04-17 02:27:03
回答 2查看 4.2K关注 0票数 5

我正在设置一段代码,以便使用foreach并行处理数据中N组的一些计算。

我有一个涉及调用h2o.gbm的计算。

在我目前的顺序设置中,我消耗了大约70%的内存.

如何在并行代码中正确地设置h2o.init()?我担心当我使用多个核时,我可能会耗尽RAM。

我的Windows 10机器有12个核心和128 of内存。

像这个伪代码有用吗?

代码语言:javascript
复制
library(foreach)
library(doParallel)

#setup parallel backend to use 12 processors
cl<-makeCluster(12)
registerDoParallel(cl)

#loop
df4 <-foreach(i = as.numeric(seq(1,999)), .combine=rbind) %dopar% {
  df4 <- data.frame()
  #bunch of computations
  h2o.init(nthreads=1, max_mem_size="10G")
  gbm <- h2o.gbm(train_some_model)
  df4 <- data.frame(someoutput)
   }

fwrite(df4, append=TRUE)

stopCluster(cl)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-17 03:43:23

当前设置代码的方式并不是最好的选择。我理解您想要做的事情--并行执行一组GBM(每个在单个核心H2O集群上),这样您就可以在机器上的12个核心上最大限度地利用CPU。但是,您的代码将尝试在同一个单核foreach集群上并行运行您的H2O循环中的所有GBM。您一次只能从一个R实例连接到一个H2O集群,但是foreach循环将创建一个新的R实例。

与R中的大多数机器学习算法不同,H2O算法都是多核的,因此训练过程将在算法级别上被并行化,而不需要像foreach这样的并行R包。

您有几个选项(#1或#3可能是最好的):

  1. h2o.init(nthreads = -1)设置在脚本的顶部,以使用所有12个核心。将foreach()循环更改为常规循环,并依次对每个GBM (在不同的数据分区上)进行培训。虽然不同的GBM是按顺序训练的,但是每个GBM都将在H2O集群中被完全并行化。
  2. h2o.init(nthreads = -1)设置在脚本的顶部,但保留foreach()循环。这应该一次运行所有GBM,每个GBM并行处理所有核心。这可能会使H2O集群有点不知所措(这实际上不是H2O的使用方式),也可能比#1慢一点,但是如果不知道数据的大小和要训练的分区的数量,就很难说了。如果您已经将70%的RAM用于单个GBM,那么这可能不是最好的选择。
  3. 您可以更新代码以执行以下操作(这与原始脚本非常相似)。这将保留您的foreach循环,在计算机上的不同端口上创建一个新的1核H2O集群。见下文。

更新的R代码示例,它使用虹膜数据集并以data.frame的形式返回虹膜的预测类:

代码语言:javascript
复制
library(foreach)
library(doParallel)
library(h2o)
h2o.shutdown(prompt = FALSE)

#setup parallel backend to use 12 processors
cl <- makeCluster(12)
registerDoParallel(cl)

#loop
df4 <- foreach(i = seq(20), .combine=rbind) %dopar% {
  library(h2o)
  port <- 54321 + 3*i
  print(paste0("http://localhost:", port))
  h2o.init(nthreads = 1, max_mem_size = "1G", port = port)
  df4 <- data.frame()
  data(iris)
  data <- as.h2o(iris)
  ss <- h2o.splitFrame(data)
  gbm <- h2o.gbm(x = 1:4, y = "Species", training_frame = ss[[1]])
  df4 <- as.data.frame(h2o.predict(gbm, ss[[2]]))[,1]
}

为了判断哪个选项是最好的,我会尝试在几个数据分区(可能是10-100)上运行这个选项,看看哪种方法似乎是最好的。如果您的培训数据很小,那么#3可能比#1更快,但总的来说,我认为#1可能是最可伸缩/最稳定的解决方案。

票数 17
EN

Stack Overflow用户

发布于 2018-09-05 14:56:32

按照Erin的回答,我只想补充一点:在许多情况下,一个不错的实用解决方案可以介于#1和#3之间。为了提高CPU利用率,并且仍然保存内存,您可以并行使用多个H2O实例,但它们都可以使用多个内核,而不需要运行多个只有一个内核的实例。

我在36台核心服务器上使用一个相对较小的40 36数据集(240 K行,22列)进行了一个实验。

  • 案例1:使用所有36个核心(nthreads=36)依次估计120个GBM模型(具有默认的超参数)。
  • 案例2:使用foreach在这台机器上运行4个H2O实例,每个实例使用9个核心依次估计30个GBM默认模型(总计=120个估计)。
  • 案例3:使用foreach在这台机器上运行12个H2O实例,每个实例使用3个核心依次估计10个GBM默认模型(总计=120个估计)。

在此数据集上使用36个核估计单个GBM模型是非常低效率的。第1种情况下的CPU利用率有很大变化,但平均低于50%。因此,一次使用多个H2O实例肯定会获得一些好处。

  • 运行时案例1: 264秒
  • 运行时案例2: 132秒
  • 运行时案例3: 130秒

考虑到从4个到12个H2O实例的小改进,我甚至没有并行运行36个H2O实例,每个实例都使用一个核心。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43444333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档