如何解决将PyTorch与芹菜一起使用
我正在尝试在Django应用中运行PyTorch模型。由于不建议在视图中执行模型(或任何长时间运行的任务),因此我决定在Celery任务中运行它。我的模型很大,加载大约需要12秒,而推断大约需要3秒。这就是为什么我认为我无力在每次请求时都加载它的原因。因此,我尝试将其加载到设置中并将其保存在该位置以供应用程序使用。所以我的最终方案是:
- 启动Django应用后,将在设置中加载PyTorch模型,并可以从该应用访问该模型。
- views.py收到请求后,将延迟芹菜任务
- 芹菜任务使用settings.model推断结果
这里的问题是,当尝试使用模型时,celery任务会引发以下错误
[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
这是我的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 ""
任务中的打印内容显示为"Executing on GPU: true"
我尝试在torch.multiprocessing.set_start_method('spawn')
之前和之后在settings.py中设置torch.cuda.init()
,但是它给出了相同的错误。
解决方法
只要您还使用同一库中的Process
,就可以设置此方法。
from torch.multiprocessing import Pool,Process
Celery使用“常规” multiprocessing
库,因此会出现此错误。
如果我是你,我会尝试:
- run it single threaded看看是否有帮助
- run it with eventlet看看是否有帮助
- read this
一个快速的解决方法是使事物成为单线程。为此,在启动芹菜工作者时将芹菜的工作者池类型设置为独奏
celery -A your_proj worker -P solo -l info
,
这是由于芹菜工人本身正在使用叉子。这似乎是当前known issue的Celery> = 4.0
您曾经能够将芹菜配置为产生而不是产生叉子,但是该功能(CELERYD_FORCE_EXECV
是removed in 4.0。
没有内置选项可以解决此问题。可能可以执行一些自定义的monkeypatching,但是YMMV
一些可能可行的选择可能是:
- 在启用
<4.0
的情况下使用芹菜CELERYD_FORCE_EXECV
。 - 在Windows上启动芹菜工作者(无论如何都无法分叉)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。