【ローカルLLM】QLoRAで「Vicuna-v1.5」の日本語翻訳性能を向上させる
Llama-2(13B)の日本語ファインチューンで試行錯誤している。
fine_tuning521k-jaなどの日本語データセットを手始めに、ShareGPTの日本語データを抽出したりしてQLoRAを試したものの、成果はイマイチで素人の限界を感じる。ColabやRunpodのGPU課金だけが積みあがってゆく…。
というか、自分でLlama-2を日本語ファインチューンしたモデルより「Vicuna」のほうが普通に日本語がうまい。
ならば、Llama-2のベースモデルをイチから日本語トレーニングするよりVicunaをファインチューンした方が話が早いのでは?と思うに至った。
Vicuna自体がLlamaのファインチューンモデルなので、さらにファインチューンを重ねるのがいいのかよくわかんないが…とりあえずテスト。
データセットの用意
ひとまず最初は、翻訳タスク(英→日)に限定して「Vicuna-13B-v1.5」をQLoRAファインチューンしてみる。
Alpacaデータセットと、それをGPT3.5で翻訳したJapanese_Alpacaデータセットをお借りして、即席の英→日対訳データを作成した。
ワード数で簡単にスクリーニングしたうえで、以下の形式でデータセットを整形。
OASST1スタイルでターゲットに指示文まで全部入れ込むのはQLoRA作者の推奨(とはいえ、今回の用途で適切なのかは分からない)。
数時間でサクっと終わらせたいので、ここから1500件ほどのデータを切り出し、これを使ってVicuna-13B-v1.5をQLoRAにかけた。
パラメータと学習曲線
Google Colabの標準GPU(T4)+ハイメモリでトレーニングした。
基本的なQLoRAハイパーパラメータは公式どおりにしたが、せっかくなので学習率は「--learning_rate 0.0001」に下げてみた。約3時間で2エポックの進捗。
ロス(損失)の推移はこちら:
1エポック過ぎからトレーニングロスと評価ロスが乖離し、オーバーフィットっぽくなった。日和って2エポックで止めたが、もう少し回してみるべきだったか。
ロスの値が1を切って始まるのは最初不安だったが、データセットの種類によってはけっこうあるので最近はそこまで気にしなくなった。
GuanacoのQLoRAを再現したこちらの記事によれば、トレーニングロスが1を割り込んだり、評価ロスが上昇していても、実際のモデルの性能に悪影響はなかったという。結局、具体的な下流のタスクで確認しないとモデルの性能は分からないとのこと。
パフォーマンスの簡易評価
ということで、実際にモデルの翻訳性能に変化があったか見てみる。
対訳データセットのうち、学習データに含めなかったものを10件ほどピックアップして、ファインチューンしたモデルの翻訳をテストした。
きちんと性能を見たいなら量子化モデルは避けるべきとは思うが、素のモデルはやはり重くて面倒…「Vicuna-13B-v1.5-GPTQ」にLoRAアダプタを付けて試す。
LoRAなしの「Vicuna-13B-v1.5」と、チェックポイント40のLoRA(epoch: 0.48)、80のLoRA(epoch: 0.96)、160のLoRA(epoch: 1.92)をそれぞれ適用した場合の出力を比較した。サンプリングはLLaMA-Presice。
ざっと見た感じ、多少は効果が出てそう。たとえば以下は、翻訳の改善がはっきり見られる例。
もうすこし客観的に評価するため、GPT-4にLoRAなしの翻訳とLoRAありの翻訳を提示し、どちらの出力の質が高いかジャッジしてもらった。
GPT-4には以下のプロンプトを与え、10件の翻訳を比較評価してもらった。
GPT-4による翻訳品質の判定結果
LoRA(epoch: 0.48):LoRA無しに対し、10問中6問で勝ち/4問で負け。
LoRA(epoch: 0.96):LoRA無しに対し、10問中8問で勝ち/2問で負け。
LoRA(epoch: 1.92):LoRA無しに対し、10問中8問で勝ち/2問で負け。
感想
とりあえずLoRAの効果はありそうだが、10問のテストでは少ないのでもう少しちゃんと検証したい。プロンプトフォーマットの影響も考慮すべきか。
同じデータ・同じ方法でLlama-2-13Bのベースモデルもファインチューンし、Vicunaをファインチューンした場合の性能と比較したい。
今回のような小規模データ(1500件)でも日本語性能を改善できるとすれば、自力のファインチューンにも希望が持てるかも。