torch.backends.cudnn.enabled = False会引起CUDA out of memory和CUDA error: an illegal memory access was
一般来说,题目所示这种问题都是由batch_size的设置引起的,修改batch_size之后就能有效解决。但是,我今天遇到一种情况,这个问题不是由batch_size引起的,而是由torch.backends.cudnn.enabled = False这个设置引起的。torch.backends.cudnn.enabled = False这个设置主要用于实验过程的可复现,具体的实验过程可复现代码
一般来说,题目所示这种问题都是由batch_size的设置引起的,修改batch_size之后就能有效解决。但是,我今天遇到一种情况,这个问题不是由batch_size引起的,而是由torch.backends.cudnn.enabled = False这个设置引起的。
torch.backends.cudnn.enabled = False这个设置主要用于实验过程的可复现,具体的实验过程可复现代码设置如下:
import numpy as np
import torch
from torch.backends import cudnn
import random
import os
print(torch.__version__)
def set_seed(seed):
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed) # if you are using multi-GPU.
np.random.seed(seed) # Numpy module.
random.seed(seed) # Python random module.
os.environ['PYTHONHASHSEED'] = str(seed)
torch.use_deterministic_algorithms(True)
torch.backends.cudnn.enabled = False # ----》引起问题的代码行
torch.backends.cudnn.benchmark = False #禁用benchmark,保证可复现
#torch.backends.cudnn.benchmark = True #恢复benchmark,提升效果
torch.backends.cudnn.deterministic = True
os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':4096:8'
def worker_init(worked_id):
worker_seed = torch.initial_seed() % 2**32
np.random.seed(worker_seed)
random.seed(worker_seed)
set_seed(2021)
一开始我并不知道是这里的原因,当我设置batch_size=1时,仍旧有 CUDA out of memory 的问题。而且是由一个 tensor加法或list.append()的操作引起的。没有这两个操作一切正常,有了这两个操作之一,立马CUDA out of memory。我百思不得解,这一个操作的计算量级非常小呀,怎么就引起CUDA out of memory了呢?
后来,我觉得可能是torch版本的问题,于是把torch-1.9.0换成1.8.0,问题依旧; 换成torch-1.7.0, 问题由CUDA out of memory变成了“CUDA error: an illegal memory access was encountered”。并提示torch.use_deterministic_algorithms(True)没有定义。
偶然的机会,我把整个上面的代码都注释掉,发现程序可以正常运行了,哪怕换成1.9.0版本也一切正常,所以确定,这个错误是由上面代码引起的,并通过逐行修改,确定了最终是由torch.backends.cudnn.enabled = False这个设置引起的。当注销掉这一行,或设置为True的时候,问题就消失了。
下面引用了一篇博客对torch.backends.cudnn.enabled的介绍,具体引起问题的原因不清楚,但是,如果网络的输入数据维度或类型上变化不大,设置 torch.backends.cudnn.benchmark = true 应该也是可以保证算法可以复现的,二者这样设置可以增加运行效率。尤其,当我们通过上面的worker_init函数约束数据加载过程时,可以保证数据的输入次序一样, torch.backends.cudnn.benchmark = true 应该可以保证算法可以复现。
以下转自:pytorch torch.backends.cudnn设置作用 - 慢行厚积 - 博客园
pytorch torch.backends.cudnn设置作用
cuDNN使用非确定性算法,并且可以使用torch.backends.cudnn.enabled = False来进行禁用
如果设置为torch.backends.cudnn.enabled =True,说明设置为使用使用非确定性算法
然后再设置:
torch.backends.cudnn.benchmark = true
那么cuDNN使用的非确定性算法就会自动寻找最适合当前配置的高效算法,来达到优化运行效率的问题
一般来讲,应该遵循以下准则:
- 如果网络的输入数据维度或类型上变化不大,设置 torch.backends.cudnn.benchmark = true 可以增加运行效率;
- 如果网络的输入数据在每次 iteration 都变化的话,会导致 cnDNN 每次都会去寻找一遍最优配置,这样反而会降低运行效率。
所以我们经常看见在代码开始出两者同时设置:
torch.backends.cudnn.enabled = True
torch.backends.cudnn.benchmark = True
更多推荐
所有评论(0)