Distributed Tensorflow Doc を読みましたが、非同期トレーニングでは、
グラフの各レプリカには、調整なしで実行される独立したトレーニングループがあります。
私が理解していることから、データ並列性アーキテクチャでパラメータサーバーを使用する場合、各ワーカーは勾配を計算し、分散トレーニングニューラルネットワークの他のワーカーの更新を気にせずに独自の重みを更新することを意味します。すべての重みはパラメータサーバー(ps)で共有されるため、psは何らかの方法ですべてのワーカーからの重みの更新を調整(または集計)する必要があると思います。非同期トレーニングで集計はどのように機能するのでしょうか。または、より一般的な言葉で言えば、分散Tensorflowで非同期トレーニングはどのように機能しますか?
Distributed TensorFlowで非同期にトレーニングを行う場合、特定のワーカーは次のことを行います。
ワーカーはPSタスクからすべての共有モデルパラメーターを並行して読み取り、ワーカータスクにコピーします。これらの読み取りは同時書き込みと調整されず、ロックは取得されません。特に、ワーカーは1つ以上の他のワーカーからの部分的な更新を見ることができます(たとえば、別のワーカーからの更新のサブセット、または要素のサブセット変数内が更新された可能性があります)。
ワーカーは、入力データのバッチとステップ1で読み取ったパラメーター値に基づいて、ローカルで勾配を計算します。
ワーカーは、各変数の勾配を適切なPSタスクに送信し、applies最適化アルゴリズム(SGD、Momentumを使用したSGD、Adagrad、Adamなど)によって決定される更新ルールを使用して、それぞれの変数への勾配。更新ルールは通常(およそ)可換操作を使用するため、各ワーカーからの更新に個別に適用でき、各変数の状態はシーケンスの実行中の集約になります更新の受信。
非同期トレーニングでは、ワーカーからの各更新が同時に適用され、オプションのuse_locking=True
フラグは、それぞれのオプティマイザー(たとえば tf.train.GradientDescentOptimizer
)が初期化されました。ただし、ここでのロックは2つの同時更新の相互排他のみを提供し、(上記のように)読み取りはロックを取得しないことに注意してください。ロックは、更新のセット全体に原子性を提供しません。
(対照的に、同期トレーニングでは、tf.train.SyncReplicasOptimizer
は、すべてのワーカーが各モデルパラメーターに対して同じ最新の値を読み取るようにします。また、同期ステップの更新はすべて、基礎となる変数に適用される前に集約されます。これを行うために、ワーカーはバリアによって同期されます。バリアは、勾配更新を送信した後に入力され、集約された更新がすべての変数に適用された後に終了します。
非同期トレーニングでは、ワーカー間で重みの同期は行われません。重みはパラメータサーバーに保存されます。各ワーカーは、共有ウェイトを互いに独立してロードおよび変更します。このように、あるワーカーが他のワーカーよりも速く反復を完了した場合、待機せずに次の反復に進みます。ワーカーは共有パラメーターサーバーとのみ対話し、相互に対話しません。
全体的に(タスクに応じて)計算を大幅に高速化できます。ただし、同期更新が遅い場合に得られる結果よりも結果が悪い場合があります。
リンク先のドキュメントの例をご覧ください。
with tf.device("/job:ps/task:0"):
weights_1 = tf.Variable(...)
biases_1 = tf.Variable(...)
with tf.device("/job:ps/task:1"):
weights_2 = tf.Variable(...)
biases_2 = tf.Variable(...)
with tf.device("/job:worker/task:7"):
input, labels = ...
layer_1 = tf.nn.relu(tf.matmul(input, weights_1) + biases_1)
logits = tf.nn.relu(tf.matmul(layer_1, weights_2) + biases_2)
# ...
train_op = ...
with tf.Session("grpc://worker7.example.com:2222") as sess:
for _ in range(10000):
sess.run(train_op)
トレーニングは、同じ重みのコピーをすべて共有する3台のマシンに分散されていることがわかりますが、例のすぐ下で説明しています。
上記の例では、変数はpsジョブの2つのタスクで作成され、モデルの計算集約的な部分はワーカージョブで作成されます。 TensorFlowは、ジョブ間に適切なデータ転送を挿入します(フォワードパスの場合はpsからワーカーへ、グラデーションを適用する場合はワーカーからpsへ)。
つまり、1つのGPUを使用してフォワードパスを計算し、結果を他の2つのマシンに送信します。他のマシンはそれぞれ、重みの一部の逆伝播を計算し、結果を他のマシンに送信します。すべてのウェイトを適切に更新できます。
GPUは、行列の乗算と並列の数学演算を高速化するために使用され、フォワードパスとバックプロパゲーションの両方で非常に集中的です。したがって、分散トレーニングとは、単にこれらの操作を多くのGPUに分散することを意味し、モデルはマシン間で同期されますが、異なる重みの逆伝播を並行して計算でき、異なるミニバッチのフォワードパスを次のように計算できます前のミニバッチのbackpropと同じ時間がまだ計算されています。分散トレーニングは、各マシンに完全に独立したモデルとウェイトがあることを意味しません。