【Need Help!】Keras(TensorFlowバックエンド)でのマルチコア・マルチプロセッサ並列化、GPU並列化はどんな実装になっているのだろう?

Keras(TensorFlowバックエンド)でのマルチコア・マルチプロセッサGPU(単体)での並列化によるアクセラレーションについてです。
 
モデルのサイズによっては効果が無い、どころか遅くなる場合もあるというのは経験がある(Google Corabolatoryにて)のですが、では、どのパラメータをどのように変えることで大体同じ結果を、より速く得る(= アクセラレーションの恩恵を受けられるモデルのサイズにしつつ、イテレーションは減らす)ことができるのか、を考えたいのですが、そのためには内部動作を知らないとどうにもならない、と考えています。

個人的には、以下のような実装になってるのではないか、と推測しているのですがどうなんでしょう?
(調べてはみたのですが、TF内の概念レベルのアーキテクチャなんかは公式にあったものの、具体的にどうやってるねんというのは見つけられず・・・。探し方が悪いのかもしれないですが・・・)
 
考えている範囲は、fit関数を呼び出して終わるまでの処理です。
基本的にはミニバッチの単位で並列処理しているのだと推測。
ただ、1ミニバッチずつ渡すのは効率が悪いので、ミニバッチ群のデータ自体は並列処理する主体にそれぞれ担当分を最初にどかっと渡しておくのではないかと。
 
■CPU内のコアもしくは、マルチプロセッサを活用するためのプロセス並列
マスタとワーカがいて、ワーカは担当するミニバッチの勾配の計算が終わったら、その勾配の情報をマスタに送って、マスタはNNの重みを更新して、更新したあとのNNの重みデータをワーカに送って、以降その繰り返し。
通信はプロセス間通信をしているのか、プロセス間で共有メモリを作ってよろしくやってたりするのか不明。
 
GPU 1枚を使った並列化
最初にCPU上のプロセスが、GPUメモリ上に重みデータを展開およびGPU上での実行プログラムを転送。
その後は、GPU上で各ワーカ的な何かが担当するミニバッチ群を処理していく。
1ミニバッチが終わったら、GPUメモリ上に置いてあるデータのロックをとって更新して、次のミニバッチの計算に進む。
一度必要なデータをGPUに転送したら、一回のfitを処理している最中はCPUとのやりとりは基本的に不要。
渡されたミニバッチ群を、指定されたepochだけ処理したら、GPU上のマスタプロセス的存在は、CPU上のプロセスに終了を通知し、CPU上のプロセスがGPU上のメモリを主記憶にコピー(CUDAの使い方の記憶は曖昧なので、最後に結果を得るあたりの記述は特に自信ありません)。
 
 
などと考えましたが、ナイーブな(深層学習の)並列化アルゴリズムを前提とすると、このような実装をした場合、どれかのワーカがNNの重みデータを更新した場合、古い重みデータを使って計算しているワーカの計算中の結果って破棄しないとダメ、つまりバッチ単位で並行に実行するって実装はNGなんですな。
 
ミニバッチの中のサンプル単位(単純には、ミニバッチに含まれるサンプルをワーカごとに均等に分けて割り振る)で並列化しないとダメ・・・?
 
もしくは↓のリンク先のように、並列化を想定したNNの重み更新アルゴリズムを用いるか。
 
togetter.com

 
しかし、それだと並列化することによって結果が変わっちゃったりするそうなんですよね。
普通にfit呼び出して、KerasだとGPUが載ってると自動的に使ってくれますが、それで、CPUだけで計算した場合と結果が変わってしまったら問題ですし、これはないですかね。
 
良い情報ソースをご存じの方がいれば教えていただければ幸いです ●刀乙
 
ちなみに、私が今いじっている以下のプログラムをfit_generatorを使って、マルチコア並列(8コア)させてみた時は、少し速くなったかな?程度でした。
ただ、ミニバッチのサイズが8(コア数に合わせたわけではなく元からこの値でした)と小さ過ぎたためで、ミニバッチのサイズをせめて64程度まで大きくすれば違ったのかも。
 
qiita.com