Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Gensim Doc2vec finalize_vocab内存错误_Python_Nlp_Gensim_Doc2vec - Fatal编程技术网

Python Gensim Doc2vec finalize_vocab内存错误

Python Gensim Doc2vec finalize_vocab内存错误,python,nlp,gensim,doc2vec,Python,Nlp,Gensim,Doc2vec,我正在尝试使用gensim培训一个Doc2Vec模型,该模型具有114M的独特文档/标签和约3M的独特单词的vocab大小。我在Azure上有115GB内存的linux机器。 当我运行build_vocab时,迭代器解析所有文件,然后抛出内存错误,如下所示 Traceback (most recent call last): File "doc_2_vec.py", line 63, in <module> model.build_vocab(sentences.

我正在尝试使用gensim培训一个Doc2Vec模型,该模型具有114M的独特文档/标签和约3M的独特单词的vocab大小。我在Azure上有115GB内存的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
根据top is的内存使用情况-

有人能告诉我预期的记忆是多少吗?更好的选择是——添加交换空间并减慢进程,或者添加更多内存,这样集群的成本最终可能是相等的。
gensim在内存中存储什么向量?为了提高内存利用率,我缺少的任何标志。

1.14亿个doctag将至少需要
1.14亿个doctags*300个维度*4个字节/float=136GB
,以便在训练期间存储原始doctag向量

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

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

因此,理想情况下,您需要更多的可寻址内存,或者一组更小的doctag

您提到了“集群”,但gensim
Doc2Vec
不支持多机分发

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

分别:

您对培训迭代和
alpha
学习率的管理存在缺陷。您在数据上实现了两次传递,值分别为0.025和0.023,即使每个
train()
调用都尝试默认的5次传递,但只是从不可重启的
语句中获得一次迭代

您应该瞄准更多的过程,模型以更少的代码行管理
alpha
从初始高值到默认的最终极小
min_alpha
值。您只需调用
train()
一次,除非您完全确定需要在多个调用之间执行额外的步骤。(此处未显示任何要求。)

通过将
改为\u array()
改为
改为\u iter()
,然后将
语句
单独传递给模型(而不是
语句.改为\u array()
),使您的
语句
对象成为一个真正的可重复多次的对象


然后用这个multiply-iterable对象调用
train()
一次,让它从高到低平滑地执行指定次数的迭代。(从
Word2Vec
继承的默认值是5次迭代,但在已发布的
Doc2Vec
工作中更常用10到20次。默认值
min_alpha
为0.0001,几乎不应更改。)

根据后面的建议更改了代码。我希望现在天气好。谢谢,谢谢你的回答。关于“docvecs_mapfile”参数,我将阅读它的工作原理。您可以参考一些源代码来了解各种参数是如何工作的,或者浏览gensim Doc2vec代码就足够了吗?
DocvecsArray
类的源代码和文档注释–可能会有所帮助。它是
model.docvecs
中对象的类。您可能还希望搜索项目讨论列表–查找先前提到的
docvecs\u mapfile
。代码更改为使您的
labeledLineSession
class a真正易读,然后让对
train()
管理时代并平滑阿尔法衰减的单个调用看起来很好。另一个注意事项-如果您的核心数超过8,则当
工人数等于核心数时,您可能无法获得更高的吞吐量。Python(GIL)和gensim实现中仍然存在一些固有的多线程瓶颈,因此训练吞吐量(以每秒训练的语料库单词数计算)通常会在16个线程以下。
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)