

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Memodifikasi skrip TensorFlow pelatihan
<a name="model-parallel-customize-training-script-tf"></a>

Di bagian ini, Anda mempelajari cara memodifikasi skrip TensorFlow pelatihan untuk mengonfigurasi pustaka paralelisme SageMaker model untuk partisi otomatis dan partisi manual. Pilihan contoh ini juga mencakup contoh yang terintegrasi dengan Horovod untuk model hibrida dan paralelisme data.

**catatan**  
Untuk menemukan TensorFlow versi mana yang didukung oleh pustaka, lihat[Kerangka Kerja yang Didukung dan Wilayah AWS](distributed-model-parallel-support.md).

Modifikasi yang diperlukan yang harus Anda buat pada skrip pelatihan Anda untuk menggunakan perpustakaan tercantum di[Pemisahan otomatis dengan TensorFlow](#model-parallel-customize-training-script-tf-23).

Untuk mempelajari cara memodifikasi skrip pelatihan Anda untuk menggunakan model hibrida dan paralelisme data dengan Horovod, lihat. [Pemisahan otomatis dengan TensorFlow dan Horovod untuk model hibrida dan paralelisme data](#model-parallel-customize-training-script-tf-2.3)

Jika Anda ingin menggunakan partisi manual, tinjau juga. [Pemisahan manual dengan TensorFlow](#model-parallel-customize-training-script-tf-manual) 

Topik berikut menunjukkan contoh skrip pelatihan yang dapat Anda gunakan untuk mengonfigurasi pustaka SageMaker paralelisme model untuk model partisi otomatis dan partisi manual. TensorFlow 

**catatan**  
Auto-partitioning diaktifkan secara default. Kecuali ditentukan lain, contoh skrip menggunakan partisi otomatis.

**Topics**
+ [Pemisahan otomatis dengan TensorFlow](#model-parallel-customize-training-script-tf-23)
+ [Pemisahan otomatis dengan TensorFlow dan Horovod untuk model hibrida dan paralelisme data](#model-parallel-customize-training-script-tf-2.3)
+ [Pemisahan manual dengan TensorFlow](#model-parallel-customize-training-script-tf-manual)
+ [Fitur kerangka kerja yang tidak didukung](#model-parallel-tf-unsupported-features)

## Pemisahan otomatis dengan TensorFlow
<a name="model-parallel-customize-training-script-tf-23"></a>

Perubahan skrip pelatihan berikut diperlukan untuk menjalankan TensorFlow model dengan pustaka SageMaker paralelisme model:

1. Impor dan inisialisasi perpustakaan dengan [`smp.init()`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init).

1. Tentukan model Keras dengan mewarisi dari al [`smp.DistributedModel`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_tensorflow.html) ih-alih kelas Model Keras. Kembalikan output model dari metode panggilan `smp.DistributedModel` objek. Perhatikan bahwa setiap tensor yang dikembalikan dari metode panggilan akan disiarkan di seluruh perangkat model-paralel, menimbulkan overhead komunikasi, sehingga tensor apa pun yang tidak diperlukan di luar metode panggilan (seperti aktivasi perantara) tidak boleh dikembalikan.

1. Tetapkan `drop_remainder=True` dalam `tf.Dataset.batch()` metode. Ini untuk memastikan bahwa ukuran batch selalu dapat dibagi dengan jumlah mikrobatch.

1. Benih operasi acak dalam pipeline data menggunakan`smp.dp_rank()`, misalnya, `shuffle(ds, seed=smp.dp_rank())` untuk memastikan konsistensi sampel data di seluruh GPU yang menyimpan partisi model yang berbeda.

1. Letakkan logika maju dan mundur dalam fungsi langkah dan hiasi dengan`smp.step`.

1. Lakukan pasca-pemrosesan pada output di seluruh mikrobatch menggunakan [`StepOutput`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput) metode seperti. `reduce_mean` [`smp.step`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init)Fungsi harus memiliki nilai pengembalian yang tergantung pada output dari`smp.DistributedModel`.

1. Jika ada langkah evaluasi, letakkan logika maju di dalam fungsi yang `smp.step` dihias dan pasca-proses output menggunakan [`StepOutput` API. ](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput)

Untuk mempelajari lebih lanjut tentang SageMaker API pustaka paralelisme model, lihat dokumentasi [ API. ](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) 

Skrip Python berikut adalah contoh skrip pelatihan setelah perubahan dilakukan.

```
import tensorflow as tf

# smdistributed: Import TF2.x API
import smdistributed.modelparallel.tensorflow as smp

# smdistributed: Initialize
smp.init()

# Download and load MNIST dataset.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    "MNIST-data-%d" % smp.rank()
)
x_train, x_test = x_train / 255.0, x_test / 255.0

# Add a channels dimension
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

# smdistributed: If needed, seed the shuffle with smp.dp_rank(), and drop_remainder
# in batching to make sure batch size is always divisible by number of microbatches
train_ds = (
    tf.data.Dataset.from_tensor_slices((x_train, y_train))
    .shuffle(10000, seed=smp.dp_rank())
    .batch(256, drop_remainder=True)
)

# smdistributed: Define smp.DistributedModel the same way as Keras sub-classing API 
class MyModel(smp.DistributedModel):
    def __init__(self):
        super(MyModel, self).__init__()
        # define layers

    def call(self, x, training=None):
        # define forward pass and return the model output

model = MyModel()

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name="train_accuracy")

# smdistributed: Define smp.step. Return any tensors needed outside
@smp.step
def get_grads(images, labels):
    predictions = model(images, training=True)
    loss = loss_object(labels, predictions)

    grads = optimizer.get_gradients(loss, model.trainable_variables)
    return grads, loss, predictions


@tf.function
def train_step(images, labels):
    gradients, loss, predictions = get_grads(images, labels)

    # smdistributed: Accumulate the gradients across microbatches
    gradients = [g.accumulate() for g in gradients]
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    # smdistributed: Merge predictions and average losses across microbatches
    train_accuracy(labels, predictions.merge())
    return loss.reduce_mean()


for epoch in range(5):
    # Reset the metrics at the start of the next epoch
    train_accuracy.reset_states()
    for images, labels in train_ds:
        loss = train_step(images, labels)
    accuracy = train_accuracy.result()
```

Jika Anda selesai menyiapkan skrip pelatihan Anda, lanjutkan ke[Langkah 2: Luncurkan Pekerjaan Pelatihan Menggunakan SageMaker Python SDK](model-parallel-sm-sdk.md). Jika Anda ingin menjalankan pekerjaan pelatihan paralel model hibrida dan data, lanjutkan ke bagian berikutnya.

## Pemisahan otomatis dengan TensorFlow dan Horovod untuk model hibrida dan paralelisme data
<a name="model-parallel-customize-training-script-tf-2.3"></a>

Anda dapat menggunakan pustaka paralelisme SageMaker model dengan Horovod untuk model hibrida dan paralelisme data. Untuk membaca lebih lanjut tentang bagaimana perpustakaan membagi model untuk paralelisme hibrida, lihat. [Paralelisme pipa (tersedia untuk PyTorch dan) TensorFlow](model-parallel-intro.md#model-parallel-intro-pp)

Pada langkah ini, kami fokus pada cara memodifikasi skrip pelatihan Anda untuk mengadaptasi perpustakaan paralelisme SageMaker model.

Untuk mengatur skrip pelatihan Anda dengan benar untuk mengambil konfigurasi paralelisme hibrida yang akan Anda atur[Langkah 2: Luncurkan Pekerjaan Pelatihan Menggunakan SageMaker Python SDK](model-parallel-sm-sdk.md), gunakan fungsi pembantu perpustakaan, `smp.dp_rank()` dan`smp.mp_rank()`, yang secara otomatis mendeteksi peringkat paralel data dan peringkat paralel model masing-masing. 

Untuk menemukan semua primitif MPI yang didukung pustaka, lihat Dasar-Das [ ar MPI ](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#mpi-basics) dalam dokumentasi SageMaker Python SDK. 

Perubahan yang diperlukan dalam skrip adalah:
+ Menambahkan `hvd.allreduce`
+ Variabel penyiaran setelah batch pertama, seperti yang dipersyaratkan oleh Horovod
+ Menyemai operasi and/or sharding shuffling di pipeline data dengan. `smp.dp_rank()`

**catatan**  
Saat Anda menggunakan Horovod, Anda tidak boleh langsung memanggil skrip `hvd.init` pelatihan Anda. Sebagai gantinya, Anda harus mengatur `"horovod"` ke `True` dalam `modelparallel` parameter SageMaker Python SDK di[Langkah 2: Luncurkan Pekerjaan Pelatihan Menggunakan SageMaker Python SDK](model-parallel-sm-sdk.md). Hal ini memungkinkan pustaka untuk menginisialisasi Horovod secara internal berdasarkan penetapan perangkat partisi model. Menelep `hvd.init()` on langsung di skrip pelatihan Anda dapat menyebabkan masalah.

**catatan**  
Menggunakan `hvd.DistributedOptimizer` API secara langsung di skrip pelatihan Anda dapat mengakibatkan kinerja dan kecepatan pelatihan yang buruk, karena API secara implisit menempatkan `AllReduce` operasi di dalamnya`smp.step`. Kami menyarankan Anda untuk menggunakan pustaka paralelisme model dengan Horovod dengan langsung memanggil `hvd.allreduce` setelah panggilan `accumulate()` atau `reduce_mean()` pada gradien yang dikembalikan dari`smp.step`, seperti yang akan ditunjukkan dalam contoh berikut.

Untuk mempelajari lebih lanjut tentang SageMaker API pustaka paralelisme model, lihat dokumentasi [ API. ](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html)

```
import tensorflow as tf
import horovod.tensorflow as hvd

# smdistributed: Import TF2.x API 
import smdistributed.modelparallel.tensorflow as smp

# smdistributed: Initialize
smp.init()

# Download and load MNIST dataset.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    "MNIST-data-%d" % smp.rank()
)
x_train, x_test = x_train / 255.0, x_test / 255.0

# Add a channels dimension
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

# smdistributed: Seed the shuffle with smp.dp_rank(), and drop_remainder
# in batching to make sure batch size is always divisible by number of microbatches
train_ds = (
    tf.data.Dataset.from_tensor_slices((x_train, y_train))
    .shuffle(10000, seed=smp.dp_rank())
    .batch(256, drop_remainder=True)
)

# smdistributed: Define smp.DistributedModel the same way as Keras sub-classing API 
class MyModel(smp.DistributedModel):
    def __init__(self):
        super(MyModel, self).__init__()
        # define layers

    def call(self, x, training=None):
        # define forward pass and return model outputs


model = MyModel()

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name="train_accuracy")

# smdistributed: Define smp.step. Return any tensors needed outside
@smp.step
def get_grads(images, labels):
    predictions = model(images, training=True)
    loss = loss_object(labels, predictions)

    grads = optimizer.get_gradients(loss, model.trainable_variables)
    return grads, loss, predictions


@tf.function
def train_step(images, labels, first_batch):
    gradients, loss, predictions = get_grads(images, labels)

    # smdistributed: Accumulate the gradients across microbatches
    # Horovod: AllReduce the accumulated gradients
    gradients = [hvd.allreduce(g.accumulate()) for g in gradients]
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    # Horovod: Broadcast the variables after first batch 
    if first_batch:
        hvd.broadcast_variables(model.variables, root_rank=0)
        hvd.broadcast_variables(optimizer.variables(), root_rank=0)

    # smdistributed: Merge predictions across microbatches
    train_accuracy(labels, predictions.merge())
    return loss.reduce_mean()


for epoch in range(5):
    # Reset the metrics at the start of the next epoch
    train_accuracy.reset_states()

    for batch, (images, labels) in enumerate(train_ds):
        loss = train_step(images, labels, tf.constant(batch == 0))
```

## Pemisahan manual dengan TensorFlow
<a name="model-parallel-customize-training-script-tf-manual"></a>

Gunakan manajer `smp.partition` konteks untuk menempatkan operasi di partisi tertentu. Setiap operasi yang tidak ditempatkan dalam `smp.partition` konteks apa pun ditempatkan di`default_partition`. Untuk mempelajari lebih lanjut tentang SageMaker API pustaka paralelisme model, lihat dokumentasi [ API. ](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) 

```
import tensorflow as tf

# smdistributed: Import TF2.x API.
import smdistributed.modelparallel.tensorflow as smp

# smdistributed: Initialize
smp.init()

# Download and load MNIST dataset.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    "MNIST-data-%d" % smp.rank()
)
x_train, x_test = x_train / 255.0, x_test / 255.0

# Add a channels dimension
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

# smdistributed: If needed, seed the shuffle with smp.dp_rank(), and drop_remainder
# in batching to make sure batch size is always divisible by number of microbatches.
train_ds = (
    tf.data.Dataset.from_tensor_slices((x_train, y_train))
    .shuffle(10000, seed=smp.dp_rank())
    .batch(256, drop_remainder=True)
)

# smdistributed: Define smp.DistributedModel the same way as Keras sub-classing API.
class MyModel(smp.DistributedModel):
    def __init__(self):
         # define layers

    def call(self, x):
        with smp.partition(0):
            x = self.layer0(x)
        with smp.partition(1):
            return self.layer1(x)


model = MyModel()

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name="train_accuracy")

# smdistributed: Define smp.step. Return any tensors needed outside
@smp.step
def get_grads(images, labels):
    predictions = model(images, training=True)
    loss = loss_object(labels, predictions)

    grads = optimizer.get_gradients(loss, model.trainable_variables)
    return grads, loss, predictions


@tf.function
def train_step(images, labels):
    gradients, loss, predictions = get_grads(images, labels)

    # smdistributed: Accumulate the gradients across microbatches
    gradients = [g.accumulate() for g in gradients]
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    # smdistributed: Merge predictions and average losses across microbatches
    train_accuracy(labels, predictions.merge())
    return loss.reduce_mean()


for epoch in range(5):
    # Reset the metrics at the start of the next epoch
    train_accuracy.reset_states()
    for images, labels in train_ds:
        loss = train_step(images, labels)
    accuracy = train_accuracy.result()
```

## Fitur kerangka kerja yang tidak didukung
<a name="model-parallel-tf-unsupported-features"></a>

Fitur- TensorFlow fitur berikut tidak didukung oleh perpustakaan:
+ `tf.GradientTape()`Saat ini tidak didukung. Anda dapat menggunakan `Optimizer.get_gradients()` atau sebagai `Optimizer.compute_gradients()` gantinya untuk menghitung gradien.
+ `tf.train.Checkpoint.restore()`API saat ini tidak didukung. Untuk checkpointing, gunakan sebagai `smp.CheckpointManager` gantinya, yang menyediakan API dan fungsionalitas yang sama. Perhatikan bahwa pemulihan pos pemeriksaan `smp.CheckpointManager` harus dilakukan setelah langkah pertama.