如何像深度学习训练一样在GPU上多线程加速机器学习算法
问题描述
采用后向消除算法做特征筛选时,高特征维度、大样本量场景下算法仅在CPU端运行,速度极慢。需要实现GPU多线程加速,达到类似深度学习模型的GPU运行效率。原有实现代码如下:
import pandas as pd data = pd.read_csv('data.csv') X = data.drop(['Path','id','label'], axis=1) y = data['label'] from mlxtend.feature_selection import SequentialFeatureSelector as sfs from sklearn.linear_model import LinearRegression lreg = LinearRegression() new_sfs = sfs(lreg, k_features=1600, forward=False, verbose=1, scoring='neg_mean_squared_error') new_sfs = new_sfs.fit(X, y) # 注:原代码此处存在笔误,sfs1未定义 feat_names = list(sfs1.k_feature_names_)
加速方案
原生mlxtend的序列特征选择器、sklearn的线性回归均为CPU实现,无原生GPU支持,要实现GPU加速需要从底层计算组件替换、执行逻辑优化两方面入手:
- 替换基础估计器为GPU实现:使用RAPIDS生态的cuML库提供的
LinearRegression替代sklearn版本,该组件基于CUDA优化,接口和sklearn完全兼容,可直接替换,线性拟合速度比CPU版高数倍到数十倍。 - 避免CPU-GPU数据拷贝开销:使用cudf替代pandas做数据读取与预处理,数据直接加载到GPU显存,不需要每轮训练在CPU和GPU间来回传输数据。
- 开启特征选择的并行能力:给SFS传入
n_jobs=-1参数,调用所有可用计算资源并行执行每轮的特征评估,进一步压缩迭代时间。 - 前置粗筛降低计算量:后向消除从全量特征开始逐轮剔除,如果初始特征维度远高于目标的1600维,总迭代轮次极多,哪怕GPU加速也会很慢。可以先用方差阈值、相关性过滤等轻量方法先剔除明显无效的特征,再进入后向消除流程,总计算量可降低一个数量级以上。
优化后的可运行代码如下:
# 需提前安装匹配本地CUDA版本的RAPIDS cuML、cudf依赖 import cudf # 数据直接读入GPU显存 data = cudf.read_csv('data.csv') X = data.drop(['Path','id','label'], axis=1) y = data['label'] from mlxtend.feature_selection import SequentialFeatureSelector as sfs # 替换为GPU版线性回归 from cuml.linear_model import LinearRegression lreg = LinearRegression() new_sfs = sfs( lreg, k_features=1600, forward=False, verbose=1, scoring='neg_mean_squared_error', n_jobs=-1 # 开启全量并行 ) new_sfs = new_sfs.fit(X, y) # 修复原代码变量名笔误 feat_names = list(new_sfs.k_feature_names_)
注意:如果数据集规模超过单卡显存容量,可开启cuML的显存溢出支持,或先做特征粗筛将维度降到显存可承载范围再运行后向消除,避免显存溢出报错。
内容的提问来源于stack exchange,提问作者Huyng
相关产品推荐
相关产品推荐

