LoRA (Low-Rank Adaptation)
LoRAは、重みを固定したまま小さな低ランク更新行列を学習させることで大規模モデルをファインチューニングし、学習可能なパラメーター数、メモリ使用量、ストレージを削減します。
LoRA(Low-Rank Adaptationの略)は、大規模な事前学習済みモデルを新しいタスクに適応させるパラメーター効率の高いファインチューニング(PEFT)手法です。元の重みを凍結し、選択したレイヤーと並行して小さな行列のペアを学習します。この2つの行列の積が低ランクの更新となり、凍結された重みに加算されるため、勾配を受け取るパラメーターはごく一部に限られます。2021年にMicrosoftのHuらが発表したLoRAは、GPT-3 175Bの学習可能なパラメーター数を1万分の1に、学習時のGPUメモリ使用量を、Adamによる完全なファインチューニングと比べて3分の1に削減しつつ、RoBERTa、DeBERTa、GPT-2、GPT-3で完全なファインチューニングと同等以上の品質を達成しました。現在では、限られたハードウェア上で大規模言語モデル(LLM)、拡散モデル、ビジョントランスフォーマーをカスタマイズするために広く使われています。IoTデバイス向けの長距離無線プロトコルであるLoRaとは無関係です。
LoRAの仕組み#
ファインチューニングでは、サイズd × kの事前学習済み重み行列Wに、何らかの更新ΔWを適用します。LoRAは、この更新の内在ランクが低いと仮定し、2つの細長い行列の積ΔW = B × Aとして表します。Aはr × k、Bはd × rで、ランクrはdやkよりはるかに小さい値です。レイヤーの出力はh = Wx + (α / r) × BAxとなります。ここでαは固定のスケーリング定数です。Aは小さな乱数で、Bはゼロで初期化されるため、学習は事前学習済みモデルそのものから始まります。誤差逆伝播中に更新されるのはAとBだけで、凍結された重みすべてに対するオプティマイザー状態も不要になります。
4096 × 4096の射影では、完全なファインチューニングで約1,680万個の重みを学習するのに対し、ランク8のアダプターでは8 × (4096 + 4096) = 65,536個を学習します。以下のPyTorchスクリプトは、このアダプターを作成し、凍結されたレイヤーに統合します。
import torch
from torch import nn
# A frozen pretrained 4096 x 4096 projection, like one in a transformer attention block
base = nn.Linear(4096, 4096).requires_grad_(False)
# LoRA's trainable rank-8 update: B @ A, scaled by alpha / r
# B starts at zero, so the adapted layer initially matches the pretrained one
r, alpha = 8, 16
A = nn.Parameter(torch.randn(r, 4096) * 0.01)
B = nn.Parameter(torch.zeros(4096, r))
trainable = A.numel() + B.numel()
total = trainable + sum(p.numel() for p in base.parameters())
print(f"Trainable: {trainable:,} of {total:,} parameters ({trainable / total:.2%})")
# After training, merge the update into the base weight so inference costs nothing extra
nn.init.normal_(B, std=0.01) # stand-in for trained values
x = torch.randn(2, 4096)
adapted = base(x) + (alpha / r) * (x @ A.T @ B.T)
merged = nn.functional.linear(x, base.weight + (alpha / r) * B @ A, base.bias)
print(f"Merged layer matches adapter output: {torch.allclose(adapted, merged, atol=1e-5)}")アダプターが学習するのは、レイヤーの16,846,848個のパラメーターのうち65,536個、つまり0.39%です。B × AをWに折り込むと、アダプターを別個に実行する場合と同じ出力が得られます。そのため、LoRAを統合したモデルは元のモデルとまったく同じ速度で実行できます。これは、各順伝播に追加の計算を加える従来のアダプターレイヤーに対する利点です。
実践におけるLoRA#
原論文ではトランスフォーマーの注意機構におけるクエリ射影と値射影のみを適応させていましたが、現在はすべての線形レイヤーを対象とするレシピも多くあります。ランクとαは主なハイパーパラメーターです。Hugging Face PEFTライブラリのデフォルト値はr = 8、α = 8です。ベースモデルには手を加えないため、1つのデプロイ環境でベースモデルを1つだけ保持し、小さなタスク固有のアダプターを切り替えて使用できます。GPT-3 175Bのクエリ射影と値射影にランク4を適用すると、適応後の各チェックポイントは350 GBから約35 MBに縮小し、およそ1万分の1になります。
- 言語モデル: チームは、1台のGPUでオープンLLMを特定のドメイン、スタイル、または指示形式に適応させます。多くの場合、LoRAを指示チューニング用データと組み合わせます。
- 画像生成: LoRAファイルを使うと、Stable Diffusionなどのモデルにキャラクター、製品、またはアートスタイルを学習させられます。これらのファイルはベースのチェックポイントとは別に共有し、重ねて適用できます。
- ビジョンモデルとマルチモーダルモデル: アダプターを使って、ビジョントランスフォーマーや視覚言語モデル(VLM)を医療、産業、または文書画像に特化させることができ、バックボーンの再学習は不要です。
バリエーション#
- QLoRA: ベースモデルを4ビットのNormalFloat精度で凍結し、その上でLoRAアダプターを学習します。Dettmersらはこの手法を使い、48 GBのGPU1台で650億パラメーターのモデルをファインチューニングし、完全な16ビットファインチューニングの性能を維持しました。
- DoRA: 各事前学習済み重みを大きさと方向に分け、方向にのみLoRAを適用します。これにより、推論コストを変えずに、完全なファインチューニングとの精度差を縮めます。
LoRAと関連用語の比較#
- パラメーター効率の高いファインチューニング: モデルのごく一部だけを学習する手法の総称です。レイヤーの凍結は最も簡単な方法で、Ultralytics YOLOでは
freeze学習引数として利用できます。この引数を使うと、YOLO26モデルの最初のN層を事前学習済みの重みに固定し、残りの層を学習します。 - フルファインチューニング: すべての重みを更新し、タスクごとにモデルのフルサイズのコピーを保存します。プログラミングと数学では、フルファインチューニングは標準的なLoRAを大幅に上回る性能を示しました。一方、LoRAはベースモデルが持つほかのスキルの壊滅的忘却がより少なくなりました。
- プロンプトチューニング: すべてのモデル重みを凍結したまま、入力の先頭に追加するソフトプロンプトの埋め込みを学習します。
- 転移学習: あるタスクで得た知識を別のタスクに再利用する一般的な考え方です。LoRAはそれを効率的に実現する方法の1つです。
- モデルマージ: 個別にファインチューニングしたモデルの重みを組み合わせます。複数のLoRAアダプターを1つのベースモデルに統合するのは、よくある例です。










