2017-04-06 2 views
2

저는 8 gpu에 대해 교육을받은 Keras 모델을 보유하고 있습니다. 즉, 모델에 with tf.device('gpu:0')과 같은 블록이 있음을 의미합니다. 이제 4GPus가있는 다른 PC로 전송 학습을 적용하고 싶습니다. 그러나이 모델은 더 많은 gpus (error: could not set cudnn tensor descriptor: CUDNN_STATUS_BAD_PARAM)에서 교육을 받았기 때문에 오류가 발생합니다. 오류 로그에서 tensorflow가 장치 GPU 0-7에서 그라디언트를 함께 배치하려고한다는 경고를 볼 수도 있습니다. Keras로 구성된 훈련 된 모델에서 장치를 적용하거나 지울 수있는 방법이 있습니까?훈련되고 다시로드 된 Keras 모델에서 장치 할당 변경

는 참고 : 모델이 또한 tensorflow 보호기 기능을 Keras로하지


현재 시도

내가 시도를 저장 한 때문에, 메타 그래프 파일이없는 레이어 속성을 변경하지만 작동하지는 못했습니다.

track = 0 
for i in range(len(model.layers)): 
    if model.layers[i].name[:6] == 'lambda': 
     model.layers[i].arguments['n_gpus'] = n_gpus 
     if model.layers[i].arguments['part'] > n_gpus-1: 
      model.layers[i].arguments['part'] = np.arange(n_gpus)[track] 
      track += 1 
      if track > n_gpus-1: 
       track = 0 
import os 
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1,2,3" 

스크립트가 8 개 GPU를

""" 
to_multi_gpu & slice_batch by: https://github.com/fchollet/keras/issues/2436 
baseline_model by: http://machinelearningmastery.com/ 
""" 
from keras import backend as K 
from keras.models import Sequential, Model 
from keras.layers import Dense, Input, Lambda, merge 
import tensorflow as tf 

def slice_batch(x, n_gpus, part): 
    """ 
    Divide the input batch into [n_gpus] slices, and obtain slice no. [part] 
    i.e. if len(x)=10, then slice_batch(x, 2, 1) will return x[5:]. 
    x: input batch (input shape of model) 
    n_gpus: number of gpus 
    part: id of current gpu 

    return: sliced model per gpu 
    """ 
    sh = K.shape(x) 
    L = sh[0] // n_gpus 
    if part == n_gpus - 1: 
     return x[part*L:] 
    return x[part*L:(part+1)*L] 

def to_multi_gpu(model, n_gpus): 
    """ 
    Given a keras [model], return an equivalent model which parallelizes 
    the computation over [n_gpus] GPUs. 
    Each GPU gets a slice of the input batch, applies the model on that slice 
    and later the outputs of the models are concatenated to a single 
    tensor, hence the user sees a model that behaves the same as the original. 

    model: sequential model created with the Keras library 
    n_gpus: number of gpus 

    return: model divided over n_gpus 
    """ 
    # Only divide model over multiple gpus if there is more than one 
    if n_gpus > 1: 
     with tf.device('/cpu:0'): 
      x = Input(model.input_shape[1:])#, name=model.input_names[0] 

     towers = [] 
     # Divide model over gpus 
     for g in range(n_gpus): 
      # Work on GPU number g. 
      with tf.device('/gpu:' + str(g)): 
       # Obtain the g-th slice of the batch. 
       slice_g = Lambda(slice_batch, lambda shape: shape, 
           arguments={'n_gpus':n_gpus, 'part':g})(x) 
       # Apply model on the batch slice. 
       towers.append(model(slice_g)) 
     # Merge multi-gpu outputs with cpu 
     with tf.device('/cpu:0'): 
      merged = merge(towers, mode='concat', concat_axis=0) 

     return Model(input=[x], output=merged) 
    else: 
     return model 

def baseline_model(num_pixels, num_classes, n_gpus): 
    # create model 
    model = Sequential() 
    model.add(Dense(num_pixels, input_dim=num_pixels, init='normal', activation='relu')) 
    model.add(Dense(num_classes, init='normal', activation='softmax')) 

    model = to_multi_gpu(model, n_gpus) 
    # Compile model 
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) 
    return model 

if __name__ == '__main__': 
    model = baseline_model(784, 9, 8) 

답변

0

사용을 통해 모델 분할을 만들 수 : 0 또한, 나는 또한 작동하지 않았다 볼 수 장치의 수를 설정하려고 아래 설정은 그것을 해결했습니다. 그러나 이제 모델은 GPU 대신 CPU에서 실행됩니다. 마지막 모델에서이 모델을 미세 조정할 때 큰 문제는 아닙니다. 그러나 전체 모델을 다시로드하고 교육하려는 경우이 대답은 만족스럽지 않을 수 있습니다.

중요 설정은 os.environ['CUDA_VISIBLE_DEVICES'] = ""allow_soft_placement=True입니다.

첫 번째는 모든 GPU를 마스크하고 두 번째는 Tensorflow가 사용 가능한 장치 (이 경우 CPU)에 자동으로 모델을 할당하게합니다.


샘플 코드

import os 
os.environ['CUDA_VISIBLE_DEVICES'] = "" 
import tensorflow as tf 
from keras.models import load_model 
from keras import backend as K 

if __name__ == '__main__': 
    model = load_model('baseline_model.h5') 
    init = tf.global_variables_initializer() 
    gpu_options = tf.GPUOptions(allow_growth=True) 
    # Add ops to save and restore all the variables. 
    with tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, allow_soft_placement=True,\ 
             log_device_placement=True)) as sess: 
     K.set_session(sess) 
     sess.run(init) 
     tf.train.start_queue_runners(sess=sess) 
     # Call model.fit here 
     sess.close() 
관련 문제