「専門家が持つ知識を、生成AIに学習させたい。」
AI開発のご相談では、このようなご要望をいただくことがあります。
専門家がこれまで話してきた内容を大量にLLMへ学習させれば、その人の知識を持ったAIを作ることができます。
今回micomiaでは、この方法について実際にどのように進んでいるのか本記事で解説します。
関戸園芸様のYouTubeチャンネル「関戸園芸【お庭男士】チャンネル」で公開されている159本の動画をもとに、園芸に関する質問へ回答するAIを構築しました。
この記事では、159本の動画からどのようにデータを整備したのか、RAGとファインチューニングを実際に比較して何が分かったのか、そして開発中に起きた失敗事例まで、実際のデータを交えて紹介します。
目次
- 1. 今回作ったもの
- 2. 学習データの準備
- 3. YouTube自動字幕をそのまま使えない理由
- 1. 動画ごとの誤変換を抽出
- 2. 全動画共通の補正辞書を作成
- 4. 話し言葉には「句読点がない」という問題もある
- 5. 224件しかなかったQAを1,349件まで増やす
- LLMは「親切心」で情報を捏造する
- 6. 学習データは「動画単位」で分割
- 7. Mac miniで3BモデルをLoRA学習する
- ベースモデルを比較
- 8. LoRA学習は約2時間
- 9. そしてファインチューニングとRAGを比較した
- 10. ファインチューニングで関戸さんらしさを作る
- ファインチューニングが得意だったこと
- ファインチューニングだけでは難しかったこと
- 11. RAGとファインチューニングは役割が違う
- 12. RAGでは2,472チャンクまでデータを増やした
- 13. RAGの評価結果
- 14. 検証損失が良いモデルほど、回答が悪くなった
- 15. batch sizeを2倍にすると8倍遅くなった
- 16. エラーにならないデータ欠損
- 17. プロンプトだけでは解決できないこともある
- 18. 今回分かったこと
- 1. 根拠を示せる専門知識AIならRAGが強い
- 2. ファインチューニングは「知識」より「らしさ」
- 3. モデル以上にデータが重要だった
- 4. 評価指標だけを信用してはいけない
- 19. 実運用ではAPIと自前GPUのどちらが安いのか
- 20. まとめ
- 関連リンク
1. 今回作ったもの
今回の目的は、関戸園芸様が発信されている動画で蓄積された園芸の知見を、ユーザーが質問形式で引き出せるようにすることです。
園芸の情報には季節性があり、剪定や植え替え、肥料、病害虫対策といった相談は特定の時期に集中します。しかし、過去の動画の中から自分の悩みに該当する情報をユーザー自身で探すのは、簡単ではありません。
動画のコメント欄には複数の質問が寄せられていますが一件一件回答するのは担当者を用意する必要があり難しい状態でした。
そこで、たとえば「アジサイの剪定はいつすればいいですか?」といった質問に対して、過去の動画をもとに回答し、できれば根拠になった動画と再生位置まで提示する仕組みを目指しました。
今回比較した方式は、次の2つです。
方式 | 概要 |
|---|---|
ファインチューニング | 園芸QAを使ってLLMの重みをLoRAで学習 |
RAG | 質問に関連する動画内容を検索し、LLMへ参考情報として入力 |
最終的には、回答根拠(出典)の提示と、情報を更新しやすいことを重視して、RAGを採用していますが、関戸さん自身の話し方なども含めて関戸さんと会話している感を出すならファインチューニングの方がおすすめです。
2. 学習データの準備
開発を始めるにあたり、まず文字起こしデータを確認しました。
文字起こしにAIを利用しましたが、実際の発話内容とのズレもありましたので関戸さん自身によるレビューも行いながら進めました。
RAGとファインチューニングの両方でベースとなるデータが間違っていると後から狙った回答を出せず目的を達成できません。
そのためこの工程にはかなりの時間を使い丁寧に行いました。
3. YouTube自動字幕をそのまま使えない理由
では、YouTube字幕をそのままRAGに投入すればいいかというと、そう単純にはいきません。専門用語の誤認識があるからです。実際には、次のような変換が発生していました。
自動字幕 | 正しい単語 |
|---|---|
換気の苗 | 柑橘の苗 |
難点の実 | ナンテンの実 |
不用度 | 腐葉土 |
込み先手 | 込み剪定 |
園芸の専門用語には、一般的な音声認識モデルにとって認識しにくい単語が多くあります。そこで今回は、2段階で補正しました。
1. 動画ごとの誤変換を抽出
既存の人手文字起こしを正解データとして、自動字幕との差分をプログラムで比較し、その動画に含まれる特徴的な誤変換を抽出します。
2. 全動画共通の補正辞書を作成
複数の動画で共通して発生する誤変換については、人間が確認しながら共通辞書へ登録し、最終的に約100個の補正ルールを作成しました。
ここで重要なのは、単純な文字列置換にしないことです。たとえば次のように、周囲の文脈を限定しています。
{
"pattern": "(?<=込み)先手",
"replacement": "剪定"
}「先手」をすべて「剪定」に置き換えてしまうと、「先手を打つ」といった正常な文章まで壊してしまいます。そのため今回は、直すべき単語を最大限直すことよりも、正常な文章を壊さないことを優先しました。
4. 話し言葉には「句読点がない」という問題もある
YouTube字幕には、句読点がないという問題がありました。
これでは文ごとに処理を行えないのでYouTube字幕がもともと持っているタイムスタンプ単位のセグメントを利用しました。
これによって文章を適切な単位へ分割できるだけでなく、「この回答は動画の何分何秒付近を根拠としているか」という情報も一緒に保持できます。
動画の該当箇所まで示せるようになり、結果的に出力精度を上げることができたので出典動画を観必要があるならばタイムスタンプも学習・参照データに入れてみてください。
5. 224件しかなかったQAを1,349件まで増やす
ファインチューニング用データとして最初に存在していたQAは、224件でした。動画154本のうち129本は1動画につき1QAしかなく、知識を学習させるにはあまりに密度が低い状態です。そこで、動画本文からQAを追加で抽出することにしました。
今回重要なのは、動画の中に本当に存在する知識だけを学習データにすることなのでLLMに自由にQAを作らせる合成データ生成は避けています。
処理は、次のような流れにしました。
動画本文
↓
QA抽出LLM
↓
QA候補
↓
検証用LLM
↓
採用 / 修正 / 却下ポイントは、抽出と検証を別々のLLMに担わせたことです。検証側には「本文に存在しない情報を追加してはいけない、必要であれば削除する」という制約を与えています。
LLMは「親切心」で情報を捏造する
検証工程を入れた結果、興味深い例がいくつも見つかりました。
たとえば、抽出されたQAの回答に「肥料は製品の表示に従って使ってください」という一文が追加されるケースです。
一見すると正しい注意書きですが、文字起こしを検索しても「表示」「ラベル」「製品」「使用量」に該当する内容は存在しませんでした。LLMが安全側に回答しようとして、元データにない注意事項を足していたのです。
別のケースでは、動画内の「たこ焼き返し」という道具が、生成されたQAでは「串」に置き換わっていました。まったく関係のない内容なら気づきやすいのですが、それらしい具体物にすり替わると、人間でも見落としやすくなります。
最終的な内訳は、次のとおりです。
抽出QA:1,146件
そのまま採用:901件
修正して採用:224件
却下:21件
これらと既存データを合わせて、1,349件のQAを作成しました。
6. 学習データは「動画単位」で分割
学習データは、OpenAI互換のmessages形式に整形しました。
{
"messages": [
{
"role": "system",
"content": "あなたは関戸園芸の園芸知識と説明方法をもとに回答するAIです。"
},
{
"role": "user",
"content": "じゃがいもをプランターで育てたいのですが、どのくらいの大きさの容器を選べばいいですか?"
},
{
"role": "assistant",
"content": "おすすめのサイズは、横幅60cm程度、深さ31cm以上..."
}
]
}データセットは、次のように分割しています。
split | 件数 |
|---|---|
train | 1,063 |
valid | 133 |
test | 133 |
ここで重要なのは、QAをランダムに分割していない点です。
分割は動画単位で行っています。同じ動画から作られたQAがtrainとtestの両方に混在すると、ほぼ同じ内容を学習時に見た状態でテストすることになり、実際の汎化性能を評価できなくなるからです。
そこで同じ動画由来のQAは必ず同じsplitへ入るようにして、データリークを防ぎました。
さらにmanifestファイルへリーク検査の結果を記録し、問題があれば学習スクリプト自体が止まるようにしています。
7. Mac miniで3BモデルをLoRA学習する
今回のファインチューニング環境は、次のとおりです。
項目 | 内容 |
|---|---|
マシン | Apple Silicon M2 / 24GB |
フレームワーク | MLX / mlx-lm |
ベースモデル | shisa-v2.1-llama3.2-3b |
量子化 | 4bit |
学習方法 | LoRA |
GPUサーバーは使わず、手元のMac miniだけで学習しています。
ベースモデルを比較
学習前に、3つのモデルを比較しました。
モデル | メモリ | 生成速度 | 日本語 |
|---|---|---|---|
Llama-3.2-3B | 2.23GB | 15.4 tok/s | 日本語が不自然 |
shisa-v2.1-llama3.2-3b | 2.20GB | 15.2 tok/s | 自然 |
Llama-3.1-Swallow-8B | 4.81GB | 5.4 tok/s | 自然だが遅い |
8Bモデルは回答品質こそ高かったものの、今回の環境では生成速度が遅く、最終的には3Bのshisaモデルを採用しました。
ここで押さえておきたいのは、「ファインチューニングで何でも修正できるわけではない」ということです。ベースモデルの時点で日本語能力が不足していると、それをLoRAだけで大きく改善するのは現実的ではありません。
まず素のモデルを評価し、最低限必要な能力を備えたものを選ぶ必要があります。
8. LoRA学習は約2時間
最終的な主な設定は、次のとおりです。
num_layers: 16
batch_size: 2
iters: 600
learning_rate: 5.0e-6
max_seq_length: 768
lora_parameters:
keys:
- self_attn.q_proj
- self_attn.v_proj
rank: 16
scale: 10.0
dropout: 0.05
mask_prompt: truemask_prompt: trueとすることで、質問部分ではなく回答部分を中心に損失を計算しています。600イテレーションでの実測は、次のようになりました。
約5.5秒 / iteration
ピークメモリ約7GB
学習時間約2時間
手元のMac miniで学習しているため、追加のクラウド利用料金はかかっていません。
小規模なLoRAであれば、Apple Siliconでも十分に試行錯誤できることが分かりました。
9. そしてファインチューニングとRAGを比較した
ここからが、今回のPoCで最も重要な部分です。同一の質問を、次の3方式へ入力しました。
未学習モデル
LoRA学習済みモデル
RAG
代表的な質問として使ったのが「アジサイの剪定はいつすればいいですか?」という問いです。
アジサイの剪定はいつすればいいですか?
動画内の説明では「花が終わった直後から7月中旬頃まで」が正しい回答です。3方式の結果は、次のようになりました。
未学習モデル | 学習済みモデル | RAG | |
|---|---|---|---|
回答 | 春(3月下旬〜4月上旬) | 花が終わった直後〜7月中旬 | 花が終わった直後〜7月中旬 |
事実の正確さ | × | ◯ | ◯ |
出典の提示 | なし | なし | あり |
学習済みモデルは、未学習モデルより自然で、内容としても概ね正しい回答を返せるようになりました。
ただし、ここに決定的な違いがあります。学習済みモデルは、その回答が「どの動画のどの説明に基づくのか」を示せません。
対してRAGは、質問に関連する動画内容を検索して入力へ追加するため、同じ内容を答えつつ、根拠になった動画と再生位置まで提示できました。

RAG型の回答例。花が終わった直後〜7月中旬と正しく答え、根拠にした動画(出典)も提示している。
10. ファインチューニングで関戸さんらしさを作る
ファインチューニングで変わったのは、回答内容だけではなく回答の仕方そのものに大きな変化がありました。
たとえば「オリーブの実をたくさんつけるコツを教えてください」という質問に対して、学習済みモデルは次のように答えています。
まず「実をつけるかどうか」が重要です。オリーブの種類によっては「実をつける」タイプと「実をつけない」タイプがあるので、まず「あなたのオリーブの種類は?」と教えてください。
情報が足りないときに、いきなり答えず追加の質問を返す。これは未学習モデルでは見られなかった挙動です。今回の結果を整理すると、次のような違いがありました。
ファインチューニングが得意だったこと
条件による但し書き
情報不足時の追加質問
回答の構成
回答の仕方・言い回し
ファインチューニングだけでは難しかったこと
回答の根拠(出典)を提示する
元データの追加・修正を即座に反映する
範囲外の質問を確実に線引きする
11. RAGとファインチューニングは役割が違う
今回の結果を踏まえると、RAGとファインチューニングは両者は得意な領域が違うため「どちらが優れているか」で比較するのは、あまり適切ではないと考えています。

モデル学習型の回答例。自然な文章で答えるが、RAG型と違い根拠とした出典は示されず、画面下に「AIによる一般的な参考情報」と注記される。
目的ごとに適した方式を整理すると、次のようになります。
目的 | 適している方式 |
|---|---|
事実を正確に回答する | RAG |
回答根拠を提示する | RAG |
情報を頻繁に更新する | RAG |
回答できない質問を判別する | RAG |
口調や言い回しを再現する | ファインチューニング |
特定のフォーマットを覚えさせる | ファインチューニング |
回答方法を統一する | ファインチューニング |
もし両方の性質が必要なのであれば、RAGで検索した知識を、ファインチューニングしたモデルへ入力するという組み合わせも考えられます。
「専門家AIを作りたい」という要件だけでファインチューニングを選ぶのではなく、何を再現したいのかを分解したうえで方式を選ぶことが大切です。
12. RAGでは2,472チャンクまでデータを増やした
RAG用のデータは、最終的に2,472チャンクとなりました。埋め込みモデルにはbge-m3を利用しています。さらに今回は、コーパスを拡張する前後で「質問と検索結果の類似度」がどう変わるかを比較しました。
拡張前 | 拡張後 | |
|---|---|---|
チャンク数 | 852 | 2,472 |
園芸質問の最小類似度 | 0.559 | 0.612 |
園芸外質問の最大類似度 | 0.541 | 0.541 |
判定マージン | 0.039 | 0.071 |
チャンク数を増やした結果、「回答できる園芸質問」と「回答すべきではない質問」との距離がはっきりし、判定マージンは約1.8倍になりました。
ここで変えたのはモデルではなく、検索対象となる元データの量だけです。データを増やしたことでRAGの判定性能が改善ました。
13. RAGの評価結果
評価用には、次の8カテゴリで100問を作成しました。
基礎知識
植物別
症状
季節
剪定
病害虫
情報不足
回答不能
今回のPoCでは、そのうち31問を使って実測しています。
RAGの結果は、次のとおりです。
指標 | 実測 |
|---|---|
正しい出典の取得率 | 95.5% |
回答不能問題の拒否判定 | 100%(2/2) |
システムエラー率 | 0.0% |
回答開始まで | 0.6〜9.9秒 |
また「確定申告のやり方を教えてください」のような園芸と関係のない質問については、検索結果の類似度から「回答根拠なし」と判定できました。評価した31問の範囲では、通常の園芸質問を誤って拒否してしまうケースもありません。
ただし、この数字の扱いには注意が必要です。
実測したのは31問で、用意した100問すべてを評価したわけではありません。
専門家本人による回答品質のレビューや、「その人らしい説明になっているか」といった定性評価も未実施です。そのため95.5%という値は、あらゆる園芸質問に対する正答率ではなく、あくまでPoCとして評価した条件内での出典取得率だと捉えてください。
14. 検証損失が良いモデルほど、回答が悪くなった
ファインチューニングでは、もうひとつ興味深い結果がありました。3回の学習結果を比較すると、次のようになります。
条件 | 最良の検証損失 | 実際の回答 |
|---|---|---|
3B / 179件 / scale 20 | 3.275 | 同じ文章を40回以上繰り返す |
shisa / 1,063件 / scale 20 | 2.269 | 同じ文章を9回繰り返す |
shisa / 1,063件 / scale 10 | 2.501 | 繰り返しなし |
数字だけを見れば、検証損失が最も小さい2.269のモデルを選びますが、実際に回答させると、次のように月をずらしながら同じ文型を繰り返してしまいました。
1月下旬から2月上旬まで〜
2月上旬から3月下旬まで〜
3月下旬から4月上旬まで〜
一方で、検証損失が2.501と数値上は悪いモデルのほうが、自然な回答を生成しました。
lossだけを見てモデルの良し悪しを判断できない、という典型的な例になっています。
LLMの学習では、lossに加えて、実際の生成結果を継続的に確認していく必要があります。
15. batch sizeを2倍にすると8倍遅くなった
Apple Silicon特有と思われる挙動も確認しました。
データ量が増えたため、batch_sizeを2から4へ増やしてみたところ、結果は次のようになりました。
batch_size | 速度 | ピークメモリ |
|---|---|---|
2 | 5.5秒 / iter | 9.4GB |
4 | 43秒 / iter | 12.0GB |
処理量は2倍ですが、実行時間はおよそ8倍です。
そのまま1,200イテレーション回すと14時間近くかかる計算になったため、学習を中断してbatch size 2へ戻しました。少なくとも今回のM2環境では、batch sizeを増やせば学習効率が上がるとは限らないということがわかりました。
16. エラーにならないデータ欠損
開発中には、AIとは直接関係のない失敗もありました。データ処理のパイプラインには、次の順番があります。
ingest
↓
rebuild-transcripts
↓
chunkところが、rebuild-transcriptsを実行せずにchunkを走らせると、本来再構築したはずの字幕データが使われません。
その結果、チャンク数は1,347から832まで減ってしまいました。厄介なのは、それでもプログラム自体は正常終了することです。システムは問題なく動いているように見えるのに、精度だけが落ちていました。
そこで現在は、前工程の実行状況をチェックし、必要なデータが作られていなければ後工程を止めるようにしています。AIシステムでは、モデルの評価だけでなく、データパイプラインそのものの確認も大切です。
17. プロンプトだけでは解決できないこともある
回答が長くなりすぎるという問題もありました。
そこでシステムプロンプトに「200〜350字にまとめる」という指示を追加してみました。
結果は、次のとおりです。
質問 | 通常版 | 長さ指定版 |
|---|---|---|
アジサイの剪定 | 337字 | 189字 |
葉が黄色くなった | 810字 | 837字 |
初回トークン | 2.2〜9.9秒 | 11.2〜12.3秒 |
一部の質問では短くなったものの、別の質問では逆に長くなり、さらにプロンプトが伸びた分だけ応答開始も遅くなりました。
そのため今回の3Bモデルでは、プロンプトだけで回答長を安定して制御する方法は採用していません。生成AIでは、問題が起きるたびにプロンプトへルールを足したくなりますが、プロンプトを長くすれば必ず制御性が高まるわけではないということがわかりました。
18. 今回分かったこと
今回のPoCを通して、いくつか明確になったことがあります。
1. 根拠を示せる専門知識AIならRAGが強い
1,063件のデータでLoRA学習したモデルは、内容自体は概ね正しく答えられるようになりました。ただし、その回答がどの動画に基づくのかまでは示せません。一方でRAGは元データを直接検索するため、出典の提示や内容の検証、データ更新への追従に優れています。
2. ファインチューニングは「知識」より「らしさ」
条件付きの回答や追加質問、回答の構成といった振る舞いには、学習の効果がはっきり表れました。特定の話し方や回答形式を再現したい場合には、依然として有力な方法です。
3. モデル以上にデータが重要だった
今回もっとも大きな改善につながったのは、文字起こしを作り直したことでした。コーパスを318,134字から676,074字へ増やしたことでRAGの検索対象が大幅に広がり、FAQについても224件から1,349件まで実データ由来のQAを増やしています。モデルを変える前に、まずAIへ渡しているデータが本当に正しいのか、必要な情報が揃っているのかを確認する必要があります。
4. 評価指標だけを信用してはいけない
検証損失が最も良かった学習モデルが、実際には最も不自然な文章を生成しました。AI開発では、次のような複数の観点を組み合わせて評価する必要があります。
loss
検索精度
レイテンシ
実際の回答
人間によるレビュー
19. 実運用ではAPIと自前GPUのどちらが安いのか
今回のRAG構成では、2,472チャンクのベクトルインデックスは約9.7MBでした。この規模であれば、大規模なベクトルDBを必須とする構成ではありません。質問文を埋め込みに変換し、関連チャンクを検索してLLMへ送るだけなら、LLM部分以外に大きなGPUリソースも要らないからです。今回試算した月3,000問程度の利用量では、APIを利用するほうが、自前GPUを常時稼働させるより低コストになる見積もりです。
一方で、データを外部APIへ送信できないという要件がある場合は話が変わります。クライアントの非公開データや機密情報を扱うケースでは、費用ではなくセキュリティやデータガバナンスを理由に、ローカルLLMや自前GPUを選ぶことも十分に考えられます。AIインフラもまた「最新の技術だから」ではなく、データの性質・利用量・セキュリティ要件から選ぶ必要があります。
20. まとめ
今回は159本の園芸動画をもとに、専門知識へ質問できるAIのPoCを構築しました。
LoRAによるファインチューニングとRAGを実際に両方つくって比較した結果、今回の用途ではRAGを採用しています。
特に重要だったのは、次の点です。
159本の動画を対象にデータを整理し、154本で字幕を取得
文字起こしを318,134字から676,074字へ再構築
QAを224件から1,349件へ拡張
Mac M2上で3BモデルをLoRA学習
1,063件を学習したモデルは内容自体は概ね答えられたが、出典提示・更新のしやすさではRAGに及ばなかった
追加質問や言い回しなど「回答の振る舞い」には学習効果があった
RAGでは2,472チャンクを検索対象として利用
評価した範囲で正しい出典の取得率95.5%
データ拡張によって回答可否判定のマージンが約1.8倍になった
検証損失が最も良いモデルが、実際には最も不自然な回答を生成するケースもあった
今回の開発でとりわけ印象的だったのは、最も「AIらしい」工程であるファインチューニングが、最も大きな改善要因ではなかったことです。
元になる学習データに誤りがある状態では、モデルや学習方法をどれだけ変えても限界があります。だからこそ、AIに何を学習させるかを考える前に、そもそも必要なデータが揃っているのか、そのデータは本当に正しいのか、そしてファインチューニングという手段が本当に必要なのかを確認することが大切です。
micomiaでは、生成AIを前提にシステムを設計するのではなく、RAGやファインチューニング、従来のプログラム処理などを比較しながら、要件に合った構成を提案しています。
AIを使うこと自体が目的ではなく、実際に使えるシステムをつくるために、どこでAIを使い、どこでは使わないのかを見極めることも、AI開発の重要な工程だと考えています。









.webp%3Falt%3Dmedia%26token%3D554beac3-1f0a-4dae-99c0-76320019500f&w=3840&q=75)







.webp%3Falt%3Dmedia%26token%3D087cf100-0101-43ba-a354-dab3bbec04d2&w=3840&q=75)
.webp%3Falt%3Dmedia%26token%3D7c77ae76-450c-48b3-be29-0e949e7116dc&w=3840&q=75)
.webp%3Falt%3Dmedia%26token%3Dd8f3f5bc-41c2-4a1e-ace1-62e9ae72d08b&w=3840&q=75)
.webp%3Falt%3Dmedia%26token%3D679eb351-4808-4d43-8b9d-92f6a88584ef&w=3840&q=75)
.webp%3Falt%3Dmedia%26token%3D5c25485e-7be1-4f95-ad65-2e4c0c2d0ddb&w=3840&q=75)