🤖
Kaggle 「LMSYS - Chatbot Arena Human Preference Predictions」 まとめ
以下のコンペについて、まとめました。
何をするコンペか
- あるpromptに対して、2つのllm(model_a, model_b)の回答のどちらかが優れているか、もしくは引き分け(tie)か予測する。正解は人間が評価したデータである。
イメージ
引用元
評価方法は?
- log loss
- winner_model_a、winner_model_b, winner_tieの確率を推論し、提出する。
sample_submissionの中身
特徴は?
-
直近のNLPコンペでほぼ有効なDeBERTaを用いてもスコアが上がらず、Gemma2やLlama3などのLLMが有用だった。これは、以下2点が理由と考えられる。関連discussion
- 推論する対象もLLMが生成した文章である。
- Gemma2について、LMSYSのデータをpretrainしている。
-
データはLMSYS Chatbot Arenaでユーザーが回答したものである。つまり、しっかりアノテーションされたデータではなく、ノイジーなデータである。関連discussion1、関連discussion2
- 具体例1: 2つのモデルが同じ回答をしていても、winner_tieではなく、winner_model_a or winner_model_bのことがある。
- 具体例2: promptが"Hey"だけの場合も存在する。
Publicな手法は?
-
Gemma-2 9b Sequence Classification
- Gemma-2 9bにSequenceClassification Headを付与し、Peftを利用する。
-
Llama-3 Sequence Classification
- LLama-3にSequenceClassification Headを付与し、Peftを利用する。
-
Infer 34B with vLLM
- (Classificationヘッダーではなく)生成モデルを利用する。生成トークンのロジットを分類問題の確率として扱い、vLLMで高速化する。
上位ソリューションは?
以下のソリューションをまとめる。
1st 2nd 3rd 5th 9th 16th
- 最終的に使用したモデル
- gemma-2-9b(1st, 2nd, 5th, 9th, 16th)
- sfairXC/FsfairX-Gemma2-RM-v0.1 (3rd)
- RLHFlow/ArmoRM-Llama3-8B-v0.1(2nd)
- RLHFlow/pair-preference-model-LLaMA3-8B(3rd, 9th)
- TTA(1st, 2nd, 3rd, 5th, 9th, 16th)
- response_a, reponse_bの順番を変えて、元のモデルの推論確率と平均をとる。
- loraを全ての線形層に追加(1st, 3rd, 9th, 16th)
- 外部データセット(33k)の利用(1st, 3rd)
- psuedo labeling
- lmsys-chat-1mを利用した(2nd, 9th)
- mlabonne/orpo-dpo-mix-40kを利用した(3rd)
- promptの利用
- LLM-as-a-JudgeのPAB formatを利用した。repo。(2nd)
- <PROMPT></PROMPT>などで囲む(3rd)
- <context>,<response_A>,<response_B>などで区切る(9th)
- Distillation
- llama3 70b、qwen2 72b、gemma2-9bをUltra Feedbackデータで1epoch分Pretrainする → さらに、llama3 70b、qwen2 72bをkaggle train data + 33kを用いて学習する → llama3 70b、qwen2 72bからlogitを得て、Ultra Feedbackデータで1epoch学習済みのgemma-9bの学習に利用した。(1st)
- 5foldのloraレイヤーを平均化した(1st)
-
XXXForSequenceClassification
による初期化は早いiterationで高いlossが出るため、headを再初期化した(2nd) - Pretrain(3-class classification)
- UltraFeedback データで、gemma2-9bをpretrainした(1st, 5th)
- full fine-tuning
- BF16、 optimizer with kahan summation(2nd)
- GPTQを用いて、quantizeされていないモデルを8bitにquantizeした(1st)
- gemma2のlogit softcapをoffにすることで、0.002程度スコアが上がった(3rd)
- swap(response_a, response_bの入れ替えによる学習時のデータ拡張)
- swapによりval_loglossが少し改善した。元のデータとswap後のデータを両方使うことで0.003改善した。(2nd)
- 1epochで2回トレーニングし、各回ではresponse_aとresponse_bを入れ替える。(5th)
- model_a, model_bの名前を追加で予測するよう、headを変更する。(16th)
- truncateする際には、文章を初めの方から落とす(16th)
※ Chris(16th)のSolutionにLLMのハイパラチューニングの手順が書いてあり、参考になる。
参加者のGPUリソース周り
- A100 80G*8(1st)
- Gemma 7bのfull fine-tuningについては、A100 80Gで行った(2nd)
- Gemma 9bのfull fine-tuningについては、A100 2台で行った(2nd)
- コンペ終わりの10日間はA100 80GB × 4を利用した(2nd)
- Nvidia 8xV100 32GB GPUs、場合によってはNvidia 4xA100 80GB GPUs(16th)
- A100 40G*2(自分、会社のリソースをお借りしました。この場を借りて感謝します。)
leak周りについて
- 流れ
- コンペ終了直前に、当時最高のLB(0.88~0.89)を大きく上回るLBスコア(0.6X台)を出すユーザーが出現した。
- 参加者がleakの存在に気づき、何チームかが再現成功。LB1位が0.1X台などになった。
- leakデータの公開が停止された。
- コンペ終了直前に、コンペ終了後にleakなしのtestに差し替えること、leakを使用していないsubを選択するようにすることをを公式が通知した。
- コンペ終了後から約1週間後に、コンペ終了後に新たに作られたデータをテストデータとして差し替え、順位が確定した。
- 何がleakだったのか
- LMSYSが公開していたリーダーボード確認用のColabからコンペのテストデータの回答が取得できた。テキストは存在しないが、トークン長の情報を用いることでコンペのテストデータとleakデータを紐づけることができた。
- 詳細
あなたのチームの順位は?
あなたのチームのソリューションは?
- Gemma2, llama-3のWeight Ensemble(Gemma2: 0.71, llama-3: 0.29)
- Gemma2
- max_length: 3072
- Loraのtarget_modulesを [“q_proj”, “k_proj”, “v_proj”, “o_proj”, “gate_proj”, “up_proj”, “down_proj” ]へと増やす
- FREEZE_LAYERSを0
- 外部データ(33k)の追加
- full train
- prompt, a, bのうち、最も単語数が多い単語から切り詰める
- llama-3
- max_length: 2560
- Gemma2の設定がベースにLlama3用にカスタム
- epoch1.8
responseをオーバーしたら先頭・末尾を残して真ん中を抜く。- 参考元(kinosukeさんTweet)
効かなかったこと
- 外部データ周り
-
Ultra Feedback 157kのデータの利用
- そのまま(GPT-4 rating)
- Gemmaによるpsuedo labeling(hard)
-
Ultra Feedback 157kのデータの利用
- モデル周り
- prompt + response_a, prompt + response_bをそれぞれGemmaのembedし、それらをConcatしたカスタムモデル
- コンペ当初に実験したDeBERTaでは有効だった
- 生成モデルとしてのLlama3の利用
- gemma2 2b, 27bの利用、lossが下がらず
- gemma2 9bのfine-tuning、lossが下がらず
- LMSYSでFine-Tuningしていたjondurbin/bagel-8b-v1.0の利用
- lora_rの変更
- prompt + response_a, prompt + response_bをそれぞれGemmaのembedし、それらをConcatしたカスタムモデル
- loss周り
- focal loss, label smoothing
- LightGBMによる2nd Stage
- テキスト周り
- 「次のテキストに対し、モデルa、bのどちらか良いか選べ」のようなpromptを追加する
- Gemma2のfine tuning時のpromptの利用
- 最後のpromptだけ利用
- prompt, response_a, reponse_bをturnとみなし、turnごとにテキストを与える。
- キャリブレーション後処理として、temprature scaling、Plat Scaling
反省点
- 1.5Bや2Bのような小さいモデルで、実験を早くするべきだった。
- TTAを試さなかった。
- ハイパラチューニングなど、細かい調整に時間をかけてしまった。
- full fine-tuningはOOMが出た時点で諦めてしまったため、メモリ削減が可能かどうかを考えるべきだった。
Discussion