首页 > 解决方案 > 减少 dask XGBoost 内存消耗

问题描述

我正在编写一个简单的脚本代码来在我的数据集上训练一个 XGBoost 预测器。这是我正在使用的代码:

import dask.dataframe as dd
import dask_ml
from dask.distributed import Client, LocalCluster
import sys
from dask_ml.model_selection import train_test_split
import dask
import xgboost
import dask_xgboost

def start_cluster(n_workers=1, threads_per_worker=2, memory_limit="12GB", processes=False):
    cluster = LocalCluster(
        n_workers=n_workers, threads_per_worker=threads_per_worker, memory_limit=memory_limit, processes=processes
    )
    client = Client(cluster)  # use default n_threads and mem
    print(client)
    print(client.cluster)
    print("Client infos:", client.scheduler_info())
    return client

client = start_cluster()

dask_df = dd.read_parquet('./sample_dataset', engine='pyarrow')

dask_df=dask_df.drop(
    ['mapped_tweet_id',
     'mapped_creator_id',
     'mapped_engager_id',
     'engagement_retweet_timestamp',
     'engagement_comment_timestamp',
     'engagement_reply_timestamp',
     'mapped_tweet_links',
     'mapped_domains',
     'mapped_tweet_hashtags'
    ], axis=1
)

y = dask_df['engagement_like_timestamp']>0

dask_df=dask_df.drop(
    [
     'engagement_like_timestamp',
    ], axis=1
)

X_train, X_test, y_train, y_test = train_test_split(dask_df, y, test_size=0.2, shuffle= True)

params = {'objective': 'binary:logistic',
          'max_depth': 4, 'eta': 0.01, 'subsample': 0.5,
          'min_child_weight': 0.5}

bst = dask_xgboost.train(client, params, X_train, y_train, num_boost_round=10)

它运行良好,但我不断收到与 Dask ( distributed.utils_perf - WARNING - full garbage collections took 36% CPU time recently (threshold: 10%))相关的常见垃圾收集器警告

我分析了可用的仪表板,我注意到我的代码一直在增加内存使用量,直到达到 80% 的限制(我更改了 .config 文件夹中的标准设置),然后由于垃圾收集器而开始变慢。

这里有一个例子:

仪表板

它基本上一直这样下去,直到它饱和所有可用内存。我使用的数据集非常大,这就是我使用 Dask 的原因。然而,它似乎基本上是将整个数据集加载到内存中(我不知道这个假设是否正确,但由于读取拼花任务似乎如此)。

代码非常简单,似乎没有什么大问题。

在以下问题(Dask Github Issue )中,图书馆的作者说:

还值得注意的是,此错误消息

Distributed.utils_perf - 警告 - 最近完全垃圾收集占用了 47% 的 CPU 时间(阈值:10%)通常(但不完全)是您正在运行的代码的错误,与 Dask 无关。Dask 正好可以让您知道是否有类似的事情发生。

但是,正如我已经说过的,代码非常简单。

  1. 如何删除此警告?这真的减慢了我的代码的性能
  2. 我正在使用 Dask 来“按块”工作,因为我的数据集太大而无法放入内存。然而,它似乎将所有内容都加载到内存中,这使得 Dask 的使用变得毫无用处。我怎样才能“强制”它按预期工作(块)?

标签: pythondaskxgboostdask-distributeddask-ml

解决方案


请您尝试使用xgboost.dask. XGboost 现在有原生 Dask 支持(请阅读我们的博客)

以下是一些文档: https ://xgboost.readthedocs.io/en/latest/tutorials/dask.html

以下是该网站的一些示例代码:

import xgboost as xgb
import dask.array as da
import dask.distributed

cluster = dask.distributed.LocalCluster(n_workers=4, threads_per_worker=1)
client = dask.distributed.Client(cluster)

# X and y must be Dask dataframes or arrays
num_obs = 1e5
num_features = 20
X = da.random.random(
    size=(num_obs, num_features),
    chunks=(1000, num_features)
)
y = da.random.random(
    size=(num_obs, 1),
    chunks=(1000, 1)
)

dtrain = xgb.dask.DaskDMatrix(client, X, y)

output = xgb.dask.train(client,
                        {'verbosity': 2,
                         'tree_method': 'hist',
                         'objective': 'reg:squarederror'
                         },
                        dtrain,
                        num_boost_round=4, evals=[(dtrain, 'train')])

您能否告诉我们您在哪里提到了之前使用 dask 和 xgboost 的方法?如果它在我们的文档中,我很乐意纠正它!


推荐阅读