🧠LoRA ファインチューニング ハイパーパラメータガイド

LoRA のランクとアルファ、エポック、バッチサイズ+勾配蓄積、QLoRA と LoRA の比較、ターゲットモジュールなど、LLM ファインチューニングの最適設定をステップバイステップで学びます。

LoRAのハイパーパラメータは、Low-Rank Adaptationがどのように調整されるかを決める調整可能な設定です。 ファインチューニングする 大規模言語モデル(LLM)を。学習率やエポック数など多くの選択肢と無数の組み合わせがあるため、適切な値を選ぶことが精度、安定性、品質、そして幻覚の少なさにとって重要です。適切に行えば、 LoRAは完全なファインチューニングの性能に匹敵できます 同時にVRAMを4倍少なく使用します。

ここでは何百もの研究論文と実験からの知見に基づいてこれらのパラメータのベストプラクティスを学び、それらがモデルにどのように影響するかを確認します。 Unslothのデフォルトの使用を推奨しますがこれらの概念を理解することで完全なコントロールが得られます。 目標はハイパーパラメータの数値を変更して精度を向上させつつ、 過学習や未学習(アンダーフィッティング)過学習はモデルが訓練データを記憶してしまい、新しく見たことのない入力に対して一般化する能力を損なう場合に発生します。目標は単に記憶するのではなく、よく一般化するモデルです。

では、LoRAとは何でしょうか?

LLMではモデルの重みがあります。Llama 70Bには700億の数値があります。すべての700億の数値を変更する代わりに、各重みに薄い行列AとBを追加してそれらを最適化します。これにより重みの約1%だけを最適化することになります。

モデル重み(黄色)を最適化する代わりに、2つの薄い行列AとBを最適化します。

🔢 重要なファインチューニングのハイパーパラメータ

学習率(Learning Rate)

各トレーニングステップでモデルの重みがどれだけ調整されるかを定義します。

  • 高い学習率: 初期収束は速くなりますが、設定が高すぎるとトレーニングが不安定になったり最適な最小値を見つけられなくなったりします。

  • 低い学習率: より安定で精密なトレーニングにつながりますが、収束により多くのエポックが必要になり全体のトレーニング時間が増える場合があります。低い学習率はしばしば未学習を引き起こすと考えられますが、実際には 過学習 を招いたり、モデルが学習するのを妨げたりすることさえあります。

  • 典型的な範囲: 2e-4 (0.0002)から 5e-6 (0.000005). 🟩 通常のLoRA/QLoRAファインチューニングの場合, 開始点として以下を推奨します 2e-4 🟦 強化学習の場合 (DPO、GRPOなど)、我々は以下を推奨します 5e-6 . 完全なファインチューニングの場合、 一般的により低い学習率が適切です。

エポック(Epochs)

モデルがトレーニングデータセット全体を見る回数です。

  • エポックを増やすと: モデルの学習を助けることができますが、エポック数が多すぎると トレーニングデータを記憶してしまうことで新しいタスクでの性能が低下します。

  • エポックを減らすと: トレーニング時間を短縮でき、過学習を防げますが、モデルがデータセットの基礎となるパターンを学習するのに十分なエポック数がない場合は未学習モデルになる可能性があります。

  • 推奨: 1〜3エポック。ほとんどの指示ベースのデータセットでは、3エポックを超えてトレーニングしても得られる効果は限定的で、過学習のリスクが高まります。

LoRAまたはQLoRA

LoRAは16ビット精度を使用し、QLoRAは4ビットのファインチューニング方式です。

  • LoRA: 16ビットのファインチューニング。やや高速でやや精度が高いですが、VRAMを大幅に多く消費します(QLoRAの4倍)。16ビット環境や最大精度が求められるシナリオに推奨されます。

  • QLoRA: 4ビットのファインチューニング。やや遅くわずかに精度が低くなる傾向がありますが、はるかに少ないVRAMを使用します(4分の1)。 🦥 70B LLaMAはUnslothのQLoRAで<48GBのVRAMに収まります - 詳細はこちらarrow-up-right.

ハイパーパラメータと推奨事項:

ハイパーパラメータ
機能
推奨設定

LoRAランク (r)

LoRAアダプタ行列内の学習可能パラメータ数を制御します。ランクが高いほどモデルの容量は増えますが、メモリ使用量も増加します。

8、16、32、64、128 16または32を選択

LoRAアルファ (lora_alpha)

ランクに対する微調整の強さをスケーリングします(r).

r (標準)または r * 2 (一般的なヒューリスティック)。 詳細はこちら.

LoRAドロップアウト

トレーニング中にLoRAアクティベーションの一部をランダムにゼロにする正則化手法で、過学習を防ぎます。 あまり有用ではないため、デフォルトで0に設定します。

0(デフォルト)〜0.1

重み減衰

大きな重みにペナルティを与えて過学習を防ぎ、汎化性能を向上させる正則化項です。大きすぎる値は避けてください!

0.01(推奨) - 0.1

ウォームアップステップ

トレーニング開始時に学習率を徐々に増加させます。

総ステップ数の5〜10%

スケジューラタイプ

トレーニング中に学習率を動的に調整します。

linear または cosine

シード(random_state)

結果の再現性を確保するための固定された数値です。

任意の整数(例: 42, 3407)

対象モジュール

LoRAアダプタを適用するモデルの部分を指定します — 注意機構(attention)、MLP、またはその両方。

Attention: q_proj、k_proj、v_proj、o_proj MLP: gate_proj、up_proj、down_proj

主要なすべての線形層を対象にすることを推奨します: q_proj、k_proj、v_proj、o_proj、gate_proj、up_proj、down_proj.

🌳 勾配蓄積とバッチサイズの同等性

実効バッチサイズ

バッチサイズを正しく設定することは、トレーニングの安定性とGPUのVRAM制限のバランスに重要です。これは、2つのパラメータの積によって管理されます: 実効バッチサイズ. 実効バッチサイズ = batch_size * gradient_accumulation_steps

  • 大きい 実効バッチサイズ 一般的に、より滑らかで安定したトレーニングにつながります。

  • 大きい より小さい有効バッチサイズ より多くの分散(バラつき)をもたらす可能性があります。

すべてのタスクは異なりますが、以下の構成は安定した開始点を提供します。 実効バッチサイズ 16 の有効バッチサイズは、最新のGPUでの多くのファインチューニングタスクに適しています。

パラメータ
説明
推奨設定

バッチサイズ (batch_size)

単一のGPUでの1回の順伝播/逆伝播で処理されるサンプル数。 VRAM使用量の主な要因。値を大きくするとハードウェア利用率が向上しトレーニングが高速化することがありますが、メモリに収まる場合に限ります。

2

勾配蓄積(Gradient Accumulation) (gradient_accumulation_steps)

モデルの重みを1回更新する前に処理するマイクロバッチの数。 トレーニング時間の主な要因。 より大きな batch_size をシミュレートしてVRAMを節約できます。値が大きいほどエポックあたりのトレーニング時間が増加します。

8

実効バッチサイズ (計算済み)

各勾配更新で使用される実際のバッチサイズ。トレーニングの安定性、品質、および最終的なモデル性能に直接影響します。

4〜16 推奨: 16(2 * 8から)

VRAMとパフォーマンスのトレードオフ

各トレーニングステップで32サンプルを使いたいと仮定します。すると、次のいずれかの構成が使えます:

  • batch_size = 32, gradient_accumulation_steps = 1

  • batch_size = 16, gradient_accumulation_steps = 2

  • batch_size = 8, gradient_accumulation_steps = 4

  • batch_size = 4, gradient_accumulation_steps = 8

  • batch_size = 2, gradient_accumulation_steps = 16

  • batch_size = 1, gradient_accumulation_steps = 32

これらはいずれもモデルの重み更新に対しては同等ですが、ハードウェア要件は大きく異なります。

最初の構成(batch_size = 32)は 最も多くのVRAMを使用し、 最後の構成(batch_size = 1)は )は最も少ないVRAMを使用します、 しかしトレーニングが若干遅くなるという代償を伴います。. OOM(メモリ不足)エラーを避けるため、常により小さい batch_size を設定し、 gradient_accumulation_steps を増やして目標の 実効バッチサイズ.

🦥 Unslothの勾配蓄積修正(Gradient Accumulation Fix)

勾配蓄積とバッチサイズ は現在Unslothでは完全に等価です 勾配蓄積に関するバグ修正によりです。私たちは勾配蓄積が同じ結果を生まないという一般的な問題を解決する特定のバグ修正を実装しました。これはコミュニティ全体で知られている課題でしたが、Unslothユーザーにとっては、これら二つの方法は現在交換可能になっています。

私たちのブログ記事をお読みくださいarrow-up-right 詳細については。

私たちの修正以前は、組み合わせによっては batch_size そして gradient_accumulation_steps 同じ結果をもたらしました 実効バッチサイズ (つまり、 batch_size × gradient_accumulation_steps = 16)は同等の訓練挙動にはなりませんでした。例えば、次のような構成は b1/g16, b2/g8, b4/g4, b8/g2、および b16/g1 はすべて 実効バッチサイズ が16ですが、グラフが示すように、標準的な勾配蓄積を使用した場合に損失曲線は一致しませんでした:

(適用前 - 標準的な勾配蓄積)

我々の修正を適用した後、損失曲線は、どのようにして16が達成されたかに関わらず、正しく一致するようになりました: 実効バッチサイズ が16であるかの

(適用後 - 🦥 Unsloth の勾配蓄積(Unsloth Gradient Accumulation))

🦥 Unsloth における LoRA ハイパーパラメータ

以下は標準的な構成の例です。 Unsloth は最適化されたデフォルトを提供しますが、これらのパラメータを理解することは手動で調整する上で重要です。

  1. ファインチューニングプロセスのランク(r)。大きなランクはより多くのメモリを使用し遅くなりますが、複雑なタスクで精度を高めることができます。高速なファインチューニングには 8 や 16 のようなランクを、最大で 128 までを推奨します。ランクが大きすぎると過学習を引き起こし、モデルの品質を損なう可能性があります。\

  2. 最適なパフォーマンスのために、 LoRA はすべての主要な線形層に適用するべきです. 研究は示しています 主要なすべての層を対象にすることが、完全なファインチューニングの性能に匹敵するために重要であると。メモリ使用量を減らすためにモジュールを削除することは可能ですが、節約効果は最小限であるため最大限の品質を保つために強く推奨しません。\

  3. 微調整の強さを制御するスケーリング係数。ランク(r)と等しく設定することは信頼できる基準です。人気かつ効果的なヒューリスティックはランクの2倍(r * 2)に設定することで、LoRA の更新により大きな重みを与え、モデルがより積極的に学習するようになります。 詳細はこちら.\

  4. 正則化手法で、 過学習を防ぐ ために、各トレーニングステップで LoRA 活性化の一部をランダムにゼロにします。 最近の研究は示唆していますarrow-up-right ことを 短いトレーニング実行に対して ファインチューニングで一般的に行われる、 lora_dropout は信頼できる正則化手段ではないかもしれません。 🦥 Unsloth の内部コードは、 lora_dropout = 0の場合に訓練を最適化できるため、わずかに高速になりますが、過学習が疑われる場合は非ゼロの値を推奨します。\

  5. これを "none" のままにして、トレーニングを高速化しメモリ使用量を削減します。この設定は線形層のバイアス項の学習を避けます。バイアスを学習可能パラメータとして追加しても実用的な利得はほとんどありません。\

  6. 選択肢は True, False、および "unsloth". 🦥 私たちは "unsloth" を推奨します。これによりメモリ使用量がさらに約30%削減され、非常に長いコンテキストのファインチューニングをサポートします。詳細は 長いコンテキストトレーニングに関する当社のブログ記事arrow-up-right.\

  7. 決定論的で再現可能な実行を保証するためのシードです。トレーニングには乱数が関与するため、実験の一貫性を保つには固定シードの設定が不可欠です。\

  8. 高度な機能で、 ランク安定化LoRAarrow-up-rightを実装します。もし Trueに設定すると、有効なスケーリングは lora_alpha / sqrt(r) の代わりに lora_alpha / rになります。これは特に高いランクで安定性を改善する場合があります。 詳細はこちら.\

  9. 高度な手法で、 LoftQarrow-up-rightでは、事前学習済み重みから上位'r'の特異ベクトルでLoRA行列を初期化します。これにより精度が向上する可能性がありますが、トレーニング開始時に大きなメモリ増加を引き起こすことがあります。

LoRA 重みの更新の確認:

次を検証する際、 LoRA アダプタ重みがファインチューニング後に更新されたかどうかを確認する際には、 np.allclose() を比較に使用するのは避けてください。この方法は、特に LoRA Aのように小さなガウス値で初期化されるものにおいて、微妙だが意味のある変化を見逃すことがあります。これらの変化は緩い数値許容範囲では重要と見なされない場合があります。このセクションに関する情報提供に感謝します。 寄稿者arrow-up-right に感謝します。

重みの更新を確実に確認するには、次を推奨します:

  • 使用すること チェックサムまたはハッシュ比較 (例:MD5)

  • 計算すること テンソル間の絶対差の合計 を比較すること

  • テンソルの統計情報 (例:平均、分散)を手動で検査すること

  • または使用すること np.array_equal() 厳密な等価性が期待される場合

📐LoRA の Alpha とランクの関係

circle-check
W^=W+αrank×AB\hat{W} = W + \frac{\alpha}{\text{rank}} \times AB
rsLoRA の他のスケーリングオプション。sqrt(r) が最良です。
W^rslora=W+αrank×AB\hat{W}_{\text{rslora}} = W + \frac{\alpha}{\sqrt{\text{rank}}} \times AB

左側に LoRA の式があります。薄い行列 A と B を alpha をランクで割った値でスケーリングする必要があります。 つまり alpha/rank を少なくとも = 1 に保つべきです.

に従うと rsLoRA(rank stabilized lora)論文arrow-up-right、代わりに alpha をランクの平方根でスケーリングすべきだとしています。他の選択肢も存在しますが、理論的にはこれが最適です。左のプロットは他のランクとそのパープレキシティ(小さいほど良い)を示しています。これを有効にするには、次を設定します use_rslora = True を Unsloth に設定します。

私たちの推奨は alpha をランクと等しく、または少なくともランクの 2 倍に設定することです。 つまり alpha/rank = 1 または 2 です。

🎯 LoRA ターゲットモジュールと QLoRA 対 LoRA

circle-check

経験的実験や元のような研究論文によると QLoRA 論文arrow-up-right、アテンションと MLP レイヤーの両方に LoRA を適用するのが最良です。

この図は、異なるターゲットモジュール構成に対する RougeL スコア(高いほど良い)を示し、LoRA と QLoRA を比較しています。

最初の 3 つの点は次を示しています:

  1. QLoRA-All: すべての FFN/MLP と Attention レイヤーに LoRA を適用。 🔥 これが全体的に最も優れた性能を示します。

  2. QLoRA-FFN:FFN のみに LoRA。 等価: gate_proj, up_proj, down_proj。

  3. QLoRA-Attention:Attention レイヤーのみに LoRA を適用。 等価: q_proj, k_proj, v_proj, o_proj.

😎 入力をマスクして完成文のみでトレーニングすること

その QLoRA 論文arrow-up-right は入力をマスクし 完成のみでの訓練 (出力またはアシスタントメッセージ)はさらに 精度を向上させることができます 数パーセントポイント(1%)。以下は Unsloth での実装例です:

ではない 完成のみでの訓練:

ユーザー: こんにちは、2+2 はいくつですか? アシスタント: 答えは 4 です。 ユーザー: こんにちは、3+3 はいくつですか? アシスタント: 答えは 6 です。

訓練 完成のみで:

ユーザー: こんにちは、2+2 はいくつですか? アシスタント: 答えは 4 です。 ユーザー: こんにちは、3+3 はいくつですか? アシスタント: 答えは 6.

QLoRA 論文では、 完成のみでの訓練が 精度をかなり向上させると述べられており、特にマルチターンの会話ファインチューンで効果的です!これを私たちは こちらの会話ノートブックで行っていますarrow-up-right.

有効にするには 完成での訓練を Unsloth では、instruction と assistant の部分を定義する必要があります。 🦥 今後これをさらに自動化する予定です!

Llama 3、3.1、3.2、3.3 および 4 モデルでは、部分は次のように定義します:

Gemma 2、3、3n モデルでは、部分は次のように定義します:

🔎視覚モデル、VLM 向けのアシスタント応答のみでの訓練

言語モデルの場合、前述のように from unsloth.chat_templates import train_on_responses_only を使用できます。視覚モデルでは、追加の引数を UnslothVisionDataCollator の一部として使用してください、前と同様です!

例えば Llama 3.2 Vision の場合:

🔑 過学習と過少学習の回避

過学習 (一般化が poor/特化しすぎ)

モデルが訓練データを記憶し、その統計的ノイズまで学んでしまうため、未見のデータに対して一般化できなくなる。

circle-check

解決策:

  • 学習率を調整する: 高い学習率は短い訓練で特に過学習を招きやすい。長時間の訓練では高い学習率の方がうまくいく場合もある。どちらが良いかは実験して確認するのが最良。

  • 訓練エポック数を減らす。1、2、または3エポックで訓練を停止する。

  • 増やす weight_decay。値としては 0.01 または 0.1 が出発点として良い。

  • 増やす lora_dropout。正則化を追加するには、例えば 0.1 のような値を使う。

  • バッチサイズまたは勾配蓄積ステップを増やす.

  • データセットの拡張 — オープンソースのデータセットを組み合わせたり連結して自分のデータセットを大きくする。品質の高いものを選ぶこと。

  • 評価による早期停止 — 評価を有効にして、評価損失が数ステップ増加したら停止する。

  • LoRA アルファスケーリング — 訓練後や推論時にアルファを下げると、ファインチューニングの効果が目立たなくなる。

  • 重みの平均化 — 文字通り元の instruct モデルとファインチューニング後のモデルの重みを足して2で割る。

過少学習 (一般的すぎる)

モデルが訓練データの基礎的なパターンを捉えられず、しばしばモデルの複雑さ不足や訓練時間の不足が原因となる。

解決策:

  • 学習率を調整する: 現在の学習率が低すぎる場合、学習率を上げることで収束が速くなることがある(特に短期の訓練では)。長期の訓練では代わりに学習率を下げてみる。どちらが有効か両方試して確認すること。

  • 訓練エポック数を増やす: エポック数を増やして訓練するが、過学習を避けるために検証損失を監視すること。

  • LoRA のランクを増やす (r)とアルファ:ランクは少なくともアルファの数と同等であるべきで、より小さいモデルやより複雑なデータセットではランクを大きくするべき;一般的には4から64の間であることが多い。

  • よりドメインに関連したデータセットを使う:訓練データが高品質でターゲットタスクに直接関連していることを確認する。

  • バッチサイズを1に減らす。これによりモデルの更新がより活発になる。

circle-check

謝辞: 心からの感謝を Eyeraarrow-up-right このガイドに寄稿してくれて!

最終更新

役に立ちましたか?