【问题标题】:H2O: Cannot read LARGE model from disk via `h2o.loadModel`H2O:无法通过“h2o.loadModel”从磁盘读取 LARGE 模型
【发布时间】:2017-11-28 01:19:57
【问题描述】:
  • 更新于 2017 年 6 月 28 日,下文,以回应 @Michal Kurka。
  • 2017 年 6 月 26 日更新,如下。

我无法加载以原生 H2O 格式(即十六进制)保存的大型 GBM 模型。

  • H2O v3.10.5.1
  • R v3.3.2
  • Linux 3.10.0-327.el7.x86_64 GNU/Linux

我的目标是最终将此模型保存为 MOJO。

这个模型太大了,我必须用最小/最大内存 100G/200G 初始化 H2O,然后 H2O 的模型训练才能成功运行。

这就是我训练 GBM 模型的方式:

localH2O <- h2o.init(ip = 'localhost', port = port, nthreads = -1,
                     min_mem_size = '100G', max_mem_size = '200G')

iret <- h2o.gbm(x = predictors, y = response, training_frame = train.hex,
                validation_frame = holdout.hex, distribution="multinomial",
                ntrees = 3000, learn_rate = 0.01, max_depth = 5, nbins = numCats,
                model_id = basename_model)

gbm <- h2o.getModel(basename_model)
oPath <- h2o.saveModel(gbm, path = './', force = TRUE)

训练数据包含 1413 列的 81,886 条记录。在这些列中,有 19 个是因子。这些列中的绝大多数是 0/1。

$ wc -l training/*.txt
     81887 training/train.txt
     27294 training/holdout.txt

这是写入磁盘的保存模型:

$ ls -l

total 37G
-rw-rw-r-- 1 bfo7328 37G Jun 22 19:57 my_model.hex

这就是我尝试使用相同的大内存分配值 100G/200G 从磁盘读取模型的方式:

$ R

R version 3.3.2 (2016-10-31) -- "Sincere Pumpkin Patch"
Copyright (C) 2016 The R Foundation for Statistical Computing
Platform: x86_64-redhat-linux-gnu (64-bit)

> library(h2o)
> localH2O=h2o.init(ip='localhost', port=65432, nthreads=-1,
                  min_mem_size='100G', max_mem_size='200G')

H2O is not running yet, starting it now...

Note:  In case of errors look at the following log files:
    /tmp/RtmpVSwxXR/h2o_bfo7328_started_from_r.out
    /tmp/RtmpVSwxXR/h2o_bfo7328_started_from_r.err

openjdk version "1.8.0_121"
OpenJDK Runtime Environment (build 1.8.0_121-b13)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)

Starting H2O JVM and connecting: .. Connection successful!

R is connected to the H2O cluster: 
    H2O cluster uptime:         3 seconds 550 milliseconds 
    H2O cluster version:        3.10.5.1 
    H2O cluster version age:    13 days  
    H2O cluster name:           H2O_started_from_R_bfo7328_kmt050 
    H2O cluster total nodes:    1 
    H2O cluster total memory:   177.78 GB 
    H2O cluster total cores:    64 
    H2O cluster allowed cores:  64 
    H2O cluster healthy:        TRUE 
    H2O Connection ip:          localhost 
    H2O Connection port:        65432 
    H2O Connection proxy:       NA 
    H2O Internal Security:      FALSE 
    R Version:                  R version 3.3.2 (2016-10-31) 

来自/tmp/RtmpVSwxXR/h2o_bfo7328_started_from_r.out

INFO: Processed H2O arguments: [-name, H2O_started_from_R_bfo7328_kmt050, -ip, localhost, -port, 65432, -ice_root, /tmp/RtmpVSwxXR]
INFO: Java availableProcessors: 64
INFO: Java heap totalMemory: 95.83 GB
INFO: Java heap maxMemory: 177.78 GB
INFO: Java version: Java 1.8.0_121 (from Oracle Corporation)
INFO: JVM launch parameters: [-Xms100G, -Xmx200G, -ea]
INFO: OS version: Linux 3.10.0-327.el7.x86_64 (amd64)
INFO: Machine physical memory: 1.476 TB

我给h2o.loadModel的电话:

if ( TRUE ) {
  now <- format(Sys.time(), "%a %b %d %Y %X")
  cat( sprintf( 'Begin %s\n', now ))

  model_filename <- './my_model.hex'
  in_model.hex <- h2o.loadModel( model_filename )

  now <- format(Sys.time(), "%a %b %d %Y %X")
  cat( sprintf( 'End   %s\n', now ))
}

来自/tmp/RtmpVSwxXR/h2o_bfo7328_started_from_r.out

INFO: GET /, parms: {}
INFO: GET /, parms: {}
INFO: GET /, parms: {}
INFO: GET /3/InitID, parms: {}
INFO: Locking cloud to new members, because water.api.schemas3.InitIDV3
INFO: POST /99/Models.bin/, parms: {dir=./my_model.hex}

等待一个小时后,我看到这些“内存不足”(OOM)错误消息:

INFO: POST /99/Models.bin/, parms: {dir=./my_model.hex}
#e Thread WARN: Swapping!  GC CALLBACK, (K/V:24.86 GB + POJO:112.01 GB + FREE:40.90 GB == MEM_MAX:177.78 GB), desiredKV=22.22 GB OOM!
#e Thread WARN: Swapping!  GC CALLBACK, (K/V:26.31 GB + POJO:118.41 GB + FREE:33.06 GB == MEM_MAX:177.78 GB), desiredKV=22.22 GB OOM!
#e Thread WARN: Swapping!  GC CALLBACK, (K/V:27.36 GB + POJO:123.03 GB + FREE:27.39 GB == MEM_MAX:177.78 GB), desiredKV=22.22 GB OOM!
#e Thread WARN: Swapping!  GC CALLBACK, (K/V:28.21 GB + POJO:126.73 GB + FREE:22.83 GB == MEM_MAX:177.78 GB), desiredKV=22.22 GB OOM!

我不希望从磁盘读取模型需要这么多内存。

如何将这个模型从磁盘读入内存。一旦我这样做了,我可以将它保存为 MOJO 吗?


更新 1:2017 年 6 月 26 日

我刚刚注意到 GBM 模型的磁盘大小在 H2O 版本之间显着增加:

H2O v3.10.2.1:
    -rw-rw-r-- 1 169M Jun 19 07:23 my_model.hex

H2O v3.10.5.1:
    -rw-rw-r-- 1  37G Jun 22 19:57 my_model.hex

任何想法为什么?这可能是问题的根源吗?


更新 2:2017 年 6 月 28 日,以回应 @Michal Kurka 的 cmets。

当我通过fread 加载训练数据时,每一列的类(类型)都是正确的: * 24 列是‘字符’; * 1389 列是“整数”(除了一列之外都是 0/1); * 总共 1413 列。

然后我将 R-native 数据框转换为 H2O 数据框并手动分解 20 列:

train.hex <- as.h2o(df.train, destination_frame = "train.hex”)
length(factorThese)
[1] 20
train.hex[factorThese] <- as.factor(train.hex[factorThese])
str(train.hex)

str(train.hex) 输出的精简版本,仅显示作为因子的 19 列(1 个因子是响应列):

 - attr(*, "nrow")= int 81886
 - attr(*, "ncol")= int 1413
 - attr(*, "types")=List of 1413
  ..$ : chr "enum" : Factor w/ 72 levels
  ..$ : chr "enum" : Factor w/ 77 levels
  ..$ : chr "enum" : Factor w/ 51 levels
  ..$ : chr "enum" : Factor w/ 4226 levels
  ..$ : chr "enum" : Factor w/ 4183 levels
  ..$ : chr "enum" : Factor w/ 3854 levels
  ..$ : chr "enum" : Factor w/ 3194 levels
  ..$ : chr "enum" : Factor w/ 735 levels
  ..$ : chr "enum" : Factor w/ 133 levels
  ..$ : chr "enum" : Factor w/ 16 levels
  ..$ : chr "enum" : Factor w/ 25 levels
  ..$ : chr "enum" : Factor w/ 647 levels
  ..$ : chr "enum" : Factor w/ 715 levels
  ..$ : chr "enum" : Factor w/ 679 levels
  ..$ : chr "enum" : Factor w/ 477 levels
  ..$ : chr "enum" : Factor w/ 645 levels
  ..$ : chr "enum" : Factor w/ 719 levels
  ..$ : chr "enum" : Factor w/ 678 levels
  ..$ : chr "enum" : Factor w/ 478 levels

上述结果在 v3.10.2.1(写入磁盘的较小模型:169M)和 v3.10.5.1(写入磁盘的较大模型:37G)之间完全相同。

实际GBM训练使用nbins &lt;- 37

numCats <- n_distinct(as.matrix(dplyr::select_(df.train,response)))
numCats
[1] 37

iret <- h2o.gbm(x = predictors, y = response, training_frame = train.hex,
          validation_frame = holdout.hex, distribution="multinomial",
          ntrees = 3000, learn_rate = 0.01, max_depth = 5, nbins = numCats,
          model_id = basename_model)

【问题讨论】:

    标签: r linux h2o


    【解决方案1】:

    模型的大小差异(169M 与 37G)令人惊讶。您能否确保 H2O 将您的所有数字列识别为数字而不是具有非常高基数的分类?

    您是使用自动检测列类型还是手动指定?

    【讨论】:

    • 我在原始问题的正文中回复了您的问题,位于 UPDATE 2: 28Jun2017 以回应 @Michal Kurka 的 cmets。 感谢您对此进行调查.在我们解决这个问题之前,我们无法继续这个项目。
    • 感谢您添加此信息。我们没有观察到其他用户的类似行为。您能否与 H2O 共享数据集的匿名版本,以便我们重现它?
    • 感谢您的回复@Michal Kurka。你介意和Josephine Wang 谈谈吗?她和我过去谈过。与她交谈可能比我可以输入的内容更丰富。如果您愿意,请随时通过语音与我联系。谢谢。
    • 没问题
    • 一个想法:也许模型大小(169M vs 37G)的大幅增加与分类数据中不同值的数量有关?
    猜你喜欢
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 2018-01-02
    相关资源
    最近更新 更多