R:如何在 linux 服务器上使用 parallelMap(与 mlr、xgboost)?与 windows 相比表现出乎意料

R: How to use parallelMap (with mlr, xgboost) on linux server? Unexpected performance compared to windows

我正在尝试在调整超参数级别并行化我在 mlr 中调整的 xgboost 模型并尝试与 parallelMap 并行化。我的代码可以在我的 windows 机器(只有 8 个内核)上成功运行,并且想使用 linux 服务器(有 72 个内核)。迁移到服务器后,我未能成功获得任何计算优势,我认为这是我对 parallelMap 参数的理解存在漏洞的结果。

我不明白 parallelMap 中多核与本地与套接字的区别 "modes"。根据我的阅读,我认为多核适合我的情况,但我不确定。我在我的 windows 机器上成功地使用了套接字,并在我的 linux 服务器上尝试了套接字和多核,但没有成功。

parallelStart(mode="socket", cpu=8, level="mlr.tuneParams")

但据我了解,对于许多不需要相互通信的内核进行并行化,套接字可能是不必要的,或者可能很慢,就像并行化超参数调整的情况一样。

详细说明我在 linux 服务器上的不成功结果:我没有收到错误,但是连续需要 <24 小时的事情并行需要 > 2 周。查看进程,我确实使用了几个内核。

每个人都会在几分钟内调用 xgboost 运行s,我并不想加快速度。我只是想调整多个核心的超级参数。

我担心我的 linux 服务器上的结果非常慢可能是由于 xgboost 试图在模型构建中使用可用的内核,所以我将 nthread = 1 通过mlr 以确保不会发生这种情况。尽管如此,我的代码在较大的 linux 服务器上似乎 运行 比在较小的 windows 计算机上慢得多 -- 关于可能发生的事情有什么想法吗?

非常感谢。

xgb_learner_tune <- makeLearner(
  "classif.xgboost",
  predict.type = "response",
  par.vals = list(
    objective = "binary:logistic",
    eval_metric = "map",
    nthread=1))

library(parallelMap)
parallelStart(mode="multicore", cpu=8, level="mlr.tuneParams")

tuned_params_trim <- tuneParams(
  learner = xgb_learner_tune,
  task = trainTask,
  resampling = resample_desc,
  par.set = xgb_params,
  control = control,
  measures = list(ppv, tpr, tnr, mmce)
)
parallelStop()

编辑

我仍然对我在调整级别尝试并行化时缺乏性能改进感到惊讶。我的期望不公平吗? parallelMap 的性能比以下过程的串行调整要慢得多:

numeric_ps = makeParamSet(
  makeNumericParam("C", lower = 0.5, upper = 2.0),
  makeNumericParam("sigma", lower = 0.5, upper = 2.0)
)
ctrl = makeTuneControlRandom(maxit=1024L)
rdesc = makeResampleDesc("CV", iters = 3L)

#In serial
start.time.serial <- Sys.time()
res.serial = tuneParams("classif.ksvm", task = iris.task, resampling = rdesc,
                 par.set = numeric_ps, control = ctrl)
stop.time.serial <- Sys.time()
stop.time.serial - start.time.serial

#In parallel with 2 CPUs
start.time.parallel.2 <- Sys.time()
parallelStart(mode="multicore", cpu=2, level="mlr.tuneParams")
res.parallel.2 = tuneParams("classif.ksvm", task = iris.task, resampling = rdesc,
                 par.set = numeric_ps, control = ctrl)
parallelStop()
stop.time.parallel.2 <- Sys.time()
stop.time.parallel.2 - start.time.parallel.2

#In parallel with 16 CPUs
start.time.parallel.16 <- Sys.time()
parallelStart(mode="multicore", cpu=16, level="mlr.tuneParams")
res.parallel.16 = tuneParams("classif.ksvm", task = iris.task, resampling = rdesc,
                          par.set = numeric_ps, control = ctrl)
parallelStop()
stop.time.parallel.16 <- Sys.time()
stop.time.parallel.16 - start.time.parallel.16 

我的控制台输出是(省略调整细节):

> stop.time.serial - start.time.serial
Time difference of 33.0646 secs

> stop.time.parallel - start.time.parallel
Time difference of 2.49616 mins

> stop.time.parallel.16 - start.time.parallel.16
Time difference of 2.533662 mins

我原以为并行处理会更快。这个例子不合理吗?如果是这样,我什么时候应该期望并行性能改进?

查看终端,我似乎确实在使用 2(和 16)threads/processes(如果我的术语不正确,请见谅)。

非常感谢任何进一步的输入。

这个问题更多的是猜测你的设置有什么问题,而不是实际提供 "real" 答案。也许你也可以更改标题,因为你没有得到 "unexpected results"。

几点:

  • nthread = 1 已经是 mlr
  • xgboost 的默认值
  • multicore 是 UNIX 系统上的首选模式
  • 如果您的本地机器比您的服务器快,那么要么您的计算完成得非常快并且两者之间的 CPU 频率有很大不同,要么您应该考虑并行化另一个级别而不是 mlr.tuneParams(有关详细信息,请参阅 here

编辑

我的机器上一切正常。看起来像是你这边的本地问题。

library(mlr)
#> Loading required package: ParamHelpers
#> Registered S3 methods overwritten by 'ggplot2':
#>   method         from 
#>   [.quosures     rlang
#>   c.quosures     rlang
#>   print.quosures rlang
library(parallelMap)

numeric_ps = makeParamSet(
  makeNumericParam("C", lower = 0.5, upper = 2.0),
  makeNumericParam("sigma", lower = 0.5, upper = 2.0)
)
ctrl = makeTuneControlRandom(maxit=1024L)
rdesc = makeResampleDesc("CV", iters = 3L)

#In serial
start.time.serial <- Sys.time()
res.serial = tuneParams("classif.ksvm", task = iris.task, resampling = rdesc,
  par.set = numeric_ps, control = ctrl)
#> [Tune] Started tuning learner classif.ksvm for parameter set:
#>          Type len Def   Constr Req Tunable Trafo
#> C     numeric   -   - 0.5 to 2   -    TRUE     -
#> sigma numeric   -   - 0.5 to 2   -    TRUE     -
#> With control class: TuneControlRandom
#> Imputation value: 1
stop.time.serial <- Sys.time()
stop.time.serial - start.time.serial
#> Time difference of 31.28781 secs


#In parallel with 2 CPUs
start.time.parallel.2 <- Sys.time()
parallelStart(mode="multicore", cpu=2, level="mlr.tuneParams")
#> Starting parallelization in mode=multicore with cpus=2.
res.parallel.2 = tuneParams("classif.ksvm", task = iris.task, resampling = rdesc,
  par.set = numeric_ps, control = ctrl)
#> [Tune] Started tuning learner classif.ksvm for parameter set:
#>          Type len Def   Constr Req Tunable Trafo
#> C     numeric   -   - 0.5 to 2   -    TRUE     -
#> sigma numeric   -   - 0.5 to 2   -    TRUE     -
#> With control class: TuneControlRandom
#> Imputation value: 1
#> Mapping in parallel: mode = multicore; level = mlr.tuneParams; cpus = 2; elements = 1024.
#> [Tune] Result: C=1.12; sigma=0.647 : mmce.test.mean=0.0466667
parallelStop()
#> Stopped parallelization. All cleaned up.
stop.time.parallel.2 <- Sys.time()
stop.time.parallel.2 - start.time.parallel.2
#> Time difference of 16.13145 secs


#In parallel with 4 CPUs
start.time.parallel.16 <- Sys.time()
parallelStart(mode="multicore", cpu=4, level="mlr.tuneParams")
#> Starting parallelization in mode=multicore with cpus=4.
res.parallel.16 = tuneParams("classif.ksvm", task = iris.task, resampling = rdesc,
  par.set = numeric_ps, control = ctrl)
#> [Tune] Started tuning learner classif.ksvm for parameter set:
#>          Type len Def   Constr Req Tunable Trafo
#> C     numeric   -   - 0.5 to 2   -    TRUE     -
#> sigma numeric   -   - 0.5 to 2   -    TRUE     -
#> With control class: TuneControlRandom
#> Imputation value: 1
#> Mapping in parallel: mode = multicore; level = mlr.tuneParams; cpus = 4; elements = 1024.
#> [Tune] Result: C=0.564; sigma=0.5 : mmce.test.mean=0.0333333
parallelStop()
#> Stopped parallelization. All cleaned up.
stop.time.parallel.16 <- Sys.time()
stop.time.parallel.16 - start.time.parallel.16 
#> Time difference of 10.14408 secs

reprex package (v0.3.0)

于 2019-06-14 创建