GPUを強化するためのトリックの中で最も完全なコレクションの歴史

序文

すでにtf.data +推定に精通している場合はまず、あなたは╮記事のxを取り出すことができる(¯▽¯「」)╭

しかし!(..)現在またはsession.run中であれば言葉!特に、GPUのメモリに悩まさ満たされているが、子供の靴の利用率を増加させない、この記事では、新しい世界ああ(∇)への扉を開いてあなたを与えることができるかもしれ

効率向上のシリーズが大幅にトレーニング後に改善された後、あなたがそれを見つけた場合、(∇)少し夜の封筒に戻ってくることを忘れないでください

しかし、これはCSDNスタイルの記事の最後に怒っペーストコードワード(c)のジェーン(はじめに)イタリア語(2)ガイ(言語)の束ではありません。だから、できるXアウト╮(¯▽¯「」)のパーティーに手を差し伸べる╭

起源

やがて夕方tensorflowとGPUの使用への新しい少し計算加速するとき、疑問がオーバー発生します。なぜ、GPUの使用率も低いので、表示されたグラフィックスメモリのほぼいっぱいですか?グッドそれを無駄にし、彼らは何もしません。GPUの利用率は、基本的な状況の100%が専用メモリのかなり小さなタスクジャム4,5に発見されたかかりませんでした。

より極端なケースでは、あってもGPUの利用率は次のように、10%以下に低減されます。

 

v2-09e10589505de7a161415b60e365e83c_b.jpg

そして、ほとんどの場合、コード列を書き出した後、それがこれです:

 

v2-77c8ae3aa2b468d2682c62a26f063c3c_b.jpg

グラフィックスメモリが充填されているが、それは、見ることができるが、グラフィックパワーはと利用(その右端の列、35%及び38%)(遠カラム、114W及び69Wの左側)遠くの限界からです。ほとんどの人はよくまあ、それは問題で、私は別れ魏[笑]実験行わないことを考えます

しかし!あなたは、大規模な実験を行っている場合は、それを実行するために数日を訓練?この詳細は、大幅にDDL到着する前に、実験の効率化と実験の数に影響を与えます!およそまったく同じモデルと設定を考えて、あなたのコードは、週を訓練する必要がありますが、隣の必要性はわずか訓練3日ファラオ╮(¯▽¯「」)╭

通行人:私は256枚のカードを持っている
小さな夜:さて、この記事のことができますXアウト

さて、私たちは、これが起こるされていない可能性があります。

 

V2-fada8f09717f3847f8eae736eb0258e1_b.jpg

それは信じられないほどのパワーと効率に見えるではありません!これはPS図である疑いはいけません!これは、ほんの少しの夜、毎日のショットです!GPU使用トリックの良い使用が99%下落した後、コードガチョウ愚か十分に記述しないで、あなたはまた、5%まで行くことができます!

質問があるので、その中に最終的な結果の違いは何ですか?

心配、我々は(それらのGPU拡大トレーニング中のGPU利用のいくつかのコードの変更の30%のみの利用を見てする必要はありません、それは少し長文ようです

        watch -n 0.1 nvidia-smi
      

 

v2-06ddcf4a0187d75ce5dffbbbac13f6d2_b.gif
PS :(フレームは(¯▽¯「」)╮あまりにも深刻探して支離滅裂に落ちること╭、)、自分のマシン上で試すことが推奨されるマルチ〜直感的になります

見て!あなたは突然私と一緒に間違って見つけるされていませんか?あなたはそれを見ることができ、実際には、GPU使用率が0に別の100バックで落とし、再び上昇し、その後、下落した後、比較的低いレベルであったが、0から100近くに非常に規則的な周期バラいるではありません。両方のオープンは、ログウィンドウを印刷する場合は、長く、このサイクルは、各トレーニングステップと全く一致していることがわかります!言い換えれば、各段階で、実際には、我々はいくつかの時間を持っているとGPUをかけていない、もちろん、それはCPUに費やされていることです。

それをやってのCPUの?もちろん、次のロードは費用のこのシリーズは、完全にCPUに依存する必要があり、GPU、後処理のログ結果を使い果たすバッチ、このバッチの前処理と後処理印刷、でもモデルの保存、書き込みの要約です。私たちは、多くの場合、コードを読み込んで見て:

        create_graph()
create_model_saver()
create_summary_writer()
create_session()
do_init()
for i in range(num_train_steps):
    load_batch(...)                # cpu
    preprocess(...)                # cpu
    feed_dict = {...}              # cpu
    fetch_list = [...]             # cpu
    buf = session.run(fetch_list, feed_dict)    # gpu
    postprocess(buf)               # cpu
    print(...)                     # cpu
    if i % x == 0:
        summary_writer.write(...)  # cpu
    if i % xx == 0:
        model_saver.save(...)      # cpu
      

ルック、特に前処理(...)タスクが重い、CPUのコードはまた、いくつかの時間のために実行された、GPU使用率が自然にそれを移動して、周期的に変化されますが発生するのは簡単です。

GPU時間を改善し、CPU時間を短縮する方法はありますか?

非常に自己(愚か)を(愚かな)考え方は、すべてのコード千万人の間tf APIを使用し、さらに最外層ではない書き換え訓練することですfor i in range(num_train_steps)実際にそれを書き換えるtf.while_loop使用することができます。ああ、私が試した、そしてので、本当に小さな夜が見つかりました。

 

V2-bde01235526089755e5a6895b1db83ec_b.jpg

TF APIは、この特別な鳴き声は何の幽霊です!同じ名前を持つ関数と行動の一貫性のないビルトインが、どのような地獄の様々なnumpyのパイソン!FML APIの少ない私が行うことができますどのようにこの引数?私はいくつかの行を書いた理由のpythonのコードの行は、物事を得ることができるようになりますか?

 

V2-b347580774f2421578d25b1429cacbd4_b.jpg

だから、関数型プログラミングに加えて、ダニエル、小さな夜は強く、同じ過ちを繰り返すことはお勧めしません!特に、私たちのものは90 Lispのクラッシュの妖精を見た後、コンパイルの叫びに遭遇します!

マップの計算に全列車のループを記述するための方法はありませんので、?

DOは、良いニュースが実際にtensorflowパッケージは、上側全体列車のループに(ピット)APIで特に優れた(およびそれ以上)を恐れていたことがないことを恐れてはいけません簡単に超高利用率とGPUを達成するために、図の計算中にカプセル化することができますトレーニング効率!

見積もり

なぜ、私たちはただ、基本はライン上で良いパッケージを与えやりたいことを知っておく必要があり、それは見積もりと呼ば無視しないでください。その古典の文言は、ちょうど上に移動します

        1. create_model()
2. create_model_saver()
3. create_summary_writer()
4. create_session()
5. do_init()
6. for i in range(num_train_steps):
7.      load_batch(...)                # cpu
8.      preprocess(...)                # cpu
9.      feed_dict = {...}              # cpu
10.     fetch_list = [...]             # cpu
11.     buf = session.run(fetch_list, feed_dict)    # gpu
12.     postprocess(buf)               # cpu
13.     print(...)                     # cpu
14.     if i % x == 0:
15.         summary_writer.write(...)  # cpu
16.     if i % xx == 0:
17.         model_saver.save(...)      # cpu
      

1-5は、パッケージライン推定器はまあ、あなただけ〜のrunConfig友達になれる推定器の形状に入れています

7-9パッケージラインもまあ、あなただけ〜スーパーインポーズinput_fn estimator.trainの前処理の関数としてコードとそれに関連するデータセットをロードする必要が

10行目は、また〜あなただけの、train_op投げEstimatorSpec推定損失をフェッチする必要がある、まあをカプセル化

11行目でもまあをカプセル化し、あなただけ〜図のmodel_fnの推定を重ねる機能モデル計算を記述する必要があります

12-13行は、詳細、global_stepと自動的損失、およびそれの残りの部分については心配しないでください - tf.PrintとLoggingTensorHook投げました

14-17あなたが行を書いていない、オートコンプリート

╮(╯▽╰)╭

そのような食事のトスの後、我々はそれが大幅にGPUの利用率を向上させることがわかった - 約80%、さらに90%に等しいです。だから、プレスそれの余地はありませんか?

注意深い分析は、コードの大部分がイトゥリを算出する推定器に書き込まれているがそれを見つけるだろうが、まだロードされ、実際にはCPUからのデータの事前処理場所シリアル行為うんが、128個のサンプルのようなバッチがあります、内部estimaorは、時間の各ステップを実行または処理ジョブの128個のシリアル試料を待ちます。これは明らかにそれが最後のボトルネックになっています!それを排除する方法はありませんか?・もちろん、それはあります

tf.data

しかし、TFデータセットのAPIが嫌いに愛する人の言うことができる、全体の予め計算されたチャートのパスを提供するように見えるん並列処理を移動しています!あなたが本当に完全tensorflow APIは、複雑な前処理を行うにした場合、本当にtf.dataとここに前の人怒っQAQそうを行います、小さな夜が強く、変換前にデータの最初のセットとして推奨します含む処理された外観、単語をやっては、カットオフ、及びそのword2idんが、パディングとinput_maskはないTFに滞在することができない、すべての後、一行のみを必要としています。

ことは、この後に、これはそれをより便利に、後続の読み取りとの契約になりますどのように前処理、データストレージに行われますか?これまでで最も推奨される方法が使用するtf.recordsストレージ、ディスク、メモリ、IOとストレージ効率は、従来の方法に比べて速く、Xとなり、yが分離しません。もちろん、この唯一の欠点は、(¯▽¯「」)╮データセットで直接開いて見ていない ╭ 結局、データセットは、バイナリファイルにしました。

本当に怠惰なtf.recordしたくない。しかし、その後、小さな夜は非常にxとyは別々に保存することが推奨され、そして使用に困難を避けるためにする場合、事前に読み出されたデータ上で必要なものtf.data仕上げを作ってみます文字列のAPIと、CPUとメモリのトレーニングを削減するために基礎となるオペレーティング・圧力。

tf.data我々はストリーミングデータを読み取るために非常に自然な方法で支援することができるという大きな利点がある(ディスカバリー負荷グラフィックの恥ずかしさを占領した後、このようなデータは╮大規模なデータセットの顔には発生しませんが¯▽¯ "")╭

あまりにも長い間話しているかのように、どのようにか、QAQを加速主題に来るtf.dataと言いませんでした。

カザフスタン、無用tf.dataを考え、私たちは、実際にはこのようなものですアップ実行コードを記述します。

 

v2-1cc7ed94295fe3bb8ef66fb01a95233d_b.jpg

また、これは重要な理由が上がると、定期的にGPUの使用率を変更することはできません理由を説明するために、物品の小さな夜の始まりです。私たちはアイドルを排除することはできませんので、このように並列のプロセスを準備し、それを訓練作りますか?

 

v2-989015918c2fa02d6d8e244fa81c6bf6_b.jpg

もちろんすることができます!即ち

プリフェッチ

これは、バッチをロードする次のステップをプリフェッチプリフェッチ手段から理解することができます。話している引数BUFFER_SIZE APIが追加は、このようなBUFFER_SIZE = 1として、フェッチどのように多くのですプリフェッチ魔法のAPIと呼ばれる使用tf.dataは簡単にそれを完了することができ、これは、その後、私たちはバッチをプリフェッチする必要があり、その後、すべてのモデル完了時間後にバッチを用意し、次の列車のステップは、この中に取り外すことができ、メモリから直接来るので、それが自動的に、追加のバッチを準備する良いバッチの友人を事前に準備します。(詳細は、後述)

待ちは、空想の言葉を描く、木材がある確かに両方の世界が、その後、特にプリフェッチいくつかのバッチに一度、あなたはかなりの時間がかかった場合は、一回以上で準備している場合であればバッチは非常に短い時間のかかる準備ということがありましたステップと列車は、列車の各ステップの性能、効率に制限されるときにそれを準備します。図に示すように、この質問が拡大された場合。

 

v2-807c180534fa39d9b4d8eccfc0aff9ab_b.jpg

電車につながる、それを使用するためのステップのGPUアイドルを完了したときに見て、あまりにも長い間の準備を(実際にはバッチ内の次のステップは、すでに十分に準備することができるが)

私たちは、ステージがそれを利用して位相を準備する際に以下の列車よりも確実にできないのですか?

パラレルマッピング

もちろん、非常にシンプルなアイデアは、友達を作ることです-サンプル並列処理バッチサイズは128、プリフェッチサイズ= 1であれば、その後にバッチを作成し、シリアル、我々は4つのスレッドを開いた場合、実行前処理128 * 2 = 256回、しかし、実行するには、それが簡単に見ははるかに魅力的ではありません。幸いなことに、私たちはマルチスレッド、あなた自身の手を爆破する必要はありません、tf.data.Datasetは、関数内のパラメータマップ(前処理)がありnum_parallel_calls、その解析このパラメータ平行に割り当てることができます。示されているように、

 

v2-2c2df2a40a1a57081d84314e1acc41f1_b.jpg

だから、限りBUFFER_SIZEとnum_parrellel_callsのプリフェッチをマッピングし、適切な取得、基本的に中断のない列車がGPUのほぼ100%の使用率である、それを達成することができます!

まあ、私は、コードを理解するために考え、それを理解することは容易です。未使用tf.record、前処理された典型的なプレーンテキストデータのロードデータセット手順から直接、次の

        def build_input(..):
    x = tf.data.XXDataset(..)
    x = x.map(..., num_parallel_calls=N)        # parellel

    y = tf.data.XXDataset(..)
    y = y.map(..., num_parallel_calls=N)

    dataset = tf.data.Dataset.zip((x, y))
    dataset = dataset.repeat(num_epochs)    
    if is_train:
        dataset = dataset.shuffle(..)
    dataset = dataset.batch(batch_size)
    dataset = dataset.prefetch(buffer_size=1)   # prefetch
    iterator = dataset.make_xx_iterator()
    return iterator.get_next()
      

もちろん、使用場合はtf.record、それぞれ、xとyの両方の友人にファイルからデータを読んでいないの後には、子供用の靴に興味を見つける行かなければならないことがあります。

補足メリット

もちろん、tf.data +推定するだけで、従来のコードの移行、それが直接session.run(debug_tensor)として、その後、どのように前にそれ好きではない、デバッグモードでは、最も重要なことに適応しない場合がありますか?

一般的な我々の印刷テンソルで2例があり、1は地図が間違っを計算する際に問題を特定するために、1つまたは複数回を印刷する必要があり、1等global_step、損失、のようなものですが、定期的チェックが必要です。どちらの場合も、習慣のsession.run前に、テンソルもなくなって、今この2つの場合が御馳走にそれを区別することができますを印刷したいとき。

まず、小さな夜のために最も効率的に感じるか、簡単に使用することに、直接接続tf.Print(..)、デバッグ機能は、イトゥリの計算では非常に強力です!あなたは世界のステップ、プラスそれを得るためにtf.condで印刷する必要がある場合。他のテンソルは、定期的な印刷が必要な場合には、第2の後には、実際には、世界的なステップは、デフォルト及び損失推定器が印刷されます、それから〜tf.train.LoggingTensorHookをパッケージ化し、それにestimator.train実際の習慣に投げ込ま使用しますまだ非常に便利なメートルを感じる(_ _)M

最後に、世界は自由なグラフィックスに喜んではありません

公開された33元の記事 ウォンの賞賛0 ビュー3284

おすすめ

転載: blog.csdn.net/xixiaoyaoww/article/details/104553499