Open4

instruction 系の LLM のプロンプトのフォーマット

ピン留めされたアイテム
PlatPlat

instruction 系 (自分が勝手にそう呼んでる) の LLM は、ユーザーの指示を与えるとアシスタントがそれに対する返信を書くように文章を生成してくれる。

いろんな instruction モデルが存在するが、プロンプト (ここでは適切に応答が返ってくるフォーマットについて) の書き方に関する標準がないせいで書き方が統一されていない...

なので、主要なものや自分がよくつかうモデルのプロンプトのフォーマットをまとめてみる。

参考:

https://huggingface.co/docs/transformers/main/chat_templating

PlatPlat

凡例

ここで使う言葉についての説明

システム指示

これは「優秀なアシスタントとして適切な回答をしなさい」みたいなアシスタントに対する指示のこと。

ユーザーの入力

これは「◯◯について教えて」や「◯◯をやって」みたいな、ユーザーの指示や入力が入る。

アシスタントの返信

これはユーザーの入力に対しての返信が入る。

PlatPlat

LLaMA 2 chat 系

システムプロンプトと応答ニ回のチャット履歴はこうなる。

<s>[INST]<<SYS>>
システム指示
<</SYS>>

ユーザーの入力 [/INST] アシスタントの返信 </s><s>[INST] ユーザーの入力2 [/INST] アシスタントの返信2 </s>

基本的に、こちらからの指示は [INST][/INST] 内に挟み込み、一回のやりとりは <s></s> で挟まれる形になる。

ニ回目以降のやりとりは <<SYS>><</SYS>> を含まずに同様に続けられる。

システム指示の周り以外には特に改行が発生しない形のようだ。

アシスタントからの返信を求める場合は、

<s>[INST]<<SYS>>
システム指示
<</SYS>>

ユーザーの入力 [/INST] アシスタントの返信 </s><s>[INST] ユーザーの入力2 [/INST] 

のように最後の </s> を閉じないことで、[INST] ユーザーの入力2 [/INST] の後ろに アシスタントの返信2 </s> が来て応答が終了する。

EYLZA 7B instruct 系 も同様のプロンプトになる。

なので、 ELYZA の例 を使うとプロンプトは以下のようになる。

<s>[INST]<<SYS>>
あなたは誠実で優秀な日本人のアシスタントです。
<</SYS>>

クマが海辺に行ってアザラシと友達になり、最終的には家に帰るというプロットの短編小説を書いてください。 [/INST] 

注: 最後の [/INST] の後ろには半角スペースが入る

応答を含めると、

<s>[INST]<<SYS>>
あなたは誠実で優秀な日本人のアシスタントです。
<</SYS>>

クマが海辺に行ってアザラシと友達になり、最終的には家に帰るというプロットの短編小説を書いてください。 [/INST] 承知しました。以下にクマが海辺に行ってアザラシと友達になり、最終的には家に帰るというプロットの短編小説を記述します。

クマは山の中でゆっくりと眠っていた。
その眠りに落ちたクマは、夢の中で海辺を歩いていた。
そこにはアザラシがいた。
クマはアザラシに話しかける。

「おはよう」とクマが言うと、アザラシは驚いたように顔を上げた。
「あ、こんにちは」アザラシは答えた。
クマはアザラシと友達になりたいと思う。

「私はクマと申します。」クマは... (略) </s>

となる。

参考:

https://huggingface.co/elyza/ELYZA-japanese-Llama-2-7b-fast-instruct

PlatPlat

ChatML 系 (Qwen chat 等)

ChatML とは、OpenAI の ChatGPT で使われている応答のフォーマットのこと。以前は Azure OpenAI Service で ChatGPT の API を叩くときに使われていたらしい [1] が今は普通に JSON で叩けるようだ。

一部の公開モデルでもこのフォーマットが使われている。(私のお気に入りは Qwen-14B-Chat)

システムプロンプトとニ回の応答履歴はこのようになる。

<|im_start|>system
システム指示<|im_end|>
<|im_start|>user
ユーザーの入力<|im_end|>
<|im_start|>assistant
アシスタントの返信<|im_end|>
<|im_start|>user
ユーザーの入力2<|im_end|>
<|im_start|>assistant
アシスタントの返信2<|im_end|>

システム、ユーザー、アシスタントの入力はそれぞれ <|im_start|><|im_end|> で囲まれ、<|im_start|> の後ろにロール (役割) が置かれる。

また、ロールの後ろとニ回目以降の <|im_start|> の前は必ず改行が入るが、それ以外に改行や空白が入る箇所はない。

ちなみに im_startim_endimI'm のことではなく、input message の頭文字のこと。

アシスタントからの返信が欲しい場合は、

<|im_start|>system
システム指示<|im_end|>
<|im_start|>user
ユーザーの入力<|im_end|>
<|im_start|>assistant
アシスタントの返信<|im_end|>
<|im_start|>user
ユーザーの入力2<|im_end|>
<|im_start|>assistant

とすることで、 アシスタントの返信2<|im_end|> が来る。

参考:

脚注
  1. https://level69.net/archives/33551 ↩︎