我正在设置一段代码,以便使用foreach并行处理数据中N组的一些计算。
我有一个涉及调用h2o.gbm的计算。
在我目前的顺序设置中,我消耗了大约70%的内存.
如何在并行代码中正确地设置h2o.init()?我担心当我使用多个核时,我可能会耗尽RAM。
我的Windows 10机器有12个核心和128 of内存。
像这个伪代码有用吗?
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)发布于 2017-04-17 03:43:23
当前设置代码的方式并不是最好的选择。我理解您想要做的事情--并行执行一组GBM(每个在单个核心H2O集群上),这样您就可以在机器上的12个核心上最大限度地利用CPU。但是,您的代码将尝试在同一个单核foreach集群上并行运行您的H2O循环中的所有GBM。您一次只能从一个R实例连接到一个H2O集群,但是foreach循环将创建一个新的R实例。
与R中的大多数机器学习算法不同,H2O算法都是多核的,因此训练过程将在算法级别上被并行化,而不需要像foreach这样的并行R包。
您有几个选项(#1或#3可能是最好的):
h2o.init(nthreads = -1)设置在脚本的顶部,以使用所有12个核心。将foreach()循环更改为常规循环,并依次对每个GBM (在不同的数据分区上)进行培训。虽然不同的GBM是按顺序训练的,但是每个GBM都将在H2O集群中被完全并行化。h2o.init(nthreads = -1)设置在脚本的顶部,但保留foreach()循环。这应该一次运行所有GBM,每个GBM并行处理所有核心。这可能会使H2O集群有点不知所措(这实际上不是H2O的使用方式),也可能比#1慢一点,但是如果不知道数据的大小和要训练的分区的数量,就很难说了。如果您已经将70%的RAM用于单个GBM,那么这可能不是最好的选择。foreach循环,在计算机上的不同端口上创建一个新的1核H2O集群。见下文。更新的R代码示例,它使用虹膜数据集并以data.frame的形式返回虹膜的预测类:
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可能是最可伸缩/最稳定的解决方案。
发布于 2018-09-05 14:56:32
按照Erin的回答,我只想补充一点:在许多情况下,一个不错的实用解决方案可以介于#1和#3之间。为了提高CPU利用率,并且仍然保存内存,您可以并行使用多个H2O实例,但它们都可以使用多个内核,而不需要运行多个只有一个内核的实例。
我在36台核心服务器上使用一个相对较小的40 36数据集(240 K行,22列)进行了一个实验。
在此数据集上使用36个核估计单个GBM模型是非常低效率的。第1种情况下的CPU利用率有很大变化,但平均低于50%。因此,一次使用多个H2O实例肯定会获得一些好处。
考虑到从4个到12个H2O实例的小改进,我甚至没有并行运行36个H2O实例,每个实例都使用一个核心。
https://stackoverflow.com/questions/43444333
复制相似问题