1. 不要在循环训练中直接将loss进行append(cannot allocate memory)
默认情况下,涉及需要求导/梯度gradients变量的计算将保存在内存中。计算中避免使用这些变量,例如在跟踪统计数据时,这些变量在循环训练中将超出你内存。相反,您应该分离变量或访问其基础数据。
有时,当可微分变量可能发生时,它可能并不明显。考虑以下循环训练(从源代码删减):
total_loss = []
for i in range(10000):
optimizer.zero_grad()
output = model(input)
loss = criterion(output)
loss.backward()
optimizer.step()
total_loss.append(loss)
在这里,total_loss你的循环训练中积累了历史,因为它loss是一个具有autograd历史的可微变量(复杂的数据结构,占用很大的内存)。你可以通过编写total_loss.append(loss)来解决这个问题。否则即使你有1T的内存,没append几次内存就爆了。
2. 如何实时查看内存或者GPU的使用情况:
内存
top
M
GPU
watch -n 0.1 nvidia-smi
3. GPU显存未释放问题
我们在使用tensorflow+pycharm 或者PyTorch写程序的时候, 有时候会在控制台终止掉正在运行的程序,但是有时候程序已经结束了,nvidia-smi也看到没有程序了,但是GPU的内存并没有释放,这是怎么回事呢?
使用PyTorch设置多线程(threads)进行数据读取(DataLoader),其实是假的多线程,他是开了N个子进程(PID都连着)进行模拟多线程工作,所以你的程序跑完或者中途kill掉主进程的话,子进程的GPU显存并不会被释放,需要手动一个一个kill才行,具体方法描述如下:
- 先关闭ssh(或者shell)窗口,退出重新登录
- 查看运行在gpu上的所有程序:
fuser -v /dev/nvidia*
- kill掉所有(连号的)僵尸进程
4. RuntimeError: CUDA out of memory.
在做模型预测的时候,需要添加下列代码:
with torch.no_grad():
output = model(input)