1392 字

基于GPU的探索性数据分析

表格数据是实验学科科研里最常用的格式之一,特别是组学,现在有了单细胞转录组学跟高分辨质谱成像,这张表动辄几百万行上万列。这个数据量在CPU生态下做探索性数据分析几乎就是个灾难,要么就是爆内存,要么就是特别慢。我最近遇到这个问题,然后发现当前GPU是可以部分解决这个问题的,这里做个笔记。

虽然pytorch可以在不同平台编译做一些深度学习项目,但不得不承认基于CUDA的GPU生态,特别是RAPIDS套件里的 cuDF 跟 cuML,在探索性数据分析上目前没有可取代的。其可实现的常见算法包括但不限于主成分分析、UMAP、聚类分析例如(K-Means、DBSCAN)、图算法等:

PCA 底层是 SVD(奇异值分解),是标准的线性代数操作,GPU 上有专门优化的实现。RAPIDS 的 cuml.decomposition.PCA 接口跟 scikit-learn 几乎一样,直接替换导入即可。对于高维数据(比如单细胞转录组,动辄几千个基因维度、几十万个细胞),GPU 的 PCA 比 CPU 快一到两个数量级。

CuPy 是最基础的工具,可以理解为 NumPy 的 GPU 版本,接口设计刻意对齐 NumPy,大部分代码把 import numpy as np 换成 import cupy as cp 就能跑。底层矩阵操作、FFT、线性方程组求解,只要你的操作能用 NumPy 表达,基本都能直接迁移到 GPU 上。

XGBoost 和 LightGBM 都内置了 GPU 训练支持,参数层面只需要设 device='cuda'(XGBoost)或 device='gpu'(LightGBM)。梯度提升树不像神经网络那样天然并行,但在特征分裂搜索这一步可以并行化,大数据集上加速效果明显。

UMAP 是近年来替代 t-SNE 的主力降维工具,算法本身涉及图构建和优化两个阶段,两个阶段都能并行化,GPU 加速效果非常好。cuml.manifold.UMAP 是目前最成熟的实现,参数和 umap-learn 基本对应。值得一提的是,UMAP 的随机性比 PCA 大,在 GPU 上跑出来的结果和 CPU 版本会有些微差异,但这属于数值精度和随机种子的问题,不影响结论。

K-Means 是 GPU 加速最彻底的聚类算法之一,因为每次迭代本质上是大量的距离计算和归属分配,天然并行。cuml.cluster.KMeans 在十万级别的数据上比 sklearn 快几十倍不是夸张。

DBSCAN 在 GPU 上的情况稍微复杂一点,因为它的核心依赖最近邻搜索,GPU 实现有 cuml.cluster.DBSCAN,但比 K-Means 的加速比例小一些,数据量越大效果越明显。

图计算通常被认为是 GPU 不太擅长的领域(因为图结构的不规则性不利于并行),但 RAPIDS 里的 cuGraph 把相当一部分图算法移植到了 GPU 上,包括 PageRank、连通分量、最短路径、谱聚类等。

尽管 GPU 算力惊人,但它在处理超大规模表格时,会有显存限制。以一个100万行× 10,000列的数据集为例,来算一笔显存账。如果这是一个密集的浮点数(FP32,占用 4 字节)矩阵,其基础物理内存占用为:

1,000,000×10,000×4 bytes≈40 GB

这 40GB 仅仅是把数据装进 GPU 的门槛。在进行 PCA 或 UMAP 计算时,算法还需要创建大量的中间变量和距离图。解决这个问题有两个思路,一个是利用稀疏矩阵,另一个就是先降维后处理,当然全局算法是没法无损批处理的,有近似的方法。数据也最好存成Parquet格式方便计算。

其实实验学科数据分析里能用上GPU的场景真的不多,但在能用的场景里GPU加速非常强,这里要有个印象那就是探索性数据分析大部分都可以搬到GPU上跑。另外就是现在只有cuda生态支持最全,别的平台可能能编译pytorch,但探索性数据分析算法严重不全,只能说黄仁勋的布局够强,科研用没得选。