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 创建
我正在尝试在调整超参数级别并行化我在 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
中 multicore
是 UNIX 系统上的首选模式- 如果您的本地机器比您的服务器快,那么要么您的计算完成得非常快并且两者之间的 CPU 频率有很大不同,要么您应该考虑并行化另一个级别而不是
mlr.tuneParams
(有关详细信息,请参阅 here)
xgboost
的默认值
编辑
我的机器上一切正常。看起来像是你这边的本地问题。
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 创建