tensorflowがGPUメモリの全体を割り当てないようにするにはどうすればよいですか?


282

私は計算リソースが共有されている環境で働いています。つまり、それぞれにいくつかのNvidia Titan X GPUを搭載したサーバーマシンがいくつかあります。

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

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

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

回答:


292

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

# 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ごとに設定する方法はありません。


3
どうもありがとうございました。この情報は、現在のドキュメントにはかなり隠されています。私は自分でそれを見つけたことはなかったでしょう:-)答えられる場合は、2つの追加情報をお願いしたいと思います。(つまり、計算グラフで必要な場合でも、より多くのメモリを割り当てますか)2-これをGPUごとに設定する方法はありますか?
Fabien C.

15
関連メモ:TensorFlowを単一のGPUに制限するようにCUDA_VISIBLE_DEVICESを設定すると、うまくいきます。acceleware.com/blog/cudavisibledevices-masking-gpusを
rd11

2
メモリ割り当てが要求を少し超えているようです。たとえば、24443MiBのgpuでper_process_gpu_memory_fraction = 0.0909を要求し、2627MiBのプロセスを取得しました
jeremy_rutman

2
私はに仕事にこれを取得するように見えることはできませんMonitoredTrainingSession
Anjumサイード

2
@jeremy_rutmanこれはcudnnとcublasコンテキストの初期化が原因だと思います。ただし、これらのライブラリを使用するカーネルを実行している場合にのみ関係があります。
ダニエル

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

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


13
マルチユーザー環境では、コード自体で予約するGPUメモリの正確な量を指定するのは非常に不便なので、これはまさに私が欲しいものです。
xuancong84

4
また、あなたはTFのバックエンドとKerasを使用している場合、あなたはこれと実行を使用することができますfrom keras import backend as Kし、K.set_session(sess)回避メモリの制限
オリバー

50

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

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

1)成長を許可:(より柔軟)

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

2番目の方法はper_process_gpu_memory_fractionオプションです。これは、each可視GPUを割り当てる必要があるメモリ全体の量の割合を決定します。注:メモリの解放は必要ありません。完了すると、メモリの断片化がさらに悪化する可能性があります。

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

40%各GPUの合計メモリを割り当てるには:

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

注: これは、TensorFlowプロセスで利用可能なGPUメモリの量を本当にバインドしたい場合にのみ役立ちます。


質問に関しては、オプション2が役立つかもしれません。一般に、GPUおよび動的ネットワークで複数のアプリケーションを実行していない場合は、「成長を許可する」オプションを使用するのが理にかなっています。
aniket


19

上記のすべての回答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)

16

Tensorflowバージョン2.0および2.1の場合、次のスニペットを使用します

 import tensorflow as tf
 gpu_devices = tf.config.experimental.list_physical_devices('GPU')
 tf.config.experimental.set_memory_growth(gpu_devices[0], True)

以前のバージョンでは、次のスニペットが私のために機能していました:

import tensorflow as tf
tf_config=tf.ConfigProto()
tf_config.gpu_options.allow_growth=True
sess = tf.Session(config=tf_config)

10

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

参照:

参照: Tensorflow-GPUの使用https : //www.tensorflow.org/guide/gpu

Tensorflow 2.0 Alphaについては、 この回答を参照してください


8

使用できます

TF_FORCE_GPU_ALLOW_GROWTH=true

環境変数で。

tensorflowコード:

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();
}

5

恥知らずなプラグイン:GPU対応のTensorflowをインストールすると、CPUまたはGPUのみを使用するように設定しているかどうかにかかわらず、セッションは最初にすべてのGPUを割り当てます。グラフをCPUのみを使用するように設定したとしても、同じ構成を(上記で回答したように)設定して、不要なGPUの占有を防ぐ必要があるというヒントを追加します。

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


3

Tensorflow 2.0この本ソリューションは、私のために働きました。(TF-GPU 2.0、Windows 10、GeForce RTX 2070)

physical_devices = tf.config.experimental.list_physical_devices('GPU')
assert len(physical_devices) > 0, "Not enough GPU hardware devices available"
tf.config.experimental.set_memory_growth(physical_devices[0], True)

1
TF-GPU 2.0、Ubuntu 16.04.6、Tesla K80を使用しています。
アザー

@azar-共有してくれてありがとう。これは、UbuntuとWindowsの両方で同じ問題が興味深いです。どういうわけか、私はいつもハードウェアに近づくと問題が異なると思います。時間が経つにつれ、これは少なくなっているかもしれません-良いことかもしれません。
Sunsetquest

3

Tensorflow 2を使用している場合は、次のことを試してください。

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


1

unocをvocデータセットでトレーニングしようとしましたが、画像サイズが大きいため、メモリが終了します。上記のすべてのヒントを試しましたが、バッチサイズ== 1でも試しましたが、まだ改善されていません。TensorFlowバージョンがメモリの問題を引き起こすこともあります。使ってみてください

pipインストールtensorflow-gpu == 1.8.0


1

まあ、テンソルフローは初めてです。Geforce740mまたは2GB ramのGPUを使用しています。38700の画像と4300のテスト画像を含むトレーニングデータを使用して、母国語でmnist手書きの例を実行していて、精度、再現率を取得しようとしていました。 F1でsklearnとして次のコードを使用すると、正確な結果が得られませんでした。これを既存のコードに追加すると、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エポックを達成できました。これがお役に立てば幸いです。


私はTFのユーティリティだけでなく、メモリの使用にも驚いています。May TFの例で使用されているflowersデータセットのトレーニングジョブに30GB程度を割り当てるCPU python。めちゃくちゃ。
エリックM

1
# allocate 60% of GPU memory 
from keras.backend.tensorflow_backend import set_session
import tensorflow as tf 
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.6
set_session(tf.Session(config=config))

提供された回答は、低品質の投稿としてレビューのためにフラグが付けられました。ここではいくつかのためのガイドラインです、私は良い答えを書くにはどうすればよいですか?。この提供された答えは正しいかもしれませんが、説明から利益を得る可能性があります。コードのみの回答は「良い」回答とは見なされません。レビューから。
Trenton McKinney
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.