

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# ファインチューニング
<a name="model-parallel-core-features-v2-fine-tuning"></a>

ファインチューニングとは、事前トレーニング済みのモデルを継続的にトレーニングし、特定のユースケースに対するパフォーマンスを向上させていくプロセスです。

モデルが小さく、1 つの GPU に完全に収まる場合や、モデルの 8 つのコピーが CPU に完全に収まるような場合は、ファインチューニングは簡単です。通常の FSDP トレーニングを別段変える必要はありません。モデルがそれより大きくなると、パラメータの遅延初期化機能の使用を検討する必要があり、これが厄介な場合があります。

この問題に対処するため、SMP ライブラリは、いずれか 1 つのランクに完全なモデルをロードし、残りのランクではメタデバイス上に空の重みを持つモデルを作成します。その後、PyTorch FSDP が `init_weights` 関数を使用して非ゼロのランクで重みを初期化し、`sync_module_states` を `True` に設定して、すべてのランクの重みをゼロ番ランクの重みと同期させます。次のコードスニペットは、トレーニングスクリプトでの設定方法を示しています。

```
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
)
```

## 事前トレーニング済みの Hugging Face Transformer モデルの SMP テンソル並列処理によるファインチューニング
<a name="model-parallel-core-features-v2-tensor-parallelism-fine-tuning-hf-transformer-with-tp"></a>

このセクションでは、小さな Transformer モデルのファインチューニングと大きな Transformer モデルのファインチューニングという 2 つのユースケースを挙げて、Transformer モデルのロードについて説明します。パラメータの遅延初期化を行わない小さなモデルの場合は、モデルを `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
    )
```