Я использую GANEstimator с MirroredStrategy для работы на нескольких графических процессорах одного экземпляра.input_fn
в моем случае - tf.data.Dataset
со следующими настройками:
dataset = dataset.repeat()
dataset = dataset.shuffle(buffer_size=100)
dataset = dataset.batch(self.batch_size, drop_remainder=True)
dataset = dataset.prefetch(100)
Причина, по которой я спрашиваю это, заключается в том, что мне нужно указать что-то вроде dataset.shard()
вручную, чтобы передавать разные данныерабочим?Я копаю код Оценщик и MirroredStrategy , но мне неясно, что происходит.Дополнительная путаница возникает из описания распределенных стратегий :
MirroredStrategy: This does in-graph replication with synchronous
training on many GPUs on one machine. Essentially, we create copies of all
variables in the model's layers on each device. We then use all-reduce
to combine gradients across the devices before applying them
to the variables to keep them in sync.
CollectiveAllReduceStrategy: This is a version of MirroredStrategy
for multi-worker training.
Так использует ли MirroredStratedy только одного работника?Я не понимаю этоМне нужно указать размер партии, равный вместимости одной башни, в противном случае я получу OOM.Может кто-нибудь указать мне код и объяснить, как такая простая установка работает с пакетами:
def create_dataset():
...
dataset = dataset.repeat()
dataset = dataset.shuffle(buffer_size=100)
dataset = dataset.batch(self.batch_size, drop_remainder=True)
dataset = dataset.prefetch(100)
return dataset
NUM_GPUS = 4
strategy = tf.contrib.distribute.MirroredStrategy(num_gpus=NUM_GPUS)
optimizer = tf.train.RMSPropOptimizer(learning_rate=0.01, use_locking=True)
optimizer_d = tf.train.RMSPropOptimizer(learning_rate=0.01, use_locking=True)
config = tf.estimator.RunConfig(save_checkpoints_steps=100,
save_summary_steps=1, keep_checkpoint_max=50,
train_distribute=strategy)
# I have more hooks here, just simplified to show
def get_hooks_fn(GANTrainOps):
disjoint_train_hook_func = tfgan.get_sequential_train_hooks(
train_steps=tfgan.GANTrainSteps(10, 1)
) # g steps, d steps
disjoint_train_hooks = disjoint_train_hook_func(GANTrainOps)
return [update_hook, summary_hook] + disjoint_train_hooks
# Create GAN estimator.
gan_estimator = tfgan.estimator.GANEstimator(
model_dir = '/data/checkpoints/estimator_model',
generator_fn = generator_fn,
discriminator_fn = discriminator_fn,
generator_loss_fn = generator_loss_fn,
discriminator_loss_fn = discriminator_loss_fn,
generator_optimizer = optimizer,
discriminator_optimizer = optimizer_d,
use_loss_summaries=True,
config=config,
get_hooks_fn=get_hooks_fn)
gan_estimator.train(input_fn=create_dataset, steps=10000)
Спасибо!
Код MirroredStrategy содержит:
1Странная формулировка:
Версия этого класса для нескольких рабочих отображает одну реплику на одно устройство на рабочем.Он отражает все переменные модели на всех репликах.Например, если у вас есть два worker
с, а у каждого worker
есть 4 графических процессора, на этих 8 графических процессорах будет создано 8 копий переменных модели.Затем, как и в MirroredStrategy (???), каждая реплика выполняет свои вычисления с собственной копией переменных, если только в модели кросс-реплики, где происходит уменьшение переменной или тензора.
2)
auto_shard_dataset: выполнять ли автоматическое разбиение набора данных при наличии нескольких рабочих.
По умолчанию этот параметр имеет значение False.
РЕДАКТИРОВАТЬ:
До сих пор я обнаружил, что tf.estimator.train()
через некоторое время указывает на то, чтокажется, что strategy.make_input_fn_iterator()
:
def _get_iterator_from_input_fn(self, input_fn, mode, distribution=None):
if distribution is not None:
iterator = distribution.make_input_fn_iterator(
lambda _: self._call_input_fn(input_fn, mode))
input_hooks = [
estimator_util.DistributedIteratorInitializerHook(iterator)]
else:
result = self._call_input_fn(input_fn, mode)
iterator = result.make_initializable_iterator()
input_hooks = [estimator_util._DatasetInitializerHook(iterator)]
return iterator, input_hooks
make_input_fn_iterator()
Но он был удален из кода MirroredStrategy и больше не существует!Я не понимаю, как это работает и где набор данных на самом деле разделен.
EDIT2: Я не могу найти строку make_input_fn_iterator
в моем распределении тензор потока 1.12.0 с помощью grep.Похоже, в коде он полностью отсутствует.