RAG vs ファインチューニング — どちらを、いつ選ぶか
LLMを賢くする二大手法を、知識の鮮度・コスト・幻覚・データ量の4軸で比べる。比喩→仕組み(式)→動く図→判断表→現場の落とし穴まで、前提知識ゼロから。
答えられない理由は、いつも二種類ある
新しく入った人が顧客の質問に答えられなかったとします。原因は大きく二つに分かれます。
一つは、知らないことです。先月改訂された返金規程を読んでいない。この場合に必要なのは訓練ではなく、規程集を手元に置くことです。
もう一つは、答え方を知らないことです。規程は読んでいるのに、社外向けの言い回しになっていない、返答の型(まず結論、次に根拠、最後に問い合わせ先)に沿っていない。この場合に規程集をもう一冊渡しても何も変わりません。必要なのは、良い返答例をたくさん見せて型を体に入れてもらうことです。
大規模言語モデル(LLM)でも事情はまったく同じです。RAG(検索拡張生成)は前者の解決策で、質問のたびに関連資料を探してきてプロンプトに同梱します。ファインチューニングは後者の解決策で、モデルの重み(内部の数値パラメータ)そのものを追加学習で書き換えます。
英語圏で最も検索される比較語のひとつがこの二つですが、多くの現場が迷うのは、比較の前に「いま困っているのはどちらの欠落か」を切り分けていないからです。この記事は、その切り分けを最後まで機械的にできるところまで持っていきます。
直感: 知識をどこに置くか
違いを一行で言うと、知識の置き場所です。
RAGは知識をモデルの外に置きます。文書は検索用のデータベースに入っており、モデルは毎回それを読みに行く「持ち込み可の試験」を受けます。文書を差し替えれば、次の質問から答えが変わります。
ファインチューニングは知識や振る舞いをモデルの中に溶かし込みます。学習が終わればプロンプトに資料を入れなくても、その調子で喋るようになります。ただし溶かし込んだものは、あとから一行だけ取り消すことができません。
この非対称性が、後で出てくる判断のほとんどを決めます。外に置いたものは差し替えられる。中に入れたものは差し替えられない。
仕組み1: RAGは「似ているものを探す」
RAGの中心にあるのは検索です。文書もクエリも、意味を表す数値の並び(埋め込みベクトル)に変換され、向きの近さで似ているものを選びます。
平たく言えば、質問のベクトルと文書のベクトルが同じ方向を向いているほど点数が高いというだけの式です。 は質問を変換したベクトル、 は文書の断片を変換したベクトル、分子の は両者の掛け算の和(内積)、分母の はベクトルの長さです。長さで割っているので、長い文書が点数を稼ぎやすくなるのを打ち消しています(この割り算をやめると何が起きるかは、下の図で実際に触れます)。
この式(1)で上位 件を選び、プロンプトの中に貼り付けてから生成させる。これがRAGの全体像です。詳しい構成要素はRAGの基礎と設計パターンで扱っています。
仕組み2: ファインチューニングは「重みをずらす」
一方のファインチューニングは、モデル内部の重み行列 に差分を足します。いま主流の LoRA という手法では、その差分を二つの細長い行列の積で表します。
言い換えると、元の重み は凍らせたまま、その横に薄い付箋 を貼るということです。 は縦長、 は横長の行列で、間の細さを (ランク)と呼びます。 を小さくすれば付箋は薄くなり、学習すべき数値の個数は元の重みの何百分の一にもなります。
「そんな薄い差分で足りるのか」という疑問はもっともで、それ自体が論文の主題になっています(論文解説 LoRA)。ここでは、足りる場合があるという事実だけ持っていけば十分です。
4軸で決める判断表
実務で効くのは、次の4軸です。
| 軸 | RAG | ファインチューニング |
|---|---|---|
| 知識の鮮度 | 索引を更新すれば即反映。今日変わった規程に今日から従う | 再学習が必要。更新のたびに学習と検証の工程が回る |
| コスト | 初期構築は軽いが、毎回の推論で資料分のトークンを払い続ける | 学習に一度コストがかかり、以後のプロンプトは短く済む |
| 幻覚 | 出典を提示でき、根拠付きの検証がしやすい | 出典が消える。誤りが「自信のある断定」として出る |
| データ量 | 文書があればよい。質問と答えの対を作らなくてよい | 入出力の対が要る。しかも品質が結果を直接左右する |
この表から読み取れる一番大事なことは、幻覚の軸だけ性質が違うという点です。他の三つは程度問題ですが、幻覚については向きが逆になります。ファインチューニングで知識を詰め込もうとすると、モデルは「その話題について自信を持って喋る癖」を先に覚えます。知識が中途半端にしか入っていない状態で自信だけが増えるので、幻覚がむしろ増えるという現象が起きます。なぜそうなるかの内部事情には踏み込みませんが、判断の指針としては単純です。事実を増やしたいならRAG、振る舞いを変えたいならファインチューニング。
2軸マップ: どの象限にいるか
上の4軸を、決断に使える形まで畳むと2軸になります。横軸が「求める挙動の変化の大きさ」、縦軸が「知識の変化の速さ」です。
| 挙動の変化: 小(今の答え方でよい) | 挙動の変化: 大(口調・形式・手順を変えたい) | |
|---|---|---|
| 知識が速く変わる(日〜週) | RAG — 社内ヘルプデスク、製品仕様Q&A、ニュース要約 | RAG + ファインチューニング — 決まった書式で最新情報を返す業務、定型レポート生成 |
| 知識が遅く変わる(年〜不変) | プロンプトで足りる — まず数行の指示と例示を試す。ここで満足できるなら何も作らないのが最善 | ファインチューニング — 特定ドメインの文体、構造化出力の徹底、独自の分類体系 |
左下の象限を最初に潰すのがコツです。何も作らずに済むなら、それが一番安い。 数例をプロンプトに入れるだけで通ることは珍しくありません。
右上、つまり「最新情報を、決まった形式で」は両方使う象限です。実際、商用システムの多くはここに落ち着きます。RAGで事実を供給し、ファインチューニングで出力の型を安定させる、という分業です。
コードで見る違い
擬似コードにすると、二つが別の場所に触っていることが一目で分かります。
# RAG: 推論のたびに外から資料を足す(モデルは触らない)
def answer(question, index, llm):
docs = index.search(question, k=5) # 式(1)で上位5件
context = "\n\n".join(d.text for d in docs)
return llm(f"資料:\n{context}\n\n質問: {question}")
# ファインチューニング: 一度だけ重みを書き換える(推論時は素で呼ぶ)
def train(base_model, pairs): # pairs = [(入力, 理想の出力), ...]
model = attach_lora(base_model, r=16) # ΔW=BA を差し込む
for x, y in pairs:
loss = cross_entropy(model(x), y)
loss.backward(); step()
return model # 以後 model(question) だけで答える
index.search が毎回走るのがRAG、train が一度だけ走るのがファインチューニングです。前者は推論時間とトークン代を払い続け、後者は学習時に払って推論を軽くします。
よくある誤解を三つ
「ファインチューニングすれば社内文書を覚えさせられる」 — 覚える場合もありますが、確実ではなく、更新もできません。10万件の規程のうち1件が変わったとき、RAGなら1件差し替えるだけです。ファインチューニングでは、その1件のためにもう一度学習を回すことになります。
「RAGは安い」 — 構築は安いですが、運用は必ずしも安くありません。毎回の質問に数千トークンの資料が付くので、それが利用回数だけ積み上がります。プロンプトの前半が固定的ならプロンプトキャッシュで削れる部分もありますが、資料は質問ごとに変わるので効きは限定的です。
「どちらか一方を選ぶ」 — 対立する選択肢ではありません。上の2軸マップの右上が示すとおり、併用が普通です。
現場ではこう使う
誰が、いつ判断するか。 社内AI基盤の担当者や機械学習エンジニアが、「LLMに◯◯をやらせたい」という要望を受けた最初の30分で決めます。ここを飛ばして実装に入ると、後戻りのコストが大きくなります。
判断の手順は固定できます。 ①失敗している出力を20件集める → ②各件について「資料を渡せば直るか」を確かめる → ③直る割合が高ければRAG、低ければファインチューニング。②は手でプロンプトに資料を貼るだけで検証できるので、実装前に答えが出ます。
触るパラメータとツール。 RAG側では、チャンクサイズとオーバーラップ、検索件数 top_k、埋め込みモデルの選定、BM25などのキーワード検索との併用、リランカーの有無。ベクトル格納には pgvector、FAISS、Qdrant といった選択肢があります。ファインチューニング側では、LoRAの r と alpha、学習率、エポック数、そして何より学習データの件数と品質。実装は PEFT や TRL、Axolotl、Unsloth あたりが定番です。
知らないと事故になる落とし穴。
- 学習データに個人情報を入れると、あとから消せない。 RAGなら索引から該当文書を削除すれば済みますが、重みに焼き付いたものは削除要求に応えられません。削除の要求を受ける可能性がある領域では、この一点だけでRAG側に倒れることがあります。
- 文書を更新したのに索引を作り直していない。 RAGで最も多い障害です。「更新したのに古い答えが返る」の大半はこれで、パイプラインに再索引の工程が入っていないことが原因です。
- 破滅的忘却。 狭いデータで学習を回しすぎると、元々できていた一般的なタスクの品質が落ちます(破滅的忘却)。学習後は必ず、学習させたタスク以外の品質も測ります。
- 評価セットを作らずに着手する。 どちらの手法でも、直ったかどうかを測る物差しがなければ判断できません。RAGの評価は検索と生成を分けて測る必要があります(RAGの評価)。
面接や設計レビューで問われる形。 「社内の就業規則に答えるボットを作りたい。どちらを使うか」に対しては、「規則は更新される/出典の提示が求められる/質問と答えの対が手元にない、の三点からRAG。ただし回答書式に社内規定があるなら、書式の部分だけ後からファインチューニングかプロンプトで足す」と答えられれば、4軸を使えていることが伝わります。
まとめ
- RAGは知識を外に置き、ファインチューニングは中に溶かす。 外は差し替えられ、中は差し替えられない
- 判断の4軸は知識の鮮度・コスト・幻覚・データ量。幻覚の軸だけは向きが逆で、知識目的のファインチューニングは事態を悪化させうる
- 2軸マップで象限を決める。左下(何も作らない)から潰すのが最短距離
- 商用システムの多くは併用に落ち着く。対立させて考えないこと
次は、選んだ側を実際に測る話です。RAGを選んだなら、検索と生成のどちらが壊れているかを切り分ける評価設計から始めてください。
コメント
コメントにはログインが必要です