代码之家  ›  专栏  ›  技术社区  ›  Konrad HelloWorld101

如何使用辅助进程初始化时使用的变量启动celery worker

  •  1
  • Konrad HelloWorld101  · 技术社区  · 7 年前

    我写的服务器将负责机器学习培训和评估。我想动态启动worker的新实例,并将变量传递给它,该变量将用于加载内部的特定模型。

    我从答案中找到了如何开始工作 here 具有 worker_main 方法。

    我在想两种解决方案:

    1. 设置为环境变量。此解决方案的问题是,当同时创建两个worker实例时,它可能会被破坏。

    2. 作为argv传递,但我不知道如何读取worker内部的变量。


    编辑

    我发现了 this

    灵感来自 this 我试着用芹菜信号。 http://docs.celeryproject.org/en/latest/userguide/signals.html#worker-init

    2 回复  |  直到 7 年前
        1
  •  4
  •   Konrad HelloWorld101    7 年前

    也许我的问题不够准确,但我自己用doc和stackoverflow线程找到了答案。

    我想为Keras模型运行单独的工人。在worker初始化中,我需要将模型加载到内存中,而在任务中,模型用于预测。

    我的解决方案:

    1. 型号\u id
    2. 打开 signal函数在worker中解析了名称并设置了全局变量
    3. 打开 信号函数我加载的模型在我的例子中,它是Grasper类中的静态字段

    下面写一些代码来精确描述解决方案。

    from celery.signals import worker_process_init, celeryd_after_setup
    from celery.concurrency import asynpool
    
    # my custom class containing static fields for model and tokenizer
    # it also can be global variable as model_id
    from myapp.ml import Grasper
    
    # set to have some time for model loading otherwise worker_process_init can terminate
    asynpool.PROC_ALIVE_TIMEOUT = 100.0
    model_id = None
    
    @celeryd_after_setup.connect()
    def set_model_id(sender, instance, **kwargs):
        global model_id
        model_id = instance.hostname.split('@')[1]
    
    @worker_process_init.connect()
    def configure_worker(signal=None, sender=None, **kwargs):
        Grasper.load_model(model_id)
    

    然后在celery任务中,您可以使用Grasper类和加载的模型。 这个解决方案是可行的,但我知道还有一个地方需要改进,所以如果你有什么想法,请发表意见。

        2
  •  0
  •   Nino Walker    7 年前

    Is there a way to change the environment variables of another process in Unix? )

    os.environ 并生成工作进程。在worker作为一个单独的进程生成之后,释放锁,您就不必担心通过修改父进程的环境而损坏子进程。

    推荐文章