目录

  • 多卡同步BN
  • 固定随机种子
  • 计算模型参数量
  • 提升Pytorch运行效率
  • 指定程序运行在特定GPU卡上
  • 保证模型的可重复性


多卡同步BN

当使用torch.nn.DataParallel将代码运行在多张GPU卡上时,PyTorch的BN层默认操作是各卡上数据独立地计算均值和标准差,同步BN使用所有卡上的数据一起计算BN层的均值和标准差,缓解了当批量大小(batch size)比较小时对均值和标准差估计不准的情况,是在目标检测等任务中一个有效的提升性能的技巧。

Pytorch官方现已支持
备注:虽然官方已经支持了,但是文档中有说,目前只支持DistributedDataParallel,我自己在单机多卡上测试时一直报错,说未初始化,所以还是尽量有上面Github那个吧,亲测可用(^U^)ノ~YO

sync_bn = torch.nn.SyncBatchNorm(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)

固定随机种子

torch.manual_seed(0)
torch.cuda.manual_seed_all(0)

计算模型参数量

param_count = sum(param.numel() for param in model.parameters())

现在Github上有开源的工具可以直接调用 计算模型的计算量和参数量,传送门:flops-counter.pytorch

import torchvision.models as models
import torch
from ptflops import get_model_complexity_info

with torch.cuda.device(0):
  net = models.densenet161()
  flops, params = get_model_complexity_info(net, (3, 224, 224), as_strings=True, print_per_layer_stat=True)
  print('Flops:  ' + flops)
  print('Params: ' + params)

提升Pytorch运行效率

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

指定程序运行在特定GPU卡上

在命令行指定环境变量

CUDA_VISIBLE_DEVICES=0,1 python train.py

或在代码中指定

os.environ['CUDA_VISIBLE_DEVICES'] = '0,1'

保证模型的可重复性

GPU上两次运行的结果会不一致,而CPU两次运行的结果相同,解决方法在主函数中加上一句

torch.backends.cudnn.deterministic = True