#python #python-3.x #deep-learning #pytorch
#python #python-3.x #глубокое обучение #pytorch
Вопрос:
Я изучаю предварительную выборку данных в графический процессор из центрального процессора, когда модель обучается на графическом процессоре. Перекрывающаяся передача данных с CPU на GPU с обучением модели GPU, по-видимому, требует обоих
- Передача данных на графический процессор с использованием
data = data.cuda(non_blocking=True)
- Закрепите данные в памяти процессора с помощью
train_loader = DataLoader(..., pin_memory=True)
Однако я не могу понять, как выполняется неблокирующая передача в этом официальном примере PyTorch, в частности, в этом блоке кода:
for i, (images, target) in enumerate(train_loader):
# measure data loading time
data_time.update(time.time() - end)
if args.gpu is not None:
images = images.cuda(args.gpu, non_blocking=True)
if torch.cuda.is_available():
target = target.cuda(args.gpu, non_blocking=True)
# compute output
output = model(images)
loss = criterion(output, target)
Не будет images.cuda(non_blocking=True)
и target.cuda(non_blocking=True)
должно быть завершено перед output = model(images)
выполнением. Поскольку это точка синхронизации, images
сначала она должна быть полностью передана на устройство CUDA, поэтому этапы передачи данных фактически больше не являются неблокирующими.
Поскольку output = model(images)
это блокировка, images.cuda()
и target.cuda()
на следующей i
итерации for
цикла не произойдет, пока не будет вычислен вывод модели, что означает отсутствие предварительной выборки на следующей итерации цикла.
Если это правильно, каков правильный способ выполнить предварительную выборку данных в GPU?
Ответ №1:
Я думаю, что вы ошибаетесь в том, что output = model(images)
это точка синхронизации. Похоже, что вычисления обрабатываются другой частью графического процессора. Цитата из официальных документов PyTorch:
Кроме того, как только вы закрепите тензор или хранилище, вы можете использовать асинхронные копии GPU. Просто передайте дополнительный
non_blocking=True
аргумент вto()
илиcuda()
вызов. Это может быть использовано для перекрытия передачи данных вычислениями.
Комментарии:
1. Должно
non_blocking=True
применяться как к изображениям, так и к целевым объектам? Поскольку изображения будут использоваться в вычислениях, как это поможет?2. @OmarAlSuwaidi Да для обоих, потому что torch может предварительно извлекать 2-й пакет, в то время как первый выполняет свои вычислительные шаги вперед / назад.
Ответ №2:
Чтобы правильно реализовать предварительную выборку GPU в PyTorch, вы должны преобразовать цикл for в цикл while.
Загрузчик данных следует преобразовать в итератор с помощью iter
функции, например iterator = iter(loader)
.
Используйте next(iterator)
на каждом шаге внутри цикла while для получения следующего мини-пакета.
Завершение загрузки данных может быть обнаружено путем перехвата StopIteration
из итератора.
Используйте флаг для завершения цикла while при поднятии StopIteration
.