一、问题描述

        在使用Pytorch训练模型的时候,程序出现卡死、没反应的现象。当卡到无法令人接受,然后强制终止运行程序的时候,得到以下的终端输出信息:

  xxxxxxxxx
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 435, in __next__
    data = self._next_data()
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 1068, in _next_data
    idx, data = self._get_data()
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 1034, in _get_data
    success, data = self._try_get_data()
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 872, in _try_get_data
    data = self._data_queue.get(timeout=timeout)
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/multiprocessing/queues.py", line 104, in get
    if not self._poll(timeout):
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/multiprocessing/connection.py", line 257, in poll
    return self._poll(timeout)
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/multiprocessing/connection.py", line 414, in _poll
    r = wait([self], timeout)
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/multiprocessing/connection.py", line 911, in wait
    ready = selector.select(timeout)
  File "/home/csx/.conda/envs/py4torch17/lib/python3.6/selectors.py", line 376, in select
    fd_event_list = self._poll.poll(timeout)
KeyboardInterrupt

        我称之为"fd_event_list = self._poll.poll(timeout)"问题。

二、原因分析

        如果模型没有问题(在一个数据集上能够正常训练,但切换到另一个数据集后出现了这个问题),这很有可能是因为数据集的规模引起的Dataloader加载数据timeout。当然,如果不考虑数据集规模,还有可能就是模型训练的机器性能不够,比如运行内存、显卡内存等,若不够大都有可能出现这个问题。

        作以上的分析,这是因为我通过降低训练数据集的方法,使得程序恢复正常运行,而不至于卡死,一直不动。

三、建议方案

        ①网上有些大神认为是因为cpu worker nums设置得太高导致,可以适当地降低worker的数量,也许能够解决该问题。但我在我所使用的模型和数据集中作了相应的尝试,不行。

        ②尝试降低模型训练的数据量。这个方法大概率是有效的,因为我通过这个办法解决了这个问题。然而,如果降低了模型训练的数据量,会不会对模型的性能带来新的问题?答案是肯定会的,因为缺少了一些训练样本,模型学习到的信息就会减少。但这一点还是有值得参考的地方的,因为你可以这个方法来排除程序所出的问题是否因为模型的训练数据量。

        ③对用于模型训练的数据进行划分(文件的形式),比如,划分为3块,即三个文件。而你的模型训练的最大迭代步数假定为90000次,那么我们可以在前30000步训练第1块数据,在30000-60000步训练第2块数据,而在60000-90000步的时候训练第3块数据。当然,如果划分为3块的每一块数据量依然很大,那么我建议你可以继续划分。这样一来,我们就既能够降低程序运行时所需的训练数据量,又能够从整体上训练所有的数据。这一想法源于大数据处理的基本原则:由大变小。

四、其他

        若你遇到了该问题,请在下方留言,如果我所作出的建议有误,也可进行批评改正。欢迎加入讨论。