

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

# 微調
<a name="model-parallel-core-features-v2-fine-tuning"></a>

微調是持續訓練預先訓練模型的程序，以改善特定使用案例的效能。

微調完全符合單一 GPU 的小型模型，或完全符合 CPU 上 8 個模型複本的模型，非常簡單。它不需要對一般 FSDP 訓練進行特殊變更。在大於此值的模型領域中，您需要考慮使用延遲參數初始化功能，這可能很棘手。

為了解決此問題，SMP 程式庫會在其中一個排名上載入完整模型，而其餘排名則會在中繼裝置上建立具有空權重的模型。然後，PyTorch FSDP 會使用 `init_weights` 函數初始化非零排名的權重，並將所有排名的權重與 `sync_module_states` 設為 `True` 的第 0 排名權重同步。下列程式碼片段說明如何在訓練指令碼中設定程式碼片段。

```
import torch.distributed as dist
from transformers import AutoModelForCasalLM
from accelerate import init_empty_weights
from torch.sagemaker.delayed_param import DelayedParamIniter

if dist.get_rank() == 0:
    model = AutoModelForCasalLM.from_pretrained(..., low_cpu_mem_usage=True)
else:
    with init_empty_weights():
        model = AutoModelForCasalLM.from_config(AutoConfig.from_pretrained(...))
    delayed_initer = DelayedParamIniter(model)

model = FSDP(
    model,
    ...,
    sync_module_states=True,
    param_init_fn=delayed_initer.get_param_init_fn() if dist.get_rank() > 0 else None
)
```

## 使用 SMP 張量平行化微調預先訓練的 Hugging Face Transformer 模型
<a name="model-parallel-core-features-v2-tensor-parallelism-fine-tuning-hf-transformer-with-tp"></a>

本節討論兩種使用案例的載入轉換器模型：微調小型轉換器模型和微調大型轉換器模型。對於沒有延遲參數初始化的小型模型，請先使用 `torch.sagemaker.transform` API 包裝模型，再使用 PyTorch FSDP 包裝模型。

```
import functools
from transformers import AutoModelForCausalLM
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy
from torch.sagemaker import transform

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf", low_cpu_mem_usage=True)

# Transform model while loading state dictionary from rank 0.
tp_model = transform(model, load_state_dict_from_rank0=True)

# Wrap with FSDP.
model = FSDP(
    tp_model, 
    ...
    sync_module_states=True,
)
```

對於較大的模型，上述方法會導致 CPU 記憶體用盡。我們建議您使用延遲參數初始化，以避免此類 CPU 記憶體問題。在此情況下，您可以套用 `torch.sagemaker.transform` API 和 `torch.sagemaker.delayed_param.DelayedParamIniter` API，如下列程式碼範例所示。

```
from transformers import AutoModelForCausalLM
from torch.sagemaker import transform
from torch.sagemaker.delayed_param import DelayedParamIniter

# Create one instance of model without delayed param
# on CPU, on one rank.
if dist.get_rank() == 0:
    model = AutoModelForCasalLM.from_pretrained(...,low_cpu_mem_usage=True)
else:
    with init_empty_weights():
        model = AutoModelForCasalLM.from_config(AutoConfig.from_pretrained(...))

# Transform model while loading state dictionary from rank 0
model = transform(model, load_state_dict_from_rank0=True)

if dist.get_rank() != 0: # For fine-tuning, delayed parameter on non-zero ranks
    delayed_initer = DelayedParamIniter(model)
else:
    delayed_initer = None

with (
    delayed_initer.validate_params_and_buffers_inited() if delayed_initer else nullcontext()
):
    # Wrap the model with FSDP
    model = FSDP(
        model, 
        ..., 
        sync_module_states=True,
        param_init_fn=delayed_initer.get_param_init_fn() if delayed_initer else None
    )
```