2017-02-23 4 views
10

테스크 플로우가있는 Keras를 백엔드로 사용하고 있습니다. 하나의 컴파일 된/훈련 된 모델이 있습니다.Keras + Tensorflow : 여러 gpus에 대한 예측

예측 루프가 느려서 predict_proba 호출을 병렬 처리하여 속도를 높이는 방법을 찾고 싶습니다. (데이터 중) 일괄 처리 목록을 가져 와서 사용할 수있는 GPU 당, 해당 일괄 처리의 하위 집합에 model.predict_proba()을 실행하고 싶습니다. 기본적으로
는 :

data = [ batch_0, batch_1, ... , batch_N ] 
on gpu_0 => return predict_proba(batch_0) 
on gpu_1 => return predict_proba(batch_1) 
... 
on gpu_N => return predict_proba(batch_N) 

나는 주어진 GPU (https://www.tensorflow.org/tutorials/using_gpu)에 작전을 할당하는 순수 Tensorflow의 가능성이 있음을 알고있다. 그러나 Keras의 API를 사용하여 내 모델을 작성/컴파일/교육 한 이래로 이것이 내 상황으로 어떻게 변환되는지 모르겠습니다.

저는 파이썬의 멀티 프로세싱 모듈을 사용하고 predict_proba(batch_n)을 실행할 수있는 gpu 당 프로세스를 시작해야한다고 생각했습니다. 나는 이것이 이론적으로 가능하다는 것을 알고있다. Keras + Tensorflow and Multiprocessing in Python. 그러나 이것은 여전히 ​​프로세스를 운영하기 위해 실제로 GPP를 "선택"하는 방법을 알지 못하는 딜레마에 빠져 있습니다.

내 질문은 다음과 같습니다. Tensorflow를 Keras 백엔드로 사용할 때 여러 gpus에서 Keras의 한 모델에 대한 예측을 병렬화하는 방법은 무엇입니까?

또한 하나의 GPU만으로도 예측을위한 비슷한 병렬화가 가능한지 궁금합니다.

높은 수준의 설명 또는 코드 예제를 크게 높이세요!

감사합니다.

답변

4

여러 GPRS에서 케라 모델을 실행하는 방법을 보여주는 간단한 예제를 만들었습니다. 기본적으로 여러 프로세스가 생성되며 각 프로세스는 GPP를 소유합니다. 프로세스에서 gpu id를 지정하려면 env 변수 CUDA_VISIBLE_DEVICES를 설정하는 것이 매우 간단합니다 (os.environ [ "CUDA_VISIBLE_DEVICES"]). 희망이 git repo 당신을 도울 수 있습니다.

https://github.com/yuanyuanli85/Keras-Multiple-Process-Prediction

0

당신은 Keras 모델에게 (kuza55 학점)을 병렬화이 기능을 사용할 수 있습니다.
https://github.com/kuza55/keras-extras/blob/master/utils/multi_gpu.py
.

from keras.layers import merge 
from keras.layers.core import Lambda 
from keras.models import Model 

import tensorflow as tf 

def make_parallel(model, gpu_count): 
    def get_slice(data, idx, parts): 
     shape = tf.shape(data) 
     size = tf.concat([ shape[:1] // parts, shape[1:] ],axis=0) 
     stride = tf.concat([ shape[:1] // parts, shape[1:]*0 ],axis=0) 
     start = stride * idx 
     return tf.slice(data, start, size) 

    outputs_all = [] 
    for i in range(len(model.outputs)): 
     outputs_all.append([]) 

    #Place a copy of the model on each GPU, each getting a slice of the batch 
    for i in range(gpu_count): 
     with tf.device('/gpu:%d' % i): 
      with tf.name_scope('tower_%d' % i) as scope: 

       inputs = [] 
       #Slice each input into a piece for processing on this GPU 
       for x in model.inputs: 
        input_shape = tuple(x.get_shape().as_list())[1:] 
        slice_n = Lambda(get_slice, output_shape=input_shape, arguments={'idx':i,'parts':gpu_count})(x) 
        inputs.append(slice_n)     

       outputs = model(inputs) 

       if not isinstance(outputs, list): 
        outputs = [outputs] 

       #Save all the outputs for merging back together later 
       for l in range(len(outputs)): 
        outputs_all[l].append(outputs[l]) 

    # merge outputs on CPU 
    with tf.device('/cpu:0'): 
     merged = [] 
     for outputs in outputs_all: 
      merged.append(merge(outputs, mode='concat', concat_axis=0)) 

     return Model(input=model.inputs, output=merged) 
훈련 후
+0

및 JSON, JSON 및 예측에서 다시로드 모델로 모델을 저장, 그것은으로 TF를 모르는 실패, 해결 방법을하거나 가장 좋은 방법은 무엇 하는가? – bygreencn

+0

예,이 코드와 관련하여 알려진 문제입니다. 이 함수를 실행하면 그래프가 변경됩니다. 따라서 하나의 브랜치를 저장해야 나중에 단일 GPU에서 예측을 위해로드 할 수 있습니다 – Temak

+0

그 기능으로 인해 내 시대가 40 초에서 1000 초가되었습니다 ... – AdAbsurdum

관련 문제