预处理提速
- 尽量减少每次读取数据时的预处理操作,可以考虑把一些固定的操作,例如
resize
,事先处理好保存下来,训练的时候直接拿来用 - Linux上将预处理搬到GPU上加速:
NVIDIA/DALI
:https://github.com/NVIDIA/DALI
IO提速
使用更快的图片处理
opencv
一般要比PIL
要快- 对于
jpeg
读取,可以尝试jpeg4py
- 存
bmp
图(降低解码时间)
小图拼起来存放(降低读取次数)
对于大规模的小文件读取,建议转成单独的文件,可以选择的格式可以考虑:TFRecord(Tensorflow)
、recordIO(recordIO)
、hdf5
、 pth
、n5
、lmdb
等等(https://github.com/Lyken17/Efficient-PyTorch#data-loader)
预读取数据
- 预读取下一次迭代需要的数据
【参考】
- 如何给你PyTorch里的Dataloader打鸡血 - MKFMIKU的文章 - 知乎 如何给你PyTorch里的Dataloader打鸡血 - 知乎
- 给pytorch 读取数据加速 - 体hi的文章 - 知乎 给pytorch 读取数据加速 - 知乎
借助内存
- 直接载到内存里面,或者把把内存映射成磁盘好了
借助固态
- 把读取速度慢的机械硬盘换成 NVME 固态吧~
【参考】
- 如何给你PyTorch里的Dataloader打鸡血 - MKFMIKU的文章 - 知乎 如何给你PyTorch里的Dataloader打鸡血 - 知乎
训练策略
作者:人民艺术家
链接:https://www.zhihu.com/question/307282137/answer/907835663
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
代码层面
torch.backends.cudnn.benchmark = True
- Do numpy-like operations on the GPU wherever you can
- Free up memory using
del
- Avoid unnecessary transfer of data from the GPU
- Use pinned memory, and use
non_blocking=True
to parallelize data transfer and GPU number crunching- 文档:https://pytorch.org/docs/stable/nn.html#torch.nn.Module.to
- 关于
non_blocking=True
的设定的一些介绍:Pytorch有什么节省显存的小技巧? - 陈瀚可的回答 - 知乎 Pytorch有什么节省显存的小技巧? - 知乎
- 网络设计很重要,外加不要初始化任何用不到的变量,因为 PyTorch 的初始化和
forward
是分开的,他不会因为你不去使用,而不去初始化 - 合适的
num_worker
: Pytorch 提速指南 - 云梦的文章 - 知乎 Pytorch 提速指南 - 知乎(这里也包含了一些其他细节上的讨论)
模型设计
来自 ShuffleNetV2 的结论:(内存访问消耗时间,memory access cost
缩写为 MAC
)
- 卷积层输入输出通道一致:卷积层的输入和输出特征通道数相等时 MAC 最小,此时模型速度最快
- 减少卷积分组:过多的 group 操作会增大 MAC ,从而使模型速度变慢
- 减少模型分支:模型中的分支数量越少,模型速度越快
- 减少
element-wise
操作:element-wise
操作所带来的时间消耗远比在 FLOPs 上的体现的数值要多,因此要尽可能减少element-wise
操作(depthwise convolution
也具有低 FLOPs 、高 MAC 的特点)
其他:
- 降低复杂度:例如模型裁剪和剪枝,减少模型层数和参数规模
- 改模型结构:例如模型蒸馏,通过知识蒸馏方法来获取小模型
推理加速
半精度与权重量化
在推理中使用低精度(FP16
甚至 INT8
、二值网络、三值网络)表示取代原有精度(FP32
)表示:
TensorRT
是 NVIDIA 提出的神经网络推理(Inference)引擎,支持训练后 8BIT 量化,它使用基于交叉熵的模型量化算法,通过最小化两个分布的差异程度来实现- Pytorch1.3 开始已经支持量化功能,基于 QNNPACK 实现,支持训练后量化,动态量化和量化感知训练等技术
- 另外
Distiller
是 Intel 基于 Pytorch 开源的模型优化工具,自然也支持 Pytorch 中的量化技术 - 微软的
NNI
集成了多种量化感知的训练算法,并支持PyTorch/TensorFlow/MXNet/Caffe2
等多个开源框架
【参考】:
网络 inference 阶段 Conv 层和 BN 层融合
【参考】
- 模型推理加速技巧:融合BN和Conv层 - 知乎
- PyTorch本身提供了类似的功能,但是我没有使用过,希望有朋友可以提供一些使用体会:https://pytorch.org/docs/1.3.0/quantization.html#torch.quantization.fuse_modules
- 网络inference阶段conv层和BN层的融合 - autocyz的文章 - 知乎 网络inference阶段conv层和BN层的融合 - 知乎
时间分析
- Python 的
cProfile
可以用来分析。(Python 自带了几个性能分析的模块:profile
、cProfile
和hotshot
,使用方法基本都差不多,无非模块是纯 Python 还是用 C 写的)
项目推荐
- 基于 Pytorch 实现模型压缩(https://github.com/666DZY666/model-compression):
- 量化:8/4/2 bits(dorefa)、三值/二值(twn/bnn/xnor-net)
- 剪枝:正常、规整、针对分组卷积结构的通道剪枝
- 分组卷积结构
- 针对特征二值量化的BN融合