每次调用python脚本时如何避免重新加载ML模型?

Sam*_*ual 5 python nlp machine-learning redis spacy

我有两个文件,file1.py它们的 ML 模型大小为 1GB,file2.py它们get_vec()从 file1调用方法并接收向量作为回报。model每次调用 file1 get_vec() 方法时都会加载ML 。这是从磁盘加载模型需要大量时间(大约 10 秒)的地方。

我想以某种方式告诉 file1 不要每次都重新加载模型,而是利用早期调用中加载的模型。

示例代码如下

# File1.py

import spacy
nlp = spacy.load('model')

def get_vec(post):
    doc = nlp(post)
    return doc.vector

Run Code Online (Sandbox Code Playgroud)
File2.py

from File1 import get_vec

df['vec'] = df['text'].apply(lambda x: get_vec(x))

Run Code Online (Sandbox Code Playgroud)

所以在这里,每次调用需要 10 到 12 秒。这看起来很小的代码,但它是一个大项目的一部分,我不能把它们放在同一个文件中。

更新1:

我做了一些研究,并知道我可以使用 Redis 在它第一次运行时将模型存储在缓存中,此后我可以直接从缓存中读取模型。我尝试使用Redis进行测试,如下所示

import spacy
import redis

nlp = spacy.load('en_core_web_lg')
r = redis.Redis(host = 'localhost', port = 6379, db = 0)
r.set('nlp', nlp)
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误

DataError: Invalid input of type: 'English'. Convert to a bytes, string, int or float first.
Run Code Online (Sandbox Code Playgroud)

似乎,type(nlp)English(),它需要以合适的格式进行转换。所以我也尝试使用泡菜来转换它。但同样,pickle 在编码和解码上花费了大量时间。有没有办法将它存储在Redis中?

有人可以建议我如何让它更快吗?谢谢。

Aji*_*kya 6

这是如何做到的

步骤 1)在 python 中创建一个函数并在该函数中加载您的模型

model=None
def load_model():

    global model
    model = ResNet50(weights="imagenet")
Run Code Online (Sandbox Code Playgroud)

如果您首先仔细观察,我将变量分配model给了 None。然后在load_model函数内部我加载了一个模型。

另外我确保变量model是全局的,以便可以从这个函数外部访问它。这里的直觉是我们在全局变量中加载模型对象。这样我们就可以在代码中的任何地方访问这个变量。

现在我们已经准备好了我们的工具(即我们可以从代码中的任何地方访问模型)让我们在您的计算机 RAM 中冻结这个模型。这是通过以下方式完成的:

if __name__ == "__main__":
    print(("* Loading Keras model and Flask starting server..."
        "please wait until server has fully started"))
    load_model()
    app.run()
Run Code Online (Sandbox Code Playgroud)

现在在不使用它的情况下在 RAM 中使用冻结模型有什么用。所以,要使用它,我在烧瓶中使用 POST 请求

@app.route("/predict", methods=["POST"])
def predict():

    if flask.request.method == "POST":

            output=model.predict(data)  #what you want to do with frozen model goes here
Run Code Online (Sandbox Code Playgroud)

所以使用这个技巧你可以在 RAM 中冻结模型,使用全局变量访问它。然后在您的代码中使用它。