web-dev-qa-db-ja.com

テンソルフローがGPUメモリ全体を割り当てないようにする方法

私は計算資源が共有される環境で働いています、すなわち、我々はそれぞれ少数のNvidia Titan X GPUを備えた少数のサーバマシンを持っています。

小型から中型のモデルでは、Titan Xの12GBは通常同じGPUで2〜3人が同時にトレーニングを実行するのに十分です。 1つのモデルでTitan Xのすべての計算単位を十分に活用できないほどモデルが十分に小さい場合、これは実際に次々にトレーニングプロセスを実行するのと比較してスピードアップをもたらします。 GPUへの同時アクセスによって個々のトレーニング時間が遅くなった場合でも、複数のユーザーが一度にGPU上で物事を実行できるという柔軟性があります。

TensorFlowの問題点は、デフォルトでは起動時にGPU上の使用可能なメモリの全容量を割り当てることです。小さな2層ニューラルネットワークでも、12 GBのTitan Xが使い果たされているのがわかります。

その量が特定のモデルに十分であることがわかっている場合、TensorFlowに4GBのGPUメモリのみを割り当てる方法はありますか?

215
Fabien C.

オプションのconfig引数の一部として tf.Session を渡すことで、 tf.GPUOptions を作成するときに割り当てるGPUメモリの割合を設定できます。

# Assume that you have 12GB of GPU memory and want to allocate ~4GB:
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)

sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))

per_process_gpu_memory_fractionは、同じマシン上の各GPU上のプロセスによって使用されるGPUメモリの量のハード上限として機能します。現在、この割合は同じマシン上のすべてのGPUに一律に適用されています。これをGPUごとに設定する方法はありません。

241
mrry
config = tf.ConfigProto()
config.gpu_options.allow_growth=True
sess = tf.Session(config=config)

https://github.com/tensorflow/tensorflow/issues/1578

152
Sergey Demyanov

これはBook Deep Learning with TensorFlowからの抜粋です。

場合によっては、プロセスが使用可能なメモリのサブセットのみを割り当てるか、またはプロセスで必要とされるときにのみメモリ使用量を増やすことが望ましいことがあります。 TensorFlowはこれを制御するために 2つの設定 セッション上のオプションを提供します。 1つ目はallow_growthオプションで、ランタイム割り当てに基づいてGPUメモリをできるだけ多く割り当てようとします。セッションの実行と必要なGPUメモリが増えるにつれて、必要なGPUメモリ領域が拡張されます。 TensorFlowプロセス.

1)成長を可能にする:(より柔軟な)

config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config, ...)

2番目の方法はper_process_gpu_memory_fractionオプションで、これはeach visible GPUを割り当てるべきメモリの総量のうちの何分の1かを決定します。 注: メモリの解放は不要です。完了すると、メモリの断片化がさらに悪化する可能性があります。

2)固定メモリを割り当てます

各GPUの合計メモリの40%を割り当てるには、次の手順に従います。

config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
session = tf.Session(config=config, ...)

注: / TensorFlowプロセスで使用可能なGPUメモリの量を本当に制限したい場合に限ります。

33
user1767754

上記のすべての答えは、sess.run()呼び出しでの実行を想定しています。これは、最近のバージョンのTensorFlowの規則ではなく例外になりつつあります。

tf.Estimatorフレームワーク(TensorFlow 1.4以降)を使用する場合、暗黙的に作成されたMonitoredTrainingSessionに小数を渡す方法は、

opts = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
conf = tf.ConfigProto(gpu_options=opts)
trainingConfig = tf.estimator.RunConfig(session_config=conf, ...)
tf.estimator.Estimator(model_fn=..., 
                       config=trainingConfig)

Eagerモード(TensorFlow 1.5以上)でも同様です。

opts = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
conf = tf.ConfigProto(gpu_options=opts)
tfe.enable_eager_execution(config=conf)

編集:11-04-2018 例として、あなたがtf.contrib.gan.trainを使用するのであれば、あなたは以下のような何かを使用することができます:

tf.contrib.gan.gan_train(........, config=conf)
13
Urs

TensorFlow 2.0 Alpha以降用に更新されました。

2.0 Alphaのドキュメントから、TensorFlowで何かをする前に、答えはたった1行になりました。

import tensorflow as tf
tf.config.gpu.set_per_process_memory_growth(True)
7
Theo

恥知らずなプラグイン:あなたがGPUをサポートするTensorflowをインストールするならば、あなたはそれがあなたがそれがCPUだけまたはGPUだけを使うように設定するかどうかにかかわらずすべてのGPUを割り当てます。私は、あなたがグラフをCPUだけを使うように設定したとしても、不要なGPUの占有を防ぐために同じ設定(上記のように:)を設定すべきだという私のヒントを追加するかもしれません。

そしてIPythonのようなインタラクティブなインターフェースでは、configureも設定する必要があります。そうしないとすべてのメモリが割り当てられ、他の人にはほとんど残されません。これは気付きにくいことがあります。

3
Lerner Zhang

Tensorflow 2.0 Betaおよび(おそらく)それ以上

APIが再び変更されました。現在、次の場所にあります。

tf.config.experimental.set_memory_growth(
    device,
    enable
)

エイリアス:

  • tf.compat.v1.config.experimental.set_memory_growth
  • tf.compat.v2.config.experimental.set_memory_growth
  • tf.config.experimental.set_memory_growth

https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/config/experimental/set_memory_growthhttps://www.tensorflow.org/beta/ guide/using_gpu#limited_gpu_memory_growth

1
mx_muc

使用できます

TF_FORCE_GPU_ALLOW_GROWTH=true

環境変数で。

tensorflow code:

bool GPUBFCAllocator::GetAllowGrowthValue(const GPUOptions& gpu_options) {
  const char* force_allow_growth_string =
      std::getenv("TF_FORCE_GPU_ALLOW_GROWTH");
  if (force_allow_growth_string == nullptr) {
    return gpu_options.allow_growth();
}
1
Mey Khalili

私はテンソルフローに不慣れです、私はGeforce 740mか2GB RAMのGPUを持っています。私は38700の画像と4300のテスト画像を含む訓練データで手書きの手書きの例を母国語で実行していました。 Sklearnとして以下のコードを使用しているF1は私に正確な結果を与えていませんでした。私がこれを私の既存のコードに追加したら、私はGPUエラーを受け始めました。

TP = tf.count_nonzero(predicted * actual)
TN = tf.count_nonzero((predicted - 1) * (actual - 1))
FP = tf.count_nonzero(predicted * (actual - 1))
FN = tf.count_nonzero((predicted - 1) * actual)

prec = TP / (TP + FP)
recall = TP / (TP + FN)
f1 = 2 * prec * recall / (prec + recall)

それに私のモデルは重いと思い、147、148エポックの後にメモリエラーが発生していました。それからタスク用の関数を作成しないのではないかと思いました。使用され、範囲外になってメモリを解放する可能性があり、モジュールのトレーニングとテストのために上記の要素を定義した場合、問題なく10000エポックを達成することができました。

1
Imran Ud Din

私はvocデータセットでunetを訓練しようとしましたが、巨大な画像サイズのために、メモリは終わります。上記のすべてのヒントを試してみましたが、バッチサイズ== 1でも試しましたが、まだ改善は見られません。時々TensorFlowバージョンもメモリの問題を引き起こします。使ってみてください

pip install tensorflow-gpu == 1.8.0

0
Khan