用于数据处理的低端GPU与中端CPU

2024-09-30 01:29:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前有一些简单的数据处理,包括groupby、merge和parallel列到列操作。不那么简单的部分是所使用的大量行(其详细的成本/财务数据)。它的大小为300-400GB

由于RAM有限,目前im使用带dask的核心外计算。然而,它真的很慢

我以前读过使用CuDF来提高map_分区和groupby的性能,但是大多数示例都使用中高端gpu(至少1050ti,大多数运行在基于gv的云vm上),数据可以放在gpu RAM上

我的机器规格是E5-2620v3(6C/12T)、128gb和K620(只有2gb专用vram)

使用的中间数据框存储在拼花地板中

如果我使用CuDF的低端GPU,它会更快吗?有可能在GPU中进行核心外计算吗?(例如,我四处寻找,但尚未找到)

下面是我试图做的简化的伪代码

a.csv是大小约为300gb的数据,由3列(Hier1、Hier2、Hier3、值)组成。Hier1-3是字符串层次结构。价值是销售价值 b、 csv是大小约为50gb的数据,由3列组成(Hier1、Hier2、valuetype、cost)。层次结构1-2是字符串形式的层次结构。值类型是字符串形式的成本类型。成本就是成本价值

基本上,我需要根据a.csv中的销售价值,对b.csv中的每个成本按比例进行自上而下的计算。我想说的是,我的每一项成本都在三级(更详细的一级)中提供

第一步是创建按比例分配的比率:

import dask.dataframe as dd
# read raw data, repartition, convert to parquet for both file
raw_reff = dd.read_csv('data/a.csv')
raw_reff = raw_reff.map_partitions(lambda df: df.assign(PartGroup=df['Hier1']+df['Hier2']))
raw_reff = raw_reff.set_index('PartGroup')
raw_reff.to_parquet("data/raw_a.parquet")

cost_reff = dd.read_csv('data/b.csv')
cost_reff = cost_reff.map_partitions(lambda df: df.assign(PartGroup=df['Hier1']+df['Hier2']))
cost_reff = cost_reff.set_index('PartGroup')
cost_reff.to_parquet("data/raw_b.parquet")

# create reference ratio
ratio_reff = dd.read_parquet("data/raw_a.parquet").reset_index()

#to push down ram usage, instead of dask groupby im using groupby on each partition. Should be ok since its already partitioned above on each group

ratio_reff = ratio_reff.map_partitions(lambda df: df.groupby(['PartGroup'])['value'].sum().reset_index())
ratio_reff = ratio_reff.set_index('PartGroup')
ratio_reff = ratio_reff.map_partitions(lambda df: df.rename(columns={'value':'value_on_group'}))
ratio_reff.to_parquet("data/reff_a.parquet")

然后进行合并以得到比率

raw_data = dd.read_parquet("data/raw_a.parquet").reset_index()
reff_data = dd.read_parquet("data/reff_a.parquet").reset_index()
ratio_data = raw_data.merge(reff_data, on=['PartGroup'], how='left')
ratio_data['RATIO'] = ratio_data['value'].fillna(0)/ratio_data['value_on_group'].fillna(0)
ratio_data = ratio_data[['PartGroup','Hier3','RATIO']]
ratio_data = ratio_data.set_index('PartGroup')
ratio_data.to_parquet("data/ratio_a.parquet")

然后合并并乘以零件组上的成本数据与比率,以获得其按比例分配的值

reff_stg = dd.read_parquet("data/ratio_a.parquet").reset_index()
cost_stg = dd.read_parquet("data/raw_b.parquet").reset_index()
final_stg = reff_stg.merge(cost_stg, on=['PartGroup'], how='left')
final_stg['allocated_cost'] = final_stg['RATIO']*final_stg['cost']
final_stg = final_stg.set_index('PartGroup')
final_stg.to_parquet("data/result_pass1.parquet")

在实际情况中,由于缺少参考数据等原因会产生残值,并且会使用多个参考在多个过程中完成,但基本上以上就是步骤

即使是严格的拼花地板到拼花地板的操作,它仍然占用了我128gb内存中约80gb的内存,我所有的核心运行100%,还有3-4天的运行时间。我在寻找用当前硬件更快完成这项工作的方法。正如您所看到的,它的大规模并行问题符合基于gpu的处理的定义

谢谢


Tags: csvtodfreaddataindexrawdd
1条回答
网友
1楼 · 发布于 2024-09-30 01:29:57

@同上,不幸的是,这无法用您当前的硬件完成。您的K620具有开普勒架构GPU,并且低于激流的最低要求。你需要一张帕斯卡卡或更好的卡才能跑急流。好消息是,如果购买与RAPIDS兼容的视频卡不是可行的选择,那么有许多便宜的云资源调配选项。老实说,你要做的是,我想要一点额外的GPU处理速度,并建议使用多GPU设置

对于比GPU RAM更大的数据集,可以使用dask_cudf来处理数据集。我们的文档和笔记本中有几个例子。请注意,dask.compute()之后的结果数据集需要能够适应GPU RAM

https://rapidsai.github.io/projects/cudf/en/0.12.0/10min.html#10-Minutes-to-cuDF-and-Dask-cuDF

https://rapidsai.github.io/projects/cudf/en/0.12.0/dask-cudf.html#multi-gpu-with-dask-cudf

一旦你能建立起一个可工作的、快速兼容的多GPU并使用dask_cudf,你就应该在加速的同时得到一个非常值得的结果,特别是对于这种规模的数据探索

希望这有帮助

相关问题 更多 >

    热门问题