gpt4 book ai didi

python - Gensim Doc2vec Finalize_vocab 内存错误

转载 作者:太空宇宙 更新时间:2023-11-03 14:50:00 25 4
gpt4 key购买 nike

我正在尝试使用 gensim 训练 Doc2Vec 模型,其中包含 114M 唯一文档/标签和大约 3M 唯一单词的词汇大小。我在 Azure 上有 115GB Ram linux 机器。当我运行 build_vocab 时,迭代器会解析所有文件,然后抛出内存错误,如下所示。

    Traceback (most recent call last):
File "doc_2_vec.py", line 63, in <module>
model.build_vocab(sentences.to_array())
File "/home/meghana/.local/lib/python2.7/site-packages/gensim/models/word2vec.py", line 579, in build_vocab
self.finalize_vocab(update=update) # build tables & arrays
File "/home/meghana/.local/lib/python2.7/site-packages/gensim/models/word2vec.py", line 752, in finalize_vocab
self.reset_weights()
File "/home/meghana/.local/lib/python2.7/site-packages/gensim/models/doc2vec.py", line 662, in reset_weights
self.docvecs.reset_weights(self)
File "/home/meghana/.local/lib/python2.7/site-packages/gensim/models/doc2vec.py", line 390, in reset_weights
self.doctag_syn0 = empty((length, model.vector_size), dtype=REAL)
MemoryError

我的代码-

import parquet
import json
import collections
import multiprocessing


# gensim modules
from gensim import utils
from gensim.models.doc2vec import LabeledSentence
from gensim.models import Doc2Vec

class LabeledLineSentence(object):
def __init__(self, sources):
self.sources = sources
flipped = {}

def __iter__(self):
for src in self.sources:
with open(src) as fo:
for row in parquet.DictReader(fo, columns=['Id','tokens']):
yield LabeledSentence(utils.to_unicode(row['tokens']).split('\x01'), [row['Id']])

## list of files to be open ##
sources = glob.glob("/data/meghana_home/data/*")
sentences = LabeledLineSentence(sources)

#pre = Doc2Vec(min_count=0)
#pre.scan_vocab(sentences)
"""
for num in range(0, 20):
print('min_count: {}, size of vocab: '.format(num), pre.scale_vocab(min_count=num, dry_run=True)['memory']['vocab']/700)
print("done")
"""

NUM_WORKERS = multiprocessing.cpu_count()
NUM_VECTORS = 300
model = Doc2Vec(alpha=0.025, min_alpha=0.0001,min_count=15, window=3, size=NUM_VECTORS, sample=1e-4, negative=10, workers=NUM_WORKERS)
model.build_vocab(sentences)
print("built vocab.......")
model.train(sentences,total_examples=model.corpus_count, epochs=10)

顶部的内存使用情况是-

enter image description here

有人可以告诉我预期内存是多少吗?什么是更好的选择 - 添加交换空间并减慢进程或添加更多内存,以便集群的成本最终可能相等。gensim 在内存中存储哪些向量?我缺少内存有效使用的任何标志。

最佳答案

1.14 亿个文档标签至少需要 114,000,000 doctags * 300 dimensions * 4 bytes/float = 136GB只是为了在训练期间存储原始文档标签向量。

(如果 doctag 键 row['Id'] 是字符串,则记住字符串到整数索引映射字典会产生额外的开销。如果 doctag 键是从 0 到 114 百万的原始整数,这将避免填充如果 doctag 键是原始整数,但包含任何大于 1.14 亿的整数,则模型将尝试分配一个足够大的数组以包含最大整数的行 - 即使许多其​​他较低的整数未使用。)

原始词向量和模型输出层 ( model.syn1 ) 将需要大约 8GB,词汇词典还需要几 GB。

因此,您理想情况下需要更多的可寻址内存,或更小的文档标签集。

你提到了一个“集群”,但是 gensim Doc2Vec不支持多机分发。

对于这些算法来说,使用交换空间通常是一个坏主意,因为它可能涉及大量的随机访问,因此在交换过程中变得非常慢。但对于 Doc2Vec 的情况,您可以使用 Doc2Vec.__init__() 将其 doctags 数组设置为由内存映射文件提供服务。可选参数docvecs_mapfile 。如果每个文档都有一个标签,并且这些标签在每次重复扫描训练文本时都以相同的升序出现,那么性能可能是可以接受的。

分别:

您对培训迭代和 alpha 的管理学习率有问题。您将在 alpha 处对数据进行 2 次传递。值 0.025 和 0.023,即使每个 train()调用正在尝试默认的 5 次传递,但随后仅从不可重新启动的 sentences.to_array() 中获取单次迭代目的。

您应该争取更多的通过,模型管理 alpha从最初的高点到默认的最终极点 min_alpha值,用更少的代码行。您只需调用 train()除非您绝对确定需要在多次调用之间执行额外的步骤。 (这里没有显示任何要求。)

让你的sentences object 一个真正的可迭代对象,可以通过更改 to_array() 来迭代多次。至__iter__() ,然后传递 sentences单独(而不是 sentences.to_array() )到模型。

然后调用train()一次使用这个可多次迭代的对象,并让它以平滑 alpha 进行指定次数的迭代从高到低更新。 (从 Word2Vec 继承的默认值是 5 次迭代,但在已发布的 Doc2Vec 工作中更常用 10 到 20 次。默认值 min_alpha 0.0001 几乎不应该更改。)

关于python - Gensim Doc2vec Finalize_vocab 内存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45943832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com