我正在将数据并行性应用于seq2seq模型,它分别为每个预定义的桶实现了几个子图。它处理它的渐变,如下所示:
# buckets = [(10,15),(20,25)..]
self.gradient_norms = []
self.grads = []
self.updates = []
self.opt = tf.train.GradientDescentOptimizer(self.learning_rate)
for b in xrange(len(buckets)):
gradients = tf.gradients(self.losses[b], params)
clipped_gradients, norm = tf.clip_by_global_norm(gradients,...)
self.gradient_norms.append(norm)
self.updates.append(opt.apply_gradients(zip(clipped_gradients, params), global_step=self.global_step))
.......
.....
output_feed = [self.updates[bucket_id],
self.gradient_norms[bucket_id],
self.losses[bucket_id]]
根据sync_replicas_optimizer.py
中的说明,我只需要包装self.opt并使用compute_gradients()
,自己剪辑,然后使用隐式分发的包裹的apply_gradients()
。< / p>
我试图以两种不同的方式实现它。
1)在存储桶循环中具有多个apply_gradients()
的outter SyncReplicasOptimizer:
...
self.opt = tf.train.GradientDescentOptimizer(self.learning_rate)
self.sync_applys = []
self.sync_opt = tf.train.SyncReplicasOptimizer(self.opt,
replicas_to_aggregate=replicas_to_aggregate,
replica_id=replica_id,
total_num_replicas=total_num_replicas)
for b in xrange(len(buckets)):
grad_var = self.sync_opt.compute_gradients(self.losses[b], params)
# collect grad and clip it by myself
for each in grad_var:
self.grads.append(each[0])
clipped_grad,norm = tf.clip_by_global_norm(self.grads,max_gradient_norm)
apply_gradients_op = self.sync_opt.apply_gradients(zip(clipped_grad, params), global_step=self.global_step)
self.sync_applys.append(apply_gradients_op)
......
....
output_feed = [self.losses[bucket_id]],
self.sync_applys[bucket_id],
self.sync_opt._local_steps,
self.sync_opt._global_step]
但是这样,一旦进入主循环,所有机器上的所有进程都会卡住。
2)每个存储桶的内部SyncReplicasOptimizer:
sync_opts = []
for b in xrange(len(buckets)):
sync_opt = tf.train.SyncReplicasOptimizer(self.opt,
replicas_to_aggregate=replicas_to_aggregate,
replica_id=replica_id,
total_num_replicas=total_num_replicas)
for each in grad_var:
self.grads.append(each[0])
clipped_grad,norm = tf.clip_by_global_norm(self.grads,max_gradient_norm)
apply_gradients_op = sync_opt.apply_gradients(...)
self.sync_opts.append(sync_opt)
.....
...
output_feed = [self.losses[bucket_id],
self.sync_applys[bucket_id],
self.sync_opts[bucket_id]._local_steps,
self.sync_opts[bucket_id]._global_step]
但是通过这种方式,我得到了一个ppx,在我的训练和有效集上都是无限的。
在我的情况下,我有1 ps和5名工人(首席是0),我的total_replicas
和replicas_to_aggregate
是相同的。
当调用apply_gradients()
时,SyncReplicasOptimizer将创建队列和一些其他变量。而且我不知道在涉及多桶一体机问题时是否会引起任何同步问题,因为在每个运行时步骤中,根据长度只有一个子图(桶)将选择输入,并且它具有由SyncReplicasOptimizer.apply_gradients()
任何人都可以给我一些建议吗,或者有更好的方法来获得seq2seq数据并行性?
我所采取的一切: tensorflow分布式指南 Cifar10分发的例子