# Smol-Course

## Docs

- [スモールコース](https://huggingface.co/learn/smol-course/ja/README.md)
- [ビジョン言語モデル](https://huggingface.co/learn/smol-course/ja/unit5/1.md)
- [VLMファインチューニング](https://huggingface.co/learn/smol-course/ja/unit5/3.md)
- [ビジュアル言語モデル](https://huggingface.co/learn/smol-course/ja/unit5/2.md)
- [🤗 smol-courseへようこそ](https://huggingface.co/learn/smol-course/ja/unit0/1.md)
- [評価](https://huggingface.co/learn/smol-course/ja/unit4/1.md)
- [カスタムドメイン評価](https://huggingface.co/learn/smol-course/ja/unit4/3.md)
- [自動ベンチマーク](https://huggingface.co/learn/smol-course/ja/unit4/2.md)
- [選好の整合](https://huggingface.co/learn/smol-course/ja/unit2/1.md)
- [ORPOの理解](https://huggingface.co/learn/smol-course/ja/unit2/3.md)
- [DPOの理解](https://huggingface.co/learn/smol-course/ja/unit2/2.md)
- [合成データセット](https://huggingface.co/learn/smol-course/ja/unit6/1.md)
- [嗜好データセットの生成](https://huggingface.co/learn/smol-course/ja/unit6/3.md)
- [インストラクションデータセットの生成](https://huggingface.co/learn/smol-course/ja/unit6/2.md)
- [インストラクションチューニング](https://huggingface.co/learn/smol-course/ja/unit1/1.md)
- [教師あり微調整](https://huggingface.co/learn/smol-course/ja/unit1/3.md)
- [チャットテンプレート](https://huggingface.co/learn/smol-course/ja/unit1/2.md)
- [パラメータ効率の良い微調整 (PEFT)](https://huggingface.co/learn/smol-course/ja/unit3/1.md)
- [プロンプトチューニング](https://huggingface.co/learn/smol-course/ja/unit3/3.md)
- [LoRA (低ランク適応)](https://huggingface.co/learn/smol-course/ja/unit3/2.md)

### スモールコース
https://huggingface.co/learn/smol-course/ja/README.md

# スモールコース

これは、特定のユースケースに合わせて言語モデルを調整するための実践的なコースです。ほとんどのローカルマシンで実行できるため、言語モデルの調整を始めるのに便利です。GPUの要件は最小限で、有料サービスは必要ありません。このコースは[SmolLM2](https://github.com/huggingface/smollm/tree/main)シリーズのモデルに基づいていますが、ここで学んだスキルを大規模なモデルや他の小型言語モデルに転用することができます。

<a href="http://hf.co/join/discord">
<img src="https://img.shields.io/badge/Discord-7289DA?&logo=discord&logoColor=white"/>
</a>

<div style="background: linear-gradient(to right, #e0f7fa, #e1bee7, orange); padding: 20px; border-radius: 5px; margin-bottom: 20px; color: purple;">
    <h2>参加は無料で、今すぐ始められます！</h2>
    <p>このコースはオープンでピアレビューされています。コースに参加するには、<strong>プルリクエストを開く</strong>ことで、あなたの作業をレビューに提出してください。以下の手順に従ってください：</p>
    <ol>
        <li>リポジトリをフォークします <a href="https://github.com/huggingface/smol-course/fork">こちら</a></li>
        <li>資料を読み、変更を加え、演習を行い、自分の例を追加します。</li>
        <li>december_2024ブランチでプルリクエストを開きます</li>
        <li>レビューを受けてマージされます</li>
    </ol>
    <p>これにより、学習を助け、常に改善されるコミュニティ主導のコースを構築することができます。</p>
</div>

このプロセスについては、この[ディスカッションスレッド](https://github.com/huggingface/smol-course/discussions/2#discussion-7602932)で議論できます。

## コース概要

このコースは、小型言語モデルを使用した実践的なアプローチを提供し、初期のトレーニングから本番展開までをカバーします。

| モジュール | 説明 | ステータス | リリース日 |
|--------|-------------|---------|--------------|
| [インストラクションチューニング](./1_instruction_tuning) | 教師あり微調整、チャットテンプレート、および基本的な指示に従う方法を学びます | ✅ 準備完了 | 2024年12月3日 |
| [選好整合](./2_preference_alignment) | DPOおよびORPO技術を探求し、人間の選好にモデルを整合させる方法を学びます | ✅ 準備完了  | 2024年12月6日 |
| [パラメータ効率の良い微調整](./3_parameter_efficient_finetuning) | LoRA、プロンプトチューニング、および効率的な適応方法を学びます | ✅ 準備完了 | 2024年12月9日 |
| [評価](./4_evaluation) | 自動ベンチマークを使用し、カスタムドメイン評価を作成する方法を学びます | ✅ 準備完了 | 2024年12月13日 |
| [ビジョン言語モデル](./5_vision_language_models) | マルチモーダルモデルをビジョン言語タスクに適応させる方法を学びます | ✅ 準備完了 | 2024年12月16日 |
| [合成データセット](./6_synthetic_datasets) | トレーニング用の合成データセットを作成し、検証する方法を学びます | ✅ 準備完了 | 2024年12月20日 |
| [推論](./7_inference) | モデルを効率的に推論する方法を学びます | [🚧 作業中](https://github.com/huggingface/smol-course/pull/150) | 2025年1月8日 |
| [エージェント](./8_agents) | 自分のエージェントAIを構築する方法を学びます | ✅ 準備完了 | 2025年1月13日 ||
| キャップストーンプロジェクト | 学んだことを使ってリーダーボードを登りましょう！ | [🚧 作業中](https://github.com/huggingface/smol-course/pull/97) | 2025年1月10日 |

## なぜ小型言語モデルなのか？

大規模な言語モデルは印象的な能力を示していますが、しばしば多くの計算リソースを必要とし、特定のアプリケーションには過剰な場合があります。小型言語モデルは、ドメイン固有のアプリケーションに対していくつかの利点を提供します：

- **効率性**：トレーニングと展開に必要な計算リソースが大幅に少ない
- **カスタマイズ**：特定のドメインに簡単に微調整および適応可能
- **制御**：モデルの動作をよりよく理解し、制御できる
- **コスト**：トレーニングと推論の運用コストが低い
- **プライバシー**：データを外部APIに送信せずにローカルで実行可能
- **グリーンテクノロジー**：リソースの効率的な使用を推進し、炭素排出量を削減
- **学術研究の容易さ**：最先端のLLMを使用した学術研究のための簡単なスターターを提供し、物流の制約を減らす

## 前提条件

開始する前に、以下を確認してください：
- 機械学習と自然言語処理の基本的な理解
- Python、PyTorch、および`transformers`ライブラリに精通していること
- 事前学習された言語モデルとラベル付きデータセットへのアクセス

## インストール

コースをパッケージとして維持しているため、パッケージマネージャーを使用して依存関係を簡単にインストールできます。`uv`をお勧めしますが、`pip`や`pdm`などの代替手段も使用できます。

### `uv`を使用する場合

`uv`がインストールされている場合、次のようにしてコースをインストールできます：

```bash
uv venv --python 3.11.0
uv sync
```

### `pip`を使用する場合

すべての例は**python 3.11**環境で実行されるため、次のように環境を作成し、依存関係をインストールします：

```bash
# python -m venv .venv
# source .venv/bin/activate
pip install -r requirements.txt
```

### Google Colab

**Google Colabから**は、使用するハードウェアに基づいて柔軟に依存関係をインストールする必要があります。次のようにします：

```bash
pip install transformers trl datasets huggingface_hub
```



<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/README.md" />

### ビジョン言語モデル
https://huggingface.co/learn/smol-course/ja/unit5/1.md

# ビジョン言語モデル

## 1. VLMの使用

ビジョン言語モデル（VLM）は、画像キャプション生成、視覚質問応答、マルチモーダル推論などのタスクを可能にするために、テキストと並行して画像入力を処理します。

典型的なVLMアーキテクチャは、視覚的特徴を抽出する画像エンコーダ、視覚的およびテキスト表現を整列させるプロジェクション層、およびテキストを処理または生成する言語モデルで構成されます。これにより、モデルは視覚要素と言語概念の間の接続を確立できます。

VLMは、使用ケースに応じてさまざまな構成で使用できます。ベースモデルは一般的なビジョン言語タスクを処理し、チャット最適化されたバリアントは会話型インタラクションをサポートします。一部のモデルには、視覚的証拠に基づいて予測を行うための追加コンポーネントや、物体検出などの特定のタスクに特化したコンポーネントが含まれています。

VLMの技術的な詳細と使用方法については、[VLMの使用](./vlm_usage.md)ページを参照してください。

## 2. VLMのファインチューニング

VLMのファインチューニングは、特定のタスクを実行するため、または特定のデータセットで効果的に動作するように、事前トレーニングされたモデルを適応させるプロセスです。このプロセスは、モジュール1および2で紹介されたように、教師ありファインチューニング、好みの最適化、またはその両方を組み合わせたハイブリッドアプローチなどの方法論に従うことができます。

コアツールと技術はLLMで使用されるものと似ていますが、VLMのファインチューニングには、画像のデータ表現と準備に特に注意を払う必要があります。これにより、モデルが視覚データとテキストデータの両方を効果的に統合および処理し、最適なパフォーマンスを発揮できるようになります。デモモデルであるSmolVLMは、前のモジュールで使用された言語モデルよりも大幅に大きいため、効率的なファインチューニング方法を探ることが重要です。量子化やPEFTなどの技術を使用することで、プロセスをよりアクセスしやすく、コスト効果の高いものにし、より多くのユーザーがモデルを試すことができます。

VLMのファインチューニングに関する詳細なガイダンスについては、[VLMのファインチューニング](./vlm_finetuning.md)ページを参照してください。


## 参考文献
- [Hugging Face Learn: Supervised Fine-Tuning VLMs](https://huggingface.co/learn/cookbook/fine_tuning_vlm_trl)
- [Hugging Face Learn: Supervised Fine-Tuning SmolVLM](https://huggingface.co/learn/cookbook/fine_tuning_smol_vlm_sft_trl)
- [Hugging Face Learn: Preference Optimization Fine-Tuning SmolVLM](https://huggingface.co/learn/cookbook/fine_tuning_vlm_dpo_smolvlm_instruct)
- [Hugging Face Blog: Preference Optimization for VLMs](https://huggingface.co/blog/dpo_vlm)
- [Hugging Face Blog: Vision Language Models](https://huggingface.co/blog/vlms)
- [Hugging Face Blog: SmolVLM](https://huggingface.co/blog/smolvlm)
- [Hugging Face Model: SmolVLM-Instruct](https://huggingface.co/HuggingFaceTB/SmolVLM-Instruct)
- [CLIP: Learning Transferable Visual Models from Natural Language Supervision](https://arxiv.org/abs/2103.00020)
- [Align Before Fuse: Vision and Language Representation Learning with Momentum Distillation](https://arxiv.org/abs/2107.07651)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit5/1.md" />

### VLMファインチューニング
https://huggingface.co/learn/smol-course/ja/unit5/3.md

# VLMファインチューニング
<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/5_vision_language_models/vlm_sft_sample.ipynb"},
]} />
    
## 効率的なファインチューニング

### 量子化
量子化は、モデルの重みとアクティベーションの精度を低下させ、メモリ使用量を大幅に削減し、計算速度を向上させます。たとえば、`float32`から`bfloat16`に切り替えると、パラメータごとのメモリ要件が半分になり、パフォーマンスを維持できます。より積極的な圧縮のために、8ビットおよび4ビットの量子化を使用してメモリ使用量をさらに削減できますが、精度が若干低下する可能性があります。これらの技術は、モデルとオプティマイザの設定の両方に適用でき、リソースが限られたハードウェアでの効率的なトレーニングを可能にします。

### PEFT & LoRA
モジュール3で紹介されたように、LoRA（Low-Rank Adaptation）は、元のモデルの重みを固定したまま、コンパクトなランク分解行列を学習することに焦点を当てています。これにより、トレーニング可能なパラメータの数が大幅に削減され、リソース要件が大幅に削減されます。LoRAはPEFTと統合されることで、大規模モデルのファインチューニングを可能にし、トレーニング可能なパラメータの小さなサブセットのみを調整します。このアプローチは、タスク固有の適応に特に効果的であり、数十億のトレーニング可能なパラメータを数百万に削減しながらパフォーマンスを維持します。

### バッチサイズの最適化
ファインチューニングのバッチサイズを最適化するには、大きな値から始め、メモリ不足（OOM）エラーが発生した場合は減らします。`gradient_accumulation_steps`を増やして補い、複数の更新にわたって合計バッチサイズを実質的に維持します。さらに、`gradient_checkpointing`を有効にして、逆伝播中に中間状態を再計算することでメモリ使用量を削減し、計算時間を犠牲にしてアクティベーションメモリ要件を削減します。これらの戦略は、ハードウェアの利用を最大化し、メモリ制約を克服するのに役立ちます。

```python
from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir="./fine_tuned_model",  # モデルチェックポイントのディレクトリ
    per_device_train_batch_size=4,   # デバイスごとのバッチサイズ（GPU/TPU）
    num_train_epochs=3,              # トレーニングの総エポック数
    learning_rate=5e-5,              # 学習率
    save_steps=1000,                 # 1000ステップごとにチェックポイントを保存
    bf16=True,                       # トレーニングに混合精度を使用
    gradient_checkpointing=True,     # アクティベーションメモリ使用量を削減するために有効にする
    gradient_accumulation_steps=16,  # 16ステップにわたって勾配を蓄積
    logging_steps=50                 # 50ステップごとにメトリクスをログ
)
```

## **教師ありファインチューニング（SFT）**

教師ありファインチューニング（SFT）は、事前トレーニングされたビジョン言語モデル（VLM）を特定のタスクに適応させるために、画像と対応するテキストを含むラベル付きデータセットを活用するプロセスです。この方法は、視覚質問応答、画像キャプション生成、チャート解釈などのドメイン固有またはタスク固有の機能を実行するモデルの能力を向上させます。

### **概要**
SFTは、ベースモデルの一般的な能力が不足する場合に、特定のドメインや特定の問題を解決するためにVLMを専門化する必要がある場合に不可欠です。たとえば、モデルが独自の視覚的特徴やドメイン固有の用語に苦労する場合、SFTはラベル付きデータから学習することでこれらの領域に焦点を当てることができます。

SFTは非常に効果的ですが、いくつかの制限があります：
- **データ依存性**：タスクに合わせた高品質のラベル付きデータセットが必要です。
- **計算リソース**：大規模なVLMのファインチューニングはリソース集約的です。
- **過学習のリスク**：モデルがあまりにも狭くファインチューニングされると、一般化能力を失う可能性があります。

これらの課題にもかかわらず、SFTは特定のコンテキストでのモデルパフォーマンスを向上させるための強力な手法です。

### **使用方法**
1. **データ準備**：画像とテキストのペアを含むラベル付きデータセットから始めます。たとえば、チャート分析のタスクでは、`HuggingFaceM4/ChartQA`データセットにはチャート画像、クエリ、および簡潔な応答が含まれています。

2. **モデル設定**：タスクに適した事前トレーニングされたVLM（例：`HuggingFaceTB/SmolVLM-Instruct`）と、テキストと画像の入力を準備するためのプロセッサをロードします。モデルを教師あり学習に設定し、ハードウェアに適した設定を行います。

3. **ファインチューニングプロセス**：
   - **データのフォーマット**：データセットをチャットボットのような形式に構造化し、システムメッセージ、ユーザークエリ、および対応する回答をペアにします。
   - **トレーニング設定**：Hugging Faceの`TrainingArguments`やTRLの`SFTConfig`などのツールを使用してトレーニングパラメータを設定します。これには、バッチサイズ、学習率、およびリソース使用を最適化するための勾配蓄積ステップが含まれます。
   - **最適化技術**：トレーニング中のメモリを節約するために**gradient checkpointing**を使用します。メモリ要件を削減し、計算速度を向上させるために量子化モデルを使用します。
   - TRLライブラリの`SFTTrainer`トレーナーを使用して、トレーニングプロセスを簡素化します。

## 好みの最適化

好みの最適化、特に直接好みの最適化（DPO）は、ビジョン言語モデル（VLM）を人間の好みに合わせるためのトレーニング手法です。事前定義された指示に厳密に従うのではなく、モデルは人間が主観的に好む出力を優先することを学習します。このアプローチは、創造的な判断、微妙な推論、または許容される回答が異なるタスクに特に有用です。

### **概要**
好みの最適化は、主観的な人間の好みがタスクの成功にとって重要なシナリオに対処します。好みをエンコードしたデータセットでファインチューニングすることで、DPOはモデルの応答生成能力を強化し、ユーザーの期待に文脈的およびスタイル的に一致させます。この方法は、創造的な執筆、顧客との対話、または複数の選択肢があるシナリオなどのタスクに特に効果的です。

その利点にもかかわらず、好みの最適化にはいくつかの課題があります：
- **データ品質**：高品質の好みが注釈されたデータセットが必要であり、データ収集がボトルネックになることがあります。
- **複雑さ**：トレーニングには、好みのペアワイズサンプリングや計算リソースのバランスなどの高度なプロセスが含まれることがあります。

好みのデータセットは、候補出力間の明確な好みをキャプチャする必要があります。たとえば、データセットは質問と2つの応答（1つは好まれ、もう1つは受け入れられない）をペアにすることがあります。モデルは、完全に正しくなくても、より人間の判断に一致する好ましい応答を予測することを学習します。

### **使用方法**
1. **データセットの準備**  
   トレーニングには、好みがラベル付けされたデータセットが重要です。各例は通常、プロンプト（例：画像と質問）と2つの候補応答（1つは選択され、もう1つは拒否される）で構成されます。たとえば：

   - **質問**：家族は何人ですか？  
     - **拒否**：画像には家族に関する情報はありません。  
     - **選択**：画像には18,000家族のユニオン組織のテーブル設定が表示されています。  

   データセットは、モデルに完全に正しくなくても、より人間の判断に一致する好ましい応答を優先することを教えます。

2. **モデル設定**  
   事前トレーニングされたVLMをロードし、DPOをサポートするHugging FaceのTRLライブラリと統合し、テキストと画像の入力を準備するためのプロセッサを使用します。モデルを教師あり学習に設定し、ハードウェアに適した設定を行います。

3. **トレーニングパイプライン**  
   トレーニングには、DPO固有のパラメータの設定が含まれます。プロセスの概要は次のとおりです：

   - **データセットのフォーマット**：各サンプルをプロンプト、画像、および候補応答で構成します。
   - **損失関数**：好みに基づく損失関数を使用して、好ましい出力を選択するようにモデルを最適化します。
   - **効率的なトレーニング**：量子化、勾配蓄積、LoRAアダプタなどの技術を組み合わせて、メモリと計算を最適化します。

## リソース

- [Hugging Face Learn: Supervised Fine-Tuning VLMs](https://huggingface.co/learn/cookbook/fine_tuning_vlm_trl) 
- [Hugging Face Learn: Supervised Fine-Tuning SmolVLM](https://huggingface.co/learn/cookbook/fine_tuning_smol_vlm_sft_trl)  
- [Hugging Face Learn: Preference Optimization Fine-Tuning SmolVLM](https://huggingface.co/learn/cookbook/fine_tuning_vlm_dpo_smolvlm_instruct)  
- [Hugging Face Blog: Preference Optimization for VLMs](https://huggingface.co/blog/dpo_vlm)

## 次のステップ

⏩ この統一アプローチを好みの最適化に実装するには、[vlm_finetune_sample.ipynb](../../../notebooks/ja/5_vision_language_models/vlm_finetune_sample.ipynb)を試してください。


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit5/3.md" />

### ビジュアル言語モデル
https://huggingface.co/learn/smol-course/ja/unit5/2.md

# ビジュアル言語モデル

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/5_vision_language_models/vlm_usage_sample.ipynb"},
]} />
    
ビジュアル言語モデル（VLM）は、画像とテキストの間のギャップを埋め、画像キャプションの生成、視覚に基づく質問への回答、テキストと視覚データの関係の理解などの高度なタスクを可能にします。そのアーキテクチャは、両方のモダリティをシームレスに処理するように設計されています。

### アーキテクチャ

VLMは、画像処理コンポーネントとテキスト生成モデルを組み合わせて、統一された理解を実現します。主な要素は次のとおりです：

![VLMアーキテクチャ](./images/VLM_Architecture.png)

- **画像エンコーダ**：生の画像をコンパクトな数値表現に変換します。CLIPやビジョントランスフォーマー（ViT）などの事前トレーニングされたエンコーダが一般的に使用されます。
- **埋め込みプロジェクタ**：画像特徴をテキスト埋め込みと互換性のある空間にマッピングします。通常、密な層や線形変換を使用します。
- **テキストデコーダ**：マルチモーダル情報を翻訳して一貫したテキストを生成する言語生成コンポーネントです。LlamaやVicunaなどの生成モデルが例として挙げられます。
- **マルチモーダルプロジェクタ**：画像とテキストの表現をブレンドするための追加の層を提供します。LLaVAのようなモデルでは、2つのモダリティ間の強力な接続を確立するために重要です。

ほとんどのVLMは、事前トレーニングされた画像エンコーダとテキストデコーダを活用し、ペアになった画像テキストデータセットで追加のファインチューニングを行います。このアプローチにより、効率的なトレーニングが可能になり、モデルが効果的に一般化できるようになります。

### 使用方法

![VLMプロセス](./images/VLM_Process.png)

VLMは、さまざまなマルチモーダルタスクに適用されます。その適応性により、さまざまなドメインで異なるレベルのファインチューニングを行うことができます：

- **画像キャプション生成**：画像の説明を生成します。
- **視覚質問応答（VQA）**：画像の内容に関する質問に答えます。
- **クロスモーダル検索**：特定の画像に対応するテキストを見つける、またはその逆を行います。
- **クリエイティブなアプリケーション**：デザイン支援、アート生成、魅力的なマルチメディアコンテンツの作成などに役立ちます。

![VLMの使用](./images/VLM_Usage.png)

VLMのトレーニングとファインチューニングには、画像とテキストの注釈がペアになった高品質なデータセットが必要です。Hugging Faceの`transformers`ライブラリなどのツールを使用すると、事前トレーニングされたVLMに簡単にアクセスでき、カスタムファインチューニングのワークフローが簡素化されます。

### チャット形式

多くのVLMは、使いやすさを向上させるためにチャットボットのような形式で構造化されています。この形式には次の要素が含まれます：

- モデルの役割やコンテキストを設定する**システムメッセージ**（例：「あなたは視覚データを分析するアシスタントです」）。
- テキスト入力と関連する画像を組み合わせた**ユーザークエリ**。
- マルチモーダル分析から得られたテキスト出力を提供する**アシスタントの応答**。

この会話形式は直感的であり、特にカスタマーサービスや教育ツールなどのインタラクティブなアプリケーションにおいて、ユーザーの期待に沿ったものです。

フォーマットされた入力の例を次に示します：

```json
[
    {
        "role": "system",
        "content": [{"type": "text", "text": "あなたはチャート画像の視覚データを解釈する専門のビジュアル言語モデルです..."}]
    },
    {
        "role": "user",
        "content": [
            {"type": "image", "image": "<image_data>"},
            {"type": "text", "text": "棒グラフの最高値は何ですか？"}
        ]
    },
    {
        "role": "assistant",
        "content": [{"type": "text", "text": "42"}]
    }
]
```

**複数の画像やビデオの処理**

VLMは、入力構造を適応させることで、複数の画像やビデオを処理することもできます。ビデオの場合、フレームを抽出して個々の画像として処理し、時間順序を維持します。

## リソース

- [Hugging Face Blog: Vision Language Models](https://huggingface.co/blog/vlms)
- [Hugging Face Blog: SmolVLM](https://huggingface.co/blog/smolvlm)

## 次のステップ

⏩ SMOLVLMのさまざまな使用方法を試すには、[vlm_usage_sample.ipynb](../../../notebooks/ja/5_vision_language_models/vlm_usage_sample.ipynb)を試してください。


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit5/2.md" />

### 🤗 smol-courseへようこそ
https://huggingface.co/learn/smol-course/ja/unit0/1.md

# 🤗 smol-courseへようこそ

このコースの完全な紹介については、英語版をご覧ください：

[Read the full introduction in English](https://huggingface.co/learn/smol-course/unit0/1)

## このコースについて簡単に

- **言語モデルをファインチューンするための包括的コース**
- **初心者から専門家まで**を対象としたステップバイステップの学習
- インストラクション・チューニング、評価、プリファレンス・アライメントなどを学ぶ
- ハンズオン実習と実際のプロジェクトを含む

## コースの構成

1. インストラクション・チューニング
2. 評価
3. プリファレンス・アライメント
4. パラメータ効率的ファイン・チューニング
5. ビジョン言語モデル
6. 合成データセット

[コースを開始する](https://huggingface.co/smol-course)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit0/1.md" />

### 評価
https://huggingface.co/learn/smol-course/ja/unit4/1.md

# 評価

評価は、言語モデルの開発と展開において重要なステップです。評価は、モデルがさまざまな能力にわたってどれだけうまく機能するかを理解し、改善の余地を特定するのに役立ちます。このモジュールでは、標準ベンチマークとドメイン固有の評価アプローチの両方をカバーし、smolモデルを包括的に評価します。

Hugging Faceが開発した強力な評価ライブラリである[`lighteval`](https://github.com/huggingface/lighteval)を使用します。評価の概念とベストプラクティスについて詳しく知りたい場合は、評価[ガイドブック](https://github.com/huggingface/evaluation-guidebook)を参照してください。

## モジュール概要

徹底した評価戦略は、モデル性能の複数の側面を検討します。質問応答や要約などのタスク固有の能力を評価し、モデルがさまざまなタイプの問題にどれだけうまく対処できるかを理解します。出力の品質を一貫性や事実の正確性などの要素で測定します。安全性評価は、潜在的な有害な出力やバイアスを特定するのに役立ちます。最後に、ドメインの専門知識テストは、ターゲット分野でのモデルの専門知識を検証します。

## コンテンツ

### 1️⃣ [自動ベンチマーク](./automatic_benchmarks.md)

標準化されたベンチマークとメトリクスを使用してモデルを評価する方法を学びます。MMLUやTruthfulQAなどの一般的なベンチマークを探求し、主要な評価メトリクスと設定を理解し、再現可能な評価のベストプラクティスをカバーします。

### 2️⃣ [カスタムドメイン評価](./custom_evaluation.md)

特定のユースケースに合わせた評価パイプラインを作成する方法を学びます。カスタム評価タスクの設計、専門的なメトリクスの実装、要件に合った評価データセットの構築について説明します。

### 3️⃣ [ドメイン評価プロジェクト](./project/README.md)

ドメイン固有の評価パイプラインを構築する完全な例を紹介します。評価データセットの生成、データ注釈のためのArgillaの使用、標準化されたデータセットの作成、LightEvalを使用したモデルの評価方法を学びます。

## リソース

- [評価ガイドブック](https://github.com/huggingface/evaluation-guidebook) - LLM評価の包括的なガイド
- [LightEvalドキュメント](https://github.com/huggingface/lighteval) - LightEvalライブラリの公式ドキュメント
- [Argillaドキュメント](https://docs.argilla.io) - Argillaアノテーションプラットフォームについて学ぶ
- [MMLU論文](https://arxiv.org/abs/2009.03300) - MMLUベンチマークを説明する論文
- [カスタムタスクの作成](https://github.com/huggingface/lighteval/wiki/Adding-a-Custom-Task)
- [カスタムメトリクスの作成](https://github.com/huggingface/lighteval/wiki/Adding-a-New-Metric)
- [既存のメトリクスの使用](https://github.com/huggingface/lighteval/wiki/Metric-List)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit4/1.md" />

### カスタムドメイン評価
https://huggingface.co/learn/smol-course/ja/unit4/3.md

# カスタムドメイン評価

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/4_evaluation/lighteval_evaluate_and_analyse_your_LLM.ipynb"},
]} />
    
標準ベンチマークは貴重な洞察を提供しますが、多くのアプリケーションでは特定のドメインやユースケースに合わせた評価アプローチが必要です。このガイドでは、ターゲットドメインでモデルの性能を正確に評価するためのカスタム評価パイプラインを作成する方法を説明します。

## 評価戦略の設計

成功するカスタム評価戦略は、明確な目標から始まります。ドメインでモデルが示すべき具体的な能力を考慮してください。これには、技術的な知識、推論パターン、ドメイン固有の形式が含まれるかもしれません。これらの要件を慎重に文書化してください。これがタスク設計とメトリック選択の両方を導きます。

評価は、標準的なユースケースとエッジケースの両方をテストする必要があります。例えば、医療ドメインでは、一般的な診断シナリオと稀な状態の両方を評価するかもしれません。金融アプリケーションでは、通常の取引と複数の通貨や特別な条件を含む複雑なエッジケースの両方をテストするかもしれません。

## LightEvalを使用した実装

LightEvalは、カスタム評価を実装するための柔軟なフレームワークを提供します。カスタムタスクを作成する方法は次のとおりです：

```python
from lighteval.tasks import Task, Doc
from lighteval.metrics import SampleLevelMetric, MetricCategory, MetricUseCase

class CustomEvalTask(Task):
    def __init__(self):
        super().__init__(
            name="custom_task",
            version="0.0.1",
            metrics=["accuracy", "f1"],  # 選択したメトリック
            description="カスタム評価タスクの説明"
        )
    
    def get_prompt(self, sample):
        # 入力をプロンプトにフォーマット
        return f"質問: {sample['question'
  ]}\n回答:"
    
    def process_response(self, response, ref):
        # モデルの出力を処理し、参照と比較
        return response.strip() == ref.strip()
```

## カスタムメトリック

ドメイン固有のタスクには、専門的なメトリックが必要なことがよくあります。LightEvalは、ドメインに関連する性能の側面を捉えるカスタムメトリックを作成するための柔軟なフレームワークを提供します：

```python
from aenum import extend_enum
from lighteval.metrics import Metrics, SampleLevelMetric, SampleLevelMetricGrouping
import numpy as np

# サンプルレベルのメトリック関数を定義
def custom_metric(predictions: list[str], formatted_doc: Doc, **kwargs) -> dict:
    """サンプルごとに複数のスコアを返す例のメトリック"""
    response = predictions[0]
    return {
        "accuracy": response == formatted_doc.choices[formatted_doc.gold_index],
        "length_match": len(response) == len(formatted_doc.reference)
    }

# サンプルごとに複数の値を返すメトリックを作成
custom_metric_group = SampleLevelMetricGrouping(
    metric_name=["accuracy", "length_match"],  # サブメトリックの名前
    higher_is_better={  # 各メトリックで高い値が良いかどうか
        "accuracy": True,
        "length_match": True
    },
    category=MetricCategory.CUSTOM,
    use_case=MetricUseCase.SCORING,
    sample_level_fn=custom_metric,
    corpus_level_fn={  # 各メトリックを集計する方法
        "accuracy": np.mean,
        "length_match": np.mean
    }
)

# LightEvalにメトリックを登録
extend_enum(Metrics, "custom_metric_name", custom_metric_group)
```

サンプルごとに1つのメトリック値のみが必要な場合の簡単なケース：

```python
def simple_metric(predictions: list[str], formatted_doc: Doc, **kwargs) -> bool:
    """サンプルごとに単一のスコアを返す例のメトリック"""
    response = predictions[0]
    return response == formatted_doc.choices[formatted_doc.gold_index]

simple_metric_obj = SampleLevelMetric(
    metric_name="simple_accuracy",
    higher_is_better=True,
    category=MetricCategory.CUSTOM,
    use_case=MetricUseCase.SCORING,
    sample_level_fn=simple_metric,
    corpus_level_fn=np.mean  # サンプル全体で集計する方法
)

extend_enum(Metrics, "simple_metric", simple_metric_obj)
```

カスタムメトリックを評価タスクで参照することで、評価タスクで自動的に計算され、指定された関数に従って集計されます。

より複雑なメトリックの場合、次のことを検討してください：
- フォーマットされたドキュメントのメタデータを使用してスコアを重み付けまたは調整
- コーパスレベルの統計のためのカスタム集計関数の実装
- メトリック入力の検証チェックの追加
- エッジケースと期待される動作の文書化

これらの概念を実装する完全な例については、[ドメイン評価プロジェクト](./project/README.md)を参照してください。

## データセットの作成

高品質の評価には、慎重にキュレーションされたデータセットが必要です。データセット作成のアプローチを次に示します：

1. 専門家のアノテーション：ドメインの専門家と協力して評価例を作成および検証します。[Argilla](https://github.com/argilla-io/argilla)のようなツールを使用すると、このプロセスがより効率的になります。

2. 実世界のデータ：実際の使用データを収集し、匿名化して、実際の展開シナリオを反映します。

3. 合成生成：LLMを使用して初期例を生成し、専門家がそれを検証および洗練します。

## ベストプラクティス

- 評価方法論を徹底的に文書化し、仮定や制限を含める
- ドメインのさまざまな側面をカバーする多様なテストケースを含める
- 自動メトリックと人間の評価の両方を適用する
- 評価データセットとコードをバージョン管理する
- 新しいエッジケースや要件を発見するたびに評価スイートを定期的に更新する

## 参考文献

- [LightEvalカスタムタスクガイド](https://github.com/huggingface/lighteval/wiki/Adding-a-Custom-Task)
- [LightEvalカスタムメトリック](https://github.com/huggingface/lighteval/wiki/Adding-a-New-Metric)
- データセットアノテーションのための[Argillaドキュメント](https://docs.argilla.io)
- 一般的な評価原則のための[評価ガイドブック](https://github.com/huggingface/evaluation-guidebook)

# 次のステップ

⏩ これらの概念を実装する完全な例については、[ドメイン評価プロジェクト](./project/README.md)を参照してください。


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit4/3.md" />

### 自動ベンチマーク
https://huggingface.co/learn/smol-course/ja/unit4/2.md

# 自動ベンチマーク

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/4_evaluation/lighteval_evaluate_and_analyse_your_LLM.ipynb"},
]} />
    
自動ベンチマークは、さまざまなタスクや能力にわたって言語モデルを評価するための標準化されたツールとして機能します。これらはモデルの性能を理解するための有用な出発点を提供しますが、包括的な評価戦略の一部に過ぎないことを認識することが重要です。

## 自動ベンチマークの理解

自動ベンチマークは通常、事前に定義されたタスクと評価指標を持つキュレーションされたデータセットで構成されます。これらのベンチマークは、基本的な言語理解から複雑な推論まで、モデルのさまざまな側面を評価することを目的としています。自動ベンチマークの主な利点はその標準化にあります。これにより、異なるモデル間で一貫した比較が可能となり、再現性のある結果が得られます。

ただし、ベンチマークの性能が必ずしも実世界での有効性に直結するわけではないことを理解することが重要です。学術的なベンチマークで優れた成績を収めたモデルでも、特定のドメインアプリケーションや実際のユースケースでは苦労することがあります。

## ベンチマークとその限界

### 一般知識ベンチマーク

MMLU（Massive Multitask Language Understanding）は、科学から人文科学まで57の科目にわたる知識をテストします。包括的ではありますが、特定のドメインに必要な専門知識の深さを反映しているわけではありません。TruthfulQAは、モデルが一般的な誤解を再現する傾向を評価しますが、すべての形態の誤情報を捉えることはできません。

### 推論ベンチマーク
BBH（Big Bench Hard）とGSM8Kは、複雑な推論タスクに焦点を当てています。BBHは論理的思考と計画をテストし、GSM8Kは特に数学的な問題解決を対象としています。これらのベンチマークは分析能力を評価するのに役立ちますが、実世界のシナリオで必要とされる微妙な推論を完全に捉えることはできません。

### 言語理解
HELMは包括的な評価フレームワークを提供し、WinoGrandeは代名詞の曖昧性解消を通じて常識をテストします。これらのベンチマークは言語処理能力に関する洞察を提供しますが、自然な会話やドメイン固有の用語の複雑さを完全に表現することはできません。

## 代替評価アプローチ

多くの組織は、標準ベンチマークの限界に対処するために代替評価方法を開発しています：

### LLM-as-Judge
ある言語モデルを使用して別のモデルの出力を評価する方法がますます人気を集めています。このアプローチは、従来の指標よりも微妙なフィードバックを提供することができますが、それ自体のバイアスと限界も伴います。

### 評価アリーナ
AnthropicのConstitutional AI Arenaのようなプラットフォームでは、モデルが相互に対話し、制御された環境で互いを評価することができます。これにより、従来のベンチマークでは明らかにならない強みと弱みが明らかになります。

### カスタムベンチマークスイート
組織は、特定のニーズやユースケースに合わせた内部ベンチマークスイートを開発することがよくあります。これには、ドメイン固有の知識テストや実際の展開条件を反映した評価シナリオが含まれることがあります。

## 独自の評価戦略の作成

LightEvalを使用して標準ベンチマークを実行するのは簡単ですが、ユースケースに特化した評価方法の開発にも時間を投資する必要があります。

標準ベンチマークは有用なベースラインを提供しますが、それだけが評価方法であってはなりません。より包括的なアプローチを開発する方法は次のとおりです：

1. 関連する標準ベンチマークから始めて、ベースラインを確立し、他のモデルとの比較を可能にします。

2. ユースケースの特定の要件と課題を特定します。モデルが実際に実行するタスクは何ですか？どのようなエラーが最も問題になりますか？

3. 実際のユースケースを反映したカスタム評価データセットを開発します。これには次のようなものが含まれるかもしれません：
   - ドメインからの実際のユーザークエリ
   - 遭遇した一般的なエッジケース
   - 特に挑戦的なシナリオの例

4. 多層評価戦略の実装を検討します：
   - クイックフィードバックのための自動指標
   - 微妙な理解のための人間の評価
   - 専門家によるレビュー
   - 制御された環境でのA/Bテスト

## LightEvalを使用したベンチマーク

LightEvalタスクは特定の形式を使用して定義されます：
```
{suite}|{task}|{num_few_shot}|{auto_reduce}
```

- **suite**: ベンチマークスイート（例：'mmlu', 'truthfulqa'）
- **task**: スイート内の特定のタスク（例：'abstract_algebra'）
- **num_few_shot**: プロンプトに含める例の数（ゼロショットの場合は0）
- **auto_reduce**: プロンプトが長すぎる場合に少数ショットの例を自動的に削減するかどうか（0または1）

例：`"mmlu|abstract_algebra|0|0"`は、ゼロショット推論でMMLUの抽象代数学タスクを評価します。

### 評価パイプラインの例

特定のドメインに関連する自動ベンチマークの評価を設定して実行する完全な例を次に示します：

```python
from lighteval.tasks import Task, Pipeline
from transformers import AutoModelForCausalLM

# 評価するタスクを定義
domain_tasks = [
    "mmlu|anatomy|0|0",
    "mmlu|high_school_biology|0|0", 
    "mmlu|high_school_chemistry|0|0",
    "mmlu|professional_medicine|0|0"
]

# パイプラインパラメータを設定
pipeline_params = {
    "max_samples": 40,  # 評価するサンプル数
    "batch_size": 1,    # 推論のバッチサイズ
    "num_workers": 4    # ワーカープロセスの数
}

# 評価トラッカーを作成
evaluation_tracker = EvaluationTracker(
    output_path="./results",
    save_generations=True
)

# モデルを読み込み、パイプラインを作成
model = AutoModelForCausalLM.from_pretrained("your-model-name")
pipeline = Pipeline(
    tasks=domain_tasks,
    pipeline_parameters=pipeline_params,
    evaluation_tracker=evaluation_tracker,
    model=model
)

# 評価を実行
pipeline.evaluate()

# 結果を取得して表示
results = pipeline.get_results()
pipeline.show_results()
```

結果は次のような表形式で表示されます：
```
|                  Task                  |Version|Metric|Value |   |Stderr|
|----------------------------------------|------:|------|-----:|---|-----:|
|all                                     |       |acc   |0.3333|±  |0.1169|
|leaderboard:mmlu:_average:5             |       |acc   |0.3400|±  |0.1121|
|leaderboard:mmlu:anatomy:5              |      0|acc   |0.4500|±  |0.1141|
|leaderboard:mmlu:high_school_biology:5  |      0|acc   |0.1500|±  |0.0819|
```

結果をpandas DataFrameで処理し、視覚化や表現を自由に行うこともできます。

# 次のステップ

⏩ [カスタムドメイン評価](./custom_evaluation.md)を探索し、特定のニーズに合わせた評価パイプラインの作成方法を学びましょう


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit4/2.md" />

### 選好の整合
https://huggingface.co/learn/smol-course/ja/unit2/1.md

# 選好の整合

このモジュールでは、言語モデルを人間の選好に合わせるための技術について説明します。教師あり微調整（SFT）がモデルにタスクを学習させるのに役立つ一方で、選好の整合は出力が人間の期待や価値観に一致するようにします。

## 概要

選好の整合の典型的な方法には、複数のステージが含まれます：
1. 教師あり微調整（SFT）でモデルを特定のドメインに適応させる。
2. 選好の整合（RLHFやDPOなど）で応答の質を向上させる。

ORPOのような代替アプローチは、指示調整と選好の整合を単一のプロセスに統合します。ここでは、DPOとORPOのアルゴリズムに焦点を当てます。

さまざまな整合技術について詳しく知りたい場合は、[Argillaのブログ](https://argilla.io/blog/mantisnlp-rlhf-part-8)を参照してください。

### 1️⃣ 直接選好最適化（DPO）

直接選好最適化（DPO）は、選好データを使用してモデルを直接最適化することで、選好の整合を簡素化します。このアプローチは、別個の報酬モデルや複雑な強化学習を必要とせず、従来のRLHFよりも安定して効率的です。詳細については、[直接選好最適化（DPO）のドキュメント](./dpo.md)を参照してください。

### 2️⃣ 選好確率比最適化（ORPO）

ORPOは、指示調整と選好の整合を単一のプロセスに統合する新しいアプローチを導入します。これは、負の対数尤度損失とトークンレベルのオッズ比項を組み合わせて標準的な言語モデリングの目的を修正します。このアプローチは、単一のトレーニングステージ、参照モデル不要のアーキテクチャ、および計算効率の向上を提供します。ORPOは、さまざまなベンチマークで印象的な結果を示しており、従来の方法と比較してAlpacaEvalで優れたパフォーマンスを示しています。詳細については、[選好確率比最適化（ORPO）のドキュメント](./orpo.md)を参照してください。

## リソース

- [TRLのドキュメント](https://huggingface.co/docs/trl/index) - DPOを含むさまざまな整合技術を実装するためのTransformers Reinforcement Learning（TRL）ライブラリのドキュメント。
- [DPO論文](https://arxiv.org/abs/2305.18290) - 人間のフィードバックを用いた強化学習の代替として、選好データを使用して言語モデルを直接最適化するシンプルなアプローチを紹介する論文。
- [ORPO論文](https://arxiv.org/abs/2403.07691) - 指示調整と選好の整合を単一のトレーニングステージに統合する新しいアプローチを紹介する論文。
- [ArgillaのRLHFガイド](https://argilla.io/blog/mantisnlp-rlhf-part-8/) - RLHF、DPOなどのさまざまな整合技術とその実践的な実装について説明するガイド。
- [DPOに関するブログ記事](https://huggingface.co/blog/dpo-trl) - TRLライブラリを使用してDPOを実装する方法についての実践ガイド。コード例とベストプラクティスが含まれています。
- [TRLのDPOスクリプト例](https://github.com/huggingface/trl/blob/main/examples/scripts/dpo.py) - TRLライブラリを使用してDPOトレーニングを実装する方法を示す完全なスクリプト例。
- [TRLのORPOスクリプト例](https://github.com/huggingface/trl/blob/main/examples/scripts/orpo.py) - TRLライブラリを使用してORPOトレーニングを実装するためのリファレンス実装。詳細な設定オプションが含まれています。
- [Hugging Faceの整合ハンドブック](https://github.com/huggingface/alignment-handbook) - SFT、DPO、RLHFなどのさまざまな技術を使用して言語モデルを整合させるためのガイドとコード。


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit2/1.md" />

### ORPOの理解
https://huggingface.co/learn/smol-course/ja/unit2/3.md

## ORPOの理解

DPOのような選好整合方法は、通常、微調整と選好整合の2つの別々のステップを含みます。微調整はモデルを特定のドメインや形式に適応させ、選好整合は人間の選好に合わせて出力を調整します。SFT（教師あり微調整）は、モデルをターゲットドメインに適応させるのに効果的ですが、望ましい応答と望ましくない応答の両方の確率を増加させる可能性があります。ORPOは、以下の比較図に示すように、これらのステップを単一のプロセスに統合することで、この制限に対処します。

![モデル整合技術の比較](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-alignments.png)
*モデル整合技術の比較*

## ORPOの仕組み

ORPOのトレーニングプロセスは、DPOと同様に、入力プロンプトと2つの応答（1つは選好、もう1つは非選好）を含む選好データセットを使用します。他の整合方法とは異なり、ORPOは選好整合を教師あり微調整プロセスに直接統合します。この統合アプローチにより、参照モデルが不要になり、計算効率とメモリ効率が向上し、FLOP数が減少します。

ORPOは、次の2つの主要なコンポーネントを組み合わせて新しい目的を作成します：

1. **SFT損失**：負の対数尤度損失を使用して、参照トークンの生成確率を最大化します。これにより、モデルの一般的な言語能力が維持されます。
2. **オッズ比損失**：望ましくない応答をペナルティし、選好される応答を報酬する新しいコンポーネントです。この損失関数は、トークンレベルで選好される応答と非選好の応答を効果的に対比するためにオッズ比を使用します。

これらのコンポーネントを組み合わせることで、モデルは特定のドメインに対して望ましい生成を適応させながら、非選好の応答を積極的に抑制します。オッズ比メカニズムは、選好された応答と拒否された応答の間のモデルの選好を測定および最適化する自然な方法を提供します。数学的な詳細については、[ORPO論文](https://arxiv.org/abs/2403.07691)を参照してください。実装の観点からORPOについて学びたい場合は、[TRLライブラリ](https://github.com/huggingface/trl/blob/b02189aaa538f3a95f6abb0ab46c0a971bfde57e/trl/trainer/orpo_trainer.py#L660)でORPO損失がどのように計算されるかを確認してください。

## パフォーマンスと結果

ORPOは、さまざまなベンチマークで印象的な結果を示しています。MT-Benchでは、さまざまなカテゴリで競争力のあるスコアを達成しています：

![MT-Benchの結果](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-mtbench.png)
*MT-Benchのカテゴリ別結果（Mistral-ORPOモデル）*

他の整合方法と比較すると、ORPOはAlpacaEval 2.0で優れたパフォーマンスを示しています：

![AlpacaEvalの結果](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-winrate.png)
*さまざまな整合方法におけるAlpacaEval 2.0スコア*

SFT+DPOと比較して、ORPOは参照モデルが不要であり、バッチごとのフォワードパスの数を半減させることで計算要件を削減します。さらに、トレーニングプロセスは、さまざまなモデルサイズとデータセットでより安定しており、調整するハイパーパラメータが少なくて済みます。パフォーマンスに関しては、ORPOはより大きなモデルと同等のパフォーマンスを示しながら、人間の選好に対する整合性が向上しています。

## 実装

ORPOの成功した実装は、高品質の選好データに大きく依存します。トレーニングデータは明確な注釈ガイドラインに従い、さまざまなシナリオで好ましい応答と拒否された応答のバランスの取れた表現を提供する必要があります。

### TRLを使用した実装

ORPOは、Transformers Reinforcement Learning（TRL）ライブラリを使用して実装できます。以下は基本的な例です：

```python
from trl import ORPOConfig, ORPOTrainer

# ORPOトレーニングの設定
orpo_config = ORPOConfig(
    learning_rate=1e-5,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    max_steps=1000,
    orpo_alpha=1.0,  # 選好最適化の強度を制御
    orpo_beta=0.1,   # オッズ比計算の温度パラメータ
)

# トレーナーを初期化
trainer = ORPOTrainer(
    model=model,
    args=orpo_config,
    train_dataset=dataset,
    tokenizer=tokenizer,
)

# トレーニングを開始
trainer.train()
```

考慮すべき主要なパラメータ：
- `orpo_alpha`：選好最適化の強度を制御
- `orpo_beta`：オッズ比計算の温度パラメータ
- `learning_rate`：忘却のカタストロフィーを避けるために比較的小さく設定
- `gradient_accumulation_steps`：トレーニングの安定性を向上

## 次のステップ

⏩ この統合された選好整合アプローチを実装するための[ORPOチュートリアル](../../../notebooks/ja/2_preference_alignment/orpo_tutorial.ipynb)を試してみてください。

## リソース
- [ORPO論文](https://arxiv.org/abs/2403.07691)
- [TRLドキュメント](https://huggingface.co/docs/trl/index)
- [ArgillaのRLHFガイド](https://argilla.io/blog/mantisnlp-rlhf-part-8/)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit2/3.md" />

### DPOの理解
https://huggingface.co/learn/smol-course/ja/unit2/2.md

## DPOの理解

DPOは、選好の整合を人間の選好データに基づく分類問題として再定義します。従来のRLHFアプローチでは、別個の報酬モデルをトレーニングし、PPO（近接ポリシー最適化）などの複雑なアルゴリズムを使用してモデルの出力を整合させる必要があります。DPOは、好ましい出力と好ましくない出力に基づいてモデルのポリシーを直接最適化する損失関数を定義することで、このプロセスを簡素化します。

このアプローチは実際に非常に効果的であり、Llamaなどのモデルのトレーニングに使用されています。別個の報酬モデルや強化学習のステージを必要としないため、DPOは選好の整合をよりアクセスしやすく、安定したものにします。

## DPOの仕組み

DPOのプロセスには、ターゲットドメインにモデルを適応させるための教師あり微調整（SFT）が必要です。これにより、標準的な指示追従データセットでトレーニングすることで、選好学習の基盤が形成されます。モデルは基本的なタスクを完了しながら、一般的な能力を維持することを学びます。

次に、選好学習が行われ、モデルは好ましい出力と好ましくない出力のペアでトレーニングされます。選好ペアは、モデルがどの応答が人間の価値観や期待に最も一致するかを理解するのに役立ちます。

DPOの中心的な革新は、その直接最適化アプローチにあります。別個の報酬モデルをトレーニングする代わりに、DPOはバイナリクロスエントロピー損失を使用して、選好データに基づいてモデルの重みを直接更新します。この簡素化されたプロセスにより、トレーニングがより安定し、効率的になり、従来のRLHFメソッドと同等またはそれ以上の結果が得られます。

## DPOのデータセット

DPOのデータセットは、通常、選好または非選好として注釈された応答ペアを含むように作成されます。これは手動で行うか、自動フィルタリング技術を使用して行うことができます。以下は、単一ターンのDPO選好データセットの構造の例です：

| プロンプト | 選好 | 非選好 |
|--------|---------|-----------|
| ...    | ...     | ...       |
| ...    | ...     | ...       |
| ...    | ...     | ...       |

`Prompt`列には、`選好`および`非選好`の応答を生成するために使用されたプロンプトが含まれています。`選好`および`非選好`列には、それぞれ好ましい応答と好ましくない応答が含まれています。この構造にはバリエーションがあり、例えば、`system_prompt`や`Input`列に参照資料を含めることができます。`選好`および`非選好`の値は、単一ターンの会話の場合は文字列として、または会話リストとして表現されることがあります。

Hugging FaceでDPOデータセットのコレクションを[こちら](https://huggingface.co/collections/argilla/preference-datasets-for-dpo-656f0ce6a00ad2dc33069478)で見つけることができます。

## TRLを使用した実装

Transformers Reinforcement Learning（TRL）ライブラリは、DPOの実装を容易にします。`DPOConfig`および`DPOTrainer`クラスは、`transformers`スタイルのAPIに従います。

以下は、DPOトレーニングを設定する基本的な例です：

```python
from trl import DPOConfig, DPOTrainer

# 引数を定義
training_args = DPOConfig(
    ...
)

# トレーナーを初期化
trainer = DPOTrainer(
    model,
    train_dataset=dataset,
    tokenizer=tokenizer,
    ...
)

# モデルをトレーニング
trainer.train()
```

DPOConfigおよびDPOTrainerクラスの使用方法の詳細については、[DPOチュートリアル](../../../notebooks/ja/2_preference_alignment/../notebooks/ja/2_preference_alignment/dpo_finetuning_example.ipynb)を試してみてください。この実践ガイドでは、データの準備からトレーニングおよび評価まで、選好整合の実装方法を説明します。

⏭️ チュートリアルを完了した後、別の選好整合技術について学ぶために[ORPOページ](./orpo.md)を探索してください。


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit2/2.md" />

### 合成データセット
https://huggingface.co/learn/smol-course/ja/unit6/1.md

# 合成データセット

合成データは、実際の使用状況を模倣する人工的に生成されたデータです。データセットを拡張または強化することで、データの制限を克服することができます。合成データはすでにいくつかのユースケースで使用されていましたが、大規模な言語モデルは、言語モデルの事前および事後トレーニング、および評価のための合成データセットをより一般的にしました。

私たちは、検証済みの研究論文に基づいた迅速で信頼性が高くスケーラブルなパイプラインを必要とするエンジニアのための合成データとAIフィードバックのフレームワークである[`distilabel`](https://distilabel.argilla.io/latest/)を使用します。パッケージとベストプラクティスの詳細については、[ドキュメント](https://distilabel.argilla.io/latest/)を参照してください。

## モジュール概要

言語モデルの合成データは、インストラクション、嗜好、批評の3つの分類に分類できます。私たちは、インストラクションチューニングと嗜好調整のためのデータセットの生成に焦点を当てます。両方のカテゴリでは、既存のデータをモデルの批評とリライトで改善するための第3のカテゴリの側面もカバーします。

![合成データの分類](./images/taxonomy-synthetic-data.png)

## コンテンツ

### 1. [インストラクションデータセット](./instruction_datasets.md)

インストラクションチューニングのためのインストラクションデータセットの生成方法を学びます。基本的なプロンプトを使用してインストラクションチューニングデータセットを作成する方法や、論文から得られたより洗練された技術を使用する方法を探ります。SelfInstructやMagpieのような方法を使用して、インコンテキスト学習のためのシードデータを使用してインストラクションチューニングデータセットを作成できます。さらに、EvolInstructを通じたインストラクションの進化についても探ります。[学び始める](./instruction_datasets.md)。

### 2. [嗜好データセット](./preference_datasets.md)

嗜好調整のための嗜好データセットの生成方法を学びます。セクション1で紹介した方法と技術を基に構築し、追加の応答を生成します。次に、EvolQualityプロンプトを使用して応答を改善する方法を学びます。最後に、スコアと批評を生成するUltraFeedbackプロンプトを探り、嗜好ペアを作成します。[学び始める](./preference_datasets.md)。

## リソース

- [Distilabel Documentation](https://distilabel.argilla.io/latest/)
- [Synthetic Data Generator is UI app](https://huggingface.co/blog/synthetic-data-generator)
- [SmolTalk](https://huggingface.co/datasets/HuggingFaceTB/smoltalk)
- [Self-instruct](https://arxiv.org/abs/2212.10560)
- [Evol-Instruct](https://arxiv.org/abs/2304.12244)
- [Magpie](https://arxiv.org/abs/2406.08464)
- [UltraFeedback](https://arxiv.org/abs/2310.01377)
- [Deita](https://arxiv.org/abs/2312.15685)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit6/1.md" />

### 嗜好データセットの生成
https://huggingface.co/learn/smol-course/ja/unit6/3.md

# 嗜好データセットの生成

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/6_synthetic_datasets/preference_dpo_dataset.ipynb"},
]} />
    
[嗜好調整の章](../2_preference_alignment/README.md)では、直接嗜好最適化について学びました。このセクションでは、DPOのような方法のための嗜好データセットを生成する方法を探ります。[インストラクションデータセットの生成](./instruction_datasets.md)で紹介した方法を基に構築します。さらに、基本的なプロンプトを使用してデータセットに追加の完了を追加する方法や、EvolQualityを使用して応答の品質を向上させる方法を示します。最後に、UltraFeedbackを使用してスコアと批評を生成する方法を示します。

## 複数の完了を作成する

嗜好データは、同じ`インストラクション`に対して複数の`完了`を持つデータセットです。モデルにプロンプトを与えて追加の`完了`を生成することで、データセットにより多くの`完了`を追加できます。この際、2つ目の完了が全体的な品質や表現において最初の完了とあまり似ていないことを確認する必要があります。これは、モデルが明確な嗜好に最適化される必要があるためです。通常、`選ばれた`と`拒否された`と呼ばれる完了のどちらが好まれるかを知りたいのです。[スコアの作成セクション](#creating-scores)で、選ばれた完了と拒否された完了を決定する方法について詳しく説明します。

### モデルプーリング

異なるモデルファミリーからモデルを使用して2つ目の完了を生成することができます。これをモデルプーリングと呼びます。2つ目の完了の品質をさらに向上させるために、`温度`を調整するなど、異なる生成引数を使用することができます。最後に、異なるプロンプトテンプレートやシステムプロンプトを使用して2つ目の完了を生成し、特定の特性に基づいて多様性を確保することができます。理論的には、異なる品質の2つのモデルを使用し、より良いものを`選ばれた`完了として使用することができます。

まず、[Qwen/Qwen2.5-1.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct)と[HuggingFaceTB/SmolLM2-1.7B-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct)モデルを`transformers`統合の`distilabel`ライブラリを使用してロードします。これらのモデルを使用して、与えられた`プロンプト`に対して2つの合成`応答`を作成します。`LoadDataFromDicts`、`TextGeneration`、および`GroupColumns`を使用して別のパイプラインを作成します。最初にデータをロードし、次に2つの生成ステップを使用し、最後に結果をグループ化します。ステップを接続し、`>>`演算子と`[]`を使用してデータをパイプラインに流します。これは、前のステップの出力を次のステップの入力として使用することを意味します。

```python
from distilabel.llms import TransformersLLM
from distilabel.pipeline import Pipeline
from distilabel.steps import GroupColumns, LoadDataFromDicts
from distilabel.steps.tasks import TextGeneration

with Pipeline() as pipeline:
    data = LoadDataFromDicts(data=[{"instruction": "合成データとは何ですか？"}])
    llm_a = TransformersLLM(model="HuggingFaceTB/SmolLM2-1.7B-Instruct")
    gen_a = TextGeneration(llm=llm_a)
    llm_b = TransformersLLM(model="Qwen/Qwen2.5-1.5B-Instruct")
    gen_b = TextGeneration(llm=llm_b)
    group = GroupColumns(columns=["generation"])
    data >> [gen_a, gen_b] >> group

if __name__ == "__main__":
    distiset = pipeline.run()
    print(distiset["default"]["train"]["grouped_generation"][0])
# {[
#   '合成データは、実際の使用状況を模倣する人工的に生成されたデータです。',
#   '合成データとは、人工的に生成されたデータを指します。'
# 
  ]}
```

ご覧のとおり、与えられた`プロンプト`に対して2つの合成`完了`があります。生成ステップを特定の`システムプロンプト`で初期化するか、`TransformersLLM`に生成引数を渡すことで、多様性をさらに向上させることができます。次に、EvolQualityを使用して`完了`の品質を向上させる方法を見てみましょう。

### EvolQuality

EvolQualityは、[EvolInstruct](./instruction_datasets.md#evolinstruct)に似ていますが、入力`プロンプト`の代わりに`完了`を進化させます。このタスクは、`プロンプト`と`完了`の両方を受け取り、一連の基準に基づいて`完了`をより良いバージョンに進化させます。このより良いバージョンは、役立ち度、関連性、深化、創造性、または詳細の基準に基づいて定義されます。これにより、データセットに追加の`完了`を自動的に生成できます。理論的には、進化したバージョンが元の完了よりも優れていると仮定し、それを`選ばれた`完了として使用することができます。

プロンプトは[distilabelで実装されています](https://github.com/argilla-io/distilabel/tree/main/src/distilabel/steps/tasks/evol_quality)が、簡略化されたバージョンは以下の通りです：

```bash
応答リライターとして行動してください。
与えられたプロンプトと応答を、より良いバージョンに書き換えてください。
以下の基準に基づいてプロンプトを複雑化してください：
{{ criteria }}

# プロンプト
{{ input }}

# 応答
{{ output }}

# 改善された応答
```

これを使用するには、[EvolQualityクラス](https://distilabel.argilla.io/dev/components-gallery/tasks/evolquality/)に`llm`を渡す必要があります。[モデルプーリングセクション](#model-pooling)の合成`プロンプト`と`完了`を使用して、より良いバージョンに進化させてみましょう。この例では、1世代だけ進化させます。

```python
from distilabel.llms import TransformersLLM
from distilabel.steps.tasks import EvolQuality

llm = TransformersLLM(model="HuggingFaceTB/SmolLM2-1.7B-Instruct")
evol_quality = EvolQuality(llm=llm, num_evolutions=1)
evol_quality.load()

instruction = "合成データとは何ですか？"
completion = "合成データは、実際の使用状況を模倣する人工的に生成されたデータです。"

next(evol_quality.process([{
    "instruction": instruction,
    "response": completion
}]))
# 手動プロンプトを使用して合成データを生成するプロセスは何ですか？
```

`応答`はより複雑で、`インストラクション`に特化しています。これは良いスタートですが、EvolInstructで見たように、進化した生成物が常に優れているわけではありません。したがって、データセットの品質を確保するために追加の評価技術を使用することが重要です。次のセクションでこれを探ります。

## スコアの作成

スコアは、ある応答が他の応答よりもどれだけ好まれるかを測定するものです。一般的に、これらのスコアは絶対的、主観的、または相対的です。このコースでは、最初の2つに焦点を当てます。これらは嗜好データセットの作成に最も価値があるためです。このスコアリングは、評価技術と重なる部分があり、[評価の章](../3_evaluation/README.md)で見たように、通常はより大きなモデルが必要です。

### UltraFeedback

UltraFeedbackは、与えられた`プロンプト`とその`完了`に対してスコアと批評を生成する技術です。

スコアは、一連の基準に基づいて`完了`の品質を評価します。基準には、`役立ち度`、`関連性`、`深化`、`創造性`の4つの細かい基準があります。これらは便利ですが、一般的には全体的な基準を使用するのが良いスタートです。これにより、スコアの生成プロセスが簡略化されます。スコアは、どの`完了`が`選ばれた`もので、どれが`拒否された`ものであるかを決定するために使用できます。絶対的なスコアであるため、データセットの外れ値を見つけるための興味深いフィルターとしても使用できます。たとえば、最悪の完了や差が大きいペアを見つけることができます。

批評はスコアの理由を提供するために追加されます。これにより、スコアの違いを理解するための追加のコンテキストが提供されます。言語モデルは広範な批評を生成しますが、これは非常に便利ですが、スコアを表す単一のトークンを生成するよりもコストと複雑さが増します。

プロンプトは[distilabelで実装されています](https://github.com/argilla-io/distilabel/tree/main/src/distilabel/steps/tasks/templates/ultrafeedback)が、簡略化されたバージョンは以下の通りです：

```bash
モデルの出力をさまざまな基準に基づいて評価してください：役立ち度、関連性、深化、創造性
上記の要因に基づいて全体的な評価を提供する役割を果たします。
出力の全体的な品質を1から5のスコアで評価してください。

以下の形式で回答してください：スコア - 理由

# 入力
{{ input }}

# 応答
{{ output }}

# スコア - 理由
```

これを使用するには、[UltraFeedbackクラス](https://distilabel.argilla.io/dev/components-gallery/tasks/ultrafeedback/)に`llm`を渡す必要があります。[モデルプーリングセクション](#model-pooling)の合成`プロンプト`と`完了`を評価してみましょう。

```python
from distilabel.llms import TransformersLLM
from distilabel.steps.tasks import UltraFeedback

llm = TransformersLLM(model="HuggingFaceTB/SmolLM2-1.7B-Instruct")
ultrafeedback = UltraFeedback(llm=llm)
ultrafeedback.load()

instruction = "合成データとは何ですか？"
completion_a = "合成データは、実際の使用状況を模倣する人工的に生成されたデータです。"
completion_b = "合成データとは、人工的に生成されたデータを指します。"

next(ultrafeedback.process([{
    "instruction": instruction,
    "generations": [completion_a, completion_b]
}]))
# [
#     {
#         'ratings': [4, 5],
#         'rationales': ['could have been more specific', 'good definition'],
#     }
# ]
```

## ベストプラクティス

- 全体的なスコアは、批評や特定のスコアよりも安価で生成が容易です
- スコアや批評を生成するために大きなモデルを使用する
- スコアや批評を生成するために多様なモデルセットを使用する
- `system_prompt`やモデルの構成を繰り返し改善する

## 次のステップ

👨🏽‍💻 コード -[演習ノートブック](../../../notebooks/ja/6_synthetic_datasets/preference_dpo_dataset.ipynb)でインストラクションチューニングのためのデータセットを生成する

## 参考文献

- [Distilabel Documentation](https://distilabel.argilla.io/latest/)
- [Deita](https://arxiv.org/abs/2312.15685)
- [UltraFeedback](https://arxiv.org/abs/2310.01377)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit6/3.md" />

### インストラクションデータセットの生成
https://huggingface.co/learn/smol-course/ja/unit6/2.md

# インストラクションデータセットの生成

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/6_synthetic_datasets/instruction_sft_dataset.ipynb"},
]} />

[インストラクションチューニングの章](../1_instruction_tuning/README.md) では、教師あり微調整によるモデルの微調整について学びました。このセクションでは、SFTのためのインストラクションデータセットの生成方法を探ります。基本的なプロンプトを使用してインストラクションチューニングデータセットを作成する方法や、論文から得られたより洗練された技術を使用する方法を探ります。インストラクションチューニングデータセットは、SelfInstructやMagpieのような方法を使用して、インコンテキスト学習のためのシードデータを使用して作成できます。さらに、EvolInstructを通じたインストラクションの進化についても探ります。最後に、distilabelパイプラインを使用してインストラクションチューニングのためのデータセットを生成する方法を探ります。

## プロンプトからデータへ

合成データは一見複雑に見えますが、モデルから知識を抽出するための効果的なプロンプトを作成することに簡略化できます。つまり、特定のタスクのためのデータを生成する方法と考えることができます。課題は、データが多様で代表的であることを保証しながら、効果的にプロンプトを作成することです。幸いなことに、多くの論文がこの問題を探求しており、このコースではいくつかの有用なものを探ります。まずは、手動でプロンプトを作成して合成データを生成する方法を探ります。

### 基本的なプロンプト

基本的な例から始めましょう。[HuggingFaceTB/SmolLM2-1.7B-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct)モデルを`distilabel`ライブラリの`transformers`統合を使用してロードします。`TextGeneration`クラスを使用して合成`プロンプト`を生成し、それを使用して`completion`を生成します。

次に、`distilabel`ライブラリを使用してモデルをロードします。

```python
from distilabel.llms import TransformersLLM
from distilabel.steps.tasks import TextGeneration

llm = TransformersLLM(model="HuggingFaceTB/SmolLM2-1.7B-Instruct")
gen = TextGeneration(llm=llm)
gen.load()
```

!!! note
    Distilabelは`llm`をメモリにロードするため、ノートブックで作業する場合は、メモリの問題を避けるために使用後に`gen.unload()`する必要があります。

次に、`llm`を使用してインストラクションチューニングのための`プロンプト`を生成します。

```python
next(gen.process([{"instruction": "Hugging Faceの小規模AIモデルに関するSmol-Courseについての質問を生成してください。"}]))
# Smol-Courseの目的は何ですか？
```

最後に、同じ`プロンプト`を入力として使用して`completion`を生成します。

```python
next(gen.process([{"instruction": "Smol-Courseの目的は何ですか？"}]))
# Smol-Courseはコンピュータサイエンスの概念を学ぶためのプラットフォームです。
```

素晴らしい！合成`プロンプト`と対応する`completion`を生成できました。このシンプルなアプローチをスケールアップして、より多くのデータを生成することができますが、データの品質はそれほど高くなく、コースやドメインのニュアンスを考慮していません。さらに、現在のコードを再実行すると、データがそれほど多様でないことがわかります。幸いなことに、この問題を解決する方法があります。

### SelfInstruct

SelfInstructは、シードデータセットに基づいて新しいインストラクションを生成するプロンプトです。このシードデータは単一のインストラクションやコンテキストの一部である場合があります。プロセスは、初期のシードデータのプールから始まります。言語モデルは、インコンテキスト学習を使用してこのシードデータに基づいて新しいインストラクションを生成するようにプロンプトされます。このプロンプトは[distilabelで実装されています](https://github.com/argilla-io/distilabel/blob/main/src/distilabel/steps/tasks/templates/self-instruct.jinja2)が、簡略化されたバージョンは以下の通りです：

```
# タスクの説明
与えられたAIアプリケーションが受け取ることができる{{ num_instructions }}のユーザークエリを開発してください。モデルのテキスト能力内で動詞と言語構造の多様性を強調してください。

# コンテキスト
{{ input }}

# 出力
```

これを使用するには、`llm`を[SelfInstructクラス](https://distilabel.argilla.io/dev/components-gallery/tasks/selfinstruct/)に渡す必要があります。[プロンプトからデータセクション](#prompt-to-data)のテキストをコンテキストとして使用し、新しいインストラクションを生成してみましょう。

```python
from distilabel.steps.tasks import SelfInstruct

self_instruct = SelfInstruct(llm=llm)
self_instruct.load()

context = "<prompt_to_data_section>"

next(self_instruct.process([{"input": text}]))["instructions"][0]
# 手動プロンプトを使用して合成データを生成するプロセスは何ですか？
```

生成されたインストラクションはすでにかなり良くなっており、実際のコンテンツやドメインに適しています。しかし、プロンプトを進化させることでさらに良くすることができます。

### EvolInstruct

EvolInstructは、入力インストラクションを進化させて、同じインストラクションのより良いバージョンにするプロンプト技術です。このより良いバージョンは、一連の基準に従って定義され、元のインストラクションに制約、深化、具体化、推論、または複雑化を追加します。このプロセスは、元のインストラクションのさまざまな進化を作成するために複数回繰り返すことができ、理想的には元のインストラクションのより良いバージョンに導きます。このプロンプトは[distilabelで実装されています](https://github.com/argilla-io/distilabel/tree/main/src/distilabel/steps/tasks/evol_instruct)が、簡略化されたバージョンは以下の通りです：

```
プロンプトリライターとして行動してください。
与えられたプロンプトを、より複雑なバージョンに書き換えてください。
以下の基準に基づいてプロンプトを複雑化してください：
{{ criteria }}

# プロンプト
{{ input }}

# 出力
```

これを使用するには、`llm`を[EvolInstructクラス](https://distilabel.argilla.io/dev/components-gallery/tasks/evolinstruct/)に渡す必要があります。[SelfInstructセクション](#selfinstruct)の合成プロンプトを入力として使用し、それをより良いバージョンに進化させてみましょう。この例では、1世代だけ進化させます。

```python
from distilabel.steps.tasks import EvolInstruct

evol_instruct = EvolInstruct(llm=llm, num_evolutions=1)
evol_instruct.load()

text = "手動プロンプトを使用して合成データを生成するプロセスは何ですか？"

next(evol_instruct.process([{"instruction": text}]))
# 手動プロンプトを使用して合成データを生成するプロセスは何ですか？
# そして、人工知能システムであるGPT4が機械学習アルゴリズムを使用して入力データを合成データに変換する方法は？
```

インストラクションはより複雑になりましたが、元の意味を失っています。したがって、進化させることは両刃の剣であり、生成するデータの品質に注意する必要があります。

### Magpie

Magpieは、言語モデルの自己回帰的要因と、インストラクションチューニングプロセス中に使用されていた[チャットテンプレート](../1_instruction_tuning/chat_templates.md)に依存する技術です。覚えているかもしれませんが、チャットテンプレートは、システム、ユーザー、アシスタントの役割を明確に示す形式で会話を構造化します。インストラクションチューニングフェーズ中に、言語モデルはこの形式を再現するように最適化されており、Magpieはそれを利用します。チャットテンプレートに基づいた事前クエリプロンプトから始めますが、ユーザーメッセージインジケーター、例：<|im_end|>ユーザー\nの前で停止し、その後、言語モデルを使用してユーザープロンプトを生成し、アシスタントインジケーター、例：<|im_end|>まで生成します。このアプローチにより、多くのデータを非常に効率的に生成でき、マルチターンの会話にもスケールアップできます。この生成されたデータは、使用されたモデルのインストラクションチューニングフェーズのトレーニングデータを再現すると仮定されています。

このシナリオでは、プロンプトテンプレートはチャットテンプレート形式に基づいているため、モデルごとに異なります。しかし、プロセスをステップバイステップで簡略化して説明できます。

```bash
# ステップ1：事前クエリプロンプトを提供する
<|im_end|>ユーザー\n

# ステップ2：言語モデルがユーザープロンプトを生成する
<|im_end|>ユーザー\n
Smol-Courseの目的は何ですか？

# ステップ3：生成を停止する
<|im_end|>
```

distilabelで使用するには、`llm`を[Magpieクラス](https://distilabel.argilla.io/dev/components-gallery/tasks/magpie/)に渡す必要があります。

```python
from distilabel.steps.tasks import Magpie

magpie = Magpie(llm=llm)
magpie.load()

next(magpie.process([{"system_prompt": "あなたは役立つアシスタントです。"}]))
# [{
#   "role": "user",
#   "content": "トップ3の大学のリストを提供できますか？"
# },
# {
#   "role": "assistant",
#   "content": "トップ3の大学は：MIT、イェール、スタンフォードです。"
# }]
```

すぐに`プロンプト`と`completion`を含むデータセットが得られます。ドメインに特化したパフォーマンスを向上させるために、`system_prompt`に追加のコンテキストを挿入できます。LLMが特定のドメインデータを生成するために、システムプロンプトでユーザーのクエリがどのようなものかを説明することが役立ちます。これは、ユーザープロンプトを生成する前の事前クエリプロンプトで使用され、LLMがそのドメインのユーザークエリを生成するようにバイアスをかけます。

```
あなたは数学の問題を解決するためにユーザーを支援するAIアシスタントです。
```

システムプロンプトに追加のコンテキストを渡すことは、一般的に言語モデルが最適化されていないため、カスタマイズには他の技術ほど効果的ではないことが多いです。

### プロンプトからパイプラインへ

これまで見てきたクラスはすべて、パイプラインで使用できるスタンドアロンのクラスです。これは良いスタートですが、`Pipeline`クラスを使用してデータセットを生成することでさらに良くすることができます。`TextGeneration`ステップを使用してインストラクションチューニングのための合成データセットを生成します。パイプラインは、データをロードするための`LoadDataFromDicts`ステップ、`プロンプト`を生成するための`TextGeneration`ステップ、およびそのプロンプトの`completion`を生成するためのステップで構成されます。ステップを接続し、`>>`演算子を使用してデータをパイプラインに流します。distilabelの[ドキュメント](https://distilabel.argilla.io/dev/components-gallery/tasks/textgeneration/#input-output-columns)には、ステップの入力および出力列に関する情報が記載されています。データがパイプラインを正しく流れるようにするために、`output_mappings`パラメータを使用して出力列を次のステップの入力列にマッピングします。

```python
from distilabel.llms import TransformersLLM
from distilabel.pipeline import Pipeline
from distilabel.steps import LoadDataFromDicts
from distilabel.steps.tasks import TextGeneration

with Pipeline() as pipeline:
    data = LoadDataFromDicts(data=[{"instruction": "Hugging Faceの小規模AIモデルに関するSmol-Courseについての短い質問を生成してください。"}])
    llm = TransformersLLM(model="HuggingFaceTB/SmolLM2-1.7B-Instruct")
    gen_a = TextGeneration(llm=llm, output_mappings={"generation": "instruction"})
    gen_b = TextGeneration(llm=llm, output_mappings={"generation": "response"})
    data >> gen_a >> gen_b

if __name__ == "__main__":
    distiset = pipeline.run(use_cache=False)
    print(distiset["default"]["train"][0])
# [{
#   "instruction": "Smol-Courseの目的は何ですか？",
#   "response": "Smol-Courseはコンピュータサイエンスの概念を学ぶためのプラットフォームです。"
# }]
```

このパイプラインの背後には多くのクールな機能があります。生成結果を自動的にキャッシュするため、生成ステップを再実行する必要がありません。フォールトトレランスが組み込まれており、生成ステップが失敗してもパイプラインは実行を続けます。また、すべての生成ステップを並行して実行するため、生成が高速です。`draw`メソッドを使用してパイプラインを視覚化することもできます。ここでは、データがパイプラインをどのように流れ、`output_mappings`が出力列を次のステップの入力列にどのようにマッピングするかを確認できます。

![Pipeline](./images/pipeline.png)

## ベストプラクティス

- 多様なシードデータを確保して、さまざまなシナリオをカバーする
- 生成されたデータが多様で高品質であることを定期的に評価する
- データの品質を向上させるために（システム）プロンプトを繰り返し改善する

## 次のステップ

👨🏽‍💻 コード - [演習ノートブック](../../../notebooks/ja/6_synthetic_datasets/instruction_sft_dataset.ipynb)でインストラクションチューニングのためのデータセットを生成する
🧑‍🏫 学ぶ - [preference datasetsの生成](./preference_datasets.md)について学ぶ

## 参考文献

- [Distilabel Documentation](https://distilabel.argilla.io/latest/)
- [Self-instruct](https://arxiv.org/abs/2212.10560)
- [Evol-Instruct](https://arxiv.org/abs/2304.12244)
- [Magpie](https://arxiv.org/abs/2406.08464)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit6/2.md" />

### インストラクションチューニング
https://huggingface.co/learn/smol-course/ja/unit1/1.md

# インストラクションチューニング

このモジュールでは、言語モデルのインストラクションチューニングのプロセスをガイドします。インストラクションチューニングとは、特定のタスクに対してモデルを適応させるために、特定のタスクに関連するデータセットで追加のトレーニングを行うことを指します。このプロセスは、特定のタスクにおけるモデルのパフォーマンスを向上させるのに役立ちます。

このモジュールでは、2つのトピックを探ります：1) チャットテンプレートと2) 教師あり微調整

## 1️⃣ チャットテンプレート

チャットテンプレートは、ユーザーとAIモデル間のインタラクションを構造化し、一貫性のある文脈に適した応答を保証します。これらのテンプレートには、システムメッセージや役割に基づくメッセージなどのコンポーネントが含まれます。詳細については、[チャットテンプレート](./chat_templates.md)セクションを参照してください。

## 2️⃣ 教師あり微調整

教師あり微調整（SFT）は、事前トレーニングされた言語モデルを特定のタスクに適応させるための重要なプロセスです。これは、ラベル付きの例を含む特定のタスクのデータセットでモデルをトレーニングすることを含みます。SFTの詳細なガイド、重要なステップ、およびベストプラクティスについては、[教師あり微調整](./supervised_fine_tuning.md)ページを参照してください。


## 参考文献

- [Transformersのチャットテンプレートに関するドキュメント](https://huggingface.co/docs/transformers/main/en/chat_templating)
- [TRLの教師あり微調整スクリプト](https://github.com/huggingface/trl/blob/main/examples/scripts/sft.py)
- [TRLの`SFTTrainer`](https://huggingface.co/docs/trl/main/en/sft_trainer)
- [直接選好最適化に関する論文](https://arxiv.org/abs/2305.18290)
- [TRLを使用した教師あり微調整](https://huggingface.co/docs/trl/main/en/tutorials/supervised_fine_tuning)
- [ChatMLとHugging Face TRLを使用したGoogle Gemmaの微調整方法](https://www.philschmid.de/fine-tune-google-gemma)
- [LLMを微調整してペルシャ語の商品カタログをJSON形式で生成する方法](https://huggingface.co/learn/cookbook/en/fine_tuning_llm_to_generate_persian_product_catalogs_in_json_format)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit1/1.md" />

### 教師あり微調整
https://huggingface.co/learn/smol-course/ja/unit1/3.md

# 教師あり微調整

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/1_instruction_tuning/sft_finetuning_example.ipynb"}
  ]} />

教師あり微調整（SFT）は、事前トレーニングされた言語モデルを特定のタスクやドメインに適応させるための重要なプロセスです。事前トレーニングされたモデルは一般的な能力を持っていますが、特定のユースケースで優れたパフォーマンスを発揮するためにはカスタマイズが必要です。SFTは、慎重に選ばれた人間によって検証された例を含むデータセットを使用してモデルをトレーニングすることで、このギャップを埋めます。

## 教師あり微調整の理解

教師あり微調整の核心は、事前トレーニングされたモデルに特定のタスクを実行する方法を教えることです。これは、入力と出力の例を多数提示し、モデルが特定のユースケースのパターンを学習できるようにすることを含みます。

SFTは、事前トレーニング中に獲得した基本的な知識を活用しながら、モデルの動作を特定のニーズに合わせて調整するため、効果的です。

## 教師あり微調整を使用するタイミング

SFTを使用するかどうかの決定は、現在のモデルの能力と特定の要件とのギャップに依存します。SFTは、モデルの出力を正確に制御する必要がある場合や、専門的なドメインで作業する場合に特に価値があります。

例えば、カスタマーサービスアプリケーションを開発している場合、モデルが一貫して企業のガイドラインに従い、技術的な問い合わせを標準化された方法で処理することを望むかもしれません。同様に、医療や法律のアプリケーションでは、正確さと特定のドメインの用語に従うことが重要です。これらの場合、SFTはモデルの応答を専門的な基準とドメインの専門知識に合わせるのに役立ちます。

## 教師あり微調整（SFT）のプロセス

教師あり微調整のプロセスは、特定のタスクのデータセットでモデルの重みをトレーニングすることを含みます。

まず、ターゲットタスクを表すデータセットを準備または選択する必要があります。このデータセットには、モデルが直面するさまざまなシナリオをカバーする多様な例が含まれている必要があります。これらのデータの品質は重要です。各例は、モデルが生成することを望む出力の種類を示している必要があります。次に、微調整のフェーズがあり、ここでは`transformers`やHugging Faceの`trl`などのフレームワークを使用して、データセットでモデルをトレーニングします。

プロセス全体を通じて、継続的な評価が重要です。モデルが望ましい動作を学習していることを確認するために、検証セットでのパフォーマンスを監視する必要があります。これにより、モデルが一般的な能力を失うことなく、特定のタスクに適応していることを確認できます。[モジュール4](../4_evaluation)では、モデルの評価方法について詳しく説明します。

## 教師あり微調整の役割

SFTは、言語モデルを人間の好みに合わせる上で重要な役割を果たします。人間のフィードバックを使用した強化学習（RLHF）や直接選好最適化（DPO）などの技術は、SFTを使用してタスクの基本的な理解を形成し、その後、モデルの応答を望ましい結果にさらに合わせます。事前トレーニングされたモデルは、一般的な言語能力に優れているにもかかわらず、必ずしも人間の好みに一致する出力を生成するわけではありません。SFTは、特定のドメインのデータとガイダンスを導入することで、このギャップを埋め、モデルが人間の期待により密接に一致する応答を生成する能力を向上させます。

## トランスフォーマーの強化学習（TRL）を使用した教師あり微調整

教師あり微調整のための主要なソフトウェアパッケージは、トランスフォーマーの強化学習（TRL）です。TRLは、強化学習（RL）を使用してトランスフォーマーモデルをトレーニングするためのツールセットです。

Hugging FaceのTransformersライブラリに基づいており、ユーザーが事前トレーニングされた言語モデルを直接ロードできるようにし、ほとんどのデコーダーおよびエンコーダーデコーダーアーキテクチャと互換性があります。このライブラリは、教師あり微調整（SFT）、報酬モデリング（RM）、近接ポリシー最適化（PPO）、および直接選好最適化（DPO）など、言語モデリングで使用される主要なRLプロセスを容易にします。このリポジトリ全体で、さまざまなモジュールでTRLを使用します。

# 次のステップ

次のチュートリアルを試して、TRLを使用したSFTの実践的な経験を積んでください：

⏭️ [チャットテンプレートのチュートリアル](../../../notebooks/ja/1_instruction_tuning/../notebooks/ja/1_instruction_tuning/supervised_fine_tuning_tutorial.ipynb)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit1/3.md" />

### チャットテンプレート
https://huggingface.co/learn/smol-course/ja/unit1/2.md

# チャットテンプレート

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/1_instruction_tuning/chat_templates_example.ipynb"}
  ]} />

チャットテンプレートは、言語モデルとユーザー間のインタラクションを構造化するために不可欠です。これらは会話の一貫した形式を提供し、モデルが各メッセージの文脈と役割を理解し、適切な応答パターンを維持することを保証します。

## ベースモデル vs インストラクションモデル

ベースモデルは次のトークンを予測するために生のテキストデータでトレーニングされる一方、インストラクションモデルは特定の指示に従い会話に参加するように微調整されたモデルです。例えば、`SmolLM2-135M`はベースモデルであり、`SmolLM2-135M-Instruct`はその指示に特化したバリアントです。

ベースモデルをインストラクションモデルのように動作させるためには、モデルが理解できるようにプロンプトを一貫してフォーマットする必要があります。ここでチャットテンプレートが役立ちます。ChatMLは、システム、ユーザー、アシスタントの役割を明確に示すテンプレート形式で会話を構造化します。

ベースモデルは異なるチャットテンプレートで微調整される可能性があるため、インストラクションモデルを使用する際には、正しいチャットテンプレートを使用していることを確認する必要があります。

## チャットテンプレートの理解

チャットテンプレートの核心は、言語モデルと通信する際に会話がどのようにフォーマットされるべきかを定義することです。これには、システムレベルの指示、ユーザーメッセージ、およびアシスタントの応答が含まれ、モデルが理解できる構造化された形式で提供されます。この構造は、インタラクションの一貫性を維持し、モデルがさまざまな種類の入力に適切に応答することを保証します。以下はチャットテンプレートの例です：

```sh
<|im_end|>ユーザー
こんにちは！<|im_end|>
<|im_end|>アシスタント
はじめまして！<|im_end|>
<|im_end|>ユーザー
質問してもいいですか？<|im_end|>
<|im_end|>アシスタント
```

`transformers`ライブラリは、モデルのトークナイザーに関連してチャットテンプレートを自動的に処理します。`transformers`でチャットテンプレートがどのように構築されるかについて詳しくは[こちら](https://huggingface.co/docs/transformers/en/chat_templating#how-do-i-use-chat-templates)を参照してください。私たちはメッセージを正しい形式で構造化するだけで、残りはトークナイザーが処理します。以下は基本的な会話の例です：

```python
messages = [
    {"role": "system", "content": "あなたは技術的なトピックに焦点を当てた役立つアシスタントです。"},
    {"role": "user", "content": "チャットテンプレートとは何か説明できますか？"},
    {"role": "assistant", "content": "チャットテンプレートは、ユーザーとAIモデル間の会話を構造化します..."}
]
```

上記の例を分解して、チャットテンプレート形式にどのようにマッピングされるかを見てみましょう。

## システムメッセージ

システムメッセージは、モデルの動作の基礎を設定します。これらは、以降のすべてのインタラクションに影響を与える持続的な指示として機能します。例えば：

```python
system_message = {
    "role": "system",
    "content": "あなたはプロフェッショナルなカスタマーサービスエージェントです。常に礼儀正しく、明確で、役立つようにしてください。"
}
```

## 会話

チャットテンプレートは、ユーザーとアシスタント間の以前のやり取りを保存し、会話の履歴を通じて文脈を維持します。これにより、複数ターンにわたる一貫した会話が可能になります：

```python
conversation = [
    {"role": "user", "content": "注文に関して助けが必要です"},
    {"role": "assistant", "content": "お手伝いします。注文番号を教えていただけますか？"},
    {"role": "user", "content": "注文番号はORDER-123です"},
]
```

## Transformersを使用した実装

`transformers`ライブラリは、チャットテンプレートのための組み込みサポートを提供します。使用方法は以下の通りです：

```python
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM2-135M-Instruct")

messages = [
    {"role": "system", "content": "あなたは役立つプログラミングアシスタントです。"},
    {"role": "user", "content": "リストをソートするPython関数を書いてください"},
]

# チャットテンプレートを適用
formatted_chat = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
```

## カスタムフォーマット

異なる役割に対して特別なトークンやフォーマットを追加するなど、さまざまなメッセージタイプのフォーマットをカスタマイズできます。例えば：

```python
template = """
<|system|>{system_message}
<|user|>{user_message}
<|assistant|>{assistant_message}
""".lstrip()
```

## マルチターン会話のサポート

テンプレートは、文脈を維持しながら複雑なマルチターン会話を処理できます：

```python
messages = [
    {"role": "system", "content": "あなたは数学の家庭教師です。"},
    {"role": "user", "content": "微積分とは何ですか？"},
    {"role": "assistant", "content": "微積分は数学の一分野です..."},
    {"role": "user", "content": "例を教えてください。"},
]
```

⏭️ [次へ: Supervised Fine-Tuning](./supervised_fine_tuning.md)

## リソース

- [Hugging Face Chat Templating Guide](https://huggingface.co/docs/transformers/main/en/chat_templating)
- [Transformers Documentation](https://huggingface.co/docs/transformers)
- [Chat Templates Examples Repository](https://github.com/chujiezheng/chat_templates)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit1/2.md" />

### パラメータ効率の良い微調整 (PEFT)
https://huggingface.co/learn/smol-course/ja/unit3/1.md

# パラメータ効率の良い微調整 (PEFT)

言語モデルが大きくなるにつれて、従来の微調整はますます困難になります。1.7Bパラメータのモデルの完全な微調整には、かなりのGPUメモリが必要であり、別々のモデルコピーを保存することが高価であり、モデルの元の能力を破壊的に忘れるリスクがあります。パラメータ効率の良い微調整（PEFT）メソッドは、モデルパラメータの小さなサブセットのみを変更し、ほとんどのモデルを固定したままにすることで、これらの課題に対処します。

従来の微調整は、トレーニング中にすべてのモデルパラメータを更新しますが、これは大規模なモデルには実用的ではありません。PEFTメソッドは、元のモデルサイズの1％未満のパラメータを使用してモデルを適応させるアプローチを導入します。この劇的な学習可能なパラメータの削減により、次のことが可能になります：

- 限られたGPUメモリを持つ消費者向けハードウェアでの微調整
- 複数のタスク固有の適応を効率的に保存
- 低データシナリオでのより良い一般化
- より速いトレーニングと反復サイクル

## 利用可能なメソッド

このモジュールでは、2つの人気のあるPEFTメソッドを紹介します：

### 1️⃣ LoRA (低ランク適応)

LoRAは、効率的なモデル適応のためのエレガントなソリューションを提供する最も広く採用されているPEFTメソッドとして浮上しました。モデル全体を変更する代わりに、**LoRAはモデルの注意層に学習可能な行列を注入します。**このアプローチは、通常、完全な微調整と比較して約90％の学習可能なパラメータを削減しながら、同等の性能を維持します。[LoRA (低ランク適応)](./lora_adapters.md)セクションでLoRAを詳しく見ていきます。
 
### 2️⃣ プロンプトチューニング

プロンプトチューニングは、モデルの重みを変更するのではなく、**入力に学習可能なトークンを追加する**さらに軽量なアプローチを提供します。プロンプトチューニングはLoRAほど人気はありませんが、モデルを新しいタスクやドメインに迅速に適応させるための便利な技術です。[プロンプトチューニング](./prompt_tuning.md)セクションでプロンプトチューニングを詳しく見ていきます。

## リソース
- [PEFTドキュメント](https://huggingface.co/docs/peft)
- [LoRA論文](https://arxiv.org/abs/2106.09685)
- [QLoRA論文](https://arxiv.org/abs/2305.14314)
- [プロンプトチューニング論文](https://arxiv.org/abs/2104.08691)
- [Hugging Face PEFTガイド](https://huggingface.co/blog/peft)
- [2024年にHugging FaceでLLMを微調整する方法](https://www.philschmid.de/fine-tune-llms-in-2024-with-trl) 
- [TRL](https://huggingface.co/docs/trl/index)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit3/1.md" />

### プロンプトチューニング
https://huggingface.co/learn/smol-course/ja/unit3/3.md

# プロンプトチューニング

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/3_parameter_efficient_finetuning/finetune_sft_peft.ipynb"},
]} />
    
プロンプトチューニングは、モデルの重みではなく入力表現を変更するパラメータ効率の良いアプローチです。従来の微調整がすべてのモデルパラメータを更新するのに対し、プロンプトチューニングはベースモデルを固定したまま、少数の学習可能なトークンを追加して最適化します。

## プロンプトチューニングの理解

プロンプトチューニングは、学習可能な連続ベクトル（ソフトプロンプト）を入力テキストの前に追加するパラメータ効率の良い微調整方法です。従来の離散テキストプロンプトとは異なり、これらのソフトプロンプトはベースモデルを固定したまま、逆伝播を通じて学習されます。この方法は、["The Power of Scale for Parameter-Efficient Prompt Tuning"](https://arxiv.org/abs/2104.08691)（Lester et al., 2021）で紹介され、モデルサイズが大きくなるにつれてプロンプトチューニングがモデル微調整と競争力を持つようになることが示されました。論文内では、約100億パラメータのモデルで、プロンプトチューニングがモデル微調整の性能に匹敵し、タスクごとに数百のパラメータしか変更しないことが示されています。

これらのソフトプロンプトは、トレーニング中に最適化されるモデルの埋め込み空間内の連続ベクトルです。従来の自然言語トークンを使用する離散プロンプトとは異なり、ソフトプロンプトは固有の意味を持たず、勾配降下を通じて固定モデルから望ましい動作を引き出すことを学習します。この技術は、各タスクに対して小さなプロンプトベクトル（通常は数百パラメータ）を保存するだけで済むため、マルチタスクシナリオに特に効果的です。このアプローチは、最小限のメモリフットプリントを維持するだけでなく、モデルの再読み込みなしにプロンプトベクトルを交換するだけで迅速なタスク切り替えを可能にします。

## トレーニングプロセス

ソフトプロンプトは通常、8〜32トークンで構成され、ランダムに初期化するか、既存のテキストから初期化されます。初期化方法はトレーニングプロセスにおいて重要な役割を果たし、テキストベースの初期化はランダム初期化よりも優れた性能を発揮することがよくあります。

トレーニング中は、プロンプトパラメータのみが更新され、ベースモデルは固定されたままです。この集中アプローチは標準的なトレーニング目標を使用しますが、プロンプトトークンの学習率と勾配の挙動に注意を払う必要があります。

## PEFTを使用した実装

PEFTライブラリを使用すると、プロンプトチューニングの実装が簡単になります。以下は基本的な例です：

```python
from peft import PromptTuningConfig, TaskType, get_peft_model
from transformers import AutoModelForCausalLM, AutoTokenizer

# ベースモデルを読み込む
model = AutoModelForCausalLM.from_pretrained("your-base-model")
tokenizer = AutoTokenizer.from_pretrained("your-base-model")

# プロンプトチューニングを設定
peft_config = PromptTuningConfig(
    task_type=TaskType.CAUSAL_LM,
    num_virtual_tokens=8,  # 学習可能なトークンの数
    prompt_tuning_init="TEXT",  # テキストから初期化
    prompt_tuning_init_text="このテキストがポジティブかネガティブかを分類してください：",
    tokenizer_name_or_path="your-base-model",
)

# プロンプトチューニング可能なモデルを作成
model = get_peft_model(model, peft_config)
```

## 他の方法との比較

他のPEFTアプローチと比較すると、プロンプトチューニングはその効率性で際立っています。LoRAは低パラメータ数とメモリ使用量を提供しますが、タスク切り替えにはアダプタの読み込みが必要です。プロンプトチューニングはさらに低いリソース使用量を達成し、即時のタスク切り替えを可能にします。対照的に、フルファインチューニングは多くのリソースを必要とし、異なるタスクごとに別々のモデルコピーが必要です。

| 方法 | パラメータ | メモリ | タスク切り替え |
|--------|------------|---------|----------------|
| プロンプトチューニング | 非常に低い | 最小限 | 簡単 |
| LoRA | 低い | 低い | 読み込みが必要 |
| フルファインチューニング | 高い | 高い | 新しいモデルコピー |

プロンプトチューニングを実装する際は、最初に少数の仮想トークン（8〜16）を使用し、タスクの複雑さが要求する場合にのみ増やします。タスクに関連するテキストを使用したテキスト初期化は、ランダム初期化よりも優れた結果をもたらすことがよくあります。初期化戦略は、ターゲットタスクの複雑さを反映する必要があります。

トレーニングには、フルファインチューニングとは異なる考慮事項が必要です。高い学習率が効果的なことが多いですが、プロンプトトークンの勾配を注意深く監視することが重要です。多様な例で定期的に検証することで、さまざまなシナリオでの堅牢な性能を確保します。

## 応用

プロンプトチューニングは、次のようなシナリオで優れた効果を発揮します：

1. マルチタスク展開
2. リソース制約のある環境
3. 迅速なタスク適応
4. プライバシーに敏感なアプリケーション

モデルが小さくなるにつれて、プロンプトチューニングはフルファインチューニングと比較して競争力が低下します。例えば、SmolLM2のようなモデルでは、プロンプトチューニングはフルファインチューニングよりも関連性が低くなります。

## 次のステップ

⏭️ [LoRAアダプタのチュートリアル](../../../notebooks/ja/3_parameter_efficient_finetuning/finetune_sft_peft.ipynb)に進み、LoRAアダプタでモデルを微調整する方法を学びましょう。

## リソース
- [PEFTドキュメント](https://huggingface.co/docs/peft)
- [プロンプトチューニング論文](https://arxiv.org/abs/2104.08691)
- [Hugging Face Cookbook](https://huggingface.co/learn/cookbook/prompt_tuning_peft)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit3/3.md" />

### LoRA (低ランク適応)
https://huggingface.co/learn/smol-course/ja/unit3/2.md

# LoRA (低ランク適応)

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/ja/3_parameter_efficient_finetuning/finetune_sft_peft.ipynb"},
]} />

LoRAは最も広く採用されているPEFTメソッドとなっています。これは、注意重み行列に小さなランク分解行列を追加することで機能し、通常、学習可能なパラメータを約90％削減します。

## LoRAの理解

LoRA（低ランク適応）は、事前学習されたモデルの重みを固定し、学習可能なランク分解行列をモデルの層に注入するパラメータ効率の良い微調整技術です。微調整中にすべてのモデルパラメータを学習する代わりに、LoRAは低ランク分解を通じて重みの更新を小さな行列に分解し、学習可能なパラメータの数を大幅に削減しながらモデルの性能を維持します。例えば、GPT-3 175Bに適用した場合、LoRAは学習可能なパラメータを10,000倍、GPUメモリ要件を3倍削減しました。LoRAについての詳細は[LoRA論文](https://arxiv.org/pdf/2106.09685)を参照してください。

LoRAは、通常、注意重みに焦点を当てて、トランスフォーマーレイヤーにランク分解行列のペアを追加することで機能します。推論中に、これらのアダプタ重みはベースモデルと統合され、追加の遅延オーバーヘッドが発生しません。LoRAは、大規模な言語モデルを特定のタスクやドメインに適応させるのに特に役立ち、リソース要件を管理可能に保ちます。

## LoRAアダプタの読み込み

アダプタは、load_adapter()を使用して事前学習されたモデルに読み込むことができ、これは重みが統合されていない異なるアダプタを試すのに便利です。set_adapter()関数を使用してアクティブなアダプタ重みを設定します。ベースモデルに戻るには、unload()を使用してすべてのLoRAモジュールをアンロードできます。これにより、異なるタスク固有の重み間の切り替えが容易になります。

```python
from transformers import AutoModelForCausalLM
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("<base_model_name>")
peft_model_id = "<peft_adapter_id>"
model = PeftModel.from_pretrained(base_model, peft_model_id)
```

![lora_load_adapter](./images/lora_adapter.png)

## LoRAアダプタの統合

LoRAでトレーニングした後、アダプタ重みをベースモデルに統合して、デプロイを容易にすることができます。これにより、統合された重みを持つ単一のモデルが作成され、推論中にアダプタを別々に読み込む必要がなくなります。

統合プロセスには、メモリ管理と精度に注意が必要です。ベースモデルとアダプタ重みの両方を同時に読み込む必要があるため、十分なGPU/CPUメモリが利用可能であることを確認してください。`transformers`の`device_map="auto"`を使用すると、自動メモリ管理が容易になります。トレーニング中に使用した精度（例：float16）を一貫して維持し、統合されたモデルを同じ形式で保存してデプロイします。デプロイ前に、アダプタベースのバージョンと出力および性能メトリックを比較して、統合されたモデルを検証してください。

アダプタは、異なるタスクやドメイン間の切り替えにも便利です。ベースモデルとアダプタ重みを別々に読み込むことができます。これにより、異なるタスク固有の重み間の迅速な切り替えが可能になります。

## 実装ガイド

`notebooks/`ディレクトリには、さまざまなPEFTメソッドを実装するための実践的なチュートリアルと演習が含まれています。基本的な紹介には`load_lora_adapter_example.ipynb`を、LoRAとSFTを使用したモデルの微調整について詳しく知りたい場合は`lora_finetuning.ipynb`を参照してください。

PEFTメソッドを実装する際は、LoRAのランク値（4-8）を小さく設定し、トレーニング損失を監視します。検証セットを使用して過学習を防ぎ、可能であればフルファインチューニングのベースラインと結果を比較します。異なるメソッドの有効性はタスクによって異なるため、実験が重要です。

## OLoRA

[OLoRA](https://arxiv.org/abs/2406.01775)は、QR分解を使用してLoRAアダプタを初期化します。OLoRAは、QR分解の係数によってモデルのベース重みを変換します。つまり、トレーニングを行う前に重みを変換します。このアプローチは、安定性を大幅に向上させ、収束速度を加速し、最終的に優れた性能を達成します。

## TRLとPEFTの使用

PEFTメソッドは、TRL（Transformers Reinforcement Learning）と組み合わせて効率的な微調整を行うことができます。この統合は、RLHF（Reinforcement Learning from Human Feedback）に特に有用であり、メモリ要件を削減します。

```python
from peft import LoraConfig
from transformers import AutoModelForCausalLM

# PEFT設定でモデルを読み込む
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

# 特定のデバイスにモデルを読み込む
model = AutoModelForCausalLM.from_pretrained(
    "your-model-name",
    load_in_8bit=True,  # オプション: 8ビット精度を使用
    device_map="auto",
    peft_config=lora_config
)
```

上記では、`device_map="auto"`を使用してモデルを自動的に適切なデバイスに割り当てました。また、`device_map={"": device_index}`を使用してモデルを特定のデバイスに手動で割り当てることもできます。メモリ使用量を効率的に保ちながら、複数のGPUにトレーニングをスケールすることもできます。

## 基本的な統合実装

LoRAアダプタをトレーニングした後、アダプタ重みをベースモデルに統合することができます。以下はその方法です：

```python
import torch
from transformers import AutoModelForCausalLM
from peft import PeftModel

# 1. ベースモデルを読み込む
base_model = AutoModelForCausalLM.from_pretrained(
    "base_model_name",
    dtype=torch.float16,
    device_map="auto"
)

# 2. アダプタを持つPEFTモデルを読み込む
peft_model = PeftModel.from_pretrained(
    base_model,
    "path/to/adapter",
    dtype=torch.float16
)

# 3. アダプタ重みをベースモデルと統合
try:
    merged_model = peft_model.merge_and_unload()
except RuntimeError as e:
    print(f"統合に失敗しました: {e}")
    # フォールバック戦略またはメモリ最適化を実装

# 4. 統合されたモデルを保存
merged_model.save_pretrained("path/to/save/merged_model")
```

保存されたモデルのサイズに不一致がある場合は、トークナイザーも保存していることを確認してください：

```python
# モデルとトークナイザーの両方を保存
tokenizer = AutoTokenizer.from_pretrained("base_model_name")
merged_model.save_pretrained("path/to/save/merged_model")
tokenizer.save_pretrained("path/to/save/merged_model")
```

## 次のステップ

⏩ [プロンプトチューニング](prompt_tuning.md)ガイドに進み、プロンプトチューニングでモデルを微調整する方法を学びましょう。
⏩ [LoRAアダプタの読み込みチュートリアル](../../../notebooks/ja/3_parameter_efficient_finetuning/load_lora_adapter.ipynb)に進み、LoRAアダプタを読み込む方法を学びましょう。

# リソース

- [LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS](https://arxiv.org/pdf/2106.09685)
- [PEFTドキュメント](https://huggingface.co/docs/peft)
- [Hugging FaceのPEFTに関するブログ記事](https://huggingface.co/blog/peft)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/ja/unit3/2.md" />
