2016-03-16 12 views
10

4 GPU設定でテンソルフローからピーク性能を引き出す方法についてアドバイスをいただけるかどうか疑問に思っていました。テンソルフローを最大化するマルチGPUパフォーマンス

テストとして、私は、32x32入力で小さなフィルタバンク(16-128の範囲にある18のishレイヤ残留ネットワーク、バッチサイズ512、GPUあたり128)を作成しました。 1つはMXNetで、もう1つはthe inception exampleからモデル化しました。

私のMXNetネットワークでは、テンソルフローがダミーデータで4.2k、リアルデータで3.7しか使用できない約7kサンプルを1秒間にトレーニングできます。私は物事をスピードアップするために期待していくつかの質問を持って私の実験では

(1つのGPU上で実行しているときに数字が第二2.1K対1.2K例です)

  1. GPU使用率がかなり低いと思われます。テンソルフローのホワイトペーパーでは、同じGPU上で複数のストリームを実行することがサポートされています。これは一般公開で可能ですか?

  2. session.run()を1回実行して複数の列車操作を実行することはありますか?または、非同期実行がありますか?これにより、次のバッチが順方向に通過するのと同時に、重量の更新を行うことができます。私は2つのスレッド(両方のシステムとQueueRunnersの両方)を使用してみましたが、これは減速の原因となりました。 MXNetはCPU上でウェイト更新を実行することで速度を上げることができ、gpuを次のバッチに使用することができます。

  3. 1台のマシンで複数のワーカーを実行させることで、新しい分散実行時間はこれらの問題のいくつかを回避できますか?

  4. 他にも何かできますか?

は、私はここで、スタックオーバーフロー上の類似した質問の数がある知っているが、私の検索かかわらず、私はまだ試していないが、私の問題への解決策を見つけることができませんでした。

編集:

私は高価なカーネルが何であったかを見るために、プロファイリングCUDAの少しをしました。

void Eigen::internal::EigenMetaKernel_NonVectorizable<Eigen::TensorEvaluator 
<Eigen::TensorAssignOp<Eigen::TensorMap<Eigen::Tensor<float, int=4, int=1, long>, int=16>, 
Eigen::TensorPaddingOp<Eigen::array<std::pair<int, int>, 
unsigned long=4> const, Eigen::TensorMap<Eigen::Tensor<float const, 
int=4, int=1, long>, int=16> const > const > const, Eigen::GpuDevice>, long>(float, int=4) 

と時間の20.0%が、署名のオフ

void Eigen::internal::EigenMetaKernel_NonVectorizable<Eigen::TensorEvaluator 
<Eigen::TensorAssignOp<Eigen::TensorMap<Eigen::Tensor<float, int=4, int=1, long>, int=16>, 
Eigen::TensorBroadcastingOp<Eigen::array<int, unsigned long=4> 
const, Eigen::TensorMap<Eigen::Tensor<float const, int=4, int=1, long>, 
int=16> const > const > const, Eigen::GpuDevice>, long>(float, int=4) 

で過ごした私は、これらが何をしているか正確にわからない:内部の私の実行によると、時間の21.4%が費やされています。これらは理にかなっていますか?

さらに、この分析では、予想通りカーネルの並行性が0%と低いと報告されています。 と低計算の利用34.9パーセント(これは起動時間や鉄道ループ内のpythonの少しを含んで付与された。約32秒91のうち、合計これはtensorflow内部の約50%の利用率に出てくる。)

編集2:

私がダウンしてトリミングsource codeの写しを添付しています。一般的には、私は質問1-3についてより心配していますが、今までの体の時間をあまり過ごしたくありません。

加えて、私はから構築tensorflow上で実行しています:f07234db2f7b316b08f7df25417245274b63342a

編集3:

最新tensorflow(63409bd23facad471973b110df998782c0e19c06)同じコード、デフォルトのデータ・フォーマット(NHWC)に更新され、それはように見えましたこれを多くスピードアップする。 6.7k-6.8kの偽データ(熱依存性と思いますか?)の例では、2番目の4gpuです。 1gpu - 2.0k秒の例。 実際のデータパフォーマンスは、4gpuで約4.9k秒です。 1gpu - 1.7k秒の例。

編集4:

またIはBCHWにデータ形式を切り替えてみました。私はSoumith's benchmarksからモデル化された変換を行いました。畳み込み部分は本当に速かったですが、バッチノルムはすべてを乱しているようです。 naive implementation(固定軸と、[C、]の代わりに[1、C、1,1]を作る)私は4kpu(偽のデータ)で1.2kサンプルを1秒しか得ることができません。バッチノルムオペレーションの前と後の転置と同様に、私は6.2kサンプルを1秒(偽のデータ)得ることができます。 NHWCのdata_formatよりもまだ遅いです。

答えて

1

コードを見ずにプログラムのパフォーマンスの問題を診断するのは少し難しいです。何らかの形でテストコードを読むことは可能でしょうか?

上部に表示されているTensorPaddingは少し奇妙です。私はcudnnコールがプロファイルの最上部にあるはずだと思います。とにかく、私たちにテストコードを示すことは役に立ちます。

+0

ソースの要点を添付しました。お手伝いありがとう。 'TensorMap'の2番目のテンプレート引数がカーネルに適用されていると仮定するのは安全でしょうか?たとえば、それが「TensorPadding」であり、「TensorAssign」ではないことをどのように知っていますか? – luke

+1

いくつかの提案: 1)HEADからrecloningを試してください - スピードを助けるべき3月からEigenのいくつかの改良がありました。 2)CuDNNによる最適なレイアウトを使用すると、コンボリューションは現在より高速です。NCHWは現在、最良のテンソルレイアウトです。畳み込み、最大プールなどのデータフォーマットの順序を指定する方法の例については、https://github.com/soumith/convnet-benchmarks/blob/master/tensorflow/benchmark_alexnet.py#L18をご覧ください。 – vrv

+0

@vrv Recloning from HEADを使用すると、パフォーマンスが大幅に向上します。ありがとう! data_formatに関しては、私はオリジナルの投稿を更新しました。私は減速を見ている。 (かなり確かに異なる次元での削減。) – luke

関連する問題