このソリューションは、Kaggle の LMSYS - Chatbot Arena Human Preference Predictions コンペティション用に開発されました。参加者は、大規模言語モデル (LLM) を利用したチャットボット間の直接の会話でユーザーの好みを予測することに挑戦しました。このタスクには、 Chatbot Arenaのデータセットの利用が含まれており、ユーザーは 2 つの匿名 LLM と対話し、好みの応答を選択します。これらの好みを正確に予測する機械学習モデルを作成することで、チャットボットの応答と人間の好みの整合性の向上に貢献することを目指しました。
私たちのチームは1849 チーム中 4 位にランクインし、ソリューションに対して金メダルと賞金 20,000 ドルを獲得しました。 ?
まず、公式データセット (55k) と 33k の重複排除データを利用し、20 分割相互検証 (n_splits=20) を採用しましたが、トレーニング データの量を最大化するために 1 分割のみでトレーニングしました。さらに、データセットをさらに補足するために、ウルトラフィードバック データセットから 30,000 エントリの疑似ラベルを作成しました。
私たちは独自のプロンプトを設計しました。これは、対話の長さが最大トークン長 ( max_length
) を超える場合に、会話の最終ラウンドを合理的に切り捨てることができるため、有益です。これにより、プロンプト、応答 A、および応答 B がすべて適切に表示され、プロンプトまたは応答 A のみが切り捨てられる状況が回避されます。最終ラウンドの残りのトークン数が 80 未満の場合、会話ラウンド全体 (およびその後のラウンド) が破棄されます。これらのしきい値と割合は、トレーニング セットの観察を通じて決定されました。
def tokenize_cls_p3 ( example , tokenizer , max_length , is_train ):
input_ids = []
attention_mask = []
dot_tokens = tokenizer ( "......" , add_special_tokens = False )[ "input_ids" ]
final_p_tokens = tokenizer ( " n n --- n Which response is better? [A or B or tie] n Answer: " , add_special_tokens = False )[ "input_ids" ]
for ps , ras , rbs in zip ( example [ 'prompt' ], example [ 'response_a' ], example [ 'response_b' ]):
one_input_ids = [ tokenizer . bos_token_id ]
prev_tokens_num = 2 + len ( final_p_tokens ) # 2 for bos_token and eos_token
for idx , ( p , ra , rb ) in enumerate ( zip ( ps , ras , rbs )):
r_tokens = tokenizer ( f' n n ## Round { idx + 1 } :' if idx else f'## Round { idx + 1 } :' , add_special_tokens = False )[ "input_ids" ]
p_tokens = tokenizer ( f' n ### Prompt: n { p } ' , add_special_tokens = False )[ "input_ids" ]
ra_tokens = tokenizer ( f' n n ### Response A: n { ra } ' , add_special_tokens = False )[ "input_ids" ]
rb_tokens = tokenizer ( f' n n ### Response B: n { rb } ' , add_special_tokens = False )[ "input_ids" ]
all_tokens_num = prev_tokens_num + len ( r_tokens ) + len ( p_tokens ) + len ( ra_tokens ) + len ( rb_tokens
if all_tokens_num > max_length :
remain_tokens_num = max_length - prev_tokens_num - len ( r_tokens ) - 3 * len ( dot_tokens )
if remain_tokens_num >= 80 :
p_tokens = p_tokens [: int ( remain_tokens_num * 0.2 )] + dot_tokens if len ( p_tokens ) > int ( remain_tokens_num * 0.2 ) else p_tokens
ra_tokens = ra_tokens [: int ( remain_tokens_num * 0.4 )] + dot_tokens if len ( ra_tokens ) > int ( remain_tokens_num * 0.4 ) else ra_tokens
rb_tokens = rb_tokens [: int ( remain_tokens_num * 0.4 )] + dot_tokens if len ( rb_tokens ) > int ( remain_tokens_num * 0.4 ) else rb_tokens
one_input_ids += r_tokens + p_tokens + ra_tokens + rb_tokens
break
else :
prev_tokens_num = all_tokens_num
one_input_ids += r_tokens + p_tokens + ra_tokens + rb_tokens
one_input_ids += final_p_tokens + [ tokenizer . eos_token_id ]
one_attention_mask = [ 1 ] * len ( one_input_ids )
input_ids . append ( one_input_ids )
attention_mask . append ( one_attention_mask )
if is_train :
labels = [ 0 if a_win else 1 if b_win else 2 for a_win , b_win , tie in zip ( example [ 'winner_model_a' ], example [ 'winner_model_b' ], example [ 'winner_tie' ])]
return {
"input_ids" : input_ids ,
"attention_mask" : attention_mask ,
"labels" : labels ,
}
else :
return {
"input_ids" : input_ids ,
"attention_mask" : attention_mask ,
}
開始モデルとしてgemma-2-9b-it を選択しました。これは、 Llama3 8bやLlama3.1 8bなどの他のモデルよりも大幅に優れています。 3 クラス分類タスクにGemma2ForSequenceClassification を使用し、 bf16精度のloraを使用してモデルを微調整しました。最良の実験結果は 4 つの A100 GPU で得られました。
各実験には、4 つの A100 GPU (40G) を備えたシステムでの第 1 フェーズで約 10 時間、第 2 フェーズで約 15 時間かかりました。
推論フェーズでは、トレーニング フェーズと同様のコード構造が使用されますが、いくつかの重要な違いがあります。max_length がmax_length
に増加し、test-time Augmentation (TTA) 戦略の一部としてresponse_aとresponse_bが交換されます。最終結果は両方の平均出力です。
後処理は 2 つの特定のシナリオ (重複する可能性があります) に適用されました。
df2 = pd . read_csv ( '/kaggle/input/lmsys-chatbot-arena/test.csv' )
df2 [ 'id' ] = df2 [ 'id' ]. astype ( str )
a_null_df = df2 [( df2 [ "response_a" ] == '[null]' ) | ( df2 [ "response_a" ] == '[]' ) | ( df2 [ "response_a" ] == '[ ]' ) | ( df2 [ "response_a" ] == '[ ]' ) | ( df2 [ "response_a" ] == '[""]' ) | ( df2 [ "response_a" ] == '["",""]' )]
a_null_id_list = a_null_df [ "id" ]. tolist ()
submission_df . loc [ submission_df [ 'id' ]. isin ( a_null_id_list ), [ 'winner_model_a' , 'winner_model_b' , 'winner_tie' ]] = [ 0.04 , 0.88 , 0.08 ]
b_null_df = df2 [( df2 [ "response_b" ] == '[null]' ) | ( df2 [ "response_b" ] == '[]' ) | ( df2 [ "response_b" ] == '[ ]' ) | ( df2 [ "response_b" ] == '[ ]' ) | ( df2 [ "response_b" ] == '[""]' ) | ( df2 [ "response_b" ] == '["",""]' )]
b_null_id_list = b_null_df [ "id" ]. tolist ()
submission_df . loc [ submission_df [ 'id' ]. isin ( b_null_id_list ), [ 'winner_model_a' , 'winner_model_b' , 'winner_tie' ]] = [ 0.88 , 0.04 , 0.08 ]
same_a_b_df2 = df2 [( df2 [ "response_a" ] == df2 [ "response_b" ])]
same_a_b_id_list = same_a_b_df2 [ "id" ]. tolist ()
submission_df . loc [ submission_df [ 'id' ]. isin ( same_a_b_id_list ), [ 'winner_model_a' , 'winner_model_b' , 'winner_tie' ]] = [ 0.06 , 0.06 , 0.88 ]
概要: gemma-2-9b-it モデルに基づいた対話システム用の人間の嗜好予測モデルを開発および最適化し、対話システムにおけるユーザーの嗜好応答の予測精度を向上させました。
主要なテクニック:
Daoyuan Li - Kaggle プロフィール
ご質問がございましたら、Daoyuan Li([email protected])までご連絡ください。