

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

# 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\~n)로 초기 모델 변수를 브로드캐스트합니다. 이는 모든 작업자 순위에서 일관된 초기화를 보장하는 데 필요합니다. 모델 및 옵티마이저 변수를 초기화한 후 `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) 섹션으로 넘어갑니다.