概要
NvidiaのGPU(A100)を使った場合のConvolutionの最適化についてのまとめ
- Batch sizeは2の累乗で出来るだけ大きく。
- Channel数は最低でも4の倍数。runtimeの環境で計測するのが良い。
- 効率の良いChannel数を見つけたら、Group ConvolutionでFLOPS(1秒間に実行できる浮動小数点演算の回数)を下げずに計算数を減らすのを試してみる。
- cudnn.benchmarkをTrueにする。
- channel last(NHWC)にする。
- ストライド数は気にしなくて良い。
- あまり大きなDilationは避けたほうが良さそう。代わりに画像サイズを小さくして、Channel数を増やすのを試してみる。
- ChannelやKernel sizeを大きくするとweight数が増えて、メモリー転送時間が掛かる事も頭の片隅に置いておく。
ただし、GPUのアーキテクチャー、CuDnnなどのlibraryのversion、TensorRTを使った場合などで変わる事がある
もう少し一般的な高速化の記事はこちら
Channel数
flag
torch.backends.cudnn.benchmark = Trueにすると自動でベストの計算方法を選んでくれる。
例えば、フーリエ変換を使うことでconvolutionを速く出来るらしい。
Tensor Layout
チャネルファースト(NCHW)よりチャネルラスト(NHWC)の方が並列化しやすい
channel lastだと畳み込みたい値が近くのメモリーにいるので、メモリー効率が高いのが一つの理由
Filter size
C(channel数)*R(kernel height)*S(kernel width)が大きくなると並列化を最大限活用出来る
ただkernel sizeはそんなに変える事は無いのでChannelサイズを調整してみると良い。
ストライド数
U(Horizontal stride)とV(Vertical stride)を変えても速度にはあまり影響が無い
*横軸はP(OutputのHeight)とQ(OutputのWidth)
Dilation
Dilation=2の方がDilation=1より若干遅い。メモリアクセス効率が影響しているはず。
*横軸はN(Batch数)
左がDilation=1 右がDilation=2
参考文献
https://pytorch.org/blog/accelerating-pytorch-vision-models-with-channels-last-on-cpu/
https://docs.nvidia.com/deeplearning/performance/dl-performance-convolutional/index.html
https://docs.nvidia.com/deeplearning/performance/dl-performance-matrix-multiplication/index.html#dim-quantization