はじめに
噂では4000人規模で受講生がいるらしい東大松尾・岩澤研究室主催のLLM講座応用編2025のメインコンペに参加しました。コンペはメインコンペ(予選)とアドバンスドコンペ(決勝)の2トラック制で、メインコンペのスコア上位者がアドバンスドに進めるという仕組みです。リーダーボード上では予選〆切時点で参加者が約550人でした。その中で約50位で無事アドバンスドに進めました~♪
(リーダーボードでは最新スコアで上書きされていくので、あくまで〆切時点の最新スコアの順位です)
1週間弱の超短期決戦で、リソース(コンペに割く時間、計算資源、お金(笑))が限られるハードなコンペでしたが、無事決勝に駒を進められて良かったと思います。。。
この講座でLLMを本格的に勉強し始めたほぼLLM初学者の私が、どのような工夫で勝ち残ったかについてまとめたいと思います。
※ LLM初学者ですが、DeepLearningや古典的な機械学習、データ分析にはある程度精通してます
※ 予選の〆切で一旦順位付けされましたが、メインコンペは現在進行形のため、工夫点の紹介は概要にとどめます。メインコンペ終了後、詳細版を記事にするかもしれません。
コンペ概要
本コンペではQwen系列の小規模な事前学習済LLMをベースに、独自の追加学習を行い、出力の品質を評価するというものです。評価には、StructEvalというベンチマークを一部改変した独自ベンチマークが用いられました。Struct EvalはLLMにおける構造化データの生成能力を計るベンチマークで、テキスト生成能力を計るStruct Eval-Tと、レンダリングを必要とする構造化データの生成能力を計るStruct Eval-Vの2つの評価セットで構成されます。
今回のコンペでは前者のStruct Eval-Tが用いられました。Struct Eval-T(以下、StructEval)はCSV/JSON/XML等の構造化データを正確に出力できるかを評価するもので、ソフトウェア開発向けのシステムやAIエージェントワークフローへの応用を意識した設計になっています。Struct Eval-Tは下記2つのタスクに分類されます。余計な文章やキーを含めず、厳密且つ必要十分な構造化データを出力できるかが問われます。
-
生成(Generation)タスク
自然言語で指示を与え、構造化データを出力させる
指示文の例)Please output JSON code. ... -
変換(Conversion)タスク
指示文の例)Transform this CSV data int TOML format: ...
計算機環境差異による公平性の確保や、ライセンス既定等の都合から、主なコンペルールとして以下の項目が設定されました。
- 所定のモデル以外の使用は禁止、アーキテクチャの変更も不可
- 所定のデータセットリスト以外の使用は禁止
- 人手やプログラムによるデータ加工はOKだが、LLMを用いた処理は一切禁止
- モデルの推論結果にいかなる処理も加えてはいけない
- 採点基準の詳細は非公開
最後の2つの項目は、特定の評価観点や評価の癖に過剰に適合するのではなく、正しい構造を安定して生成する汎化性能を真正面から計るために設定されたものです。
コンペで配布されたもの
事務局から以下が配布されました。スクラッチ開発ではなく、かなり丁寧な標準コードが提供されました。
- 各種データセット(CoT向け/Instruction向けで複数)
- SFT(Supervised Fine-Tuning)用の標準コード
- DPO(Direct Preference Optimization)用の標準ラインコード
- 推論用の標準コード
試したこと・工夫点(改善効果があったもの)
色々試した中でTestスコア(リーダーボード上)の改善があったものを中心に記載していきます。標準コードが提供されたとはいえ、超短期決戦である中、LLMの学習にかなり時間がかかるので、シンプルで時間がかかりすぎず、コスパが良さそうな対策を中心に進めていきました。
標準ベースラインのスコア確認
SFTで0.68038, DPOで0.69428でした。これだけで講座修了のためのボーダーラインにほぼ到達する水準でした。
ハイパラチューニング
SFTのTrain,Validationロスの推移から、過学習の傾向は見られずスコア改善の伸びしろがありました。そこでハイパラをチューニングすると、スコアが0.78555と大幅に改善(当時のリーダーボードでいきなり2位に浮上)しました。
学習時の特定カテゴリのアップサンプリング
(※ アップサンプリングの実装ミスで、実は単なるスコアのぶれであることに後で気づきました)
Testデータのタスク別のサンプル数を比較すると、GenerationよりもConversionの比率が高く、Conversionの重要度がより高いと予想されました(評価基準は明かされていませんが、両タスクが均等に評価される前提)。また、Conversionの方がルールベースでの構文解析を行いやすかったため、Testデータに対するConversionの推論傾向を重点的に分析することにしました。具体的には、以下の考え方で機械的に(ルールベース)で処理しました。QueryとAnswerのkey, valueのマッチング度から、簡易的に見逃しと誤検出の性能を計ろうという意図です。
- 推論結果を所定の構造化形式でパースし、パース出来たものだけ残す
- パースできたもののうち、Query(指示文)内に含まれる構造化データのkey, valueペアと、Answer(回答)に含まれる構造化データのkey, valueペアを抽出
- QueryとAnswerのkey, valueのマッチングを取り、Recall, Precision, F1スコアを計算
上記の結果、明らかにスコアが低い(F1スコアが0になる)カテゴリがありました。したがって、弱点タスクを重点的に学習させる狙いで、学習時にスコアが低いカテゴリのサンプリング率を高める工夫をしました。結果、スコアが0.78555⇒0.79003に若干改善しました(と思ってましたが、冒頭にもある通り単なるスコアのブレであることに後で気づきました)
学習データのクリーニング
Testデータの推論結果をさらに細かく分析した結果、構造化データ以外の余計な文章が出力されてしまう問題に気付きました。これはおそらく、ベースモデルがCoTを前提に学習されており、ベースモデルの癖が出力されてしまったからと推測されます。SFTの過程で、構造化データ部分に限定してLossをかけているため、前段に余分な文章をつけてもロスには影響しない、という根本的な問題があります。
【Generation】
- コードブロック混入(主にTOML形式で多発)
例)'''toml'''
【Conversion】
-
コードブロック混入
-
前置きテキスト混入
例)Here's the provided CSV data converted into a peorperly structured JSON object... -
CoT混入
例)Let's t think step by step...
そこで大胆な見切りですが、正解データのassistant部分からCoTの文章を除き、純粋な構造化データ部分に限定することにしました。CoTをスキップさせてSFTする(CoTを誘導しない)ことによる精度悪化の懸念と、これだけでベースモデルの学習時の癖(分布)を変えられるかという疑問はありましたが、トライしてみたところ0.79003⇒0.79521と若干の改善。実際に推論結果を見ると、CoT混入問題は完全に解消され、コードブロック混入・前置きテキスト混入問題が起きるサンプルも激減しました。
その他試したこと・工夫点(改善効果が無かったもの)
上記以外で、色々と試したけどTestスコアの改善にはいたらなかった工夫点を書きます。
SFT向け学習データセットの合成
SFT標準コードで使っているCoT系のデータセットを他のものに置き換えたり、Instruction系のデータセットを混ぜたりしてみましたが、精度改善しませんでした。いたずらに合成してサンプルを増やすのは処理時間を延ばすだけですし、特にCoT系の方はあるデータセットをベースに機械的にN増しさせたように見えたので、SFTの汎化性能向上に寄与する可能性は低いと判断し、早々に見切りをつけました。
(よく分析するとそうでもないかもしれませんが、時間が限られてたので)
SFT→DPOの2段階学習
時間が限られていたので、序盤にほぼ脳死状態でSFT→DPO(両方とも標準データセット)の2段階学習を試しましたが精度改善しませんでした。DPOの学習初期の時点で報酬が高くサチっている傾向で、学習履歴からも明らかに改善は見られませんでした。
後でよくよく考えてみると、DPOの使いどころを全く理解できていなかったなと反省しました。DPOの標準データセットは、構造化出力のポジ・ネガのラベルがなんらかの考え方でふられていたようですが、それは今回SFTしたモデルの弱点を補完するようには当然作られていないので、効かないのはある意味当たり前。
もしやるなら、残存するコードブロック混入問題・前置きテキスト混入問題の対処として、余計な文章が入ったものをrejected, 入っていないものをchosenにした疑似データを作りDPOさせる案があるかと思いました。
アップサンプリングのバリエーション
Conversionには色々なType(csv to json, xml to yaml等)があるので、先述のF1スコアを見ながらいくつか重み付けのバリエーションを試してみました。スコアは0.77~0.79とぶれましたが、先述の通り、実は実装ミスでアップサンプリングは機能していませんでした。したがって0.77~0.79の幅は、LLMの学習・推論過程の確率的なブレによるものです。
RandomSeed含め全く同じ条件にもかかわらず、これだけスコアがぶれるのは驚きでした。要因は、LLMの行列演算では、数式的には等価でも結果が変わる可能性があるためです。詳細は下記に記載されているのでご参考に。
学び、良かったこと
-
データは嘘をつかない
今回色々試してみて結果的に効果があったのは、推論傾向や学習過程の分析から、明確な仮説と対策があり「これはいけそう」と確信が持てるものでした。逆になんとなく入れた対策は、ことごとく精度改善にはいたりませんでした。もちろんスコアへのインパクトを正確に予想するのは不可能ですが(実際、ちょっとしたハイパラ調整で劇的に精度が上がるのは驚きでした)、実データに立脚した仮説検証サイクルの重要性を身に染みて感じました。 -
ちょっとしたスコアのブレに騙されてはいけない
先述の通り、全く同じ条件でもスコアがかなりブレました。LLM開発に限らず一般論として言われることですが、そのスコア差が統計的に意味があるものか、より強く意識することになりました。 -
Weight & Biasの活用、可視化
数行でハイパラ管理と学習ログの管理ができるので、コンペ期間中とても重宝しました。また、これで学習過程をちゃんと追ってたので、Testスコアは変わったけどTrain・Validationのスコアがほぼ同じだと何かおかしい、という風に実装ミスに気づけました。 -
円滑な開発環境の用意(Google Colab Proの課金)
「計算環境の差でコンペ結果に差が生まれるのは不公平」という事情を考慮し、無料枠のT4でも動かせるレベルにするための、運営側の配慮とルール設計の尽力には頭が上がりません。ですが無料枠の範囲で挑むのには、限界を感じました。小規模なLLMといえどそれなりに時間がかかりますし、今回のような超短期決戦の中では、複数の仮説検証をいかに早く回すかが勝敗を分けるので。LLM開発における計算機環境構築の重要性を実体験として感じました。結果的にGoogle Colabの有料枠で少し課金しました。笑 -
受講生同士のナレッジシェア
私はコンペ〆切に存在に気付きましたが、コンペ向けのSlackチャンネルがあり、日々ナレッジシェアと熱い議論が繰り広げられていました。「たしかに」「わかるわかる」と思う話題や、「こんなアプローチもあるんだ」という気付きが多く、大変学びになっています。色々なレベルの方がいますが、学びや疑問を発信するのは、双方にとってメリットがあることを改めて実感しました。
リポジトリ
今回のコンペで作成したモデルをHuggingFaceで公開してます。
https://huggingface.co/kuririrn/qwen3-4b-structured-output-lora-tuned_param_v2-without_cot
まとめ
本記事では、「松尾研LLM講座2025 応用編」メインコンペにおいて、LLM初学者に近い立場から、限られた時間と計算資源の中でどのようにスコアを伸ばしたかを振り返りました。
振り返ってみると、成果につながった工夫の多くは「派手な手法」ではなく、
- 推論結果・学習ログを丁寧に観察する
- スコア悪化の原因を構造的に分解して仮説を立てる
- 効果が薄いと判断した施策は早めに切る
といった、ごく基本的だが地道な分析と意思決定でした。
特に今回のStructEval系タスクでは、
- 「余計な文章を出さない」という制約が極めて本質的
- CoTやコードブロックは 能力 ではなく ノイズ になりうる
- 評価関数がブラックボックスな状況ほど、出力そのものを観察する重要性が増す
という点を、実体験として強く学びました。
また、LLMでは同一条件でもスコアが大きくぶれること、DPOなどの手法も「目的とデータ設計を理解せずに使っても効かない」ことなど、書籍や講義だけでは得にくい知見も多く得られました。
短期間ながらも非常に密度の高いコンペであり、
「LLMを 使う 側から 育てる・評価する 側に一歩踏み込む」良い機会だったと感じています。
メインコンペ終了後には、
- より定量的な分析
- DPO用データ設計の掘り下げ
- 実装ミスを踏まえた再検証
なども含めて、詳細版の記事を書くかもしれません。
同じ講座・コンペに参加されている方、これからLLMの学習や評価に取り組む方の参考になれば幸いです。
最後にこのコンペを用意してくださった運営の皆様に心から感謝申し上げます。
参考文献
松尾研LLM講座・コンペ関連
-
東京大学 松尾・岩澤研究室
「大規模言語モデル(LLM)講座2025 基礎編・応用編」
https://weblab.t.u-tokyo.ac.jp/news/%E3%80%8C%E5%A4%A7%E8%A6%8F%E6%A8%A1%E8%A8%80%E8%AA%9E%E3%83%A2%E3%83%87%E3%83%ABllm%E8%AC%9B%E5%BA%A72025-%E5%9F%BA%E7%A4%8E%E7%B7%A8%E3%83%BB%E5%BF%9C%E7%94%A8%E7%B7%A8%E3%80%8D%E5%8B%9F%E9%9B%86/ -
StructEval: Measuring Structured Data Generation in LLMs
https://github.com/struct-eval/struct-eval
SFT / DPO / 学習手法
-
Ouyang et al., Training language models to follow instructions with human feedback, NeurIPS 2022
https://arxiv.org/abs/2203.02155 -
Rafailov et al., Direct Preference Optimization: Your Language Model is Secretly a Reward Model, NeurIPS 2023
https://arxiv.org/abs/2305.18290 -
Zhang et al., Understanding the Impact of Chain-of-Thought on LLM Outputs
https://arxiv.org/abs/2307.12375
Hugging Face / 実装・運用
-
Hugging Face Transformers Documentation
https://huggingface.co/docs/transformers -
Hugging Face PEFT (LoRA) Documentation
https://huggingface.co/docs/peft -
Weight & Biases Documentation
https://docs.wandb.ai/
推論の非決定性・再現性
- Thinking Machines Lab, Defeating Nondeterminism in LLM Inference
https://thinkingmachines.ai/blog/defeating-nondeterminism-in-llm-inference/