python - 减少 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 正好可以让您知道是否有类似的事情发生。
但是,正如我已经说过的,代码非常简单。
- 如何删除此警告?这真的减慢了我的代码的性能
- 我正在使用 Dask 来“按块”工作,因为我的数据集太大而无法放入内存。然而,它似乎将所有内容都加载到内存中,这使得 Dask 的使用变得毫无用处。我怎样才能“强制”它按预期工作(块)?
解决方案
请您尝试使用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 的方法?如果它在我们的文档中,我很乐意纠正它!
推荐阅读
- r - 如果用户写入超过 1 列,如何从 Shiny 的数据框中选择列?
- php - 客户端生成的唯一 ID 与数据库唯一 ID
- java - 为什么while循环的经过时间值小于错误时间总和?
- outlook - 用户打开电子邮件时激活功能的 Outlook 插件
- email - 将 cpanel 电子邮件服务器与 Gsuite 一起使用
- php - 不推荐使用:不推荐使用 each() 函数。此消息将在进一步调用时被隐藏
- php - 使用 Symfony 客户端发出 localhost API 请求?
- python - numpy.lib.format.open_memmap 不存储数据
- spring - 创建一个虚拟实体来存储来自不同表的数据
- unity3d - 属性“Raycast target”在动画中不起作用