Как использовать несколько графических процессоров в PyTorch

Эффективно сократите время обучения вашей модели и обрабатывайте большие наборы данных, используя расширенную вычислительную мощность нескольких графических процессоров в PyTorch.
выберите прикладные программы +для обработки графической информации product python

Знакомство с PyTorch?

В мире науки о данных и разработки программного обеспечения это знакомый сценарий: вы по колено в данных — их горы — и пытаетесь построить сложную модель. Вы можете почувствовать, как ваш единственный графический процессор испытывает трудности с рабочей нагрузкой, часы тикают громче, а сроки приближаются.

Такие времена требуют спасательного круга — именно здесь и появляется возможность использовать мощь нескольких графических процессоров.

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

В этой статье мы рассмотрим, почему и как использовать архитектуру с несколькими графическими процессорами в PyTorch , популярной среде глубокого обучения , проливая свет на ее важность в современной среде, управляемой данными.

pytorch cuda
pytorch install

Выходя за рамки обучения, использование нескольких графических процессоров также дает значительные преимущества при выводе. Это обеспечивает более высокую пропускную способность, одновременно обеспечивая быструю обработку множества задач, критически важных в современном мире, включая управление трафиком, рекомендации по электронной коммерции и аналитику в реальном времени.

Более того, установка с несколькими графическими процессорами добавляет избыточность, повышая надежность системы, обеспечивая непрерывную работу даже в случае возникновения проблем с одним графическим процессором.

В совокупности эти преимущества использования нескольких графических процессоров как на этапе обучения, так и на этапе вывода представляют собой значительный сдвиг в повышении эффективности и надежности приложений машинного обучения (ML) . В свете этого понимание эффективного использования нескольких графических процессоров становится бесценным знанием.

Что такое PyTorch?

PyTorch, библиотека машинного обучения с открытым исходным кодом, поддерживаемая группой исследований искусственного интеллекта Facebook, известна своим балансом простоты и мощности в машинном обучении.

Он предлагает динамический вычислительный граф, который обеспечивает исключительную гибкость при построении и изменении сложных моделей во время выполнения.

Одной из характеристик, которая отличает PyTorch от других, является его Pythonic природа, что делает его удобным для начинающих и опытных разработчиков.

Он обеспечивает отличную совместимость как с процессорами, так и с графическими процессорами. Он имеет встроенную поддержку распределенной обработки и использования нескольких графических процессоров, что позволяет значительно ускорить обучение модели или прогнозирование.

По своей сути PyTorch содержит высокоуровневый API для нейронных сетей , способствующий повторному использованию и чистоте кода. В следующих разделах мы рассмотрим, как использовать эти надежные функции для практического использования нескольких графических процессоров.

Зачем использовать несколько графических процессоров?

Вы можете спросить: «Моя модель прекрасно работает на моей рабочей станции! Почему я должен использовать несколько графических процессоров?». Однако по мере того, как модели машинного обучения усложняются и требуют больше вычислений, модели могут доводить до предела даже высокопроизводительные установки с одним графическим процессором.

Кроме того, время ожидания будет увеличиваться по мере увеличения сложности, увеличивая время простоя для вас и вашей команды. Таким образом, можно привести доводы в пользу «альтернативной стоимости» и «инженерных часов», потраченных на ожидание завершения этих задач ML.

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

Разработчики могут разделить источник данных на разные графические процессоры для обработки — метод, известный как параллелизм данных. Однако PyTorch вооружает нас не только этим; он предоставляет другие альтернативные стратегии использования нескольких графических процессоров:

  • Параллелизм данных . Эта стратегия одновременно обрабатывает сегменты данных на разных графических процессорах, ускоряя вычисления.
  • Параллелизм моделей . Этот метод имеет решающее значение для колоссальных моделей, превышающих объем памяти одного графического процессора. Этот метод распределяет различные части одной и той же модели по нескольким графическим процессорам. Каждый графический процессор самостоятельно вычисляет свою часть модели, а затем передает результаты следующему графическому процессору.
  • Конвейерный параллелизм : комбинация параллелизма данных и модели, при которой разные части модели и пакетов данных одновременно обрабатываются на разных графических процессорах. Обычно это более эффективно и может привести к более быстрому обучению.

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

pytorch models
Зачем использовать pytorch models

Плюсы и минусы методов параллелизма

Как уже упоминалось, PyTorch реализует распараллеливание тремя методами: данные, модель и конвейер. Каждый из них предоставляет уникальные преимущества и несет в себе свои сложности.

Интересно, что хотя эти стратегии обычно используются для ускорения операций, неправильное их использование в определенных контекстах может непреднамеренно привести к замедлению работы.

Например, несмотря на свою общую пользу, параллелизм данных может снизить производительность при работе с небольшими моделями или недостаточно большими размерами пакетов из-за накладных расходов на связь.

В свете этого понимание тонких нюансов, преимуществ и недостатков каждого метода параллелизма становится критически важным. В следующих подразделах мы сравниваем плюсы и минусы каждого метода, помогая вам выбрать лучшую стратегию параллелизма для ваших нужд.

Параллелизм данных

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

Результаты каждого графического процессора затем объединяются и синхронизируются для получения окончательного результата. Этот метод использует вычислительную мощность всех задействованных графических процессоров для более быстрых вычислений и надежного процесса обучения.

Плюсы

  • Простота : параллелизм данных легко реализовать в PyTorch с помощью класса DataParallel().
  • Поместить модель в параллельную установку может быть так же просто, как обернуть вашу модель в эти классы.
  • Масштабируемость . Параллелизм данных хорошо масштабируется в зависимости от количества графических процессоров, поскольку предполагает разделение пакетов данных и их одновременную обработку.

Минусы

  • Накладные расходы на связь . Градиентная синхронизация должна происходить между графическими процессорами во время каждого прохода обратного распространения ошибки, что может стать узким местом, особенно по мере увеличения количества графических процессоров.
  • Дисбаланс памяти графического процессора : все параметры модели и промежуточные карты активации должны храниться на каждом графическом процессоре, что увеличивает общее использование памяти в системе.

Модельный параллелизм

Модельный параллелизм

Модельный параллелизм распределяет слои модели нейронной сети по нескольким графическим процессорам. В отличие от параллелизма данных, каждый графический процессор хранит уникальный сегмент модели и работает со всеми входными данными.

Информация передается от одного графического процессора к другому по конвейеру и последовательно обрабатывается каждой частью сегментированной модели. Различные части модели выполняются на разных графических процессорах, каждый из которых выполняет определенную часть вычислений, необходимых для обучения модели.

Плюсы

  • Обрабатывает большие модели : идеально подходит для развертывания больших моделей, объем памяти которых превышает объем памяти одного графического процессора, поскольку части модели находятся на разных графических процессорах.
  • Снижение накладных расходов на связь . Параллелизм моделей может привести к меньшим накладным расходам на обмен данными, чем параллелизм данных, поскольку градиенты не обязательно требуют синхронизации между графическими процессорами.

Минусы

  • Сложность : это усложняет реализацию, поскольку требует ручного разделения модели между графическими процессорами.
  • Неэффективное использование графического процессора . Если слои модели не имеют одинаковой вычислительной сложности, некоторые графические процессоры могут простаивать, в то время как другие выполняют обработку, что приводит к неэффективному использованию графического процессора.

Параллелизм конвейеров

Конвейерный параллелизм — это стратегия, сочетающая в себе элементы параллелизма данных и моделей. Он сегментирует слои модели по нескольким графическим процессорам, аналогично параллелизму моделей.

Затем каждый графический процессор обрабатывает разные мини-пакеты данных через свой сегмент модели, аналогично параллелизму данных.

Мини-пакеты перемещаются через графические процессоры по конвейеру, при этом каждый графический процессор передает выходные данные следующему графическому процессору для дальнейшей обработки, точно так же, как данные проходят по конвейеру.

В результате каждый графический процессор в любой момент времени работает над разными мини-пакетами, что может повысить эффективность вычислений и пропускную способность.

Плюсы

  • Эффективность : этот метод предлагает сочетание параллелизма данных и модели, что позволяет эффективно использовать ресурсы графического процессора за счет распределения различных частей модели и мини-пакетов данных между графическими процессорами.
  • Обрабатывает большие модели и пакеты : полезно, когда модель и размер пакета слишком велики, чтобы поместиться в одну память графического процессора.

Минусы

  • Накладные расходы на связь . Подобно параллелизму данных, градиенты должны быть синхронизированы между графическими процессорами.
  • Сложность : требуется тщательное разделение модели и пакетов по графическим процессорам, что усложняет ее реализацию.

Реализация параллелизма с использованием PyTorch

Реализация параллелизма с PyTorch

После того как вы решили, какой метод параллелизма лучше всего соответствует потребностям вашего проекта и конфигурации системы, пришло время его реализовать. Ниже приведены примеры, демонстрирующие различия в реализации трех методов.

Параллелизм данных

Шаг 1. Импортируйте PyTorch и определите модель . В этом примере мы будем использовать простую сверточную нейронную сеть (CNN) для классификации изображений для набора данных CIFAR-10.

import torch
import torch.nn as nn
import torch.optim as optim

class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.fc1 = nn.Linear(32 * 8 * 8, 64)
self.fc2 = nn.Linear(64, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = nn.functional.relu(x)
        x = self.pool(x)
        x = self.conv2(x)
        x = nn.functional.relu(x)
        x = self.pool(x)
        x = x.view(-1, 32 * 8 * 8)
        x = self.fc1(x)
        x = nn.functional.relu(x)
        x = self.fc2(x)
        return x

Шаг 2. Затем инициализируйте модель и определите функцию потерь и оптимизатор . В этом примере будет использоваться функция перекрестных энтропийных потерь и оптимизатор стохастического градиентного спуска (SGD).

model = CNN()
criterion = nn.CrossEntropyLoss()

Шаг 3. Создайте загрузчик данных и переместите модель на графические процессоры . В этом примере мы будем использовать набор данных CIFAR-10 и разобьем его на пакеты по 64 изображения.

Мы также перенесем модель на графические процессоры с помощью nn.DataParallel()модуля. По сути, nn.DataParallel()модель оборачивается и при этом копируется ваша модель на каждом графическом процессоре, разделяется входные данные и агрегируется выходные данные каждого графического процессора.

Шаг 4: Обучите модель . Последний шаг — обучение модели с использованием нескольких графических процессоров. Мы пройдемся по набору данных, вычислим градиенты с помощью обратного распространения ошибки и обновим веса с помощью оптимизатора.

Мы также напечатаем потери при обучении и точность для каждой эпохи. Обратите внимание: поскольку мы обернули нашу модель с помощью nn.DataParallel(), PyTorch будет обрабатывать распределение данных на другие графические процессоры, оставляя логику кода в цикле обучения неизменной.

for epoch in range(10):
    running_loss = 0.0
    running_corrects = 0.0

Модельный параллелизм

Шаг 1. Импортируйте PyTorch и определите модель . В этом случае мы определим две части модели отдельно и распределим их по разным графическим процессорам.

import torch
import torch.nn as nn
import torch.optim as optim

class ModelPart1(nn.Module):
    def __init__(self):

    def forward(self, x):
        x = self.conv1(x)
        x = nn.functional.relu(x)
        x = self.pool(x)
        return x

class ModelPart2(nn.Module):
    def __init__(self):
super(ModelPart2, self).__init__()
self.fc1 = nn.Linear(32 * 8 * 8, 64)
self.fc2 = nn.Linear(64, 10)

    def forward(self, x):
        x = self.conv2(x)
        x = nn.functional.relu(x)
        x = x.view(-1, 32 * 8 * 8)
        x = self.fc1(x)
        x = nn.functional.relu(x)
        x = self.fc2(x)
        return x

Шаг 2. Инициализируйте части модели и определите функцию потерь и оптимизатор .

device1 = torch.device("cuda:0")
device2 = torch.device("cuda:1")

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(
lr=0.001, momentum=0.9
)

Шаг 3. Создайте загрузчик данных .

Шаг 4: Обучите модель . Обратите внимание, что нам нужно обрабатывать поток управления каждым сегментом модели и нашими данными для каждого графического процессора.

Параллелизм конвейеров

Шаг 1. Импортируйте библиотеки и определите модель . Разделите модель на две основные части и рассматривайте их как отдельные этапы конвейера.

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
from torchvision import transforms

Шаг 2. Оберните многоэтапную модель с помощьюsync.pipe() .

model = CNN()

# 8 equals batch_size/number_of_Gpus
model = sync.Pipe(model, chunks=8)

Шаг 3: Определите функцию потерь и оптимизатор .

criterion = nn.CrossEntropyLoss()

Шаг 4. Создайте загрузчик данных

Шаг 5: Обучение модели . Обратите внимание, как нам нужно передавать входные данные и метки на разные графические процессоры (cuda:0 и cuda:1). При выполнении прямых и обратных проходов конвейер будет автоматически управлять выполнением каждого этапа на соответствующих графических процессорах.

Обратите внимание, что параллелизм конвейеров приводит к остановкам конвейера, что может привести к простою графических процессоров в определенное время.

Лучше всего это будет работать, когда время вычислений достаточно велико, чтобы окупить накладные расходы на эти стойла.

for epoch in range(10):
    running_loss = 0.0
    running_corrects = 0.0
        optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
        
        loss.backward()
        optimizer.step()
_, preds = torch.max(outputs, 1)

Распределенные вычисления PyTorch

Что делать, если вам нужно больше мощности, чем есть в вашей системе?

PyTorch имеет встроенные функции, способствующие распределенным вычислениям , позволяющие использовать несколько графических процессоров из нескольких узлов. Его DistributedDataParallel() (DDP)модуль обеспечивает синхронизированное обучение нескольких графических процессоров, а распределенная структура RPC и средства выборки данных помогают управлять вычислениями на многочисленных узлах.

Выбор распределенных вычислений на нескольких графических процессорах может дать такие преимущества, как улучшенная масштабируемость, более высокая скорость, возможность использования более крупных моделей и наборов данных, а также лучшая устойчивость перед лицом сбоев отдельных узлов.

Однако достижение эффективных распределенных вычислений предполагает нечто большее, чем просто использование одной библиотеки или платформы. Дополнительные платформы, такие как Dask , Ray и Saturn Cloud, могут предоставить дополнительную функциональность и упростить процесс.

Dask превосходно справляется с ситуациями, требующими вычислений с нехваткой памяти и сложных задач предварительной обработки данных. И наоборот, Ray упрощает реализацию распределенных алгоритмов машинного обучения с помощью надежной системы планирования задач.

Кроме того, Saturn Cloud поддерживает простую настройку распределенных сред в облаке с помощью масштабируемых сценариев машинного обучения, включая поддержку графических процессоров.

Прежде всего, очень важно помнить о сложности, которую могут представлять эти платформы. Практические распределенные вычисления требуют тщательного баланса масштаба и сложности.

Инициативы всегда должны гарантировать, что преимущества скорости, масштабируемости и устойчивости явно превосходят любые эксплуатационные сложности, которые могут возникнуть при распределенных вычислениях.

Заключение

Использование мощности нескольких графических процессоров может значительно ускорить время обучения модели PyTorch, а также обрабатывать более крупные наборы данных.

С этой целью PyTorch предлагает разработчикам несколько стратегий: параллелизм данных, когда данные выходят за пределы памяти графического процессора; параллелизм моделей, полезный для огромных моделей; и, наконец, конвейерный параллелизм, который лучше всего работает, когда модель и размер данных превышают объем памяти графического процессора.

Однако важно помнить, что эти стратегии имеют потенциальные ловушки, которые могут непреднамеренно привести к снижению производительности или узким местам. Следовательно, оценка специфики задачи и вдумчивое применение наиболее подходящего метода может оказаться решающим.

Переход на распределенные вычисления также может стать потенциальным решением для моделей и данных большого размера. Использование таких платформ, как Dask , Ray и Saturn Cloud , может предоставить дополнительные преимущества для более простой и организованной реализации.

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

Способность быстро переключаться между различными стратегиями в конфигурациях с несколькими графическими процессорами с использованием PyTorch быстро становится фундаментальным навыком в области глубокого обучения.

Понимание этих инструментов и методов, а также их компромиссов может дать значительные преимущества: от повышения производительности модели до эффективного управления ресурсами и затратами.