Pytorchに切り替える理由として多くのユーザーから引用されていますが、熱心な実行のために最も重要で実用的な品質、速度を犠牲にする正当性/説明をまだ見つけていません。
以下は、TF1対TF2のコードベンチマークパフォーマンスです。TF1は、47%から276%高速のいずれかで実行されます。
私の質問は:グラフまたはハードウェアレベルで、このような大幅な減速をもたらすのは何ですか?
詳細な答えを探しています-幅広い概念にすでに精通しています。 関連するGit
仕様:CUDA 10.0.130、cuDNN 7.4.2、Python 3.7.4、Windows 10、GTX 1070
ベンチマーク結果:
[〜#〜] update [〜#〜]:以下のコードごとにEager Executionを無効にすると、not助けて。ただし、動作は一貫性がありません。グラフモードで実行すると、Eagerに対してslowerを実行する場合にかなり役立つことがあります。
TF開発者はどこにも現れないので、私はこの問題を自分で調査します-リンクされたGithubの問題の進行状況を追跡できます。
UPDATE 2:説明に沿って、共有する多くの実験結果。今日行われるべきです。
ベンチマークコード:
# use tensorflow.keras... to benchmark tf.keras; used GPU for all above benchmarks
from keras.layers import Input, Dense, LSTM, Bidirectional, Conv1D
from keras.layers import Flatten, Dropout
from keras.models import Model
from keras.optimizers import Adam
import keras.backend as K
import numpy as np
from time import time
batch_shape = (32, 400, 16)
X, y = make_data(batch_shape)
model_small = make_small_model(batch_shape)
model_small.train_on_batch(X, y) # skip first iteration which builds graph
timeit(model_small.train_on_batch, 200, X, y)
K.clear_session() # in my testing, kernel was restarted instead
model_medium = make_medium_model(batch_shape)
model_medium.train_on_batch(X, y) # skip first iteration which builds graph
timeit(model_medium.train_on_batch, 10, X, y)
使用される関数:
def timeit(func, iterations, *args):
t0 = time()
for _ in range(iterations):
func(*args)
print("Time/iter: %.4f sec" % ((time() - t0) / iterations))
def make_small_model(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = Conv1D(128, 400, strides=4, padding='same')(ipt)
x = Flatten()(x)
x = Dropout(0.5)(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_medium_model(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = Bidirectional(LSTM(512, activation='relu', return_sequences=True))(ipt)
x = LSTM(512, activation='relu', return_sequences=True)(x)
x = Conv1D(128, 400, strides=4, padding='same')(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(128, activation='relu')(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_data(batch_shape):
return np.random.randn(*batch_shape), np.random.randint(0, 2, (batch_shape[0], 1))
UPDATE 2/18/2020:私は2.1と2.1を毎晩ベンチに入れました;結果はまちまちです。 1つを除くすべての設定(モデルとデータサイズ)は、TF2とTF1の最高の設定と同じかそれよりはるかに高速です。より遅く、劇的に遅くなるのは、大-大-特にです。グラフの実行(1.6xから2.5x低速).
さらに、私がテストした大規模なモデルでは、グラフとEagerの間にextreme再現性の違いがあります-ランダム性/計算並列性では説明できません。現在、これらのクレームごとの時間制限に関する再現可能なコードを提示することはできません。そのため、独自のモデルでこれをテストすることを強くお勧めします。
これらについてはまだGitの問題を公開していませんが、 original -まだ応答していません。進捗が確認されたら、回答を更新します。
[〜#〜] verdict [〜#〜]:it is n't、あなたが何をしているのか知っているなら。しかし、do n'tの場合、平均していくつかのGPUのアップグレードによって、最悪の場合は複数のGPUによって、多くのコストがかかる可能性があります。
この回答:問題の高レベルの説明と、ニーズに固有のトレーニング構成を決定する方法のガイドラインを提供することを目的としています。すべてのベンチマーク結果と使用コードを含む詳細な低レベルの説明については、他の回答を参照してください。
答えを更新します。何か情報があれば追加情報を追加します。この質問を参照用にブックマーク/「スター」することができます。
問題の概要:as 確認済み TensorFlow開発者、Q。Scott Zhu、TF2はEager Executionと緊密な統合に重点を置いた開発w /グラフレベルを含む、TFソースの抜本的な変更を伴うKeras。利点:処理、配布、デバッグ、および展開の機能が大幅に拡張されました。ただし、これらの一部のコストは速度です。
ただし、問題はかなり複雑です。 TF1とTF2だけではありません。列車の速度に大きな違いをもたらす要因には次のものがあります。
keras
vs. _tf.keras
_numpy
vs. _tf.data.Dataset
_ vs. ...train_on_batch()
vs. fit()
model(x)
vs. model.predict(x)
vs. ...残念ながら、上記のほとんどは互いに独立しておらず、それぞれが少なくとも別の実行時間に比べて実行時間を2倍にすることができます。幸いなことに、ここで示すように、いくつかのショートカットを使用して、何が体系的に最適に機能するかを決定できます。
何をすべきか?現在、唯一の方法は-特定のモデル、データ、ハードウェアを試すことです。常に最適な単一の構成はありませんが、検索を簡素化するためにareすることとしないことはあります。
>> DO:
train_on_batch()
+ numpy
+ _tf.keras
_ + TF1 + Eager/Graphtrain_on_batch()
+ numpy
+ _tf.keras
_ + TF2 +グラフfit()
+ numpy
+ _tf.keras
_ + TF1/TF2 +グラフ+ラージモデルとデータ>>しない:
fit()
+ numpy
+ keras
小規模および中規模モデルとデータ用fit()
+ numpy
+ _tf.keras
_ + TF1/TF2 + Eagertrain_on_batch()
+ numpy
+ keras
+ TF1 + Eager
[メジャー]_tf.python.keras
_;実行速度は10〜100倍遅く、多くのバグがあります。 詳細
layers
、models
、optimizers
、および関連する「すぐに使用できる」使用状況インポートが含まれます。 ops、utils、および関連する「プライベート」インポートは問題ありません-しかし、確実に、altをチェックし、_tf.keras
_で使用されているかどうかを確認してくださいベンチマークのセットアップ例については、他の回答の最後にあるコードを参照してください。上記のリストは、主に他の回答の「ベンチマーク」テーブルに基づいています。
[〜#〜] limitations [〜#〜]上記のDOおよび禁止事項:
Conv1D
_およびDense
-RNNなし、スパースデータ/ターゲット、4/5D入力、およびその他の構成numpy
および_tf.data.Dataset
_に制限されていますが、他の多くの形式が存在します。他の答えを見るTF2が熱心な実行のために最も実用的な品質、速度を犠牲にしたのはなぜですか?明確ではありません-グラフはまだ利用可能です。しかし、質問が「なぜ熱心なのか」の場合:
.__dict__
_と同じくらい簡単です。対照的に、グラフは特別なバックエンド機能に精通している必要があり、デバッグとイントロスペクションのプロセス全体を非常に複雑にします。Egerを有効/無効にする方法は?
_tf.enable_eager_execution() # TF1; must be done before any model/tensor creation
tf.compat.v1.disable_eager_execution() # TF2; above holds
_
追加情報:
_on_batch()
メソッドに注意してください。 TF devによると、彼らはまだ遅い実装を使用していますが、意図的ではない-つまり修正する必要があります。詳細については、他の回答をご覧ください。テンソルフローの開発の要求:
train_on_batch()
と、fit()
を繰り返し呼び出したときのパフォーマンスの側面を修正してください。カスタムトレインループは多くの人にとって、特に私にとって重要です。[〜#〜]謝辞[〜#〜]:ありがとう
[〜#〜] updates [〜#〜]:
11/14/19-TF2で実行速度が遅いモデル(私の実際のアプリケーション)が見つかりましたすべての構成の場合 wumpy入力データ付き。差は13〜19%で、平均17%です。ただし、keras
と_tf.keras
_の違いはより劇的でした:18-40%、平均32%(TF1と2の両方)。 (*-TF2がOOMしたEagerを除く)
11/17/19-開発者はon_batch()
メソッドを 最近のコミット で更新し、速度が向上したことを示している-TF 2.1でリリース、または利用可能現在は_tf-nightly
_として。私は後者を実行することができないので、2.1までベンチ処理を遅らせます。