Bagaimana mencegah tensorflow mengalokasikan totalitas memori GPU?

283

Saya bekerja di lingkungan di mana sumber daya komputasi dibagi, yaitu, kami memiliki beberapa mesin server yang masing-masing dilengkapi dengan beberapa GPU Nvidia Titan X.

Untuk model ukuran kecil hingga sedang, 12 GB Titan X biasanya cukup untuk 2-3 orang untuk menjalankan pelatihan secara bersamaan pada GPU yang sama. Jika model cukup kecil sehingga satu model tidak mengambil keuntungan penuh dari semua unit komputasi GPU, ini sebenarnya dapat menghasilkan percepatan dibandingkan dengan menjalankan satu proses pelatihan setelah yang lainnya. Bahkan dalam kasus-kasus di mana akses konkuren ke GPU memperlambat waktu pelatihan individu, tetap menyenangkan memiliki fleksibilitas memiliki banyak pengguna yang secara bersamaan berlatih menggunakan GPU.

Masalah dengan TensorFlow adalah bahwa, secara default, ini mengalokasikan jumlah penuh memori GPU yang tersedia saat diluncurkan. Bahkan untuk jaringan saraf dua lapis yang kecil, saya melihat bahwa semua 12 GB memori GPU habis.

Apakah ada cara untuk membuat TensorFlow hanya mengalokasikan, katakanlah, 4 GB memori GPU, jika ada yang tahu bahwa ini cukup untuk model yang diberikan?

Fabien C.
sumber

Jawaban:

292

Anda dapat mengatur fraksi memori GPU yang akan dialokasikan ketika Anda membangun a tf.Sessiondengan melewatkan tf.GPUOptionssebagai bagian dari configargumen opsional :

# 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))

The per_process_gpu_memory_fractionbertindak sebagai keras atas terikat pada jumlah memori GPU yang akan digunakan oleh proses pada setiap GPU pada mesin yang sama. Saat ini, fraksi ini diterapkan secara seragam untuk semua GPU pada mesin yang sama; tidak ada cara untuk mengatur ini berdasarkan per-GPU.

Pak
sumber
3
Terima kasih banyak. Info ini cukup tersembunyi di dokumen saat ini. Saya tidak akan pernah menemukannya sendiri :-) Jika Anda dapat menjawab, saya ingin meminta dua info tambahan: 1- Apakah ini membatasi jumlah memori yang pernah digunakan, atau hanya memori yang awalnya dialokasikan? (mis. apakah masih akan mengalokasikan lebih banyak memori jika diperlukan oleh grafik perhitungan) 2- Apakah ada cara untuk mengatur ini berdasarkan basis per-GPU?
Fabien C.
15
Catatan terkait: mengatur CUDA_VISIBLE_DEVICES untuk membatasi TensorFlow menjadi satu GPU berfungsi untuk saya. Lihat acceleware.com/blog/cudavisibledevices-masking-gpus
rd11
2
tampaknya alokasi memori sedikit melebihi permintaan, e..g saya meminta per_process_gpu_memory_fraction = 0,0909 pada gpu 24443MiB dan mendapat proses pengambilan 2627MiB
jeremy_rutman
2
Sepertinya saya tidak bisa membuatnya bekerja diMonitoredTrainingSession
Anjum Sayed
2
@ jeremy_rutman Saya percaya ini karena inisialisasi konteks cudnn dan cublas. Itu hanya relevan jika Anda menjalankan kernel yang menggunakan lib tersebut.
Daniel
187
config = tf.ConfigProto()
config.gpu_options.allow_growth=True
sess = tf.Session(config=config)

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

Sergey Demyanov
sumber
13
Yang ini persis seperti yang saya inginkan karena dalam lingkungan multi-pengguna, sangat merepotkan untuk menentukan jumlah persis memori GPU yang akan disimpan dalam kode itu sendiri.
xuancong84
4
Juga, jika Anda menggunakan Keras dengan backend TF, Anda dapat menggunakan ini dan menjalankan from keras import backend as Kdan K.set_session(sess)untuk menghindari keterbatasan memori
Oliver
50

Ini adalah kutipan dari Buku Deep Learning with TensorFlow

Dalam beberapa kasus, diinginkan agar proses hanya mengalokasikan sebagian dari memori yang tersedia, atau hanya menumbuhkan penggunaan memori sebagaimana diperlukan oleh proses. TensorFlow menyediakan dua opsi konfigurasi pada sesi untuk mengontrol ini. Yang pertama adalah allow_growthopsi, yang mencoba mengalokasikan hanya sebanyak memori GPU berdasarkan alokasi runtime, itu mulai mengalokasikan memori yang sangat sedikit, dan seiring sesi berjalan dan lebih banyak memori GPU diperlukan, kami memperluas wilayah memori GPU yang dibutuhkan oleh TensorFlow proses.

1) Biarkan pertumbuhan: (lebih fleksibel)

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

Metode kedua adalah per_process_gpu_memory_fractionopsi, yang menentukan sebagian kecil dari jumlah keseluruhan memori yang eachharus dialokasikan GPU yang terlihat. Catatan: Tidak diperlukan pelepasan memori, bahkan dapat memperburuk fragmentasi memori saat dilakukan.

2) Alokasikan memori tetap :

Untuk hanya mengalokasikan 40%total memori masing-masing GPU dengan:

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

Catatan: Itu hanya berguna jika Anda benar-benar ingin mengikat jumlah memori GPU yang tersedia pada proses TensorFlow.

pengguna1767754
sumber
Sejauh menyangkut pertanyaan Anda, opsi 2 mungkin bermanfaat bagi Anda. Secara umum jika Anda tidak memiliki banyak aplikasi yang berjalan pada GPU dan jaringan dinamis maka masuk akal untuk menggunakan opsi 'Izinkan pertumbuhan'.
aniket
19

Semua jawaban di atas menganggap eksekusi dengan sess.run()panggilan, yang menjadi pengecualian daripada aturan di versi terbaru dari TensorFlow.

Saat menggunakan tf.Estimatorframework (TensorFlow 1.4 dan di atas) cara untuk melewatkan pecahan bersama dengan yang dibuat secara implisit MonitoredTrainingSessionadalah,

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)

Demikian pula dalam mode Eager (TensorFlow 1.5 dan di atas),

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

Sunting: 11-04-2018 Sebagai contoh, jika Anda ingin menggunakan tf.contrib.gan.train, maka Anda dapat menggunakan sesuatu yang mirip dengan di bawah ini:

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

Untuk Tensorflow versi 2.0 dan 2.1 gunakan cuplikan berikut :

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

Untuk versi sebelumnya , cuplikan berikut digunakan untuk saya:

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

Tensorflow 2.0 Beta dan (mungkin) di luar

API berubah lagi. Sekarang dapat ditemukan di:

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

Alias:

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

Referensi:

Lihat juga: Tensorflow - Gunakan GPU : https://www.tensorflow.org/guide/gpu

untuk Tensorflow 2.0 Alpha lihat: jawaban ini

mx_muc
sumber
9

Kamu bisa memakai

TF_FORCE_GPU_ALLOW_GROWTH=true

dalam variabel lingkungan Anda.

Dalam kode 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();
}
Mey Khalili
sumber
5

Plug Shameless: Jika Anda menginstal Tensorflow yang didukung GPU, sesi pertama akan mengalokasikan semua GPU apakah Anda mengaturnya untuk hanya menggunakan CPU atau GPU. Saya dapat menambahkan tip saya bahwa bahkan Anda mengatur grafik untuk menggunakan CPU saja Anda harus mengatur konfigurasi yang sama (seperti yang dijawab di atas :)) untuk mencegah pendudukan GPU yang tidak diinginkan.

Dan dalam antarmuka interaktif seperti IPython Anda juga harus mengatur konfigurasi itu, jika tidak maka akan mengalokasikan semua memori dan hampir tidak meninggalkan yang lain. Ini terkadang sulit untuk diperhatikan.

Lerner Zhang
sumber
3

Untuk Tensorflow 2.0 ini solusi ini bekerja untuk saya. (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)
Sunsetquest
sumber
1
Saya menggunakan TF-GPU 2.0, Ubuntu 16.04.6, Tesla K80.
azar
@azar - Terima kasih telah berbagi. Itu menarik masalah yang sama di Ubuntu dan Windows. Entah bagaimana, saya selalu berpikir bahwa masalahnya berbeda ketika semakin dekat dengan perangkat keras. Mungkin ini menjadi kurang sehingga waktu berlalu - mungkin hal yang baik.
Sunsetquest
3

Jika Anda menggunakan Tensorflow 2 coba yang berikut ini:

config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.compat.v1.Session(config=config)
Moosefeather
sumber
bekerja untuk Tensorflow 2
mobin alhassan
1

Saya mencoba untuk melatih unet pada set data voc tetapi karena ukuran gambar yang besar, memori selesai. saya mencoba semua tips di atas, bahkan mencoba dengan ukuran batch == 1, namun tidak ada peningkatan. terkadang versi TensorFlow juga menyebabkan masalah memori. coba dengan menggunakan

pip install tensorflow-gpu == 1.8.0

Khan
sumber
1

Yah saya baru di tensorflow, saya punya Geforce 740m atau sesuatu GPU dengan ram 2GB, saya menjalankan jenis tulisan tangan mnist contoh untuk bahasa asli dengan data pelatihan yang berisi 38700 gambar dan 4300 gambar pengujian dan berusaha untuk mendapatkan presisi, ingat, F1 menggunakan kode berikut sebagai sklearn tidak memberi saya hasil yang tepat. setelah saya menambahkan ini ke kode saya yang ada saya mulai mendapatkan kesalahan 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)

ditambah model saya berat saya kira, saya mendapatkan kesalahan memori setelah 147, 148 zaman, dan kemudian saya pikir mengapa tidak membuat fungsi untuk tugas jadi saya tidak tahu apakah itu bekerja dengan cara ini di tensrorflow, tapi saya pikir jika variabel lokal adalah digunakan dan ketika di luar ruang lingkup mungkin melepaskan memori dan saya mendefinisikan elemen-elemen di atas untuk pelatihan dan pengujian dalam modul, saya dapat mencapai 10.000 zaman tanpa masalah, saya harap ini akan membantu ..

Imran Ud Din
sumber
Saya kagum pada utilitas TF tetapi juga dengan penggunaan memorinya. Pada python CPU mengalokasikan 30GB atau lebih untuk pekerjaan pelatihan pada dataset bunga yang digunakan dalam contoh TF Mei. Gila.
Eric 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))
DSBLR
sumber
Jawaban yang diberikan ditandai untuk ditinjau sebagai Pos Kualitas Rendah. Berikut adalah beberapa pedoman untuk Bagaimana cara saya menulis jawaban yang baik? . Jawaban yang diberikan ini mungkin benar, tetapi bisa mendapat manfaat dari penjelasan. Jawaban hanya kode tidak dianggap sebagai jawaban "baik". Dari ulasan .
Trenton McKinney