Keras PlatoBlockchain Data Intelligence を使用したマルチ GPU トレーニングのための 5 つのヒント。垂直検索。あい。

Kerasを使用したマルチGPUトレーニングの5つのヒント

ディープラーニング(ブロックチェーン/ビットコインとデータサイエンス/機械学習と共に2010年代後半に人気の流行語)により、過去数年間、私たちはいくつかの本当にクールなことをすることができました。 アルゴリズムの進歩(1990年代以降「データマイニング時代」とも呼ばれていることは認められています)のほかに、その成功の主な理由は、大規模な無料データセットの可用性、オープンソースライブラリの導入、 GPUの使用。 このブログ投稿では、最後のXNUMXつに焦点を当てます。難しい方法で学んだいくつかのヒントを紹介します。

なぜTensorFlowとKerasなのですか?

TensorFlow Googleが開発した非常に人気のあるディープラーニングライブラリで、複雑なネットワークのプロトタイプをすばやく作成できます。 自動微分(コスト関数の勾配を推定/コーディングする手間を省く)やGPUサポート(まともなハードウェアを使用して200倍の速度向上を簡単に実現できる)など、多くの興味深い機能が付属しています。 さらに、Pythonインターフェイスを提供します。つまり、CまたはCUDAコードを記述せずにプロトタイプをすばやく作成できます。 確かに、Torch、MXNet、Theano、Caffe、Deeplearning4j、CNTKなど、TensorFlowの代わりに使用できる他の多くのフレームワークがありますが、すべてはユースケースと個人の好みに集約されます。

しかし、なぜ ケラス? 私にとって直接使用するTFは、Numpyで機械学習を行うようなものです。 はい、それは可能であり、時々それを行う必要があります(特にカスタムレイヤー/損失関数を作成する場合)が、複雑なネットワークを一連のベクトル演算として説明するコードを本当に書きたいですか(はい、私は知っています) TFにはより高レベルのメソッドがありますが、それらはKerasほどクールではありません)? また、別のライブラリに移動したい場合はどうなりますか? さて、あなたはおそらくコードを書き直す必要があるでしょう、それはひどいです。 Ta ta taaa、Kerasが助けに! Kerasを使用すると、高レベルの概念を使用してネットワークを記述し、バックエンドにとらわれないコードを記述できます。つまり、さまざまなディープラーニングライブラリ全体でネットワークを実行できます。 Kerasについて私が好きなことは、それがよく書かれていること、オブジェクト指向のアーキテクチャを持っていること、貢献しやすいこと、友好的なコミュニティがあることです。 気に入ったら、ありがとうと言って フランソワ・ショレ それを開発し、それをオープンソース化するため。

マルチGPUトレーニングのヒントと注意点

さらに苦労せずに、KerasでGPUトレーニングを最大限に活用するためのいくつかのヒントと、心に留めておくべきいくつかの落とし穴にジャンプしましょう。

1.マルチGPUトレーニングは自動ではありません

Keras&Tensorflowを使用したGPUでのモデルのトレーニングはシームレスです。 NVIDIAカードをお持ちで、CUDAをインストールしている場合、ライブラリは自動的にそれを検出し、トレーニングに使用します。 とてもクール! しかし、もしあなたが甘やかされて育ったガキで、複数のGPUを持っているとしたらどうでしょうか? 残念ながら、マルチGPUトレーニングを実現するには少し作業が必要になります。
Keras PlatoBlockchain Data Intelligence を使用したマルチ GPU トレーニングのための 5 つのヒント。垂直検索。あい。
目的に応じてネットワークを並列化する方法は複数ありますが、主なXNUMXつのアプローチはモデルとデータの並列化です。 前者はモデルが複雑すぎてXNUMXつのGPUに収まらない場合に役立ち、後者は実行を高速化したい場合に役立ちます。 通常、人々がマルチGPUトレーニングについて話すとき、それらは後者を意味します。 以前は達成するのが困難でしたが、ありがたいことに、Kerasは最近、 multi_gpu_model これにより、並列トレーニング/予測が容易になります(現在、TFバックエンドでのみ使用できます)。 主なアイデアは、モデルをメソッドに渡し、異なるGPU間でコピーすることです。 元の入力はチャンクに分割され、さまざまなGPUに送られ、単一の出力として集約されます。 この方法は、並列トレーニングと予測を達成するために使用できますが、トレーニングでは、必要な同期のためにGPUの量に比例してスケーリングされないことに注意してください。

2.バッチサイズに注意する

マルチGPUトレーニングを行うときは、バッチサイズに注意してください。バッチサイズは速度/メモリ、モデルの収束に複数の影響を与えるため、注意しないとモデルの重みが破損する可能性があります。

速度/メモリ: 明らかに、バッチが大きいほど、トレーニング/予測が速くなります。 これは、GPUからのデータの出し入れにオーバーヘッドがあるため、小さなバッチのオーバーヘッドが大きくなるためです。 反対に、バッチが大きいほど、GPUで必要なメモリが多くなります。 特にトレーニング中は、各層の入力はバックプロパゲーションステップで必要になるため、メモリに保持されるため、バッチサイズを大きくしすぎると、メモリ不足エラーが発生する可能性があります。

収束: Stochastic Gradient Decent(SGD)またはそのバリアントの一部を使用してモデルをトレーニングする場合、バッチサイズがネットワークの収束と一般化の能力に影響を与える可能性があることに注意してください。 多くのコンピュータビジョンの問題における典型的なバッチサイズは、32〜512の例です。 なので ケスカー他 「一般的に、512より大きいバッチを使用すると、モデルの品質が低下することが観察されています。これは、一般化する能力によって測定されます。」 他の異なるオプティマイザには異なるプロパティがあり、特殊な分散最適化手法が問題の解決に役立つことに注意してください。 数学の詳細に興味がある場合は、Joeri Hermansの論文「スケーラブルなディープラーニングと勾配降下法の並列化について"。
Keras PlatoBlockchain Data Intelligence を使用したマルチ GPU トレーニングのための 5 つのヒント。垂直検索。あい。
重みを壊す: これは厄介な技術的詳細であり、壊滅的な結果をもたらす可能性があります。 マルチGPUトレーニングを行う場合、すべてのGPUにデータを供給することが重要です。 エポックの最後のバッチのデータが定義より少ない場合があります(データセットのサイズをバッチのサイズで正確に除算できないため)。 これにより、一部のGPUが最後のステップでデータを受信しない可能性があります。 残念ながら、一部のKeras層、特にバッチ正規化層は、重み(BN層の移動平均と分散)にnan値が表示される原因となるものに対処できません。 特定のレイヤーは推定でバッチの平均/分散を使用するため、状況をより複雑にするために、トレーニング中(学習フェーズが1の間)の問題は観察されません。 それにもかかわらず、予測中(学習フェーズが0に設定されている場合)は、実行中の平均/分散が使用されます。 ですから、自分でお願いして、マルチGPUトレーニングを行うときは、常にバッチサイズが固定されていることを確認してください。 これを実現するXNUMXつの簡単な方法は、事前定義されたサイズに一致しないバッチを拒否するか、事前定義されたサイズに達するまでバッチ内のレコードを繰り返すことです。 最後に重要なこととして、マルチGPUセットアップでは、バッチサイズはシステムで使用可能なGPUの数の倍数である必要があります。

3. GPUデータスターベーション、つまりCPUがGPUに対応できない

通常、ディープネットワークのトレーニング/予測で最も費用がかかるのは、GPUで発生する推定です。 データはバックグラウンドのCPUで前処理され、定期的にGPUに送られます。 それでも、GPUの速度を過小評価しないでください。 ネットワークが浅すぎたり、前処理ステップが複雑すぎたりして、CPUがGPUに追いつけない、つまり、GPUに十分な速度でデータを供給できない場合があります。 これにより、GPUの使用率が低くなり、お金やリソースが無駄になる可能性があります。
Keras PlatoBlockchain Data Intelligence を使用したマルチ GPU トレーニングのための 5 つのヒント。垂直検索。あい。
Kerasは通常、バッチの推定を並行して実行しますが、PythonのGIL(グローバルインタープリターロック)のため、Pythonで真のマルチスレッドを実際に実現することはできません。 そのためのXNUMXつの解決策があります。複数のプロセスを使用する(ここでは説明しませんが、このプロセスには多くの落とし穴があることに注意してください)か、前処理ステップを単純にします。 過去に私はKerasにプルリクエストを送信して、画像の前処理中にCPUにかかる不要な負担の一部を軽減しました。そのため、ほとんどのユーザーが標準のジェネレーターを使用しても影響を受けません。 カスタムジェネレーターがある場合は、NumpyなどのCライブラリにできるだけ多くのロジックをプッシュしてみてください。これらのメソッドの一部は実際に GILを解放する つまり、並列化の度合いを上げることができます。 GPUデータの枯渇に直面しているかどうかを検出する良い方法は、GPU使用率を監視することですが、これがそれを観察する唯一の理由ではないことに注意してください(複数のGPUにわたるトレーニング中に発生する同期は、使用率が低いことのせいでもあります)。 通常、GPUデータの枯渇は、GPUバーストに続いて使用率のない長い休止を観察することで検出できます。 過去には、GPU使用率の測定に役立つDstatの拡張機能をオープンソース化してきましたので、 元のブログ投稿.

4.並列モデルを保存する

mutli_gpu_modelメソッドを使用してモデルを並列化し、トレーニングが終了して、重みを維持したいとします。 悪い知らせは、save()を呼び出すだけではできないということです。 現在、Kerasには、次のことを許可しない制限があります 並列モデルを保存する。 これには2つの方法があります。元のモデルの参照でsave()を呼び出す(重みは自動的に更新されます)か、並列化されたバージョンを切り刻み、すべての不要な接続をクリーンアップしてモデルをシリアル化する必要があります。 最初のオプションの方が簡単ですが、将来的には後者を実行するserialize()メソッドをオープンソースにする予定です。

5.使用可能なGPUをカウントすると、厄介な副作用が発生します

残念ながら現時点では、tensorflow.python.client.device_lib.list_local_devices()メソッドに厄介な副作用があり、新しいTensorFlowセッションが作成され、システムで利用可能なすべてのGPUが初期化されます。 これにより、指定した数より多くのGPUを表示したり、新しいセッションを時期尚早に初期化したりするなど、予期しない結果が発生する可能性があります(この詳細をすべて読むことができます) プルリクエスト)。 同様の驚きを避けるために、代わりにKerasのK.get_session()。list_devices()メソッドを使用することをお勧めします。これにより、セッションに現在登録されているすべてのGPUが返されます。 最後に重要なことですが、list_devices()メソッドの呼び出しは多少コストがかかるため、使用可能なGPUの数だけに関心がある場合は、メソッドをXNUMX回呼び出してローカル変数にその数を保存してください。

それでおしまい! このリストがお役に立てば幸いです。 KerasでのGPUトレーニングに関する他の落とし穴/ヒントを見つけた場合は、コメントで以下に共有してください。 🙂

タイムスタンプ:

より多くの データムボックス