我正在尝试与 GPU 配合使用的 DbScan Rapids 版本。
我用 Python 编写了一段简短的代码,用于查找 3D 随机生成点中的簇,当我使用该代码时,我意识到 CPU 的方式由于某种我不熟悉的原因,它比 GPU 更快:
from sklearn.cluster import DBSCAN
from cuml.cluster import DBSCAN as cuDBSCAN
import cupy as cp
pij_gpu = cp.asarray(pij.astype(np.float32)) # Transfer data to GPU
eps = 0.3
min_samples = 5
start = time.time()
cluster = DBSCAN(eps=eps, min_samples=min_samples, n_jobs=-1)
cluster.fit(pij)
print(f"CPU: {time.time() - start}")
start = time.time()
cluster_gpu = cuDBSCAN(eps=eps, min_samples=min_samples)
cluster_gpu.fit(pij_gpu)
print(f"GPU: {time.time() - start}")
日志:
size is: (670761, 3)
CPU: 1.508012294769287
[W] [14:24:17.089902] Batch size limited by the chosen integer type (4 bytes). 6007 -> 3201. Using the larger integer type might result in better performance
GPU: 10.168060541152954
我打印了 pij 大小。
我错过了什么吗?
我浏览了互联网并使用 ChatGPT找到答案,但我找不到答案。
我注意到的一件事是,当点更接近时,GPU 往往比 CPU 快一点。
我有 nvidia 3090 和比较强的电脑。
观察到 RAPIDS 的 cuML DBSCAN 比 scikit-learn 的 CPU 版本慢,有几个原因。让我们来分析一下这些原因,并探讨一下如何改进:
-
数据传输开销: 正确地将数据传输到了 GPU (使用
cp.asarray
),但此过程本身就需要时间。对于较小的数据集,此开销可能会盖过 GPU 计算带来的好处。 -
DBSCAN 算法的性质: DBSCAN 是一种基于算法,它涉及到基于密度的聚类,需要进行大量的最近邻搜索。虽然 GPU 擅长并行计算,但在某些情况下,基于树的 CPU 算法(例如 scikit-learn 中使用的算法)对于此类搜索来说效率更高,尤其是在数据集不太大的情况下。
-
cuML DBSCAN 实现: cuML 仍在积极开发中,其某些算法(包括 DBSCAN)可能尚未针对所有情况进行全面优化。
-
批处理大小警告: 收到的警告表明,所选数据类型限制了批处理大小。这可能会影响 cuML DBSCAN 的性能。
可能的改进:
-
更大的数据集: 尝试使用更大的数据集。随着数据集大小的增加,GPU 加速的优势将更加明显。
-
参数调整: 对
eps
和min_samples
参数进行试验。这些参数会影响 DBSCAN 算法的行为,并且 GPU 和 CPU 实现的最佳值可能不同。 -
不同的 GPU: 与 3090 相比,功能更强大的 GPU 可能会显示出更好的性能。
-
cuML 版本: 确保使用的是最新版本的 cuML,因为可能会进行性能改进。
-
替代算法: 对于的特定数据集和用例,其他聚类算法(例如 K 均值或基于树的方法)可能更适合于 GPU 加速。cuML 提供了这些算法的 GPU 加速版本。
基准测试:
为了更好地了解性能差异,请对不同数据集大小和参数值进行基准测试,比较 cuML DBSCAN 和 scikit-learn DBSCAN。这将有助于确定哪种实现对的特定用例更有利。
总而言之, 虽然 GPU 在处理许多机器学习任务时可以提供显著的加速,但并非所有算法或数据集大小都能从中平等受益。对于像 DBSCAN 这样的算法,数据传输开销、算法的性质以及特定的实现细节都会影响 CPU 和 GPU 性能之间的相对速度。
标签:python,scikit-learn,dbscan,rapids,cuml From: 78754311