我的需求是在reader中使用inference_model进行预测,reader放在multiprocess_reader中。使用了两种实现方式都报错:Error: cudaSetDevice failed in paddle::platform::SetDeviced, error code : 3, Please see detail in https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__TYPES.htm l#group__CUDART__TYPES_1g3f51e3575c2178246db0a94a430e0038: initialization error at (/paddle/paddle/fluid/platform/gpu_info.cc:240)
第一种是:在reader中定义CUDAPlace和exe;第二种是在reader中使用python API预测。其中第二种方法在pool构造的多进程中没问题,在本场景的multiprocess_reader中有问题。
最小可复现代码:paddle1.7 post97
import os
os.environ["CUDA_VISIBLE_DEVICES"]="2"
import paddle
import paddle.fluid as fluid
from paddle.fluid.core import PaddleTensor
from paddle.fluid.core import AnalysisConfig
from paddle.fluid.core import create_paddle_predictor
def reader():
landmark_config = AnalysisConfig('lmk_model/model','lmk_model/params')
landmark_config.switch_use_feed_fetch_ops(False)
#landmark_config.disable_gpu()
landmark_config.enable_use_gpu(100, 0)
landmark_predictor = create_paddle_predictor(landmark_config)
for i in range(10):
yield i
if __name__=="__main__":
place = fluid.CUDAPlace(0)
exe = fluid.Executor(place)
train_reader = paddle.reader.multiprocess_reader([reader, reader])
for data in train_reader():
print(data)
27条答案
按热度按时间lp0sw83n1#
什么原因呢?而且我的场景里就是需要在multiprocess_reader里的reader里进行预测,得把这个方案走通
pbgvytdp2#
好吧,我没想到这个问题这么复杂。我试试paddle server方法吧。
gev0vcfq3#
嗯嗯,所以结论是目前想在主进程中创建子进程,在子进程中做inference这种思路在目前的paddle实现下是行不通的,这也不是一个bug修复的问题,而是架构层面的设计就不满足这样的写法,所以对于您这个需求,需要想别的办法,您看看reader多线程用GPU做inference能满足需求吗?
zi8p0yeb4#
这种方法也不行,我的主进程里需要进行训练啊
hfwmuf9z5#
@wang-kangkang import paddle的时候会在当前进程初始化cuda的环境,如果一定要用子进程的话,只能在子进程中import paddle了,这样倒不会报错,但应该也没法用了吧。。。
ui7jx7zq6#
reader是否可以用多线程
mkshixfv7#
reader中使用place=fluid.CPUPlace()速度同样很慢,我期望的是起码能实用python API能在reader中调用cuda预测。
agxfikkp8#
那在reader中去掉cuda相关(或者接口内部有调用cuda)的代码吧
xmjla07d9#
使用多线程会降低原有的训练速度。所以有没有办法能直面并解决当前问题
vd8tlhqk10#
这个错误,具体的原因是,CUDA的context不能在多进程内共享。
具体的解释可见:
https://stackoverflow.com/questions/22950047/cuda-initialization-error-after-fork
在调用
paddle.reader.multiprocess_reader
之后会fork出子进程,但是在这之前paddle会初始化cuda context,因此会有上述的问题。Paddle/python/paddle/fluid/init.py
Line 221 in cb0472b
| | core.init_devices(notin_test) |
Paddle/paddle/fluid/pybind/pybind.cc
Line 1533 in cb0472b
| | m.def("init_devices", |
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/platform/init.cc#L139-L154
因此在使用cuda期间避免fork多进程,建议使用多线程。
knpiaxh111#
需求场景是我在训练人脸检测模型的时候,想要在检测模型上再出另一个分支来输出人脸的模糊属性。由于检测的数据产生过程有data argument,其中会改变人脸模糊度和大小,所以模糊属性无法提前离线标注。当前的方法就是使用一个提前训练好的模糊分类小模型,在reader中的data argument之后进行inference,从而获得模糊度“标签”。
目前在reader中使用cpu预测十分慢,整体训练速度不到原先的40%
yruzcnhs12#
@wang-kangkang 这里应该是因为,从框架层面来讲的话,import paddle的时候,会初始化的CUDADeviceContext,而一旦初始化之后,就不能共享给主进程创建的子进程使用,而要支持这种写法,涉及到的底层改动还是挺大的,后续反馈下要不要做,一时半会这种写法应该不行,单预测API的话等等 @NHZIX 回复
为什么一定要这么写?这个本质需求是预测的速度不够快吗?
byqmnocz13#
@wang-kangkang 我这边试了下,把exe塞到子进程里执行就会报这个错,还需要时间分析下
@NHZlX 说预测python API理论上支持这种第二种写法,麻烦等他回复下
liwlm1x914#
稍等,我再排查一下
6vl6ewon15#
在这个例子中,不用multiprocess_reader装饰是可以正常工作的吗