Это решение было разработано для конкурса LMSYS — Chatbot Arena Human Preferences Predictions на Kaggle, где участникам было предложено предсказать предпочтения пользователей в личных беседах между чат-ботами, основанными на больших языковых моделях (LLM). Задача заключалась в использовании набора данных Chatbot Arena , в котором пользователи взаимодействуют с двумя анонимными LLM и выбирают предпочтительный ответ. Создав модель машинного обучения, которая точно предсказывает эти предпочтения, мы стремились внести свой вклад в улучшение соответствия ответов чат-бота предпочтениям человека.
Наша команда успешно заняла 4-е место из 1849 команд , получив золотую медаль за наше решение и приз в размере 20 000 долларов США! ?
Во-первых, мы использовали официальный набор данных (55 000) вместе с 33 000 дедуплицированных данных, применяя 20-кратную перекрестную проверку (n_splits = 20), но обучали только один раз, чтобы максимизировать объем обучающих данных. Кроме того, мы создали псевдометки для 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 . Мы использовали Gemma2ForSequenceClassification для задачи классификации трех классов и настроили модель с помощью lora с точностью bf16 . Наилучшие экспериментальные результаты были достигнуты на четырех графических процессорах A100.
Каждый эксперимент занимал примерно 10 часов на первом этапе и 15 часов на втором этапе в системе с 4 графическими процессорами A100 (40G).
На этапе вывода используется структура кода, аналогичная фазе обучения, с некоторыми ключевыми отличиями: max_length
увеличено до 3072, а response_a и response_b меняются местами в рамках стратегии увеличения времени тестирования (TTA). Конечным результатом является средний выход обоих.
Постобработка применялась для двух конкретных сценариев (которые могут пересекаться):
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, повышающая точность прогнозирования ответов предпочтений пользователей в диалоговой системе.
Ключевые методы :
Даоюань Ли — Профиль на Kaggle
По любым вопросам обращайтесь к Даоюань Ли по адресу: [email protected].