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

时间:2020-04-05 20:49:13

标签: python machine-learning redis nlp spacy

我有两个文件,file1.py,其ML模型大小为1GB,file2.py,它从file1调用get_vec()方法,并接收向量。每次调用file1 get_vec()方法时,都会加载ML model。从磁盘加载模型需要花费大量时间(大约10s)。

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

示例代码如下

# File1.py

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

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

File2.py

from File1 import get_vec

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

因此,在这里,每个呼叫要花费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)

它引发错误

DataError: Invalid input of type: 'English'. Convert to a bytes, string, int or float first.

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

有人可以建议我如何使其更快吗?谢谢。

5 个答案:

答案 0 :(得分:3)

在这里怎么做

第1步)在python中创建一个函数,然后在该函数中加载模型

model=None
def load_model():

    global model
    model = ResNet50(weights="imagenet")

如果您先仔细观察,则将变量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()

现在不使用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

因此,使用此技巧,您可以将模型冻结在RAM中,并使用全局变量进行访问。然后在您的代码中使用它。

答案 1 :(得分:1)

使用Flask。 在此处查看该用户如何尝试实现:Simple Flask app using spaCy NLP hangs intermittently

通过HTTP请求将数据帧数据发送到Flask。或者,您可以另存为文件,然后将其发送到服务器。

只需将模型加载到全局变量,然后在应用程序代码中使用该变量即可。

答案 2 :(得分:1)

如果所有语法正确,则此模型加载不应超过一次。 (仅在ml类的构造函数中)

# File1.py

import spacy
class ml:
   def __init__(self, model_path):
       self.nlp = spacy.load(model_path) # 'model'
   def get_vec(self, post):
       return self.nlp(post).vector


# File2.py

from File1 import ml

my_ml = ml('model') # pass model path

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

答案 3 :(得分:-2)

我不清楚您的问题。 nlp = spacy.load('model')此行在导入时仅在给定代码中执行一次。 由于每次致电get_vec都不会加载模型,即使每次致电get_vec花费10到12秒的时间,您的情况也无济于事。

答案 4 :(得分:-3)

训练后保存模型。
并开始使用python作为一种面向对象的编程语言,而不是脚本语言。

相关问题