Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 芹菜用火把_Python_Django_Multiprocessing_Pytorch_Celery - Fatal编程技术网

Python 芹菜用火把

Python 芹菜用火把,python,django,multiprocessing,pytorch,celery,Python,Django,Multiprocessing,Pytorch,Celery,我正在Django应用程序中运行PyTorch模型。由于不建议在视图中执行模型(或任何长时间运行的任务),我决定在芹菜任务中运行它。我的模型相当大,加载大约需要12秒,推断大约需要3秒。这就是为什么我决定不能在每次请求时都加载它。所以我尝试在“设置”中加载它,并将其保存在那里,以便应用程序使用它。因此,我的最终方案是: 当Django应用程序启动时,在设置中加载PyTorch模型,并且可以从应用程序访问该模型 当views.py收到请求时,它会延迟芹菜任务 芹菜任务使用settings.mod

我正在Django应用程序中运行PyTorch模型。由于不建议在视图中执行模型(或任何长时间运行的任务),我决定在芹菜任务中运行它。我的模型相当大,加载大约需要12秒,推断大约需要3秒。这就是为什么我决定不能在每次请求时都加载它。所以我尝试在“设置”中加载它,并将其保存在那里,以便应用程序使用它。因此,我的最终方案是:

  • 当Django应用程序启动时,在设置中加载PyTorch模型,并且可以从应用程序访问该模型
  • 当views.py收到请求时,它会延迟芹菜任务
  • 芹菜任务使用settings.model来推断结果
这里的问题是芹菜任务在尝试使用模型时抛出以下错误

[2020-08-29 09:03:04,015: ERROR/ForkPoolWorker-1] Task app.tasks.task[458934d4-ea03-4bc9-8dcd-77e4c3a9caec] raised unexpected: RuntimeError("Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method")
Traceback (most recent call last):
  File "/home/ubuntu/anaconda3/envs/tensor/lib/python3.7/site-packages/celery/app/trace.py", line 412, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/home/ubuntu/anaconda3/envs/tensor/lib/python3.7/site-packages/celery/app/trace.py", line 704, in __protected_call__
    return self.run(*args, **kwargs)
  /*...*/
  File "/home/ubuntu/anaconda3/envs/tensor/lib/python3.7/site-packages/torch/cuda/__init__.py", line 191, in _lazy_init
    "Cannot re-initialize CUDA in forked subprocess. " + msg)
RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method
以下是加载模型时my settings.py中的代码:

if sys.argv and sys.argv[0].endswith('celery') and 'worker' in sys.argv: #In order to load only for the celery worker
    import torch
    torch.cuda.init()
    torch.backends.cudnn.benchmark = True
    load_model_file()
和任务代码

@task
def getResult(name):
    print("Executing on GPU:", torch.cuda.is_available())
    if os.path.isfile(name):
        try:
            outpath = model_inference(name)
            os.remove(name)
            return outpath
        except OSError as e:
            print("Error", name, "doesn't exist")
    return ""
任务中的打印显示“在GPU上执行:true”


我尝试在
torch.cuda.init()
之前和之后的settings.py中设置
torch.multiprocessing.set_start_method('spawn')
,但它给出了相同的错误。

设置此方法时,只要您还使用同一库中的
Process

from torch.multiprocessing import Pool, Process
芹菜使用“常规”
多处理
库,因此出现此错误

如果我是你,我会试试:

  • 看看这是否有帮助
  • 看看这是否有帮助

这是因为芹菜工人本身正在使用叉子。这似乎是一个当前芹菜>=4.0的问题

您过去可以将芹菜配置为产卵,而不是分叉,但该功能(
CELERYD\u FORCE\u EXECV
)不可用

没有内置的选项可以绕过此问题。一些定制的monkeypatching可能可以做到这一点,但YMMV

一些可能可行的选择可能是:


  • 使用芹菜一个快速的解决办法是使事情单线程。为此,在启动芹菜工人时,将芹菜工人池类型设置为solo

    celery -A your_proj worker -P solo -l info
    

    不需要“torch.multiprocessing.set_start_method('spawn')”或“from torch.multiprocessing import Pool,Process”。使用eventlet和并发0解决了问题single threaded works也解决了问题-
    芹菜-你的项目工作者-P solo
    有没有办法知道哪一个是更好的解决方案-solo池中的单线程与并发为0的eventlet/gevent?