如何将gensim的KeyedVectors对象存储在Redis Queue worker内部的全局变量中

我正在尝试将数据存储在Redis Queue(RQ)工作器内的全局变量中,以便使此数据保持预加载状态,即不需要为每个RQ作业都加载该数据。

具体来说,我正在使用Word2Vec矢量,并使用gensim的KeyedVectors加载它们。

我的应用程序位于Python flask中,在Linux服务器上运行,并使用Docker进行了容器化。

我的目标是通过始终将少量大矢量文件加载到内存中来减少处理时间。

我首先尝试将它们存储在flask中的全局变量中,但是随后我的8名古吉康工人中的每一个 加载了向量,这会占用大量RAM。

我只需要一个 工人即可存储特定的矢量文件。

有人告诉我一种解决方案是让一定数量的RQ工作人员将矢量保存在全局变量中,以便我可以控制哪些工作人员将哪些矢量文件加载到其中。

这是我到目前为止所拥有的:

RQ_worker.py

from rq import Worker,Connection
from gensim.models.keyedvectors import KeyedVectors
from my_common_methods import get_redis

W2V = KeyedVectors.load_word2vec_format('some_path/vectors.bin',binary=True)

def rq_task(some_args):
    # use some_args and W2V to do some processing,e.g.:
    with open(some_args_filename,'w') as f_out:
        f_out.write(str(W2V['word']))

if __name__ == '__main__':
    with Connection(get_redis()):
        worker = Worker(['default'])
        worker.work()

app.py

from rq import Queue,Connection
from RQ_worker import rq_task

@app.route("/someroute",methods=['POST'])
def some_route():
    # test Redis Queue
    with Connection(get_redis()):
        q = Queue()
        task = q.enqueue(rq_task,some_args)

docker-stack.yml

version: '3.7'

services:
  nginx:
    image: nginx:mainline-alpine
    deploy: ...
    configs: ...
    networks: ...

  flask:
    image: ...
    deploy: ...
    environment: ...
    networks: ...
    volumes: ...

  worker:
    image: ...
    command: python2.7 RQ_worker.py
    deploy:
      replicas: 1
    networks: ...
    volumes:
      - /some_path/data:/some_path/data

configs:
  nginx.conf:
    external: true
    name: nginx.conf

networks:
  external:
    external: true
  database:
    external: true

(我从Docker中删除了很多东西,但是可以提供更多详细信息,如果相关的话。)

上面的方法通常有效,除了 ,RQ工作者每次获得新工作似乎都从头开始加载W2V ,这违背了整个目的。它应该将向量存储在W2V中作为全局变量,这样就不必每次都重新加载它们。

我想念什么吗?我应该设置不同吗?

有人告诉我,可能可以使用mmap将矢量文件加载到RQ工作人员所在的全局变量中,但是我不确定KeyedVectors如何工作。

任何建议将不胜感激!

ahricher1 回答:如何将gensim的KeyedVectors对象存储在Redis Queue worker内部的全局变量中

如果您使用load_word2vec_format(),则代码将始终解析(非Gensim或Gensim或Python)字向量格式,并分配新的对象/内存来存储结果。

您可以改为使用gensim的本机.save()以更友好的格式存储,以便以后进行本机.load()的操作。向量的大数组将存储在单独的内存映射就绪文件中。然后,当您.load(...,mmap='r')使用这些文件时,即使多次来自同一容器中的不同线程或进程,它们也将共享同一RAM。

(请注意,这甚至不需要任何共享全局变量。操作系统会注意到每个进程都在请求相同的只读内存映射文件,并自动共享这些RAM页面。唯一的重复是冗余Python { {1}}个可帮助每个单独的dict知道共享数组中的索引。)

在对向量进行相似操作时,模型需要反复进行一些折皱处理,而模型将要对其进行重复的单位范数-有关如何解决该问题的更多详细信息,请参见此较早的答案

How to speed up Gensim Word2vec model load time?

(请注意,.load()syn0在最近的syn0_norm版本中已重命名为vectorsvectors_norm,但旧名称可能仍适用弃用警告一会儿。)

本文链接:https://www.f2er.com/3125935.html

大家都在问