Rq: Precargar modelo de aprendizaje profundo

Creado en 16 may. 2019  ·  4Comentarios  ·  Fuente: rq/rq

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

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.

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()

Todos 4 comentarios

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()
¿Fue útil esta página
0 / 5 - 0 calificaciones