Kaggle | Jigsawコンペ振り返りメモ
はじめに
2025/10/24に終了したJigsaw - Agile Community Rules Classificationに参加し、幻の金メダルを獲得しました(*後述)。非常に悔しい結果に終わったので、拙速な内容にはなりますが、コンペの概要、基本解法、上位解法についてまとめました。個人的な復習のためのメモでもありますが、間違い・抜け漏れなどあればコメント等でご指摘いただけると幸いです。
コンペの概要
タスク
Redditのコメントが特定のコミュニティルールに違反しているかどうかを予測するものでした。
たとえばruleとして「金融アドバイスを禁止する」などがあり、コメントがそのルールに違反しているかどうかを判定します。
データセット
-
train.csvには、以下のカラムが含まれていました:-
body: コメントのテキスト -
rule: 違反が判定されるルール -
subreddit: コメントが投稿されたフォーラム -
positive_example_1,positive_example_2: ルールに違反するコメントの例 -
negative_example_1,negative_example_2: ルールに違反しないコメントの例 -
rule_violation: バイナリのターゲット変数 (1: 違反, 0: 非違反)
-
-
test.csvはtrain.csvと同様のカラムを持ちますが、rule_violationは含まれません
評価指標
AUC (Area Under the ROC Curve) でした。そのため純粋な確率値ではなく、ranking処理した予測値を提出するソリューションが多かったです。
その他特徴
-
Probingによるhidden ruleの解明
train.csvには2種類のruleのデータが含まれています。加えて、test.csvには別のruleが存在することがhostから説明されていました。このため、コンペ序盤ではtestデータに有効な合成データの作成は難しいと考えていました。しかしコンペ中盤、Probingによって未知のルールが推定可能であることが指摘されました:(discussion)。
実際に複数のユーザが協力してProbingを行ったことで、hidden rule(4つ)が割り出され、Discussionで共有されていました。
ただし、このProbing情報をうまく利用したチームは見当たりませんでした。 -
データセットの質
前述の通りデータセットにはPositive/Negativeそれぞれに対して2つのexample列が存在していました。
ただし、これはtrain.csv内でも重複が多く、またsubredditやruleごとにラベルにブレがあるなど、使うには工夫が必要なものでした。
また上記のようにtest.csvには未知のルール・データが含まれており、train.csvのデータをそのまま学習に使うだけでは汎化が難しいものでした。
基本解法
公開NoteBookで使用されていた手法について取り上げます。
Test Time Training(以下TTT)
上記のようにtrain.csvのデータだけでは汎化が難しかっため、submit時にtest.csvのexampleデータを利用してモデルのオンライントレーニングを行なう手法です。
従来の埋め込みモデルやDeBERTa系モデルに加え、Qwen2.5 0.5bなどの比較的軽量なLLMを、DeepSpeedなどを用いて高速に学習させる手法が有効でした。
事前学習済みLoRAアダプタによる推論(Qwen2.5 14B,32Bなど)
train.csvや合成データによる事前学習済みのLoRAアダプタを用いて、テストデータの推論を行なう方法です。
コンペ序盤から共有されており、多くのユーザがForkしアンサンブルに組み込んでいました(私も参考にさせていただきました)。
ただし、上位ソリューションではほとんど見られませんでした。
その他(TTT含む)
- BERT系モデルによるClassification(DeBERTa,modernbertなど)
- 埋め込みモデルによるClassification(BGE,E5など)
- 類似度検索とk-NNによる分類(Qwen3 0.6B-Embeddingなど)
- 埋め込みモデルによる距離学習とfaissによるベクトル検索を用いた分類(bge-base-en-v1.5など)
上位解法
本記事執筆時点(2025/10/26)では1st,3rd,6-9th,12-13th,18thのソリューションが公開されていますが、これら(の多く)に共通している点について簡単にまとめました。
Unsloth+QLoRAを用いた高速なTest Time Training/推論
多くの上位ソリューションで、Unslothを用いた高速なTest Time Trainingが採用されていました。
UnslothはVRAM使用量を抑えつつ、かつ高速にLLMをファインチューニングできるフレームワークです。
前述の通り、本コンペではtest.csvのデータを用いたTTTが非常に有効でしたが、公開Notebookでは小規模なモデルのファインチューニングが主でした。対して上位陣はUnslothを用いることで7B~14B程度のモデルのオンライントレーニングを可能にし、かつそれらをアンサンブルすることで高精度を実現していました。
使用されていたモデルを見ると、Qwenシリーズが多く見られ、特にQwen3は確認した上位ソリューション全てで使用されていました。
Qwen3ファミリーからさらに複数のモデルサイズ・種類を組み合わせてアンサンブルすることで、多様性を確保していたようです。
それ以外では、Gemmaシリーズも性能が高かったようです。
なお学習方法ですが、基本的にCausalモデルとして、Yes/Noのトークンを予測する形で学習が行われていました。
-
Qwen 3シリーズ(14B,8B,4b-instruct-2507,Guard-Gen-4B,1.7Bなど) -
Qwen 2.5シリーズ(14B,7B,0.5Bなど) -
Gemmaシリーズ(gemma-2-9b-it,shieldgemma-9bなど) - その他(phi-4,llama3.1-8b,Llama2-13B)
ただそれぞれのソリューションで、損失関数の工夫や並列化の工夫など、差別化が見られました。(詳細追えてなく雑ですが、気になったものを列挙してます)
特にUnslothの高速化の工夫とvLLMの組み合わせは、これを機会に勉強したいと思います...
- train.csvのZero-Shot事前学習LoRAアダプター+TTT(3rd)
- LLMや埋め込みモデルを直接の分類器として使わず,Embeddingを抽出し,古典的MLモデルで分類(3rd)
- Deep Mutual Learningによるオンライン蒸留(6th)
- Gemma2モデルのためのvLLMコードの修正(7th)
- 他ruleのpositive exampleをnegative exampleとして利用(13th)
- Qwen3-32Bを使ったparaphraseによるdata augmentation(18th)
- ruleごとのranking+正規化後処理(1st)
- 推論時に
generate()関数の代わりにforward()関数を使用することで高速化(1st) - 追加データセットの活用とDeberta-large(12th)
なお、具体的な処理時間についても言及されており、たとえば(9th)によれば、Unslothを使うことでSingle GPUでQwen3-4BのTTTを含む推論時間が2.1〜3.0時間に収まっていたようです。
データ処理
前述の通り本コンペのデータはノイズが多かったため、ほとんどのソリューションでデータ処理の工夫が見られました。
とはいっても、概ね以下のような処理が多かったです。
-
subredditはノイズになるため無視 -
rule-commentあるいはrule-body-labelの組み合わせで重複を削除 - ラベルノイズのクレンジング(同じ
rule-bodyに対してラベルが揺れている場合、最頻値に統一など)
感想
まだ全てを読み切れてはいないですが、どのソリューションも奇抜なアプローチをしているわけではない印象です。
ただすべてのチームが細部にわたって工夫を凝らしており、またそれらを組み合わせることで高精度を実現している点が印象的でした。
またこのコンペではオンライントレーニングが非常に有効であった(逆にローカルでモデルを育ててもスコアが伸びなかった)ため、GPUリソースが貧弱な自分でも戦えたのは良かったです。直近のNLP(LLM)系のコンペでは、巨大モデルの事前学習が必要なものが多く、個人で参加するのはつらいものがあるため、こういったコンペが増えると個人的には嬉しいです。
雑記
幻の金メダル
私もこのコンペに参加しており、コンペ終了時点で15th place(暫定Gold)でした。
ただし、その後複数のユーザが不正行為でLBから排除された結果、Goldの枠が14位までとなり、最終的には銀メダルとなってしまいました。
非常に悔しい結果とはなりましたが、あらためて上位ソリューションをまとめているうちに、これは順当な結果だったな...と納得の気持ちも強いです。『勝ちに不思議の勝ちあり。負けに不思議の負けなし。』という言葉に尽きる結果だったと思います。
最後に
チームを組んでいただいたKinosukeさんとkfskyさんにはとても助けていただきました。
私が初めてのチーム参加で、かつ、いろいろと力不足でしたが、とても良い経験をさせていただきました。
この場を借りてお礼申し上げます。
Discussion