在某一层面上,如果您需要它在内存中,这就是将千兆字节以上从磁盘读取到有用的 RAM 结构所需的时间,那么是的 - 这就是进程准备好使用该数据所需的时间.但是还有优化的空间!
例如,将其作为第一个 Pandas 数据帧读取,然后将其转换为 Python 字典,比其他选项涉及更多的步骤和更多的 RAM。 (在瞬间高峰,当glove_pd 和glove 都被完全构造和引用时,你将在内存中有两个完整的副本——而且都没有理想的紧凑,这可能会引发其他减速,特别是如果膨胀触发使用任何虚拟内存。)
正如您所担心的,如果 3 个 gunicorn 工作人员各自运行相同的加载代码,则会加载相同数据的 3 个单独副本 - 但有一种方法可以避免这种情况,如下所示。
我建议首先将向量加载到用于访问词向量的实用程序类中,例如 Gensim 库中的 KeyedVectors 接口。它将所有向量存储在一个紧凑的 numpy 矩阵中,并带有一个类似 dict 的接口,仍然为每个单独的向量返回一个 numpy ndarray。
例如,您可以将 GLoVe 文本格式向量转换为稍微不同的交换格式(带有一个额外的标题行,Gensim 在原始 Google word2vec.c 代码使用它后调用 word2vec_format)。在gensim-3.8.3(截至 2020 年 8 月的当前版本)中,您可以:
from gensim.scripts.glove2word2vec import glove2word2vec
glove2word2vec('glove.6B.300d.txt', 'glove.6B.300d.w2vtxt')
然后,实用程序类KeyedVectors 可以像这样加载它们:
from gensim.models import KeyedVectors
glove_kv = KeyedVectors.load_word2vec_format('glove.6B.300d.w2vtxt', binary=False)
(从未来的gensim-4.0.0 版本开始,应该可以跳过转换& 只需使用新的no_header 参数直接读取GLoVe 文本文件:glove_kv = KeyedVectors.load_word2vec_format('glove.6B.300d.w2vtxt', binary=False, no_header=True)。但是这种无标题格式会有点速度较慢,因为它需要两次遍历文件 - 第一次学习完整大小。)
只加载一次到KeyedVectors 应该已经比原来的通用两步过程更快、更紧凑。而且,类似于您在先前的字典中所做的查找将在 glove_kv 实例上可用。 (此外,还有许多其他便利操作,例如排名.most_similar() 查找,它们利用高效的数组库函数来提高速度。)
不过,您可以采取另一个步骤,最大限度地减少加载时解析,并延迟加载整个向量集的不需要范围,并在进程之间自动重用原始数组数据。
额外的步骤是使用 Gensim 实例的 .save() 函数重新保存向量,该函数会将原始向量转储到一个单独的密集文件中,该文件适用于下次加载时的内存映射。所以首先:
glove_kv.save('glove.6B.300d.gs')
这将创建多个文件,如果重新定位,这些文件必须保存在一起 - 但保存的 .npy 文件将是内存映射准备好的最小格式。
然后,稍后需要时,加载为:
glove_kv = KeyedVectors.load('glove.6B.300d.gs', mmap='r')
mmap 参数使用底层操作系统机制将相关矩阵地址空间简单地映射到磁盘上的(只读)文件,因此初始“加载”实际上是即时的,但任何尝试矩阵的访问范围将使用虚拟内存来分页文件的正确范围。因此,它消除了任何扫描分隔符并将 IO 推迟到绝对需要。 (如果有任何你永远不会访问的范围?它们永远不会被加载。)
内存映射的另一大好处是,如果多个进程每个只读内存映射相同的磁盘文件,操作系统就足够智能,可以让它们共享任何公共的分页范围。因此,如果有 3 个完全独立的操作系统进程,每个进程都映射同一个文件,您可以节省 3 倍的 RAM。
(如果在所有这些更改之后,重新启动服务器进程的延迟仍然是一个问题 - 可能是因为服务器进程崩溃或需要经常重新启动 - 你甚至可以考虑使用一些 other long-lived , 稳定的进程来初始映射向量。然后,即使所有服务器进程崩溃也不会导致操作系统丢失文件的任何分页范围,并且服务器进程的重新启动可能会找到部分或全部相关数据已经在 RAM 中。但是一旦其他优化到位,这个额外角色的复杂性可能是多余的。)
一个额外的警告:如果您开始使用 KeyedVectors 之类的 .most_similar() 方法,它可以(直到 gensim-3.8.3)触发创建单位长度规范化字向量的全尺寸缓存,您可以除非您采取一些额外的步骤来缩短该过程,否则将失去 mmap 的好处。在之前的答案中查看更多详细信息:How to speed up Gensim Word2vec model load time?