Handle the new device parameter in dask and demos. (#9386)

* Handle the new `device` parameter in dask and demos.

- Check no ordinal is specified in the dask interface.
- Update demos.
- Update dask doc.
- Update the condition for QDM.
This commit is contained in:
Jiaming Yuan
2023-07-15 19:11:20 +08:00
committed by GitHub
parent 9da5050643
commit 16eb41936d
31 changed files with 631 additions and 450 deletions

View File

@@ -32,6 +32,7 @@ class LintersPaths:
"tests/test_distributed/test_with_spark/",
"tests/test_distributed/test_gpu_with_spark/",
# demo
"demo/dask/",
"demo/json-model/json_parser.py",
"demo/guide-python/cat_in_the_dat.py",
"demo/guide-python/categorical.py",
@@ -42,6 +43,8 @@ class LintersPaths:
"demo/guide-python/quantile_regression.py",
"demo/guide-python/multioutput_regression.py",
"demo/guide-python/learning_to_rank.py",
"demo/guide-python/quantile_data_iterator.py",
"demo/guide-python/update_process.py",
"demo/aft_survival/aft_survival_viz_demo.py",
# CI
"tests/ci_build/lint_python.py",

View File

@@ -322,3 +322,15 @@ class TestQuantileDMatrix:
X: np.ndarray = np.array(orig, dtype=dtype)
with pytest.raises(ValueError):
xgb.QuantileDMatrix(X)
def test_changed_max_bin(self) -> None:
n_samples = 128
n_features = 16
csr, y = make_sparse_regression(n_samples, n_features, 0.5, False)
Xy = xgb.QuantileDMatrix(csr, y, max_bin=9)
booster = xgb.train({"max_bin": 9}, Xy, num_boost_round=2)
Xy = xgb.QuantileDMatrix(csr, y, max_bin=11)
with pytest.raises(ValueError, match="consistent"):
xgb.train({}, Xy, num_boost_round=2, xgb_model=booster)

View File

@@ -27,7 +27,7 @@ def train_result(param, dmat, num_rounds):
param,
dmat,
num_rounds,
[(dmat, "train")],
evals=[(dmat, "train")],
verbose_eval=False,
evals_result=result,
)
@@ -169,13 +169,21 @@ class TestTreeMethod:
hist_res = {}
exact_res = {}
xgb.train(ag_param, ag_dtrain, 10,
[(ag_dtrain, 'train'), (ag_dtest, 'test')],
evals_result=hist_res)
xgb.train(
ag_param,
ag_dtrain,
10,
evals=[(ag_dtrain, "train"), (ag_dtest, "test")],
evals_result=hist_res
)
ag_param["tree_method"] = "exact"
xgb.train(ag_param, ag_dtrain, 10,
[(ag_dtrain, 'train'), (ag_dtest, 'test')],
evals_result=exact_res)
xgb.train(
ag_param,
ag_dtrain,
10,
evals=[(ag_dtrain, "train"), (ag_dtest, "test")],
evals_result=exact_res
)
assert hist_res['train']['auc'] == exact_res['train']['auc']
assert hist_res['test']['auc'] == exact_res['test']['auc']

View File

@@ -1349,10 +1349,11 @@ def test_multilabel_classification() -> None:
np.testing.assert_allclose(clf.predict(X), predt)
def test_data_initialization():
def test_data_initialization() -> None:
from sklearn.datasets import load_digits
X, y = load_digits(return_X_y=True)
validate_data_initialization(xgb.DMatrix, xgb.XGBClassifier, X, y)
validate_data_initialization(xgb.QuantileDMatrix, xgb.XGBClassifier, X, y)
@parametrize_with_checks([xgb.XGBRegressor()])

View File

@@ -1,10 +1,9 @@
"""Copyright 2019-2022 XGBoost contributors"""
import asyncio
import os
import subprocess
import json
from collections import OrderedDict
from inspect import signature
from typing import Any, Dict, Type, TypeVar, Union
from typing import Any, Dict, Type, TypeVar
import numpy as np
import pytest
@@ -64,7 +63,7 @@ def run_with_dask_dataframe(DMatrixT: Type, client: Client) -> None:
dtrain = DMatrixT(client, X, y)
out = dxgb.train(
client,
{"tree_method": "gpu_hist", "debug_synchronize": True},
{"tree_method": "hist", "debug_synchronize": True, "device": "cuda"},
dtrain=dtrain,
evals=[(dtrain, "X")],
num_boost_round=4,
@@ -116,12 +115,18 @@ def run_with_dask_array(DMatrixT: Type, client: Client) -> None:
dtrain = DMatrixT(client, X, y)
out = dxgb.train(
client,
{"tree_method": "gpu_hist", "debug_synchronize": True},
{"tree_method": "hist", "debug_synchronize": True, "device": "cuda"},
dtrain=dtrain,
evals=[(dtrain, "X")],
num_boost_round=2,
)
from_dmatrix = dxgb.predict(client, out, dtrain).compute()
assert (
json.loads(out["booster"].save_config())["learner"]["gradient_booster"][
"updater"
][0]["name"]
== "grow_gpu_hist"
)
inplace_predictions = dxgb.inplace_predict(client, out, X).compute()
single_node = out["booster"].predict(xgb.DMatrix(X.compute()))
np.testing.assert_allclose(single_node, from_dmatrix)
@@ -149,7 +154,8 @@ def run_gpu_hist(
DMatrixT: Type,
client: Client,
) -> None:
params["tree_method"] = "gpu_hist"
params["tree_method"] = "hist"
params["device"] = "cuda"
params = dataset.set_params(params)
# It doesn't make sense to distribute a completely
# empty dataset.
@@ -196,11 +202,11 @@ def run_gpu_hist(
def test_tree_stats() -> None:
with LocalCUDACluster(n_workers=1) as cluster:
with Client(cluster) as client:
local = run_tree_stats(client, "gpu_hist")
local = run_tree_stats(client, "hist", "cuda")
with LocalCUDACluster(n_workers=2) as cluster:
with Client(cluster) as client:
distributed = run_tree_stats(client, "gpu_hist")
distributed = run_tree_stats(client, "hist", "cuda")
assert local == distributed
@@ -214,12 +220,12 @@ class TestDistributedGPU:
X_, y_ = load_breast_cancer(return_X_y=True)
X = dd.from_array(X_, chunksize=100).map_partitions(cudf.from_pandas)
y = dd.from_array(y_, chunksize=100).map_partitions(cudf.from_pandas)
run_boost_from_prediction(X, y, "gpu_hist", local_cuda_client)
run_boost_from_prediction(X, y, "hist", "cuda", local_cuda_client)
X_, y_ = load_iris(return_X_y=True)
X = dd.from_array(X_, chunksize=50).map_partitions(cudf.from_pandas)
y = dd.from_array(y_, chunksize=50).map_partitions(cudf.from_pandas)
run_boost_from_prediction_multi_class(X, y, "gpu_hist", local_cuda_client)
run_boost_from_prediction_multi_class(X, y, "hist", "cuda", local_cuda_client)
def test_init_estimation(self, local_cuda_client: Client) -> None:
check_init_estimation("gpu_hist", local_cuda_client)
@@ -282,7 +288,7 @@ class TestDistributedGPU:
)
result = xgb.dask.train(
client,
{"tree_method": "gpu_hist"},
{"tree_method": "hist", "device": "cuda", "debug_synchronize": True},
Xy,
num_boost_round=10,
evals=[(Xy_valid, "Valid")],
@@ -313,7 +319,8 @@ class TestDistributedGPU:
{
"objective": "binary:logistic",
"eval_metric": "error",
"tree_method": "gpu_hist",
"tree_method": "hist",
"device": "cuda",
},
m,
evals=[(valid, "Valid")],
@@ -328,7 +335,8 @@ class TestDistributedGPU:
valid_y = y
cls = dxgb.DaskXGBClassifier(
objective="binary:logistic",
tree_method="gpu_hist",
tree_method="hist",
device="cuda",
eval_metric="error",
n_estimators=100,
)
@@ -356,7 +364,11 @@ class TestDistributedGPU:
run_dask_classifier(X, y, w, model, "gpu_hist", local_cuda_client, 10)
def test_empty_dmatrix(self, local_cuda_client: Client) -> None:
parameters = {"tree_method": "gpu_hist", "debug_synchronize": True}
parameters = {
"tree_method": "hist",
"debug_synchronize": True,
"device": "cuda",
}
run_empty_dmatrix_reg(local_cuda_client, parameters)
run_empty_dmatrix_cls(local_cuda_client, parameters)
@@ -374,7 +386,11 @@ class TestDistributedGPU:
"y": [10, 20, 30, 40.0, 50] * mult,
}
)
parameters = {"tree_method": "gpu_hist", "debug_synchronize": True}
parameters = {
"tree_method": "hist",
"debug_synchronize": True,
"device": "cuda",
}
empty = df.iloc[:0]
ddf = dask_cudf.concat(
@@ -432,13 +448,25 @@ class TestDistributedGPU:
def test_empty_dmatrix_auc(self, local_cuda_client: Client) -> None:
n_workers = len(tm.get_client_workers(local_cuda_client))
run_empty_dmatrix_auc(local_cuda_client, "gpu_hist", n_workers)
run_empty_dmatrix_auc(local_cuda_client, "cuda", n_workers)
def test_auc(self, local_cuda_client: Client) -> None:
run_auc(local_cuda_client, "gpu_hist")
run_auc(local_cuda_client, "cuda")
def test_invalid_ordinal(self, local_cuda_client: Client) -> None:
"""One should not specify the device ordinal with dask."""
with pytest.raises(ValueError, match="device=cuda"):
X, y, _ = generate_array()
m = dxgb.DaskDMatrix(local_cuda_client, X, y)
dxgb.train(local_cuda_client, {"device": "cuda:0"}, m)
booster = dxgb.train(local_cuda_client, {"device": "cuda"}, m)["booster"]
assert (
json.loads(booster.save_config())["learner"]["generic_param"]["device"]
== "cuda:0"
)
def test_data_initialization(self, local_cuda_client: Client) -> None:
X, y, _ = generate_array()
fw = da.random.random((random_cols,))
fw = fw - fw.min()
@@ -531,7 +559,9 @@ async def run_from_dask_array_asyncio(scheduler_address: str) -> dxgb.TrainRetur
y = y.map_blocks(cp.array)
m = await xgb.dask.DaskQuantileDMatrix(client, X, y)
output = await xgb.dask.train(client, {"tree_method": "gpu_hist"}, dtrain=m)
output = await xgb.dask.train(
client, {"tree_method": "hist", "device": "cuda"}, dtrain=m
)
with_m = await xgb.dask.predict(client, output, m)
with_X = await xgb.dask.predict(client, output, X)

File diff suppressed because it is too large Load Diff

View File

@@ -1120,7 +1120,9 @@ class XgboostLocalTest(SparkTestCase):
reg1 = SparkXGBRegressor(**self.reg_params)
model = reg1.fit(self.reg_df_train)
init_booster = model.get_booster()
reg2 = SparkXGBRegressor(max_depth=2, n_estimators=2, xgb_model=init_booster)
reg2 = SparkXGBRegressor(
max_depth=2, n_estimators=2, xgb_model=init_booster, max_bin=21
)
model21 = reg2.fit(self.reg_df_train)
pred_res21 = model21.transform(self.reg_df_test).collect()
reg2.save(path)