【发布时间】:2011-09-11 21:08:11
【问题描述】:
背景
我正在为一个计算语言学项目做一个计算量相当大的项目,但我遇到的问题非常普遍,因此我希望其他人也会感兴趣的解决方案。
要求
我必须编写的这个特定程序的关键方面是它必须:
- 通读大型语料库(介于 5G 和 30G 之间,可能还有更大的内容)
- 处理每一行的数据。
- 根据这些处理过的数据,构造大量向量(其中一些向量的维数 > 4,000,000)。通常它会构建数十万个这样的向量。
- 这些向量必须全部以某种格式保存到磁盘。
第 1 步和第 2 步并不难高效完成:只需使用生成器并拥有数据分析管道即可。最大的问题是操作 3(以及连接 4)
括号:技术细节
如果构建向量的实际过程影响解决方案:
对于语料库中的每一行,一个或多个向量必须更新其基础权重。
如果您从 python 列表的角度来考虑它们,每一行在处理时都会更新一个或多个列表(如果需要,创建它们),方法是将这些列表在一个或多个索引处的值增加一个值(可能不同基于指数)。
向量不相互依赖,语料库行的读取顺序也无关紧要。
尝试的解决方案
关于如何做到这一点,有三个极值:
- 我可以在内存中构建所有向量。然后将它们写入磁盘。
- 我可以使用 pickle 架子或类似的库直接在磁盘上构建所有向量。
- 我可以一次在内存中构建一个向量并将其写入磁盘,每个向量通过语料库一次。
所有这些选项都相当棘手。 1 只是用完所有系统内存,它会恐慌并缓慢爬行。 2 太慢了,因为 IO 操作并不快。出于同样的原因,3 可能甚至比 2 还要慢。
目标
一个好的解决方案包括:
- 尽可能多地在内存中构建。
- 内存已满后,将所有内容转储到磁盘。
- 如果再次需要磁盘中的位,请将它们恢复到内存中以将内容添加到这些向量中。
- 回到 1,直到构建所有向量。
问题是我不太确定该怎么做。担心诸如 RAM 之类的系统属性似乎有些不合情理,但我看不出如何在不考虑这一点的情况下以最佳方式解决此类问题。结果,我真的不知道如何开始做这种事情。
问题
有谁知道如何解决这类问题?我的 python 根本不是这种事情的正确语言?或者是否有一个简单的解决方案可以最大限度地(在合理范围内)从内存中完成多少工作,同时最大限度地减少必须从磁盘读取或写入数据的次数?
非常感谢您的关注。我期待看到 stackoverflow 的聪明才智可以为我带来什么。
其他详情
运行此问题的机器通常有 20 多个内核和约 70G 的 RAM。这个问题可以并行化(就像 MapReduce),因为可以从语料库的片段构建一个实体的单独向量,然后将其相加以获得从整个语料库构建的向量。
问题的一部分涉及确定在需要进行磁盘写入之前可以在内存中构建多少限制。 python 是否提供任何机制来确定有多少可用 RAM?
【问题讨论】:
-
取决于向量的构建方式以及它们是否相互依赖。
-
@knitti 感谢您的提问。我不知道它是否与解决方案有关,但我相信你的直觉。我已将您问题的答案(希望如此!)添加到问题描述中的“技术细节”部分。
-
您的结果集(向量)需要 TB 区域中的空间(天真估计为 4 000 000 x 100 000 x 1..2 字节),因此通过语料库实际上是较小的问题。你打算怎么写数据?
-
@knitti 向量通常相当稀疏。在实践中,我使用 numpy.sparse.lil_matrix 实例,并将它们编写为 .npy 文件,但我愿意以不同的方式做事。
-
听起来像是 Hadoop 的一个大的 map/reduce 问题:第一遍,map 从每个输入文件创建一个向量文件,第二遍,reduce 将输出文件合并为一个。