nikkie-ftnextの日記

イベントレポートや読書メモを発信

素振りの記:『日経Linux2023年9月号』の特集に沿ってLLMをファインチューニング! Linuxコマンドを教え込む

はじめに

面白いじゃない!1 nikkieです。

世はまさに大LLM時代。
ChatGPTのAPIを叩いたり2、各社が公開したLLMを触ったり3と既存のLLMを利用してきたnikkie氏。
「LLMのファインチューニング(解きたいタスクに特化した少量データでの調整訓練)ってどうやるんだろう」という疑問を次第に抱えるようになったのですが、このたび日経Linuxさんの特集をきっかけに、1パターン経験できました。

目次

『日経Linux2023年9月号』 生成AI特集

【特集1】
「ChatGPT」&「Stable Diffusion」
生成AIをLinuxで使いこなそう!

特集1は8パートからなるのですが、その中にBelugaさんとぽんでるさんによる「LLMのカスタマイズ」の記事があります。

LLMのカスタマイズということで、「プロンプトエンジニアリング」と「ファインチューニング」がそれぞれ解説されます。

LLMのファインチューニング

記事の参考文献にもあるOpenAIのドキュメントを参照すると

大まかに3つのステップとあります。

  1. Prepare and upload training data
  2. Train a new fine-tuned model
  3. Use your fine-tuned model

ファインチューニングのソースコードは以下にあります4

こちらを写経していきます!

まずColabに課金

A100 GPUが必要ということで、Colab Proに早速課金!💸
全然使ってない私でもこれでプロ!

GPUマシンを用意する手間への金の弾丸!
今回の私には妥当な投資でした。

rinna/japanese-gpt-neox-3.6bをLoRAでファインチューニング!

写経したノートブックは以下です。

初めてやってみたLLMのファインチューニングでしたが、なんと1分かからず終わりました

  • Linuxコマンドのインストラクションデータセットが全部で169件(データ量が少ない)
  • ファインチューニングは4エポックだけ指定5

notebook実行で一番時間がかかった(体感)のは、transformersライブラリでrinna/japanese-gpt-neox-3.6b(7GB)をダウンロードするところでした。
次点がpip installです

ファインチューニング前

プロンプトを構造化しているにもかかわらず改行を取り除いて構造を解体している実装が腑に落ちなかった6ので、プロンプトから改行を取り除かないで統一しました(懸念あったら突っ込んでください)。
その結果、紙面とは違ってファインチューニング前でも回答できています(exitコマンドと答えてほしいところですが)

プロンプト

### 指示:
Linuxでシェルを終了するコマンドを教えてください。

### 回答:

rinna/japanese-gpt-neox-3.6b 曰く

Linuxでシェルを終了するコマンドは、 shutdownコマンドです。

紙面の例は、Base LLM7なので同様の質問文を生成するというものです。

ファインチューニング後

ファインチューニングを経てどうなったのでしょうか?

プロンプト

### 指示:
Linuxでシェルを終了するコマンドを教えてください。

### 回答:

rinna/japanese-gpt-neox-3.6b 「shutdown」

おーっと、ここでもshutdownコマンドが強い...

ですが、もう少し尋ねてみると

  • Linuxコマンドを教えてください
    • 「ls」
    • よさそう🙆‍♂️(紙面と同じ)
  • lsコマンドは何のために使用されますか?
  • wgetコマンドの主な用途と使用方法について説明していただけますか?
    • Linuxでファイルをダウンロードするコマンドです。」
    • よさそう!🙆‍♂️(紙面だと正解できず)
  • catとmore、lessコマンドの違いは何ですか?
    • 「more コマンドは、ファイルの内容を表示します。 less はファイルを1行ずつ表示し、コマンドを入力するのに使用」
    • (おそらくmax_new_tokens=30指定により)切れちゃっているけど望みあり!
  • pwdコマンドの機能とは何ですか??
    • コマンドの出力を表示する
    • ぶっぶーですわ🙅‍♂️(それはechoですかね)

正解・不正解数で見ると、紙面と同様の結果と言えそうです!(再現している🙌)

手を動かした際のメモ

  • pip install -qq-qを重ねると、インストール中の出力を減らせるんだな〜(知らなかった)
  • huggingface/datasets、train_test_splitメソッドあるんだ〜
    • 分割した後のshuffleはseed引数を指定してみたよ(再現性のため)
  • huggingface/peft曰く、prepare_model_for_int8_trainingに代えてprepare_model_for_kbit_trainingを使ってね
    • PEFTのパラメタの意味は、サンプルコードに解説コメントありました(多謝)
  • 訓練前後でuse_cacheを切り替えているの、独特だな〜(なんでだろう)
  • 訓練中ロスが下がっているわけですが、このロスってどう計算している?
    • テキストを生成しているはずで、正解と比べるにしても、どうやって1つの数値に落とし込んでいるんだろう?
  • ファインチューニング後に利用するときはmin_new_tokensを指定しないことで、簡潔な回答を得られるということを学びました

終わりに

LLMのファインチューニング、面白いじゃない!!!
ChatGPTをファインチューニングしようとするとAPIリクエストになると思いますが、公開されているLLMのファインチューニングはtransformersやpeftを使った実装のポイントがいくつもあり、新しいことを知れて面白かったです。
ストックマークさんのLLMもファインチューニングしてみるなど、素振りを続けて完全に理解まで行きたい!

P.S. 『日経Linux2023年9月号』特集1には、からあげさんも寄稿

積読がたまっていくぅ〜(嬉しい悲鳴)

P.S. その2 一般庶民でもfine-tuningしたい!(StudyCoさん勉強会)

家事しながらばーっと流していたのですが、今回手を動かした部分の理論面の解説があってタイムリーでした。

ファインチューニングの工夫2点

  • 量子化
    • load_in_8bitやってますもんね
  • PEFT
    • LoRA
    • LLMの大量の重みは更新しないという割り切りは、結構筋が良いんじゃないかと思いました(デザインパターンのアダプターっぽさ)

こちらも積み動画の仲間入りです


  1. LangChainから叩いたり
  2. 最近の様子
  3. このリポジトリには参考文献へのリンクもあり、特にPEFTのサーベイ論文やLoRAの元論文に飛べて、理論面のキャッチアップがおろそかな身には非常にありがたかったです
  4. 実際にやるときは早期終了(early stopping)するのかな?
  5. Andrew Ng先生の講義で「入力を構造化しよう」と学んでおり、今回矛盾したので私はNg先生を信じました
  6. 前の注で示した記事にもありますが、Andrew Ng先生の講義で紹介された概念です。Base LLMとInstruction tuned LLM