Python 如何制作word2vec模型&x27;s加载时间和内存使用效率更高?

Python 如何制作word2vec模型&x27;s加载时间和内存使用效率更高?,python,nlp,nltk,gensim,word2vec,Python,Nlp,Nltk,Gensim,Word2vec,我想在web服务器(产品)中以两种不同的变体使用Word2vec,在这两种变体中,我从web上获取两个句子并实时比较。目前,我正在一台拥有16GB内存的本地机器上测试它 情景: w2v=负载w2v模型 If condition 1 is true: if normalize: reverse normalize by w2v.init_sims(replace=False) (not sure if it will work) Loop through some item

我想在web服务器(产品)中以两种不同的变体使用Word2vec,在这两种变体中,我从web上获取两个句子并实时比较。目前,我正在一台拥有16GB内存的本地机器上测试它

情景: w2v=负载w2v模型

If condition 1 is true:
   if normalize:
      reverse normalize by w2v.init_sims(replace=False) (not sure if it will work)
   Loop through some items:
   calculate their vectors using w2v
else if condition 2 is true:
   if not normalized:
       w2v.init_sims(replace=True)
   Loop through some items:
   calculate their vectors using w2v
我已经阅读了关于将词汇量减少到一个小规模的解决方案,但是我想使用所有的词汇量


在如何处理这个问题上有新的解决办法吗?有没有一种方法可以在最初的1-2分钟内加载一小部分词汇表,并同时加载整个词汇表

作为一种一次性延迟,您应该能够安排在任何服务请求之前发生,我建议您不要过于担心第一次
load()
时间。(将大量数据从磁盘加载到RAM本身就需要花费大量时间,但一旦加载到RAM,如果数据能够在各个进程之间妥善保存和共享,那么就不会再为任意长的服务正常运行时间花费成本。)

“在前1-2分钟加载一小部分词汇表,同时保持加载整个词汇表”没有多大意义——一旦需要任何相似性计算,就需要访问整个向量集以获得任何前N个结果。(所以“半加载”状态不是很有用。)

请注意,如果执行
init_sims(replace=True)
,则模型的原始向量幅值将与新的单位赋范(所有相同幅值)向量发生碰撞。因此,看看伪代码,这两条路径之间的唯一区别是显式的
init\u sims(replace=True)
。但是,如果在请求之间确实在内存中保留相同的共享模型,则只要出现
条件2
,该模型就会被规范化,此后在
条件1
下的调用也会使用规范化向量发生。此外,条件2下的附加调用只是冗余地(且代价高昂地)重新规范化向量。因此,如果规范化比较是您唯一关注的焦点,那么最好在服务启动时就地进行一次
init_sims(replace=True)
,而不是任由请求顺序摆布

如果您使用gensim的本机
save()
(而不是
save\u word2vec\u format()
)保存模型,并将其作为未压缩文件保存,则可以选择在将来重新加载时“内存映射”文件。这意味着,磁盘上的文件被简单地标记为提供寻址空间,而不是立即将完整的向量数组复制到RAM中。这样做有两个潜在的好处:(1)如果您甚至只访问阵列的某些有限范围,则只会根据需要加载这些范围;(2) 许多单独的进程都使用相同的映射文件,它们将自动重用加载到RAM中的任何共享范围,而不是潜在地复制相同的数据


(1) 当您需要对整个词汇表进行全面扫描时,这并不是一个很大的优势,因为它们都被带到RAM中,并且在访问时(这将比您只预加载它们有更多的服务延迟)。但是(2)在多进程Web服务器场景中仍然是一个优势。在我之前的回答中,有很多关于如何有效使用内存映射word2vec模型的详细信息,在

我不知道您的web服务器,但我确信在生产中,您只需要打开一次文件,并将向量保留在内存中,而不是在每次新会话中重新初始化它。这里的代码中没有它。所以我猜不出有什么样的解决方案。我已经在整个项目中使用一个全局变量来实现这一点,在第一次初始化模型时,我在其中设置了一个标志。然而,我更感兴趣的是如何减少第一次加载的时间。在这种情况下,第一次加载的时间意味着启动服务器的时间,对吗?是的。在这一点上,高效地使用内存也变得很重要,因为这个模型占用了几GB的内存。我不确定这一点:你可以很容易地检查:如果你有float64,你可以通过使其float32来减少内存大小。但这会降低精确度。减少词汇量是最好的解决方案。这样看:如果一个单词在语料库中只出现一次,那么它在word2vec中有一个随机初始化向量。这更多的是代码错误。我已采纳该守则。我仍然不确定是否可以反转normalize函数,因为我希望同时使用规范化模型和非规范化模型。我可以初始化两个不同的模型,但效率很低。除非使用非默认的
replace=True
,否则单个模型将保留原始向量和规范化向量。。。但余弦相似性(根据定义)仅对单位归一化向量起作用。