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

@@ -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)