pytorch中提高GPU显存利用率方法

一、GPU内存占用包括两个方面:

1优化器参数模型自身参数模型中各层缓存:

有参数层,如CNN, RNN;

无参数层, 如RELU, POOL等。

2batch size:GPU显存满足情况下,设为最大,但是不建议超过32.

二、显存不足的应对策略

1降低batch size:适当减少。

2选择更小的数据类型 :选用16位替换32位的数据类型

3精简模型:减少有参数层的使用。

4损失函数:选择合适的求损失的方式

5释放张量:del模型后续不使用的张量

6Relu 的 inplace 参数:将Relu 的inplace 参数设置为True,得到的新值直接覆盖旧值。

7梯度累积:loss.backward() 为每个参数计算梯度,并存储到paramter.grad中,paramter.grad 是一个张量, 其会累加每次计算得到的梯度。

调用 optimizer.step()时才会进行梯度下降更新网络参数。

过去的梯度变化

for i,(feature,target) in enumerate(train_loader):
    outputs = model(feature)  #前向传播
    loss = criterion(outputs,target)  #计算损失
 
    optimizer.zero_grad()   #清空梯度
    loss.backward()      #计算梯度
    optimizer.step()     #反向传播,更新网络参数

梯度累加

for i,(features,target) in enumerate(train_loader):
    outputs = model(images)    #前向传播
    loss = criterion(outputs,target)   #计算损失
    loss = loss/accumulation_steps    #可选,如果损失要在训练样本上取平均
 
    loss.backward()    #计算梯度
    if ((i+1)%accumulation_steps) == 0:
        optimizer.step()   #反向传播,更新网络参数
        optimizer.zero_grad()    #清空梯度

我们发现,梯度累加本质上就是累加 accumulation_steps 个 batchsize 或accumulationsteps 的梯度, 再根据累加的梯度来更新网络参数,以达到真实梯度类似batch_size 的效果。在使用时,需要注意适当的扩大学习率。

更详细来说, 我们假设 batch size = 4 , accumulation steps = 8 , 梯度积累首先在前向传播的时候以 batch_size=4 来计算梯度,但是不更新参数,将梯度积累下来,直到我们计算了 accumulation steps 个 batch, 我们再更新参数。其实本质上就等价于:

真正的 batch_size = batch_size * accumulation_steps

8分布式训练Distribution Training

数据并行 Data Parallelism

模型并行 Model Parallelism

你可能感兴趣的:(pytorch,python,算法)