我想利用分布在许多节点上的多个 GPU 使用 3 个NC12s_v3 计算节点在 Azure 机器学习中的一个非常大的数据集上训练 XGBoost 模型。数据集大小在持久化到 Dask 时超过了 VRAM 和 RAM 大小,但可以舒适地放在磁盘上。但是,XGBoost 的 dask 模块似乎在训练时保留了所有数据(至少默认情况下)。
所有数据预处理都已处理(一种具有 np.bool 数据类型的热编码),并且可以假设我在其他地方拥有最有效的数据类型(例如,将 np.float64 更改为 np.float32 用于十进制特征,更改为 int8 用于序数数据等)。
目前,我正在尝试制作一个仅使用训练集的简单玩具模型。我的代码如下:
from dask_cuda import LocalCUDACluster
import dask
import xgboost as xgb
import pandas as pd
import numpy as np
import distributed
from dask.distributed import Client, wait, LocalCluster
# Start cluster and client. This is currently local, although I would like to make this distributed across many nodes.
cluster = LocalCUDACluster(n_workers=2, device_memory_limit='16 GiB')
client = distributed.Client(cluster)
# Read in training data.
train_dd = dask.dataframe.read_parquet("folder_of_training_data/*.parquet", chunksize="128 MiB")
# Split into features and target, all other preprocessing including one hot encoding has been completed.
X = train_dd[train_dd.columns.difference(['label'])]
y = train_dd['label']
# Delete dask dataframe to free up memory.
del train_dd
# Create DaskDMatrix from X, y inputs.
dtrain = xgb.dask.DaskDMatrix(client, X, y)
# Delete X and y to free up memory.
del X
del y
# Create watchlist for input into xgb train method.
watchlist = [(dtrain, 'train')]
# Train toy booster on 10 rounds with subsampling and gradient based sampling to reduce memory requirements.
bst = xgb.dask.train(
client,
{
'predictor': 'gpu_predictor',
'tree_method': 'gpu_hist',
'verbosity': 2,
'objective': 'binary:logistic',
'sampling_method': 'gradient_based',
'subsample': 0.1
},
dtrain,
num_boost_round=10,
evals=watchlist
)
del dtrain
print("History:", str(bst['history']))
在包含 2 个 GPU 的单个节点上使用上述内容,我一次最多只能加载 32GB(VRAM 的限制)。
从我当前的代码中,我有几个问题:
有什么办法可以阻止 XGBoost 将所有数据持久保存到内存中,而不是分批处理分区?
有什么方法可以让 Dask 本地处理批处理而不是手动执行,例如增量学习?
在他们提到的文档中,您可以使用外部存储器模式及其分布式模式。假设我有 libsvm 文件,我将如何处理多个节点和多个 GPU?
如何更改上面的代码,以便可以使用多个节点?
额外问题:假设有一种方法可以使用 xgboost.dask 进行批处理,我如何将它与 RAPIDS 集成以仅在 GPU 上进行处理?