Fix loading GPU pickle with a CPU-only xgboost distribution. (#8632)

We can handle loading the pickle on a CPU-only machine if the XGBoost is built with CUDA
enabled (Linux and Windows PyPI package), but not if the distribution is CPU-only (macOS
PyPI package).
This commit is contained in:
Jiaming Yuan 2023-01-05 02:14:30 +08:00 committed by GitHub
parent d3ad0524e7
commit 26c9882e23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -28,6 +28,7 @@
#include "xgboost/logging.h" #include "xgboost/logging.h"
#include "xgboost/objective.h" #include "xgboost/objective.h"
#include "xgboost/predictor.h" #include "xgboost/predictor.h"
#include "xgboost/string_view.h"
#include "xgboost/tree_updater.h" #include "xgboost/tree_updater.h"
namespace xgboost { namespace xgboost {
@ -394,23 +395,36 @@ void GBTree::LoadConfig(Json const& in) {
tparam_.process_type = TreeProcessType::kDefault; tparam_.process_type = TreeProcessType::kDefault;
int32_t const n_gpus = xgboost::common::AllVisibleGPUs(); int32_t const n_gpus = xgboost::common::AllVisibleGPUs();
if (n_gpus == 0 && tparam_.predictor == PredictorType::kGPUPredictor) { if (n_gpus == 0 && tparam_.predictor == PredictorType::kGPUPredictor) {
LOG(WARNING) LOG(WARNING) << "Loading from a raw memory buffer on CPU only machine. "
<< "Loading from a raw memory buffer on CPU only machine. "
"Changing predictor to auto."; "Changing predictor to auto.";
tparam_.UpdateAllowUnknown(Args{{"predictor", "auto"}}); tparam_.UpdateAllowUnknown(Args{{"predictor", "auto"}});
} }
auto msg = StringView{
R"(
Loading from a raw memory buffer (like pickle in Python, RDS in R) on a CPU-only
machine. Consider using `save_model/load_model` instead. See:
https://xgboost.readthedocs.io/en/latest/tutorials/saving_model.html
for more details about differences between saving model and serializing.)"};
if (n_gpus == 0 && tparam_.tree_method == TreeMethod::kGPUHist) { if (n_gpus == 0 && tparam_.tree_method == TreeMethod::kGPUHist) {
tparam_.UpdateAllowUnknown(Args{{"tree_method", "hist"}}); tparam_.UpdateAllowUnknown(Args{{"tree_method", "hist"}});
LOG(WARNING) LOG(WARNING) << msg << " Changing `tree_method` to `hist`.";
<< "Loading from a raw memory buffer on CPU only machine. "
"Changing tree_method to hist.";
} }
auto const& j_updaters = get<Object const>(in["updater"]); auto const& j_updaters = get<Object const>(in["updater"]);
updaters_.clear(); updaters_.clear();
for (auto const& kv : j_updaters) { for (auto const& kv : j_updaters) {
std::unique_ptr<TreeUpdater> up( auto name = kv.first;
TreeUpdater::Create(kv.first, ctx_, model_.learner_model_param->task)); if (n_gpus == 0 && name == "grow_gpu_hist") {
name = "grow_quantile_histmaker";
LOG(WARNING) << "Changing updater from `grow_gpu_hist` to `grow_quantile_histmaker`.";
}
std::unique_ptr<TreeUpdater> up{
TreeUpdater::Create(name, ctx_, model_.learner_model_param->task)};
up->LoadConfig(kv.second); up->LoadConfig(kv.second);
updaters_.push_back(std::move(up)); updaters_.push_back(std::move(up));
} }