Распределенное обучение в PyTorch с помощью HuggingFace Accelerate

HuggingFace Accelerate позволяет запускать один и тот же скрипт обучения PyTorch на CPU, одной или нескольких GPU, в многоузловых конфигурациях, на TPU или платформе Apple MPS, добавив всего несколько строк кода.

Hermes OpenClaw Средний Скопировали: 0
1 ресурс

Что понадобится

  • Требуются зависимости Python: accelerate, torch и transformers.
  • Accelerate устанавливается через pip.
  • DDP: torch.distributed.run (встроено)
  • DeepSpeed: deepspeed (pip install deepspeed)
  • FSDP встроен в PyTorch версии 1.12 и выше.
  • Для работы с Megatron требуется специальная настройка.
  • Требуется версия Accelerate 1.11.0 или выше.

Как применить

Используйте Accelerate, если нужно самое простое распределенное обучение, один скрипт для любого оборудования, экосистема HuggingFace, гибкость при использовании DDP, DeepSpeed, FSDP и Megatron, или быстрое прототипирование.

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

Поддерживает один скрипт, который работает на любом оборудовании.

Хорошо подходит, если вы используете экосистему HuggingFace.

Обеспечивает гибкость при работе с DDP, DeepSpeed, FSDP и Megatron.

Подходит для быстрого прототипирования.

Используйте альтернативные решения, если вам нужны их специализированные возможности.

Выберите PyTorch Lightning, если вам нужны коллбэки и высокоуровневые абстракции.

Выберите Ray Train для оркестрации в многоузловых средах и настройки гиперпараметров.

Выберите DeepSpeed напрямую для управления API и расширенных функций.

Выберите чистый DDP для максимального контроля при минимальных абстракциях.

Работает на CPU, хотя и медленно.

Работает на одной GPU.

Много-GPU работает с DDP (по умолчанию), DeepSpeed или FSDP.

Многоузловая работа поддерживает DDP, DeepSpeed, FSDP и Megatron.

Поддерживается TPU.

Поддерживается Apple MPS.

Установите Accelerate, чтобы начать работу с быстрого старта.

Установка осуществляется через pip.

pip install accelerate

Преобразуйте свой скрипт обучения PyTorch, добавив четыре строки: создайте объект Accelerator, вызовите метод prepare для модели, оптимизатора и загрузчика данных, а также замените loss.backward на accelerator.backward.

import torch
+ from accelerate import Accelerator

+ accelerator = Accelerator()

  model = torch.nn.Transformer()
  optimizer = torch.optim.Adam(model.parameters())
  dataloader = torch.utils.data.DataLoader(dataset)

+ model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)

  for batch in dataloader:
      optimizer.zero_grad()
      loss = model(batch)
-     loss.backward()
+     accelerator.backward(loss)
      optimizer.step()

Запустите преобразованный скрипт обучения одной командой запуска.

accelerate launch train.py

Начните с существующего скрипта обучения PyTorch на одной GPU в качестве базы.

# train.py
import torch

model = torch.nn.Linear(10, 2).to('cuda')
optimizer = torch.optim.Adam(model.parameters())
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32)

for epoch in range(10):
    for batch in dataloader:
        batch = batch.to('cuda')
        optimizer.zero_grad()
        loss = model(batch).mean()
        loss.backward()
        optimizer.step()

С помощью Accelerate добавьте четыре строки: импортируйте и создавайте экземпляр Accelerator, подготовьте модель, оптимизатор и загрузчик данных, затем используйте accelerator.backward; явные вызовы .to('cuda') больше не нужны, так как размещение устройства происходит автоматически после вызова prepare.

# train.py
import torch
from accelerate import Accelerator  # +1

accelerator = Accelerator()  # +2

model = torch.nn.Linear(10, 2)
optimizer = torch.optim.Adam(model.parameters())
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32)

model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)  # +3

for epoch in range(10):
    for batch in dataloader:
        # No .to('cuda') needed - automatic!
        optimizer.zero_grad()
        loss = model(batch).mean()
        accelerator.backward(loss)  # +4
        optimizer.step()

Запустите интерактивную команду конфигурации для настройки вашей среды.

accelerate config

Ответьте на интерактивные вопросы о вашей конфигурации.

Выберите тип используемой машины: одна или несколько GPU, TPU или CPU.

Укажите количество машин; по умолчанию — 1.

Выберите режим смешанной точности: нет, fp16, bf16 или fp8.

Выберите, использовать ли DeepSpeed: нет или да.

Затем запустите обучение; одна и та же команда запуска работает на любой конфигурации, включая одну GPU, много-GPU с указанием числа процессов и многоузловую среду с указанием номера узла и IP-адреса главного процесса.

# Single GPU
accelerate launch train.py

# Multi-GPU (8 GPUs)
accelerate launch --multi_gpu --num_processes 8 train.py

# Multi-node
accelerate launch --multi_gpu --num_processes 16 \
  --num_machines 2 --machine_rank 0 \
  --main_process_ip $MASTER_ADDR \
  train.py

Режим смешанной точности включается через конструктор Accelerator.

Установите параметр mixed_precision в значение fp16 (с масштабированием градиентов), bf16 (без масштабирования, более стабильно) или fp8 (для GPU H100 и новее); контекст autocast является необязательным и применяется автоматически.

from accelerate import Accelerator

# FP16 (with gradient scaling)
accelerator = Accelerator(mixed_precision='fp16')

# BF16 (no scaling, more stable)
accelerator = Accelerator(mixed_precision='bf16')

# FP8 (H100+)
accelerator = Accelerator(mixed_precision='fp8')

model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)

# Everything else is automatic!
for batch in dataloader:
    with accelerator.autocast():  # Optional, done automatically
        loss = model(batch)
    accelerator.backward(loss)

Включите DeepSpeed ZeRO-2, создав объект DeepSpeedPlugin и передав его в Accelerator.

Передавайте экземпляр DeepSpeedPlugin, а не сырой словарь; плагин задает этап ZeRO, устройство для выгрузки оптимизатора и количество шагов накопления градиентов.

from accelerate import Accelerator, DeepSpeedPlugin

deepspeed_plugin = DeepSpeedPlugin(
    zero_stage=2,                     # ZeRO-2
    offload_optimizer_device="none",  # or "cpu" to offload
    gradient_accumulation_steps=4,
)

accelerator = Accelerator(
    mixed_precision='bf16',
    deepspeed_plugin=deepspeed_plugin,  # DeepSpeedPlugin instance (or dict[str, DeepSpeedPlugin])
)

# Same code as before!
model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)

В качестве альтернативы укажите плагину полный файл конфигурации DeepSpeed в формате JSON, например ds_config.json.

from accelerate import Accelerator, DeepSpeedPlugin

# hf_ds_config accepts a path to a DeepSpeed config JSON (or a dict)
deepspeed_plugin = DeepSpeedPlugin(hf_ds_config="ds_config.json")
accelerator = Accelerator(mixed_precision='bf16', deepspeed_plugin=deepspeed_plugin)

Файл ds_config.json представляет собой сырую конфигурацию DeepSpeed, передаваемую через плагин, а не через команду запуска.

{
    "fp16": {"enabled": false},
    "bf16": {"enabled": true},
    "zero_optimization": {
        "stage": 2,
        "offload_optimizer": {"device": "cpu"},
        "allgather_bucket_size": 5e8,
        "reduce_bucket_size": 5e8
    }
}

Как вариант, настройте DeepSpeed через интерактивный конфигуратор, выбрав DeepSpeed и режим ZeRO-2.

accelerate config
# Select: DeepSpeed → ZeRO-2
# This writes an accelerate YAML config (default: ~/.cache/huggingface/accelerate/default_config.yaml)

Запустите обучение в обычном режиме или укажите параметр config-file на конкретный файл конфигурации accelerate в формате YAML; команда запуска ожидает именно такой файл, а не сырой JSON-конфиг DeepSpeed.

# Uses the default accelerate config written by `accelerate config`
accelerate launch train.py

# Or point at a specific accelerate YAML
accelerate launch --config_file accelerate_deepspeed.yaml train.py

Режим FSDP (Fully Sharded Data Parallel) включается с помощью плагина FullyShardedDataParallelPlugin.

Соберите плагин с такой стратегией шардирования, как FULL_SHARD (эквивалент ZeRO-3), политикой автоматического обёртывания и настройкой выгрузки на CPU, затем передайте его в Accelerator.

from accelerate import Accelerator, FullyShardedDataParallelPlugin

fsdp_plugin = FullyShardedDataParallelPlugin(
    sharding_strategy="FULL_SHARD",  # ZeRO-3 equivalent
    auto_wrap_policy="transformer_based_wrap",  # valid: transformer_based_wrap | size_based_wrap | no_wrap
    cpu_offload=False
)

accelerator = Accelerator(
    mixed_precision='bf16',
    fsdp_plugin=fsdp_plugin
)

model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)

Как вариант, включите режим FSDP через интерактивный конфигуратор, выбрав FSDP, режим Full Shard и вариант выгрузки на CPU.

accelerate config
# Select: FSDP → Full Shard → No CPU Offload

Накопление градиентов настраивается в Accelerator и применяется с помощью менеджера контекста accumulate вокруг цикла обучения.

Установите параметр gradient_accumulation_steps в Accelerator, затем оберните тело цикла в менеджер контекста accumulate — он и будет отвечать за накопление.

from accelerate import Accelerator

accelerator = Accelerator(gradient_accumulation_steps=4)

model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)

for batch in dataloader:
    with accelerator.accumulate(model):  # Handles accumulation
        optimizer.zero_grad()
        loss = model(batch)
        accelerator.backward(loss)
        optimizer.step()

Избегайте ручного перемещения батчей на устройство при распределённом обучении.

Неправильное размещение устройств — распространённая проблема.

Не вызывайте функцию batch.to('cuda') вручную; Accelerate автоматически управляет размещением устройств после вызова prepare.

# WRONG
batch = batch.to('cuda')

# CORRECT
# Accelerate handles it automatically after prepare()

Неработающий механизм накопления градиентов — частая проблема.

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

# CORRECT
with accelerator.accumulate(model):
    optimizer.zero_grad()
    accelerator.backward(loss)
    optimizer.step()

Проблемы с сохранением точек восстановления при распределённом обучении — распространённая область сложностей.

Используйте методы Accelerator: сохраняйте состояние только на главном процессе и загружайте его на всех остальных процессах.

# Save only on main process
if accelerator.is_main_process:
    accelerator.save_state('checkpoint/')

# Load on all processes
accelerator.load_state('checkpoint/')

Получение разных результатов при использовании FSDP — частая проблема.

Чтобы гарантировать одинаковые случайные числа, установите одинаковое значение семени с помощью функции set_seed.

from accelerate.utils import set_seed
set_seed(42)

DDP: torch.distributed.run (встроенный)

DeepSpeed: deepspeed (pip install deepspeed)

Ссылки

Источник: nousresearch/hermes-agent и участники проекта. Лицензия: MIT.

Copyright (c) 2025 Nous Research

Перевод и редакционная адаптация: ClawCases.

>Ресурсы

>Похожие юзкейсы

Разработка

Арбитр разрешения конфликтов слияния агентов

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

Hermes Средний
Автоматизация Разработка

Автономное управление проектами с помощью подагентов

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

OpenClaw Средний
Соцсети Автоматизация

Ежедневная сводка с Reddit

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

OpenClaw Средний

>Ещё на этом уровне: Средний