RAPIDS 24.12 将 cuDF 包引入 PyPI,加快了 groupby
聚合和从 AWS S3 读取文件的速度,在 Polars GPU 引擎中支持大于 GPU 内存的查询,并加快了真实图形的图形神经网络 (GNN) 训练速度。
cuDF 和 RMM CUDA 12 软件包现在可在 PyPI 上获得
从 24.12 版本的 RAPIDS 开始,rmm
、cudf
、dask-cudf
的 CUDA 12 版本及其所有依赖项现在均可 在 PyPI 上使用 。因此,安装这些库不再需要使用 –extra-index-url
和 pip
的其他配置。试用:
pip install \ 'cudf-cu12==24.12.*' \ 'dask-cudf-cu12==24.12.*'\ 'rmm-cu12==24.12.*' |
这也意味着 Polars 用户无需再在安装期间指定额外的索引即可获得 GPU 支持:pip install polars[gpu]
即可正常工作。
这是通过 pypi.org 提供 RAPIDS 库的持续努力的第一步。敬请关注,了解更多信息。
Polars GPU 引擎:扩展对大数据规模的支持
我们与 Polars 一起在 Open Beta 中推出了基于 cuDF 构建的 Polars GPU 引擎,将加速计算引入到适合 GPU 内存的 Polars 工作负载中。但是,随着数据大小的增加,使用 Polars GPU 引擎处理数据集可能会导致 GPU 内存不足 (OOM) 错误。
24.12 版本引入了两项功能来消除 OOM,同时在大型数据集大小下保持出色性能:分块 IO 和 CUDA 统一内存。
分块 IO
首先,cudf-polars
现在以块 (默认为每个块 8 GiB) 处理 parquet 文件,同时保持高解压缩和解码吞吐量。
压缩文件需要在内存中进行扩展,这可能会导致一些工作负载在 IO 期间显存不足,而如果数据位于内存中,这些工作负载就会成功。这对于 ZSTD 压缩尤其重要,因为实际内存占用通常是文件大小的 3 倍。
分块 IO 可减少此峰值内存压力,助力更多工作负载取得成功。
CUDA 统一显存
其次,此版本在 cudf-polars
中默认启用预取的托管内存池,这与之前在 cudf.pandas
中完成的工作类似。有关更多详细信息,请参阅使用 RAPIDS cuDF 在 pandas 中扩展至十亿行数据。
统一内存使 DataFrames 能够在 GPU 和主机内存之间进行扩展,高效处理通过 GPU 互连 (PCIe 或 C2C) 进行的数据迁移,实现无缝处理。
借助 Unified Memory 和 prefetching,Polars GPU 引擎现在可以处理更大的数据集,而不会出现显存不足的情况。
PDS-H 基准测试
在上一版本中,随着 Scale Factor(数据集大小)超过 80 GB 或 100 GB,许多使用 Polars GPU 引擎运行的 PDS-H 基准查询将在 NVIDIA H100 GPU 上显存不足。
借助这些增强功能,Polars GPU 引擎现在可以高效处理适合 GPU 和 CPU 组合显存但之前会导致 GPU OOM 错误的工作负载。
图 1 比较了使用 RAPIDS 24.10 和 24.12 在 PDS-H 基准测试中进行的 22 次查询中 Polars GPU 与 Polars CPU 引擎的加速比。根据对 Scale Factors 的扫描,先前因 OOM 而失败的查询现已成功。与仅使用 CPU 的基础设施相比,更新后的引擎现在可以大幅加速,甚至可提升至 Scale Factor 250 (250 GB)。
GPU:NVIDIA H100|CPU:双路英特尔 Xeon 8480CL (Sapphire Rapids)|存储:本地 NVMe。注意:PDS-H 源自 TPC-H,但这些结果无法与 TPC-H 结果进行比较。
cuDF 性能改进
RAPIDS 24.12 还包括两项性能优化,旨在改善大规模数据处理工作流程。
cuDF 中更快的低基数 groupby
此版本包括针对 cuDF 中基于哈希的 groupby
聚合的新优化。以前,处理低基数 (少量组) 的 groupby
聚合会导致吞吐量相对较低。
吞吐量较低的原因是当组数量低于 100 时发生原子争用。现在,通过使用 GPU 共享内存来追踪部分聚合,可以避免此瓶颈。
以下代码示例展示了此效果的实际应用:
import cudf, cupy, rmm import time rmm.mr.set_current_device_resource(rmm.mr.CudaAsyncMemoryResource()) df = cudf.DataFrame({ 'key' : cupy.ones( 100_000_000 ), 'payload' : cupy.random.rand( 100_000_000 ), }) for _ in range ( 3 ): t0 = time.time() g = df.groupby( 'key' ).agg({ 'payload' : 'sum' }).reset_index() t1 = time.time() print (f 'cudf {cudf.__version__}: {t1-t0:0.3f} seconds' ) cudf 24.10 . 01 : 0.177 seconds cudf 24.12 . 01 : 0.012 seconds pandas 2.2 . 3 : 1.463 seconds |
在配备 NVIDIA H100 GPU 和 Intel Xeon Platinum 8480CL CPU 的系统上执行,可在此用例中将 cuDF 24.10 至 24.12 的速度提高 15 倍。
此优化对于 Spark 和 Dask 用户特别有用,因为在这些用户中,大型工作负载可能需要对少量类别得出聚合结果。
AWS S3 提供更快的 IO (远程存储)
cuDF 24.12 为 cuDF 和 Dask-cuDF 引入了新的可选择功能,用于多线程 S3 对象读取。
新功能基于 KvikIO 中用于管理 S3 对象读取的 libcurl 用法,可显著提高 Dask cuDF 中 S3 读取的整体性能和可扩展性。可以使用 CUDF_KVIKIO_REMOTE_IO
环境变量启用,并使用 KVIKIO_NTHREADS
进行控制。
在图 2 中,KvikIO (通过 CUDF_KVIKIO_REMOTE_IO=ON
) 用于将 Red-Pajama v2 数据集的子集从 S3 存储桶读取到具有不同线程数的 4-GPU g5.12xlarge EC2 实例。
在这种情况下,KVIKIO_NTHREADS=128
的总吞吐量为 963 MiB/s,而不使用 KvikIO 的总吞吐量为 450 MiB/s。
由于每个工作负载都不同,因此线程数量是可配置的。我们目前正在研究一系列数据集和系统中的适当默认配置,因此此功能目前可供用户选择,但可广泛使用。
在 WholeGraph 中通过基于层次结构的集合加快 GNN 训练速度
此版本还通过专为 power-law 图形设计的新通信优化,显著提升了 WholeGraph 的性能。
定律图的度数分布与图 3 所示相似。大多数顶点的度数很小 (许多顶点只有一个近邻),而一些顶点的度数非常高且高度连接。大多数真实图形都属于这一类。
对幂律图进行采样时,最高度顶点可以在批量中多次出现。对于 ogbn-papers100M 数据集,使用 8 个 GPU 进行训练时,重复顶点的百分比最高可达 70%。
通过仅读取重复顶点的特征张量一次,我们可以在特征获取阶段节省大量时间。这称为基于层次结构的收集操作,而不是默认的分布式收集操作。
在这些场景中,使用基于层次结构的收集操作可获得比分布式收集操作高 2 倍的速度。更快的采集步骤可为批量大小为 1,024 的三层 GraphSAGE 模型提供约 30-40% 的端到端加速。
系统:NVIDIA DGX H100
结束语
RAPIDS 24.12 版本为 DataFrame 分析和 GNN 训练带来了显著的用户体验改进和性能优化。Polars GPU 引擎处于 Open Beta 阶段,多线程 AWS S3 文件读取处于实验阶段。欢迎您向 GitHub 提供反馈。您还可以加入 RAPIDS Slack 社区 的 3,500+ 名成员,讨论 GPU 加速的数据处理。
如果您不熟悉 RAPIDS,请查看这些 资源以开始使用 。