运行 xgboost 在多个 R 进程中的问题

Issues with running xgboost in multiple R processes

同时在多个 R 进程中使用 运行ning xgboost 是否存在任何已知问题?

背景是我正在尝试对最佳超参数进行简单的网格搜索。由于我在这台机器上有多个内核,我想我会 运行 并行处理模型。但是,xgb.DMatrix 死于错误:

> cl <- makeCluster(4)
> clusterEvalQ(cl, {
+     load("processed_data.rdata")
+     library(xgboost)
+     traindata <- xgb.DMatrix(as.matrix(train_df), label=train_y)
+     testdata <- xgb.DMatrix(as.matrix(test_df), label=test_y)
+ })
[[1]]
Error in dim.xgb.DMatrix(x) :
  [12:59:39] amalgamation/../src/c_api/c_api.cc:355: DMatrix/Booster has not been intialized or has already been disposed.

似乎不​​允许将 xgboost 代码加载到多个进程中。这个对吗?如果是这样,进行并行网格搜索的最佳方法是什么?

我的会话信息:

R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)

Matrix products: default

locale:
[1] LC_COLLATE=English_Australia.1252  LC_CTYPE=English_Australia.1252
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C
[5] LC_TIME=English_Australia.1252    

attached base packages:
[1] parallel  stats     graphics  grDevices utils     datasets  methods
[8] base

other attached packages:
[1] purrr_0.3.4     xgboost_1.2.0.1 tidyr_1.1.2     dplyr_1.0.2

loaded via a namespace (and not attached):
 [1] magrittr_2.0.1    tidyselect_1.1.0  lattice_0.20-41   R6_2.5.0
 [5] rlang_0.4.9       fansi_0.4.1       tools_4.0.3       grid_4.0.3
 [9] data.table_1.13.2 utf8_1.1.4        cli_2.2.0         ellipsis_0.3.1
[13] assertthat_0.2.1  tibble_3.0.4      lifecycle_0.2.0   crayon_1.3.4     
[17] Matrix_1.2-18     vctrs_0.3.5       glue_1.4.2        stringi_1.5.3    
[21] compiler_4.0.3    pillar_1.4.7      generics_0.1.0    pkgconfig_2.0.3

您在 load() 行上有一个额外的 )。否则,

也许将任务分解成不连续的步骤会奏效吗?

library(xgboost)
load("processed_data.rdata")
cl <- makeCluster(4)
clusterEvalQ(cl, {
  traindata <- xgb.DMatrix(as.matrix(train_df), label=train_y)
})
clusterEvalQ(cl, {
  testdata <- xgb.DMatrix(as.matrix(test_df), label=test_y)
})

解决了。根据 R 中的约定,clusterEvalQ 使用最后计算的表达式的值作为返回到头节点的值。这是通过将值序列化到 worker 和 head 之间的管道中,然后再次反序列化来完成的。但是,xgb.DMatrix 不能像常规 R 对象那样序列化,因为它包含外部指针;试图反序列化它会导致错误。

解决方案是将传递给 clusterEvalQ 的表达式的最后一行作为 xgb.DMatrix 调用以外的任何内容。 NULL 会做:

> clusterEvalQ(cl, {
+     load(file.path(local_dir, "processed_data.rdata")
+     library(xgboost)
+     traindata <- xgb.DMatrix(as.matrix(train_df), label=train_y)
+     testdata <- xgb.DMatrix(as.matrix(test_df), label=test_y)
+     NULL
+ })
[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

[[4]]
NULL