「ファインチューニング(FT)は何に効くのか」——その答えを、自前で14万件・QLoRA学習した実例で示します。災害リスクを妖怪キャラクターが優しく説明し、毎回パースできる構造化JSONで返す「妖怪ハザードマップ」のAIです。最適化の順序で述べた「形式はFT・事実は外部」を、そのまま形にしたケースになります。
本モデルの学習は「ローカルLLMに向き合う会」の inai17ibar 様・サルドラ様よりGPU環境をお借りして実施しました(末尾に謝辞)。
何を作ったか
地図をクリックすると、その地点の災害リスクを分析し、担当の妖怪——河童(水害)・大ナマズ(地震)・土蜘蛛(土砂)・火車(火災)・雪女(雪害)・ヒノカグツチ(火山)ほか——が会話で説明し、VOICEVOXが音声で読み上げます。肝は、妖怪の応答が毎回パースできるJSONで返ること。会話・リスク・備えを構造化して、UIと音声へ確実に流し込む必要があります。
なぜファインチューニングなのか(知識ではなく振る舞い)
このアプリで知識にあたるもの——リスクスコア・避難所・自然災害伝承碑——は、すべて**外部(API・GeoJSON・計算)**が持ちます。モデルに覚えさせる必要はありません。
FTに任せたのは振る舞いです。
- 妖怪ごとの口調・一人称(河童=「ワシ」「〜じゃ」、土蜘蛛=「拙者」「〜でござる」…)の一貫性
- タスク別の厳密なJSONスキーマ(会話/避難所/経路/シナリオ/地域情報の5種)
- 防災の倫理(後述。不安を煽らない表現)
つまり「何を知っているか」ではなく「どう答えるか」をFTで固めた——最適化の順序の原則そのものです。
学習レシピ(再現可能)
| 項目 | 値 |
|---|---|
| ベースモデル | Qwen2.5-14B-Instruct(Apache-2.0) |
| 手法 | QLoRA(4bit NF4・double quant・compute bf16) |
| LoRA | r=64 / α=128 / dropout=0.05 / target=全7線形層(q,k,v,o,gate,up,down) |
| 学習 | 3エポック・系列長4096・batch1×grad_accum5・lr 2e-4(cosine)・warmup3%・paged_adamw_8bit |
| 枠組み | TRL SFTTrainer(completion-only loss)・PEFT・bitsandbytes |
QLoRA(ベースを4bitで凍結し、小さなアダプタだけ学習)なので、14B級でも単体GPUで現実的でした。手元で動くか・学習できそうかは動くか診断と自宅GPUの選び方を参照してください。
データ設計:量より「質」と「倫理」
教師データは142,000件・12カテゴリ・5タスク種別(妖怪ハザード3.2万件+避難案内11万件)。生成はQwen3-32Bで合成し、品質フィルタにかけました(大きいモデルで作り、軽いモデルに教える形)。
差別化の核は、件数ではなく表現の設計です。防災コミュニケーションとして、言葉を3段階で管理しました。
- 絶対に使わない表現(hard_reject):「死ぬぞ」「逃げ場がない」「住むべきではない」「諦めろ」等7語。不安や絶望を煽らず、住民の尊厳を守るため。
- 文脈次第の表現(soft_warn):「危険」「被害」等は、行政の正式用語(土砂災害危険箇所 など)としてのみ許容。
- 推奨表現:「〜を知っておくと安心じゃ」「備えがあれば大丈夫じゃ」等、前向きな言い回し。
これらは自然災害伝承碑・自治体ハザードマップ・気象庁の警戒レベル・内閣府「自助・共助・公助」に基づいて設計しました。「正確なリスク認知」と「安心感」の両立——FTが効くのは、まさにこうした振る舞いの作り込みです。
評価:構造化JSONを99.97%(テスト14,200件)
学習に使っていないテスト14,200件で、学習後モデルをvLLMで推論し、定量評価しました。
| 指標 | 結果 |
|---|---|
| JSON生成成功率 | 99.97% |
| eval_loss | 0.312(perplexity ≈ 1.37) |
| スキーマ準拠(タスク別の必須フィールド) | タスク別に計測 |
| キャラクター一貫性(妖怪の一人称) | 計測 |
| 禁止表現の回避 | 計測 |
「99.97%」の測り方(正直に):マークダウンの ``` フェンス除去・JSON部分の抽出・末尾の閉じ括弧補完まで許容した上でのパース成功率です(temperature 0.1)。失敗は5種に分類しました(途中切れ/マークダウン混入/構文エラー/スキーマ欠落/APIエラー)。厳密な「一発で完全JSON」より緩い定義ですが、実アプリではこの寛容パースで十分動きます。構造化出力がモデルの素性でどう変わるかはfunction callingの実測もどうぞ。
ローカル配信(GGUF量子化)
学習したアダプタをベースにマージし、GGUFに量子化して配信しました。
| 量子化 | サイズ | 用途 |
|---|---|---|
| Q4_K_M | 8.4GB | 推奨(GPU 10GB+) |
| Q3_K_M | 6.9GB | メモリ節約 |
| IQ3_XS | 6.0GB | 最小(VPS等) |
14BがQ4で約8.4GB——量子化はどれを選ぶのとおり、量子化レベルでVRAMと用途が変わります。手元で載るかは動くか診断へ。
学び(持ち帰り)
- FTは知識でなく振る舞い:口調・JSONスキーマ・倫理を固めるのにFTは強い。知識は外部に分離する。
- データは量より質+設計:14万件でも、効いたのは表現ガイドラインと倫理設計。合成生成+品質フィルタで質を担保。
- QLoRAで14Bが単機:4bit凍結+アダプタで、大きめモデルの学習も現実的。
- 配信は量子化:GGUF Q4で約8.4GB、VPSでも動く構成に。
謝辞
本モデルの学習(教師データ生成・QLoRA学習・評価)は、ローカルLLMに向き合う会の inai17ibar 様よりGPU環境をお借りし、サルドラ様の仲介・サポートのもとで実施しました。記して感謝します。
限界(要検証)
- 本記事は単一プロジェクトの実例です。最適なハイパーパラメータや必要件数はタスク・データで変わります。
- 「JSON 99.97%」は上記の寛容パース定義での値です。指標の定義を変えれば数値も変わります(要検証)。
- 教師データはQwen3-32Bによる合成を含みます。生成モデルの癖が反映される可能性があり、品質フィルタと評価で担保しています。