パラメータ調整器、ここを見てください!ディープラーニングのトレーニング効率を向上させる2つのコツ

パラメータ調整器、ここを見てください!ディープラーニングのトレーニング効率を向上させる2つのコツ

[[343402]]

1. トレーニングのボトルネックはどこですか?

  • GPU 使用率が低い: モデルのトレーニング中は GPU メモリが完全に使用されますが、GPU 使用率は不安定で、0% になることもあれば、90% になることもあります。

  • トレーニング データの量が膨大: トレーニング データの量は数百万または数千万と膨大です。1 エポックのトレーニングに長い時間がかかり、モデルの反復サイクルが長すぎます。

2. GPU 使用率の向上: CPU と GPU

GPU 使用率が低いです。主な原因は、CPU の処理効率が GPU に追いつけないことです。

2.1 CPUとGPUの通信

  • CPU は、データのロードとデータの前処理、およびメモリとビデオ メモリ間での継続的なデータ交換を担当します。
  • GPU はモデルのトレーニングを担当します (インターネットからの画像)

2.2 解決策

マルチプロセス並列処理を使用してCPUのデータ読み込みパフォーマンスを高速化します

  • keras keras は、データを並列処理し、GPU モデル トレーニング用にキューにプッシュするマルチプロセス アプローチを採用するワーカー use_multiprocessing を提供します。プロセスは互いのリソースに影響を与える可能性があるため、大きいほど良いです。ワーカーは 2、4、または 8 に設定できます。
  1. 実行モデル.フィットジェネレータ(  
  2. ジェネレータ= training_generator  
  3. class_weight ={0: config.weights, 1: 1},  
  4. エポックエポック=エポック、  
  5. 詳細= 1  
  6. ステップ数/エポックステップ数/エポック=ステップ数/エポック、  
  7. コールバック= callbacks_list  
  8. 検証データ=有効なジェネレータ
  9.  検証手順検証手順= 検証手順、  
  10. シャッフル= True  
  11. 労働者= 8  
  12. use_multiprocessing = True  
  13. 最大キューサイズ= 20  
  • Pytorch torch は、データのロード時に同様のパラメータ num_workers を提供します。 pin_memory=True メモリを必要とせずにビデオメモリに直接ロードできます
  1. torch.utils.data.DataLoader(image_datasets[x],  
  2. バッチサイズバッチサイズ=バッチサイズ、  
  3. シャッフル= True  
  4. 労働者数= 8  
  5. pin_memory = True )

3. 分散並列トレーニング

3.1 パラレルモード

トレーニングデータの量が多い場合は、複数のマシンと複数の GPU を使用することでトレーニング効率を向上させることができます。 Hadoop や Spark などの分散データ処理フレームワークとは異なり、ディープラーニングのトレーニングにはパラメータの順方向伝播と逆方向伝播が含まれるため、次の 2 つの並列方法があります。

  • モデルの並列処理: 分散システム内の異なるマシン (GPU/CPU など) は、ネットワーク モデルの異なる部分を担当します。通常、ニューラル ネットワーク モデルの異なるネットワーク レイヤーは異なるマシンに割り当てられるか、同じレイヤー内の異なるパラメーターは異なるマシンに割り当てられます。通常、これらは NLP モデルなどのグラフィック カードに収まらない非常に大きなモデルです。モデル並列処理の欠点は、レイヤー間に依存関係が存在する可能性があり、完全に並列化できないことです。 (インターネットからの写真)

  • データ並列処理: 異なるマシンに同じモデルの複数のコピーがあり、各マシンに異なるデータが割り当てられ、その後、すべてのマシンの計算結果が何らかの方法でマージされます。これはビッグデータの状況に適しています。データ並列処理が解決する必要がある問題は、データの分割と転送、およびパラメータの更新です。

3.2 データの並列処理

Facebook は、「正確で大規模なミニバッチ SGD: 1 時間で ImageNet をトレーニング」で、ResNet-50 ネットワークの「データ並列」トレーニングに 256 個の GPU を使用する方法を紹介しました。

  • データのセグメンテーション: 大きなバッチサイズを使用し、ワーカーの数に応じてセグメント化し、異なるワーカーに分散して実行します。
  • パラメータ更新:パラメータ更新には2つのモードがあります:(1)パラメータサーバー(2)リング更新(サーバーレスモード)

3.2.1 パラメータサーバーモード

パラメータ サーバー モードについては、下の図を参照してください。各ワーカーがトレーニングのバッチを完了した後、パラメータをバックプロパゲーションするときに、すべてのワーカーはパラメータをパラメータ サーバーに渡して集約および平均化し、その後、各ワーカーに渡して 2 番目のトレーニング バッチを入力します。 (インターネットからの写真)

パラメータ サーバーには 1 つ以上の構造モードがあります。このデータ並列モードの効率が向上するかどうかは、パラメータ サーバーとワーカー間の通信効率、つまり、最も遅いワーカーのトレーニング時間と、パラメータ サーバーがパラメータを受信して​​更新し、それを送り返すのにかかる時間によって決まることがわかります。ワーカーの数が多い場合、パラメータ サーバーがボトルネックになる可能性があります。 (インターネットからの写真)

3.2.2 リング削減

Baidu が提案したリングリデュースは、パラメータサーバーを廃止し、パラメータを更新するためにリング構造を採用しています。リング削減は、すべてのワーカーをリング構造に編成し、2 つのワーカーを互いに隣接させます。各ワーカーは隣接するワーカーとのみパラメータを交換します。数回のやり取りの後、すべてのワーカーに他のワーカーのパラメータ情報が含まれ、更新の目的が達成されます。 (インターネットからの写真)

次の図はいくつかのステップを示しています。プロセスを高速化するために、ring-reduce はすべてのパラメータを一度に交換しません。代わりに、最初にパラメータを分割し、分割されたパラメータを連続的に交換します。

4. 実装フレームワーク: Horovod

Horovod は、Uber がオープンソース化したもう 1 つのディープラーニング ツールです。その開発は、Facebook の「1 時間の ImageNet トレーニング ペーパー」と Baidu の Ring Allreduce の利点を活用しており、ユーザーが分散トレーニングを実装するのに役立ちます。 https://github.com/horovod/horovod

NCCL を使用して、Baidu の ring-allreduce 実装を置き換えます。 NCCL は、ring-allreduce の高度に最適化されたバージョンを提供する NVIDIA の集合通信ライブラリです。 NCCL 2 では、複数のマシン間で ring-allreduc を実行できます。

スタンドアロンのトレーニング コードを分散コードに変更する場合、分散トレーニングを変換するために必要な手順はわずかです。

  • Horovod のインストール 環境をインストールする手間を省くために、docker の horovod をインストールすることをお勧めします。 HorovodはNCCL 2オープンMPIに依存している
  1. $ mkdir horovod-docker-gpu  
  2. $ wget -O horovod-docker-gpu/Dockerfile https://raw.githubusercontent.com/horovod/horovod/master/Dockerfile.gpu  
  3. $ docker build -t horovod:最新のhorovod-docker-gpu
  • マシンワーカーマシン間の SSH 接続
  • トレーニング コードを変更します。horovod は、tf、keras、pytorch、mxnet などのさまざまなディープラーニング フレームワークをサポートします。 kerasを例にとると、主な6つのステップを変更します(1)初期化:hvd.init()(2)GPUコンピューティングリソースの割り当て:config.gpu_options.visible_device_list = str(hvd.local_rank())(3)パラメータの分散更新を実現するための分散オプティマイザー:opt = hvd.DistributedOptimizer(opt)(4)すべてのワーカーモデルの初期化の一貫性を定義しますhvd.callbacks.BroadcastGlobalVariablesCallback(0)(5)モデルは特定のワーカーに保存されます
  1. __future__ から print_function をインポートする 
  2. kerasをインポートする
  3.   keras.datasetsからmnistをインポートする 
  4. keras.modelsからSequentialをインポートする 
  5. keras.layers から Dense、Dropout、Flatten をインポートします 
  6. keras.layers から Conv2D、MaxPooling2D をインポートします 
  7. kerasからバックエンドをKとしてインポートします 
  8. インポート数学 
  9. テンソルフローをtfとしてインポートする
  10. horovod.keras を hvd としてインポートします 
  11. # Horovod: Horovod を初期化します。  
  12. hvd.init()  
  13. # Horovod: ローカルランクの処理に使用する GPU をピン留めする (プロセスごとに 1 つの GPU)  
  14. config = tf.ConfigProto ()です。  
  15. config.gpu_options.allow_growth = True    
  16. config.gpu_options.visible_device_list = str (hvd.local_rank())  
  17. K.set_session(tf.Session( config config =config))  
  18. バッチサイズ= 128    
  19. num_classes = 10    
  20. # Horovod: GPU の数に基づいてエポックの数を調整します。  
  21. エポック= int (math.ceil(12.0 / hvd.size()))  
  22. # 入力画像のサイズ
  23.   画像行数、画像列= 28、28   
  24. # データはシャッフルされ、トレーニングセットとテストセットに分割されます 
  25. (x_train, y_train)、(x_test, y_test) = mnist.load_data()   
  26. K.image_data_format() == 'channels_first'の場合:  
  27. x_train x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)  
  28. x_test x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)  
  29. 入力形状= (1, 画像行数, 画像列数)  
  30. それ以外:  
  31. x_train x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)  
  32. x_test x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)  
  33. 入力シェイプ= (画像行、画像列、1)  
  34. x_train x_train = x_train.astype('float32')  
  35. x_test x_test = x_test.astype('float32')  
  36. x_train /= 255  
  37. x_テスト /= 255  
  38. print('x_train の形状:', x_train.shape)  
  39. print(x_train.shape[0], 'トレーニングサンプル')  
  40. print(x_test.shape[0], 'テストサンプル')  
  41. # クラスベクトルをバイナリクラス行列に変換する 
  42. y_train = keras.utils.to_categorical (y_train、num_classes)  
  43. y_test = keras.utils.to_categorical (y_test、num_classes)  
  44. モデル=シーケンシャル()  
  45. モデルを追加します(Conv2D(32,カーネルサイズ= (3, 3),  
  46. アクティベーション= 'relu'  
  47. 入力形状入力形状=入力形状))  
  48. model.add(Conv2D(64, (3, 3),アクティベーション= 'relu' ))  
  49. モデルを追加します(MaxPooling2D(プールサイズ=(2, 2)))  
  50. モデル.add(ドロップアウト(0.25))  
  51. モデルを追加します(フラット化())  
  52. model.add(Dense(128, activation = 'relu' ))  
  53. モデルを追加します(ドロップアウト(0.5))  
  54. model.add(Dense(num_classes, activation = 'softmax' ))  
  55. # Horovod: GPU の数に基づいて学習率を調整します。  
  56. opt = keras.optimizers.Adadelta (1.0 * hvd.size())  
  57. # Horovod: Horovod Distributed Optimizer を追加します。  
  58. opt = hvd.DistributedOptimizer (opt)  
  59. model.compile( loss = keras .losses.categorical_crossentropy,  
  60. optオプティマイザ=opt、  
  61. メトリック= ['精度'])  
  62. コールバック= [
  63.   # Horovod: 初期変数状態をランク 0 から他のすべてのプロセスにブロードキャストします。  
  64. # これは、すべてのワーカーの一貫した初期化を保証するために必要です。  
  65. # トレーニングはランダムな重みで開始されるか、チェックポイントから復元されます。  
  66. hvd.callbacks.BroadcastGlobalVariablesCallback(0)、  
  67. ]  
  68. # Horovod: 他のワーカーによってチェックポイントが破損するのを防ぐため、ワーカー 0 にのみチェックポイントを保存します。  
  69. hvd.rank() == 0 の場合:  
  70. callbacks.append(keras.callbacks.ModelCheckpoint('./checkpoint-{epoch}.h5'))  
  71. モデル.fit(x_train, y_train,
  72.  バッチサイズバッチサイズ=バッチサイズ、  
  73. コールバックコールバック=コールバック、  
  74. エポックエポック=エポック、  
  75. 詳細= 1  
  76. 検証データ= (x_test, y_test))  
  77. スコア=モデル.evaluate(x_test, y_test,詳細= 0 )  
  78. print('テスト損失:', スコア[0])  
  79. print('テスト精度:', score[1])
  • horovodrun による分散トレーニングの実行

horovodrun -np 16 -H server1:4、server2:4、server3:4、server4:4 python train.py

5. 結論

この記事では、GPU の利用と分散トレーニング Horovod フレームワークを通じてディープラーニング トレーニングを改善する方法について説明します。

  • CPUのロードと前処理を並列化することで、GPUがCPUを待つ必要がなくなる
  • Horovod は、データの並列処理を可能にして、大量のデータのトレーニングの反復時間を改善するために使用されます。

<<:  AIと機械学習プロジェクトのセキュリティを確保する方法

>>:  アルゴリズム実践者が知っておくべき TensorFlow のヒント 10 選

ブログ    
ブログ    
ブログ    

推薦する

...

人工知能のトレンドは将来的に急速な変化をもたらす

私たちはよく、「未来はどうなるのだろう?」と考えます。もっと正確に言えば、人類の未来はどのように発展...

AIとブロックチェーンの統合:6つの予測と可能性

今のところ、AI とブロックチェーン技術がもたらす可能性について聞いたことも、気付いていないのであれ...

大型モデルを実行するカード、パフォーマンスは4090の80%に達し、価格は半分だけ:陳天奇TVMチームが制作

最近、テクノロジー分野の多くの人々がコンピューティング能力について懸念しています。 OpenAI C...

...

匿名の論文が驚くべきアイデアを提案!大規模なモデルと長いテキストの能力を強化する

大規模モデルで長いテキストを処理する能力を向上させる場合、長さの外挿やコンテキスト ウィンドウの拡張...

李開復氏:若者は人工知能に取って代わられない仕事を探すべきだ

AlphaGo が囲碁のゲームを解読した日、人類は自分たちの仕事が AI に置き換えられるのではない...

AI | 人工知能プロジェクトを成功させるための 8 つの重要な役割

企業が AI プロジェクトをさらに展開するにつれて、特定の役割がビジネスの成功に不可欠であることがわ...

...

...

顔認識の背後にあるもの:怖いのは技術ではなく…

以前、AI顔変換ソフトウェアZAOが一夜にして人気を博したことで、サーバーが「満杯になって崩壊」する...

IoTとAIの組み合わせ:さまざまなスマートフォンが互いに学習できるようにする

センサーといえば、まず思い浮かぶのはウェアラブルデバイスです。今ではウェアラブルデバイスが広く普及し...

MapReduceアルゴリズムをわかりやすく説明する方法

Hackbright でメンターをしているときに、技術的な背景が限られている学生に MapReduc...

高精度地図のデータの問題についてお話ししましょう。地図以外の認識の落とし穴は何でしょうか?

この記事は、Heart of Autonomous Driving の公開アカウントから許可を得て転...

アルゴリズム エンジニアはなぜ一日中データを扱うのでしょうか。また、どのような種類のデータを扱うのでしょうか。

[[353273]]なぜ私たちはモデルをほとんど作らないのでしょうか?アルゴリズムエンジニアの仕事...