我想在Web服务器(生产)中使用Word2vec两种不同的变体,我从网上获取两个句子并实时比较。目前,我正在一台具有16GB RAM的本地机器上进行测试。
方案: 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分钟内加载一小部分词汇表并且并行加载整个词汇表?
答案 0 :(得分:2)
作为一次性延迟,你应该能够安排在任何服务请求之前发生,我建议不要过多担心第一次load()
时间。 (它本来会花费大量时间将大量数据从磁盘加载到RAM中 - 但是一旦存在,如果它被保留并在进程之间共享,那么成本就不会再次花费任意长的服务时间。)
在最初的1-2分钟内加载一小部分词汇并且并行地保持加载整个词汇量并没有多大意义。 - 只要需要任何相似度计算,就需要访问任何前N个结果的整个向量集。 (所以"半载"状态不是非常有用。)
请注意,如果执行init_sims(replace=True)
,则模型的原始原始矢量幅度会被新的单位标准(全部相同幅度)矢量所破坏。因此,查看您的伪代码,两个路径之间的唯一区别是显式init_sims(replace=True)
。但是,如果您确实在请求之间在内存中保持相同的共享模型,则只要condition 2
发生,模型就会被标准化,此后condition 1
下的调用也会发生归一化向量。此外,condition 2
下的额外调用只是冗余地(并且昂贵地)对矢量进行原位重新规范化。因此,如果规范化比较是您唯一关注的焦点,那么最好在服务启动时进行一个就地init_sims(replace=True)
- 而不是受到请求顺序的影响。
如果您使用gensim的原生save()
(而不是save_word2vec_format()
)保存了模型,并且作为未压缩文件,可以选择&#39 ;存储器映射'将来重新加载的文件。这意味着不是立即将完整的矢量阵列复制到RAM中,而是将磁盘上的文件标记为提供寻址空间。这有两个潜在的好处:(1)如果你甚至只访问阵列的某些有限范围,只需要按需加载那些; (2)许多使用相同映射文件的独立进程将自动重用加载到RAM中的任何共享范围,而不是可能复制相同的数据。
(1)只要你需要对整个词汇表进行全面扫描,就不会有什么好处 - 因为它们全部被带入RAM,然后在访问时进一步(与您预先加载它们相比,它将具有更多的服务延迟)。但是(2)在多进程Web服务器场景中仍然是一个优势。关于如何在我的先前答案中有效使用内存映射的word2vec模型的详细信息,How to speed up Gensim Word2vec model load time?