cuDF 讓 pandas 直接跑上 GPU
我把 cuDF 的 GPU dataframe 堆疊拆開,順手整理成可直接抄走的 pandas、Polars、Dask 上 GPU 起手式。

我拆解 cuDF 的 GPU dataframe 堆疊,順手給你一份能直接抄走的 pandas、Polars、Dask 起手式。
我盯 cuDF 一陣子了,老實說它一開始真的很像那種「看起來很猛、裝起來很煩」的專案。你想把 pandas 工作搬去 GPU,結果先卡在 CUDA 版本、套件變體、到底該走哪個前端。功能不是問題,問題是你根本還沒開始算,就先被安裝流程消耗掉耐心。我最不爽的就是這種工具:嘴上說幫你加速,實際上先叫你補功課。
但我後來看懂一件事,cuDF 不是單一套件在那邊硬扮萬能,它本來就是一整層堆疊。底下有 C++ 核心,上面有 Python 綁定,再往上才是 pandas、Polars、Dask 這些使用入口。這樣一拆,很多原本看起來很亂的東西就合理了。第一次把它當成堆疊來看,我才真的知道自己該從哪一層下手,而不是在安裝文件裡面打轉。
我先看懂它不是一包,而是一整層堆疊
訂閱 AI 趨勢週報
每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。
不會寄垃圾信,隨時可取消。
cuDF is composed of multiple libraries including: libcudf, pylibcudf, cudf, cudf.pandas, cudf-polars, and dask-cudf.
翻譯一下就是:cuDF 不是一個「裝了就好」的單體,它是一家族套件。這件事很重要,因為每一層處理的問題都不一樣。你只看 Python API,會忽略底層 GPU tabular primitive;你只看 C++,又會錯過真正讓人願意用它的原因,也就是既有 dataframe 程式碼能不能少改就上 GPU。

我以前很常被這種平台型 repo 搞到煩。文件寫一堆內部名詞,但你明明只是想把一個 notebook 跑快一點。cuDF 這次反而算老實,README 直接把層級攤開來:RAPIDS cuDF GitHub、libcudf 文件、pylibcudf、cudf、cudf-polars、dask-cudf,你要哪條路,自己挑。
實操上我會這樣判斷:如果你團隊本來就寫 pandas,先看 cudf.pandas;如果你已經在用 Polars,就看 cudf-polars;如果你是分散式 dataframe 工作,那就看 dask-cudf。不要一開始就問「cuDF 能不能支援我全部工作流」,這題太空泛。先問你現在到底在哪一層,答案會乾淨很多。
- 底層想碰 GPU tabular 原語:看 libcudf。
- 想要 pandas 風格 API:看 cudf。
- 想保留既有 pandas 程式碼:先碰 cudf.pandas。
安裝不是隨便裝,是 CUDA 版本配對
You will need to match the major version number of your installed CUDA version with a -cu## suffix when installing from PyPI.
這句話其實就是整個安裝故事的核心。cuDF 的 PyPI wheel 不是亂發的,它是跟 CUDA major version 綁死的。你如果是 CUDA 13,就得裝 -cu13;你如果是 CUDA 12,就得裝 -cu12。這不是小註解,這是門檻。很多 GPU Python 工具爛就爛在這裡,大家嘴上都說「先 pip install 再說」,結果一半的人直接版本不合,另一半的人在錯的地方 debug 半天。
我比較喜歡 cuDF 的地方,是它至少把這件事講在前面,不跟你玩模糊地帶。它也直接把你導去 RAPIDS 安裝指南,先看作業系統、驅動、CUDA 支援版本,再決定要走 pip 還是 conda。這種順序我認同,因為 GPU 套件本來就不是「先裝再看」的玩法。
我自己的實操建議很簡單:先確認三件事,作業系統、GPU 驅動、CUDA major version。確認完再選安裝路徑。習慣 pip 就用對應的 -cu12 或 -cu13;習慣 conda 就走 -c rapidsai;如果你是要追新版,再去看 nightly channel。不要一上來就把問題丟給 Python 環境,這通常只會讓你更氣。
- PyPI 路線要先對齊 CUDA major version。
- conda 路線就老實用 RAPIDS channel。
- 要從原始碼裝,再去看 repo 的 build / contribution 文件。
cudf.pandas 是最不痛的切入口
A zero-code change accelerator, cudf.pandas, for existing pandas code.
這句我覺得很關鍵,因為它直接回答了最實際的問題:我現有的 pandas 程式碼要改多少?答案通常是,比你想像少。你可以用 python -m cudf.pandas script.py 跑腳本,也可以在 notebook 裡先 %load_ext cudf.pandas,然後照樣 import pandas。支援的操作會被導到 GPU,至少先讓你知道哪些地方真的值得加速。

我會把這個模式當成第一個實驗,不會一開始就急著重寫整條 pipeline。因為很多團隊卡在 GPU 導入,不是技術不行,是心理上以為自己得先大改程式碼才有資格試。這想法很煩,也很浪費時間。正確做法是先包住既有程式,挑一個慢 notebook 或 batch job 來試,先看那些重的 dataframe 操作是不是真的適合 GPU。
實操上我會這樣做:先選一支最慢的 pandas 腳本,不改邏輯,只改啟動方式。跑一次原版、跑一次 cudf.pandas 版,量 runtime、量記憶體、量有沒有踩到不支援的 API。等你有數字,再決定要不要往 native cuDF API 走。沒有數字就談遷移,通常只是在開會。
這條路還有一個好處,就是你會在真實上下文裡發現相容性問題。哪些 pandas API 其實已經夠快,哪些才是瓶頸,一次就看得出來。你不需要先寫一份很漂亮的 migration plan,你只需要先知道哪個步驟在拖慢你。
Polars 跟 Dask 不是附帶品,是正經入口
cudf-polars: A Python library providing a GPU engine for Polars; dask-cudf: A Python library providing a GPU backend for Dask DataFrames.
這代表 cuDF 不只想吃 pandas,它也想接住 Polars 跟 Dask 這兩個常見生態。這很合理,因為現在很多團隊早就不是純 pandas 了。有些人改用 Polars,因為 lazy execution 比較順;有些人本來就在 Dask 上做分散式 dataframe。cuDF 不是逼大家換腦袋,而是把 GPU execution 插到既有習慣裡。
README 裡的 Polars 範例我看得很順眼:掃 parquet、drop null、group by,最後用 collect(engine="gpu")。我喜歡這種寫法,因為它把 GPU 的位置講清楚了,不是藏在奇怪的自訂抽象裡。Dask-cudf 也是同一個邏輯,保留 Dask 的思考方式,只是把 dataframe backend 換成 GPU 版本。
我碰過混合團隊最知道這件事有多重要。A 組要 pandas 相容,B 組想用 lazy plan,C 組要 cluster execution。如果 GPU 方案只照顧其中一種,導入就會變成政治問題。cuDF 的做法比較務實,至少它沒有假裝一個 API 可以把所有人都哄好。
實操上我會先畫出你現有的 dataframe 地圖。你如果是 Polars 使用者,就挑一條 lazy pipeline,直接試 engine="gpu"。你如果是 Dask 使用者,就挑一個最吃時間的分散式 job,先看 GPU backend 能不能吃下去。你如果是 pandas 團隊,就先待在 cudf.pandas,不要急著跳 native API,先看結果再說。
這 repo 比較像生產環境工具,不像 demo 玩具
Notable projects that use cuDF include Spark RAPIDS, Velox-cuDF, and Sirius.
這句話讓我比較放心。因為它代表 cuDF 不是只拿來做 notebook demo 的。README 直接點出幾個真正在用的專案:Spark RAPIDS、Velox 的 cuDF 整合、還有 Sirius。這不是裝飾,是訊號:cuDF 被設計成可以塞進更大的資料系統裡。
翻譯一下就是,你評估 cuDF 的方式不該是「我要不要換一個 dataframe 套件」,而是「GPU tabular execution 在我現有資料流裡哪一段最划算」。這個問法好多了,因為它逼你去看整條路徑,而不是只看單點 benchmark。
我很吃這一套,因為很多 GPU 專案都喜歡拿 toy example 先把你騙進來,等真的接到生產流程就開始掉漆。cuDF 至少把整合關係講出來,表示它預設自己是被嵌進系統裡,不是拿來當展示品。
實操上,如果你們公司本來就有 Spark 或 SQL engine,不要把 cuDF 獨立拿出來看。直接挑一條資料路徑,從來源、轉換、到下游消費者都畫出來,然後找出最花 wall-clock time 的那一段。GPU 加速要是不能省到時間,就別硬上。
日常使用上,我會把它當平台依賴來管
For bug reports or feature requests, please file an issue on the GitHub issue tracker.
這句看起來很普通,但它其實透露了專案的使用方式。cuDF 不是一次性丟給你用完就算,它預設你會回到 GitHub issue tracker、看文件、看貢獻流程、看版本相容性。這對一個深入堆疊底層的工具來說很正常,也很合理。
我建議你把它當平台依賴,而不是一個「反正 pip 裝得起來」的小套件。先讀 README,再裝;先確認版本,再寫程式;先記錄 CUDA 假設,再交給團隊。你如果是多人協作,最好把安裝方式、CUDA 版本、conda/pip 選擇都寫進 README 或 runbook,不然之後一定有人在別台機器上重演同一個坑。
我自己會特別注意三件事:一,版本要 pin;二,安裝筆記要留;三,出問題先看 issue tracker 跟文件,不要先在 Slack 裡亂猜。這種基礎工作雖然煩,但它會直接決定你是不是每次換環境都要重來一次。
如果你真的要把 cuDF 放進團隊流程,我會建議你先從單一慢任務開始,不要整條資料管線一起搬。先驗證價值,再談擴大。這是我看這類工具最實際的態度:先讓它在一件事上證明自己,不要先把自己說服。
可抄的模板
# cuDF 導入起手式(可直接貼進團隊 README)
## 1. 先選入口
- 舊 pandas 程式碼不想大改:先用 cudf.pandas
- 已經在用 Polars:先看 cudf-polars
- 已經在用 Dask:先看 dask-cudf
- 要碰底層 GPU tabular primitive:看 libcudf / pylibcudf
## 2. 先確認環境
- 作業系統是否受支援: https://docs.rapids.ai/install
- GPU 驅動是否正確
- CUDA major version 是 12 還是 13
- 安裝路徑要跟 CUDA major version 對齊
## 3. 安裝原則
### pip
- CUDA 13:裝對應的 -cu13 套件
- CUDA 12:裝對應的 -cu12 套件
### conda
- 用 rapidsai channel
- 團隊若有夜版需求,再評估 nightly channel
## 4. 最小可行測試
### pandas 相容模式
python -m cudf.pandas script.py
### notebook
%load_ext cudf.pandas
import pandas as pd
df = pd.read_parquet("data.parquet")
df = df.dropna().groupby(["A", "B"]).mean()
### native cuDF
import cudf
df = cudf.read_parquet("data.parquet")
df = df.dropna().groupby(["A", "B"]).mean()
### Polars GPU engine
import polars as pl
lf = pl.scan_parquet("data.parquet")
lf = lf.drop_nulls().group_by(["A", "B"]).mean()
result = lf.collect(engine="gpu")
## 5. 評估方式
- 先保留原本 CPU 路徑
- 比 runtime
- 比記憶體
- 比相容性
- 只有真的省時間,才往更深的 native API 走
## 6. 出問題怎麼辦
- 看 GitHub repo: https://github.com/rapidsai/cudf
- 看 API 文件: https://docs.rapids.ai/api/cudf/stable/
- 要從原始碼裝,再看 contribution guide: https://github.com/rapidsai/cudf/blob/main/CONTRIBUTING.md
## 7. 團隊備註
- 把 CUDA 版本寫進 README
- 把安裝方式寫進 runbook
- 把已知不相容的 pandas API 記錄下來
- 不要把 GPU 導入當成一次性試驗,當成平台依賴管理這份模板我故意寫得很直白,因為我比較不想給你一份看起來很漂亮、實際上不能貼的 checklist。你如果要在團隊裡推 cuDF,順序就是這樣:先選入口、先對版本、先做最小測試、先量結果,再決定要不要擴大。
原始來源是 https://github.com/rapidsai/cudf,我拆的 package 層級、安裝邏輯、範例流程都來自這個 repo 與相關文件;上面這份導入模板跟實操順序,是我根據來源整理出的可直接拿去用的版本。