はじめに
2026年3月1日、Mistral AI主催のハッカソンに参加してきました。2日間で
- Mistralのモデルを使って何か作る
または - SLM, LLMをfine-tuneして何か作る
をテーマに与えられました。
作ったのは野生のキノコを写真で判定するオフラインAIですが、本当に興味があったのはキノコそのものではなく、Small Language Model(SLM)にどうやって専門知識を持たせるかという問題です。キノコはその実験台でした。
プロジェクト名は AI Or Die。結果としてTop 3に選んでいただきました。反省点だらけのプロジェクトですが、だからこそ書き残す価値があると思っています。
なぜこのテーマにしたか
SLMは小さいので端末上で動かせる。でも小さいからこそ、専門知識が足りない。この「小さなモデルに知識をどう持たせるか」がやりたかったテーマです。
応用先として「オフラインでしか使えない環境」を想定しました。Wi-Fiが使えるのは地球の陸地の約20%だけ。残りの80%ではChatGPTに聞くこともできない。海の上での魚の判定、鉱山での鉱石分類、山でのキノコ判定——いろいろ候補はありましたが、iNaturalistという公開データセットが一番使いやすかったのでキノコにしました。
SLMに知識を持たせる2つのアプローチ
知識の持たせ方には大きく2パターンあります。
| アプローチ | やること | 問題 |
|---|---|---|
| weightに詰め込む | fine-tuneで事実を覚えさせる | ハルシネーション。「知ってるつもり」で嘘をつく |
| 外部DBをツールで引く | fine-tuneでは行動だけ学ばせる | ✅ 事実はDBが保証。モデルは使い方だけ覚える |
今回は後者を選びました。
モデルに覚えさせるのは「このキノコは毒である」ではなく、「ユーザーがキノコの写真を見せたら species_db_lookup を呼ぶ」「食べてしまった場合は emergency_protocol を呼ぶ」という行動パターンです。事実はローカルのJSONファイル(species_db.json)に全部入っています。
3つのツールを状況に応じて使い分ける:
- 「これ食べられる?」→
species_db_lookup - 「食べちゃったんだけど」→
emergency_protocol - 「この辺で食べられるもの探して」→
nearby_species_search
学習データの作り方
iNaturalistから7,900枚以上の画像を取得。ただし全種で学習するには時間が足りず(後述)、最終的に安全カテゴリを代表する5種のキノコに絞りました。
| 種名 | カテゴリ |
|---|---|
| Amanita phalloides | LETHAL(死の傘) |
| Amanita muscaria | DO_NOT_EAT(ベニテングタケ) |
| Flammulina velutipes | CONFUSING(エノキタケ — 野生は危険) |
| Lentinula edodes | CONDITIONAL_SAFE(シイタケ) |
| Hericium erinaceus | SAFE(ヤマブシタケ) |
画像にランダム生成したGPS・季節・環境コンテキストを付与し、ルールエンジンで正解ラベルを決定。そのうえでGemini 2.5 Flashに自然言語の応答を生成させ、1,394件のtool-calling会話にまとめました。
学習はMinistral-3B + QLoRA(4-bit NF4、r=32)。学習中のlossや品質メトリクス(tool_fire_rate、safety_verdict_accuracyなど)はW&Bでトラッキングしました。
評価:行動は学べたのか?
評価にはW&B Weaveを使いました。Weaveのいいところは、モデルの出力をサンプル単位で記録・比較できること。「このサンプルで正しいfunction callが発火したか」「safety verdictは正しかったか」「species名は合っていたか」を1件ずつ追跡できます。lossが下がっただけでは見えない、モデルの実際の行動を細かく検証するのにかなり便利でした。
Gemini 2.5 Flash Lite・Ministral-3B(base)・fine-tunedの3モデルを同じ75テストサンプルで比較。fine-tunedモデルがsafety recall・species accuracyともに最高スコアでした。特にbase modelにはツール呼び出しの概念がそもそもないので、「ツールを呼ぶ」という行動自体がfine-tuneで獲得されたことは確認できました。「SLMに行動を学ばせる」という仮説には一定の手応えがあります。
ただしこの比較には穴があります。
base modelの性能はプロンプト次第でどうにでも変わる。発表で見せたレーダーチャートは「このプロンプトでの比較」でしかなく、プロンプトを最適化すればbase modelの結果は全然違うものになりえます。発表後にこれに気づきました。次やるならプロンプト最適化済みのbaselineを用意してから比較すべきです。
反省点
データコンタミ
iNaturalistの画像をそのまま使ったため、同じ観測データが学習・テスト両方に入っている可能性が高い。評価結果が実力を反映していない恐れがあります。
また、明らかにきのこの画像ではない (おそらく胞子?)の画像もおおく、このような目的にずれるデータのクレンジングは学習前にやるべきでした。
学習時間
100種全部で回そうとしたら、A10-smallでも1エポックが想定より大幅に長い。結局5種に絞らざるを得ませんでした。QLoRAなのにこの時間がかかるのは何かがおかしい気もしますが、2日間では原因を追えず。
SFTしかやれていない
言語モデルのfine-tuneは今回が初めてで、やったのはbasicなSFTだけです。DPOやsafety-weighted lossなど、安全性に寄せた手法は試せていません。モデルの元の能力をどう活かすかも未検証。やりたいことリストだけが長くなりました。
分類モデルとの組み合わせ
すべてを言語モデルに任せる設計にしましたが、種の同定には画像分類モデルのほうが向いている可能性があります。分類モデルで種を特定 → SLMが判定結果を自然言語で説明、というハイブリッド構成も検討の余地があります。
実用性について:ぶっちゃけダメです
ここまで技術的な話をしてきましたが、冷静なツッコミをひとつ。
このシステム、「🟢 SAFE」と判定したとき、ユーザーは食べます。
本来なら「わからないから食べない」と判断できた場面で、AIが「安全です」と言ってしまう。精度が100%でない限り、AIがなければ死ななかった人を、AIが背中を押して殺すシナリオが生まれます。
危険物の分類問題では「中途半端な精度のシステムは存在しないほうがマシ」という結論がありえます。医療AIでもよく議論される話です。
SLMへの知識付与の実験としては面白かったですが、実際に山に持っていくには全然足りない。これが正直な感想です。
まとめ
2日間でやったこと:
- Ministral-3Bをアジェンティックなtool-callingができるようfine-tune
- 1,394件の学習データをiNaturalist + Gemini + ルールエンジンで自動生成
- W&B Weaveで3モデルの定量比較
「SLMに知識を持たせるにはweightではなくツールで」という仮説に対して、一定の結果は出せました。ただ、データ品質・評価方法・学習手法のどれもが2日間では詰めきれず、「これが正しい」と言い切れるものにはなっていません。
言語モデルのfine-tuneは初めてでしたが、座学では得られない感覚がたくさんありました。次やるときはもっとじっくり、自分が納得できるところまで検証してから発表したいです。
コード・モデル:
- GitHub: Yongtae723/mistral-hackathon-2026
- HF Spaces: yongtae-jp/survive-or-die-app
- Fine-tuned model: Yongtae723/survive-or-die-lora






