我在 8 核 Linux 上使用以下代码,它需要所有 8 个内核(6 个工作线程中的每一个都占用 130% 的利用率(
library(mlr); library(parallel); library(parallelMap)
# Load data
iris_num <- iris; iris_num$Species <- as.numeric(iris_num$Species)
#create tasks
traintask <- makeRegrTask(data = iris_num, target = 'Species')
#create learner
lrn = makeLearner('regr.xgboost'); nthread <- min(6, detectCores());
lrn$par.vals = list(print.every.n = 500, objective = "reg:linear", eval_metric="rmse", nthread = nthread)
#set parameter space
params <- makeParamSet(
makeIntegerParam("max_depth",lower = 5L,upper = 20L), # 6
makeNumericParam("min_child_weight",lower = 1L,upper = 20L), # 1
makeNumericParam("subsample",lower = 0.5,upper = 1),
makeNumericParam("colsample_bytree",lower = 0.5,upper = 1),
makeIntegerParam("nrounds",lower=3000,upper=5000),
makeNumericParam("lambda",lower=0.75,upper=1),
makeNumericParam("lambda_bias",lower=0,upper=0.75),
makeNumericParam("gamma",lower=0,upper=1),
makeNumericParam("eta", lower = 0.01, upper = 0.05) # 0.3
)
#set resampling strategy
rdesc <- makeResampleDesc("CV",iters=9L)
#search strategy
ctrl <- makeTuneControlRandom(maxit = 10L)
#set parallel backend
if(Sys.info()['sysname'] == "Linux") {
parallelStartMulticore(cpus = nthread, show.info = T)
} else parallelStartSocket(cpus = nthread, show.info = T)
tune <- tuneParams(learner = lrn, task = traintask,resampling = rdesc,measures = rmse, par.set = params, control = ctrl, show.info = T)
如何确保 MLR 仅采用 6 核
MLR 无法控制学习器在内部执行的操作 - 如果它们是并行的,您最终将使用更多内核。为了安全起见,请只给它例如 4 个内核。
nthread <- min(6, detectCores())
这里的这一行将立即执行,并将始终在 8 核机器上返回 6。您可以在 xgboost 模型和调优中使用此行。您的 6 个调优线程中的每一个都将尝试创建一个需要 6 个线程的 xgboost 模型。所以你在一台 8 核机器上制作 36 个线程。
我不知道有什么方法可以让 mlr(或任何东西(尊重"未使用"内核的数量。如果你知道你有一台 6 核机器,我建议手动分解它。例如,给 tuneParams 2 个线程,给每个 xgboost 模型 2 个线程。由于 tuneparams 进程将处于空闲状态并等待来自 xgboost 模型的回复,因此您可能会为 xgboost 模型提供 3 个线程。