我想在大数组M[159459,159459]
上执行SVD。
由于SVD计算取决于形状为(159459,159459)
的输入矩阵,因此该here不能满足我的目标。
我尝试使用:scipy.linalg.svd
scipy.linalg.svd(check_finite=False)
将驱动程序更改为lapack_driver='gesvd
numpy.linalg.svd
但是,我总是收到MemoryError。最后,我想计算完整的SVD,因为我想执行Procrustes分析,即如果M是我现在拥有的矩阵,则需要M = USV'
import numpy as np
from scipy import linalg
#M = np.load("M.npy")
M = np.random.rand(159459,159459)
U, s, Vh = linalg.svd(M, check_finite=False, lapack_driver='gesvd)
一切都失败了。
我的系统详细信息:
$ cat /proc/meminfo
MemTotal: 527842404 kB
MemFree: 523406068 kB
MemAvailable: 521659112 kB
最佳答案
内存大小很重要,延迟成本会伤害您下一个:
在给定mM.shape == [159459, 159459]
的情况下,给定的mM.dtype
默认为float(64)
,将需要具有以下内容:203.42 [GB]
表示mM[159459, 159459]
的原始名称,加上203.42 [GB]
表示计算出的mU[159459, 159459]
,再加上为计算出的203.42 [GB]
Vh[159459, 159459]
为计算出的0.0013 [GB]
尝试从vS[159459]
到float64
或什至float32
的仅线性缩小比例为2(且不超过4)的系数,这是有史以来最便宜的步骤,它不会改变游戏规则,甚至会受到效率低下(如果未在内部进行高达float16
的反向转换-我自己的尝试就此止步不前,以至于我在这里遇到了不满意之处,以避免在尝试从最低限度的挂起开始重复自己的错误水果第一...)
如果您的分析仅适用于向量numpy
,则仅float64
标志将通过不返回(因此不为其保留空间)实例来避免为大约vS
RAM分配留出空间。和.svd( ..., compute_uv = False, ... )
。
即使是这样的情况,也并不意味着您的SLOC会像报告的~ 1/2 [TB]
RAM系统那样存活。 mU
处理将分配内部工作资源,这些资源不在您的编码范围内(请确保,除非您自行重构和重新设计Vh
模块,如果不确定,可以认为这很可能)和配置控制。因此,请注意,即使在测试0.5 TB
处理模式时,如果scipy.linalg.svd()
无法在内部分配不适合当前RAM的所需内部使用的数据结构,它仍可能会引发错误。
这也意味着即使使用scipy.linalg
,这也可能是卸载原始compute_uv = False
的RAM中表示的成功诀窍(避免了第一个所需.svd()
的显着部分搁置并阻止使用主机RAM),但使用此技巧需要支付一些费用。
我的实验在较小的numpy.memmap()
-s规模下,用于矩阵处理和ML优化时,产生的mM
速度较慢,因为尽管进行了智能缓存,但203.4 [GB]
实例仍依赖于磁盘I / O。
最好的结果将来自使用先进的.memmap
大小,仅SSD的存储设备,该设备直接托管在某些快速且低延迟的访问总线M.2或PCIx16上的计算设备上。
最后的经验,可能还不想在这里听到:
使用更大的基于主机的RAM(这意味着使用多TB计算设备)是更安全的方法。如果降低的性能和其他费用在您的项目预算之内,则测试上述建议的步骤将有所帮助。如果没有,请在您的母校或项目最近的研究中心使用HPC中心,在该中心通常使用这种多TB计算设备。