启用%load_ext cudf.pandas后GridSearch报DataFrame的AttributeError
问题描述
在Kaggle笔记本中启用%load_ext cudf.pandas以利用GPU加速pandas操作,运行sklearn的GridSearchCV进行超参数搜索时,触发AttributeError: 'DataFrame' object has no attribute '_mgr'错误。移除%load_ext cudf.pandas指令后,代码可正常执行。
环境信息
GPU硬件与驱动
!nvidia-smi Tue Jun 18 17:31:56 2024 +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 CUDA Version: 12.2 | |-----------------------------------------+----------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla T4 Off | 00000000:00:04.0 Off | 0 | | N/A 46C P8 10W / 70W | 0MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ | 1 Tesla T4 Off | 00000000:00:05.0 Off | 0 | | N/A 40C P8 9W / 70W | 0MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| | No running processes found | +---------------------------------------------------------------------------------------+
cuDF版本
import cudf print("cuDF version: ", cudf.__version__) # 输出 cuDF version: 24.04.01
报错原因分析
%load_ext cudf.pandas通过猴子补丁将原生pandas的DataFrame替换为cuDF的兼容实现,以实现GPU加速。但sklearn的GridSearchCV在启用多进程并行(n_jobs=-1)时,会通过joblib在进程间传递数据。cuDF的DataFrame在跨进程序列化/反序列化后,丢失了pandas原生DataFrame的内部属性_mgr,而sklearn的_safe_indexing等内部方法依赖该属性完成数据索引操作,最终触发报错。
解决方案
方案1:禁用cudf.pandas扩展
直接移除%load_ext cudf.pandas指令,使用原生pandas处理数据。由于XGBoost已经设置device='cuda',模型训练阶段仍可利用GPU加速,无需担心训练速度问题。
方案2:转换为原生pandas DataFrame后再传入GridSearchCV
如果需要保留cudf.pandas加速数据预处理步骤,在将数据传入GridSearchCV前,将cuDF DataFrame转换为原生pandas DataFrame:
# 假设X、y是cudf DataFrame/Series X = X.to_pandas() y = y.to_pandas() # 后续GridSearchCV代码保持不变 gs_cv = GridSearchCV(estimator=model[p], param_grid=hyperparam_grid, scoring='average_precision', cv=4, return_train_score=True, n_jobs=-1, verbose=1) gs_cv.fit(X, y)
方案3:关闭GridSearchCV的多进程并行
修改GridSearchCV的n_jobs参数为1,避免跨进程传递数据,但这会显著降低超参数搜索速度,仅作为临时调试方案:
gs_cv = GridSearchCV(estimator=model[p], param_grid=hyperparam_grid, scoring='average_precision', cv=4, return_train_score=True, n_jobs=1, # 关闭多进程 verbose=1)
验证
采用方案2后,重新运行GridSearchCV代码,可正常完成超参数搜索,无AttributeError报错。
内容的提问来源于stack exchange,提问作者Nader Afshar

