python tensorflow keras python-multiprocessing

python - Keras+Tensorflow: Predicción en múltiples gpus



python-multiprocessing (2)

Estoy usando Keras con tensorflow como back-end. Tengo un modelo compilado / entrenado.

Mi ciclo de predicción es lento, así que me gustaría encontrar una forma de paralelizar las llamadas a predict_proba para acelerar las cosas. Me gustaría tomar una lista de lotes (de datos) y luego, por gpu disponible, ejecutar model.predict_proba() sobre un subconjunto de esos lotes.
Esencialmente:

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)

Sé que es posible en Tensorflow puro asignar operaciones a un gpu determinado ( https://www.tensorflow.org/tutorials/using_gpu ). Sin embargo, no sé cómo se traduce esto en mi situación, ya que he construido / compilado / entrenado mi modelo usando la API de Keras.

Pensé que tal vez solo necesitaba usar el módulo de multiprocesamiento de python y comenzar un proceso por gpu que ejecutaría predict_proba(batch_n) . Sé que esto es teóricamente posible dado otro post SO mío: Keras + Tensorflow y Multiprocesamiento en Python . Sin embargo, esto todavía me deja con el dilema de no saber cómo realmente "elegir" un gpu para operar el proceso.

Mi pregunta se reduce a: ¿cómo se puede paralelizar la predicción para un modelo en Keras a través de múltiples gpus cuando se usa Tensorflow como backend de Keras?

Además, tengo curiosidad si es posible una paralelización similar para la predicción con solo un gpu.

¡Una descripción de alto nivel o un ejemplo de código sería muy apreciado!

¡Gracias!


Creé un ejemplo simple para mostrar cómo ejecutar el modelo de kera en múltiples gpus. Básicamente, se crean múltiples procesos y cada uno de los procesos posee un gpu. Para especificar el id. De gpu en proceso, la configuración de la variable de entorno CUDA_VISIBLE_DEVICES es muy sencilla (os.environ ["CUDA_VISIBLE_DEVICES"]). Espero que este git repo pueda ayudarte.

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


Puede usar esta función para paralelizar un modelo de Keras (créditos a 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)