Fine-tuningとは?LLMを用途に合わせて調整する方法

Fine-tuningの記事概要

Fine-tuning(ファインチューニング、追加学習)とは、事前学習済みモデルに目的別のデータを与え、重みの全部または一部を更新することです。向いているのは、出力形式、回答方針、専門タスクの解き方など、何度も再利用したい振る舞いをモデル側へ定着させる場面です。

一方、最新の社内規程を回答の根拠にしたいなら、重みに覚え込ませるよりRAG(検索拡張生成)の方が更新と出典確認をしやすいことがあります。Fine-tuningを始める前に、「変えたいのは知識の参照先か、振る舞いか、今回だけの条件か」を切り分けます。

3文要約

Fine-tuningの記事概要

  1. SFT(教師ありFine-tuning)やInstruction Tuningは「どんなデータと目的で学ぶか」、Full fine-tuningやLoRAは「どのパラメータを更新するか」を表します。
  2. PEFTは学習対象と保存差分を小さくできますが、ベースモデルのforward計算やactivationまで消えるわけではありません。
  3. 学習lossだけで成功を判断せず、未見データ、一般能力、安全性、形式遵守、運用コストを同じ版のモデルで回帰評価します。

Fine-tuningで変えられるもの、変えにくいもの

LLMは事前学習で広い文章分布を学びます。しかし、企業固有のJSON形式、問い合わせの分類基準、応答時の禁止事項までは自動的に知りません。入力と望ましい出力の例を与えるFine-tuningでは、そうした反復可能な振る舞いを学習できます。

要求 主な第一候補 理由
常に決まったJSON schemaで返す SFT 出力形式と判断例を反復して学ばせる
今月改訂された規程を引用して答える RAG 更新可能な文書を検索できる
今回だけ簡潔に答える Prompting 推論時の指示で変更できる
医療文書の語彙や文体へ基礎分布を寄せる 継続事前学習 生テキストで次トークン予測を続ける
複数種類の指示へ応答する Instruction Tuning 多様な指示・応答例でSFTする
根拠文書を読み所定形式へ変換する RAG + SFT 知識の参照と振る舞いを分担する

Fine-tuningは「PDFを投入すれば、正確に検索できる知識ベースになる」処理ではありません。学習後の重みから、どの文書に基づく回答かを直接追跡するのも困難です。更新頻度や根拠提示が重要なら、文書を外部で管理する方式も比較します。

用語を2つの軸に分ける

Fine-tuning周辺では、目的を表す言葉と更新方法を表す言葉が混ざりやすくなります。

Fine-tuning周辺の用語を学習目的と更新方法に分けた図

主な用語 問い
学習段階 事前学習、継続事前学習、Fine-tuning いつ、どの分布で学習するか
データ・目的 SFT、Instruction Tuning、選好学習 何を正解として学ぶか
更新方法 Full fine-tuning、LoRA、Adapter、Prefix Tuning どのパラメータを更新するか
推論時方式 Prompting、in-context learning、RAG 重みを変えず入力へ何を足すか

たとえばInstruction TuningをLoRAで実施できます。「SFTかLoRAか」という二者択一は、学習目的と更新方法を比較しているため粒度が合いません。

InstructGPT論文では、人が作成したdemonstration(望ましい応答例)でSFTした後、人のランキングを使うRLHFへ進みます。SFTはアラインメント工程の一部にもなり得ますが、Fine-tuning全般が必ず人間の価値観へ合わせる学習というわけではありません。

SFTではどのtokenに損失をかけるのか

SFT用データは単なる文章の集まりではありません。一般にはsystem、user、assistantのroleを持つ会話を、対象モデルのchat templateで一列のtoken列へ変換します。BOS、EOS、role区切りなどの特殊tokenも、モデルが想定する形式へ合わせます。

会話データからchat templateとloss maskを作る流れ

入力を \(x_i\)、assistantの正解応答を \(y_i\)、損失対象なら1となるmaskを \(m_{i,t}\) とすると、response-onlyのSFT損失は次のように書けます。

\[\mathcal{L}_{\mathrm{SFT}} = -\frac{1}{M} \sum_i \sum_t m_{i,t} \log p_\theta\!\left(y_{i,t}\mid x_i,y_{i,<t}\right), \qquad M=\sum_i\sum_t m_{i,t}\]

maskを使う理由は、user側の文面を再現する能力ではなく、指示に対するassistantの応答を主に学ばせたいからです。ただし、全tokenを対象にする設計もあります。モデル、trainer、タスクで異なるため、初期値に任せず確認します。

学習前に確認する整形項目

  • 学習時と推論時で同じchat templateを使っているか
  • assistant部分だけを対象にするmaskが意図どおりか
  • EOSを付け、応答の終了を学べるか
  • 最大長で切れたとき、正解応答の末尾だけが大量に欠けていないか
  • packing(複数の短い例を一系列へ詰める処理)で例同士が混線しないか
  • padding tokenとignore indexがloss実装と一致するか

lossが下がっても、prompt形式が本番と違えば性能は出ません。学習コードより前に、tokenize後の数例とmaskを人が読める形で確認します。

Full fine-tuningは何にメモリを使うか

Full fine-tuningは原則としてベースモデルの全重みを更新します。表現力への制約は少ない一方、重みだけでなくgradient(勾配)とoptimizer state(更新計算用の状態)も必要です。さらにforward中のactivation(中間値)を保持します。

\[\text{training memory} \approx \text{parameters} +\text{gradients} +\text{optimizer states} +\text{activations} +\text{temporary buffers}\]

これは正確なバイト数を出す式ではありません。精度形式、optimizer、分散方式、sequence length、batch size、gradient checkpointingで値が変わります。モデルのファイルサイズだけを見て「GPUに入る」と判断しないことが大切です。

PEFTが減らすもの、減らさないもの

PEFT(Parameter-Efficient Fine-Tuning)は、ベース重みの多くを凍結し、追加した少数パラメータなどを学習する手法群です。Hugging Face PEFT documentationでは、LoRA、IA3、prompt tuningなどが整理されています。

Full fine-tuningとPEFTで保持する学習状態の違い

比較軸 Full fine-tuning PEFT
更新対象 原則すべての重み adapterなど少数部分
gradient・optimizer state 全更新対象分 学習部分を中心に削減
ベースモデルのforward 必要 必要
activation 必要 原則として必要
タスク別保存 モデル全体になりやすい 小さな差分で管理しやすい
更新自由度 高い rank、挿入位置などの制約を受ける
複数タスク運用 モデル複製が重い ベース共有と切替がしやすい

PEFTは「GPUメモリをほぼ使わない学習」ではありません。gradientとoptimizer stateは減らせますが、大きなベースモデルを読み込み、入力を通す計算は残ります。長いsequenceではactivationが支配的になる場合もあります。

手法 追加・更新するもの 特徴 注意点
LoRA 線形層へ低ランク差分 差分をmergeできる実装もある rankとtarget moduleで容量が変わる
Adapter 層の間に小さなmodule タスク別部品を分離しやすい 推論経路に追加計算が残る場合がある
Prefix Tuning 各層で使う連続prefix ベースを凍結して条件付けする prefix長が容量へ影響する
Prompt Tuning 入力側の学習可能な埋め込み 追加パラメータが小さい タスクによって容量不足を検証する

Adapterの原論文Prefix-Tuning論文は、ベースを固定する異なる設計を示します。表は性能順位ではなく構造の違いです。

LoRAは低ランク行列で更新差分を表す

LoRA(Low-Rank Adaptation)は、元の重み行列 \(W\) を凍結し、更新差分 \(ΔW\) を2つの小さな行列の積で表します。

\[W’ = W + \Delta W, \qquad \Delta W = sBA\]

行列サイズは、Wが d_out × d_in、Aが r × d_in、Bが d_out × r です。rはrank、sはscaleです。

LoRAが凍結重みへ低ランク差分を加える仕組み

元の行列をすべて更新する場合のパラメータ数は \(d_{out}d_{in}\) です。LoRA差分は次の数です。

\[N_{\mathrm{LoRA}}=r(d_{in}+d_{out})\]

$ が両次元より十分小さければ、学習・保存する差分を小さくできます。LoRA論文の中心的な発想です。

ただしrankだけを見て設定を決められません。attentionのquery/valueだけへ入れるのか、key/outputやMLPにも入れるのかで容量とコストが変わります。rankを上げても、データの誤りや評価設計の不備は解消しません。

adapterをベースへmergeする運用では推論が単純になる一方、差分を即座に切り替える運用はしにくくなります。merge前のbase model ID、revision、tokenizer、chat template、adapterを一組として残します。

QLoRAは量子化したベースへLoRAを学習する

QLoRAは、量子化したベースモデルを凍結したままLoRAを学習する構成です。QLoRA論文では、4-bit NormalFloat、double quantization、paged optimizerなどを組み合わせ、勾配をLoRAへ伝えます。

項目 LoRA QLoRA
ベース重み 凍結する 量子化して凍結する
学習対象 低ランク差分 低ランク差分
主な追加目的 更新パラメータの削減 ベース保持メモリも削減
確認事項 rank、target module、scale 左記に加え量子化形式と計算dtype

量子化すれば必ず同じ品質になる、と一般化はできません。モデル、データ、タスク、量子化設定を固定した比較で判断します。

Prompting・RAG・継続事前学習との選び方

変えたい対象からPrompt・RAG・SFT・継続事前学習を選ぶ図

方式 主に変える場所 向く要求 主な失敗
Prompting / in-context learning 今回の入力 一時条件、少数の例 prompt肥大、指示の揺れ
RAG 外部文書と検索結果 最新情報、根拠提示 検索漏れ、無関係文書
継続事前学習 モデル重み 分野の言語・文章分布 指示応答を直接は教えない
SFT 重みまたはadapter 形式、分類、回答方針 過学習、一般能力の回帰

RAGの原論文は、モデル内部のparametric memoryと外部のnon-parametric memoryを組み合わせます。Don’t Stop Pretrainingは、分野内の未ラベルテキストなどで事前学習を継続する設計を扱います。

実務ではRAGで規程を取得し、SFTで「根拠内だけを使い所定JSONで返す」振る舞いを教え、promptで今回の条件を渡せます。方式ごとの失敗原因を個別に観測できる構成にします。

データセット設計は量より先に整える

SFTデータは入力、期待する応答、metadataで構成します。metadataに言語、タスク種別、出典、作成者、品質確認、機密区分を残すと、後から分布や問題例を追跡できます。

重複除去してグループ単位でデータを分割する流れ

ランダムに行単位で分割するだけでは、同じ原文の言い換えや、同一顧客の類似問い合わせがtrainとtestへまたがることがあります。未見性能を過大評価しないため、次の順で整えます。

  1. 完全重複とnear duplicate(ほぼ同じ例)を検出する。
  2. 同じ文書、会話、顧客、テンプレート由来の例をgroup化する。
  3. group単位でtrain、validation、testへ分ける。
  4. testは学習途中の意思決定に使わず、最終候補の比較まで保持する。
  5. 新しい時期への対応が重要なら時間分割も用意する。

数を増やす前に、誤った正解、方針の矛盾、定型句だけが違う複製を減らします。「少数なら常に高品質」「大量なら常に強い」とは限りません。学習曲線とカテゴリ別評価で追加データの効果を測ります。

学習用データにも著作権、利用規約、個人情報、営業秘密の確認が必要です。公開ログにはprompt injection文字列、秘密情報、悪意ある誤答が混ざる可能性があります。由来、利用根拠、加工履歴、除外理由を記録し、本番ログを無承認で学習へ戻さない設計にします。

学習設定は実効量で記録する

学習率、epoch、batch size、sequence length、warmup、weight decay、LoRA rankは相互に影響します。別モデルの有名な設定値をそのまま移植せず、実際に何tokenで何回更新したかを残します。

gradient accumulationを使う場合、1 updateあたりの概算token数は次のように考えられます。

\[T_{\mathrm{update}} \approx B_{\mathrm{device}} \times N_{\mathrm{device}} \times N_{\mathrm{accum}} \times \bar{L}\]

\(\bar{L}\) はpaddingを除く平均有効token長です。短い試行でもtrain loss、validation loss、タスク指標、learning rate、gradient norm、tokens seenを同じstep軸で記録します。loss spike、非有限の勾配、形式遵守率の悪化を早期停止条件へ含めます。

過学習と破滅的忘却を分けて測る

過学習はtrainへ合う一方、未見の同種データへ一般化しない問題です。破滅的忘却(新しい学習により既存能力が低下する現象)は、対象タスクが改善しても、一般的な指示追従や他タスクが悪化する問題です。

対象タスク改善と一般能力低下を別々に監視する評価図

継続的なinstruction tuningにおける忘却の研究でも忘却が実験的に分析されています。大きさはモデル、データ順序、評価条件で変わるため、論文の数値を自分のモデルへそのまま当てはめません。

評価面 比較対象
対象タスク F1、exact match、人手rubric base + prompt、RAGのみ
形式 JSON schema適合率、必須項目 学習前モデル
一般能力 既存の代表タスク、一般指示 base model
安全性 拒否入力、機密情報誘導 現行本番版
根拠整合 引用箇所との一致、根拠外回答 RAG baseline
運用 latency、VRAM、throughput、cost 現行構成

平均値だけでなく、言語、入力長、顧客種別、例外ケースごとに切ります。validationで最良のcheckpointが、本番制約や一般能力でも最良とは限りません。

デプロイではadapter単体を版管理しない

PEFTでは差分が小さく配布しやすい一方、適用するベースを間違えると再現できません。

ベースモデルとadapterなどを束ねて配備・rollbackする流れ

一つのreleaseとして、次を記録します。

  • base modelの名前、revision、重みhash、利用条件
  • tokenizerとchat templateの版
  • adapter方式、rank、target module、scale
  • 学習データsnapshotと前処理コードの版
  • seed、学習設定、checkpoint
  • task・general・safety評価結果
  • 推論時の量子化、system prompt、RAG構成
  • rollback先と切替手順

canary(少量のトラフィックで先行検証する方式)では、品質だけでなく例外率、形式不正率、latency、fallback率も監視します。adapter、prompt、検索indexを同時に変えると原因を切り分けにくいため、変更単位を記録します。

Full fine-tuningとPEFTの選択基準

条件 Full fine-tuningを検討 PEFTを検討
計算資源 全更新の状態を保持できる GPUメモリを抑えたい
タスク数 少数でモデルを専有できる ベースを共有し差分を切り替える
更新容量 広い変化が必要か検証する 小さなmoduleで足りる可能性がある
配布 モデル一式を管理できる 小さな差分を配布したい
rollback モデル版ごと切り替える baseとadapterの組を切り替える
実装制約 学習基盤が対応 adapter servingへの対応が必要

base model + prompt、RAG、PEFT、Full fine-tuningの順が常に正解という意味ではありません。要件に対する単純なbaselineを先に作り、満たさない理由を確認してから必要な方式へ進みます。

よくある誤解

Fine-tuningすればhallucinationはなくなる?

なくなりません。望ましい応答や拒否を増やせても、未知の事実を生成する性質や、RAGの検索失敗は別に評価します。

学習lossが低いほど本番性能は高い?

同じ学習例を記憶しただけでもlossは下がります。未見test、一般能力、安全性、本番に近いshadow評価が必要です。

LoRAなら品質はFull fine-tuningと同じ?

タスクと設定次第です。低ランク制約で足りる場合もあれば、target moduleやrankを変える必要がある場合もあります。同じデータと評価で比較します。

PEFTならベースモデルのライセンスを気にしなくてよい?

いいえ。adapterを利用するにはベースモデルが必要です。学習、商用利用、再配布、派生物に関するベースとデータ双方の条件を確認します。

学習後はpromptが不要?

不要とは限りません。推論時のrole、出力schema、RAG文脈の境界は引き続きpromptで指定します。学習時と推論時のtemplate不一致は性能劣化の原因になります。

実行前チェックリスト

  • [ ] 変えたい対象を「一時的な指示・外部知識・振る舞い・分野分布」に分類した
  • [ ] base + prompt、必要ならRAGのbaselineを測った
  • [ ] 学習データの利用権、個人情報、機密情報を確認した
  • [ ] 重複除去後にgroup単位でtrain・validation・testを分けた
  • [ ] chat template、EOS、truncation、loss maskをtokenize後に確認した
  • [ ] task、general、safety、format、運用指標を定義した
  • [ ] base、tokenizer、template、adapter、データ、評価を版管理した
  • [ ] canary、監視、rollback手順を用意した

まとめ

Fine-tuningは、事前学習済みLLMの重み全体または一部を追加データで更新する方法です。SFTやInstruction Tuningは学習目的、LoRAやAdapterは更新方法なので、同じ軸へ並べないことが第一歩です。

実装では、SFTのloss maskとchat template、Full fine-tuningの学習状態、PEFTでも残るactivation、LoRAのrankと適用層まで確認します。学習後は対象タスクの改善だけでなく、一般能力、安全性、形式、根拠整合、運用性能の回帰を測ります。

最新知識はRAG、一時的な条件はprompt、反復する振る舞いはSFT、分野の言語分布は継続事前学習が主な候補です。組み合わせる場合も、各方式が何を担当し、どこで失敗したかを観測できる構成にしてください。

関連記事

次回は、SFTの中でも多様な指示と応答を学ぶInstruction Tuningを詳しく扱います。

参考資料

コメント

タイトルとURLをコピーしました