当前位置: 首页 > 知识库问答 >
问题:

R H2O - 内存管理

乐正晟
2023-03-14

我试图通过R使用H2O来html" target="_blank">构建多个模型,使用一个大型数据集的子集(~ 10GB)。该数据是一年的数据,我试图建立51个模型(即第一周的训练,第二周的预测,等等。)每周大约150-250万行,有8个变量。

我在一个循环中完成了这个操作,我知道这并不总是R中的最佳方法。我发现另一个问题是H2O实体会积累之前的对象,所以我创建了一个函数来删除除主数据集以外的所有对象。

h2o.clean <- function(clust = localH2O, verbose = TRUE, vte = c()){
  # Find all objects on server
  keysToKill <- h2o.ls(clust)$Key
  # Remove items to be excluded, if any
  keysToKill <- setdiff(keysToKill, vte)
  # Loop thru and remove items to be removed
  for(i in keysToKill){
    h2o.rm(object = clust, keys = i)

    if(verbose == TRUE){
      print(i);flush.console()

    }    
  }
  # Print remaining objects in cluster.
  h2o.ls(clust)
}

该脚本运行良好一段时间,然后崩溃-经常抱怨运行内存溢出和交换到磁盘。

下面是一些伪代码来描述这个过程

# load h2o library
library(h2o)
# create h2o entity
localH2O = h2o.init(nthreads = 4, max_mem_size = "6g")
# load data
dat1.hex = h2o.importFile(localH2O, inFile, key = "dat1.hex")

# Start loop
for(i in 1:51){
# create test/train hex objects
train1.hex <- dat1.hex[dat1.hex$week_num == i,]
test1.hex <- dat1.hex[dat1.hex$week_num == i + 1,]
# train gbm
dat1.gbm <- h2o.gbm(y = 'click_target2', x = xVars, data = train1.hex
                      , nfolds = 3
                      , importance = T
                      , distribution = 'bernoulli' 
                      , n.trees = 100
                      , interaction.depth = 10,
                      , shrinkage = 0.01
  )
# calculate out of sample performance
test2.hex <- cbind.H2OParsedData(test1.hex,h2o.predict(dat1.gbm, test1.hex))
colnames(test2.hex) <- names(head(test2.hex))
gbmAuc <- h2o.performance(test2.hex$X1, test2.hex$click_target2)@model$auc

# clean h2o entity
h2o.clean(clust = localH2O, verbose = F, vte = c('dat1.hex'))

} # end loop

我的问题是,如果有的话,在独立实体中管理数据和内存的正确方法是什么(这不是在hadoop或集群上运行——只是一个大型EC2实例(约64gb RAM 12 CPU))?对于这种类型的过程,我应该在每次循环后杀死并重新创建H2O实体吗?(这是原始过程,但每次从文件中读取数据每次迭代会增加约10分钟)?在每次循环后,是否有适当的方法来垃圾收集或释放内存?

任何建议将不胜感激。

共有3个答案

乐正焕
2023-03-14

这个问题的最新答案是,你应该只使用h2o.grid()函数,而不是编写一个循环

章永安
2023-03-14

截至2015年12月15日的新建议:更新至最新稳定版本(提布拉尼3.6.0.8或更高版本)。我们完全重新设计了R

下一篇: H2O温度可以通过R死变量保持“活”...因此,每次循环迭代都运行 R gc()。一旦R的GC删除了死变量,H2O将回收该内存。

之后,您的集群应该只保留专门命名的东西,比如加载的数据集和模型。你需要尽可能快地删除它们,以避免在K/V存储中积累大量数据。

如果您有任何其他问题,请通过发布到谷歌组h2o流让我们知道:https://groups.google.com/forum/#!forum/h2ostream

悬崖

印成天
2023-03-14

这个答案适用于原始的H2O项目(版本2.x.y.z)。

在最初的H2O项目中,H2O R包在H2O集群DKV(分布式键/值存储)中创建了许多带有“Last.value”前缀的临时H2O对象。

这些都可以在Web UI的商店视图中看到,也可以通过从r。

我建议做的是:

    < li >在每个循环迭代的底部,使用h2o.assign()对要保存到已知键名的任何内容进行深层复制 < li >使用h2o.rm()删除您不想保留的任何内容,尤其是" Last.value" temps < li >在R循环中的某处显式调用GC()

这是一个为您删除Last.value临时对象的函数。传入H2O连接对象作为参数

removeLastValues <- function(conn) {
    df <- h2o.ls(conn)
    keys_to_remove <- grep("^Last\\.value\\.", perl=TRUE, x=df$Key, value=TRUE)
    unique_keys_to_remove = unique(keys_to_remove)
    if (length(unique_keys_to_remove) > 0) {
        h2o.rm(conn, unique_keys_to_remove)
    }
}

以下是H2O github存储库中一个R测试的链接,该测试使用此技术,可以无限期运行,而不会耗尽内存:

https://github . com/h2oai/H2O/blob/master/R/tests/testdir _ misc/runit _ looping _ slice _ quantile。稀有

 类似资料:
  • 对于一个基于图论的框架来说,节点和边是最小的部件。实际应用中,这些部件构成了各种有向图。比如一个有环图,它的数据流动就是一个环形,部件之间的持有关系如果不能很好的处理,那么可能就会存在内存问题。EasyReact 的内存管理逻辑非常简单,也非常精巧。可以让框架使用者无需关注太多的细节即可轻松的使用,而不必担心本框架涉及的内存方面的问题。 中间节点 节点包含了 fork、map、filter、ski

  • 在计算系统中,通常存储空间可以分为两种:内部存储空间和外部存储空间。内部存储空间通常访问速度比较快,能够按照变量地址随机地访问,也就是我们通常所说的 RAM(随机存储器),可以把它理解为电脑的内存;而外部存储空间内所保存的内容相对来说比较固定,即使掉电后数据也不会丢失,这就是通常所讲的 ROM(只读存储器),可以把它理解为电脑的硬盘。 计算机系统中,变量、中间数据一般存放在 RAM 中,只有在实际

  • 内存生命周期 垃圾回收 垃圾回收在计算机科学中是一种自动的内存管理机制。当一个计算机上的动态内存不再需要时,就应该予以释放以让出内存,这种内存资源管理称为垃圾回收。垃圾回收器可以让程序员减轻许多负担,也减少程序员犯错的机会。 特征 垃圾回收基于两个原理: 考虑某个对象在未来的程序运行中将不会被访问; 向这些对象要求归还内存。 然而,最主要的也是最艰难的部分就是找到「所分配的内存确实已经不再需要了」

  • 主要内容:一、redis的内存管理,二、源码分析,三、总结一、redis的内存管理 一般来说,稍微有点规模的软件,都会自己搞一块内存管理,原因很简单,统一管理内存,适应自己的场景。其实按大牛们的话,这未必是最优选择,实在是小看了写库的那群大牛们。不过说归说,人家写也不会给你报备,想写自然就写了。Redis就听从了大牛的看法,使用了底层更好的内存分配库,根据情况使用tmalloc,jemalloc 以及glibc中的 malloc(pmalloc)。 一般

  • 本章描述 Linux 内核中的内存管理。在本章中你会看到一系列描述 Linux 内核内存管理框架的不同部分的帖子。 内存块 - 描述早期的 memblock 分配器。 固定映射地址和 ioremap - 描述固定映射的地址和早期的 ioremap 。 kmemcheck - 第三部分描述 kmemcheck 工具。

  • 本章描述 Linux 内核中的内存管理。在本章中你会看到一系列描述 Linux 内核内存管理框架的不同部分的帖子。 内存块 - 描述早期的 memblock 分配器。 固定映射地址和 ioremap - 描述固定映射的地址和早期的 ioremap 。 kmemcheck - 第三部分描述 kmemcheck 工具。

  • 一、内存连续分配 主要是指动态分区分配时所采用的几种算法。 动态分区分配又称为可变分区分配,是一种动态划分内存的分区方法。这种分区方法不预先将内存划分,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。因此系统中分区的大小和数目是可变的。 首次适应(First Fit)算法: 空闲分区以地址递增的次序链接。分配内存时顺序查找,找到大小能满足要求的第一个空闲分区。

  • RTOS内核需要使用 RAM 来为每次创建任务、队列、互斥量、信号量、事件组、软件定时器分配内存,内存分配可以由 freeRTOS 的API动态自动从堆上创建,也可以由开发者自己分配。 如果RTOS对象是动态创建的,标准C库中的malloc()和free()函数有时可以达到目的,但是: 在某些嵌入式系统中可能不可用 标准库函数占用代码空间 不是线程安全的 不是精确的,会导致总体执行时间降低 以上问