Как установить случайное начальное число, когда оно находится в распределенном обучении в PyTorch? - PullRequest
0 голосов
/ 30 мая 2020

Сейчас я обучаю модель, используя torch.distributed, но я не уверен, как установить случайные начальные числа. Например, это мой текущий код:

def main():
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    torch.cuda.manual_seed(args.seed)

    cudnn.enabled = True
    cudnn.benchmark = True
    cudnn.deterministic = True 

    mp.spawn(main_worker, nprocs=args.ngpus, args=(args,))

И следует ли мне переместить

    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    torch.cuda.manual_seed(args.seed)

    cudnn.enabled = True
    cudnn.benchmark = True
    cudnn.deterministic = True 

в функцию main_worker(), чтобы убедиться, что каждый процесс имеет правильные настройки seed и cudnn ? Кстати, я пробовал это, и такое поведение сделает тренировку в 2 раза медленнее , что меня очень смутило.

Большое спасибо за любую помощь!

1 Ответ

2 голосов
/ 30 мая 2020

Порожденные дочерние процессы не наследуют начальное число, которое вы установили вручную в родительском процессе, поэтому вам необходимо установить начальное значение в функции main_worker.

Тот же logi c применяется к cudnn.benchmark и cudnn.deterministic, поэтому, если вы хотите их использовать, вы должны также установить их в main_worker. Если вы хотите убедиться в этом, вы можете просто распечатать их значения в каждом процессе.

cudnn.benchmark = True пытается найти оптимальный алгоритм для вашей модели, сравнивая различные реализации определенных операций (например, доступная свертка алгоритмы ). Это займет время, чтобы найти лучший алгоритм, но как только это будет сделано, дальнейшие итерации могут быть быстрее. Алгоритм, который был признан лучшим, применяется только к указанному размеру c ввода, который был использован. Если на следующей итерации у вас будет другой размер входных данных, эталонный тест необходимо запустить снова, чтобы определить лучший алгоритм для этого заданного c входного размера, который может отличаться от первого входного размера.

Я предполагаю, что ваши размеры ввода различаются, что объясняет замедление, поскольку тест не использовался, когда он был установлен в родительском процессе. cudnn.benchmark = True следует использовать только в том случае, если ваши входные размеры фиксированы.

cudnn.determinstic = True также может иметь негативное влияние на производительность, потому что некоторые базовые операции, которые не являются детерминированными c, должны быть заменена на детерминированную c версию, которая, как правило, работает медленнее, иначе в первую очередь будет использоваться детерминированная c версия, но это влияние на производительность не должно быть слишком драматичным c.

...