Руководство по обучению распределенного GPU (пакет SDK версии 2)

ОБЛАСТЬ ПРИМЕНЕНИЯ: Пакет SDK для Python azure-ai-ml версии 2 (current)

Дополнительные сведения об использовании распределенного кода обучения GPU см. в Машинное обучение Azure. Эта статья поможет вам запустить существующий код распределенного обучения, а также предлагает советы и примеры для каждой платформы:

  • Интерфейс передачи сообщений (MPI)
    • Horovod
    • Переменные среды из Open MPI
  • PyTorch
  • TensorFlow
  • Ускорение обучения с поддержкой GPU с помощью InfiniBand.

Необходимые компоненты

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

Совет

Если вы не знаете, какой тип параллелизма следует использовать, более 90 % времени, в течение которого следует использовать параллелизм распределенных данных.

MPI

Машинное обучение Azure предлагает Задание MPI для запуска заданного количества процессов в каждом узле. Машинное обучение Azure создает полную команду запуска MPI (mpirun) за кулисами. Вы не можете предоставить собственные полные команды head-node-launcher, такие как mpirun или DeepSpeed launcher.

Совет

В базовом образе Docker, используемом заданием MPI Машинного обучения Azure, должна быть установлена библиотека MPI. Открытие MPI включается во все базовые образы gpu Машинное обучение Azure. При использовании пользовательского образа Docker вы несете ответственность за то, чтобы он включал в себя библиотеку MPI. Рекомендуется использовать Open MPI, но вы можете также использовать другую реализацию MPI, например Intel MPI. Машинное обучение Azure также предоставляет курируемые среды для популярных платформ.

Чтобы выполнить распределенное обучение с помощью MPI, сделайте следующее.

  1. Используйте среду Машинное обучение Azure с предпочтительной платформой глубокого обучения и MPI. Машинное обучение Azure предоставляет курируемые среды для популярных платформ. Или создайте настраиваемую среду с предпочтительной платформой глубокого обучения и MPI.
  2. command Определение с instance_countпомощью . instance_count должно быть равно количеству GPU на узел для каждого запуска процесса или иметь значение 1 (по умолчанию) для запуска на узел, если сценарий пользователя отвечает за запуск процессов на узел.
  3. distribution Используйте параметр command для указания параметровMpiDistribution.
from azure.ai.ml import command, MpiDistribution

job = command(
    code="./src",  # local path where the code is stored
    command="python train.py --epochs ${{inputs.epochs}}",
    inputs={"epochs": 1},
    environment="AzureML-tensorflow-2.7-ubuntu20.04-py38-cuda11-gpu@latest",
    compute="gpu-cluster",
    instance_count=2,
    distribution=MpiDistribution(process_count_per_instance=2),
    display_name="tensorflow-mnist-distributed-horovod-example"
    # experiment_name: tensorflow-mnist-distributed-horovod-example
    # description: Train a basic neural network with TensorFlow on the MNIST dataset, distributed via Horovod.
)

Horovod

Используйте конфигурацию задания MPI для распределенного обучения с помощью платформы глубокого обучения Horovod.

Убедитесь, что в вашем коде применены следующие советы.

  • Код обучения правильно инструментирован с Horovod перед добавлением Машинное обучение Azure частей.
  • Среда Машинное обучение Azure содержит Horovod и MPI. Среды GPU PyTorch и TensorFlow предварительно настроены с помощью Horovod и его зависимостей.
  • Создайте нужный command дистрибутив.

Пример Horovod

Переменные среды из Open MPI

При выполнении заданий MPI с открытыми образами MPI можно использовать следующие переменные среды для каждого запущенного процесса:

  1. OMPI_COMM_WORLD_RANK: ранг процесса
  2. OMPI_COMM_WORLD_SIZE: размер мира
  3. AZ_BATCH_MASTER_NODE: основной адрес с портом, MASTER_ADDR:MASTER_PORT
  4. OMPI_COMM_WORLD_LOCAL_RANK: локальный ранг процесса на узле
  5. OMPI_COMM_WORLD_LOCAL_SIZE: количество процессов на узле

Совет

Несмотря на имя, переменная OMPI_COMM_WORLD_NODE_RANK среды не соответствует NODE_RANK. Чтобы использовать режим per-node-launcher, задайте process_count_per_node=1 и используйте OMPI_COMM_WORLD_RANK в качестве NODE_RANK.

PyTorch

Машинное обучение Azure поддерживает выполнение распределенных заданий с помощью собственных возможностей распределенного обучения PyTorch (torch.distributed).

Совет

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

инициализация группы процессов;

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

torch.distributed.init_process_group(backend='nccl', init_method='env://', ...)

Наиболее распространенные внутренние серверы подключений: mpi, nccl и gloo. Для обучения nccl на основе GPU рекомендуется повысить производительность и по возможности использовать их.

init_method указывает, как процессы могут обнаружить друг друга, как они инициализируются и проверяют группу процессов, используя внутренний сервер подключений. По умолчанию, если init_method он не указан, PyTorch использует метод инициализации переменной среды (env://). init_method— рекомендуемый метод инициализации для использования в коде обучения для запуска распределенного PyTorch на Машинное обучение Azure. PyTorch ищет следующие переменные среды для инициализации:

  • MASTER_ADDR: IP-адрес компьютера, на котором размещен процесс с рангом 0
  • MASTER_PORT: бесплатный порт на компьютере, на котором размещен процесс с рангом 0
  • WORLD_SIZE: общее количество процессов. Должно быть равно общему количеству устройств (GPU), используемым для распределенного обучения
  • RANK: (глобальный) ранг текущего процесса. Возможные значения равны 0 (размер мира — 1)

Дополнительные сведения об инициализации группы процессов см. в документации по PyTorch.

Многие приложения также нуждаются в следующих переменных среды:

  • LOCAL_RANK: локальный (относительный) ранг процесса в узле. Возможные значения: от 0 до (число процессов на узле — 1). Эта информация полезна, так как многие операции, такие как подготовка данных, должны выполняться только один раз на узел, обычно на local_rank = 0.
  • NODE_RANK: ранг узла для обучения с несколькими узлами. Возможные значения: от 0 до (общее число узлов — 1).

Не нужно использовать служебную программу запуска, например torch.distributed.launch. Чтобы отправить распределенное задание PyTorch, сделайте следующее.

  1. Укажите скрипт обучения и аргументы.
  2. command Создайте и укажите тип как PyTorch и process_count_per_instance в параметреdistribution. process_count_per_instance соответствует общему количеству процессов, которые вы хотите выполнить для задания. process_count_per_instance обычно должно быть равно # of GPUs per node. Если process_count_per_instance не указано, Машинное обучение Azure по умолчанию запускает один процесс на узел.

Машинное обучение Azure задает MASTER_ADDRпеременные среды и MASTER_PORTNODE_RANKWORLD_SIZEпеременные среды на каждом узле и задает переменные уровня RANK процесса и LOCAL_RANK среды.

from azure.ai.ml import command
from azure.ai.ml.entities import Data
from azure.ai.ml import Input
from azure.ai.ml import Output
from azure.ai.ml.constants import AssetTypes

# === Note on path ===
# can be can be a local path or a cloud path. AzureML supports https://`, `abfss://`, `wasbs://` and `azureml://` URIs.
# Local paths are automatically uploaded to the default datastore in the cloud.
# More details on supported paths: https://docs.microsoft.com/azure/machine-learning/how-to-read-write-data-v2#supported-paths

inputs = {
    "cifar": Input(
        type=AssetTypes.URI_FOLDER, path=returned_job.outputs.cifar.path
    ),  # path="azureml:azureml_stoic_cartoon_wgb3lgvgky_output_data_cifar:1"), #path="azureml://datastores/workspaceblobstore/paths/azureml/stoic_cartoon_wgb3lgvgky/cifar/"),
    "epoch": 10,
    "batchsize": 64,
    "workers": 2,
    "lr": 0.01,
    "momen": 0.9,
    "prtfreq": 200,
    "output": "./outputs",
}

from azure.ai.ml.entities import ResourceConfiguration

job = command(
    code="./src",  # local path where the code is stored
    command="python train.py --data-dir ${{inputs.cifar}} --epochs ${{inputs.epoch}} --batch-size ${{inputs.batchsize}} --workers ${{inputs.workers}} --learning-rate ${{inputs.lr}} --momentum ${{inputs.momen}} --print-freq ${{inputs.prtfreq}} --model-dir ${{inputs.output}}",
    inputs=inputs,
    environment="azureml-acpt-pytorch-2.0-cuda11.7:26",
    instance_count=2,  # In this, only 2 node cluster was created.
    distribution={
        "type": "PyTorch",
        # set process count to the number of gpus per node
        # NC6s_v3 has only 1 GPU
        "process_count_per_instance": 1,
    },
)
job.resources = ResourceConfiguration(
    instance_type="Standard_NC6s_v3", instance_count=2
)  # Serverless compute resources

Пример Pytorch

DeepSpeed

поддерживается Машинное обучение AzureDeepSpeed как гражданин первого класса для запуска распределенных заданий с почти линейной масштабируемостью с точки зрения:

  • Увеличение размера модели
  • Увеличение числа gpu

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

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

Пример DeepSpeed

TensorFlow

Если вы используете собственный распределенный TensorFlow в коде обучения, например API TensorFlow 2.xtf.distribute.Strategy, можно запустить распределенное задание с помощью Машинное обучение Azure с помощью distribution параметров или TensorFlowDistribution объекта.

# create the command
job = command(
    code="./src",  # local path where the code is stored
    command="python main.py --epochs ${{inputs.epochs}} --model-dir ${{inputs.model_dir}}",
    inputs={"epochs": 1, "model_dir": "outputs/keras-model"},
    environment="AzureML-tensorflow-2.4-ubuntu18.04-py37-cuda11-gpu@latest",
    compute="cpu-cluster",
    instance_count=2,
    # distribution = {"type": "mpi", "process_count_per_instance": 1},
    # distribution={
    #     "type": "tensorflow",
    #     "parameter_server_count": 1,  # for legacy TensorFlow 1.x
    #     "worker_count": 2,
    #     "added_property": 7,
    # },
    # distribution = {
    #        "type": "pytorch",
    #        "process_count_per_instance": 4,
    #        "additional_prop": {"nested_prop": 3},
    #    },
    display_name="tensorflow-mnist-distributed-example"
    # experiment_name: tensorflow-mnist-distributed-example
    # description: Train a basic neural network with TensorFlow on the MNIST dataset, distributed via TensorFlow.
)

# can also set the distribution in a separate step and using the typed objects instead of a dict
job.distribution = TensorFlowDistribution(worker_count=2)

Если в скрипте обучения используется стратегия сервера параметров для распределенного обучения, например для устаревшего TensorFlow 1.x, необходимо также указать количество серверов параметров, используемых в задании, внутри distribution параметра.command Например, в приведенном выше примере "parameter_server_count" : 1 и "worker_count": 2.

TF_CONFIG

В TensorFlow для обучения на нескольких компьютерах требуется переменная среды TF_CONFIG. Для заданий TensorFlow Машинное обучение Azure настраивает и задает TF_CONFIG переменную соответствующим образом для каждой рабочей роли перед выполнением скрипта обучения.

Вы можете получить доступ TF_CONFIG из скрипта обучения, если вам нужно: os.environ['TF_CONFIG']

Пример TF_CONFIG , заданный на главном рабочем узле:

TF_CONFIG='{
    "cluster": {
        "worker": ["host0:2222", "host1:2222"]
    },
    "task": {"type": "worker", "index": 0},
    "environment": "cloud"
}'

Пример TensorFlow

Ускорение распределенного обучения с поддержкой GPU с помощью InfiniBand

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

InfiniBand может играть важную роль в обеспечении такого линейного масштабирования. InfiniBand обеспечивает связь на уровне GPU между узлами в кластере с низкой задержкой. Для работы с InfiniBand требуется специализированное оборудование. Некоторые серии виртуальных машин Azure, в частности серии NC, ND и H, теперь поддерживают виртуальные машины RDMA с поддержкой SR-IOV и InfiniBand. Эти виртуальные машины обмениваются данными по сети InfiniBand с низкой задержкой и высокой пропускной способностью, которая гораздо быстрее, чем сеть Ethernet. SR-IOV для InfiniBand обеспечивает почти производительность без операционной системы для любой библиотеки MPI (MPI используется многими распределенными платформами обучения и инструментами, включая программное обеспечение NCCL NVIDIA).) Эти номера SKU предназначены для удовлетворения потребностей вычислительных ресурсов с ускорением GPU в машинном обучении. Дополнительные сведения см. в разделе Accelerating Distributed Training in Azure Machine Learning with SR-IOV (Ускорение распределенного обучения в Машинном обучении Azure с помощью SR-IOV).

Как правило, номера SKU виртуальных машин с именем "r" содержат требуемое оборудование InfiniBand, и они без "r" обычно не выполняются. ("r" — это ссылка на RDMA, которая обозначает удаленный прямой доступ к памяти.) Например, номер SKU Standard_NC24rs_v3 виртуальной машины включен с поддержкой InfiniBand, но номер SKU Standard_NC24s_v3 не является. Помимо возможностей InfiniBand, спецификации между этими двумя номерами SKU в значительной степени одинаковы. Оба имеют 24 ядра, 448 ГБ ОЗУ, 4 GPU одного номера SKU и т. д. Дополнительные сведения об RDMA и о номерах SKU виртуальных машин, поддерживающих InfiniBand.

Предупреждение

Номер SKU Standard_NC24r компьютера старшего поколения включен с поддержкой RDMA, но он не содержит аппаратного обеспечения SR-IOV, необходимого для InfiniBand.

При создании AmlCompute кластера одного из этих размеров RDMA с поддержкой InfiniBand образ ОС поставляется с драйвером Mellanox OFED, необходимым для включения предварительно установленного и предварительно настроенного InfiniBand.

Следующие шаги