我从英语维基百科转储中提取了145,185,965个句子(14GB),我想根据这些句子训练一个Doc2Vec模型。不幸的是,我只有'32GB的RAM,并且在尝试训练时得到 MemoryError 。即使我将min_count设置为50,gensim告诉我它需要超过150GB的RAM。我不认为进一步增加min_count是个好主意,因为结果模型不是很好(只是一个猜测)。但无论如何,我会用500来试试看内存是否足够。
有没有可能用有限的RAM训练这么大的模型?
这是我目前的代码:
corpus = TaggedLineDocument(preprocessed_text_file)
model = Doc2Vec(vector_size=300,
window=15,
min_count=50, #1
workers=16,
dm=0,
alpha=0.75,
min_alpha=0.001,
sample=0.00001,
negative=5)
model.build_vocab(corpus)
model.train(corpus,
epochs=400,
total_examples=model.corpus_count,
start_alpha=0.025,
end_alpha=0.0001)
我可能会犯一些明显的错误吗?使用它完全错了吗?
我也可以尝试减少矢量大小,但我认为这会导致更糟糕的结果,因为大多数论文都使用300D矢量。
答案 0 :(得分:3)
可寻址存储器中所需的模型大小很大程度上取决于所需的权重数量,唯一字数和唯一doc标签的数量。
拥有145,000,000个独特的doc-tags,无论你限制自己有多少单词,只需要训练中的原始doc-vectors就可以了:
145,000,000 * 300 dimensions * 4 bytes/dimension = 174GB
您可以尝试较小的数据集。您可以减小矢量大小。你可以获得更多的记忆。
我会首先尝试其中的一个或多个,只是为了验证你能够让事情有效并取得一些初步结果。
有一个技巧,最好被认为是实验性的,可以用来培训更大的doc-vector集合,但代价是额外的复杂性和较低的性能:docvecs_mapfile
的{{1}}参数。 / p>
通常,您不希望Doc2Vec
/ Word2Vec
式训练会话使用任何虚拟内存,因为任何使用较慢磁盘IO的方法都会导致训练速度极慢。但是,对于只在一个顺序中迭代的大型doc-set,在使doc-vectors数组由内存映射文件支持之后,性能命中可能是可存活的。基本上,每个训练传递从字体到后面扫描文件,一次读取每个部分并将其分页一次。
如果提供Doc2Vec
参数,docvecs_mapfile
将分配doc-vectors数组以供该磁盘文件支持。因此,您将在磁盘上拥有数百GB的文件(理想情况下为SSD),其范围根据需要在RAM中进行分页。
如果您尝试这样做,请务必首先在小型运行中试验此选项,以熟悉其操作,尤其是在保存/加载模型时。
另请注意,如果您在doc-vectors上执行默认Doc2Vec
,则必须从原始数组创建另一个174GB的单位规范化向量数组。 (您可以强制执行此操作,通过在调用需要单元规范向量的任何其他方法之前显式调用most_similar()
调用来破坏现有原始值。)