

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用模型平行化進行 FP16 訓練
<a name="model-parallel-extended-features-pytorch-fp16"></a>

若要進行 FP16 訓練，請套用下列修改至訓練指令碼與估算器。

**注意**  
此功能適用 SageMaker 模型平行化程式庫 v1.10.0 及更高版本的 PyTorch。

**調整 PyTorch 訓練指令碼**

1. 使用 [smdistributed.modelparallel.torch.model\$1creation()](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.model_creation) 內容管理器來包裝模型。

   ```
   # fp16_training_script.py
   
   import torch
   import smdistributed.modelparallel.torch as smp
   
   with smp.model_creation(
       dtype=torch.float16 if args.fp16 else torch.get_default_dtype()
   ):
       model = ...
   ```
**提示**  
如果您使用張量平行處理，請新增 `tensor_parallelism=smp.tp_size() > 1` 至 `smp.model_creation` 內容管理器。新增此行也有助於自動偵測張量平行處理是否已啟動。  

   ```
   with smp.model_creation(
       ... ,
       tensor_parallelism=smp.tp_size() > 1
   ):
       model = ...
   ```

1. 當您使用 `smdistributed.modelparallel.torch.DistributedOptimizer` 包裝最佳化工具時，請設定 `static_loss_scaling` 或 `dynamic_loss_scaling` 引數。依預設，`static_loss_scaling` 設定為 `1.0`，`dynamic_loss_scaling` 設定為 `False`。如果設定 `dynamic_loss_scale=True`，您可以透過 `dynamic_loss_args` 引數饋送動態損失縮放選項作為字典。在多數情況，我們建議您使用動態損失縮放與預設選項。有關最佳化工具包裝函式的更多資訊、選項與範例，請參閱 [smdistributed.modelparallel.torch.DistributedOptimizer](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed-modelparallel-torch-distributedoptimizer) API。

   下列程式碼範例示範使用 FP16 訓練的動態損失縮放來包裝 `Adadelta` 最佳化工具物件。

   ```
   optimizer = torch.optim.Adadelta(...)
   optimizer = smp.DistributedOptimizer(
       optimizer,
       static_loss_scale=None,
       dynamic_loss_scale=True,
       dynamic_loss_args={
           "scale_window": 1000,
           "min_scale": 1,
           "delayed_shift": 2
       }
   )
   ```

**設定 SageMaker PyTorch 估算器**

在建立 SageMaker PyTorch 估算器物件時，新增 FP16 參數 (`"fp16"`) 至模型平行化的發佈組態。如需模型平行化設定參數的完整清單，請參閱 [`smdistributed` 的參數](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#parameters-for-smdistributed)。

```
from sagemaker.pytorch import PyTorch

smp_options = {
    "enabled": True,
    "parameters":  {
        "microbatches":  4,
        "pipeline_parallel_degree":  2,
        "tensor_parallel_degree":  2,
        ...,

        "fp16": True
    }
}

fp16_estimator = PyTorch(
    entry_point="fp16_training_script.py", # Specify your train script
    ...,

    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": {...}
    }
)

fp16_estimator.fit(...)
```

當 FP16 訓練開始時，模型與最佳化工具分別由 `FP16_Module` 與 `FP16_Optimizer` 包裝，這些都是 [Apex utils](https://nvidia.github.io/apex/fp16_utils.html#apex-fp16-utils) 的修改 `smdistributed` 版本。`FP16_Module` 將模型轉換為 FP16 dtype，並在 FP16 處理向前傳遞。

**提示**  
您可以在 `optimizer.step` 之前透過呼叫 `clip_master_grads` 來套用漸層剪輯。  

```
optimizer.clip_master_grads(max_norm)     # max_norm(float or int): max norm of the gradients
```

**提示**  
當使用 `torch.optim.lr_scheduler` 與 FP16 訓練時，您需要傳遞 `optimizer.optimizer` 至 LR 排程器，而非最佳化工具。請參閱以下範例程式碼。  

```
from torch.optim.lr_scheduler import StepLR

scheduler = StepLR(
    optimizer.optimizer if smp.state.cfg.fp16 else optimizer,
    step_size=1,
    gamma=args.gamma
)
```