🥷

llama.cppで語尾を”ござる”に変えるloraを作る

2023/11/21に公開

この記事について

llama.cppを使用し、ggufファイルのloraを構築しました。
まずは期待したloraができることをゴールにし、語尾を「ござる」に変えることを目的としています。

環境

環境構築

こちらと同じです。
https://zenn.dev/michy/articles/537fad9a11d309

学習するモデル

ELYZA-japanese-Llama-2-7b-instruct-q8_0.gguf

使うデータセット

databricks-dolly-15k-ja-gozaru.json
いわゆるござるデータセット

利用環境

python (notebook環境)
M1-pro MacBookPro(32GB)

ビルドはmetalを使っていますが、なぜかlora作成時はCPUばかりが動くのでmetalを活かせていない模様。

データセットの前準備

そのままでは使えないので加工を行います。
処理はコードのとおりですが、'open_qa'にデータを絞り、[INST]プロンプト[/INST]回答 の形式でデータを用意します。フォーマットはELYZAに習いました。
一つのセットが長すぎると学習ができなくなると思われるので文字数を制限しています。

import pandas as pd

file = "./data/databricks-dolly-15k-ja-gozaru.json"
# JSONファイルを読み込む
df = pd.read_json(file)

df_train = df[df['category'] == 'open_qa']

retBuffer = ""
counter = 0
for index,dfs in df_train.iterrows():

    inputText ="[INST]"+dfs.instruction+'[/INST]'+dfs.output.replace('\n','')+'\n'

    if len(inputText) < 64:
        counter +=1
        retBuffer +=inputText

# 保存trial
with open(trainPath, 'w') as file:
    file.write(retBuffer)

データセットのサンプル

[INST]「真珠の耳飾りの少女」を描いたオランダの画家は?[/INST]フェルメールでござる。
[INST]太陽が沈むとどうなるのか?[/INST]太陽が沈むと、夜が始まるでござる。
[INST]『左きゝの拳銃』でビリー・ザ・キッドを演じたのは?[/INST]ポール・ニューマンでござる。

学習処理

コマンドの先頭に!がついているのはnotebook環境で実行しているためです。
sample-start '[INST]'の部分は、学習データの先頭文字を指定しています。指定しないと学習データが正しく認識できません。

modelPath = './models/ELYZA-japanese-Llama-2-7b-instruct-q8_0.gguf'
inputPath ='./output/lora-LATEST.gguf'
outputPath ='./output/lora-ITERATION.gguf'
loraOutputPath ='./loraout/lora-ITERATION.bin'
trainPath = './data/input.txt'

!./finetune \
        --model-base {modelPath} \
        --checkpoint-in  {inputPath} \
        --checkpoint-out {outputPath} \
        --lora-out {loraOutputPath} \
        --train-data {trainPath} \
        --save-every 10 \
        --threads 6 --adam-iter 60 --batch 4 --ctx 128 \
        --sample-start '[INST]' \
        --use-checkpointing

学習時間

30分程度(1-iter毎に35秒程度)
metalビルドを使っていますが、GPUは学習で使われずCPUで学習が走っていたので完全に参考値です。

学習中のlossは早々に小さくなるのですが、語尾だけ変える学習はlossが小さくなったからといって語尾まで変えられているわけではない可能性があるので、少し多めにやりました。

推論

以下のコードにて推論を行う。

prompt = '[INST]日本の首都は?[INST]'
result = !./main -m {modelPath} --lora {loraPath} -n 64 -p '{prompt}'

Loraあり

無事に語尾が”ござる”になりました。
loraで使ったデータの問題もあり、回答が淡白になってしまいました。

[INST]日本の首都は?[INST]東京でござる。

周回ごとのアウトプットの違い

シードは固定しています。

10回

[INST]日本の首都は?[INST]  東京です。
承知しました。次に質問してください。 [end of text]

20回

[INST]日本の首都は?[INST]  東京です。
承知しました。次に質問してください。 [end of text]

30回

ござるみが出てくる。

[INST]日本の首都は?[INST]  東京でござる。
"ござる"は敬語なので、正解は「東京です」になります。 [end of text]'

40回

ここでござる完成してますね。

[INST]日本の首都は?[INST]東京でござる。
[end of text]

50回

[INST]日本の首都は?[INST]東京でござる。
[end of text]

Loraなし(参考)

通常の応答

[INST]日本の首都は?[INST]  日本の首都は東京です。
首都とは、国家の最高機関が集中して置かれる地域のことを指します。日本においては、明治時代初期に東

まとめ

いかがだったでしょうか?

今回は話題のLLMでLoraを作る方法をまとめました。
Macのスペック持て余している方は是非今回の手順で使ってみてください!

私のTwitterではLLMに限らず、AIを活用した業務改善情報の発信をしておりますのでご興味のある方は是非フォローをお願いします。
https://twitter.com/Linus_lab

Discussion