¿Cómo funciona el entrenamiento asíncrono en Tensorflow distribuido?

He leído Distributed Tensorflow Doc , y menciona que en el entrenamiento asíncrono,

Cada réplica del gráfico tiene un ciclo de entrenamiento independiente que se ejecuta sin coordinación.

Por lo que entiendo, si utilizamos el servidor de parámetros con una architecture de paralelismo de datos, significa que cada trabajador calcula los gradientes y actualiza sus propios pesos sin preocuparse por las actualizaciones de otros trabajadores para la formación de redes neuronales de capacitación distribuida. Como todos los pesos se comparten en el servidor de parámetros (ps), creo que ps todavía tiene que coordinar (o agregar) las actualizaciones de peso de todos los trabajadores de alguna manera. Me pregunto cómo funciona la agregación en el entrenamiento asíncrono. O en palabras más generales, ¿cómo funciona la capacitación asíncrona en Tensorflow distribuido?

Cuando se entrena de forma asíncrona en TensorFlow distribuido, un trabajador en particular hace lo siguiente:

  1. El trabajador lee todos los parámetros del modelo compartido en paralelo desde la (s) tarea (s) PS y los copia en la tarea del trabajador. Estas lecturas no están coordinadas con ninguna escritura concurrente, y no se adquieren lockings: en particular, el trabajador puede ver actualizaciones parciales de uno o más trabajadores adicionales (por ejemplo, puede haberse aplicado un subconjunto de las actualizaciones de otro trabajador, o un subconjunto de los elementos). en una variable puede haber sido actualizada).

  2. El trabajador calcula los gradientes localmente, basándose en un lote de datos de entrada y los valores de los parámetros que leyó en el paso 1.

  3. El trabajador envía los gradientes para cada variable a la tarea PS adecuada, y aplica los gradientes a su variable respectiva, utilizando una regla de actualización que está determinada por el algoritmo de optimización (por ejemplo, SGD, SGD con Momentum, Adagrad, Adam, etc.). Las reglas de actualización generalmente utilizan (aproximadamente) operaciones conmutativas , por lo que pueden aplicarse de forma independiente en las actualizaciones de cada trabajador, y el estado de cada variable será un agregado en ejecución de la secuencia de actualizaciones recibidas.

En la capacitación asíncrona, cada actualización del operario se aplica al mismo tiempo, y las actualizaciones pueden coordinarse de alguna manera si se establece el use_locking=True opcional use_locking=True cuando se inicializó el optimizador respectivo (por ejemplo, tf.train.GradientDescentOptimizer ). Sin embargo, tenga en cuenta que el locking aquí solo proporciona la exclusión mutua para dos actualizaciones simultáneas, y (como se indicó anteriormente) las lecturas no adquieren lockings; El locking no proporciona atomicidad en todo el conjunto de actualizaciones.

(Por el contrario, en el entrenamiento síncrono, una utilidad como tf.train.SyncReplicasOptimizer asegurará que todos los trabajadores lean los mismos valores actualizados para cada parámetro del modelo y que todas las actualizaciones para un paso síncrono se agreguen antes de que se apliquen a las variables subyacentes. Para hacer esto, los trabajadores se sincronizan por una barrera, que ingresan después de enviar su actualización de gradiente, y se van después de que la actualización agregada se haya aplicado a todas las variables.)

En el entrenamiento asíncrono no hay sincronización de pesos entre los trabajadores. Los pesos se almacenan en el servidor de parámetros. Cada trabajador carga y cambia los pesos compartidos independientemente uno del otro. De esta manera, si un trabajador finalizó una iteración más rápido que los otros trabajadores, continuará con la siguiente iteración sin esperar. Los trabajadores solo interactúan con el servidor de parámetros compartido y no interactúan entre sí.

En general, puede (según la tarea) acelerar el cálculo de manera significativa. Sin embargo, los resultados a veces son peores que los obtenidos con las actualizaciones síncronas más lentas.

Mirando el ejemplo en la documentación que vinculas a:

 with tf.device("/job:ps/task:0"): weights_1 = tf.Variable(...) biases_1 = tf.Variable(...) with tf.device("/job:ps/task:1"): weights_2 = tf.Variable(...) biases_2 = tf.Variable(...) with tf.device("/job:worker/task:7"): input, labels = ... layer_1 = tf.nn.relu(tf.matmul(input, weights_1) + biases_1) logits = tf.nn.relu(tf.matmul(layer_1, weights_2) + biases_2) # ... train_op = ... with tf.Session("grpc://worker7.example.com:2222") as sess: for _ in range(10000): sess.run(train_op) 

Puede ver que la capacitación se distribuye en tres máquinas que comparten una copia de pesos idénticos, pero como se menciona justo debajo del ejemplo:

En el ejemplo anterior, las variables se crean en dos tareas en el trabajo ps, y la parte de uso intensivo de cómputo del modelo se crea en el trabajo del trabajador. TensorFlow insertará las transferencias de datos apropiadas entre los trabajos (de ps a worker para el pase de reenvío, y de worker a ps para aplicar gradientes).

En otras palabras, un gpu se usa para calcular el paso hacia adelante y luego transmite los resultados a las otras dos máquinas, mientras que cada una de las otras máquinas calcula la propagación hacia atrás para una parte de los pesos y luego envía los resultados a las otras máquinas para que todos pueden actualizar sus pesos apropiadamente

Las GPU se utilizan para acelerar las multiplicaciones de matrices y las operaciones matemáticas paralelas que son muy intensivas para la propagación tanto hacia adelante como hacia atrás. Por lo tanto, la capacitación distribuida simplemente significa que usted distribuye estas operaciones en muchas GPU, el modelo aún está sincronizado entre las máquinas, pero ahora la propagación hacia atrás de diferentes pesos se puede calcular en paralelo y el pase directo en un mini lote diferente se puede calcular en todavía se está calculando el mismo tiempo que el backprop del mini lote anterior. La capacitación distribuida no significa que tenga modelos y pesos totalmente independientes en cada máquina.