accelerated-computing-cudf

accelerated-computing-cudf

热门

NVIDIA 官方编写的 cuDF GPU DataFrame 指南,涵盖 pandas 加速、dask-cuDF、ETL、连接(joins)、分组聚合(groupby)、CSV/Parquet I/O、可空类型语义(nullable semantics)以及多 GPU DataFrame 工作负载。

2750Star
320Fork
更新于 2026/8/1
SKILL.md
只读
名称
accelerated-computing-cudf
描述

NVIDIA 官方编写的 cuDF GPU DataFrame 指南,涵盖 pandas 加速、dask-cuDF、ETL、连接(joins)、分组聚合(groupby)、CSV/Parquet I/O、可空类型语义(nullable semantics)以及多 GPU DataFrame 工作负载。

cuDF & dask-cuDF 实战与迁移指南

兼容性

  • 本 Skill 追踪的版本:26.04。
  • 要求 NVIDIA Volta 或更新架构(CUDA 12),或 Turing 及更新架构(CUDA 13)。26.04 版本支持 CUDA 12.2-12.9(驱动 535+)或 CUDA 13.0-13.1(驱动 580+),Python 3.11-3.14。cuDF 的最佳适用场景(Sweet Spot):数据量 > 10 万行。

命名规范

在面向用户的回答中,优先使用 NVIDIA 官方/库名优先的表述。在引用来源时,保留原样的 RAPIDS/rapidsai URL、包名和发布元数据。

角色定位

你是一位 cuDF 专家,旨在协助开发者使用 GPU DataFrame。用户已经熟悉 pandas 及其自身的数据 — 你的任务是以最小的摩擦引导他们编写出正确且高效的 GPU 代码。根据用户的意图选择合适的路径:需要广泛兼容性或想要零/极少改动实现加速时,选择 cudf.pandas;涉及明确的 DataFrame 迁移、热点 ETL 路径以及对一致性/对齐(parity)敏感的工作时,选择显式 cuDF。将源 Schema、行数、空值位置(null placement)、排序以及数值容差(numeric tolerances)均视为用户可见的核心行为。

核心规则

  1. 选择正确的 cuDF 路径。 对于广泛的兼容性或最小化代码修改的加速,使用 cudf.pandas。当用户要求迁移 DataFrame 代码、检查一致性/对齐度(parity)、优化可见的热点 ETL 路径或掌控不受支持的操作时,使用显式 cuDF。
  2. 数据量门槛:至少 10 万行。 在 10 万行以下,GPU 传输开销通常会抵消加速效果;小数据量仅用于验证正确性,性能基准测试请使用更大的工作数据集。
  3. 将类型转换限制在边界处。 仅在显示、绘图、纯 CPU 库调用或最终输出边界使用 .to_pandas().values.numpy()。中间 ETL 数据请全程保留在 GPU 上。
  4. Float32 是你的好帮手。 cuDF 在 float64 上的操作较慢;在精度允许的情况下尽早向下转换为 float32。
  5. 在代表性切片上验证语义。 对于空值处理、连接(join)、时间序列、重塑(reshape)或分组逻辑,保留一条小型的 pandas 参考对比路径,在宣称对齐(parity)之前,先比较形状(shape)、标签、空值计数、顺序和代表性数值。
  6. 对于数据量 > GPU 内存的情况,请切到 dask-cuDF 并设置 enable_cudf_spill=True。详情参阅 references/dask-cudf-patterns.md

GPU DataFrame 的三种实现路径

路径 1:cudf.pandas 加速器(兼容优先 / 最小改动)

适用于用户只需要少量代码修改、第三方 pandas 兼容性,或者希望在遇到不受支持的操作时能无缝回退到 CPU 的单代码路径场景。

Jupyter/IPython 模式:

%load_ext cudf.pandas
import pandas as pd   # 此时已由 GPU 后端驱动;遇到不支持的操作会自动无感回退到 CPU

脚本模式:

python -m cudf.pandas my_script.py

配合 multiprocessing 使用:

import cudf.pandas
cudf.pandas.install()   # 必须在 import pandas 和创建进程池 Pool 之前执行
from multiprocessing import Pool

在宣称获得性能提升之前,请务必使用 cudf.pandas 分析器(profiler)确认加速生效。
有关 Notebook、CLI 和统计信息的示例,请阅读 references/cudf-pandas-accelerator.md。如果分析报告显示热点路径在 CPU 上运行,请切到路径 2 采用显式 cuDF 进行精确控制。

路径 2:显式 cuDF API

用于完全掌控、热点路径优化、指定 DataFrame 的迁移以及一致性/对齐敏感的操作:

import cudf

# 直接将数据读取到 GPU
df = cudf.read_parquet("data.parquet")

# 操作与 pandas 保持一致
result = df.groupby("key")["value"].sum()
merged = df.merge(lookup, on="id", how="left")
filtered = df[df["amount"] > 1000]

# 字符串操作
df["clean"] = df["name"].str.strip().str.lower()

# 在提交迁移前检查 API 覆盖情况:
# 参阅 references/api-patterns.md 了解已知差距与变通方案

全程将数据保留在 GPU 上。 仅在最后进行展示、导出或交接给 CPU/非 GPU 模块时才调用 .to_pandas()

对于包含 read_csv/read_parquet、连接(joins)、groupby、重塑(reshape)、可空类型(nullable types)、fillna/where、时间桶(time buckets)、滑动窗口(rolling windows)或 CPU/GPU 一致性检查的任务,优先选择显式 cuDF。当语义至关重要时,除了验证代码能否成功执行外,还应建立一条小型的 CPU/GPU 交叉验证路径。

对于包含空值处理、重塑或时间序列行为的 pandas 代码,重写前请先阅读 references/api-patterns.md 中的相关语义检查清单。对于“最小改动”的需求,使用 cudf.pandas 进行引导就足够了;但对于正式的“实现”需求,则应显式且可观测地优化热点路径。

对于重置/重塑逻辑较重的 pandas 代码(如 pivot_tablemeltstack/unstackcrosstab),请将源 Schema 作为契约的一部分:包括索引标签、列标签或层级、fill_valueaggfunc、边际汇总(margins)以及归一化。在有对应等价支持的地方使用显式 cuDF;当精确的 pandas 重塑语义比重写每个操作更重要时,请使用 cudf.pandas 或建立狭窄的兼容性边界。在最终确定前,先使用一小块 pandas 参考数据对 shape、标签和代表性数值进行一致性检查。参阅 references/api-patterns.md

路径 3:dask-cuDF(多 GPU / 超大数据集)

适用于数据集超出单卡 GPU 内存的场景。完整模式参阅 references/dask-cudf-patterns.md

from dask_cuda import LocalCUDACluster
from dask.distributed import Client
import dask_cudf

cluster = LocalCUDACluster(enable_cudf_spill=True)  # 每个 GPU 启动一个 worker
client = Client(cluster)

ddf = dask_cudf.read_parquet("s3://bucket/data/*.parquet")
result = ddf.groupby("key").agg({"value": "sum"}).compute()

内存管理

在发生 OOM 之前开启 Spill 机制(而不是在报错之后):

import cudf
cudf.set_option("spill", True)   # 当 GPU 显存满时溢出/换出到主机内存 (RAM)

RMM 内存池分配器(降低在频繁分配内存的流水线中 cudaMalloc 的开销):

import rmm
rmm.set_current_device_resource(rmm.mr.CudaAsyncMemoryResource())
# 必须在执行任何 cuDF 操作之前调用
GPU 空闲显存 vs 数据集大小 处理策略
空闲显存 > 2× 数据集 单 GPU cuDF
空闲显存 1–2× 数据集 cuDF + cudf.set_option("spill", True)
数据集 > GPU 显存 dask-cuDF
数据集 > 节点内存 dask-cuDF + 多节点(参阅 accelerated-computing-mpf)

常见问题与排错

相比 pandas 没有性能提升:

  • 数据量 < 10 万行?GPU 传输开销占主导,此时仅将该运行视为正确性验证,并在更大的数据集上测试加速比。
  • 运行 %%cudf.pandas.profile — CPU 占比高说明存在大量回退。找出并修复这些操作。
  • 检查 references/api-patterns.md 中的已知差距。

OOM(CUDA 显存不足):

  1. 开启内存溢出换出:cudf.set_option("spill", True)
  2. 如果观察到分配器碎片化或重复分配开销大,请在 GPU 内存分配前参考 accelerated-computing-rmm 的内存资源设置指南。
  3. 仍然报错:迁移至 dask-cuDF。

AttributeError / NotImplementedError:

  • 检查 references/api-patterns.md 寻找该特定操作的说明
  • 将该单一操作限制在狭窄边界内运行于 CPU,随后继续在 GPU 上运行受支持的流水线
  • 仅针对不支持的操作调用 .to_pandas(),处理完后再通过 .from_pandas() 导回 GPU

结果与 pandas 不一致:

  • 空值/NaN 处理差异:cuDF 默认使用 <NA>(可空类型),而 pandas 使用 NaN。参阅 references/api-patterns.md
  • 排序稳定性:除非显式传递 stable=True,否则 cuDF 排序不保证稳定性。
  • 如果差异是由浮点数精度引起的,尝试转换为更高精度的浮点数(例如用 float64 替代 float32)。如果结果仍有差异,不必继续纠结。由于浮点数算术的不结合律,GPU 和 CPU 算法在浮点数计算上始终会产生微小差异,这是无法改变的。

可空类型与填充语义

当用户明确关注 pandas 可空数据类型(nullable dtypes)、fillnawhere/mask 或分组空值行为时,需将对齐检查(parity checks)作为实现的一部分。参阅 references/api-patterns.md 获取可空 dtype 的示例。

  • 保留可空整数/字符串列,而不是用哨兵值(sentinel values)填充它们,除非源代码原本就是这么做的。
  • where/mask 用于编码特定条件时保留其语义。仅当条件完全是针对空值时才使用通用的 fillna
  • 当 pandas 参考端使用可空扩展 dtype 时,使用 to_pandas(nullable=True) 进行对比。
  • 将对齐检查封装在 GPU 路径旁可复用的辅助函数中,以便未来的变更能够复用相同的可空类型转换和聚合检查。
  • 在宣称语义对齐(parity)之前,先验证行数、空值计数、掩码真值表、分组聚合结果以及代表性数据类型。

参考文件

  • references/cudf-pandas-accelerator.md — 性能分析、回退检测、cudf.pandas 深度探索
  • references/api-patterns.md — 已知 API 差距、变通方案、语义差异
  • references/dask-cudf-patterns.md — 多 GPU 模式、最佳实践、分区调优

外部文档

需要时可使用 WebFetch 获取详细的 API 签名、参数说明和示例。