はじめに
8月5日に開催された NVIDIA Model Customization Bootcamp に参加してきました。テーマは、合成データ生成→強化学習(GRPO)→エージェントとして動かす、という一連のパイプラインを一通り体験する内容です。
FPT AI FACTORYでファインチューニング自体はやったことがあったので、恐らく小さいモデルならパラメータ数が少ない分、ファインチューニングの効果が出やすいだろうとは思っていましたが、「今回はどうなるかな」という気持ちで参加しました。
研修で使った生データ(生成された合成データの内容や、学習中の詳細なログなど)をそのまま公開するのは避けたいので、この記事ではパイプラインの構造と、そこに込められた設計判断を中心にまとめます。手元で似たようなことをやろうとしている人の参考になれば、というのが今回の趣旨です。
この記事でわかること
- NeMo Data DesignerとGRPOを組み合わせた、小さいモデルのツール呼び出し学習パイプラインの全体像
- 合成データ生成でハマりやすい落とし穴と、その対策
- GRPOの報酬設計で「形式ボーナス」がなぜ必要なのか
一言でまとめると、「Qwen3-0.6Bみたいな小さいベースモデルでも、正しく設計すれば専用タスクのツール呼び出しを覚えられる」ということを、合成データ生成→強化学習→実行の3ステップで体験した研修のまとめです。
全体のパイプライン
今回のハンズオンは、3本のノートブックに分かれていました。
対象タスクは、LangGraph CLI(langgraph new、langgraph devなど)を自然言語で操作するエージェントです。「agent-pythonのテンプレでプロジェクト作って」のような日本語の指示を、構造化されたJSONのツール呼び出しに変換する部分を、ゼロから学習させます。
① 合成データ生成(NeMo Data Designer)
まず、学習データがそもそも存在しないので、作るところから始まります。ここで使うのがNeMo Data Designerです。
何をしているか
- ローカルでvLLMを立てて、ラベル生成用のモデル(Nemotron系のreasoningモデル)をサーブする
- そのモデルに対して、「CLIコマンド」→「自然言語のリクエスト文」→「構造化ツール呼び出し(JSON)」という3段のデータを生成させる
- 出力の構造はPydanticスキーマで固定し、
command・template・pathなど、コマンドごとに必要な引数を定義しておく
ラベル生成に使うモデルがreasoningモデルだと、そのまま運用すると<think>...</think>の思考過程が出力に漏れ込みます。今回はenable_thinking: FalseをvLLM経由で明示的に指定して、思考トレースを止めていました。地味やけど、これを忘れると後工程が全部おかしくなる大事な設定です。
生成したデータの品質管理
500件生成して終わり、ではありません。生成後に3種類の不良データを機械的にふるい落とす工程が入っています。
| 除外理由 | 内容 |
|---|---|
| 思考トレースの漏れ込み |
enable_thinkingの設定漏れなどで、出力に推論の過程が残ってしまったもの |
| 入力とラベルの不整合 | 自然言語の指示文と、生成された構造化ラベルの内容が一致していないもの |
| 必須引数の欠落 | CLIコマンドとして実行するのに必要な引数(newならpath、buildならtagなど)が欠けているもの |
「生成して終わりじゃなく、検証してから学習データにする」という工程が、合成データ生成では一番大事な部分やと感じました。LLMに生成させたデータは、見た目は綺麗でも、実行可能性の観点では普通に壊れています。ここを甘く見ると、後で学習が変な方向に転びます。
② GRPOによる強化学習
合成データが揃ったら、Qwen3-0.6B-Baseという小さい・未指示チューニングのベースモデルに、そのタスクを覚えさせます。
なぜこの構成なのか
- ベースモデル(未指示チューニング)なので伸びしろが大きく、学習の効果が報酬の推移として観察しやすい
- フルファインチューニングではなくLoRA(低ランクアダプタ)で学習し、計算コストを抑える
- 学習アルゴリズムはGRPO(TRLの
GRPOTrainer)を使用
報酬設計がポイント
GRPOは強化学習なので、「何を報酬にするか」の設計がそのまま学習の質を決めます。今回の設計は、以下の2段構えでした。
-
正解一致スコア: 生成されたツール呼び出しが正解と一致するかを、検証サーバー(NeMo Gym)の
/verifyエンドポイントで判定 - 形式ボーナス: 正解と一致していなくても、有効なJSONを出せていれば+0.3点を加算
この形式ボーナスが無いと、学習の初期(cold start)でモデルがまともなJSONを1つも出せず、報酬が最低値のまま学習が進まない、という状況に陥りやすいです。「惜しい」出力にも部分点を与えることで、学習の立ち上がりを助けています。小さいモデルを強化学習で育てるとき、こういう地味な下駄が意外と効いてきます。
この設計上、学習が進むにつれて報酬(reward)の平均値が右肩上がりになることを想定した作り(ステップごとの報酬をログに出して確認できる仕組み)になっていました。学習がうまくいっているかどうかを、この報酬カーブ1本で判断できるのは、GRPOのようなオンライン強化学習らしいところやなと思います。
学習後は、LoRAアダプタを保存したうえで、ベースモデルとマージした完全なモデルとしても書き出します。
③ エージェントとして動かす
学習済みモデルを、実際にBashコマンドを実行できるエージェントとして動かす部分です。
安全に動かすための工夫
-
Human-in-the-loop: モデルが提案したコマンドは、必ずユーザーが
y/nで確認してから実行する - allowlist: 実行できるコマンドを事前に絞り込んでおく
- インジェクション対策: コマンド文字列の組み立て方に注意を払う
強化学習で学習したモデルは、正解データにない状況で予期しない出力をすることがあるので、「モデルの出力をそのまま実行しない」という安全設計は、この手のエージェントを作るうえで外せないところです。
考察
今回の研修で一番残ったのは、「専用タスクなら、小さいモデル+適切な報酬設計で戦える可能性がある」という気づきです。0.6Bという小さいベースモデルでも、タスクを「自然言語→構造化JSON」という狭い範囲に絞り、報酬設計(正解一致+形式ボーナス)を工夫することで、比較的少ない学習ステップで専用エージェントを目指せる、というのがこのパイプラインの考え方でした。ただ、実際の学習結果は一筋縄ではいかない部分もあり、「設計すればすぐ上手くいく」というほど単純ではないというのも実感です。
一方で、合成データの品質管理(3種類のフィルタリング)や、報酬設計の細かいチューニング(形式ボーナスの重み付けなど)は、実際にパイプラインを組んで動かしてみるまで気づきにくい部分でした。「動くけど微妙に間違っている」データやモデルをどう検出するか、というところに一番手間がかかる印象です。
まとめ
NeMo Data Designerで合成データを作り、GRPOで小さいモデルに専用タスクを覚えさせ、Human-in-the-loopのエージェントとして動かす、という一連の流れを体験した研修でした。個々の技術要素(合成データ生成、強化学習、エージェント実行)は知っていても、実際に繋げて一つのパイプラインとして動かしてみると、「データの品質管理」と「報酬設計」の2箇所に一番手間がかかる、というのが今回の実感です。
おわりに
こうした学習・推論のパイプラインを試すには、GPU環境が欠かせません。FPT CLOUDでもGPU VMやMetal Cloudを使って、こういった検証環境をすぐに用意できます。GPU基盤の選定で悩んでいる方は、FPT AI FACTORYもぜひ選択肢の一つとして検討してみてください。
