1

我想利用分布在许多节点上的多个 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 的限制)。

从我当前的代码中,我有几个问题:

  1. 有什么办法可以阻止 XGBoost 将所有数据持久保存到内存中,而不是分批处理分区?

  2. 有什么方法可以让 Dask 本地处理批处理而不是手动执行,例如增量学习?

  3. 在他们提到的文档中,您可以使用外部存储器模式及其分布式模式。假设我有 libsvm 文件,我将如何处理多个节点和多个 GPU?

  4. 如何更改上面的代码,以便可以使用多个节点?

  5. 额外问题:假设有一种方法可以使用 xgboost.dask 进行批处理,我如何将它与 RAPIDS 集成以仅在 GPU 上进行处理?

4

1 回答 1

2

目前,Dask-XGBoost 希望您的数据驻留在 GPU 内存中。核外溢出到主机内存和增量数据加载的实验工作正在进行中,但现在部署其中之一可能还为时过早。

您使用的是哪个版本的 XGBoost?XGBoost 1.1在许多情况下显着降低了 GPU 内存使用量,因此值得一试。

但是,由于您使用的是云提供商,因此启动更多 GPU 可能是最简单的选择(如果它使您的训练更快,您可以更快地关闭这些实例并保持成本稳定)。

基本上,您将在主节点上启动一个 dask 调度程序,然后在每个工作节点上启动 Dask GPU 工作程序。(例如,通过在每个工作人员上运行 dask-cuda-worker 命令行程序。)

有几个旧教程可以在 Azure 上设置 Dask 集群,但 Tom Drabas 和 AzureML 团队的这个新教程视频可能是最好的起点:https ://www.youtube.com/watch?v=zyDpbH33LXE&feature=youtu .be 它利用 Dask 云提供商来简化集群设置。

于 2020-07-02T17:17:52.200 回答