

# 直接選好最適化 (DPO)
<a name="nova-dpo-smtj"></a>

## 概要:
<a name="nova-dpo-smtj-overview"></a>

直接選好最適化 (DPO) は、ペア比較データを使用して基盤モデルをファインチューニングし、モデル出力を人間のプリファレンスに合わせる調節手法です。強化学習方法とは異なり、DPO は、どの応答がより望ましいかという人間のフィードバックに基づいてモデルの動作を直接最適化し、より安定したスケーラブルなアプローチを提供します。

**DPO を使用する理由**

基盤モデルは、事実としては正しいものの、特定のユーザーニーズ、組織の価値観、または安全要件に合致しない出力を生成する場合があります。DPO は、以下を可能にすることでこれに対処します。
+ 希望する動作パターンに合わせてモデルをファインチューニングする
+ 不適切または有害な出力を減らす
+ モデルレスポンスをブランドボイスおよびコミュニケーションガイドラインに合わせる
+ ドメインエキスパートのフィードバックに基づいてレスポンスの品質を向上させる
+ 望ましいレスポンスパターンによる安全ガードレールを実装する

**DPO の仕組み**

DPO は、サンプルのペアを使用し、人間の評価者が 2 つのレスポンスのどちらが好ましいかを示します。モデルは、望ましくないレスポンスを最小限に抑えながら、望ましいレスポンスを生成する可能性を最大化することを学習します。

**DPO を使用する場合**

以下のシナリオで、DPO を使用します。
+ 特定の人間のプリファレンスに合わせて調整する必要がある主観的な出力を最適化する場合
+ モデルのトーン、スタイル、またはコンテンツ特性を調整する場合
+ ユーザーのフィードバックとエラー分析に基づいて、的を絞った改善を行う場合
+ さまざまなユースケースで一貫した出力品質を維持する場合
+ プリファレンスデータのみを使用して、無報酬の強化学習でトレーニングする場合

## サポートされているモデルと手法
<a name="nova-dpo-smtj-models"></a>

DPO は、フルパラメータファインチューニングと LoRA (Low-Rank Adaptation) の両方をサポートしています。


| モデル | サポートされる入力 | インスタンスタイプ | 推奨インスタンスカウント | 許可されるインスタンス数 | 
| --- | --- | --- | --- | --- | 
| Amazon Nova Micro | テキスト | ml.p5.48xlarge | 2 | 2、4、8 | 
| Amazon Nova Lite | テキスト、イメージ | ml.p5.48xlarge | 4 | 2、4、8、16 | 
| Amazon Nova Pro | テキスト、イメージ | ml.p5.48xlarge | 6 | 6、12、24 | 

**トレーニングアプローチ**
+ **フルランク DPO**: すべてのモデルパラメータを更新します。調整品質は向上する可能性がありますが、より多くのコンピューティングリソースが必要になり、より大きなモデルが生成されます。
+ **LoRA DPO**: 軽量アダプターを使用してパラメータ効率の高いファインチューニングを行います。優れたアライメント品質を維持しながら、より小さな出力モデルでより効率的なトレーニングとデプロイを提供します。

ほとんどのユースケースでは、LoRA アプローチは十分な適応機能を提供し、効率を大幅に向上させます。

## データ形式
<a name="nova-dpo-smtj-data"></a>

DPO トレーニングデータは SFT と同じ形式に従いますが、最後のアシスタントターンには `preferred` および `non-preferred` ラベルのプリファレンスペアを含める必要があります。

### 基本構造
<a name="nova-dpo-smtj-data-structure"></a>

最後のアシスタントターンでは、`content` の代わりに `candidates` 配列を使用します。

```
{
  "role": "assistant",
  "candidates": [
    {
      "content": [
        {
          "text": "This is the preferred response."
        }
      ],
      "preferenceLabel": "preferred"
    },
    {
      "content": [
        {
          "text": "This is the non-preferred response."
        }
      ],
      "preferenceLabel": "non-preferred"
    }
  ]
}
```

### 完全なテキストの例
<a name="nova-dpo-smtj-data-text-example"></a>

```
{
  "schemaVersion": "bedrock-conversation-2024",
  "system": [
    {
      "text": "You are a helpful assistant."
    }
  ],
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "text": "What is the capital of France?"
        }
      ]
    },
    {
      "role": "assistant",
      "content": [
        {
          "text": "The capital of France is Paris."
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "text": "Tell me more about it."
        }
      ]
    },
    {
      "role": "assistant",
      "candidates": [
        {
          "content": [
            {
              "text": "Paris is the capital and largest city of France, known for the Eiffel Tower, world-class museums like the Louvre, and its rich cultural heritage."
            }
          ],
          "preferenceLabel": "preferred"
        },
        {
          "content": [
            {
              "text": "Paris is a city in France."
            }
          ],
          "preferenceLabel": "non-preferred"
        }
      ]
    }
  ]
}
```

### イメージを使用した例
<a name="nova-dpo-smtj-data-image-example"></a>

```
{
  "schemaVersion": "bedrock-conversation-2024",
  "system": [
    {
      "text": "You are a helpful assistant."
    }
  ],
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "text": "Describe this image."
        },
        {
          "image": {
            "format": "jpeg",
            "source": {
              "s3Location": {
                "uri": "s3://your-bucket/your-path/image.jpg",
                "bucketOwner": "your-aws-account-id"
              }
            }
          }
        }
      ]
    },
    {
      "role": "assistant",
      "candidates": [
        {
          "content": [
            {
              "text": "The image shows a detailed description with relevant context and observations."
            }
          ],
          "preferenceLabel": "preferred"
        },
        {
          "content": [
            {
              "text": "This is a picture."
            }
          ],
          "preferenceLabel": "non-preferred"
        }
      ]
    }
  ]
}
```

### データセット要件
<a name="nova-dpo-smtj-data-requirements"></a>
+ **形式**: トレーニング用の単一の JSONL ファイル、検証用の単一の JSONL ファイル (オプション)
+ **最小サイズ**: 効果的なトレーニングに推奨されるプリファレンスペアは 1,000 個です
+ **品質**: 高品質のプリファレンスデータにより、より効果的な結果が得られます
+ **その他の制約**: SFT と同じ。詳細については、「データセットの制約」を参照してください。

**データをアップロードする**

```
aws s3 cp /path/to/training-data/ s3://your-bucket/train/ --recursive
aws s3 cp /path/to/validation-data/ s3://your-bucket/val/ --recursive
```

## レシピ設定
<a name="nova-dpo-smtj-recipe"></a>

### 一般的な実行設定
<a name="nova-dpo-smtj-recipe-run"></a>

```
run:
  name: "my-dpo-run"
  model_type: "amazon.nova-lite-v1:0:300k"
  model_name_or_path: "nova-lite/prod"
  replicas: 4
```


| パラメータ | 説明 | 
| --- | --- | 
| name | トレーニングジョブのわかりやすい名前 | 
| model\$1type | Nova モデルバリアント (変更しないでください) | 
| model\$1name\$1or\$1path | ベースモデルパス (変更しないでください) | 
| replicas | 分散トレーニング用のコンピューティングインスタンスの数 | 

### トレーニング設定
<a name="nova-dpo-smtj-recipe-training"></a>

```
training_config:
  max_length: 16384
  global_batch_size: 32

  trainer:
    max_epochs: 3

  model:
    hidden_dropout: 0.0
    attention_dropout: 0.0
    ffn_dropout: 0.0
```


| パラメータ | 説明 | Range | 
| --- | --- | --- | 
| max\$1length | トークンの最大シーケンス長 | 1024～32768 | 
| global\$1batch\$1size | オプティマイザーステップあたりのサンプル数 | Micro/Lite/Pro: 16、32、64、128。Micro/Lite: 256 | 
| max\$1epochs | データセットに対する学習回数 | 最小: 1 | 
| hidden\$1dropout | 隠れ状態に対するドロップアウト率 | 0.0–1.0 | 
| attention\$1dropout | 注意重みに対するドロップアウト率 | 0.0–1.0 | 
| ffn\$1dropout | フィードフォワード層に対するドロップアウト率 | 0.0–1.0 | 

### オプティマイザー設定
<a name="nova-dpo-smtj-recipe-optimizer"></a>

```
model:
  optim:
    lr: 1e-5
    name: distributed_fused_adam
    adam_w_mode: true
    eps: 1e-08
    weight_decay: 0.0
    betas:
      - 0.9
      - 0.999
    sched:
      warmup_steps: 10
      constant_steps: 0
      min_lr: 1e-6
```


| パラメータ | 説明 | Range | 
| --- | --- | --- | 
| lr | 学習率 | 0～1 (通常は 1e-6～1e-4) | 
| weight\$1decay | L2 正則化の強度 | 0.0–1.0 | 
| warmup\$1steps | 学習率を徐々に増やすステップの数 | 0～20 | 
| min\$1lr | 減衰終了時の最小学習率 | 0～1 (< lr である必要があります) | 

### DPO 固有の設定
<a name="nova-dpo-smtj-recipe-dpo"></a>

```
model:
  dpo_cfg:
    beta: 0.1
```


| パラメータ | 説明 | Range | 
| --- | --- | --- | 
| beta | トレーニングデータに適合することと元のモデルに近い状態を保つこととのバランス | 0.001–0.5 | 
+ **高いベータ値 (0.1)**: 参照モデルの動作は保持されますが、プリファレンスの学習が遅くなる可能性があります
+ **低いベータ値 (0.01～0.05)**: より積極的なプリファレンス学習ですが、参照から逸脱するリスクがあります

**推奨事項**:「`beta: 0.1`」から始めて、プリファレンス学習が不十分だと思われる場合はベータ値を下げて調整します。

### LoRA PEFT 設定
<a name="nova-dpo-smtj-recipe-lora"></a>

```
model:
  peft:
    peft_scheme: "lora"
    lora_tuning:
      loraplus_lr_ratio: 64.0
      alpha: 32
      adapter_dropout: 0.01
```


| パラメータ | 説明 | 許可される値 | 
| --- | --- | --- | 
| peft\$1scheme | ファインチューニング方法 | "lora" または null (フルランク) | 
| alpha | LoRA 重みのスケーリング係数 | 32、64、96、128、160、192 | 
| loraplus\$1lr\$1ratio | LoRA\$1 学習レートのスケーリング係数 | 0.0–100.0 | 
| adapter\$1dropout | LoRA パラメータの正規化 | 0.0–1.0 | 

## トレーニングジョブを開始する
<a name="nova-dpo-smtj-start"></a>

**コンテナイメージ**

```
708977205387.dkr.ecr.us-east-1.amazonaws.com/nova-fine-tune-repo:SM-TJ-DPO-latest
```

**コードの例**

```
from sagemaker.pytorch import PyTorch
from sagemaker.inputs import TrainingInput

instance_type = "ml.p5.48xlarge"
instance_count = 4

image_uri = "708977205387.dkr.ecr.us-east-1.amazonaws.com/nova-fine-tune-repo:SM-TJ-DPO-latest"

recipe_overrides = {
    "training_config": {
        "trainer": {"max_epochs": 2},
        "model": {
            "dpo_cfg": {"beta": 0.1},
            "peft": {
                "peft_scheme": "lora",
                "lora_tuning": {
                    "loraplus_lr_ratio": 64.0,
                    "alpha": 32,
                    "adapter_dropout": 0.01,
                },
            },
        },
    },
}

estimator = PyTorch(
    output_path=f"s3://{bucket_name}/{job_name}",
    base_job_name=job_name,
    role=role,
    instance_count=instance_count,
    instance_type=instance_type,
    training_recipe="fine-tuning/nova/nova_lite_p5_gpu_lora_dpo",
    recipe_overrides=recipe_overrides,
    max_run=18000,
    sagemaker_session=sagemaker_session,
    image_uri=image_uri,
    disable_profiler=True,
    debugger_hook_config=False,
)

train_input = TrainingInput(
    s3_data=train_dataset_s3_path,
    distribution="FullyReplicated",
    s3_data_type="Converse",
)

val_input = TrainingInput(
    s3_data=val_dataset_s3_path,
    distribution="FullyReplicated",
    s3_data_type="Converse",
)

estimator.fit(inputs={"train": train_input, "validation": val_input}, wait=True)
```

## モデルをデプロイする
<a name="nova-dpo-smtj-deploy"></a>

トレーニングが完了したら、カスタムモデルインポート機能を使用して、カスタマイズされたモデルを Amazon Bedrock にデプロイします。モデルは、プロビジョニングされたスループットとオンデマンド推論の両方をサポートしています。LoRA トレーニング済みモデルは、オンデマンド推論をサポートします。

デプロイの手順については、[カスタマイズされたモデルをデプロイする方法](deploy-custom-model.md)を参照してください。

## 制限事項
<a name="nova-dpo-smtj-limitations"></a>
+ **入力モダリティ**: DPO はテキストとイメージのみを受け入れます。動画入力はサポートされていません。
+ **出力モダリティ**: テキストのみ
+ **プリファレンスペア**: アシスタントの最終ターンには、`preferred` ラベルと `non-preferred` ラベルを持つ 2 つの候補のみが含まれている必要があります
+ **イメージ制限**: コンテンツブロックあたり最大 10 イメージ
+ **混合モダリティ**: 同じトレーニングジョブでテキスト、イメージ、動画を組み合わせることはできません