gpt4 book ai didi

docker - 如何将 gensim 的 KeyedVectors 对象存储在 Redis 队列工作程序内的全局变量中

转载 作者:行者123 更新时间:2023-12-02 19:54:47 25 4
gpt4 key购买 nike

我正在尝试将数据存储在 Redis 队列 (RQ) 工作程序内的全局变量中,以便这些数据保持预加载,即不需要为每个 RQ 作业加载它。

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

我的应用程序在 Python Flask 中,在 Linux 服务器上运行,使用 Docker 进行容器化。

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

我首先尝试将它们存储在 Flask 中的全局变量中,但随后我的 8 个 gunicorn 工作人员中的每一个都加载了向量,这会占用大量 RAM。

我只需要一个 worker 来存储一个特定的向量文件。

有人告诉我,一种解决方案是让一组 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()

应用程序.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 一起使用。

任何建议将不胜感激!

最佳答案

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

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

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

在对模型想要重复单位范数的向量进行相似性运算时,需要考虑一些额外的问题 - 有关如何解决该问题的更多详细信息,请参阅这个较旧的答案:

How to speed up Gensim Word2vec model load time?

(请注意,syn0syn0_norm 已在较新的 vectors 版本中重命名为 vectors_normgensim,但旧名称可能仍会在一段时间内与弃用警告一起使用。)

关于docker - 如何将 gensim 的 KeyedVectors 对象存储在 Redis 队列工作程序内的全局变量中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58797101/

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