在Python中最小化内存密集操作的磁盘读写
背景
我正在做一个计算量比较大的项目,属于计算语言学的范畴。不过,我遇到的问题比较普遍,所以我觉得解决方案对其他人也会有帮助。
需求
我需要写的这个程序有几个关键点:
- 要处理一个很大的文本库(大小在5G到30G之间,未来可能会更大)
- 逐行处理这些数据。
- 从处理后的数据中,构建大量的向量(有些向量的维度超过4,000,000)。通常需要构建数十万个这样的向量。
- 这些向量必须以某种格式保存到磁盘上。
步骤1和2相对简单,只要使用生成器和数据分析管道就可以高效完成。真正的大问题在于步骤3(以及相关的步骤4)。
插入:技术细节
如果构建向量的具体过程会影响解决方案:
对于文本库中的每一行,必须更新一个或多个向量的基础权重。
可以把它们想象成Python中的列表,每处理一行,就会更新一个或多个列表(如果需要的话会创建新的列表),通过在一个或多个索引位置增加这些列表的值(这个值可能根据索引不同而不同)。
这些向量之间没有依赖关系,读取文本库的顺序也无关紧要。
尝试的解决方案
在处理这个问题时,有三种极端的选择:
- 我可以把所有向量都放在内存中,然后再写入磁盘。
- 我可以直接在磁盘上构建所有向量,使用pickle库或类似的工具。
- 我可以一次在内存中构建一个向量,然后写入磁盘,每个向量都要遍历一次文本库。
这三种选择都不太可行。第一种会占用所有系统内存,导致系统崩溃和变得非常慢。第二种因为IO操作太慢,所以效率低下。第三种可能比第二种还慢,原因是一样的。
目标
一个好的解决方案应该包括:
- 尽可能多地在内存中构建。
- 一旦内存满了,就把所有内容写入磁盘。
- 如果需要从磁盘中获取数据,就把它们恢复到内存中,以便添加到向量中。
- 重复步骤1,直到所有向量都构建完成。
问题是我不太确定该如何进行。担心系统属性(比如内存)似乎有点不符合Python的风格,但我觉得不考虑这些问题就很难找到最佳解决方案。因此,我不知道该如何开始。
问题
有没有人知道该如何解决这个问题?Python是否不适合这种情况?或者有没有简单的方法来最大化内存使用(在合理范围内),同时最小化从磁盘读取或写入数据的次数?
非常感谢你的关注。我期待看到StackOverflow的聪明人们能给我提供什么建议。
附加细节
这个问题运行的机器通常有20个以上的核心和大约70G的内存。这个问题可以进行并行处理(类似MapReduce),即可以从文本库的不同部分构建一个实体的独立向量,然后将它们合并,得到从整个文本库构建的向量。
部分问题涉及确定在需要写入磁盘之前,内存中可以构建多少内容。Python是否提供了某种机制来确定可用的内存?