Multi GPU dalam keras

33

Bagaimana Anda bisa memprogram di perpustakaan keras (atau tensorflow) untuk mempartisi pelatihan pada beberapa GPU? Katakanlah Anda menggunakan instance Amazon ec2 yang memiliki 8 GPU dan Anda ingin menggunakan semuanya untuk berlatih lebih cepat, tetapi kode Anda hanya untuk satu CPU atau GPU.

Hector Blandin
sumber
3
Sudahkah Anda memeriksa dokumen tensorflow?
n1tk
@ sb0709: Saya mulai membaca pagi ini tetapi saya bertanya-tanya bagaimana melakukannya dengan keras
Hector Blandin
1
tidak tahu dengan keras tetapi untuk tensorflow: tf akan menggunakan GPU secara default untuk perhitungan bahkan jika untuk CPU (jika hadir didukung GPU). jadi kamu bisa melakukan a for loop: "for d in ['/ gpu: 1', '/ gpu: 2', '/ gpu: 3' ... '/ gpu: 8',]:" dan di "tf.device (d)" harus menyertakan semua sumber daya GPU instan Anda. Jadi tf.device () sebenarnya akan digunakan.
n1tk
Seperti ini ?? untuk d di ['/ gpu: 1', '/ gpu: 2', '/ gpu: 3' ... '/ gpu: 8',]: tf.device (d) dan apakah itu? Saya akan coba seperti itu :)
Hector Blandin
1
Sejauh yang saya tahu ya, Anda dapat melakukan tugas apa pun pada perangkat yang berbeda.
n1tk

Jawaban:

37

Dari FAQ Keras:

https://keras.io/getting-started/faq/#how-can-i-run-a-keras-model-on-multiple-gpus

Di bawah ini adalah kode yang disalin untuk memungkinkan 'paralelisme data'. Yaitu memiliki masing-masing GPU Anda memproses subset berbeda dari data Anda secara mandiri.

from keras.utils import multi_gpu_model

# Replicates `model` on 8 GPUs.
# This assumes that your machine has 8 available GPUs.
parallel_model = multi_gpu_model(model, gpus=8)
parallel_model.compile(loss='categorical_crossentropy',
                       optimizer='rmsprop')

# This `fit` call will be distributed on 8 GPUs.
# Since the batch size is 256, each GPU will process 32 samples.
parallel_model.fit(x, y, epochs=20, batch_size=256)

Perhatikan bahwa ini tampaknya hanya valid untuk backend Tensorflow pada saat penulisan.

Pembaruan (Feb 2018) :

Keras sekarang menerima pemilihan gpu otomatis menggunakan multi_gpu_model, sehingga Anda tidak perlu lagi melakukan hardcode jumlah GPU. Detail dalam Permintaan Tarik ini . Dengan kata lain, ini memungkinkan kode yang terlihat seperti ini:

try:
    model = multi_gpu_model(model)
except:
    pass

Tetapi untuk lebih eksplisit , Anda bisa tetap dengan sesuatu seperti:

parallel_model = multi_gpu_model(model, gpus=None)

Bonus :

Untuk memeriksa apakah Anda benar-benar menggunakan semua GPU Anda, khususnya yang NVIDIA, Anda dapat memantau penggunaan Anda di terminal menggunakan:

watch -n0.5 nvidia-smi

Referensi:

weiji14
sumber
Apakah multi_gpu_model(model, gpus=None)berfungsi dalam kasus di mana hanya ada 1 GPU? Akan keren jika secara otomatis disesuaikan dengan jumlah GPU yang tersedia.
CMCDragonkai
Ya saya pikir ini bekerja dengan 1 GPU, lihat github.com/keras-team/keras/pull/9226#issuecomment-361692460 , tetapi Anda mungkin perlu berhati-hati agar kode Anda diadaptasi untuk dijalankan pada multi_gpu_model alih-alih model yang sederhana . Untuk sebagian besar kasus, itu mungkin tidak masalah, tetapi jika Anda akan melakukan sesuatu seperti mengambil output dari beberapa lapisan perantara, maka Anda perlu kode sesuai.
weiji14
Apakah Anda punya referensi untuk perbedaan model multi gpu?
CMCDragonkai
Referensi itu luar biasa @ weiji14. Namun saya juga tertarik pada bagaimana ini bekerja untuk inferensi. Apakah keras entah bagaimana membagi batch sama atau putaran jadwal robin pada replika model yang tersedia?
CMCDragonkai
4
  1. Untuk TensorFlow:

TensorFlow Menggunakan GPU

Berikut adalah contoh kode tentang bagaimana digunakan, jadi untuk setiap tugas ditentukan daftar dengan perangkat / perangkat:

# Creates a graph.
c = []
for d in ['/gpu:2', '/gpu:3']:
  with tf.device(d):
    a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3])
    b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2])
    c.append(tf.matmul(a, b))
with tf.device('/cpu:0'):
  sum = tf.add_n(c)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print(sess.run(sum))

tf akan menggunakan GPU secara default untuk perhitungan bahkan jika untuk CPU (jika ada GPU yang didukung). jadi kamu bisa melakukan a for loop: "for d in ['/ gpu: 1', '/ gpu: 2', '/ gpu: 3' ... '/ gpu: 8',]:" dan di "tf.device (d)" harus menyertakan semua sumber daya GPU instan Anda. Jadi tf.device () sebenarnya akan digunakan.

Pelatihan Scaling Keras Model ke Beberapa GPU

  1. Keras

Untuk Keras dengan menggunakan Mxnet daripada args.num_gpus , di mana num_gpus adalah daftar GPU yang diperlukan Anda.

def backend_agnostic_compile(model, loss, optimizer, metrics, args):
  if keras.backend._backend == 'mxnet':
      gpu_list = ["gpu(%d)" % i for i in range(args.num_gpus)]
      model.compile(loss=loss,
          optimizer=optimizer,
          metrics=metrics, 
          context = gpu_list)
  else:
      if args.num_gpus > 1:
          print("Warning: num_gpus > 1 but not using MxNet backend")
      model.compile(loss=loss,
          optimizer=optimizer,
          metrics=metrics)
  1. horovod.tensorflow

Di atas semua itu, Horovod bersumber terbuka dari Uber baru-baru ini dan menurut saya hebat:

Horovod

import tensorflow as tf
import horovod.tensorflow as hvd

# Initialize Horovod
hvd.init()

# Pin GPU to be used to process local rank (one GPU per process)
config = tf.ConfigProto()
config.gpu_options.visible_device_list = str(hvd.local_rank())

# Build model…
loss = 
opt = tf.train.AdagradOptimizer(0.01)

# Add Horovod Distributed Optimizer
opt = hvd.DistributedOptimizer(opt)

# Add hook to broadcast variables from rank 0 to all other processes during
# initialization.
hooks = [hvd.BroadcastGlobalVariablesHook(0)]

# Make training operation
train_op = opt.minimize(loss)

# The MonitoredTrainingSession takes care of session initialization,
# restoring from a checkpoint, saving to a checkpoint, and closing when done
# or an error occurs.
with tf.train.MonitoredTrainingSession(checkpoint_dir=“/tmp/train_logs”,
                                      config=config,
                                      hooks=hooks) as mon_sess:
 while not mon_sess.should_stop():
   # Perform synchronous training.
   mon_sess.run(train_op)
n1tk
sumber
2

Pada dasarnya, Anda dapat mengambil contoh dari contoh berikut ini. Yang Anda butuhkan hanyalah menentukan nilai konsumsi cpu dan gpu setelah mengimpor dengan keras.

import keras

config = tf.ConfigProto( device_count = {'GPU': 1 , 'CPU': 56} )
sess = tf.Session(config=config) 
keras.backend.set_session(sess)

Setelah itu, Anda akan cocok dengan modelnya.

model.fit(x_train, y_train, epochs=epochs, validation_data=(x_test, y_test))

Akhirnya, Anda dapat mengurangi nilai konsumsi bukan pekerjaan pada batas atas.

johncasey
sumber