O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Chainer で Tensor コア (fp16) を使いこなす

11.404 visualizações

Publicada em

2018年12月15日の Chainer Meetup #08 でエヌビディアの成瀬が発表した資料です。
https://chainer.connpass.com/event/106292/

Publicada em: Tecnologia
  • Seja o primeiro a comentar

Chainer で Tensor コア (fp16) を使いこなす

  1. 1. Akira Naruse, Senior Developer Technology Engineer, 2018/12/15 Chainer で Tensor コア (fp16) を 使いこなす
  2. 2. 2 ドーナツで、発表枠を、頂戴しました 128個 90個
  3. 3. 3 最初におことわり… タイトル: • Chainer で Tensor コア (fp16) を使いこなす 中身: • ありとあらゆる手段を使い、Chainer で Tensor コア (fp16) を どこまで使いきれるかを、実験した
  4. 4. 4 VOLTA TENSOR コア FP16/FP32 混合精度行列演算ユニット Tesla P100 Tesla V100 FP16 20 TFLOPS 125 TFLOPS (Tensor コア) FP32 10 TFLOPS 16 TFLOPS FP16 FP16 × + FP32 FP32 FP16 FP32
  5. 5. 5 FP16 で学習して、精度は大丈夫? • 2 つのテクニック • ロス スケーリング • ロス値をスケールアップし、勾配消失を緩和 • ウェイト更新直前に、勾配値をスケールダウン • FP32 ウェイト更新 (FP16 と FP32 の併用) • Forward/Backward は FP16 で計算 • Update で FP32 を使用 Mixed Precision Training https://devblogs.nvidia.com/mixed-precision-training-deep-neural-networks/ 勾配値の分布 (*) FP16 にすると、多くの勾配値がゼロになってしまう
  6. 6. 6 ロス スケーリングと FP32 ウェイト更新 勾配勾配勾配勾配勾配勾配勾配 損失 関数 誤差 Backward Forward Update 勾配をスケールダウンし (例: 1/10 倍)、 FP32 ウェイト (master) を更新し、 FP16 ウェイトにコピーする Backward 直前に誤差をスケールアップし (例: 10 倍)、勾配消失を回避する
  7. 7. 7 FP16 で精度を維持する方法 • FP16 で学習しても、FP32 モデルとほぼ同じ精度 • 主要な DL フレームワークで利用可能 • TensorFlow • PyTorch • MxNet • Chainer Mixed Precision Training https://devblogs.nvidia.com/mixed-precision-training-deep-neural-networks/ Better
  8. 8. 8 本日のお題 ResNet-50 のトレーニングを Tensor コア/fp16 を用いて Chainer で速くする (*) K. He, et.al., Deep Residual Learning for Image Recognition, arxive:1512.03385 Bottleneck architecture ResNet-34 ResNet-50
  9. 9. 9 テスト環境 Machine: DGX Station GPU: Tesla V100-16GB CUDA: 9.2 cuDNN: 7.4.1 Chainer: v6.0.0b1+ CuPy: v6.0.0b1+
  10. 10. 10 注意事項: その1 cuDNN のワークスペースサイズを大きめに設定する chainer.cuda.set_max_workspace_size(512*1024*1024) # 512MiB cuDNN の Auto Tuning を使う config.autotune = True (*) そうしないと、適切なアルゴリズムが選択されない、ことが多い cuDNN の高速 Batch Normalization 実装を使う config.cudnn_fast_batch_normalization = True (*) fp32 でも有効、オーバーフローの可能性有るので注意 cuDNN tips
  11. 11. 11 注意事項: その2 モデル記述を fp16 向けに修正 • 入力: fp16 に cast • Initializer、Batch normalization: dtype に fp16 指定 本当は、fp16 モードをセットするだけで OK なんだけど.. CHAINER_DTYPE=float16 Chainer tips def forward(self, x, t): - h = self.bn1(self.conv1(x)) + h = self.bn1(self.conv1(F.cast(x, np.float16))) h = F.max_pooling_2d(F.relu(h), 3, stride=2) self.conv1 = L.Convolution2D(3, 64, 7, 2, 3, - initialW=initializers.HeNormal()) - self.bn1 = L.BatchNormalization(64) + initialW=initializers.HeNormal(dtype=np.float16)) + self.bn1 = L.BatchNormalization(64, dtype=np.float16)
  12. 12. 12 性能比較 良い点: • BS: 128 以上で、fp32 より速い • BS: 256で学習可能 (fp32 だと メモリ不足) 悪い点: • BS: 64 以下だと、fp32 より遅い FP32 vs. FP16 0 100 200 300 400 500 600 700 800 900 bs:32 bs:64 bs:128 bs:256 Images/sec fp32 fp16 Better
  13. 13. 13 TRAINING ITERATION CPU の仕事 • IO: 入力画像の前処理 (Decode, Augmentation) • Forward/Backward/Update: 計算グラフ管理, メモリ管理, GPU カーネル投入 IO Forward Backward Update GPU の仕事 • Forward/Backward/Update: CPU から投入されたカーネルを実行
  14. 14. 14 性能比較 良い点: • BS: 128以上で、fp32 より速い • BS: 256で学習可能 (fp32 だと メモリ不足) 悪い点: • BS: 64以下だと、fp32 より遅い FP32 vs. FP16 0 100 200 300 400 500 600 700 800 900 bs:32 bs:64 bs:128 bs:256 Images/sec fp32 fp16 Better
  15. 15. 15 NVVP で挙動を確認 (FP32, BS: 64) 高い GPU 稼働率 FWD BWD UPDIO CPU FWD BWD GPU 拡大
  16. 16. 16 NVVP で挙動を確認 (FP32, BS: 64) 拡大図 高い GPU 稼働率 FWD BWD
  17. 17. 17 NVVP で挙動を確認 (FP16, BS: 64) GPU稼働率が低い FWD BWDIO CPU FWD BWDGPU Tensor コア使用で GPU 処理は速くなった。しかし、CPU の処理が間に合わない
  18. 18. 18 NVVP で挙動を確認 (FP16, BS: 64) 拡大図 GPU 稼働率が低い FWD BWD
  19. 19. 19 対策: CPU の負荷を減らす IO 処理を高速化、別スレッドで実行 • NVIDIA DALI GPU 操作回数、GPU カーネル数を削減 • Batched weight update、 Fused Bnorm/ReLu、 NHWC format 計算グラフ管理負荷を削減 • Chainer static_graph
  20. 20. 20 NVIDIA DALI https://github.com/NVIDIA/DALI (オープンソース) 前処理は別スレッドで実行 一部前処理は GPU 利用して加速 Chainer、DALI 対応済 (experimental) • 詳しくは、examples/imagenet を参照
  21. 21. 21 NVIDIA DALIの効果 良い点: • BS: 64以上で、fp32 より速い • BS: 128 はBS: 256 とほぼ同性能 悪い点: • BS: 32以下だと、fp32 より遅い 0 100 200 300 400 500 600 700 800 900 bs:32 bs:64 bs:128 bs:256 Images/sec fp32 fp16 fp16 (+dali) Better
  22. 22. 22 NVIDIA DALI の効果確認 (FP16, BS: 64) IO 処理は、他とオーバーラップ FWD BWD FWD BWD IO by DALI (next) CPU GPU 依然として、CPU の処理が間に合っていない
  23. 23. 23 対策: CPU の負荷を減らす IO 処理を高速化、別スレッドで実行 • NVIDIA DALI GPU 操作回数、GPU カーネル数を削減 • Batched weight update、 Fused Bnorm/ReLu、 NHWC format 計算グラフ管理負荷を削減 • Chainer static_graph
  24. 24. 24 BATCHED WEIGHT UPDATE Chainer optimizer は、レイヤー毎(より正確にはパラメータ毎)に、重みを更新 • 多数の GPU カーネル起動 → CPU 負荷大 Single GPU カーネルで、全ての重みを更新 (batched_update) Chainer #5841 PR中 update update CPU GPU
  25. 25. 25 FUSED BNORM/RELU • cuDNN 7.4 から導入 • Fp16 and NHWC フォーマット (後述) のときに利用可能 • レイヤーの自動融合は大変。 bnorm_add_relu モジュールを試作。 モデル記述を修正。 GPU カーネル数の削減、メモリアクセス量を削減 試作
  26. 26. 26 NHWC FORMAT • NCHW だと、Convolution 前後 で、合計 3 回の Tensor Transpose が必要 • NHWC なら、Transpose 不要 → GPU カーネル数削減 • Chainer は NCHW only • NHWC 専用の Convolution/Bnorm モジュール を試作 cuDNN Convolution for TensorCore: NHWC format で高い性能を発揮 NCHW NHWC 試作
  27. 27. 27 BATCHED+FUSED+NHWC の効果 良い点: • 常に fp32 より速い • BS: 256 で、1200 imgs/sec 悪い点 (相対的に): • BS: 32は、BS: 256 の 1/3 の 性能0 200 400 600 800 1000 1200 1400 bs:32 bs:64 bs:128 bs:256 Images/sec fp32 fp16 (+dali) fp16 (+nhwc, fused, batched) Better
  28. 28. 28 効果確認 (FP16, BS: 64) NHWC+FUSED+BATCHED FWD BWD FWD BWD IO by DALI (next) CPU GPU CPU 負荷を減らしたが、GPU 時間も NHWC+FUSED で短縮 → まだ GPU に空きがある
  29. 29. 29 対策: CPU の負荷を減らす IO 処理を高速化、別スレッドで実行 • NVIDIA DALI GPU 操作回数、GPU カーネル数を削減 • Batched weight update、 Fused Bnorm/ReLu、 NHWC format 計算グラフ管理負荷を削減 • Chainer static_graph
  30. 30. 30 STATIC_GRAPH 説明省略
  31. 31. 31 STATIC_GRAPHの効果 良い点: • BS: 32/64 の性能改善 悪い点: • BS: 128 以上で実行不可 (メモリ使用量が増える?) 0 200 400 600 800 1000 1200 1400 bs:32 bs:64 bs:128 bs:256 Images/sec fp32 fp16 (+nhwc, fused, batched) fp16 (+static_graph) Better
  32. 32. 32 効果確認 (FP16, BS: 64) Static_graph FWD BWD FWD BWD IO by DALI (next) CPU GPU やっと、「CPU 処理時間 < GPU 処理時間」、になった
  33. 33. 33 ここまでのまとめ fp32 の3倍の性能を達成 (最大で) • DALI • Batched weight update • Fused Bnorm/ReLu • NHWC format • Static_graph Backend が python でも、ここまで 速くできる Tensor コア/fp16 を用いた ResNet-50 トレーニング 0 200 400 600 800 1000 1200 1400 bs:32 bs:64 bs:128 bs:256 Images/sec fp32 fp16 (base) fp16 (best) Better ChainerXで 速くなる?
  34. 34. 34 何故 “BS: 32” を速くしたいのか Goal: ImageNet+ResNet50 with 4096 GPUs Processor DL framework Time Microsoft Tesla P100 x8 Caffe 29 hours Facebook Tesla P100 x256 Caffe2 1 hour Google TPUv2 x256 TensorFlow 30 mins PFN Tesla P100 x1024 Chainer 15 mins Tencent Tesla P40 x2048 TensorFlow 6.6 mins SONY Tesla V100 x2176 NNL 3.7 mins Google TPUv3 x1024 TensorFlow 2.2 mins
  35. 35. 35 LARGE MINI-BATCH PROBLEM Local BS: 32 でも、4096 GPU だと、 Global BS: 128K ImageNet + ResNet50だと、Global BS: 32~64K でも、validation error < 25% を出せるようになってき たが.. SGD の限界? ImageNet, ResNet50, Local BS:32 (*) P. Goyal, et.al., Facebook, “Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour” Better
  36. 36. 36 SGD 以外の選択肢 Backprop で得られる「勾配ベクトル」の向きは、 それほど正しくない KFAC: フィッシャー行列を近似計算して勾配補正 • 学習の「向き」が SGD より正しくなる (反復数減) • 1 反復あたりの計算量が増える Global BS: 128K でも、75% の validation accuracy を実証 • BS 16K 以下なら、30~35 epoch で収束 (SGD は90 epoch 必要) K. Osawa, et.al., “Second-order Optimization Method for Large Mini-batch: Training ResNet-50 on ImageNet in 35 Epochs” (*) 東工大 横田研・松岡研との共同研究 ImageNet + ResNet50 Better Distributed KFAC optimizer on Chainer
  37. 37. 37 ご案内 「第1 回 ディープラーニング分散学習ハッカソン」 https://www.cc.u-tokyo.ac.jp/events/lectures/111/

×