LFM2.5-350M GRPOファインチューニングでIFStructスコアを29.7%まで向上

TL;DR

350MパラメータのLFM2.5モデルを、Group Relative Policy Optimization (GRPO)でたった100ステップ、約500サンプルでファインチューニングすると、IFStructの構造化出力準拠率が**22.6%から29.7%**に上昇し、7.1ポイントの向上を達成。これは、はるかに大きなモデルとの差を縮めることに成功した。


構造化出力準拠の重要性

構造化出力とは、文法的に正しい形式で、規定されたスキーマに従ったデータを返すことを意味します。これは、LLMを下流システムに統合するための前提条件です。多くのベンチマークは、単純な推論能力を測定するだけで、この要件を無視しがちです。IFStructはスキーマ準拠を明確に分離しており、実世界での展開可能性を信頼できる指標として機能します。

"モデルが要求された形式と構造で、信頼性高く有効な、パース可能な出力を返すかどうか——すなわちスキーマ準拠——は、それが下流システムに接続可能かどうかを決めることが多い。" – Hugging Faceブログ

LFM2.5-350Mのベースライン評価

  • モデル: LiquidAI/LFM2.5-350M (GGUF BF16) は llama.cpp で提供。
  • 設定: サービングに無料TierのColab/Kaggle GPUを使用;評価はApple M5 Max、36 GBメモリのMacBook Pro上でIFStruct評価ツールを使用。
  • 結果: 全体の通過率は22.6%(2000サンプル中452個)。詳細な内訳:
    • JSON: 18.0%
    • YAML: 27.2%
    • ラッパーキー: 28.5%
    • バーリスト: 16.6%
  • 一般的なエラー: 必須フィールドの欠落、アイテム数の不一致、型の不一致、閉じられていないコードブロック。

これらの数値は、元のIFStructリリースで報告された21.1%と非常に近いものであり、ベースラインの妥当性を確認しています。


GRPOファインチューニングパイプライン

このワークフロー全体はGitHub上の公開ノートブックとして利用可能で、無料TierのGPU上で実行可能です。

学習データ

  • ソース: nvidia/Nemotron-RL-instruction_following-structured_outputs(約500サンプル)。
  • 拡張:
    • プロンプトの40%に「出力を囲みコードブロック内に返す」という指示を追加し、形式指示に従うことを学習させる。
    • 20%をトップレベル配列タスクに変換し、正しいバーリスト生成とアイテム数準拠を促進する。

モデルとLoRAアダプタ

lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    bias="none",
    task_type="CAUSAL_LM",
    target_modules=[
        "q_proj", "k_proj", "v_proj", "out_proj", "in_proj",
        "w1", "w2", "w3",
    ],
)
  • 学習対象パラメータは約600万(350Mモデルの約1.66%)。

リワード関数

3つのスカラー報酬(0〜1)で構造的正確性を評価する:

  1. json_format_reward – 出力をパースして、要求された形式(囲みコード vs. ロウ)を確認。正確な形式で完全報酬、誤りだがパース可能で0.2、パース不可能で0。
  2. field_count_reward – トップレベルフィールド数を期待値と比較;不一致は線形減衰。
  3. schema_validation_reward – 提供されたJSONスキーマに基づいて検証;必須キーの欠落や制約違反をペナルティ。

組み合わせ報酬は重み付き和で、reward_weights = [1.0, 0.5, 2.0]

学習設定

training_args = GRPOConfig(
    output_dir="./outputs/lfm25-350m-nemotron-schema-grpo",
    learning_rate=5e-5,
    max_steps=100,
    warmup_steps=10,
    num_generations=8,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=8,
    steps_per_generation=2,
    max_completion_length=1024,
    mask_truncated_completions=False,
    temperature=1.1,
    beta=0.01,
    reward_weights=[1.0, 0.5, 2.0],
    logging_steps=1,
    save_steps=100,
)
  • 100回の最適化ステップ、1プロンプトグループあたり8回のサンプリング完了、控えめなKLペナルティ(beta=0.01)。
  • 16GB GPU上で1時間未満で学習が完了。

LoRAのマージ

学習後、LoRAアダプタをベース重みにマージし、単一のチェックポイントとして保存。これにより、llama.cppのGGUF変換が可能になる。


ファインチューニング後のIFStruct結果

  • モデル: マージ済みGRPOチューニングチェックポイントをBF16 GGUFに変換。
  • サービング: ベースラインと同一のllama.cppパラメータ、異なるエイリアスとポート。
  • 結果: 全体の通過率は29.7%(2000サンプル中594個)。
    • JSON: 31.9%(↑13.9ポイント)
    • YAML: 27.5%(↑0.3ポイント)
    • ラッパーキー: 29.7%(↑1.2ポイント)
    • バーリスト: 29.7%(↑13.1ポイント)
  • エラーの傾向変化: 必須フィールドの欠落が減ったが、依然として型の不一致や余分なフィールドが見られる。
メトリクス ベースライン GRPOチューニング済み Δ
全体 22.6% 29.7% +7.1
JSON 18.0% 31.9% +13.9
YAML 27.2% 27.5% +0.3
ラッパーキー 28.5% 29.7% +1.2
バーリスト 16.6% 29.7% +13.1

改善は、報酬信号が集中したJSONフォーマットとバーリスト生成に限定されており、GRPOアプローチの有効性を裏付けている。


意味と教訓

  • コスト効率の高いスケーリング – 約500サンプルで100ステップのGRPO実行は、無料TierのColabセッションより安価でありながら、構造化出力準拠率を7ポイント向上させる。
  • モデルサイズのパリティ – チューニング済みの350Mモデルは、2Bパラメータモデル(Qwen3.5-2BはIFStructで33.15%)の性能に迫るが、はるかに小さく、実行コストも低い。
  • リワード設計の重要性 – フォーマット、フィールド数、スキーマ検証に対する明示的なリワードは、ターゲット出力形式の通過率向上に直接つながる。
  • 再現可能性 – すべてのスクリプト、データリンク、変換手順が公開されており、研究者が他のモデルやデータセットで実験を再現または拡張できる。

再現方法

  1. ブログに記載された通り、uvllama.cpp、IFStruct評価スクリプトをインストール。
  2. ノートブックリポジトリをクローンし、提供されたGRPOConfigでGRPOファインチューニングセルを実行。
  3. LoRAアダプタをマージし、チェックポイントをGGUFに変換、llama-serverでサービング。
  4. サービングされたエンドポイントに対してIFStruct評価ツールを実行。

すべてのコマンドとURLは、元のHugging Face投稿と完全に同一。


制限

  • 学習データ(約500サンプル)は、大規模なRLHFで使用されるデータのほんの一部であり、効果はすぐに飽和する。
  • YAML出力では改善が限定的であり、現在のリワード重みがJSONフォーマットに偏っている可能性を示唆している。
  • ベンチマークは依然として合成タスクを反映しており、実世界の統合では追加のエッジケースが現れる可能性がある。

今後の方向性

  • より多様なスキーマとフォーマット(XML、CSVなど)を学習データに追加し、準拠範囲を広げる。
  • 代替のリワード重みや追加の制約(例:論理的一貫性)を実験する。
  • 同じGRPOパイプラインを他のコンパクトモデル(例:200Mパラメータバージョン)に適用し、スケーラビリティを評価する。

参考文献

Sources