Solusi ini dikembangkan untuk kompetisi LMSYS - Chatbot Arena Human Predictions di Kaggle, di mana peserta ditantang untuk memprediksi preferensi pengguna dalam percakapan tatap muka antar chatbot yang didukung oleh model bahasa besar (LLM). Tugasnya melibatkan pemanfaatan kumpulan data dari Chatbot Arena , di mana pengguna berinteraksi dengan dua LLM anonim dan memilih respons yang mereka sukai. Dengan membuat model pembelajaran mesin yang secara akurat memprediksi preferensi ini, kami bertujuan untuk berkontribusi dalam meningkatkan keselarasan respons chatbot dengan preferensi manusia.
Tim kami berhasil menempati posisi ke-4 dari 1849 tim , mendapatkan Medali Emas untuk solusi kami dan hadiah sebesar $20.000! ?
Pertama, kami menggunakan kumpulan data resmi (55k) bersama dengan 33k data yang dihapus duplikatnya, menggunakan validasi silang 20 kali lipat (n_splits=20), tetapi hanya dilatih pada satu kali lipat untuk memaksimalkan jumlah data pelatihan. Selain itu, kami membuat label semu untuk 30.000 entri dari kumpulan data ultrafeedback untuk melengkapi kumpulan data tersebut lebih lanjut.
Kami merancang prompt unik, yang bermanfaat karena ketika panjang dialog melebihi panjang token maksimum ( max_length
), hal ini memungkinkan pemotongan yang wajar pada putaran terakhir percakapan. Hal ini memastikan bahwa prompt, respon A, dan respon B semuanya dapat ditampilkan secara memadai, menghindari situasi di mana hanya prompt atau respon A yang terpotong. Jika jumlah token yang tersisa di babak terakhir kurang dari 80, seluruh babak percakapan (dan babak berikutnya) akan dibuang. Ambang batas dan proporsi ini ditentukan melalui observasi terhadap set pelatihan.
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 ,
}
Kami memilih gemma-2-9b-it sebagai model awal, yang secara signifikan mengungguli model lain seperti Llama3 8b dan Llama3.1 8b . Kami menggunakan Gemma2ForSequenceClassification untuk tugas klasifikasi tiga kelas, dan menyempurnakan model menggunakan lora dengan presisi bf16 . Hasil eksperimen terbaik dicapai pada empat GPU A100.
Setiap percobaan memakan waktu sekitar 10 jam untuk fase pertama dan 15 jam untuk fase kedua pada sistem dengan 4 GPU A100 (40G).
Fase inferensi menggunakan struktur kode yang mirip dengan fase pelatihan, dengan beberapa perbedaan utama: max_length
ditingkatkan menjadi 3072, dan respon_a serta respon_b ditukar sebagai bagian dari strategi augmentasi waktu pengujian (TTA). Hasil akhirnya adalah rata-rata keluaran keduanya.
Pasca-pemrosesan diterapkan untuk dua skenario tertentu (yang mungkin tumpang tindih):
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 ]
Ikhtisar : Mengembangkan dan mengoptimalkan model prediksi preferensi manusia untuk sistem dialog berdasarkan model gemma-2-9b-it, meningkatkan akurasi dalam memprediksi respons preferensi pengguna dalam sistem dialog.
Teknik Utama :
Daoyuan Li - Profil Kaggle
Untuk pertanyaan apa pun, silakan hubungi Daoyuan Li di [email protected].