Tengo un modelo de aprendizaje profundo que se carga en la GPU
Quiero precargarlo y reutilizarlo cada vez que ejecuto job.
Encontré https://python-rq.org/docs/workers/#performance -notes, pero no sé cómo acceder a los objetos desde el código de trabajo
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
Encontré una solución usando un trabajador personalizado para pasar el modelo cargado a la función de trabajo
¡pero esto se ve feo!
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, no sé si podrías hacerlo mejor. Probablemente así es como yo también lo haría. ¿Por qué crees que es feo?
@hnykda Es feo porque estoy violando la encapsulación de la clase Worker cambiando su variable args. Originalmente, debería representar valores pasados de la persona que llama "result = q.enqueue (predict," 1.jpeg ")" ¡Solo hay un parámetro!
pero he encontrado una mejor solución
Finalmente, entendí cómo esto debería funcionar. RQ usa importlib.import_module para cargar la función. Entonces, cada vez que llama a la función, carga el archivo de trabajos. Entonces, según tengo entendido, para solucionar esto, debe cargar este archivo ANTES de la ejecución del trabajador.
import library_that_you_want_preloaded
debe ser reemplazado con
from job import predict
no esta
import cv2
import numpy as np
from cv.cnn_model import init_model, predict
__model = init_model("config.json", "weights.data")#loads to GPU
Mi guión final se ve así
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
trabajador.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()
Comentario más útil
Finalmente, entendí cómo esto debería funcionar. RQ usa importlib.import_module para cargar la función. Entonces, cada vez que llama a la función, carga el archivo de trabajos. Entonces, según tengo entendido, para solucionar esto, debe cargar este archivo ANTES de la ejecución del trabajador.
debe ser reemplazado con
no esta
Mi guión final se ve así
job.py
trabajador.py