【问题标题】:How to avoid reloading ML model every time when I call python script?每次调用python脚本时如何避免重新加载ML模型?
【发布时间】:2020-07-17 19:58:09
【问题描述】:

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

我想以某种方式告诉 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(),它需要转换成合适的格式。所以我也尝试使用 pickle 来转换它。但同样,pickle 在编码和解码方面花费了大量时间。有没有办法将它存储在 Redis 中?

谁能建议我怎样才能让它更快?谢谢。

【问题讨论】:

标签: python machine-learning redis nlp spacy


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    通过 HTTP 请求将您的数据帧数据发送到您的 Flask。或者您可以将文件保存为文件并将文件发送到服务器。

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

    【讨论】:

      【解决方案3】:

      我不清楚你的问题。 nlp = spacy.load('model') 此行在导入时仅在给定代码中执行一次。 由于每次调用 get_vec 都不会加载模型,即使每次调用 get_vec 需要 10-12 秒,那么在你的情况下什么也做不了。

      【讨论】:

      • 感谢您的建议。 get_vec() 平均只需 12 毫秒。
      【解决方案4】:

      如果您的所有语法都正确,则不应多次加载模型。 (只在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))
      
      

      【讨论】:

      • 感谢您的评论。我尝试了这段代码,但没有提高速度。由于我从终端调用file2.py,我认为在执行之后,文件变量被破坏了。我已经更新了这个问题。请看。
      • 这与 spacy 如何在内部加载模型和管理缓存有关,您的问题应该完全改写。
      【解决方案5】:

      这是怎么做的

      第 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 中,使用全局变量访问它。然后在你的代码中使用它。

      【讨论】:

      • 这似乎是正确的做法。这意味着我必须在 Flask 中托管我的模型以使其快速运行。感谢您的建议。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 2019-12-11
      • 1970-01-01
      • 2018-01-06
      • 2021-02-12
      相关资源
      最近更新 更多