n_jobs = -1 不使用所有核心的 XGBoost 训练

XGBoost training with n_jobs = -1 not using all cores

我在使用计算机上的所有核心进行 XGBoost 模型的训练和交叉验证时遇到问题。

数据:

data_dmatrix = xgb.DMatrix(data=X,label=y, nthread=-1)
dtrain = xgb.DMatrix(X_train, label=y_train, nthread=-1)
dtest = xgb.DMatrix(X_test, label=y_test, nthread=-1)

型号:

xg_model = XGBRegressor(objective='reg:linear', colsample_bytree= 0.3, learning_rate = 0.2,
                         max_depth = 5, alpha = 10, n_estimators = 100, subsample=0.4, booster = 'gbtree', n_jobs=-1)

如果我用以下方法进行模型训练:

xgb.train(
    xg_model.get_xgb_params(),
    dtrain,
    num_boost_round=500,
    evals=[(dtest, "Test")],
    early_stopping_rounds=200)

它工作正常,但它只使用 1 个线程 运行 xgboost。 处理器是 25%。它忽略 n_jobs=-1

但是如果我使用 scikit-learn 实现进行交叉验证:

scores = cross_val_score(xg_model, X, y, cv=kfold, n_jobs=-1)

比它使用所有核心。 如何强制 xgb.trainxgb.cv 使用所有内核?

Boosting 本质上是一种顺序算法,您只能在训练 1..t 之后训练树 t+1。因此,对于并行化,XGBoost "does the parallelization WITHIN a single tree",如前所述 。使用 max_depth=5,您的树相对较小,因此并行化树构建步骤并不明显。

cross_val_score 然而正在并行训练 K 个不同的 XGBoost 模型 。这些模型彼此完全独立。根据我的经验,这种使用 cross_val_scoreGridSearchCV 的粗粒度并行总是比并行化单个模型更快。

一种替代方法是使用随机森林变体:XGBRFClassifier。与提升算法不同,并且与 cross_val_score 一样,随机森林是 embarrassingly parallel

所选最佳答案中提到的约束似乎不是 XGBoost 的关键问题。我也遇到了 n_jobs = -1 不起作用的问题。显然,这似乎与 XGBoost 中的一个已知问题有关。参见 here

当我将n_jobs设置为我需要的线程数时,发生了多核的使用。使用n_jobs = 16,我现在的训练时间减少了近10倍。