Скажем, у меня есть доступ к ряду графических процессоров на одной машине (ради аргумента предполагают 8GPU с максимальной памятью 8 ГБ каждый на одной машине с некоторым объемом ОЗУ и диска). Я хотел запустить один сингл script, а на одной машине - программу, которая оценивает несколько моделей (скажем, 50 или 200) в TensorFlow, каждый из которых имеет другую настройку гиперпараметра (скажем, пошаговый, скорость распада, размер партии, эпохи/итерации и т.д.). По окончанию обучения предположим, что мы просто записываем его точность и избавляемся от модели (если вы хотите, чтобы модель проверялась каждый раз так часто, поэтому ее штраф, чтобы просто выбросить модель и начать обучение с нуля. предположим, что некоторые другие данные могут быть записаны как специальные гиперпараметры, поезд, валидация, ошибки поезда регистрируются по мере обучения и т.д.).
В настоящее время у меня есть (псевдо -) script, который выглядит следующим образом:
def train_multiple_modles_in_one_script_with_gpu(arg):
'''
trains multiple NN models in one session using GPUs correctly.
arg = some obj/struct with the params for trianing each of the models.
'''
#### try mutliple models
for mdl_id in range(100):
#### define/create graph
graph = tf.Graph()
with graph.as_default():
### get mdl
x = tf.placeholder(float_type, get_x_shape(arg), name='x-input')
y_ = tf.placeholder(float_type, get_y_shape(arg))
y = get_mdl(arg,x)
### get loss and accuracy
loss, accuracy = get_accuracy_loss(arg,x,y,y_)
### get optimizer variables
opt = get_optimizer(arg)
train_step = opt.minimize(loss, global_step=global_step)
#### run session
with tf.Session(graph=graph) as sess:
# train
for i in range(nb_iterations):
batch_xs, batch_ys = get_batch_feed(X_train, Y_train, batch_size)
sess.run(fetches=train_step, feed_dict={x: batch_xs, y_: batch_ys})
# check_point mdl
if i % report_error_freq == 0:
sess.run(step.assign(i))
#
train_error = sess.run(fetches=loss, feed_dict={x: X_train, y_: Y_train})
test_error = sess.run(fetches=loss, feed_dict={x: X_test, y_: Y_test})
print( 'step %d, train error: %s test_error %s'%(i,train_error,test_error) )
по существу он пробует много моделей за один прогон, но он строит каждую модель в отдельном графе и запускает каждый в отдельном сеансе.
Я думаю, что мое основное беспокойство заключается в том, что его неясно, как тензорный поток под капотом выделяет ресурсы для используемых графических процессоров. Например, загружает ли (часть) набор данных только при запуске сеанса? Когда я создаю график и модель, он сразу же появляется в графическом процессоре или когда он вставлен в графический процессор? Нужно ли мне очищать/освобождать GPU каждый раз, когда он пробует новую модель? Мне на самом деле не очень-то интересно, если модели работают параллельно в нескольких графических процессорах (что может быть приятным дополнением), но я хочу, чтобы он сначала запускал все последовательно без сбоев. Есть ли что-то особенное, что мне нужно сделать для этого?
В настоящее время я получаю сообщение об ошибке, которое начинается следующим образом:
I tensorflow/core/common_runtime/bfc_allocator.cc:702] Stats:
Limit: 340000768
InUse: 336114944
MaxInUse: 339954944
NumAllocs: 78
MaxAllocSize: 335665152
W tensorflow/core/common_runtime/bfc_allocator.cc:274] ***************************************************xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
W tensorflow/core/common_runtime/bfc_allocator.cc:275] Ran out of memory trying to allocate 160.22MiB. See logs for memory state.
W tensorflow/core/framework/op_kernel.cc:975] Resource exhausted: OOM when allocating tensor with shape[60000,700]
и далее вниз по строке:
ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[60000,700]
[[Node: standardNN/NNLayer1/Z1/add = Add[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/gpu:0"](standardNN/NNLayer1/Z1/MatMul, b1/read)]]
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla P100-SXM2-16GB, pci bus id: 0000:06:00.0)
однако дальше по выходному файлу (там, где он печатается), кажется, печатаются мелкие ошибки/сообщения, которые должны отображаться по мере продолжения обучения. Означает ли это, что у него не осталось ресурсов? Или действительно ли он мог использовать GPU? Если бы он смог использовать CPU вместо CPU, то почему это ошибка происходит только при использовании графического процессора?
Странно то, что набор данных на самом деле не такой большой (все 60K точек 24.5M), и когда я запускаю одну модель локально на своем собственном компьютере, кажется, что процесс использует менее 5 ГБ. Графические процессоры имеют не менее 8 ГБ, а компьютер с ними имеет большое количество оперативной памяти и диска (не менее 16 ГБ). Таким образом, ошибки, которые тензорный поток бросает на меня, довольно озадачивают. Что он пытается делать и почему они происходят? Любые идеи?
После прочтения ответа, предлагающего использовать библиотеку многопроцессорности, я пришел к следующему script:
def train_mdl(args):
train(mdl,args)
if __name__ == '__main__':
for mdl_id in range(100):
# train one model with some specific hyperparms (assume they are chosen randomly inside the funciton bellow or read from a config file or they could just be passed or something)
p = Process(target=train_mdl, args=(args,))
p.start()
p.join()
print('Done training all models!')
Честно говоря, я не уверен, почему его ответ предлагает использовать пул, или почему есть странные скобки, но это то, что имеет смысл для меня. Будут ли ресурсы для тензорного потока перераспределяться каждый раз, когда новый процесс создается в вышеуказанном цикле?