ethnhe / raster_triangle

A simple renderer with z-buffer for synthesis data generating.
56 stars 22 forks source link

分布式训练下动态链接库的在线渲染 #21

Open vtasStu opened 1 year ago

vtasStu commented 1 year ago

同学你好,我采用你设计的动态链接库对模型进行在线渲染获取数据,在线渲染在正常的Dataset+Dataloader情况下是可行的,但是当我使用PyTorch提供的分布式训练流程的时候会出现错误:

Traceback (most recent call last):
  File "/root/Workspace/project/krrnv5/train.py", line 309, in <module>
    mp.spawn(
  File "/root/anaconda3/envs/krrn/lib/python3.9/site-packages/torch/multiprocessing/spawn.py", line 240, in spawn
    return start_processes(fn, args, nprocs, join, daemon, start_method='spawn')
  File "/root/anaconda3/envs/krrn/lib/python3.9/site-packages/torch/multiprocessing/spawn.py", line 198, in start_processes
    while not context.join():
  File "/root/anaconda3/envs/krrn/lib/python3.9/site-packages/torch/multiprocessing/spawn.py", line 160, in join
    raise ProcessRaisedException(msg, error_index, failed_process.pid)
torch.multiprocessing.spawn.ProcessRaisedException:

-- Process 1 terminated with the following error:
Traceback (most recent call last):
  File "/root/anaconda3/envs/krrn/lib/python3.9/site-packages/torch/multiprocessing/spawn.py", line 69, in _wrap
    fn(i, *args)
  File "/root/Workspace/project/krrnv5/train.py", line 293, in ddp_train
    train(rank, copy.deepcopy(opt))
  File "/root/Workspace/project/krrnv5/train.py", line 273, in train
    trainer.train_epoch(dataloader, epoch, train_logger, opt_pose)
  File "/root/Workspace/project/krrnv5/tools/trainer.py", line 71, in train_epoch
    for i, patch_datas in enumerate(train_dataloader, 0):
  File "/root/anaconda3/envs/krrn/lib/python3.9/site-packages/torch/utils/data/dataloader.py", line 435, in __iter__
    return self._get_iterator()
  File "/root/anaconda3/envs/krrn/lib/python3.9/site-packages/torch/utils/data/dataloader.py", line 381, in _get_iterator
    return _MultiProcessingDataLoaderIter(self)
  File "/root/anaconda3/envs/krrn/lib/python3.9/site-packages/torch/utils/data/dataloader.py", line 1034, in __init__
    w.start()
  File "/root/anaconda3/envs/krrn/lib/python3.9/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
  File "/root/anaconda3/envs/krrn/lib/python3.9/multiprocessing/context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "/root/anaconda3/envs/krrn/lib/python3.9/multiprocessing/context.py", line 284, in _Popen
    return Popen(process_obj)
  File "/root/anaconda3/envs/krrn/lib/python3.9/multiprocessing/popen_spawn_posix.py", line 32, in __init__
    super().__init__(process_obj)
  File "/root/anaconda3/envs/krrn/lib/python3.9/multiprocessing/popen_fork.py", line 19, in __init__
    self._launch(process_obj)
  File "/root/anaconda3/envs/krrn/lib/python3.9/multiprocessing/popen_spawn_posix.py", line 47, in _launch
    reduction.dump(process_obj, fp)
  File "/root/anaconda3/envs/krrn/lib/python3.9/multiprocessing/reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'CDLL.__init__.<locals>._FuncPtr'

关于这个问题,我询问了ChatGPT

np.ctypeslib.load_library 分布式训练 AttributeError: Can't pickle local object 'CDLL.__init__.<locals>._FuncPtr'

他的答复是

这个错误是因为 np.ctypeslib.load_library 函数在分布式训练时尝试对 CDLL 对象进行 pickle 操作,但由于 CDLL 对象包含了本地函数指针(即 _FuncPtr),这导致 pickle 操作失败。

在分布式训练中,由于涉及到多个进程或多台机器之间的通信,通常需要将数据进行序列化和反序列化操作,以便在不同的进程或机器之间传递数据。然而,某些对象,如包含了本地函数指针的 CDLL 对象,无法被序列化。

解决这个问题的方法通常有以下几种:

1. 避免对 CDLL 对象进行 pickle 操作:可以通过重新设计代码,避免在分布式训练中对 CDLL 对象进行序列化和反序列化操作,从而避免这个错误。

2. 使用可序列化的替代对象:如果 CDLL 对象中的本地函数指针不是必要的,可以考虑使用其他可序列化的替代对象,例如使用 ctypes.CDLL 中的 PyDLL 类型,它不包含本地函数指针。

3. 使用其他序列化库:如果需要在分布式训练中序列化和反序列化包含了本地函数指针的对象,可以考虑使用其他支持序列化本地函数指针的库,例如 dill 或 cloudpickle,而不是使用 Python 内建的 pickle 库。

需要注意的是,根据具体的代码和使用场景,以上的解决方法可能会有不同的适用性和效果,具体的解决方案需要根据实际情况进行调整。

请问同学有没有好的建议,让这个动态链接库在DDP训练中也可以采用?