打算尝试将我的一些 scipy/numpy 计算转移到新的 GPU,如何避免令人失望的结果?

计算科学 优化 Python 麻木的 显卡
2021-12-17 00:53:28

更新:我根据链接元数据中的有用建议重构了这个问题。

我是 Python 的 NumPy 和 SciPy(仅此而已)的重度用户,多年来我可以在笔记本电脑上运行任何我需要的东西。

现在,我将开始编写包含 100 到 10,000 个元素的模拟,这些元素远远超出了单个 CPU 在合理时间内所能完成的工作。

添加内核的一种潜在经济的方法是使用 PC 并添加 CUDA GPU,而CuPy是将繁重的计算转移到它的一种方法:

CuPy 的接口与 NumPy 和 SciPy 高度兼容;在大多数情况下,它可以用作替代品。您需要做的就是在 Python 代码中将 numpy 和 scipy 替换为cupycupyx.scipyCuPy基础教程对于学习使用 CuPy 的第一步很有用。CuPy 支持各种方法、索引、数据类型、广播等。此比较表显示了 NumPy / SciPy API 及其对应的 CuPy 实现的列表。

我将购买一个适中的 CUDA GPU 并开始尝试如何做到这一点。

我不是开发人员,我看到(至少)两个潜在问题可能导致我陷入困境并最终陷入困境并失败:

  1. 我购买了错误的 CUDA GPU,速度提升很小或根本不存在。
  2. 我错误地配置了我的数组(例如快轴与慢轴)或严重依赖索引数组,并且花费了大量时间在 CPU、内存和 GPU 之间移动数据,以至于加速很少或根本不存在。

问题:我将尝试将我的一些 scipy/numpy 计算转移到一个新的 GPU 上,并希望得到一些具体的建议来帮助我避免由于上述因素而导致的令人失望的结果。

虽然这类似于“最佳实践”问题,但我还没有任何经验,因此我更容易提出和支持一个关于不做错什么的问题,而不是关于如何把所有事情都做对的问题。

在不久的将来会有一个单独但相关的问题,我将在其中包含一个特定的示例和 NumPy 中的一些替代实现,希望那时我能从这里的一些帮助中受益,并启动并运行一个适度的 GPU。


背景和相关职位:

这个答案到CUDA 和 Python 进行数值积分和求解微分方程

环顾四周,我发现了 CudaPyInt,它使用PyCuda

这个答案到在开发时在 CPU 上编写代码,在运行时在 GPU 上运行 - 哪种方法?

ArrayFire有一个C++ API和一个Python API您可以在多个后端之间切换,包括 CPU、CUDA 和 OpenCL。它还将为您处理内存移动和内核融合。

1个回答

我购买了错误的 CUDA GPU,速度提升很小或根本不存在。

除非您的模型非常大,否则您选择的 GPU 不太可能对您的加速产生重大影响。

大致而言,所有 GPU 都是平等的,除了两个变化点:

  1. 流式多处理器的数量。
  2. 他们拥有的 RAM 数量。

RAM 是最容易理解的。如果您的所有数据都可以放入 GPU 的 RAM 中,那么您不必在计算机之间来回移动它。由于移动数据很慢,因此避免移动可以提高速度。

然而,情况并非一帆风顺。GPU 可以在移动数据时处理数字,因此,如果您进行足够的数学运算以使 GPU 饱和,则数据移动的成本实际上为零。

更多流式多处理器意味着您可以一次处理更多数字。然而,这也不是直截了当的。GPU 可以在等待例如从 GPU 的 RAM 加载数据时交错计算。

我的 Thinkpad P1 有一个 Nvidia Quadro P2000,目前零售价为500美元在某些情况下,例如游戏、CAD 和深度学习,与没有 GPU 相比,这是变革性的。相比之下,我拥有的 2,000 美元左右的 Nvidia GeForce RTX 2080 Ti 大部分时间都尘埃落定,因为我很少需要这么大的功率,而且当我这样做时,我通常可以使用超级计算机并在那里运行我的工作负载。

使用任何GPU所获得的增量提升对您的工作的影响将大于拥有特定 GPU 所获得的提升。

我给你的建议是你找到一个便宜的 GPU,你可以用它来试验和构建你需要的算法。我建议这样做,因为与完全在云中工作相比,拥有对 GPU 的本地访问和舒适的开发环境可以真正加快您的开发周期。不过,根据以下内容,您可以通过先在云中进行试验来节省资金。

一切正常后,如果您的性能仍然受到影响,您可以以约0.20美元/小时的价格在Google Cloud 的 GPU上购买时间。目前我认为他们有 K80 和 P100。这可能足以让你做你想做的工作,或者至少是一种便宜的方式来确定你是否应该在更大的家用 GPU 上花费2,000 美元以上。

如果您的机器内部没有 GPU 插槽,支持 Thunderbolt 的机箱可提供高数据传输率和外围设备的灵活性。

tl;dr 在你知道你需要一个那么昂贵的 GPU 之前,不要在 GPU 上投资数千美元。要么使用云,要么找到可以试验的廉价 GPU。


我错误地配置了我的数组(例如快轴与慢轴)或严重依赖索引数组,并且花费了大量时间在 CPU、内存和 GPU 之间移动数据,以至于加速很少或根本不存在。

编程 GPU 的一个具有挑战性的方面是最大限度地提高并行度。很难回答这个问题,考虑到你做错事的所有方式,所以我认为你最好的选择是访问 GPU(见上文),进行实验,如果遇到障碍,再提出更具体的问题。

也就是说,您对 GPU 进行编程的目标是让高级库为您完成尽可能多的工作。这些库通常对您的数据应该如何布局有强烈的意见,并使用这些假设来构建快速操作。除非您正在做相对新颖的事情,否则您应该假设您正在做的事情可以通过库来实现并找到该库。

在你的库运行起来之后,你可以使用PyTorch ProfilerNvidia Nsight等工具来分析代码并识别性能瓶颈。