【问题标题】:Pytorch SSLError on Dataloader when Workers are greater than 1当工人大于 1 时,Dataloader 上的 Pytorch SSLError
【发布时间】:2021-11-01 03:18:42
【问题描述】:

我创建了一个 Dataset 对象,它在加载项目时从 API 加载一些数据

class MyDataset(Dataset):

    def __init__(self, obj_ids = []):
        """
        """
        super(Dataset, self).__init__()

        self.obj_ids = obj_ids

    def __len__(self):
        return len(self.obj_ids)

    def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        result = session.get('/api/url/{}'.format(idx))

        ## Post processing work...

然后我将它添加到我的数据加载器中:

data_loader = torch.utils.data.DataLoader(
              dataset, batch_size=2, shuffle=True, num_workers=1,
              collate_fn=utils.collate_fn)

使用num_workers=1 进行训练时一切正常。但是当我将其增加到 2 或更大时,我的训练循环中会出现错误。

在这一行:

train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq=10)

SSLError: Caught SSLError in DataLoader worker process 0.
Original Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 384, in _make_request
    six.raise_from(e, None)
  File "<string>", line 2, in raise_from
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 380, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/lib/python3.7/http/client.py", line 1373, in getresponse
    response.begin()
  File "/usr/lib/python3.7/http/client.py", line 319, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python3.7/http/client.py", line 280, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/lib/python3.7/socket.py", line 589, in readinto
    return self._sock.recv_into(b)
  File "/usr/lib/python3.7/ssl.py", line 1071, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/lib/python3.7/ssl.py", line 929, in read
    return self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] decryption failed or bad record mac (_ssl.c:2570)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/local/lib/python3.7/dist-packages/urllib3/util/retry.py", line 399, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='mydomain.com', port=443): Max retries exceeded with url: 'url_with_error_is_here' (Caused by SSLError(SSLError(1, '[SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] decryption failed or bad record mac (_ssl.c:2570)')))

如果我删除 post 请求,我将停止收到 SSL 错误,所以问题可能与 requests.post 库或 urllib 有关。

我将错误中的域和 url 更改为虚拟值,但是当只有 1 个工作人员时,url 和域都可以工作。

我在启用了 GPU 的谷歌协作环境中运行它,但也在我的本地机器上尝试过它并遇到了同样的问题。

谁能帮我解决这个问题?

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    经过一些调试并阅读更多关于multiprocessingrequest.session 的信息。似乎问题在于我不能在数据集中使用requests.session,因为 pytorch 最终在训练循环上使用了多处理。

    关于这个问题的更多信息:How to assign python requests sessions for single processes in multiprocessing pool?

    通过将任何 session.getsession.post 更改为 requests.getrequests.post 来解决此问题,因为在没有会话的情况下使用它可以避免共享相同的连接并获得 SSLError。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-26
      • 1970-01-01
      • 2021-04-18
      • 2019-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      相关资源
      最近更新 更多