チャットテンプレートとは
LLM の主要な用途としてチャット機能がありますが,ユーザーと LLM の会話のやり取りは文字列のやり取りでしかないので,どれがユーザーからの要求・質問で,どれが LLM の回答なのか識別する必要があります。
チャットテンプレートとは,この会話の始まりと終わりを表す特殊なトークンを含む文法のことです。
チャットテンプレートはトークナイザーの機能の一部であり,ユーザーから入力されたシステムプロンプトや要求プロンプトを「あらかじめ定められた一定のトークンで区切って」LLM のエンコーダーに伝送します。LLM はこの特定のトークンを目印として会話のやり取りの開始と終了を判断します。またここでは会話を例に取っていますが,会話以外にも FIM(Fill in the Middle)モードというものもあり,これは文章の途中に割り込みで LLM の作成した文字列を挿入するためのモードです。この場合も専用のトークンが用意されています。
ChatML, OpenAI 系
現在最も普及しているのが ChatML でしょう。
ChatML とはOpenAI が開発したChat Markup Language の略称です。チャットマークアップ言語というのが正式な名称です。
似た例として HTML があります。HTML はHyperText Markeup Language の略称であり,これはブラウザが文字列を解釈するための言語であり,ブラウザ表示した場合に描画様式やリンク等の機能を持たせるために使われています。
これと同様に,ChatML は LLM が文字列・会話のやり取りを解釈し,コンテキストを理解しやすくするための目印として使われています。ChatML 以外のマークアップ様式やテンプレートは各種ありますが目的は同じで,LLM が文字列を解釈するためのアシストをするためのものです。
ChatML 様式の例は以下のとおりです。
以下のようなやり取りがあった場合に
{ " role " : " system " , " content " : " You are a helpful assistant. " },
{ " role " : " user " , " content " : " Who won the world series in 2020? " },
{ " role " : " assistant " , " content " : " The Los Angeles Dodgers won the World Series in 2020. " },
{ " role " : " user " , " content " : " Where was it played? " }
トークナイザーで ChatML 形式でマークアップすると以下のようになります。区切り文字として<|im_start|>, <|im_end|>が挿入され,さらにそれぞれのブロックの区切りの意味を持たせるために「system」「user」「assistant」という文字列も挿入されています。
You are a helpful assistant. ## システムプロンプトを入力します。
Who won the world series in 2020? # ユーザープロンプトを入力します。
The Los Angeles Dodgers won the World Series in 2020.<|im_end|> # AIの応答が返信され,<|im_end|>トークンでやり取りが終了します。
わかりやすく改行を入れるとこのような感じの区切りです。初回のみシステムプロンプトを送り,LLM の「役割」「振る舞い」を定義しますが,それ以降はユーザープロンプトと LLM 応答の繰り返しが続きます。
概要がわかったところで,ollama 形式に合わせて template, stop toke を整理していきます。
ollama ではシステムプロンプト,ユーザープロンプト,応答が以下のような形式 で定義されています。
変数 定義 {{ .System }}
システムプロンプト {{ .Prompt }}
ユーザープロンプト {{ .Response }}
LLM からの応答。(省略されることがある)
ollama 以外のバックエンドをお使いの場合は上記の書き方をそれぞれのバックエンドサーバーの仕様に合わせて読み替えてください。
システムプロンプトあり
{{ .Response }}<|im_end|>
または
STOP token
PARAMETER stop "<|im_start|>"
PARAMETER stop "<|im_end|>"
Llama2 Chat, Mistral(Codestral など Mistral 系含む)
当初 Meta の Llama2 モデルで採用されていたテンプレート形式で,後に Mistral でも使われるようになりました。
Meta は ChatML に移行していますが,Mistral では現在の最新のモデルもこの Llama2 と同様のテンプレートが使われ続けています。
Mistral
やり取り例
システムプロンプトありの場合以下のようになります
{{ .Prompt }} [/INST] {{ .Response }}</s>
<s>[INST] {{ .Prompt }} [/INST] {{ .Response }}</s> # このやり取りが基本形
<s>[INST] {{ .Prompt }} [/INST] {{ .Response }}</s>
<s>[INST] {{ .Prompt }} [/INST] {{ .Response }}</s>
システムプロンプトあり
システムプロンプトなし
<s>[INST] {{ .Prompt }} [/INST]
または
<s>[INST] {{ .Prompt }} [/INST]
STOP token
Gemma 系
Geema
{{ .System }} {{ .Prompt }}<end_of_turn>
{{ .Response }}<end_of_turn>
STOP token
PARAMETER stop "<start_of_turn>"
PARAMETER stop "<end_of_turn>"
DeepSeek 系
DeepSeek Coder V2
Assistant:{{ .Response }}
STOP token
PARAMETER stop "Assistant:"
Cohere Command-R 系
Command-R
システムプロンプトあり
<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>{{ .System }}<|END_OF_TURN_TOKEN|><|START_OF_TURN_TOKEN|><|USER_TOKEN|>{{ .Prompt }}<|END_OF_TURN_TOKEN|><|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>{{ .Response }}<|END_OF_TURN_TOKEN|>
システムプロンプトなし
<|START_OF_TURN_TOKEN|><|USER_TOKEN|>{{ .Prompt }}<|END_OF_TURN_TOKEN|><|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>{{ .Response }}<|END_OF_TURN_TOKEN|>
または
<|START_OF_TURN_TOKEN|><|USER_TOKEN|>{{ .Prompt }}<|END_OF_TURN_TOKEN|><|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>
STOP token
PARAMETER stop "<|START_OF_TURN_TOKEN|>"
PARAMETER stop "<|END_OF_TURN_TOKEN|>"
Llama3 系
Llama3
システムプロンプトあり
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
{{ .System }}<|eot_id|><|start_header_id|>user<|end_header_id|>
{{ .Prompt }}<|eot_id|><|start_header_id|>assistant<|end_header_id|>
{{ .Response }}<|eot_id|>
システムプロンプトなし
<|begin_of_text|><|start_header_id|>user<|end_header_id|>
{{ .Prompt }}<|eot_id|><|start_header_id|>assistant<|end_header_id|>
{{ .Response }}<|eot_id|>
または
<|begin_of_text|><|start_header_id|>user<|end_header_id|>
{{ .Prompt }}<|eot_id|><|start_header_id|>assistant<|end_header_id|>
STOP token
PARAMETER stop "<|start_header_id|>"
PARAMETER stop "<|end_header_id|>"
PARAMETER stop "<|eot_id|>"
Granite
Granite
システムプロンプトあり
<|start_of_role|>system<|end_of_role|>{{ .System }}<|end_of_text|>
<|start_of_role|>user<|end_of_role|>{{ .Prompt }}<|end_of_text|>
<|start_of_role|>assistant<|end_of_role|>{{ .Response }}<|end_of_text|>
システムプロンプトなし
<|start_of_role|>user<|end_of_role|>{{ .Prompt }}<|end_of_text|>
<|start_of_role|>assistant<|end_of_role|>{{ .Response }}<|end_of_text|>
または
<|start_of_role|>user<|end_of_role|>{{ .Prompt }}<|end_of_text|>
<|start_of_role|>assistant<|end_of_role|>
STOP token