Python 中的 SVD 内存错误
SVD MemoryError in Python
我想对大数组执行 SVD M[159459,159459]
。
由于 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]
有史以来最便宜的步骤,通过尝试将 linear-only 缩小 2 倍(且不超过 4),从 float64
到 float32
甚至 float16
不是游戏规则的改变者,甚至因 numpy
效率低下而受到严重惩罚(如果没有在内部执行 back-conversions 再次达到 float64
- 我自己的尝试在这方面如此流血,我分享了结果在这里不满意,以免重复我自己的错误,试图从最低的挂果开始......)
如果您的分析可能仅适用于向量 vS
,只有 .svd( ..., compute_uv = False, ... )
标志将避免生成 space 大约~ 1/2 [TB]
RAM-allocations 通过不返回(因此不为他们保留 space )实例 mU
和 Vh
.
即使是这种情况也不意味着您的 SLOC 会像报告中那样存活下来 0.5 TB
RAM-system。 scipy.linalg.svd()
处理将分配内部工作资源,这超出了您的编码范围(当然,除非您 re-factor 和 re-design 您自己的 scipy.linalg
模块,这是公平地考虑非常可能,如果不确定)和配置控制。因此,请注意,即使您测试 compute_uv = False
处理模式,.svd()
仍可能会抛出错误,如果它无法在内部分配 required internally used data-structures,则不会适合当前内存。
这也意味着即使使用numpy.memmap()
,这可能是一个成功的技巧off-load in-RAM表示原始mM
(避免第一个需要的某些显着部分 203.4 [GB]
坐下并阻止主机 RAM 的使用) ,但使用此技巧需要付出一定的代价。
我的实验,在 .memmap
-s 的较小尺度上,用于矩阵处理和 ML-optimisations, 产量大约 1E4 ~ 1E6
处理速度较慢 因为尽管有智能缓存,numpy.memmap()
-实例依赖于 disk-I/O.
最好的结果将来自于使用先进的、TB
大小、SSD-only-storage 设备,在一些快速和 low-latency access-bus M 上托管在计算设备上。 2 或 PCIx16。
最后一段经验,大家可能还不想听:
使用更大的 host-based RAM,这意味着使用 multi-TB 计算设备,是更安全的方法。如果降低的性能和额外费用在您项目的预算范围内,则测试上述建议的步骤将有所帮助。如果没有,请前往您的母校或您项目最近的研究中心使用 HPC 中心,这些 multi-TB 计算设备正在共同使用。
我想对大数组执行 SVD M[159459,159459]
。
由于 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]
有史以来最便宜的步骤,通过尝试将 linear-only 缩小 2 倍(且不超过 4),从 float64
到 float32
甚至 float16
不是游戏规则的改变者,甚至因 numpy
效率低下而受到严重惩罚(如果没有在内部执行 back-conversions 再次达到 float64
- 我自己的尝试在这方面如此流血,我分享了结果在这里不满意,以免重复我自己的错误,试图从最低的挂果开始......)
如果您的分析可能仅适用于向量 vS
,只有 .svd( ..., compute_uv = False, ... )
标志将避免生成 space 大约~ 1/2 [TB]
RAM-allocations 通过不返回(因此不为他们保留 space )实例 mU
和 Vh
.
即使是这种情况也不意味着您的 SLOC 会像报告中那样存活下来 0.5 TB
RAM-system。 scipy.linalg.svd()
处理将分配内部工作资源,这超出了您的编码范围(当然,除非您 re-factor 和 re-design 您自己的 scipy.linalg
模块,这是公平地考虑非常可能,如果不确定)和配置控制。因此,请注意,即使您测试 compute_uv = False
处理模式,.svd()
仍可能会抛出错误,如果它无法在内部分配 required internally used data-structures,则不会适合当前内存。
这也意味着即使使用numpy.memmap()
,这可能是一个成功的技巧off-load in-RAM表示原始mM
(避免第一个需要的某些显着部分 203.4 [GB]
坐下并阻止主机 RAM 的使用) ,但使用此技巧需要付出一定的代价。
我的实验,在 .memmap
-s 的较小尺度上,用于矩阵处理和 ML-optimisations, 产量大约 1E4 ~ 1E6
处理速度较慢 因为尽管有智能缓存,numpy.memmap()
-实例依赖于 disk-I/O.
最好的结果将来自于使用先进的、TB
大小、SSD-only-storage 设备,在一些快速和 low-latency access-bus M 上托管在计算设备上。 2 或 PCIx16。
最后一段经验,大家可能还不想听:
使用更大的 host-based RAM,这意味着使用 multi-TB 计算设备,是更安全的方法。如果降低的性能和额外费用在您项目的预算范围内,则测试上述建议的步骤将有所帮助。如果没有,请前往您的母校或您项目最近的研究中心使用 HPC 中心,这些 multi-TB 计算设备正在共同使用。