trainingおよびservingニューラルネットワークでは、どのような戦略と形式の並列化が可能であり、利用可能ですか?:
また、それらがどのように使用されるかについての証拠も探しています。 TensorFlow、PyTorchまたはMXNet。
私の知る限り、大規模なデータセットで大規模なニューラルネットワークをトレーニングする場合、少なくとも次のことが可能です。
それぞれの戦略は、どのタイプの問題またはニューラルネットワークに適していますか?最新のライブラリでサポートされているモードはどれですか?そして4つ(2x2)の戦略すべてを組み合わせることができますか?
その上で、私は以下について読みました:
しかし、それが何を意味するのか正確にはわかりません。 gradientsの計算different data batchsか、それともgradientsの計算subgraphsか?それとも、それは他に何かを指すのでしょうか?
ネットワークが巨大な場合、予測/推論も遅くなる可能性があり、モデルはサービス時にメモリ内の単一のマシンに適合しない可能性があります。そのようなモデルを処理できる、機能する既知のマルチコアおよびマルチノード予測ソリューションはありますか?
質問はかなり広いので、私は @ Daniel's の詳細な回答で示されたものとは少し異なる光を当てて、さまざまなトピックに触れようとします。
@ Daniel で述べたように、データ並列処理はより頻繁に使用され、正しく実行する方が簡単です。モデルの並列処理の主な注意点は、ニューラルネットワークの一部とそれらの間の同期を待つ必要があることです。
シンプルなフィードフォワード5
レイヤーニューラルネットワークが5
異なるGPUに分散していて、各レイヤーが1つのデバイスに対応しているとします。この場合、各転送パスの間、各デバイスは前のレイヤーからの計算を待つ必要があります。この単純なケースでは、デバイス間でのデータのコピーと同期にはかなり時間がかかり、メリットはありません。
一方、モデルの並列化に適したモデルが Inception networks のようにあります。以下の図を参照してください。
ここでは、前のレイヤーからの4
独立したパスを確認できます。これらのパスは、並行して進むことができ、2
同期ポイント(Filter concatenation
およびPrevious Layer
)のみです。
例えば。グラフ自体の逆伝播は並列化できます。 (私はそう思いますか?)autodiffグラフは常にDAGであるため、異なるマシンで異なるレイヤーをホストすることによって。
それは簡単ではありません。勾配は損失値に基づいて計算され(通常)、より浅い層の勾配を計算するには、より深い層の勾配を知る必要があります。上記のように、独立したパスがある場合は簡単で便利ですが、単一のデバイスの方がはるかに簡単です。
これは勾配累積とも呼ばれます(?)
いいえ、それは実際には複数のデバイスにわたる削減です。その一部は PyTorchチュートリアル で確認できます。勾配の累積は、フォワードパス(単一または複数のデバイスで)をN
回実行してバックプロパゲートし(勾配はグラフに保持され、値は各パス中に追加されます)、オプティマイザーは1つのステップのみを実行しますニューラルネットワークの重みを変更します(勾配をクリアします)。この場合、損失は通常、オプティマイザーなしのステップ数で除算されます。これは、通常、大きなバッチを使用できない場合に、より信頼性の高い勾配推定に使用されます。
デバイス間の削減は次のようになります。
これはデータの並列化ですべて削減され、各デバイスは他のすべてのデバイスに送信されてそこで逆伝播される値を計算します。
それぞれの戦略は、どのタイプの問題またはニューラルネットワークに適していますか?
上記のように、十分なデータがあり、サンプルが大きい場合、ほとんどの場合、データの並列処理は問題ありません(最大8k
サンプル以上をvery大きな問題なく一度に実行できます)。
最新のライブラリでサポートされているモードはどれですか?
tensorflow
とpytorch
はどちらもサポートしています。最新のライブラリと維持されているライブラリのどちらにも、これらの機能が実装されています
4つ(2x2)の戦略すべてを組み合わせることができます
はい、モデルとデータの両方をマシン間およびマシン内で並列化できます。
同期と非同期
@ Daniel で簡単に説明しますが、更新が完全に分離しているわけではないことを言及する価値があります。バッチに基づいてN
異なるモデルを基本的にトレーニングするので、それはほとんど意味がありません。
代わりに、各レプリカが計算された更新を非同期で共有することになっているグローバルパラメータスペースがあります(したがって、フォワードパス、バックワード、オプティマイザで更新を計算し、この更新をグローバルパラメータに共有します)。
ただし、このアプローチには1つの問題があります。あるワーカーが前方に計算されたときに別のワーカーがパラメーターを更新したことが保証されないため、更新が計算されます古いパラメーターのセットに関してと呼ばれます古いグラデーション。これにより、収束が損なわれる可能性があります。
他のアプローチは、各ワーカーのN
ステップと更新を計算し、後で同期することですが、あまり使用されません。
この部分は素晴らしい blogpost に基づいていたので、興味があれば必ず読んでください(古さといくつかの解決策についての詳細があります)。
主に以前に説明したように、さまざまなアプローチがありますが、PyTorchはネットワークから出力を収集し、それらにバックプロパゲートします(torch.nn.parallel.DistributedDataParallel
)[https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel] 。ところで。 PythonのGIL問題を克服するため、これだけ(torch.nn.DataParallel
なし)にする必要があります。
大きなモデルを求めているので、短いモデルのオプションについては詳しく説明しません。
ネットワークを介して複数のユーザーにサービスを提供する場合は、アーキテクチャ(通常はGCPやAWSなどのクラウド)をスケーリングする方法が必要です。 Kubernetes を使用してそれを行うことができ、要求を処理するためにPODまたは一部のサーバーを事前に割り当てますが、そのアプローチは非効率的です(少数のユーザーと実行中のサーバーは無意味なコストを生成しますが、多数のユーザーはインフラストラクチャが停止し、再処理に時間がかかりすぎる可能性があります)。
他の方法は、サーバーレスアプローチに基づく自動スケーリングを使用することです。リソースは各リクエストに基づいて提供されるため、大規模なスケーリング機能があり、トラフィックが少ない場合は料金を支払う必要はありません。 Azure関数 は、ML/DLタスクを改善するためのパス上にあるため、または torchlambda
はPyTorchに対して表示されます(免責事項、私は著者)より小さなモデル用。
前述のとおり、Kubernetesをカスタムコードで使用したり、すぐに使用できるツールを使用したりできます。
最初のケースでは、トレーニングと同じようにモデルを展開できますが、forward
パスのみを実行します。このようにして、巨大なモデルでさえネットワーク上に置くことができます(もう一度、 GPT- で175Bパラメータを使用)が、多くの作業が必要です。
2番目の例では、 @ Daniel は2つの可能性を提供しました。言及する価値のあるその他のもの(それらは多くの機能を持っているので、それぞれのドキュメントを読んでください):
PyTorchの場合、さらに読むことができます here 一方で、tensorflowには Tensorflow EXtended(TFX) を介して多くの機能が用意されています。
マシン内よりもマシン間で優れている並列処理の形式はありますか
デバイス間の転送を最小限に抑えるためには、並列処理の最善の方法はおそらく1台の巨大なコンピューター内にあるでしょう。
さらに、(少なくとも[PyTorch]で)さまざまなバックエンドがあり(mpi
、gloo
、nccl
)、すべてが直接送信、受信、削減をサポートしているわけではありませんデバイス間のデータ(CPUからCPUへのサポート、GPUからGPUへのサポートなど)。デバイス間に直接リンクがない場合は、それらを最初に別のデバイスにコピーし、ターゲットデバイスに再度コピーする必要があります(たとえば、他のマシンのGPU->ホストのCPU->ホストのGPU)。 pytorch info を参照してください。
データが多くなり、ネットワークが大きくなるほど、計算の並列化による収益性が高くなります。データセット全体を1つのデバイスに収めることができる場合は、並列化の必要はありません。さらに、インターネットの転送速度、ネットワークの信頼性などを考慮に入れる必要があります。これらのコストがメリットを上回る可能性があります。
一般に、大量のデータ(たとえば、ImageNetと1.000.000
画像)または大きなサンプル(たとえば、画像2000x2000
)がある場合は、データの並列化を行います。可能であれば、マシン間の転送を最小限に抑えるために、単一のマシン内で。回避策がない場合にのみモデルを配布します(例:GPUに適合しない)。それ以外は行わないでください(データセット全体がRAMに収まり、読み取りが最も高速になるため、MNISTをトレーニングするときに並列化するポイントはほとんどありません)。
tPUなどのカスタムML固有のハードウェアを構築する必要があるのはなぜですか?
CPUは、高度な並列計算(たとえば、行列の乗算)に最適ではありません+ CPUは、他の多くのタスク(データの読み込みなど)に占有される可能性があるため、GPUを使用することは理にかなっています。
GPUはグラフィックス(代数的変換)を念頭に置いて作成されたため、CPUの一部の負荷をかけて専門化することができます(CPUに比べて多くのコアがありますが、よりシンプルです。たとえば V1 を参照してください)。
現在、TPUはテンソル計算(主にディープラーニング)に特化して調整されており、GPUと比較した場合でもWIPであるGoogleで開発されました。これらは特定のタイプのモデル(主に畳み込みニューラルネットワーク)に適しており、この場合は高速化できます。さらに、このデバイスでは最大のバッチを使用する必要があります( ここ を参照)。128
で割り切れるのが最適です。これを、16
または8
(float16
精度とint8
でそれぞれ割り切れるバッチ(またはレイヤーサイズ)で問題がない場合、NVidiaのTensor Coreテクノロジー(GPU)と比較できます。 )使用率が高い場合(ただし、コア数、正確なグラフィックカード、およびその他の多くのものに依存しますが、より優れているため、いくつかのガイドラインを参照してください こちら )。
一方、2つの主要なフレームワークがTPUをサポートすることはまだ最善ではありません(tensorflow
が正式にサポートされていますが、PyTorchは torch_xla
パッケージを使用しています)。
一般的に、GPUは現時点でディープラーニングの優れたデフォルトの選択肢です。たたみ込みの重いアーキテクチャのTPUは、頭痛の種になるかもしれません。また、(もう一度@Danielに感謝します)、TPUはより電力効率が良いため、単一の浮動小数点演算コストを比較すると安価になります。