LLMのファインチューニングとは、すでに事前学習された大規模言語モデルに追加学習を行い、特定の用途やタスク、文章スタイルなどに適応させる方法です。
一般的なLLMは、膨大な文章データを使った事前学習によって、文章生成や質問応答、要約、翻 translating など幅広い能力を獲得しています。
しかし、事前学習されたモデルはあくまで汎用的なモデルです。
そのため、特定企業向けのカスタマーサポート、専門分野の文章生成、決まった形式での回答、特定の文体での記事作成などを行わせたい場合には、追加学習によってモデルの振る舞いを調整することがあります。
これがLLMのファインチューニングです。
たとえば、汎用的なLLMに対してブログ記事の教師データを学習させることで、
「検索キーワードから記事構成を作る」
「H2・H3を使って記事を書く」
「特定の文体に統一する」
といった出力傾向を学習させることができます。
ただし、現在のLLM開発では、事前学習後に行われる調整全体を「Post-Training」と呼ぶことも多く、その中にSFTやDPOなど複数の手法があります。
LLMのファインチューニングを理解するための3つの分類
LLMのファインチューニングを理解するときは、すべての手法を同じ種類として考えないことが重要です。
SFT、DPO、LoRA、QLoRAなどは、それぞれ役割が異なります。
大きく分けると、次の3つの観点があります。
何を学習するか
モデルにどのような振る舞いを学習させるかという分類です。
代表的な方法には、以下があります。
- SFT
- DPO
- PPO
- GRPO
たとえばSFTは「この質問にはこのように回答する」という教師データを学習します。
DPOは「回答Aと回答Bなら回答Aの方が望ましい」といったPreference Dataを利用します。
どのパラメータを学習するか
モデル内部のどのパラメータを更新するかという分類です。
代表的なのが以下です。
- Full Fine-Tuning
- LoRA
- その他のPEFT
Full Fine-Tuningでは基本的にモデル全体のパラメータを更新します。
一方、LoRAではベースモデルのパラメータを固定し、追加された小さなパラメータを中心に学習します。
どのようにメモリ使用量を抑えるか
LLMの学習には大量のGPUメモリが必要です。
そこで、次のような技術が利用されます。
- FP16・BF16
- 量子化
- QLoRA
- Gradient Checkpointing
- FSDP
- DeepSpeed
つまり、SFTとLoRAは競合する概念ではありません。
たとえば、
SFT+LoRA
SFT+QLoRA
DPO+LoRA
といった組み合わせが可能です。
SFTとは
SFTは教師ありファインチューニング
SFTは「Supervised Fine-Tuning」の略です。
日本語では教師ありファインチューニングと呼ばれます。
SFTでは基本的に、
「入力」
「理想的な出力」
の組み合わせをモデルに学習させます。
たとえば、
ユーザー:
チノパンとは何ですか?
アシスタント:
チノパンとは、一般的にチノクロスと呼ばれる綿素材を使用したパンツです。
といったデータです。
チャットモデルの場合は、system、user、assistantなどの役割を持つ会話形式のデータを利用することがあります。
SFTで学習できること
SFTは特に、次のような用途と相性があります。
- 回答形式を統一する
- 文体を学習させる
- 特定タスクの回答方法を学習させる
- JSONなど特定フォーマットを守らせる
- 専門分野の回答傾向を学習させる
- カスタマーサポートの回答スタイルを学習させる
一方で、頻繁に変化する最新情報をモデル内部へ覚え込ませる用途には、必ずしも最適とは限りません。
Full Fine-Tuningとは
モデル全体のパラメータを更新する方法
Full Fine-Tuningでは、基本的にモデル全体のパラメータを学習対象にします。
たとえば70億パラメータを持つ7Bモデルであれば、大量のパラメータを更新しながら学習します。
モデル全体を調整できるため自由度は高いものの、非常に多くの計算資源を必要とします。
推論より多くのGPUメモリが必要になる
LLMを学習するときは、モデルの重みだけをGPUメモリに保存するわけではありません。
一般的には、
- モデルの重み
- 勾配
- Optimizer State
- Activation
なども必要になります。
そのため、
「7BモデルをFP16で保存すると約14GBだから、14GBのGPUがあればFull Fine-Tuningできる」
とは限りません。
実際の学習では、さらに多くのVRAMが必要になります。
その問題を軽減するために広く利用されているのがLoRAです。
LoRAとは
LoRAは一部の追加パラメータだけを学習する方法
LoRAは「Low-Rank Adaptation」の略です。
モデル本体のパラメータを直接すべて更新するのではなく、低ランク行列によって表現された追加部分を学習します。
概念的には、元の重みをWとすると、
W+ΔW
という形でモデルの出力を変化させます。
LoRAでは、このΔWを、
ΔW=B×A
のような低ランク行列として表現します。
元のベースモデルの重みは基本的に固定され、LoRA Adapter側のパラメータを学習します。
LoRAのメリット
LoRAの大きなメリットは、学習対象となるパラメータ数を大幅に減らせることです。
これにより、Full Fine-Tuningと比較してGPUメモリの使用量を抑えやすくなります。
さらに、学習後にはモデル全体ではなくLoRA Adapterだけを保存できる場合があります。
そのため、
ベースモデル
+SEOライター用LoRA
+カスタマーサポート用LoRA
+商品説明用LoRA
といった運用も可能です。
LoRAは必ず高速になるわけではない
LoRAは学習対象パラメータ数を大幅に減らせます。
ただし、ベースモデル自体のForward PassやBackward Passに必要な計算が完全になくなるわけではありません。
そのため、
「LoRAなら必ずFull Fine-Tuningより大幅に高速になる」
と断定するのは正確ではありません。
環境や実装、モデルサイズ、Batch Size、Sequence Lengthなどによって学習速度は変化します。
LoRAの大きな利点は、主に学習パラメータ数やメモリ使用量を抑えられることだと理解するとよいでしょう。
LoRAでもモデル性能が低下する可能性はある
LoRAでは元のモデルパラメータを直接変更しないため、Adapterを外せば元のベースモデルへ戻せます。
ただし、LoRAを適用した状態でモデルの性能が必ず維持されるわけではありません。
偏ったデータや過度な学習を行えば、特定タスクに過適応したり、一般的な能力が低下したりする可能性があります。
LoRAの重要なパラメータ
r
LoRAで特に重要なのが「r」です。
rはLoRAの低ランク行列のRankを表します。
たとえば、
r=8
r=16
r=32
r=64
などを設定できます。
一般的には、rを大きくするほど学習可能なパラメータ数が増えます。
その一方で、GPUメモリ使用量や計算量も増加します。
そのため、rを大きくすれば必ず性能が向上するわけではありません。
最初の実験では8〜32程度から試すケースもありますが、モデルやデータ量、タスクによって最適値は変わります。
lora_alpha
lora_alphaは、LoRAによる更新量のスケーリングに関係するパラメータです。
通常のLoRAでは、概念的に、
lora_alpha ÷ r
によって更新量が調整されます。
そのため、rだけでなくlora_alphaとの組み合わせも重要です。
target_modules
target_modulesは、Transformer内部のどの層へLoRAを適用するかを決める設定です。
たとえば、
q_proj
k_proj
v_proj
o_proj
などがあります。
モデルによっては、
gate_proj
up_proj
down_proj
なども対象になります。
ただし、モジュール名はモデルアーキテクチャによって異なります。
そのため、別のモデル向けLoRA設定をそのままコピーするのではなく、使用するモデルの構造を確認する必要があります。
QLoRAとは
QLoRAは量子化されたモデルとLoRAを組み合わせる方法
QLoRAは、LoRAをさらにメモリ効率よく利用するための手法です。
代表的なQLoRAでは、ベースモデルを4bitに量子化し、そのベースモデルを固定した状態でLoRA Adapterを学習します。
つまり、
4bit量子化したベースモデル
+LoRA
という構成です。
QLoRAが省メモリになる理由
通常のLoRAでは、ベースモデルをFP16やBF16などで保持することがあります。
QLoRAではベースモデルを4bitなどで保持できるため、GPUメモリ使用量を大幅に削減できます。
そのため、比較的限られたGPU環境でも大規模なモデルをファインチューニングしやすくなります。
QLoRAは必ず高速になるわけではない
QLoRAはVRAM削減に非常に有効ですが、
「QLoRAは通常のLoRAより必ず高速」
というわけではありません。
量子化や逆量子化などの処理が入るため、学習速度についてはGPUやライブラリ、モデル構成などに左右されます。
QLoRAの主なメリットは、学習速度よりもGPUメモリ使用量の削減にあると考えるとよいでしょう。
DPOとは
DPOは好ましい回答を学習する方法
DPOは「Direct Preference Optimization」の略です。
SFTが「この質問にはこの回答を返す」という教師データを学習するのに対して、DPOでは、
質問
+好ましい回答
+好ましくない回答
という比較データを学習します。
たとえば、
Prompt:
SEOについて説明してください。
Chosen:
詳しく分かりやすい回答
Rejected:
不正確で分かりにくい回答
といった形式です。
モデルは、Chosenのような回答を出しやすくし、Rejectedのような回答を出しにくくなるように学習します。
SFTとDPOの違い
SFTでは、
「この質問には、このように回答する」
ことを学習します。
DPOでは、
「回答Aと回答Bなら、回答Aの方が望ましい」
ことを学習します。
したがって、役割が異なります。
SFTのあとにDPOを行う場合もある
独自のチャットモデルを作る場合、
Base Model
↓
SFT
↓
DPO
という流れが使われることがあります。
ただし、必ずSFTを行ってからDPOをしなければならないわけではありません。
すでにInstruction Tuningされたモデルをベースに、直接Preference Optimizationを行うケースもあります。
RLHFとDPOの違い
従来のRLHF
代表的なRLHFでは、
Preference Data
↓
Reward Model
↓
PPOなどの強化学習
という流れを使用します。
人間がどちらの回答を好むかというデータを使ってReward Modelを作り、そのRewardを利用してモデルを最適化します。
DPO
DPOでは、明示的なReward Modelを別途学習して強化学習を行う方法とは異なり、Preference Dataから比較的直接的にモデルを最適化します。
そのため、
DPO=RLHFそのもの
と考えるのではなく、Preference OptimizationやPost-Trainingの代表的手法の一つとして理解するとよいでしょう。
LLMファインチューニングの基本的な手順
1.目的を決める
最初に、
「何を改善したいのか」
を明確にします。
たとえば、
- 回答形式を統一したい
- SEO記事を書けるようにしたい
- 商品説明を決まった文体で書きたい
- 特定の分類タスクを高精度化したい
- カスタマーサポート向けに調整したい
などです。
ここが曖昧なまま学習を始めると、モデルを評価する基準も曖昧になります。
2.Fine-Tuningが本当に必要か判断する
目的によっては、Fine-TuningよりPrompt EngineeringやRAGの方が適していることがあります。
たとえば、
「自社の最新商品情報を回答させたい」
という目的なら、モデルへ商品情報を覚え込ませるよりもRAGを利用する方が管理しやすいケースがあります。
一方、
「回答スタイルを統一したい」
「特定フォーマットを安定して出力させたい」
のであればFine-Tuningが有力です。
3.ベースモデルを選ぶ
次に学習対象となるベースモデルを選びます。
代表的なOSS系LLMには、
- Llama系
- Qwen系
- Gemma系
- Mistral系
などがあります。
モデルにはBase ModelとInstruct Modelがあります。
Base Modelは主に事前学習された状態のモデルです。
Instruct Modelは、すでに指示に従って回答する能力を追加学習されたモデルです。
チャットボットを作る場合は、Instruct Modelから始めた方が扱いやすいケースが多くあります。
4.学習データを作る
ファインチューニングで非常に重要なのが学習データです。
モデルやGPU性能だけでなく、教師データの品質によって最終的な性能が大きく変わります。
良いデータには、次のような特徴があります。
- 回答内容が正確
- 指示が明確
- 回答形式が統一されている
- 重複データが少ない
- 矛盾が少ない
- 多様な質問パターンが含まれている
- 実際の利用場面に近い
単純にデータ量を増やせば性能が向上するとは限りません。
高品質なデータを作ることが重要です。
5.Training・Validation・Testに分ける
データセットは一般的に、
Training Data
Validation Data
Test Data
に分けます。
Training Dataは実際の学習に使用します。
Validation Dataは学習中の性能確認やハイパーパラメータ調整に使用します。
Test Dataは最終的な性能評価に使用します。
80%・10%・10%などに分割することがありますが、この比率は絶対ではありません。
データセットの規模によって適切な割合は変わります。
6.Chat Templateを確認する
チャットモデルでは、単純な文章として入力するのではなく、モデルごとのChat Templateが使用されます。
概念的には、
system
user
assistant
といった役割が、モデル固有の特殊トークンへ変換されます。
モデルによってChat Templateは異なるため、学習時と推論時で形式が食い違うと、性能低下の原因になることがあります。
7.LoRAまたはQLoRAを設定する
計算資源を抑えたい場合は、LoRAやQLoRAを設定します。
代表的なLoRA設定には、
- r
- lora_alpha
- lora_dropout
- target_modules
などがあります。
使用するモデルのアーキテクチャを確認しながら設定することが重要です。
8.Learning Rateを設定する
Learning Rateは学習結果に大きな影響を与えます。
大きすぎると学習が不安定になったり、モデルの既存能力を損なったりする可能性があります。
小さすぎると十分に学習されない場合があります。
LoRAを使ったSFTでは、
1e-4
2e-4
5e-5
などから試すケースがあります。
ただし、固定された正解値ではありません。
モデルサイズ、データ量、Batch Size、LoRA設定などによって最適値は変化します。
9.Batch Sizeを決める
GPUメモリが少ない場合、大きなBatch Sizeを設定できないことがあります。
その場合はGradient Accumulationを利用できます。
たとえば、
per_device_train_batch_size=1
gradient_accumulation_steps=16
とすると、1GPUの場合は概念的にEffective Batch Sizeを16程度にできます。
複数GPUの場合はGPU数も関係します。
10.Epoch数を設定する
Epochとは、学習データ全体を何回学習するかを表します。
1〜3 Epoch程度から試すケースがありますが、これも固定的な正解ではありません。
重要なのはEpoch数だけではなく、
- Dataset Size
- 総Token数
- Optimizer Step数
- Learning Rate
なども合わせて考えることです。
11.学習を実行する
Hugging Face環境では、
- Transformers
- Datasets
- TRL
- PEFT
- bitsandbytes
などを組み合わせて学習できます。
TransformersはLLM本体を扱うライブラリです。
Datasetsは学習データ管理に利用できます。
TRLはSFTやDPOなどのPost-Trainingに利用できます。
PEFTはLoRAなどのParameter-Efficient Fine-Tuningに利用されます。
bitsandbytesは4bit・8bit量子化などで使われることがあります。
過学習に注意する
過学習とは
過学習とは、学習データには高い性能を示す一方で、未知のデータに対する性能が低下してしまう状態です。
たとえば同じ形式の教師データを過度に学習すると、似た質問にしか対応できなくなる可能性があります。
Training Lossだけを見ない
学習中にはTraining Lossが低下しているかを確認します。
ただし、
Training Lossが下がった=良いモデルになった
とは限りません。
Training Lossが低下し続けていても、Validation性能が悪化している場合は過学習の可能性があります。
そのため、Validation Dataによる評価も重要です。
ファインチューニング後の評価方法
ベースモデルと比較する
Fine-Tuning後は、
Base Model
Fine-Tuned Model
へ同じ質問を入力して比較します。
重要なのは、学習データに含まれていない質問を使うことです。
学習済みデータで評価すると、本当の汎化性能を確認できません。
タスクに合った評価指標を設定する
たとえばSEO記事生成モデルであれば、
- 事実性
- 見出し構成
- 検索意図への適合
- 文体
- フォーマット遵守率
- 重複表現
- 禁止表現の有無
などを評価できます。
Lossだけでなく、実際の用途に沿った評価が重要です。
RAGとFine-Tuningの違い
RAGは外部情報を検索して回答する
RAGは「Retrieval-Augmented Generation」の略です。
ユーザーの質問に応じて関連文書を検索し、その情報をLLMへ渡して回答を生成します。
そのため、
- 社内文書
- 商品情報
- 最新ニュース
- 価格
- 在庫情報
- 頻繁に更新される情報
などを扱う場合に適しています。
Fine-Tuningはモデルの振る舞いを変える
Fine-Tuningでは、学習によってモデルのパラメータやAdapterを調整します。
そのため、
- 文体
- 回答形式
- タスク遂行方法
- 専門的な応答パターン
などを学習させる用途に向いています。
Fine-Tuningでも知識は学習できる
Fine-Tuningによって特定の知識をモデルへ学習させること自体は可能です。
ただし、頻繁に変わる知識をモデル内部へ保存すると、情報を更新するたびに再学習が必要になる可能性があります。
さらに、情報の出典管理や削除も難しくなります。
そのため、更新頻度の高い情報を扱うのであればRAGが適しているケースが多くあります。
RAGとFine-Tuningは併用できる
RAGとFine-Tuningはどちらか一方しか使えないわけではありません。
Fine-Tuningによって回答スタイルやタスク処理方法を調整し、RAGで最新情報を取得する構成もできます。
イメージとしては、
Fine-Tuning
=どう答えるか
RAG
=何を根拠に答えるか
と考えると分かりやすいでしょう。
Prompt Engineering・RAG・Fine-Tuningの使い分け
まずPrompt Engineeringを試す
LLMの回答を改善したいからといって、最初からFine-Tuningを行う必要はありません。
まずはPrompt Engineeringで解決できるかを検討します。
プロンプトだけで十分に安定した回答が得られるのであれば、追加学習は不要です。
外部知識が必要ならRAGを検討する
社内データや最新情報を回答に利用したいのであればRAGを検討します。
RAGであれば、外部データを更新するだけで最新情報を反映できます。
モデルの振る舞いを変えたいならFine-Tuningを検討する
Prompt EngineeringやRAGだけでは、
- 回答形式が安定しない
- 特定の文体にならない
- 専門タスクの精度が足りない
といった問題が残る場合に、Fine-Tuningを検討します。
個人でLLMをファインチューニングするときの構成
よく使われるライブラリ
OSSモデルを自分でファインチューニングする場合は、次のような構成がよく利用されます。
Python
+PyTorch
+Transformers
+Datasets
+TRL
+PEFT
+bitsandbytes
これらを組み合わせることで、LoRAやQLoRAを使ったSFTを比較的簡単に構築できます。
初心者はSFT+LoRAまたはQLoRAから始める
初めてLLMのファインチューニングを行う場合は、
小〜中規模のInstruct Model
↓
高品質な数百〜数千件程度の教師データ
↓
SFT
↓
LoRAまたはQLoRA
↓
未学習データで評価
という流れから始めると理解しやすいでしょう。
ただし、数百〜数千件あれば必ず十分という意味ではありません。
必要なデータ量はタスクの複雑さによって大きく変わります。
単純な文体変換であれば比較的少ないデータでも効果が出る可能性があります。
一方、高度な推論能力や多言語対応、複数分野への対応などでは、より多くのデータが必要になる場合があります。
LLMのファインチューニングではデータ品質が重要
データ量だけを増やせばよいわけではない
LLMのファインチューニングでは、
GPU性能
モデルサイズ
LoRA Rank
Learning Rate
などに注目しがちです。
しかし、実務では教師データの品質が最終的な性能を大きく左右します。
特に、
- 誤情報
- 矛盾
- 重複
- 曖昧なInstruction
- 回答品質のばらつき
- フォーマットの不統一
などが含まれていると、モデルもそれらを学習してしまいます。
実際の用途に近いデータを作る
たとえばライター向けLLMを作る場合、
検索キーワード
↓
検索意図
↓
記事構成
↓
H2・H3
↓
本文
といった形で、実際の業務フローに近いデータを作ることが重要です。
LLMファインチューニングの全体像
LLMのファインチューニングをシンプルに整理すると、
既存のLLM
+高品質な教師データ
+追加学習
=特定用途に適応したモデル
という仕組みです。
そして、実際の開発では、
Instruct Model
↓
SFT
↓
LoRAまたはQLoRA
↓
Validation
↓
タスクごとの評価
↓
必要に応じてDPOなど
↓
Deployment
という流れが一つの代表例です。
重要なのは、
「どのモデルを使うか」
だけではありません。
それ以上に、
「何を学習させたいのか」
「Fine-Tuningが本当に必要なのか」
「どのような教師データを作るのか」
「どのように評価するのか」
を事前に設計することが重要です。
特に、最新情報や外部知識を扱う目的ならRAG、モデルの文体や行動、回答形式を変える目的ならFine-Tuningというように、それぞれの役割を理解して使い分けることが、LLM開発では重要になります。
以上、LLMのファインチューニングについてでした。
最後までお読みいただき、ありがとうございました。
