Рекомендации по ускорению тренировок в рамках одной GPU.
Как бы ты не ухищрялся, достичь производительности следующей GPU в модельном ряду, скорее всего, не получится.
Если есть возможность достать GPU получше - это лучшее решение.
Перед тем как начать что-то улучшать, научись это измерять. Используй профайлеры.
Проверяй что тренировка не разваливается, после внесения изменений.
Использование Pytorch docker-образа от NVidia поможет избежать нетривиальных проблем с версией CUDA
, неработающих тензорных ядер и множества других интересных проблем. C которыми ты почти наверняка столкнешься, пытаясь ускорить тренировку моделей.
Если есть возможность - лучше использовать.
По умолчанию DataLoader
будет готовить данные для обучения в основном потоке исполнения.
Попробуй выставить num_workers=1
, чтобы отселить загрузку данны в отдельные процесс.
С помощью профайлера и бенчмарков определи оптимальное число воркеров.
Параметр DataLoader(pin_memory=True)
в связке с Tensor.to(device, non_blocking=True)
, может ускорить загрузку тензоров на GPU.
Если упираешься в чтение данных - поищи более быстрые форматы / ридеры под свои данные.
Любые вызовы Tensor.cpu()/to()/numpy()
заставляют GPU синхронизироваться.
Синхронизация это дорого. Выкидывай все ненужные синхронизации.
Увеличение размера батча делает твою тренировку стабильнее (если ты не занимаешься совсем эзотерикой) и позволяет протолкнуть чуть больше данных в единицу времени. Подробнее.
Не забывай про эвристики связывающие размет батча и learnin-rate.
Не всегда возможно, но если есть возможность кормить батчи фиксированного размера, это может положительно сказаться на скорости обучения.
Если размер батчей будет меняться - преаллоцируй память, под батч самого большого размера, чтобы сэкономить на аллокациях. Преаллокация делается вот так.
В недрах CUDNN
живут разные способы выполнения математических операций.
В зависимости от железа, драйверов и данных они могут показывать разную эффективность.
Если выставить флаг
torch.backends.cudnn.benchmark = True
на старте тренировки, Torch попробует разные операции. И дальше будет использовать самые эффективные.
При фиксированном размере батча это может ускорить тренировку на несколько процентов.
Если размер батча постоянно меняется - лучше отключить. Скорее всего выбранные операции окажутся неоптимальными и учиться будет очень медленно.
AdaptiveMixedPrecision
позволяет выполнять часть операций в 16bit
.
Самый эффективный рецепт.
Проверяй что тренировка не взрывается. Внимательно читай документацию, особенно если используешь несколько лосс-функций или занимаешься любмым другим нетривиальным колдунством.
Apex - расширение для PyTorch от NVidia.
Внутри можно найти реализацию FusedAdam. Ведет себя как обычный adam
, но может работать быстрее.
Кроме того, в последних версиях торча появился параметр Adam(fused=False)
, можно попробовать включить и померить. Но скорее всего версия из apex
окажется быстрее.
Jit.Fuse
позволяет склеить несколько операций в одну.
Можно пробовать, если организация кода и операции позволяют.