对于较大的十字架或外部产品,NumPy比PyTorch更快



我正在计算大小为(50500,)的向量之间的巨大外积,并发现NumPy在计算时比PyTorch快(很多?)。

以下是测试:

# NumPy
In [64]: a = np.arange(50500) 
In [65]: b = a.copy()  
In [67]: %timeit np.outer(a, b) 
5.81 s ± 56.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
-------------
# PyTorch
In [73]: t1 = torch.arange(50500)
In [76]: t2 = t1.clone()
In [79]: %timeit torch.ger(t1, t2) 
7.73 s ± 143 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

理想情况下,我希望在PyTorch中完成计算。那么,对于如此巨大的向量,如何在PyTorch中加速计算外积呢?


注意:我试图将张量移动到GPU,但我使用了MemoryError,因为它需要大约19GiB的空间。所以,我最终不得不在CPU上完成。

不幸的是,如果不付出大量的努力,就无法特别加快torch计算外积torch.ger()的方法。

解释和选项

numpy函数np.outer()之所以如此快速,是因为它是用C编写的,您可以在这里看到:https://github.com/numpy/numpy/blob/7e3d558aeee5a8a5eae5ebb6aef03de892a92ebd/numpy/core/numeric.py#L1123其中该函数使用来自CCD_ 5C源代码的操作。

Pytorch的torch.ger()函数在这里用C++编写:https://github.com/pytorch/pytorch/blob/7ce634ebc2943ff11d2ec727b7db83ab9758a6e0/aten/src/ATen/native/LinearAlgebra.cpp#L142这使得它变得稍微慢一点,正如您在示例中看到的那样。

您可以选择"在PyTorch中加速计算外部产品",即在PyTorch的本地代码中为外部产品添加一个C实现,或者如果您真的不想使用numpy(这没有多大意义),则在使用Cython之类的东西与C接口时使用您自己的外部产品功能。

p.S.

此外,使用GPU只会提高GPU上的并行计算速度,这可能不会超过在RAM和GPU内存之间传输数据所需的时间成本。

一个非常好的解决方案是将两者结合起来。

class LazyFrames(object):
def __init__(self, frames):
self._frames = frames
def __array__(self, dtype=None):
out = np.concatenate(self._frames, axis=0)
if dtype is not None:
out = out.astype(dtype)
return out

例如,frames可能只是你的pytorch张量。

该对象确保观测之间的公共帧只存储一次。它的存在纯粹是为了优化可能巨大的内存使用(例如DQN的1M帧重放缓冲区)。在将此对象传递给模型之前,只应将其转换为numpy数组。

参考:https://github.com/Shmuma/ptan/blob/master/ptan/common/wrappers.py

相关内容

  • 没有找到相关文章

最新更新