674. Jigsaw - Agile Community Rules Classification | jigsaw-agile-community-rules
代码链接见 这里。
我想感谢 Kaggle 和 Jigsaw 组织并 hosting 了这个有趣的竞赛。这是一个探索 LLM 微调实践方面的绝佳机会。
已知信息:
然而,为了构建强大的本地验证,我们仍然需要为这四条新规则生成真实的评论——这是一项不平凡的任务。
我认为公共榜(Public LB)是更好的验证选择,原因如下:
因此,所有模型都是在线微调并使用公共榜进行验证的。
这个 notebook 为数据处理和微调提供了极好的基线。其想法是利用 test.csv 中的正负样本作为训练数据。我对数据处理流程的主要修改如下:
最初,我使用原生 transformers + pytorch 代码,效果很好,早期通过集成 Qwen3-4b-instruct-2507, llama3.2-3b, 和 phi-4-mini-instruct 在公共榜上达到了 0.931。然而,由于内存限制,我无法扩展超过 7B 的模型。后来,我切换到了 Unsloth,它的内存效率更高——它可以轻松地将 14B 模型适配到 16GB 的 GPU 内存中。
在微调之前,我将 test.csv 中的样本上采样了一次以增加其权重,然后微调了一个 epoch。这相当于 train.csv 的一个 epoch 和 test.csv 的两个 epoch。
Chat templates 可能会在"Yes"或"No"目标前后引入不必要的 token,例如 Qwen3 模型中的"\n\n\n\n",以及"Yes"或"No"目标后的一个或多个 token。默认情况下,微调也会对这些额外的 token 应用损失,这是不必要的并且会减慢训练速度。
为了解决这个问题,我手动将这些 token 从损失计算中排除,确保只有"Yes"或"No"token 贡献损失。这一步的额外好处是它标准化了不同模型的训练行为,导致更一致的收敛速度,并允许我在不同模型之间使用单一的一组超参数。
由于最后一层线性层映射到整个词汇表,即使是在 Yes/No token 上微调后,概率仍可能分散在其他 token 上。所以我为许多变体构建了一个首 token 候选集:
这些变体是通过本地实验输出最频繁的前 K 个预测 token 获得的。对于评分,我输出的概率等价于 Yes_ids 与 No_ids 的对数几率的 sigmoid。
其他加速推理的技巧包括:
对于每个模型的输出,我计算了每条规则的排名,将分数归一化到 [0, 1] 范围,然后基于这些归一化值进行集成。此后处理步骤提供了一致的改进,在早期测试中将公共榜分数从 0.929 提高到 0.931。
| 模型 | 公共榜 | 私有榜 |
|---|---|---|
| Qwen3-14b | 0.9297 | 0.9239 |
| Qwen2.5-14b | 0.9287 | 0.9232 |
| Qwen3-8b | 0.9272 | 0.9236 |
| Qwen3-4b-instruct-2507 | 0.9258 | 0.9198 |
| llama3.1-8b | 0.9257 | 0.9202 |
| Ettin-400M | 0.8991 | 0.8944 |
| ensemble | 0.9344 | 0.9293 |