使用 MultiWorkerMirroredStrategy 训练对象检测研究模型时出错 ssd_mobilenet_v1_fpn_640x640_coco17_tpu-8

Error using MultiWorkerMirroredStrategy to train object detection research model ssd_mobilenet_v1_fpn_640x640_coco17_tpu-8

我正在尝试使用 MultiWorkerMirroredStrategy 训练研究模型 ssd_mobilenet_v1_fpn_640x640_coco17_tpu-8(通过在调用 model_main_tf2.py 时设置 --num_workers=2)。我正在尝试训练两个工人(0 和 1),每个工人都有一个 GPU。但是,当我尝试这样做时,总是在工作人员 1 上出现以下错误:

Traceback (most recent call last):
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\distribute\input_lib.py", line 553, in __next__
    return self.get_next()
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\distribute\input_lib.py", line 610, in get_next
    return self._get_next_no_partial_batch_handling(name)
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\distribute\input_lib.py", line 642, in _get_next_no_partial_batch_handling
    replicas.extend(self._iterators[i].get_next_as_list(new_name))
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\distribute\input_lib.py", line 1594, in get_next_as_list
    return self._format_data_list_with_options(self._iterator.get_next())
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\data\ops\multi_device_iterator_ops.py", line 580, in get_next
    result.append(self._device_iterators[i].get_next())
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\data\ops\iterator_ops.py", line 889, in get_next
    return self._next_internal()
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\data\ops\iterator_ops.py", line 819, in _next_internal
    ret = gen_dataset_ops.iterator_get_next(
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\ops\gen_dataset_ops.py", line 2922, in iterator_get_next
    _ops.raise_from_not_ok_status(e, name)
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\framework\ops.py", line 7186, in raise_from_not_ok_status
    raise core._status_to_exception(e) from None  # pylint: disable=protected-access
tensorflow.python.framework.errors_impl.OutOfRangeError: End of sequence [Op:IteratorGetNext]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\JS\Desktop\Tensorflow\models\research\object_detection\model_main_tf2.py", line 114, in <module>
    tf.compat.v1.app.run()
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\platform\app.py", line 36, in run
    _run(main=main, argv=argv, flags_parser=_parse_flags_tolerate_undef)
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\absl\app.py", line 312, in run
    _run_main(main, args)
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\absl\app.py", line 258, in _run_main
    sys.exit(main(argv))
  File "C:\Users\JS\Desktop\Tensorflow\models\research\object_detection\model_main_tf2.py", line 105, in main
    model_lib_v2.train_loop(
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\object_detection\model_lib_v2.py", line 605, in train_loop
    load_fine_tune_checkpoint(
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\object_detection\model_lib_v2.py", line 401, in load_fine_tune_checkpoint
    _ensure_model_is_built(model, input_dataset, unpad_groundtruth_tensors)
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\object_detection\model_lib_v2.py", line 161, in _ensure_model_is_built
    features, labels = iter(input_dataset).next()
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\distribute\input_lib.py", line 549, in next
    return self.__next__()
  File "C:\Users\JS\.conda\envs\tensor2\lib\site-packages\tensorflow\python\distribute\input_lib.py", line 555, in __next__
    raise StopIteration
StopIteration

Worker 0 在检测到 Worker 1 已关闭后最终失败。

无论这两个工人 运行 在哪个物理机器上,都会发生此错误。换句话说,如果我 运行 在一台机器上(使用本地主机)或同一网络上的不同机器上连接两个工作人员,我就会看到它。

根据错误消息中的跟踪,每当训练循环尝试迭代 strategy.experimental_distribute_datasets_from_function 生成的训练数据时,错误似乎就会发生。请注意,如果我将策略更改为 MirroredStrategy,它 运行 在一台机器上没问题(没有进行其他更改)。我不确定是我做错了什么还是对象检测有问题 API.

我在两台机器上的设置是相同的(我基本上遵循了对象检测网站上的设置说明):

  1. Windows 10
  2. 张量流 2.8.0
  3. Cuda 工具包 11.2
  4. cudnn 8.1

有没有人见过这个错误?如果是这样,有没有解决办法?

好的,我想我明白了。在对象检测库中有一个名为 dataset_builder.py 的文件,它根据存储在 pipeline.config 文件中指定文件中的 TFRecord 构建训练数据集(在 [=22=21=] 项中=]).真正读取TFRecord文件的函数是_read_dataset_internal。此函数将管道配置的 input_path 视为文件列表,然后应用分片函数(作为参数传递)在进行训练的副本之间划分文件(每个工作人员一个副本)。由于我的 input_path 只指定了一个 TFRecord 文件,它被分配给第一个副本,而其他副本被赋予空文件名!!因此只有第一个副本实际上有一个输入数据集可以使用,因此崩溃。

解决方案是将训练数据拆分为两个文件(两个 TFRecords),然后将 pipeline.config 中的 input_path 设置为路径列表而不是单个路径。完成此操作后,模型似乎训练成功(至少没有崩溃)。

我不确定这是否是对象检测代码中的错误。我假设如果我只有一个培训记录(两个工人都可见),两个工人都会使用它并相应地批处理数据。我只是不确定假设本身是错误的还是假设是正确的但代码是错误的。

无论如何,这对可能遇到同样问题的任何人都有帮助。