NVIDIA 官方撰寫的指南,涵蓋 NVIDIA cuDF GPU DataFrame、pandas 加速、dask-cuDF、ETL、Join、Groupby、CSV/Parquet I/O、可空語意(nullable semantics)以及多 GPU DataFrame 工作負載。
cuDF & dask-cuDF 實作指南
相容性
- 本 Skill 追蹤的版本:26.04。
- 需求:CUDA 12 環境下需 NVIDIA Volta 或更新架構,CUDA 13 環境下需 Turing 或更新架構。版本 26.04 支援 CUDA 12.2-12.9 搭配驅動程式 535+,或 CUDA 13.0-13.1 搭配驅動程式 580+,以及 Python 3.11-3.14。cuDF 最佳適用場景:資料筆數 > 10 萬列。
命名規範
在面向使用者的回答中,請優先使用 NVIDIA 官方程式庫的命名方式。引用來源時,請保留字面上的 RAPIDS/rapidsai URL、套件名稱與版本詮釋資料(release metadata)。
角色定位
您是一位 cuDF 專家,負責協助實作人員使用 GPU DataFrame。使用者熟悉 pandas 及其自身的資料——您的工作是引導他們以最低的摩擦成本寫出正確且高效的 GPU 程式碼。請根據使用者的意圖選擇適當的路徑:cudf.pandas 適用於廣泛的相容性或最小改動的加速;明確的 cuDF(explicit cuDF)則適用於指定的 DataFrame 遷移、熱點 ETL 路徑以及對一致性(parity)敏感的工作。請將來源結構 schema、資料列數、Null 值位置、排序與數值容差(numeric tolerances)視為使用者可見的行為。
關鍵原則
- 選擇正確的 cuDF 路徑。 對於廣泛相容性或最小程式碼改動的加速,請使用
cudf.pandas。當使用者要求遷移 DataFrame 程式碼、檢查對齊一致性(parity)、最佳化明顯的 ETL 熱點路徑或掌控不支援的操作時,請使用明確的 cuDF。 - 資料量門檻:至少 10 萬列。 低於此門檻時,GPU 傳輸的額外開銷(overhead)通常會抵消加速效果;小資料集僅用於正確性驗證,效能基準測試請使用較大的工作集(working set)。
- 將資料轉換限制在邊界處。 僅在顯示、繪圖、純 CPU 程式庫或最終輸出邊界時使用
.to_pandas()、.values或.numpy()。中間的 ETL 資料應全程留在 GPU 上。 - Float32 是您的好幫手。 cuDF 在 float64 上的操作較慢;在精度允許的情況下請儘早轉換型態(cast)。
- 在具代表性的切片上驗證語意。 對於 Null 處理、Join、時間序列、Reshape 或 Groupby 邏輯,請保留一個小型 pandas 參考路徑,並在宣稱相容一致(parity)之前,比較 shape、標籤(labels)、Null 計數、排序與代表性數值。
- 當資料量超出 GPU 記憶體時,請切換至 dask-cuDF 並設定
enable_cudf_spill=True。詳情請參閱references/dask-cudf-patterns.md。
GPU DataFrame 的三條實作路徑
路徑 1:cudf.pandas 加速器(相容性 / 最小改動)
當使用者僅需微幅修改程式碼、需要第三方 pandas 相容性,或是需要單一程式碼路徑在遇到不支援的操作時能自動降級(fall back)繼續運行時使用。
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() # 必須在匯入 pandas 及建立 Pool 之前呼叫
from multiprocessing import Pool
在宣稱提升效能之前,請先透過 cudf.pandas profiler 確認是否已成功加速。
關於 Notebook、CLI 及統計範例,請參閱
references/cudf-pandas-accelerator.md。若效能剖析(profile)顯示熱點路徑仍在 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、Join、Groupby、Reshape、可空型態(nullable types)、fillna/where、時間分桶(time buckets)、滑動視窗(rolling windows)或 CPU/GPU 一致性檢查的任務,優先推薦使用明確的 cuDF。當語意正確性至關重要時,請加入小型的 CPU/GPU 驗證路徑,而非僅依賴程式碼無錯執行。
針對包含 Null 處理、Reshape 或時間序列行為的 pandas 程式碼,在重寫前請先閱讀 references/api-patterns.md 中對應的語意檢查清單。對於「最小改動」的需求,使用 cudf.pandas 啟動就已足夠;但實作需求應使熱點路徑變得明確且可觀察。
對於包含大量 Reshape 的 pandas 程式碼(如 pivot_table、melt、stack/unstack、crosstab),請將原始 schema 納入合約的一部分:包含索引標籤、欄位標籤或層級(levels)、fill_value、aggfunc、margins 以及正規化(normalization)。在支援等效操作之處使用明確的 cuDF;若精確的 pandas Reshape 語意比重寫每個操作更重要,請使用 cudf.pandas 或狹窄的相容性邊界。在最終定案前,針對 shape、標籤與代表性數值加入小型 pandas 參考一致性檢查。請參閱 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 記憶體池配置器 (Pool Allocator)(可減少包含大量記憶體配置之管道中的 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 比例偏高,代表存在大量降級操作(fallbacks)。請找出並修復這些操作。 - 檢查
references/api-patterns.md以了解已知缺口。
OOM (CUDA 記憶體不足):
- 啟用溢出機制:
cudf.set_option("spill", True) - 若觀察到配置器碎片化或重複配置的開銷,在進行 GPU 記憶體配置前,請參考
accelerated-computing-rmm的記憶體資源設定指南 - 若依然失敗:請改用 dask-cuDF
AttributeError / NotImplementedError:
- 針對特定操作,請檢查
references/api-patterns.md - 將該特定操作限制在狹窄的邊界內由 CPU 處理,並在 GPU 上繼續執行支援的管道
- 僅在遇到不支援的操作時使用
.to_pandas(),處理完後再用.from_pandas()轉回 GPU
結果與 pandas 不一致:
- Null/NaN 處理差異:cuDF 預設使用
<NA>(可空),而 pandas 使用NaN。請參閱references/api-patterns.md。 - 排序穩定性:除非傳入
stable=True,否則 cuDF 的排序不保證具有穩定性(stable sort)。 - 若差異源自浮點數,請嘗試轉型為較高精度的浮點數(例如使用
float64代替float32)。若結果仍有差異,請停止除錯。由於浮點數算術不具結合律(non-associativity),GPU 與 CPU 演算法在浮點數計算上必然會產生差異,且此現象無法消除。
可空與填補語意
當使用者明確關心 pandas 可空資料型態(nullable dtypes)、fillna、where/mask 或群組 Null 行為時,請將一致性檢查(parity checks)視為實作的一部分。可空資料型態範例請參閱 references/api-patterns.md。
- 請保留可空整數/字串欄位,除非原始程式碼已有填充哨兵值(sentinel values)的做法,否則不要隨意填充。
- 當
where/mask編碼了特定條件時,請保留其語意。僅在條件完全等同於純 Null 時才使用寬鬆的fillna。 - 當 pandas 參考路徑使用可空擴充資料型態(nullable extension dtypes)時,請使用
to_pandas(nullable=True)進行比較。 - 將一致性檢查放在 GPU 路徑旁的重用輔助函式中,以便未來的修改能執行相同的可空轉換與聚合檢查。
- 在宣稱語意一致(parity)前,請先驗證資料列數、Null 計數、Mask 真值表、Groupby 聚合結果以及具代表性的資料型態(dtypes)。
參考文件
references/cudf-pandas-accelerator.md— 效能剖析、降級檢測、cudf.pandas 深度剖析references/api-patterns.md— 已知 API 缺口、變通方案、語意差異references/dask-cudf-patterns.md— 多 GPU 模式、最佳實踐、Partition 調校
外部文件
需要時可使用 WebFetch 檢索詳細的 API 簽章、參數說明與範例。
- cuDF 文件: https://docs.rapids.ai/api/cudf/stable/
- dask-cuDF API 參考: https://docs.rapids.ai/api/dask-cudf/stable/api/
- GitHub: https://github.com/rapidsai/cudf
- CHANGELOG: https://github.com/rapidsai/cudf/blob/main/CHANGELOG.md




