# チャットテンプレート

当社のGitHubには、Llama、Mistral、Phi-4などでUnslothが使用するすべてのチャットテンプレートの一覧があります。フォーマットやユースケースについてヒントが必要な場合は、ここで確認できます： [github.com/unslothai/unsloth/blob/main/unsloth/chat\_templates.py](https://github.com/unslothai/unsloth/blob/main/unsloth/chat_templates.py)

#### Colabのチャットテンプレートノートブック一覧：

* [会話形式](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3.2_\(1B_and_3B\)-Conversational.ipynb)
* [ChatML](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3_\(8B\)-Ollama.ipynb)
* [Ollama](https://colab.research.google.com/drive/1WZDi7APtQ9VsvOrQSSC5DDtxq159j8iZ?usp=sharing)
* [テキスト分類](https://github.com/timothelaborie/text_classification_scripts/blob/main/unsloth_classification.ipynb) 作成者：Timotheeee
* [複数データセット](https://colab.research.google.com/drive/1njCCbE1YVal9xC83hjdo2hiGItpY_D6t?usp=sharing) 作成者：Flail

### 新しいトークンの追加

Unslothには次のような関数があります： `add_new_tokens` この関数を使うとファインチューニングに新しいトークンを追加できます。例えば、次を追加したい場合： `<CHARACTER_1>`, `<THINKING>` および `<SCRATCH_PAD>` 次のように行えます：

```python
model, tokenizer = FastLanguageModel.from_pretrained(...)
from unsloth import add_new_tokens
add_new_tokens(model, tokenizer, new_tokens = ["<CHARACTER_1>", "<THINKING>", "<SCRATCH_PAD>"])
model = FastLanguageModel.get_peft_model(...)
```

{% hint style="warning" %}
注意 - 常に次を必ず呼び出す必要があります： `add_new_tokens` の前に `FastLanguageModel.get_peft_model`!
{% endhint %}

## マルチターン会話

気づかなかった場合の問題点として、Alpacaデータセットはシングルターンであるのに対し、ChatGPTを使っていたときは対話的で複数ターンで会話できました。例えば、左側が我々の望む形ですが、右側のAlpacaデータセットは単一の会話しか提供しません。ファインチューニングされた言語モデルにChatGPTのようなマルチターン会話のやり方を何らかの形で学習させたいのです。

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-2a65cd74ddd03a6bcbbc9827d9d034e4879a8e6a%2Fdiff.png?alt=media" alt=""><figcaption></figcaption></figure>

そこで私たちは `conversation_extension` パラメータを導入しました。これは本質的にシングルターンデータセットのいくつかのランダムな行を選択し、それらを1つの会話にマージします！例えば、これを3に設定すると、ランダムに3行を選択して1つにマージします。長すぎる設定は学習を遅くする可能性がありますが、チャットボットや最終的なファインチューニング結果を大幅に改善することがあります！

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-2b1b3494b260f1102942d86143a885225c6a06f2%2Fcombine.png?alt=media" alt=""><figcaption></figcaption></figure>

次に `output_column_name` を予測／出力カラムに設定します。Alpacaデータセットの場合は出力カラムになります。

その後、私たちは `standardize_sharegpt` 関数を使ってデータセットをファインチューニングに適した正しい形式にします！必ずこれを呼び出してください！

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-7bf83bf802191bda9e417bbe45afa181e7f24f38%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

## カスタマイズ可能なチャットテンプレート

ファインチューニング自体のチャットテンプレートを指定できるようになりました。有名なAlpaca形式は以下の通りです：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-59737e6dcb09fed15487d5a57c69f07cb40bb8e7%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

しかし、ChatGPTスタイルのファインチューニングはプロンプトが1つだけ必要だと言ったのを覚えていますか？Unslothを使ってすべてのデータセットカラムを1つにマージできたので、実質的に以下のようなチャットテンプレートを1つの入力カラム（instruction）と1つの出力で作成できます：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-d54582ae98c396d51bfb85628b46c54f2517d030%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

ただし、必ず `{INPUT}` というフィールドを指示文用に配置し、 `{OUTPUT}` というフィールドをモデルの出力用に配置する必要があります。実際にはオプションで `{SYSTEM}` というフィールドも許可しており、ChatGPTのようにシステムプロンプトをカスタマイズするのに便利です。例えば、以下はいくつかのカスタマイズ可能なかっこいい例です：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-cc455dc380d3d44ef136e485754964159dc773d8%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

OpenAIモデルで使用されるChatML形式の場合：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-15bfca9cfadf10d54b4d3f66e3050044317d62c5%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

あるいはLlama-3のテンプレート自体を使用することもできます（これはLlama-3のinstructバージョンを使用する場合にのみ機能します）：実際にはオプションで `{SYSTEM}` というフィールドも許可しており、ChatGPTのようにシステムプロンプトをカスタマイズするのに便利です。

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-80a2ed4de2ca323ac192c513cac65e9e8bf475db%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

または、乗客が死亡したか生存したかを予測するTitanic予測タスクのように、このColabノートブックにはCSVおよびExcelのアップロードが含まれています： <https://colab.research.google.com/drive/1VYkncZMfGFkeCEgN2IzbZIKEDkyQuJAS?usp=sharing>

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-20911ab305c1a10e85859c703157b80175141eb1%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

## Unslothでチャットテンプレートを適用する

通常チャットMLフォーマットに従うデータセットの場合、トレーニングやファインチューニングのためのデータセット準備プロセスは4つの簡単なステップで構成されます：

* Unslothが現在サポートしているチャットテンプレートを確認：\\

  ```
  from unsloth.chat_templates import CHAT_TEMPLATES
  print(list(CHAT_TEMPLATES.keys()))
  ```

  \
  これにより、Unslothが現在サポートしているテンプレートの一覧が出力されます。例として以下の出力：\\

  ```
  ['unsloth', 'zephyr', 'chatml', 'mistral', 'llama', 'vicuna', 'vicuna_old', 'vicuna old', 'alpaca', 'gemma', 'gemma_chatml', 'gemma2', 'gemma2_chatml', 'llama-3', 'llama3', 'phi-3', 'phi-35', 'phi-3.5', 'llama-3.1', 'llama-31', 'llama-3.2', 'llama-3.3', 'llama-32', 'llama-33', 'qwen-2.5', 'qwen-25', 'qwen25', 'qwen2.5', 'phi-4', 'gemma-3', 'gemma3']
  ```

  \\
* を使用して `get_chat_template` をトークナイザに適用する：\\

  ```
  from unsloth.chat_templates import get_chat_template

  tokenizer = get_chat_template(
      tokenizer,
      chat_template = "gemma-3", # これを適切なchat_template名に変更してください
  )
  ```

  \\
* フォーマット関数を定義します。例：\\

  ```
  def formatting_prompts_func(examples):
     convos = examples["conversations"]
     texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False) for convo in convos]
     return { "text" : texts, }
  ```

  \
  \
  この関数はデータセットをループし、定義したチャットテンプレートを各サンプルに適用します。\\
* 最後に、データセットを読み込み必要な変更を適用しましょう： \\

  ```
  # データセットをインポートして読み込む
  from datasets import load_dataset
  dataset = load_dataset("repo_name/dataset_name", split = "train")

  # mapメソッドを使ってフォーマット関数をデータセットに適用する
  dataset = dataset.map(formatting_prompts_func, batched = True,)
  ```

  \
  データセットがChatMLの"role"/"content"形式の代わりに"from"/"value"キーを持つShareGPT形式を使用している場合、まず変換するために `standardize_sharegpt` 関数を使用できます。修正後のコードは次のようになります：\n\\

  ```
  # データセットをインポート
  from datasets import load_dataset
  dataset = load_dataset("mlabonne/FineTome-100k", split = "train")

  # 必要ならデータセットを"role"/"content"形式に変換する
  from unsloth.chat_templates import standardize_sharegpt
  dataset = standardize_sharegpt(dataset)

  # mapメソッドを使ってフォーマット関数をデータセットに適用する
  dataset = dataset.map(formatting_prompts_func, batched = True,)
  ```

## 詳細情報

データセットが以下のような辞書のリストのリストであると仮定すると：

```python
[
    [{'from': 'human', 'value': 'Hi there!'},
     {'from': 'gpt', 'value': 'Hi how can I help?'},
     {'from': 'human', 'value': 'What is 2+2?'}],
    [{'from': 'human', 'value': 'What's your name?'},
     {'from': 'gpt', 'value': 'I'm Daniel!'},
     {'from': 'human', 'value': 'Ok! Nice!'},
     {'from': 'gpt', 'value': 'What can I do for you?'},
     {'from': 'human', 'value': 'Oh nothing :)'},],
]
```

当社の `get_chat_template` を使用してフォーマットできます。次を選択してください： `chat_template` を次のいずれかに設定できます： `zephyr, chatml, mistral, llama, alpaca, vicuna, vicuna_old, unsloth`、および `mapping` を使用して辞書値をマップします `から`, `value` など。 `map_eos_token` は `<|im_end|>` を学習なしでEOSにマップすることを可能にします。

```python
from unsloth.chat_templates import get_chat_template

tokenizer = get_chat_template(
    tokenizer,
    chat_template = "chatml", # zephyr, chatml, mistral, llama, alpaca, vicuna, vicuna_old, unslothをサポート
    mapping = {"role" : "from", "content" : "value", "user" : "human", "assistant" : "gpt"}, # ShareGPTスタイル
    map_eos_token = True, # <|im_end|>を代わりに</s>にマップします
)

def formatting_prompts_func(examples):
    convos = examples["conversations"]
    texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False) for convo in convos]
    return { "text" : texts, }
pass

from datasets import load_dataset
dataset = load_dataset("philschmid/guanaco-sharegpt-style", split = "train")
dataset = dataset.map(formatting_prompts_func, batched = True,)
```

カスタムチャットテンプレートを自分で作成することもできます！例えば、私たちが内部的に使用しているチャットテンプレートは以下です。必ず `tuple` の `(custom_template, eos_token)` を渡してください。ここで `eos_token` はテンプレート内で使用される必要があります。

```python
unsloth_template = \
    "{{ bos_token }}"\
    "{{ 'You are a helpful assistant to the user\n' }}"\
    "</div>"\
    "<div data-gb-custom-block data-tag="for">"\
        "<div data-gb-custom-block data-tag="if" data-0='role' data-1='role' data-2='] == ' data-3='user'>"\
            "{{ '>>> User: ' + message['content'] + '\n' }}"\
        "<div data-gb-custom-block data-tag="elif" data-0='role' data-1='role' data-2='] == ' data-3='assistant'></div>"\
            "{{ '>>> Assistant: ' + message['content'] + eos_token + '\n' }}"\
        "</div>"\
    "</div>"\
    "<div data-gb-custom-block data-tag="if">"\
        "{{ '>>> Assistant: ' }}"\
    "</div>"
unsloth_eos_token = "eos_token"

tokenizer = get_chat_template(
    tokenizer,
    chat_template = (unsloth_template, unsloth_eos_token,), # テンプレートとEOSトークンを提供する必要があります
    mapping = {"role" : "from", "content" : "value", "user" : "human", "assistant" : "gpt"}, # ShareGPTスタイル
    map_eos_token = True, # <|im_end|>を代わりに</s>にマップします
)
```
