発展:効率的なファインチューニング(LoRA と QLoRA の考え方)
転移学習とファインチューニングのレッスンの続きとして、巨大なモデルを少ない手間で目的に合わせる工夫を掘り下げます。すべての重みを学び直す全体のファインチューニングがなぜ重いのか、変化ぶんだけを小さな形で学ぶ低ランク適応(LoRA)の考え方、なぜ小さな形で足りるのか、土台を軽くして必要メモリを減らす QLoRA、そして差し替えられる部品として持てる利点までを実装のコードは扱わず、考え方に絞って説明します。
ねらい
このレッスンは、転移学習とファインチューニングのレッスンの続きにあたる発展(はってん)の記事です。大規模言語モデル(だいきぼげんごモデル、Large Language Models)を自分の目的に合わせて仕上げようとすると、モデルが巨大なために、素直なやり方では手間も費用も大きくなります。その困りごとを軽くする代表的な工夫が、ここで扱う低ランク適応(ていランクてきおう、LoRA)です。
この記事は、ある程度の知識のある人に向けた深掘りです。転移学習とファインチューニングのレッスンで、事前学習したモデルを目的の仕事に合わせて仕上げる、という流れをつかんでいることを前提にします。この記事は、あくまで考え方を扱い、実装の手順やコードは扱いません。なぜ、少ない手間で仕上げられるのか、その理由に絞ります。
1. 変化ぶんだけを小さな形で学ぶ:LoRA
事前学習した巨大なモデルを自分の仕事に合わせたいとき、素直なやり方は、モデルの重みを全部、目的のデータで学び直すことです。これを全体のファインチューニングと呼びます。しかし、これは重い作業です。重みが何十億とあれば、そのすべてを更新するために大きな計算資源が要ります。しかも仕上がったモデルは、また何十億もの重みのかたまりです。目的ごとにそのかたまりを丸ごと持つことになり、仕事が10個あれば巨大なモデルを10個かかえることになります。もっと軽く目的に合わせる方法はないか。ここで効いてくるのが、「仕上げで変わる部分は、実はそれほど大きくないのではないか」という見立てです。
低ランク適応(LoRA、Low-Rank Adaptation)の考え方は、モデルの重みそのものを書きかえるのではなく、重みに加える変化ぶんだけを小さな形で学ぶことです。
全体のファインチューニングは、もとの重みを新しい重みへと直接書きかえていました。LoRA は、そうしません。もとの重みは、そのまま凍らせて動かしません。そのかわり、もとの重みに足し合わせる、小さな変化ぶんの部品を新しく用意して、そこだけを学びます。仕上がったモデルは、凍らせたもとの重みと、学んだ小さな変化ぶんを足し合わせて働きます。式で書くと、使う重み = 凍らせたもとの重み + 学んだ変化ぶん となります。もとの重みは書きかわらず、その横に変化ぶんが1つ足されるだけだと読めます。
大事なのは、この変化ぶんの部品が、とても小さくてすむことです。もとの重みが巨大でも、学ぶのは、それに比べればごくわずかな数の部品だけです。だから、更新する量が大幅に減り、少ない計算資源で、速く仕上げられます。凍らせたもとの重みは、目的が変わっても使い回せるので、目的ごとに巨大なモデルを丸ごと持つ必要もなくなります。
ポイント
LoRA は、もとの重みを凍らせたまま、それに足し合わせる小さな変化ぶんの部品だけを学びます。更新する量が大幅に減り、少ない資源で速く仕上げられます。
理解の確認
低ランク適応(LoRA)は、もとの重みを凍らせて動かさず、それに足し合わせる小さな変化ぶんの部品だけを学びます。全体のファインチューニングのように巨大な重みを丸ごと書きかえないため、更新する量が大幅に減り、少ない資源で速く仕上げられます。
2. なぜ、小さな形で足りるのか
では、なぜ変化ぶんをそんなに小さな形にしても足りるのでしょうか。ここに、LoRA の名前にある「低ランク」という考え方があります。かみくだいて説明します。
見立ては、こうです。事前学習で、すでに幅広い力を身につけたモデルをある目的に合わせて仕上げるとき、必要な調整は、それほど多くの方向に散らばっていないのではないか。言いかえると、仕上げで動かすべき変化は、限られた少数の方向の組み合わせで、だいたい表せるのではないか、という見立てです。
「限られた少数の方向の組み合わせで表せる」ことを数のことばで低ランクと言います。もし変化が、あらゆる方向にまんべんなく散らばっているなら、それを表すには、もとの重みと同じだけの大きな部品が要ります。しかし、変化が少数の方向に収まっているなら、その少数の方向だけを表す、小さな部品で足ります。LoRA は、この「変化は少数の方向に収まる」という見立てに乗って、変化ぶんをわざと小さな低ランクの形に限って学びます。具体的には、変化ぶんを大きな表として直接持つのではなく、細長い小さな表2枚のかけ算として作ります。式で書くと、変化ぶん = 縦に細長い小さな表 × 横に平たい小さな表 となります。
読み下すと、こうです。かりに、もとの重みが1000行1000列の表だとすると、そのまま持てば100万個の数が要ります。ところが、1000行4列の表と4行1000列の表のかけ算で作れば、覚える数は 1000 × 4 + 4 × 1000 で8000個ですみます。かけ算の結果は同じ1000行1000列の大きさになるのに、覚える数は100分の1以下です。この4という細さが「ランク」にあたり、少数の方向だけを表せる、という見立てを形にしたものです。
そして実際に、多くの場合、この小さな形でも、全体のファインチューニングに近い仕上がりが得られることが分かっています。つまり、仕上げの調整は、思ったより少ない方向で足りる、という見立てが、おおむね当たっていたわけです。ここでは、仕上げで動かす変化は少数の方向に収まるという見立てが、小さな部品で足りる理由だ、と押さえてください。
理解の確認
LoRA が小さな形で足りるのは、事前学習済みのモデルを目的に合わせる調整が、少数の方向の組み合わせ(低ランク)でだいたい表せる、という見立てによります。変化が少数の方向に収まるなら、それを表す小さな部品で足ります。多くの場合、これで全体のファインチューニングに近い仕上がりが得られます。
3. 土台も軽くする:QLoRA
LoRA は、学ぶ部品を小さくしました。しかし、凍らせたもとの重みは、計算のあいだ、手元に置いておく必要があります。巨大なモデルでは、この置いておくだけでも、多くのメモリを食います。ここをさらに軽くするのが、QLoRA(キューロラ)です。
QLoRA の工夫は、凍らせたもとの重みをざっくりした精度に落として持つことです。重みは、ふつう細かい精度の数で表しますが、これを粗い精度の数に置きかえて持ちます。数を粗くすると、1つあたりの置き場所が小さくなり、モデル全体で必要なメモリが大きく減ります。この、数を粗くしてメモリを節約する工夫を量子化(りょうしか、quantization)と呼びます。QLoRA は、量子化で軽くした土台の上で、LoRA の小さな部品を学ぶ、という組み合わせです。
その結果、以前は大がかりな設備が要った巨大モデルの仕上げが、より手近な環境でも行えるようになりました。もとの重みは粗くしても、学ぶ変化ぶんの部品は必要な精度で扱うなど、精度を落とす所と保つ所を分ける工夫で、仕上がりの質を保ちます。ここでは、QLoRA は、量子化で土台を軽くし、その上で LoRA を行う組み合わせだ、と押さえてください。
理解の確認
QLoRA は、凍らせたもとの重みを量子化(数を粗い精度に落とすこと)でメモリを節約して持ち、その上で LoRA の小さな部品を学ぶ組み合わせです。巨大モデルの仕上げをより手近な環境でも行えるようにします。精度を落とす所と保つ所を分けて、仕上がりの質を保ちます。
4. 差し替えられる部品として持てる
LoRA には、もう1つ、実務でうれしい性質があります。学んだ変化ぶんを差し替えられる小さな部品として持てることです。
もとの重みは凍らせて共通のまま、目的ごとに、小さな変化ぶんの部品だけを別々に学びます。すると、1つの共通の土台に、目的ごとの小さな部品を付け替えて使えます。翻訳向けの部品、要約向けの部品、ある分野に特化した部品、というように、小さな部品をいくつも用意しておき、必要に応じて付け替える。巨大なモデルを目的の数だけ持つのに比べ、置き場所も切り替えも、ずっと軽くなります。
このため、効率的なファインチューニングは、少ない資源で仕上げられるだけでなく、多くの目的に1つの土台で対応する、という使い方にも向いています。パラメータの一部だけを効率よく学ぶ、こうした一群のやり方は、パラメータ効率のよいファインチューニングと総称されます。LoRA は、その代表です。
理解度の確認
説明できる項目にチェックを入れましょう。すべて確認できたら、完了ボタンで記録します。
分からなかった点・気になった点
読み込み中です。