

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# SMDDP 집합 작업을 사용하도록 훈련 스크립트 조정
<a name="data-parallel-modify-sdp-select-framework"></a>

이 섹션에 제공된 훈련 스크립트 예시는 간소화되었으며 훈련 스크립트에서 SageMaker AI 분산형 데이터 병렬화(SMDDP) 라이브러리를 사용하는 데 필요한 변경 사항만 강조 표시합니다. SMDDP 라이브러리를 사용하여 분산 훈련 작업을 실행하는 방법을 보여주는 엔드 투 엔드 Jupyter 노트북 예제는 [Amazon SageMaker AI 데이터 병렬화 라이브러리 예시](distributed-data-parallel-v2-examples.md) 섹션을 참조하세요.

**Topics**
+ [PyTorch 훈련 스크립트에서 SMDDP 라이브러리 사용](data-parallel-modify-sdp-pt.md)
+ [PyTorch Lightning 훈련 스크립트에서 SMDDP 라이브러리 사용](data-parallel-modify-sdp-pt-lightning.md)
+ [TensorFlow 훈련 스크립트에서 SMDDP 라이브러리 사용(사용되지 않음)](data-parallel-modify-sdp-tf2.md)

# PyTorch 훈련 스크립트에서 SMDDP 라이브러리 사용
<a name="data-parallel-modify-sdp-pt"></a>

SageMaker AI 분산형 데이터 병렬화(SMDDP) 라이브러리 v1.4.0부터 이 라이브러리를 [PyTorch 분산형 패키지](https://pytorch.org/tutorials/beginner/dist_overview.html)의 백엔드 옵션으로 사용할 수 있습니다. SMDDP `AllReduce` 및 `AllGather` 집합 작업을 사용하려면 훈련 스크립트 시작 시 SMDDP 라이브러리를 가져와서 프로세스 그룹 초기화 중에 SMDDP를 PyTorch 분산 모듈의 백엔드로 설정하기만 하면 됩니다. 한 줄의 백엔드 사양을 사용하면 모든 기본 PyTorch 분산 모듈과 전체 훈련 스크립트를 변경하지 않을 수 있습니다. 다음 코드 조각은 SMDDP 라이브러리를 [PyTorch 분산 데이터 병렬(DDP)](https://pytorch.org/docs/stable/notes/ddp.html), [PyTorch 완전 샤딩 데이터 병렬(FSDP)](https://pytorch.org/docs/stable/fsdp.html), [DeepSpeed](https://github.com/microsoft/DeepSpeed) 및 [Megatron-DeepSpeed](https://github.com/microsoft/Megatron-DeepSpeed) 등 PyTorch 기반 분산 훈련 패키지의 백엔드로 사용하는 방법을 보여줍니다.

## PyTorch DDP 또는 FSDP의 경우
<a name="data-parallel-enable-for-ptddp-ptfsdp"></a>

다음과 같이 프로세스 그룹을 초기화합니다.

```
import torch.distributed as dist
import smdistributed.dataparallel.torch.torch_smddp

dist.init_process_group(backend="smddp")
```

**참고**  
(PyTorch DDP 작업에만 해당)`smddp` 백엔드는 현재 `torch.distributed.new_group()` API를 사용한 하위 프로세스 그룹 생성을 지원하지 않습니다. `smddp` 백엔드는 `NCCL` 및 `Gloo` 같은 다른 프로세스 그룹 백엔드와 동시에 사용할 수 없습니다.

## DeepSpeed 또는 Megatron-DeepSpeed의 경우
<a name="data-parallel-enable-for-deepspeed"></a>

다음과 같이 프로세스 그룹을 초기화합니다.

```
import deepspeed
import smdistributed.dataparallel.torch.torch_smddp

deepspeed.init_distributed(dist_backend="smddp")
```

**참고**  
[SageMaker Python SDK를 사용하여 SMDDP로 분산 훈련 작업 시작](data-parallel-use-api.md)의 `mpirun` 기반 런처(`smdistributed` 및 `pytorchddp`)와 함께 SMDDP `AllGather`를 사용하려면 훈련 스크립트에서 다음 환경 변수도 설정해야 합니다.  

```
export SMDATAPARALLEL_OPTIMIZE_SDP=true
```

PyTorch FSDP 훈련 스크립트 작성에 대한 일반적인 지침은 PyTorch 설명서의 [FSDP(Fully Sharded Data Parallel)를 사용한 고급 모델 훈련](https://pytorch.org/tutorials/intermediate/FSDP_adavnced_tutorial.html)을 참조하세요.

PyTorch DDP 훈련 스크립트 작성에 대한 일반 지침은 PyTorch 설명서의 [분산 데이터 병렬 시작하기](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html)를 참조하세요.

훈련 스크립트 조정을 완료한 후 [SageMaker Python SDK를 사용하여 SMDDP로 분산 훈련 작업 시작](data-parallel-use-api.md) 섹션으로 넘어갑니다.

# PyTorch Lightning 훈련 스크립트에서 SMDDP 라이브러리 사용
<a name="data-parallel-modify-sdp-pt-lightning"></a>

[PyTorch Lightning](https://pytorch-lightning.readthedocs.io/en/latest/starter/introduction.html) 훈련 스크립트를 가져와 SageMaker AI에서 분산형 데이터 병렬 훈련 작업을 실행하려는 경우, 훈련 스크립트를 최소한으로 변경하여 훈련 작업을 실행할 수 있습니다. 필요한 변경 사항에는 `smdistributed.dataparallel` 라이브러리의 PyTorch 모듈을 가져오고, SageMaker 훈련 도구 키트에서 사전 설정된 SageMaker AI 환경 변수를 수락하도록 PyTorch Lightning의 환경 변수를 설정하고, 프로세스 그룹 백엔드를 `"smddp"`로 설정하여 SMDDP 라이브러리를 활성화하는 작업이 포함됩니다. 자세히 알아보려면 코드 예제를 사용하여 단계를 세분화하는 다음 지침을 살펴보세요.

**참고**  
PyTorch Lightning 지원은 SageMaker AI 데이터 병렬 라이브러리 v1.5.0 이상에서 사용할 수 있습니다.

## PyTorch Lightning == v2.1.0 및 PyTorch == 2.0.1
<a name="smddp-pt-201-lightning-210"></a>

1. `pytorch_lightning` 라이브러리 및 `smdistributed.dataparallel.torch` 모듈을 가져옵니다.

   ```
   import lightning as pl
   import smdistributed.dataparallel.torch.torch_smddp
   ```

1. [LightningEnvironment](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.plugins.environments.LightningEnvironment.html)를 인스턴스화합니다.

   ```
   from lightning.fabric.plugins.environments.lightning import LightningEnvironment
   
   env = LightningEnvironment()
   env.world_size = lambda: int(os.environ["WORLD_SIZE"])
   env.global_rank = lambda: int(os.environ["RANK"])
   ```

1. **PyTorch DDP의 경우** - `process_group_backend`용 `"smddp"` 및 `accelerator`용 `"gpu"`를 사용하여 [DDPStrategy](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.strategies.DDPStrategy.html) 클래스의 객체를 생성하고 이를 [Trainer](https://pytorch-lightning.readthedocs.io/en/stable/common/trainer.html) 클래스에 전달합니다.

   ```
   import lightning as pl
   from lightning.pytorch.strategies import DDPStrategy
   
   ddp = DDPStrategy(
       cluster_environment=env, 
       process_group_backend="smddp", 
       accelerator="gpu"
   )
   
   trainer = pl.Trainer(
       max_epochs=200, 
       strategy=ddp, 
       devices=num_gpus, 
       num_nodes=num_nodes
   )
   ```

   **PyTorch FSDP의 경우** - `process_group_backend`용 `"smddp"` 및 `accelerator`용 `"gpu"`를 사용하여 [FSDPStrategy](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.strategies.FSDPStrategy.html) 클래스의 객체([래핑 정책](https://pytorch.org/docs/stable/fsdp.html) 선택)를 생성하고 이를 [Trainer](https://pytorch-lightning.readthedocs.io/en/stable/common/trainer.html) 클래스에 전달합니다.

   ```
   import lightning as pl
   from lightning.pytorch.strategies import FSDPStrategy
   
   from functools import partial
   from torch.distributed.fsdp.wrap import size_based_auto_wrap_policy
   
   policy = partial(
       size_based_auto_wrap_policy, 
       min_num_params=10000
   )
   
   fsdp = FSDPStrategy(
       auto_wrap_policy=policy,
       process_group_backend="smddp", 
       cluster_environment=env
   )
   
   trainer = pl.Trainer(
       max_epochs=200, 
       strategy=fsdp, 
       devices=num_gpus, 
       num_nodes=num_nodes
   )
   ```

훈련 스크립트 조정을 완료한 후 [SageMaker Python SDK를 사용하여 SMDDP로 분산 훈련 작업 시작](data-parallel-use-api.md) 섹션으로 넘어갑니다.

**참고**  
SageMaker AI PyTorch 예측기를 구문화하고 [SageMaker Python SDK를 사용하여 SMDDP로 분산 훈련 작업 시작](data-parallel-use-api.md)에서 훈련 작업 요청을 제출하는 경우, SageMaker AI PyTorch 훈련 컨테이너에 `pytorch-lightning` 및 `lightning-bolts`를 설치하도록 `requirements.txt`를 제공해야 합니다.  

```
# requirements.txt
pytorch-lightning
lightning-bolts
```
훈련 스크립트 및 작업 제출과 함께 `requirements.txt` 파일을 배치할 소스 디렉터리를 지정하는 방법에 대한 자세한 내용은 *Amazon SageMaker AI Python SDK 설명서*의 [서드 파티 라이브러리 사용](https://sagemaker.readthedocs.io/en/stable/frameworks/pytorch/using_pytorch.html#id12)을 참조하세요.

# TensorFlow 훈련 스크립트에서 SMDDP 라이브러리 사용(사용되지 않음)
<a name="data-parallel-modify-sdp-tf2"></a>

**중요**  
SMDDP 라이브러리는 TensorFlow에 대한 지원을 중단했으며 v2.11.0 이후 TensorFlow용 DLC에서 더 이상 사용할 수 없습니다. SMDDP 라이브러리가 설치된 이전 TensorFlow DLC를 찾으려면 [지원되는 프레임워크](distributed-data-parallel-support.md#distributed-data-parallel-supported-frameworks) 섹션을 참조하세요.

다음 단계에서는 TensorFlow 훈련 스크립트를 수정하여 SageMaker AI 분산형 데이터 병렬 라이브러리를 활용하는 방법을 보여줍니다.  

라이브러리 API는 Horovod API와 유사하도록 설계되었습니다. 라이브러리에서 TensorFlow에 제공하는 각 API에 대한 자세한 내용은 [SageMaker AI 분산형 데이터 병렬 TensorFlow API 설명서](https://sagemaker.readthedocs.io/en/stable/api/training/smd_data_parallel.html#api-documentation)를 참조하세요.

**참고**  
SageMaker AI 분산형 데이터 병렬은 `tf.keras` 모듈을 제외한 `tf` 핵심 모듈로 구성된 TensorFlow 훈련 스크립트에 맞게 조정할 수 있습니다. SageMaker AI 분산형 데이터 병렬에서는 Keras가 구현된 TensorFlow를 지원하지 않습니다.

**참고**  
SageMaker AI의 분산형 데이터 병렬화 라이브러리는 기본적으로 자동 혼합 정밀도(AMP)를 지원합니다. 훈련 스크립트를 프레임워크 수준에서 수정하는 것 외에는 AMP를 활성화하기 위한 추가 조치가 필요하지 않습니다. FP16에 그라디언트가 있는 경우, SageMaker AI 데이터 병렬화 라이브러리는 FP16에서 `AllReduce` 작업을 실행합니다. 훈련 스크립트에 AMP API를 구현하는 방법에 대한 자세한 정보는 다음 리소스를 참조하세요.  
*NVIDIA 딥 러닝성능 문서*의 [프레임워크 - TensorFlow](https://docs.nvidia.com/deeplearning/performance/mixed-precision-training/index.html#tensorflow)
*NVIDIA 개발자 문서*의 [딥 러닝을 위한 자동 혼합 정밀도](https://developer.nvidia.com/automatic-mixed-precision)
*TensorFlow 문서*의 [TensorFlow 혼합 정밀도 API](https://www.tensorflow.org/guide/mixed_precision)

1. 라이브러리의 TensorFlow 클라이언트를 가져와서 초기화합니다.

   ```
   import smdistributed.dataparallel.tensorflow as sdp 
   sdp.init()
   ```

1. `local_rank`을(를) 사용하여 각 GPU를 단일 `smdistributed.dataparallel` 프로세스에 고정합니다. 이는 주어진 노드 내 프로세스의 상대적 순위를 나타냅니다. `sdp.tensorflow.local_rank()` API는 장치의 로컬 순위를 제공합니다. 리더 노드는 순위 0이고 워커 노드는 순위 1, 2, 3 등입니다. 이는 다음 코드 블록에서 `sdp.local_rank()`로 간접 호출됩니다. `set_memory_growth`는 SageMaker AI 분산형과 직접적인 관련이 없지만 TensorFlow로 분산 훈련을 하려면 설정해야 합니다.

   ```
   gpus = tf.config.experimental.list_physical_devices('GPU')
   for gpu in gpus:
       tf.config.experimental.set_memory_growth(gpu, True)
   if gpus:
       tf.config.experimental.set_visible_devices(gpus[sdp.local_rank()], 'GPU')
   ```

1. 작업자 수를 기준으로 학습 속도를 조정하세요. `sdp.tensorflow.size()` API는 클러스터의 작업자 수를 제공합니다. 이는 다음 코드 블록에서 `sdp.size()`(으)로서 간접 호출됩니다.

   ```
   learning_rate = learning_rate * sdp.size()
   ```

1. 라이브러리의 `DistributedGradientTape`을(를) 사용하여 훈련 중에 `AllReduce` 작업을 최적화합니다. 이것이 `tf.GradientTape`을(를) 래핑합니다.  

   ```
   with tf.GradientTape() as tape:
         output = model(input)
         loss_value = loss(label, output)
       
   # SageMaker AI data parallel: Wrap tf.GradientTape with the library's DistributedGradientTape
   tape = sdp.DistributedGradientTape(tape)
   ```

1. 리더 노드(순위 0)에서 모든 작업자 노드(순위 1\$1n)로 초기 모델 변수를 브로드캐스트합니다. 이는 모든 작업자 순위에서 일관된 초기화를 보장하는 데 필요합니다. 모델 및 옵티마이저 변수를 초기화한 후 `sdp.tensorflow.broadcast_variables` API를 사용하세요. 이는 다음 코드 블록에서 `sdp.broadcast_variables()`(으)로서 간접 호출됩니다.

   ```
   sdp.broadcast_variables(model.variables, root_rank=0)
   sdp.broadcast_variables(opt.variables(), root_rank=0)
   ```

1. 마지막으로 리더 노드에만 체크포인트를 저장하도록 스크립트를 수정합니다. 리더 노드에는 동기화된 모델이 있습니다. 이렇게 하면 워커 노드가 체크포인트를 덮어쓰거나 체크포인트가 손상되는 것도 방지할 수 있습니다.

   ```
   if sdp.rank() == 0:
       checkpoint.save(checkpoint_dir)
   ```

다음은 라이브러리를 사용한 분산 훈련을 위한 TensorFlow 훈련 스크립트 예제입니다.

```
import tensorflow as tf

# SageMaker AI data parallel: Import the library TF API
import smdistributed.dataparallel.tensorflow as sdp

# SageMaker AI data parallel: Initialize the library
sdp.init()

gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
    tf.config.experimental.set_memory_growth(gpu, True)
if gpus:
    # SageMaker AI data parallel: Pin GPUs to a single library process
    tf.config.experimental.set_visible_devices(gpus[sdp.local_rank()], 'GPU')

# Prepare Dataset
dataset = tf.data.Dataset.from_tensor_slices(...)

# Define Model
mnist_model = tf.keras.Sequential(...)
loss = tf.losses.SparseCategoricalCrossentropy()

# SageMaker AI data parallel: Scale Learning Rate
# LR for 8 node run : 0.000125
# LR for single node run : 0.001
opt = tf.optimizers.Adam(0.000125 * sdp.size())

@tf.function
def training_step(images, labels, first_batch):
    with tf.GradientTape() as tape:
        probs = mnist_model(images, training=True)
        loss_value = loss(labels, probs)

    # SageMaker AI data parallel: Wrap tf.GradientTape with the library's DistributedGradientTape
    tape = sdp.DistributedGradientTape(tape)

    grads = tape.gradient(loss_value, mnist_model.trainable_variables)
    opt.apply_gradients(zip(grads, mnist_model.trainable_variables))

    if first_batch:
       # SageMaker AI data parallel: Broadcast model and optimizer variables
       sdp.broadcast_variables(mnist_model.variables, root_rank=0)
       sdp.broadcast_variables(opt.variables(), root_rank=0)

    return loss_value

...

# SageMaker AI data parallel: Save checkpoints only from master node.
if sdp.rank() == 0:
    checkpoint.save(checkpoint_dir)
```

훈련 스크립트 조정을 완료한 후 [SageMaker Python SDK를 사용하여 SMDDP로 분산 훈련 작업 시작](data-parallel-use-api.md) 섹션으로 넘어갑니다.