LoRAとは?少ないパラメータで済むファインチューニング
元の重みは固定し、低ランク行列2つだけ足す
先に結論。7Bモデルを自分のデータで少し直したいとき、67億個の重みを全部学習させる必要はない。LoRA(Low-Rank Adaptation)は元の重みを凍結し、横に小さな行列を2つだけ付けて学習する。この記事を読めば、LoRAが実際にいくつのパラメータを学習するのか数えられるし、Full Fine-tuning・LoRA・QLoRAのどれが自分のGPUに合うか選べる。
ひとことで言うと
元の重みWはそのままにして、変化量ΔWをB × Aで表す。Wがd×kなら、Bはd×r、Aはr×kだ。r(rank、行列の「幅」)は4〜64くらいに小さく取る。順伝播はh = Wx + (α/r)·BAxで、学習されるのはAとBだけ。
最初はAもBもランダムから始まると思っていた。違った。Bはゼロから始まる。だから学習の最初のステップでは、元のモデルと出力がまったく同じになる。peft 0.17.1で64×64のLinearにr=4を付けてみると、付ける前と出力が一致し、Bはすべて0だった。50ステップ回したあとも、元のWは1要素も変わっていなかった。
実際いくつ学習するのか — 数えてみた
Llama 2 7Bと同じ形(hidden 4096・32層・語彙32,000)をmetaデバイス上に作り、peftでLoRAを付けて数えた。全体は6,738,415,616個。
r=8, q・vのみ 4,194,304 0.062%
r=16, q・k・v・o 16,777,216 0.249%
r=16, attention + MLP全部 39,976,960 0.593%
以前この記事には「元の0.1〜1%」と書いてあった。どこに付けるかで0.06%まで下がる。原論文はGPT-3 175Bで学習パラメータを1万分の1、GPUメモリを3分の1にしたと書いている。
メモリはなぜそこまで減らないのか
学習パラメータは1%未満なのに、メモリは1%にならない。凍結した重みもGPUには載せないといけないからだ。7Bをbf16で載せるとそれだけで約14GB。ざっくり計算するとこうなる(活性値・バッチは除いた概算)。
Full FT(bf16 + Adam) 7B × 16バイト ≈ 112GB
LoRA(重みbf16で固定) 7B × 2バイト ≈ 14GB + アダプター
QLoRA(重み4-bit) 7B × 0.5バイト ≈ 3.5GB + アダプター
16バイトは重み2・勾配2・Adamの状態8・fp32のコピー4を足したよくある概算だ。GPUに載せて実測した値ではない。QLoRA論文は65Bモデルを48GBのGPU 1枚でファインチューニングしたと書いている。
終わったらマージできる
W + (α/r)·BAを先に足しておけば、推論時はただのLinear 1つだ。peftのmerge_and_unload()でマージしてから出力を比べると、マージ前と一致した。逆にマージせずに置いておけば、アダプターのファイルを差し替えるだけで1つのモデルを複数の用途に使える。どちらが良いかはサービングの仕方次第。
いつ何を使うか
GPUに余裕があってドメインが大きく違うならFull FT。重みがbf16でGPUに載るならLoRA、載らないならQLoRA。ただその前に、プロンプトやRAGで済まないかを先に見る。口調や形式を揃える程度なら、そっちのほうがずっと安い。全体像はFine-tuningの記事にある。
社内データでモデルを少し直すか、RAGで行くかで迷っているならnegabaroに相談してもらって構わない。手持ちのデータ量とGPUでどこまでできるかから一緒に見られる。
キーコンセプト
元モデルの重み行列W(d×k)を固定(freeze)
Wの横にB(d×r)とA(r×k)を付ける。Aはランダム、Bはゼロから — 最初の出力は元モデルと同じ
順伝播: h = Wx + (α/r)·BAx
逆伝播: AとBだけ更新(Wはそのまま)
学習パラメータ数: 層ごとにr×(d+k)。7B相当でq・v r=8なら全体の0.062%
推論: W + (α/r)·BAにマージすれば追加計算なし。マージしなければアダプターを差し替えられる
メリット
- ✓ 学習パラメータがとても少ない(7B相当で0.06〜0.6%)
- ✓ GPUメモリの節約(原論文のGPT-3 175Bで1/3)
- ✓ マージすれば推論コストは増えない
- ✓ 元モデルをそのまま保存できる
デメリット
- ✗ 凍結した重みもGPUに載せるため、メモリは学習パラメータほど減らない
- ✗ Full Fine-tuningより性能がやや低い場合がある
- ✗ rと付ける層(q・vのみ/全部)を決める必要がある