返回列表

26th Solution for LMSYS - Chatbot Arena Human Preference Predictions

620. LMSYS - Chatbot Arena Human Preference Predictions | lmsys-chatbot-arena

开始: 2024-05-02 结束: 2024-08-12 自然语言处理 数据算法赛
LMSYS 聊天机器人竞技场人类偏好预测第 26 名解决方案

LMSYS 聊天机器人竞技场人类偏好预测第 26 名解决方案

作者: Qiwen Shi (及团队)

发布时间: 2024-08-13

比赛排名: 第 26 名

团队成员: Tianhao Liu, Qiwen Shi, OwenZxxxx, Xinyuan Qiao

感谢 Kaggle、LMSYS 以及所有参与提供这次绝佳机会的人!这是我们第一次分享解决方案,我们的工作主要基于 @emiz6413 用于训练和推理的优秀公开 Notebook,以及 @abdullahmeda 处理的 21k 额外数据。我们非常感激他们对本次比赛的贡献!他们的数据集和模型对我们帮助很大。

背景

方法概述

我们的最终模型基于 4-bit 的 Gemma-2-9b 公开 Notebook 开发,公共/私有 leaderboard 得分为 0.893/0.98728。以下是我们做出的修改:

1. 输入格式调整

  • 原始格式: 公开 Notebook 中的标准格式由简单的提示后跟两个响应组成。例如:
    <bos><prompt>: I have three oranges today, I ate an orange yesterday. How many oranges do I have?
    <response_a>: You have two oranges today.
    <response_b>: You still have three oranges. Eating an orange yesterday does not affect the number of oranges you have today.<eos>
  • 我们的适配: 我们为每个提示/响应引入了一个表示轮次编号的前缀,这有助于提高模型的上下文理解能力:
    <bos><prompt>:
    prompt 1: I have three oranges today, I ate an orange yesterday. How many oranges do I have?
    <response_a>:
    response 1: You still have three oranges. Eating an orange yesterday does not affect the number of oranges you have today.
    <response_b>:
    response 1: You have two oranges today.<eos>

2. 动态最大长度分配 (Dynamic Spread Max)

  • 受某个知名 Notebook 的固定数量 spread max 启发,我们实施了一种动态策略来处理超过最大长度的输入:
total_part_length = len_p + len_r_a + len_r_b
proportion_p = len_p / total_part_length
proportion_r_a = len_r_a / total_part_length
proportion_r_b = len_r_b / total_part_length
tokens_to_keep_p = int(proportion_p * self.max_length)
tokens_to_keep_r_a = int(proportion_r_a * self.max_length)
tokens_to_keep_r_b = int(proportion_r_b * self.max_length)
  • 该方法动态计算每个部分的 token 保留量,并在每个提示和响应内递归应用此逻辑。

3. 顺序学习 (Sequential Learning)

  • 最初,我们的模型直接在拼接数据集(21k 额外数据 + 原始训练数据)上训练,显示交叉验证 (CV) 或公共排行榜 (PB) 分数没有 improvement。随后我们切换到顺序训练:先在额外数据上用 1e-4 学习率训练,然后在原始数据上用 1.5e-5 学习率微调。

4. LoRA 配置与调优

  • 我们对 LoRA 参数进行了广泛的修改:
lora_config = LoraConfig(
    r=128,
    lora_alpha=128,
    target_modules=["q_proj", "k_proj", "v_proj","o_proj","gate_proj"],
    layers_to_transform=[i for i in range 42 if i >= 0],
    lora_dropout=0,
    bias="none",
    task_type=TaskType.SEQ_CLS)
  • 重要的是,我们从原始公开 Notebook 中使用的 adamw_8bit 切换到了 adamw_hf,我们发现后者更适合我们的训练动态。训练进行了 1 个 epoch,batch size 为 12,我们将 split 数量从 5 增加到了 10。

验证策略

我们使用了与公开训练 Notebook 相同的验证策略,但将 n_split 增加到了 10。我们观察到验证 loss 与公共排行榜 (PB) loss 之间存在强相关性。

潜在改进与未来方向

  • Alpha 缩放: 最初我们使用 alpha = rank*2;然而,后来的发现表明 alpha = rank 可能会产生更好的结果,我们的最终版本使用了此设置。进一步的调查可以探索更低的比率,如 rank/2 或 rank/4。

  • 截断标记 (Truncation Tagging): 当为超过最大长度的响应/提示添加 <truncation> 标签时,观察到本地 CV 有所 improvement。然而,其对 PB 的影响尚未测试。

  • 双模型 TTA: 虽然我们采用了 TTA (测试时增强),但使用两个分别在非交换和交换响应数据集上训练的模型可能会增强结果。

  • 探索性配置: 其他讨论的策略包括从 4-bit 量化转向 8-bit 量化,使用聊天的模板进行输入(受 Chris 的讨论帖启发 链接),我们还发现 CV/PB 结果在我们的案例中对 batch size 和学习率的选择非常敏感。因此,进一步优化这些设置以获得更好的性能还有空间。

同比赛其他方案