Ich habe ein Deep-Learning-Modell, das in die GPU geladen wird
Ich möchte es jedes Mal vorladen und wiederverwenden, wenn ich einen Job ausführe.
Ich habe https://python-rq.org/docs/workers/#performance -notes gefunden, weiß aber nicht, wie ich über den Jobcode auf Objekte zugreifen kann
custom_worker.py
import sys
from rq import Connection, Worker, SimpleWorker
import cv2
import numpy as np
from cv.cnn_model import init_model, predict
__model = init_model("config.json", "weights.data")#loads to GPU
with Connection():
qs = sys.argv[1:] or ['default']
w = SimpleWorker(qs)
w.work()
job.py
def detect(image_path):
image = cv2.imread(image_path)
data = predict(__model, image) #should use preloaded __model
return data
Ich habe eine Lösung mit einem benutzerdefinierten Worker gefunden, um das geladene Modell an die Jobfunktion zu übergeben
aber das sieht hässlich aus!
class CustomWorker(SimpleWorker):
def __init__(self, *args, **kwargs):
self.__model = init_model("config.json", "weights.data")
SimpleWorker.__init__(self, *args, **kwargs)
def execute_job(self, job, queue):
job.args = (job.args[0], self.__model)
return self.perform_job(job, queue)
job.py
def detect(image_path, model):
image = cv2.imread(image_path)
data = predict(model, image) #used preloaded model
return data
TBH Ich weiß nicht, ob Sie es besser machen könnten. So würde ich es wahrscheinlich auch machen. Warum findest du es hässlich?
@hnykda Es ist hässlich, weil ich die Kapselung der Arbeiterklasse verletze, die ihre args-Variable ändert. Ursprünglich sollte es Werte darstellen, die vom Aufrufer übergeben werden "result = q.enqueue(predict, "1.jpeg")" Es gibt nur einen Parameter!
aber ich habe eine bessere lösung gefunden
Endlich habe ich verstanden, wie das funktionieren soll. RQ verwendet importlib.import_module zum Laden der Funktion. Jedes Mal, wenn Sie die Funktion aufrufen, lädt sie die Jobdatei. Soweit ich weiß, sollten Sie diese Datei VOR der Ausführung des Workers laden.
import library_that_you_want_preloaded
sollte ersetzt werden durch
from job import predict
nicht das
import cv2
import numpy as np
from cv.cnn_model import init_model, predict
__model = init_model("config.json", "weights.data")#loads to GPU
Mein letztes Skript sieht so aus
job.py
import cv2
import numpy as np
from cv.cnn_model import init_model, predict
def init_weights():
global __model
__model =init_model("config.json", "weights.data")
def predict(image_path):
image = cv2.imread(image_path)
data = predict(__model, image)
return data
worker.py
import sys
from rq import Connection, SimpleWorker
from job import predict, init_weights
with Connection():
qs = sys.argv[1:] or ['default']
init_weights()#I initialize model before workers start
w = SimpleWorker(qs)#I use SimpleWorker because it does not fork
w.work()
Hilfreichster Kommentar
Endlich habe ich verstanden, wie das funktionieren soll. RQ verwendet importlib.import_module zum Laden der Funktion. Jedes Mal, wenn Sie die Funktion aufrufen, lädt sie die Jobdatei. Soweit ich weiß, sollten Sie diese Datei VOR der Ausführung des Workers laden.
sollte ersetzt werden durch
nicht das
Mein letztes Skript sieht so aus
job.py
worker.py