cuML DBSCAN使用Numba设备数组运行慢于CPU版scikit-learn如何优化?
性能异常原因排查
- 输入参数传递错误:代码中已通过
nb.cuda.to_device(ps)将数据拷贝到GPU显存得到变量pp,但后续fit_predict接口传入的仍是原内存中的ps数组,导致运行过程中频繁发生CPU与GPU之间的数据拷贝,产生大量额外开销,这是速度变慢的核心原因之一。 - 数据类型精度冗余:cuML的算子针对float32做了大量硬件适配优化,你当前使用的float64类型数据会强制调用计算效率更低的双精度算子,且2维坐标场景下float32的精度完全可以满足DBSCAN的计算需求,不必要的双精度会拖慢计算速度。
- DBSCAN参数适配问题:当前设置的
min_samples=100、eps=0.8组合会大幅增加邻域搜索的计算量,cuML的DBSCAN实现针对高密高维场景优化更明显,低维小邻域场景下如果存在数据传输开销的话,很容易出现性能不如CPU优化版本的情况。 - 显存未占满的根因:由于大部分运行时间消耗在数据传输环节,而非实际的GPU并行计算,因此不会出现显存占满的情况,属于典型的访存瓶颈问题。
优化方案
- 修正输入数据传递:调用
fit_predict时传入已经拷贝到GPU的pp变量,避免重复数据传输,修正后代码如下:
pp = nb.cuda.to_device(ps) # ps is a (15636915,2) cupy array with cuml.using_output_type('input'): db_gpu = cumlDBSCAN(eps=0.8, min_samples=100,verbose=5).fit_predict(pp,out_dtype='int64')
- 降低数据精度:将输入数据转换为float32类型,在不损失聚类效果的前提下大幅提升计算效率,转换代码为
ps = ps.astype('float32')。 - 调整执行参数:如果业务场景允许,可以适当调大
eps或减小min_samples降低邻域搜索复杂度;也可以开启cuML DBSCAN的max_mbytes_per_batch参数,根据你的GPU显存大小调整批处理规模,充分利用GPU并行能力。 - 检查环境适配:确认你的Rapids版本与CUDA版本匹配,GPU硬件的算力不低于7.0(V100及以上架构),低算力硬件会限制cuML算子的优化效果。
内容的提问来源于stack exchange,提问作者Hu.Xuechun
相关产品推荐
相关产品推荐

