我试图使用multiworkermirrorredstrategy训练研究模型ssd_mobilenet_v1_fpn_640x640_coco17_tpu8(通过在调用model_main_tf2.py中设置——num_workers=2)。我试图跨两个工人(0和1)进行训练,每个工人都有一个GPU。然而,当我尝试这样做时,我得到以下错误,总是在worker 1上:
Traceback (most recent call last):
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondistributeinput_lib.py", line 553, in __next__
return self.get_next()
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondistributeinput_lib.py", line 610, in get_next
return self._get_next_no_partial_batch_handling(name)
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondistributeinput_lib.py", line 642, in _get_next_no_partial_batch_handling
replicas.extend(self._iterators[i].get_next_as_list(new_name))
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondistributeinput_lib.py", line 1594, in get_next_as_list
return self._format_data_list_with_options(self._iterator.get_next())
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondataopsmulti_device_iterator_ops.py", line 580, in get_next
result.append(self._device_iterators[i].get_next())
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondataopsiterator_ops.py", line 889, in get_next
return self._next_internal()
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondataopsiterator_ops.py", line 819, in _next_internal
ret = gen_dataset_ops.iterator_get_next(
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythonopsgen_dataset_ops.py", line 2922, in iterator_get_next
_ops.raise_from_not_ok_status(e, name)
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythonframeworkops.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:UsersJSDesktopTensorflowmodelsresearchobject_detectionmodel_main_tf2.py", line 114, in <module>
tf.compat.v1.app.run()
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythonplatformapp.py", line 36, in run
_run(main=main, argv=argv, flags_parser=_parse_flags_tolerate_undef)
File "C:UsersJS.condaenvstensor2libsite-packagesabslapp.py", line 312, in run
_run_main(main, args)
File "C:UsersJS.condaenvstensor2libsite-packagesabslapp.py", line 258, in _run_main
sys.exit(main(argv))
File "C:UsersJSDesktopTensorflowmodelsresearchobject_detectionmodel_main_tf2.py", line 105, in main
model_lib_v2.train_loop(
File "C:UsersJS.condaenvstensor2libsite-packagesobject_detectionmodel_lib_v2.py", line 605, in train_loop
load_fine_tune_checkpoint(
File "C:UsersJS.condaenvstensor2libsite-packagesobject_detectionmodel_lib_v2.py", line 401, in load_fine_tune_checkpoint
_ensure_model_is_built(model, input_dataset, unpad_groundtruth_tensors)
File "C:UsersJS.condaenvstensor2libsite-packagesobject_detectionmodel_lib_v2.py", line 161, in _ensure_model_is_built
features, labels = iter(input_dataset).next()
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondistributeinput_lib.py", line 549, in next
return self.__next__()
File "C:UsersJS.condaenvstensor2libsite-packagestensorflowpythondistributeinput_lib.py", line 555, in __next__
raise StopIteration
StopIteration
Worker 0在检测到Worker 1宕机后最终失败。
无论两个worker运行在哪个物理机器上,都会发生此错误。换句话说,如果我在一台机器上(使用localhost)或在同一网络上的不同机器上运行两个worker,我就会看到它。
根据错误消息中的跟踪,每当训练循环试图迭代由strategy.experimental_distribute_datasets_from_function生成的训练数据时,错误似乎就会发生。请注意,如果我将策略更改为mirrorredstrategy,它在一台机器上运行良好(没有进行其他更改)。我不确定是否我做错了什么,或者是否有一个错误的对象检测API。
我在两台机器上的设置是相同的(我基本上遵循了对象检测网站上的设置说明):
Windows 10- Tensorflow 2.8.0 Cuda Toolkit 11.2
- cudnn 8.1
有人见过这个错误吗?如果是这样,有什么办法吗?
好的,我想我明白这个问题了。在对象检测库中有一个名为dataset_builder.py的文件,它根据存储在管道中指定的文件中的TFRecord构建训练数据集。配置文件(在tf_record_input_reader的input_path项中)。实际读取TFRecord文件的函数是_read_dataset_internal。该函数将管道配置的input_path视为文件列表,然后应用sharding函数(作为参数传递)在执行训练的副本之间划分文件(每个工作人员一个副本)。因为我的input_path只指定了一个TFRecord文件,所以它被分配给了第一个副本,而其他副本被赋予了空文件名!!因此,只有第一个副本实际上有一个输入数据集可以使用,因此崩溃。
解决方案是将训练数据分成两个文件(两个TFRecords),然后在管道中设置input_path。配置为路径列表而不是单个路径。一旦我这样做了,它看起来好像模型训练成功(至少它没有崩溃)。
我不确定这是否是对象检测代码中的错误。我假设如果我只有一个培训记录(对两个工人都可见),那么两个工人都将使用它并相应地批量处理数据。我只是不确定假设本身是错误的,还是假设是正确的,代码是错误的。
无论如何,我希望这能帮助到任何可能遇到同样问题的人。