Q&A + RAG に特化したLLMをSFTで学習させ4bit量子化モデルを作り、GPT3.5以上の性能を7Bモデルで達成する
この記事は、LLM Advent Calendar 2023の12月15日の記事である。
先日、RAG用途に使える、Wikipedia 日本語の embeddings とベクトル検索用の faiss index を作ったのだけど、質問に対しての回答の抽出に GPT 3.5 / 4 を使ってる。せっかくなのでOpenAIなどの超巨大LLM使うのではなく、発展目まぐるしいローカルで動くLLMをSupervised Fine-tuning Trainer(SFT)で学習させ、Q&A + RAG タスクに特化した LLM を作ってみた。元モデルのLLMとしては、rinna社が公開している、youri7b-instruction を用いている。
例として、学習させたモデルに以下のような入力を与えると
以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。
### 指示:
楽曲『約束はいらない』でデビューした、声優は誰?
### 入力:
Suara 大阪府立豊中高等学校を経て大阪外国語大学でインドネシア語を専攻中にバンド・ユニットを組んで音楽活動を始めた。普段はお笑い番組が大好きなこともあってよく喋るほうだが、東京の仕事で標準語の喋りをする時は、
早見沙織 声優デビュー時より、数多くの主題歌やキャラクターソングを担当し、バラードからポップス、ヒットソングのカバー曲や英語の楽曲など、様々な曲を歌いこなす。2009年には吉田仁美とのユニット「blue dro
約束はいらない 「約束はいらない」(やくそくはいらない)は、坂本真綾のデビューシングル。
約束はいらない 坂本真綾の歌手デビュー作品。当時坂本はまだ無名の声優であったが、同曲がテーマソングとなったアニメ『天空のエスカフローネ』とともに知名度を上げることとなる。後に「指輪」が同アニメの劇場版映画の主題歌とな
坂本真綾 本格的な歌手活動は、1996年にテレビアニメ『天空のエスカフローネ』へ出演したことがきっかけで始めており、同作のオープニングテーマソングである「約束はいらない」(岩里祐穂作詞、菅野よう子作曲)をシング
### 応答:
出力として
坂本真綾
と、質問に対した回答のみが出力される。手軽に試せるように、Google Colab 上のGPU(T4)で動くnotebookも作成したので、興味がある方は試してみてほしい。
GPT3.5 との性能比較
では今回作ったモデルとそれを量子化したものをGPT3.5、GPT4.0と比較してみよう。性能比較のデータセットには、hotchpotch/jaqket_v1_qa_wikija_contextのvalidationデータ980件を用いて、回答が含まれるコンテキストがある質問に対して、きちんと回答が抽出できているかを、部分一致と完全一致の正解率で評価する。
結果は以下のようになり、学習後ではどのモデルでも正解率はGPT3.5を大きく超え、実行時間もとりわけAutoGTPQ量子化モデルでは倍ぐらい速い。なお記事後半で、数値についての考察も述べている。
モデル | 完全一致 | 部分一致 | 実行時間 | GPUメモリ(MB) |
---|---|---|---|---|
GPT3.5 | 0.5949 | 0.799 | 405 | |
GPT4.0 | 0.8786 | 0.9173 | 1152 | |
fp16(学習前) | 0.5908 | 0.7327 | 4218 | 11122 |
fp16(学習後) | 0.7582 | 0.8939 | 4146 | 9964 |
BnB(4bit) | 0.7602 | 0.8867 | 397 | 3774 |
AutoGTPQ | 0.7969 | 0.8867 | 211 | 4695 |
AutoAWQ | 0.7316 | 0.8847 | 301 | 5933 |
なお、評価に使ったコードはこちらの eval_xxx というコードである。
Supervised Fine-tuning Trainer(SFT) を使った学習
STFは手軽な方法で指示に対して特定フォーマットの出力(Instruction Tuning)を学習させることができる方法である。学習のさせ方も簡単で、例えば
### 指示:
今日の天気は何ですか?
### 入力:
本日は大雨ですね。
### 応答:
大雨
のような例文を用意する。例では「### 応答:」以降がうまく出力されるように学習して欲しいデータである。この時、例文と「### 応答:」だけ与えれば、よしなに学習してくれる。実際の学習時には、「応答:」以降を推論し、望ましい回答である「大雪」のtokenの確率スコア(cross entropy loss)を学習する感じ。つまり、例文さえ作れれば、あとはいい感じに学習させることができるというお手軽な学習方法。データも1000件ぐらいあればいい感じに学習できる(要出典)との話だ。
学習用データセット
学習のデータセットには、jaqket_v1_qa_wikija_contextのtrain 2939件を使う。このデータセットはAIクイズ王データセットのうち、CC BY-SA 4.0 DEEDライセンスのものを抽出し、RAG用途に使えるコンテキストを付け加えたものだ。
学習させる
学習は、以下の実装で行った。学習にかかった時間はRTX4090で1epoch(91 steps)で2時間強ほど。
なお、この学習で行なっている細かいことは割愛するが、youri7b-instruction を BnB 4bit 量子化 + flash attention2 でロードし、LoRA を使って学習させている。性能を高めるためのNEFTuneも使っている。
学習の結果を見る
学習の過程は、以下の wandb に記録している。
train loss は割とすぐ頭打ちに、eval loss も全体の40%あたりから下がらなくなる。40%というのは1200件ぐらいの学習なので「データも1000件ぐらいあればいい感じに学習できる」の信憑性は結構高そうだ。
学習終了時に完全一致では一致しなかった間違った結果も見てみよう。wandb は dataframe を table 描画できて便利だ。
結構惜しい結果も多い。"』"が末尾に入ってしまっていたり、=(大文字)と=(小文字)の違いだったり。
モデルの量子化
2023年12月現在、HuggingFace Transformer モデルの量子化方法は、Quantize 🤗 Transformers modelsによると、python の HuggingFace Transformer から手軽に使えるものとして以下の三つを挙げている。
- AWQ
- GPTQ
- BnB (bitsandbytes)
BnBは今回学習時にも使った、割と古くからある量子化方法、GTPQは2022年、AWQは2023年に出てきた量子化手法である。今回は、各々の手法で4bit量子化して、jaqket_v1_qa_wikija_contextのvalidationデータで評価をした。なお、AWQ・GTPQではより良い量子化を行うためのキャリブレーション・サンプル用のテキストデータとして、wikipediaのテキストやtrain時の学習データを量子化時に与えている。
結果は記事冒頭で表示したものと同じ、以下の結果となった。測定環境はCPU Ryzen 9 5950とGPU RTX4090である。部分一致・完全一致でのGPT3.5よりもスコア超えはどのモデルでも、実行時間も量子化しているモデルはどれも上回り、とりわけAutoGTPQではGPT3.5の倍ぐらい速い。量子化したモデル同士で見ていくと、完全一致が量子化していないfp16が最良、というのはわかるのだが、部分一致においてはfp16を上回りAutoGTPQが最良という予期しない結果となった。これは、AutoGTPQの量子化時に、学習データをサンプルとして渡しているので、そのバイアスがかかってfp16よりも良い結果になったのかもしれない。そして GPT4.0 比較では精度で完敗だが致し方なし…。
モデル | 完全一致 | 部分一致 | 実行時間 | GPUメモリ(MB) |
---|---|---|---|---|
GPT3.5 | 0.5949 | 0.799 | 405 | |
GPT4.0 | 0.8786 | 0.9173 | 1152 | |
fp16(学習前) | 0.5908 | 0.7327 | 4218 | 11122 |
fp16(学習後) | 0.7582 | 0.8939 | 4146 | 9964 |
BnB(4bit) | 0.7602 | 0.8867 | 397 | 3774 |
AutoGTPQ | 0.7969 | 0.8867 | 211 | 4695 |
AutoAWQ | 0.7316 | 0.8847 | 301 | 5933 |
なお、GPTQ / AWQ / BnB ともに細かいチューニングはしていないため、より最適化すれば結果は異なる可能性がある。例えばAWQは利用ユースケースのtoken長やbatch_sizeによってアルゴリズム(version)を変更することで、速度の高速化が行える。また、GPUメモリはモデルロード時のメモリで、推論時にはもっと利用GPUメモリは増えるであろう。
おわりに
今回はお手軽に学習可能なSFTを使い、Q&A + RAG タスクで適切な回答ができるようなファインチューンを7BサイズのローカルLLMに対して行った。結果として、汎化性能は失われたといえ、量子化したモデルで速度・精度共にご家庭のマシンでGPT3.5を超える性能を達成することができた。また、SFTでは学習データが1000件ほどあれば、大体の出力フォーマットに沿った出力にできそうであるし、その場合は学習時間がRTX4090で1時間もかからずに学習できるであろうから、気軽に特定用途に特化したLLMの学習が行えそうだ。
今後さらにローカルLLMの性能は上がっていくであろうし、TinyLlama-1.1Bのような、さらに小さいサイズで高性能なローカルLLMも今後開発されていくであろう。来年のローカルLLMの発展も楽しみである。
学習や推論等々に使った実装・ノートブック・公開モデル
- https://github.com/hotchpotch/youri-7b-sft-qa-context-jaqket/
- hotchpotch/youri-7b-sft-qa-context-jaqket-gptq
- AutoGPTQ で量子化したモデル
- hotchpotch/youri-7b-sft-qa-context-jaqket-awq
- AutoAWQ で量子化したモデル