question = "<s>[INST] What is your favourite condiment? [/INST]"
answer = "Well, I'm quite partial to a good squeeze of fresh lemon juice. It adds just the right amount of zesty flavour to whatever I'm cooking up in the kitchen!</s> "
next_question = "[INST] Do you have mayonnaise recipes? [/INST]"
# 入力
chat = [
{"role": "user", "content": "Who is the cutest in Madoka Magica?"},
]
tokenizer.use_default_system_prompt = False
tokenizer.apply_chat_template(chat, tokenize=False)
# 出力
<s> [INST] Who is the cutest in Madoka Magica? [/INST]
# heron/datasets/inference_instruction_template.py
def llama2_instruction(content, is_system_message):
if is_system_message:
system_prompt = "You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.\n\nIf a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don\'t know the answer to a question, please don\'t share false information.\n"
prompt = f"[INST] <<SYS>>\n{system_prompt}<</SYS>>\n\n{content} [/INST] "
return prompt
else:
prompt = f"[INST] {content} [/INST] "
return prompt
# ...
def add_inference_instruction_template(content, tokenizer, instruction_template_type, is_system_message):
if instruction_template_type == "llama2":
prompt = llama2_instruction(content, is_system_message)
return prompt
elif instruction_template_type in ("mistral", "mixtral"):
prompt = mistral_instruction(content)
return prompt
elif instruction_template_type == "command-r":
prompt = commandr_instruction(content)
return prompt
elif instruction_template_type == "tinyllama":
prompt = tinyllama_instruction(content, tokenizer, is_system_message)
return prompt
elif instruction_template_type == "none":
prompt = none_instruction(content)
return prompt
else:
prompt = base_instruction(content)
return prompt
【Add Template Prompt】
Instruction Tuning 済みのモデルのテンプレートプロンプトをいい感じに指定できるようにする
Instruction tuning済みのモデル(Instructやchatがついているモデル)は固有のプロンプトテンプレートを持っている。 これらのプロンプトテンプレートは、SFT (+ DPO) の際に使用されている。 このため、このプロンプトテンプレートを用いなかったり、意図しない他のテンプレートを使用してしまうことで、パフォーマンスが低下する可能性がある。 そこで、heron を使用した学習の際にも、使用している Instruction Tuning 済み LLM に適したプロンプトテンプレートを使用して学習することが望ましいと考えられる。
そこで、プロンプトテンプレートを選択して heron を使用して学習できるようにコードを変更することを試みる。
プロンプトテンプレートの例
llama2の場合
mistralの場合
それぞれの公式のテンプレートは 🤗 hugging face でモデルがアップロードされた Repository の tokenizer_config.json の chat_template に入っている。 このテンプレートの使い方については 🤗 Templates for Chat Models を参照していただきたい。
また、
tokenizer.apply_chat_template()
にメッセージリストを渡すことで、tokenizer モデルに基づくテンプレートをもとにプロンプトを作成することができる。 メッセージは、役割”role” (system、user、assistantなど) とテキストのペアになる。(デフォルトのシステムメッセージを有効化したい場合は、
tokenizer.use_default_system_prompt = True
を指定してください)実装には、^ のものを用いれば簡単だと思うが、instruction tuning の際には、一般的にシステムの応答のみのlossを計算するというマスク設計を実施しなければならないため、今回これを直接使うのは難しい…。
したがって、heron では、(応答のみのlossを計算するように)自分でプロンプトテンプレートを作成する必要があった。
heron のプロンプトテンプレート実装の詳細
現状は個別にDatasetを用意して選ぶようにしている。
現状の個別に実装しているものはこちらです。
これらをdatasetのconfigから指定して選択できるようにしたい。
heron/datasets/train_instruction_template.py
実装の重要な部分のみ抽出この
heron/datasets/train_instruction_template.py
をheron/datasets/llava_instruct_datasets.py
のようなデータセットファイルから呼び出して、^ のadd_train_instruction_template
関数を使用することで、訓練データにシステムの応答のみの loss を計算するように、プロンプトテンプレートを付与することができる。また、評価データに関しても、プロンプトテンプレートを付与したいので、
heron/datasets/inference_instruction_template.py
を作成して、heron/datasets/llava_instruct_datasets.py
のようなデータセットファイルから呼び出して、^ のadd_inference_instruction_template
関数を使用する。(但し、評価データに関しては、訓練そのもの(loss計算)を実施しないので、訓練データと比較するとシンプルなコードになる)heron/datasets/inference_instruction_template.py
実装の重要な部分のみ抽出agent
:“human”
or“gpt”
self.processor.tokenizer
: huggingface tokenizerself.instruction_template_type
:configs/datasets
の yamlファイルで指定されたプロンプトテンプレートの種類(”llama2”
,“tinyllama”
,“mistral”
,“mixtral”
,“command-r”
,“base”
,“none”
)の中から指定できるself.is_system_message
: (もしあれば、)デフォルトの system_message を追加するかどうかheron学習実行時のテンプレート指定方法
configs/datasets
以下の yaml ファイルに各テンプレート方式instruction_template_type: llama2
: プロンプトテンプレートの種類を指定system_message: false
: システムメッセージを含めるか否かを指定を記述することで、プロンプトテンプレートを指定できるようにした。
例)
configs/datasets/llava_en_instruct.yaml
の場合実装方針についてはより良いものがあればぜひ教えて下さい! よろしくお願いします!